Skip to content

Instantly share code, notes, and snippets.

@Leftium
Created August 25, 2022 00:23
Show Gist options
  • Save Leftium/be562b92d8fe47b300a3d11dd3b8de79 to your computer and use it in GitHub Desktop.
Save Leftium/be562b92d8fe47b300a3d11dd3b8de79 to your computer and use it in GitHub Desktop.
Versioned JSON document
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