Created
August 25, 2022 00:23
-
-
Save Leftium/be562b92d8fe47b300a3d11dd3b8de79 to your computer and use it in GitHub Desktop.
Versioned JSON document
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class VersionedDoc | |
constructor: (json) -> | |
if json | |
if json._id then @_id = json._id | |
@versions = json._versions | |
if @versions.constructor isnt Array | |
@versions = [ new Date() ] | |
@props = {} | |
for propName of json | |
if propName[0] isnt '_' | |
@props[propName] = json[propName] | |
else | |
@props = {} | |
@versions = [] | |
toJson: () -> | |
json = {} | |
latest = @checkout() | |
for propName of latest | |
if propName[0] isnt '_' | |
prop = Object.assign {v: latest[propName]}, @props[propName] | |
json[propName] = prop | |
if @_id then json._id = @_id | |
json._versions = @versions | |
json._version = @versions.length-1 | |
return json | |
commit: (object) -> | |
if not object | |
throw new Error 'No object passed to VersionedObject.commit().' | |
nextVersion = "v#{@versions.length}" | |
currVersion = "v#{@versions.length - 1}" | |
versionBumped = false | |
hasDiffs = false | |
diffs = {} | |
currentDoc = @checkout() | |
for key,valueHistory of @props | |
if object[key] is undefined and currentDoc[key] isnt undefined | |
item = {} | |
item[nextVersion] = undefined | |
valueHistory = { ...item, ...valueHistory } | |
versionBumped = true | |
hasDiffs = true | |
diffs[key] = [undefined, currentDoc[key]] | |
@props[key] = valueHistory | |
for key,value of object | |
if key is '_id' | |
if value isnt @_id | |
hasDiffs = true | |
diffs[key] = [value, @_id] | |
@_id = value | |
else | |
valueHistory = @props[key] or {} | |
if value isnt currentDoc[key] | |
item = {} | |
item[nextVersion] = value | |
valueHistory = { ...item, ...valueHistory } | |
versionBumped = true | |
hasDiffs = true | |
diffs[key] = [value, currentDoc[key]] | |
@props[key] = valueHistory | |
if versionBumped | |
@versions.push new Date() | |
if not hasDiffs then diffs = null | |
return diffs | |
checkout: (version=@versions.length - 1) -> | |
result = {} | |
if @_id then result._id = @_id | |
for key,valueHistory of @props | |
for v in [version..0] | |
if v <= version | |
value = valueHistory["v#{v}"] | |
if value isnt undefined | |
result[key] = value | |
break | |
return result | |
module.exports = VersionedDoc |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment