in frontend/index.js [78:118]
function makeChange(doc, context, options) {
const actor = getActorId(doc)
if (!actor) {
throw new Error('Actor ID must be initialized with setActorId() before making a change')
}
const state = copyObject(doc[STATE])
state.seq += 1
const change = {
actor,
seq: state.seq,
startOp: state.maxOp + 1,
deps: state.deps,
time: (options && typeof options.time === 'number') ? options.time
: Math.round(new Date().getTime() / 1000),
message: (options && typeof options.message === 'string') ? options.message : '',
ops: context.ops
}
if (doc[OPTIONS].backend) {
const [backendState, patch, binaryChange] = doc[OPTIONS].backend.applyLocalChange(state.backendState, change)
state.backendState = backendState
state.lastLocalChange = binaryChange
// NOTE: When performing a local change, the patch is effectively applied twice -- once by the
// context invoking interpretPatch as soon as any change is made, and the second time here
// (after a round-trip through the backend). This is perhaps more robust, as changes only take
// effect in the form processed by the backend, but the downside is a performance cost.
// Should we change this?
const newDoc = applyPatchToDoc(doc, patch, state, true)
const patchCallback = options && options.patchCallback || doc[OPTIONS].patchCallback
if (patchCallback) patchCallback(patch, doc, newDoc, true, [binaryChange])
return [newDoc, change]
} else {
const queuedRequest = {actor, seq: change.seq, before: doc}
state.requests = state.requests.concat([queuedRequest])
state.maxOp = state.maxOp + countOps(change.ops)
state.deps = []
return [updateRootObject(doc, context ? context.updated : {}, state), change]
}
}