automerge-js adding trace to out of date errors
This commit is contained in:
parent
e6cd366aa0
commit
59bde120ee
6 changed files with 38 additions and 18 deletions
automerge-js/src
automerge-wasm
|
@ -3,6 +3,7 @@
|
|||
//const CACHE = Symbol('_cache') // map from objectId to immutable object
|
||||
export const STATE = Symbol.for('_am_state') // object containing metadata about current state (e.g. sequence numbers)
|
||||
export const HEADS = Symbol.for('_am_heads') // object containing metadata about current state (e.g. sequence numbers)
|
||||
export const TRACE = Symbol.for('_am_trace') // object containing metadata about current state (e.g. sequence numbers)
|
||||
export const OBJECT_ID = Symbol.for('_am_objectId') // object containing metadata about current state (e.g. sequence numbers)
|
||||
export const READ_ONLY = Symbol.for('_am_readOnly') // object containing metadata about current state (e.g. sequence numbers)
|
||||
export const FROZEN = Symbol.for('_am_frozen') // object containing metadata about current state (e.g. sequence numbers)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
export { uuid } from './uuid'
|
||||
|
||||
import { rootProxy, listProxy, textProxy, mapProxy } from "./proxies"
|
||||
import { STATE, HEADS, OBJECT_ID, READ_ONLY, FROZEN } from "./constants"
|
||||
import { STATE, HEADS, TRACE, OBJECT_ID, READ_ONLY, FROZEN } from "./constants"
|
||||
|
||||
import { AutomergeValue, Counter } from "./types"
|
||||
export { AutomergeValue, Text, Counter, Int, Uint, Float64 } from "./types"
|
||||
|
@ -48,6 +48,20 @@ function _heads<T>(doc: Doc<T>) : Heads | undefined {
|
|||
return Reflect.get(doc,HEADS)
|
||||
}
|
||||
|
||||
function _trace<T>(doc: Doc<T>) : string | undefined {
|
||||
return Reflect.get(doc,TRACE)
|
||||
}
|
||||
|
||||
function _set_heads<T>(doc: Doc<T>, heads: Heads) {
|
||||
Reflect.set(doc,HEADS,heads)
|
||||
Reflect.set(doc,TRACE,(new Error()).stack)
|
||||
}
|
||||
|
||||
function _clear_heads<T>(doc: Doc<T>) {
|
||||
Reflect.set(doc,HEADS,undefined)
|
||||
Reflect.set(doc,TRACE,undefined)
|
||||
}
|
||||
|
||||
function _obj<T>(doc: Doc<T>) : ObjID {
|
||||
return Reflect.get(doc,OBJECT_ID)
|
||||
}
|
||||
|
@ -104,7 +118,7 @@ function _change<T>(doc: Doc<T>, options: ChangeOptions, callback: ChangeFn<T>):
|
|||
throw new RangeError("Attempting to use an outdated Automerge document")
|
||||
}
|
||||
if (!!_heads(doc) === true) {
|
||||
throw new RangeError("Attempting to change an out of date document");
|
||||
throw new RangeError("Attempting to change an out of date document - set at: " + _trace(doc));
|
||||
}
|
||||
if (_readonly(doc) === false) {
|
||||
throw new RangeError("Calls to Automerge.change cannot be nested")
|
||||
|
@ -112,13 +126,13 @@ function _change<T>(doc: Doc<T>, options: ChangeOptions, callback: ChangeFn<T>):
|
|||
const state = _state(doc)
|
||||
const heads = state.getHeads()
|
||||
try {
|
||||
Reflect.set(doc,HEADS,heads)
|
||||
_set_heads(doc,heads)
|
||||
Reflect.set(doc,FROZEN,true)
|
||||
const root : T = rootProxy(state);
|
||||
callback(root)
|
||||
if (state.pendingOps() === 0) {
|
||||
Reflect.set(doc,FROZEN,false)
|
||||
Reflect.set(doc,HEADS,undefined)
|
||||
_clear_heads(doc)
|
||||
return doc
|
||||
} else {
|
||||
state.commit(options.message, options.time)
|
||||
|
@ -127,7 +141,7 @@ function _change<T>(doc: Doc<T>, options: ChangeOptions, callback: ChangeFn<T>):
|
|||
} catch (e) {
|
||||
//console.log("ERROR: ",e)
|
||||
Reflect.set(doc,FROZEN,false)
|
||||
Reflect.set(doc,HEADS,undefined)
|
||||
_clear_heads(doc)
|
||||
state.rollback()
|
||||
throw e
|
||||
}
|
||||
|
@ -168,14 +182,14 @@ export function save<T>(doc: Doc<T>) : Uint8Array {
|
|||
|
||||
export function merge<T>(local: Doc<T>, remote: Doc<T>) : Doc<T> {
|
||||
if (!!_heads(local) === true) {
|
||||
throw new RangeError("Attempting to change an out of date document");
|
||||
throw new RangeError("Attempting to change an out of date document - set at: " + _trace(doc));
|
||||
}
|
||||
const localState = _state(local)
|
||||
const heads = localState.getHeads()
|
||||
const remoteState = _state(remote)
|
||||
const changes = localState.getChangesAdded(remoteState)
|
||||
localState.applyChanges(changes)
|
||||
Reflect.set(local,HEADS,heads)
|
||||
_set_heads(local,heads)
|
||||
return rootProxy(localState, true)
|
||||
}
|
||||
|
||||
|
@ -267,7 +281,7 @@ export function applyChanges<T>(doc: Doc<T>, changes: Change[]) : [Doc<T>] {
|
|||
const state = _state(doc)
|
||||
const heads = state.getHeads()
|
||||
state.applyChanges(changes)
|
||||
Reflect.set(doc,HEADS,heads)
|
||||
_set_heads(doc,heads)
|
||||
return [rootProxy(state, true)];
|
||||
}
|
||||
|
||||
|
@ -322,7 +336,7 @@ export function receiveSyncMessage<T>(doc: Doc<T>, inState: SyncState, message:
|
|||
throw new RangeError("Attempting to use an outdated Automerge document")
|
||||
}
|
||||
if (!!_heads(doc) === true) {
|
||||
throw new RangeError("Attempting to change an out of date document");
|
||||
throw new RangeError("Attempting to change an out of date document - set at: " + _trace(doc));
|
||||
}
|
||||
if (_readonly(doc) === false) {
|
||||
throw new RangeError("Calls to Automerge.change cannot be nested")
|
||||
|
@ -330,7 +344,7 @@ export function receiveSyncMessage<T>(doc: Doc<T>, inState: SyncState, message:
|
|||
const state = _state(doc)
|
||||
const heads = state.getHeads()
|
||||
state.receiveSyncMessage(syncState, message)
|
||||
Reflect.set(doc,HEADS,heads)
|
||||
_set_heads(doc,heads)
|
||||
const outState = ApiHandler.exportSyncState(syncState)
|
||||
return [rootProxy(state, true), outState, null];
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import { AutomergeValue, ScalarValue, MapValue, ListValue, TextValue } from "./t
|
|||
import { Int, Uint, Float64 } from "./numbers"
|
||||
import { Counter, getWriteableCounter } from "./counter"
|
||||
import { Text } from "./text"
|
||||
import { STATE, HEADS, FROZEN, OBJECT_ID, READ_ONLY, COUNTER, INT, UINT, F64, TEXT } from "./constants"
|
||||
import { STATE, HEADS, TRACE, FROZEN, OBJECT_ID, READ_ONLY, COUNTER, INT, UINT, F64, TEXT } from "./constants"
|
||||
|
||||
function parseListIndex(key) {
|
||||
if (typeof key === 'string' && /^[0-9]+$/.test(key)) key = parseInt(key, 10)
|
||||
|
@ -108,6 +108,7 @@ const MapHandler = {
|
|||
if (key === READ_ONLY) return readonly
|
||||
if (key === FROZEN) return frozen
|
||||
if (key === HEADS) return heads
|
||||
if (key === TRACE) return target.trace
|
||||
if (key === STATE) return context;
|
||||
if (!cache[key]) {
|
||||
cache[key] = valueAt(target, key)
|
||||
|
@ -129,6 +130,10 @@ const MapHandler = {
|
|||
target.heads = val
|
||||
return true
|
||||
}
|
||||
if (key === TRACE) {
|
||||
target.trace = val
|
||||
return true
|
||||
}
|
||||
const [ value, datatype ] = import_value(val)
|
||||
if (frozen) {
|
||||
throw new RangeError("Attempting to use an outdated Automerge document")
|
||||
|
@ -211,6 +216,7 @@ const ListHandler = {
|
|||
if (index === READ_ONLY) return readonly
|
||||
if (index === FROZEN) return frozen
|
||||
if (index === HEADS) return heads
|
||||
if (index === TRACE) return target.trace
|
||||
if (index === STATE) return context;
|
||||
if (index === 'length') return context.length(objectId, heads);
|
||||
if (index === Symbol.iterator) {
|
||||
|
@ -246,6 +252,10 @@ const ListHandler = {
|
|||
target.heads = val
|
||||
return true
|
||||
}
|
||||
if (index === TRACE) {
|
||||
target.trace = val
|
||||
return true
|
||||
}
|
||||
if (typeof index == "string") {
|
||||
throw new RangeError('list index must be a number')
|
||||
}
|
||||
|
@ -356,6 +366,7 @@ const TextHandler = Object.assign({}, ListHandler, {
|
|||
if (index === READ_ONLY) return readonly
|
||||
if (index === FROZEN) return frozen
|
||||
if (index === HEADS) return heads
|
||||
if (index === TRACE) return target.trace
|
||||
if (index === STATE) return context;
|
||||
if (index === 'length') return context.length(objectId, heads);
|
||||
if (index === Symbol.iterator) {
|
||||
|
|
|
@ -2,6 +2,4 @@ let wasm = require("./bindgen")
|
|||
module.exports = wasm
|
||||
module.exports.load = module.exports.loadDoc
|
||||
delete module.exports.loadDoc
|
||||
Object.defineProperty(module.exports, "__esModule", { value: true })
|
||||
module.exports.init = () => (new Promise((resolve,reject) => { resolve(module.exports) }))
|
||||
module.exports.default = module.exports.init
|
||||
|
|
2
automerge-wasm/types/index.d.ts
vendored
2
automerge-wasm/types/index.d.ts
vendored
|
@ -205,5 +205,5 @@ export class SyncState {
|
|||
readonly sharedHeads: Heads;
|
||||
}
|
||||
|
||||
export default function init (): Promise<API>;
|
||||
export function init (): Promise<API>;
|
||||
|
||||
|
|
|
@ -47,7 +47,3 @@ export function init() {
|
|||
}))
|
||||
}
|
||||
|
||||
// depricating default export
|
||||
export default function() {
|
||||
return init()
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue