@liveblocks/client
Advanced tools
Comparing version 0.12.0-beta.6 to 0.12.0-beta.7
@@ -47,3 +47,3 @@ "use strict"; | ||
} | ||
internalRoom = room_1.createRoom(roomId, Object.assign(Object.assign({}, clientOptions), options)); | ||
internalRoom = (0, room_1.createRoom)(roomId, Object.assign(Object.assign({}, clientOptions), options)); | ||
rooms.set(roomId, internalRoom); | ||
@@ -50,0 +50,0 @@ internalRoom.connect(); |
import { Op, SerializedCrdtWithId, SerializedList } from "./live"; | ||
declare type Dispatch = (ops: Op[]) => void; | ||
export declare class Doc<T extends Record<string, any> = Record<string, any>> { | ||
private _root; | ||
private actor; | ||
private _dispatch; | ||
private _clock; | ||
private _items; | ||
#private; | ||
private constructor(); | ||
@@ -17,10 +13,2 @@ static from<T>(root: T, actor?: number, dispatch?: Dispatch): Doc<T>; | ||
apply(op: Op): void; | ||
private applyCreateRegister; | ||
private applyDeleteRecordKey; | ||
private applyUpdateRecord; | ||
private applyCreateMap; | ||
private applyCreateList; | ||
private applyCreateObject; | ||
private applyDeleteRecord; | ||
private applySetParentKey; | ||
get root(): LiveObject<T>; | ||
@@ -30,14 +18,30 @@ count(): number; | ||
} | ||
declare class AbstractCrdt { | ||
declare abstract class AbstractCrdt { | ||
#private; | ||
private _listeners; | ||
private _deepListeners; | ||
protected get doc(): Doc<Record<string, any>> | undefined; | ||
get id(): string | undefined; | ||
get parent(): AbstractCrdt | undefined; | ||
setParent(parent: AbstractCrdt): void; | ||
attach(id: string, doc: Doc): void; | ||
attachChild(id: string, key: string, crdt: AbstractCrdt): void; | ||
detach(): void; | ||
detachChild(crdt: AbstractCrdt): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
protected get _doc(): Doc<Record<string, any>> | undefined; | ||
/** | ||
* INTERNAL | ||
*/ | ||
get _id(): string | undefined; | ||
/** | ||
* INTERNAL | ||
*/ | ||
get _parent(): AbstractCrdt | undefined; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_setParent(parent: AbstractCrdt): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_attach(id: string, doc: Doc): void; | ||
abstract _attachChild(id: string, key: string, crdt: AbstractCrdt): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_detach(): void; | ||
abstract _detachChild(crdt: AbstractCrdt): void; | ||
subscribe(listener: () => void): void; | ||
@@ -48,6 +52,6 @@ subscribeDeep(listener: () => void): void; | ||
notify(onlyDeep?: boolean): void; | ||
serialize(parentId: string, parentKey: string): Op[]; | ||
abstract _serialize(parentId: string, parentKey: string): Op[]; | ||
} | ||
export declare class LiveObject<T extends Record<string, any> = Record<string, any>> extends AbstractCrdt { | ||
private _map; | ||
#private; | ||
constructor(object?: T); | ||
@@ -57,14 +61,29 @@ /** | ||
*/ | ||
serialize(parentId?: string, parentKey?: string): Op[]; | ||
static deserialize([id, item]: SerializedCrdtWithId, parentToChildren: Map<string, SerializedCrdtWithId[]>, doc: Doc): LiveObject<{ | ||
_serialize(parentId?: string, parentKey?: string): Op[]; | ||
/** | ||
* INTERNAL | ||
*/ | ||
static _deserialize([id, item]: SerializedCrdtWithId, parentToChildren: Map<string, SerializedCrdtWithId[]>, doc: Doc): LiveObject<{ | ||
[key: string]: any; | ||
}>; | ||
attach(id: string, doc: Doc): void; | ||
attachChild(id: string, key: keyof T, child: AbstractCrdt): void; | ||
detachChild(child: AbstractCrdt): void; | ||
detach(): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
apply(op: Op): void; | ||
_attach(id: string, doc: Doc): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_attachChild(id: string, key: keyof T, child: AbstractCrdt): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_detachChild(child: AbstractCrdt): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_detach(): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_apply(op: Op): void; | ||
toObject(): T; | ||
@@ -76,11 +95,28 @@ set<TKey extends keyof T>(key: TKey, value: T[TKey]): void; | ||
export declare class LiveMap<TKey extends string, TValue> extends AbstractCrdt { | ||
private _map; | ||
#private; | ||
constructor(entries?: readonly (readonly [TKey, TValue])[] | null | undefined); | ||
serialize(parentId?: string, parentKey?: string): Op[]; | ||
static deserialize([id, item]: SerializedCrdtWithId, parentToChildren: Map<string, SerializedCrdtWithId[]>, doc: Doc): LiveMap<string, unknown>; | ||
private apply; | ||
attach(id: string, doc: Doc): void; | ||
attachChild(id: string, key: TKey, child: AbstractCrdt): void; | ||
detach(): void; | ||
detachChild(child: AbstractCrdt): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_serialize(parentId?: string, parentKey?: string): Op[]; | ||
/** | ||
* INTERNAL | ||
*/ | ||
static _deserialize([id, item]: SerializedCrdtWithId, parentToChildren: Map<string, SerializedCrdtWithId[]>, doc: Doc): LiveMap<string, unknown>; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_attach(id: string, doc: Doc): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_attachChild(id: string, key: TKey, child: AbstractCrdt): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_detach(): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_detachChild(child: AbstractCrdt): void; | ||
get(key: TKey): TValue | undefined; | ||
@@ -98,12 +134,32 @@ set(key: TKey, value: TValue): void; | ||
export declare class LiveList<T> extends AbstractCrdt { | ||
private _items; | ||
#private; | ||
constructor(items?: T[]); | ||
static deserialize([id, item]: [id: string, item: SerializedList], parentToChildren: Map<string, SerializedCrdtWithId[]>, doc: Doc): LiveList<never>; | ||
serialize(parentId?: string, parentKey?: string): Op[]; | ||
attach(id: string, doc: Doc): void; | ||
detach(): void; | ||
attachChild(id: string, key: string, child: AbstractCrdt): void; | ||
detachChild(child: AbstractCrdt): void; | ||
setChildKey(key: string, child: AbstractCrdt): void; | ||
private apply; | ||
/** | ||
* INTERNAL | ||
*/ | ||
static _deserialize([id, item]: [id: string, item: SerializedList], parentToChildren: Map<string, SerializedCrdtWithId[]>, doc: Doc): LiveList<never>; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_serialize(parentId?: string, parentKey?: string): Op[]; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_attach(id: string, doc: Doc): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_detach(): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_attachChild(id: string, key: string, child: AbstractCrdt): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_detachChild(child: AbstractCrdt): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_setChildKey(key: string, child: AbstractCrdt): void; | ||
push(item: T): void; | ||
@@ -110,0 +166,0 @@ insert(item: T, index: number): void; |
"use strict"; | ||
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) { | ||
if (!privateMap.has(receiver)) { | ||
throw new TypeError("attempted to get private field on non-instance"); | ||
} | ||
return privateMap.get(receiver); | ||
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { | ||
if (kind === "m") throw new TypeError("Private method is not writable"); | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); | ||
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; | ||
}; | ||
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) { | ||
if (!privateMap.has(receiver)) { | ||
throw new TypeError("attempted to set private field on non-instance"); | ||
} | ||
privateMap.set(receiver, value); | ||
return value; | ||
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); | ||
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); | ||
}; | ||
var _parent, _doc, _id; | ||
var _Doc_instances, _Doc_clock, _Doc_items, _Doc_root, _Doc_actor, _Doc_dispatch, _Doc_applyCreateRegister, _Doc_applyDeleteRecordKey, _Doc_applyUpdateRecord, _Doc_applyCreateMap, _Doc_applyCreateList, _Doc_applyCreateObject, _Doc_applyDeleteRecord, _Doc_applySetParentKey, _AbstractCrdt_listeners, _AbstractCrdt_deepListeners, _AbstractCrdt_parent, _AbstractCrdt_doc, _AbstractCrdt_id, _LiveObject_map, _LiveMap_map, _LiveRegister_data, _LiveList_items; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -21,11 +19,14 @@ exports.LiveList = exports.LiveMap = exports.LiveObject = exports.Doc = void 0; | ||
const position_1 = require("./position"); | ||
const INTERNAL = Symbol("liveblocks.internal"); | ||
function noOp() { } | ||
class Doc { | ||
constructor(_root, actor = 0, _dispatch = noOp) { | ||
this._root = _root; | ||
this.actor = actor; | ||
this._dispatch = _dispatch; | ||
this._clock = 0; | ||
this._items = new Map(); | ||
constructor(root, actor = 0, dispatch = noOp) { | ||
_Doc_instances.add(this); | ||
_Doc_clock.set(this, 0); | ||
_Doc_items.set(this, new Map()); | ||
_Doc_root.set(this, void 0); | ||
_Doc_actor.set(this, void 0); | ||
_Doc_dispatch.set(this, void 0); | ||
__classPrivateFieldSet(this, _Doc_root, root, "f"); | ||
__classPrivateFieldSet(this, _Doc_actor, actor, "f"); | ||
__classPrivateFieldSet(this, _Doc_dispatch, dispatch, "f"); | ||
} | ||
@@ -35,4 +36,4 @@ static from(root, actor = 0, dispatch = noOp) { | ||
const storage = new Doc(rootRecord, actor, dispatch); | ||
rootRecord.attach(storage.generateId(), storage); | ||
storage.dispatch(rootRecord.serialize()); | ||
rootRecord._attach(storage.generateId(), storage); | ||
storage.dispatch(rootRecord._serialize()); | ||
return storage; | ||
@@ -65,16 +66,16 @@ } | ||
const doc = new Doc(null, actor, dispatch); | ||
doc._root = LiveObject.deserialize(root, parentToChildren, doc); | ||
__classPrivateFieldSet(doc, _Doc_root, LiveObject._deserialize(root, parentToChildren, doc), "f"); | ||
return doc; | ||
} | ||
dispatch(ops) { | ||
this._dispatch(ops); | ||
__classPrivateFieldGet(this, _Doc_dispatch, "f").call(this, ops); | ||
} | ||
addItem(id, item) { | ||
this._items.set(id, item); | ||
__classPrivateFieldGet(this, _Doc_items, "f").set(id, item); | ||
} | ||
deleteItem(id) { | ||
this._items.delete(id); | ||
__classPrivateFieldGet(this, _Doc_items, "f").delete(id); | ||
} | ||
getItem(id) { | ||
return this._items.get(id); | ||
return __classPrivateFieldGet(this, _Doc_items, "f").get(id); | ||
} | ||
@@ -84,31 +85,31 @@ apply(op) { | ||
case live_1.OpType.UpdateObject: { | ||
this.applyUpdateRecord(op); | ||
__classPrivateFieldGet(this, _Doc_instances, "m", _Doc_applyUpdateRecord).call(this, op); | ||
break; | ||
} | ||
case live_1.OpType.CreateObject: { | ||
this.applyCreateObject(op); | ||
__classPrivateFieldGet(this, _Doc_instances, "m", _Doc_applyCreateObject).call(this, op); | ||
break; | ||
} | ||
case live_1.OpType.CreateMap: { | ||
this.applyCreateMap(op); | ||
__classPrivateFieldGet(this, _Doc_instances, "m", _Doc_applyCreateMap).call(this, op); | ||
break; | ||
} | ||
case live_1.OpType.CreateList: { | ||
this.applyCreateList(op); | ||
__classPrivateFieldGet(this, _Doc_instances, "m", _Doc_applyCreateList).call(this, op); | ||
break; | ||
} | ||
case live_1.OpType.DeleteCrdt: { | ||
this.applyDeleteRecord(op); | ||
__classPrivateFieldGet(this, _Doc_instances, "m", _Doc_applyDeleteRecord).call(this, op); | ||
break; | ||
} | ||
case live_1.OpType.SetParentKey: { | ||
this.applySetParentKey(op); | ||
__classPrivateFieldGet(this, _Doc_instances, "m", _Doc_applySetParentKey).call(this, op); | ||
break; | ||
} | ||
case live_1.OpType.DeleteObjectKey: { | ||
this.applyDeleteRecordKey(op); | ||
__classPrivateFieldGet(this, _Doc_instances, "m", _Doc_applyDeleteRecordKey).call(this, op); | ||
break; | ||
} | ||
case live_1.OpType.CreateRegister: { | ||
this.applyCreateRegister(op); | ||
__classPrivateFieldGet(this, _Doc_instances, "m", _Doc_applyCreateRegister).call(this, op); | ||
break; | ||
@@ -118,171 +119,175 @@ } | ||
} | ||
applyCreateRegister(op) { | ||
const parent = this._items.get(op.parentId); | ||
if (parent == null) { | ||
return; | ||
} | ||
if (!(parent instanceof LiveMap) && !(parent instanceof LiveList)) { | ||
throw new Error("LiveRegister can only be attached to a LiveMap or LiveList"); | ||
} | ||
const newRegister = new LiveRegister(op.data); | ||
parent.attachChild(op.id, op.parentKey, newRegister); | ||
get root() { | ||
return __classPrivateFieldGet(this, _Doc_root, "f"); | ||
} | ||
applyDeleteRecordKey(op) { | ||
const item = this._items.get(op.id); | ||
if (item && item instanceof LiveObject) { | ||
item.apply(op); | ||
} | ||
count() { | ||
return __classPrivateFieldGet(this, _Doc_items, "f").size; | ||
} | ||
applyUpdateRecord(op) { | ||
const item = this._items.get(op.id); | ||
if (item && item instanceof LiveObject) { | ||
item.apply(op); | ||
} | ||
generateId() { | ||
var _a, _b; | ||
return `${__classPrivateFieldGet(this, _Doc_actor, "f")}:${__classPrivateFieldSet(this, _Doc_clock, (_b = __classPrivateFieldGet(this, _Doc_clock, "f"), _a = _b++, _b), "f"), _a}`; | ||
} | ||
applyCreateMap(op) { | ||
const parent = this._items.get(op.parentId); | ||
if (parent == null) { | ||
return; | ||
} | ||
const newMap = new LiveMap(); | ||
parent.attachChild(op.id, op.parentKey, newMap); | ||
} | ||
exports.Doc = Doc; | ||
_Doc_clock = new WeakMap(), _Doc_items = new WeakMap(), _Doc_root = new WeakMap(), _Doc_actor = new WeakMap(), _Doc_dispatch = new WeakMap(), _Doc_instances = new WeakSet(), _Doc_applyCreateRegister = function _Doc_applyCreateRegister(op) { | ||
const parent = __classPrivateFieldGet(this, _Doc_items, "f").get(op.parentId); | ||
if (parent == null) { | ||
return; | ||
} | ||
applyCreateList(op) { | ||
const parent = this._items.get(op.parentId); | ||
if (parent == null) { | ||
return; | ||
} | ||
const list = new LiveList(); | ||
parent.attachChild(op.id, op.parentKey, list); | ||
if (!(parent instanceof LiveMap) && !(parent instanceof LiveList)) { | ||
throw new Error("LiveRegister can only be attached to a LiveMap or LiveList"); | ||
} | ||
applyCreateObject(op) { | ||
if (op.parentId && op.parentKey) { | ||
const parent = this._items.get(op.parentId); | ||
if (parent == null) { | ||
return; | ||
} | ||
const newObj = new LiveObject(op.data); | ||
parent.attachChild(op.id, op.parentKey, newObj); | ||
} | ||
const newRegister = new LiveRegister(op.data); | ||
parent._attachChild(op.id, op.parentKey, newRegister); | ||
}, _Doc_applyDeleteRecordKey = function _Doc_applyDeleteRecordKey(op) { | ||
const item = __classPrivateFieldGet(this, _Doc_items, "f").get(op.id); | ||
if (item && item instanceof LiveObject) { | ||
item._apply(op); | ||
} | ||
applyDeleteRecord(op) { | ||
const item = this._items.get(op.id); | ||
if (item == null) { | ||
return; | ||
} | ||
const parent = item.parent; | ||
}, _Doc_applyUpdateRecord = function _Doc_applyUpdateRecord(op) { | ||
const item = __classPrivateFieldGet(this, _Doc_items, "f").get(op.id); | ||
if (item && item instanceof LiveObject) { | ||
item._apply(op); | ||
} | ||
}, _Doc_applyCreateMap = function _Doc_applyCreateMap(op) { | ||
const parent = __classPrivateFieldGet(this, _Doc_items, "f").get(op.parentId); | ||
if (parent == null) { | ||
return; | ||
} | ||
const newMap = new LiveMap(); | ||
parent._attachChild(op.id, op.parentKey, newMap); | ||
}, _Doc_applyCreateList = function _Doc_applyCreateList(op) { | ||
const parent = __classPrivateFieldGet(this, _Doc_items, "f").get(op.parentId); | ||
if (parent == null) { | ||
return; | ||
} | ||
const list = new LiveList(); | ||
parent._attachChild(op.id, op.parentKey, list); | ||
}, _Doc_applyCreateObject = function _Doc_applyCreateObject(op) { | ||
if (op.parentId && op.parentKey) { | ||
const parent = __classPrivateFieldGet(this, _Doc_items, "f").get(op.parentId); | ||
if (parent == null) { | ||
return; | ||
} | ||
if (parent) { | ||
parent.detachChild(item); | ||
} | ||
const newObj = new LiveObject(op.data); | ||
parent._attachChild(op.id, op.parentKey, newObj); | ||
} | ||
applySetParentKey(op) { | ||
const item = this._items.get(op.id); | ||
if (item == null) { | ||
return; | ||
} | ||
if (item.parent == null) { | ||
return; | ||
} | ||
if (item.parent instanceof LiveList) { | ||
item.parent.setChildKey(op.parentKey, item); | ||
} | ||
}, _Doc_applyDeleteRecord = function _Doc_applyDeleteRecord(op) { | ||
const item = __classPrivateFieldGet(this, _Doc_items, "f").get(op.id); | ||
if (item == null) { | ||
return; | ||
} | ||
get root() { | ||
return this._root; | ||
const parent = item._parent; | ||
if (parent == null) { | ||
return; | ||
} | ||
count() { | ||
return this._items.size; | ||
if (parent) { | ||
parent._detachChild(item); | ||
} | ||
generateId() { | ||
return `${this.actor}:${this._clock++}`; | ||
}, _Doc_applySetParentKey = function _Doc_applySetParentKey(op) { | ||
const item = __classPrivateFieldGet(this, _Doc_items, "f").get(op.id); | ||
if (item == null) { | ||
return; | ||
} | ||
} | ||
exports.Doc = Doc; | ||
if (item._parent == null) { | ||
return; | ||
} | ||
if (item._parent instanceof LiveList) { | ||
item._parent._setChildKey(op.parentKey, item); | ||
} | ||
}; | ||
class AbstractCrdt { | ||
constructor() { | ||
this._listeners = []; | ||
this._deepListeners = []; | ||
_parent.set(this, void 0); | ||
_doc.set(this, void 0); | ||
_id.set(this, void 0); | ||
_AbstractCrdt_listeners.set(this, []); | ||
_AbstractCrdt_deepListeners.set(this, []); | ||
_AbstractCrdt_parent.set(this, void 0); | ||
_AbstractCrdt_doc.set(this, void 0); | ||
_AbstractCrdt_id.set(this, void 0); | ||
} | ||
get doc() { | ||
return __classPrivateFieldGet(this, _doc); | ||
/** | ||
* INTERNAL | ||
*/ | ||
get _doc() { | ||
return __classPrivateFieldGet(this, _AbstractCrdt_doc, "f"); | ||
} | ||
get id() { | ||
return __classPrivateFieldGet(this, _id); | ||
/** | ||
* INTERNAL | ||
*/ | ||
get _id() { | ||
return __classPrivateFieldGet(this, _AbstractCrdt_id, "f"); | ||
} | ||
get parent() { | ||
return __classPrivateFieldGet(this, _parent); | ||
/** | ||
* INTERNAL | ||
*/ | ||
get _parent() { | ||
return __classPrivateFieldGet(this, _AbstractCrdt_parent, "f"); | ||
} | ||
setParent(parent) { | ||
if (__classPrivateFieldGet(this, _parent)) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
_setParent(parent) { | ||
if (__classPrivateFieldGet(this, _AbstractCrdt_parent, "f")) { | ||
throw new Error("Cannot attach parent if it already exist"); | ||
} | ||
__classPrivateFieldSet(this, _parent, parent); | ||
__classPrivateFieldSet(this, _AbstractCrdt_parent, parent, "f"); | ||
} | ||
attach(id, doc) { | ||
if (__classPrivateFieldGet(this, _id) || __classPrivateFieldGet(this, _doc)) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
_attach(id, doc) { | ||
if (__classPrivateFieldGet(this, _AbstractCrdt_id, "f") || __classPrivateFieldGet(this, _AbstractCrdt_doc, "f")) { | ||
throw new Error("Cannot attach if CRDT is already attached"); | ||
} | ||
doc.addItem(id, this); | ||
__classPrivateFieldSet(this, _id, id); | ||
__classPrivateFieldSet(this, _doc, doc); | ||
__classPrivateFieldSet(this, _AbstractCrdt_id, id, "f"); | ||
__classPrivateFieldSet(this, _AbstractCrdt_doc, doc, "f"); | ||
} | ||
attachChild(id, key, crdt) { | ||
throw new Error("attachChild should be implement by a non abstract CRDT"); | ||
} | ||
detach() { | ||
if (__classPrivateFieldGet(this, _doc) && __classPrivateFieldGet(this, _id)) { | ||
__classPrivateFieldGet(this, _doc).deleteItem(__classPrivateFieldGet(this, _id)); | ||
/** | ||
* INTERNAL | ||
*/ | ||
_detach() { | ||
if (__classPrivateFieldGet(this, _AbstractCrdt_doc, "f") && __classPrivateFieldGet(this, _AbstractCrdt_id, "f")) { | ||
__classPrivateFieldGet(this, _AbstractCrdt_doc, "f").deleteItem(__classPrivateFieldGet(this, _AbstractCrdt_id, "f")); | ||
} | ||
__classPrivateFieldSet(this, _parent, undefined); | ||
__classPrivateFieldSet(this, _doc, undefined); | ||
__classPrivateFieldSet(this, _AbstractCrdt_parent, undefined, "f"); | ||
__classPrivateFieldSet(this, _AbstractCrdt_doc, undefined, "f"); | ||
} | ||
detachChild(crdt) { | ||
throw new Error("detach child should be implement by a non abstract CRDT"); | ||
} | ||
subscribe(listener) { | ||
this._listeners.push(listener); | ||
__classPrivateFieldGet(this, _AbstractCrdt_listeners, "f").push(listener); | ||
} | ||
subscribeDeep(listener) { | ||
this._deepListeners.push(listener); | ||
__classPrivateFieldGet(this, _AbstractCrdt_deepListeners, "f").push(listener); | ||
} | ||
unsubscribe(listener) { | ||
utils_1.remove(this._listeners, listener); | ||
(0, utils_1.remove)(__classPrivateFieldGet(this, _AbstractCrdt_listeners, "f"), listener); | ||
} | ||
unsubscribeDeep(listener) { | ||
utils_1.remove(this._deepListeners, listener); | ||
(0, utils_1.remove)(__classPrivateFieldGet(this, _AbstractCrdt_deepListeners, "f"), listener); | ||
} | ||
notify(onlyDeep = false) { | ||
if (onlyDeep === false) { | ||
for (const listener of this._listeners) { | ||
for (const listener of __classPrivateFieldGet(this, _AbstractCrdt_listeners, "f")) { | ||
listener(); | ||
} | ||
} | ||
for (const listener of this._deepListeners) { | ||
for (const listener of __classPrivateFieldGet(this, _AbstractCrdt_deepListeners, "f")) { | ||
listener(); | ||
} | ||
if (this.parent) { | ||
this.parent.notify(true); | ||
if (this._parent) { | ||
this._parent.notify(true); | ||
} | ||
} | ||
serialize(parentId, parentKey) { | ||
throw new Error("serialize should be implement by a non abstract CRDT"); | ||
} | ||
} | ||
_parent = new WeakMap(), _doc = new WeakMap(), _id = new WeakMap(); | ||
_AbstractCrdt_listeners = new WeakMap(), _AbstractCrdt_deepListeners = new WeakMap(), _AbstractCrdt_parent = new WeakMap(), _AbstractCrdt_doc = new WeakMap(), _AbstractCrdt_id = new WeakMap(); | ||
class LiveObject extends AbstractCrdt { | ||
constructor(object = {}) { | ||
super(); | ||
_LiveObject_map.set(this, void 0); | ||
for (const key in object) { | ||
const value = object[key]; | ||
if (value instanceof AbstractCrdt) { | ||
value.setParent(this); | ||
value._setParent(this); | ||
} | ||
} | ||
this._map = new Map(Object.entries(object)); | ||
__classPrivateFieldSet(this, _LiveObject_map, new Map(Object.entries(object)), "f"); | ||
} | ||
@@ -292,4 +297,4 @@ /** | ||
*/ | ||
serialize(parentId, parentKey) { | ||
if (this.id == null) { | ||
_serialize(parentId, parentKey) { | ||
if (this._id == null) { | ||
throw new Error("Cannot serialize item is not attached"); | ||
@@ -299,3 +304,3 @@ } | ||
const op = { | ||
id: this.id, | ||
id: this._id, | ||
type: live_1.OpType.CreateObject, | ||
@@ -307,5 +312,5 @@ parentId, | ||
ops.push(op); | ||
for (const [key, value] of this._map) { | ||
for (const [key, value] of __classPrivateFieldGet(this, _LiveObject_map, "f")) { | ||
if (value instanceof AbstractCrdt) { | ||
ops.push(...value.serialize(this.id, key)); | ||
ops.push(...value._serialize(this._id, key)); | ||
} | ||
@@ -318,3 +323,6 @@ else { | ||
} | ||
static deserialize([id, item], parentToChildren, doc) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
static _deserialize([id, item], parentToChildren, doc) { | ||
if (item.type !== live_1.CrdtType.Object) { | ||
@@ -324,3 +332,3 @@ throw new Error(`Tried to deserialize a record but item type is "${item.type}"`); | ||
const object = new LiveObject(item.data); | ||
object.attach(id, doc); | ||
object._attach(id, doc); | ||
const children = parentToChildren.get(id); | ||
@@ -336,44 +344,56 @@ if (children == null) { | ||
const child = deserialize(entry, parentToChildren, doc); | ||
child.setParent(object); | ||
object._map.set(crdt.parentKey, child); | ||
child._setParent(object); | ||
__classPrivateFieldGet(object, _LiveObject_map, "f").set(crdt.parentKey, child); | ||
} | ||
return object; | ||
} | ||
attach(id, doc) { | ||
super.attach(id, doc); | ||
for (const [key, value] of this._map) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
_attach(id, doc) { | ||
super._attach(id, doc); | ||
for (const [key, value] of __classPrivateFieldGet(this, _LiveObject_map, "f")) { | ||
if (value instanceof AbstractCrdt) { | ||
value.attach(doc.generateId(), doc); | ||
value._attach(doc.generateId(), doc); | ||
} | ||
} | ||
} | ||
attachChild(id, key, child) { | ||
if (this.doc == null) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
_attachChild(id, key, child) { | ||
if (this._doc == null) { | ||
throw new Error("Can't attach child if doc is not present"); | ||
} | ||
const previousValue = this._map.get(key); | ||
const previousValue = __classPrivateFieldGet(this, _LiveObject_map, "f").get(key); | ||
if (isCrdt(previousValue)) { | ||
previousValue.detach(); | ||
previousValue._detach(); | ||
} | ||
this._map.set(key, child); | ||
child.setParent(this); | ||
child.attach(id, this.doc); | ||
__classPrivateFieldGet(this, _LiveObject_map, "f").set(key, child); | ||
child._setParent(this); | ||
child._attach(id, this._doc); | ||
this.notify(); | ||
} | ||
detachChild(child) { | ||
for (const [key, value] of this._map) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
_detachChild(child) { | ||
for (const [key, value] of __classPrivateFieldGet(this, _LiveObject_map, "f")) { | ||
if (value === child) { | ||
this._map.delete(key); | ||
__classPrivateFieldGet(this, _LiveObject_map, "f").delete(key); | ||
} | ||
} | ||
if (child) { | ||
child.detach(); | ||
child._detach(); | ||
} | ||
this.notify(); | ||
} | ||
detach() { | ||
super.detach(); | ||
for (const value of this._map.values()) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
_detach() { | ||
super._detach(); | ||
for (const value of __classPrivateFieldGet(this, _LiveObject_map, "f").values()) { | ||
if (isCrdt(value)) { | ||
value.detach(); | ||
value._detach(); | ||
} | ||
@@ -385,11 +405,11 @@ } | ||
*/ | ||
apply(op) { | ||
_apply(op) { | ||
if (op.type === live_1.OpType.UpdateObject) { | ||
for (const key in op.data) { | ||
const oldValue = this._map.get(key); | ||
const oldValue = __classPrivateFieldGet(this, _LiveObject_map, "f").get(key); | ||
if (isCrdt(oldValue)) { | ||
oldValue.detach(); | ||
oldValue._detach(); | ||
} | ||
const value = op.data[key]; | ||
this._map.set(key, value); | ||
__classPrivateFieldGet(this, _LiveObject_map, "f").set(key, value); | ||
} | ||
@@ -400,7 +420,7 @@ this.notify(); | ||
const key = op.key; | ||
const oldValue = this._map.get(key); | ||
const oldValue = __classPrivateFieldGet(this, _LiveObject_map, "f").get(key); | ||
if (isCrdt(oldValue)) { | ||
oldValue.detach(); | ||
oldValue._detach(); | ||
} | ||
this._map.delete(key); | ||
__classPrivateFieldGet(this, _LiveObject_map, "f").delete(key); | ||
this.notify(); | ||
@@ -410,3 +430,3 @@ } | ||
toObject() { | ||
return Object.fromEntries(this._map); | ||
return Object.fromEntries(__classPrivateFieldGet(this, _LiveObject_map, "f")); | ||
} | ||
@@ -418,3 +438,3 @@ set(key, value) { | ||
get(key) { | ||
return this._map.get(key); | ||
return __classPrivateFieldGet(this, _LiveObject_map, "f").get(key); | ||
} | ||
@@ -435,6 +455,6 @@ // delete<TKey extends keyof T>(key: TKey) { | ||
update(overrides) { | ||
if (this.doc && this.id) { | ||
if (this._doc && this._id) { | ||
const ops = []; | ||
const updateOp = { | ||
id: this.id, | ||
id: this._id, | ||
type: live_1.OpType.UpdateObject, | ||
@@ -445,11 +465,11 @@ data: {} | ||
for (const key in overrides) { | ||
const oldValue = this._map.get(key); | ||
const oldValue = __classPrivateFieldGet(this, _LiveObject_map, "f").get(key); | ||
if (oldValue instanceof LiveObject) { | ||
oldValue.detach(); | ||
oldValue._detach(); | ||
} | ||
const newValue = overrides[key]; | ||
if (newValue instanceof AbstractCrdt) { | ||
newValue.setParent(this); | ||
newValue.attach(this.doc.generateId(), this.doc); | ||
ops.push(...newValue.serialize(this.id, key)); | ||
newValue._setParent(this); | ||
newValue._attach(this._doc.generateId(), this._doc); | ||
ops.push(...newValue._serialize(this._id, key)); | ||
} | ||
@@ -459,5 +479,5 @@ else { | ||
} | ||
this._map.set(key, newValue); | ||
__classPrivateFieldGet(this, _LiveObject_map, "f").set(key, newValue); | ||
} | ||
this.doc.dispatch(ops); | ||
this._doc.dispatch(ops); | ||
this.notify(); | ||
@@ -467,11 +487,11 @@ return; | ||
for (const key in overrides) { | ||
const oldValue = this._map.get(key); | ||
const oldValue = __classPrivateFieldGet(this, _LiveObject_map, "f").get(key); | ||
if (oldValue instanceof AbstractCrdt) { | ||
oldValue.detach(); | ||
oldValue._detach(); | ||
} | ||
const newValue = overrides[key]; | ||
if (newValue instanceof AbstractCrdt) { | ||
newValue.setParent(this); | ||
newValue._setParent(this); | ||
} | ||
this._map.set(key, newValue); | ||
__classPrivateFieldGet(this, _LiveObject_map, "f").set(key, newValue); | ||
} | ||
@@ -482,5 +502,7 @@ this.notify(); | ||
exports.LiveObject = LiveObject; | ||
_LiveObject_map = new WeakMap(); | ||
class LiveMap extends AbstractCrdt { | ||
constructor(entries) { | ||
super(); | ||
_LiveMap_map.set(this, void 0); | ||
if (entries) { | ||
@@ -490,13 +512,16 @@ const mappedEntries = []; | ||
const value = selfOrRegister(entry[1]); | ||
value.setParent(this); | ||
value._setParent(this); | ||
mappedEntries.push([entry[0], value]); | ||
} | ||
this._map = new Map(mappedEntries); | ||
__classPrivateFieldSet(this, _LiveMap_map, new Map(mappedEntries), "f"); | ||
} | ||
else { | ||
this._map = new Map(); | ||
__classPrivateFieldSet(this, _LiveMap_map, new Map(), "f"); | ||
} | ||
} | ||
serialize(parentId, parentKey) { | ||
if (this.id == null) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
_serialize(parentId, parentKey) { | ||
if (this._id == null) { | ||
throw new Error("Cannot serialize item is not attached"); | ||
@@ -509,3 +534,3 @@ } | ||
const op = { | ||
id: this.id, | ||
id: this._id, | ||
type: live_1.OpType.CreateMap, | ||
@@ -516,8 +541,11 @@ parentId, | ||
ops.push(op); | ||
for (const [key, value] of this._map) { | ||
ops.push(...value.serialize(this.id, key)); | ||
for (const [key, value] of __classPrivateFieldGet(this, _LiveMap_map, "f")) { | ||
ops.push(...value._serialize(this._id, key)); | ||
} | ||
return ops; | ||
} | ||
static deserialize([id, item], parentToChildren, doc) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
static _deserialize([id, item], parentToChildren, doc) { | ||
if (item.type !== live_1.CrdtType.Map) { | ||
@@ -527,3 +555,3 @@ throw new Error(`Tried to deserialize a map but item type is "${item.type}"`); | ||
const map = new LiveMap(); | ||
map.attach(id, doc); | ||
map._attach(id, doc); | ||
const children = parentToChildren.get(id); | ||
@@ -539,46 +567,57 @@ if (children == null) { | ||
const child = deserialize(entry, parentToChildren, doc); | ||
child.setParent(map); | ||
map._map.set(crdt.parentKey, child); | ||
child._setParent(map); | ||
__classPrivateFieldGet(map, _LiveMap_map, "f").set(crdt.parentKey, child); | ||
} | ||
return map; | ||
} | ||
apply(op) { } | ||
attach(id, doc) { | ||
super.attach(id, doc); | ||
for (const [key, value] of this._map) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
_attach(id, doc) { | ||
super._attach(id, doc); | ||
for (const [key, value] of __classPrivateFieldGet(this, _LiveMap_map, "f")) { | ||
if (isCrdt(value)) { | ||
value.attach(doc.generateId(), doc); | ||
value._attach(doc.generateId(), doc); | ||
} | ||
} | ||
} | ||
attachChild(id, key, child) { | ||
if (this.doc == null) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
_attachChild(id, key, child) { | ||
if (this._doc == null) { | ||
throw new Error("Can't attach child if doc is not present"); | ||
} | ||
const previousValue = this._map.get(key); | ||
const previousValue = __classPrivateFieldGet(this, _LiveMap_map, "f").get(key); | ||
if (previousValue) { | ||
previousValue.detach(); | ||
previousValue._detach(); | ||
} | ||
child.setParent(this); | ||
child.attach(id, this.doc); | ||
this._map.set(key, child); | ||
child._setParent(this); | ||
child._attach(id, this._doc); | ||
__classPrivateFieldGet(this, _LiveMap_map, "f").set(key, child); | ||
this.notify(); | ||
} | ||
detach() { | ||
super.detach(); | ||
for (const item of this._map.values()) { | ||
item.detach(); | ||
/** | ||
* INTERNAL | ||
*/ | ||
_detach() { | ||
super._detach(); | ||
for (const item of __classPrivateFieldGet(this, _LiveMap_map, "f").values()) { | ||
item._detach(); | ||
} | ||
} | ||
detachChild(child) { | ||
for (const [key, value] of this._map) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
_detachChild(child) { | ||
for (const [key, value] of __classPrivateFieldGet(this, _LiveMap_map, "f")) { | ||
if (value === child) { | ||
this._map.delete(key); | ||
__classPrivateFieldGet(this, _LiveMap_map, "f").delete(key); | ||
} | ||
} | ||
child.detach(); | ||
child._detach(); | ||
this.notify(); | ||
} | ||
get(key) { | ||
const value = this._map.get(key); | ||
const value = __classPrivateFieldGet(this, _LiveMap_map, "f").get(key); | ||
if (value == undefined) { | ||
@@ -590,13 +629,13 @@ return undefined; | ||
set(key, value) { | ||
const oldValue = this._map.get(key); | ||
const oldValue = __classPrivateFieldGet(this, _LiveMap_map, "f").get(key); | ||
if (oldValue) { | ||
oldValue.detach(); | ||
oldValue._detach(); | ||
} | ||
const item = selfOrRegister(value); | ||
item.setParent(this); | ||
this._map.set(key, item); | ||
if (this.doc && this.id) { | ||
item.attach(this.doc.generateId(), this.doc); | ||
const ops = item.serialize(this.id, key); | ||
this.doc.dispatch(ops); | ||
item._setParent(this); | ||
__classPrivateFieldGet(this, _LiveMap_map, "f").set(key, item); | ||
if (this._doc && this._id) { | ||
item._attach(this._doc.generateId(), this._doc); | ||
const ops = item._serialize(this._id, key); | ||
this._doc.dispatch(ops); | ||
} | ||
@@ -606,17 +645,17 @@ this.notify(); | ||
get size() { | ||
return this._map.size; | ||
return __classPrivateFieldGet(this, _LiveMap_map, "f").size; | ||
} | ||
has(key) { | ||
return this._map.has(key); | ||
return __classPrivateFieldGet(this, _LiveMap_map, "f").has(key); | ||
} | ||
delete(key) { | ||
const item = this._map.get(key); | ||
const item = __classPrivateFieldGet(this, _LiveMap_map, "f").get(key); | ||
if (item == null) { | ||
return false; | ||
} | ||
item.detach(); | ||
if (this.doc && item.id) { | ||
this.doc.dispatch([{ type: live_1.OpType.DeleteCrdt, id: item.id }]); | ||
item._detach(); | ||
if (this._doc && item._id) { | ||
this._doc.dispatch([{ type: live_1.OpType.DeleteCrdt, id: item._id }]); | ||
} | ||
this._map.delete(key); | ||
__classPrivateFieldGet(this, _LiveMap_map, "f").delete(key); | ||
this.notify(); | ||
@@ -626,3 +665,3 @@ return true; | ||
entries() { | ||
const innerIterator = this._map.entries(); | ||
const innerIterator = __classPrivateFieldGet(this, _LiveMap_map, "f").entries(); | ||
return { | ||
@@ -647,10 +686,10 @@ [Symbol.iterator]: function () { | ||
} | ||
[Symbol.iterator]() { | ||
[(_LiveMap_map = new WeakMap(), Symbol.iterator)]() { | ||
return this.entries(); | ||
} | ||
keys() { | ||
return this._map.keys(); | ||
return __classPrivateFieldGet(this, _LiveMap_map, "f").keys(); | ||
} | ||
values() { | ||
const innerIterator = this._map.values(); | ||
const innerIterator = __classPrivateFieldGet(this, _LiveMap_map, "f").values(); | ||
return { | ||
@@ -684,8 +723,12 @@ [Symbol.iterator]: function () { | ||
super(); | ||
this._data = data; | ||
_LiveRegister_data.set(this, void 0); | ||
__classPrivateFieldSet(this, _LiveRegister_data, data, "f"); | ||
} | ||
get data() { | ||
return this._data; | ||
return __classPrivateFieldGet(this, _LiveRegister_data, "f"); | ||
} | ||
static deserialize([id, item], parentToChildren, doc) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
static _deserialize([id, item], parentToChildren, doc) { | ||
if (item.type !== live_1.CrdtType.Register) { | ||
@@ -695,7 +738,10 @@ throw new Error(`Tried to deserialize a map but item type is "${item.type}"`); | ||
const register = new LiveRegister(item.data); | ||
register.attach(id, doc); | ||
register._attach(id, doc); | ||
return register; | ||
} | ||
serialize(parentId, parentKey) { | ||
if (this.id == null || parentId == null || parentKey == null) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
_serialize(parentId, parentKey) { | ||
if (this._id == null || parentId == null || parentKey == null) { | ||
throw new Error("Cannot serialize register if parentId or parentKey is undefined"); | ||
@@ -705,3 +751,3 @@ } | ||
type: live_1.OpType.CreateRegister, | ||
id: this.id, | ||
id: this._id, | ||
parentId, | ||
@@ -712,3 +758,10 @@ parentKey, | ||
} | ||
_attachChild(id, key, crdt) { | ||
throw new Error("Method not implemented."); | ||
} | ||
_detachChild(crdt) { | ||
throw new Error("Method not implemented."); | ||
} | ||
} | ||
_LiveRegister_data = new WeakMap(); | ||
class LiveList extends AbstractCrdt { | ||
@@ -718,14 +771,17 @@ constructor(items = []) { | ||
// TODO: Naive array at first, find a better data structure | ||
this._items = []; | ||
_LiveList_items.set(this, []); | ||
let position = undefined; | ||
for (let i = 0; i < items.length; i++) { | ||
const newPosition = position_1.makePosition(position); | ||
const newPosition = (0, position_1.makePosition)(position); | ||
const item = selfOrRegister(items[i]); | ||
this._items.push([item, newPosition]); | ||
__classPrivateFieldGet(this, _LiveList_items, "f").push([item, newPosition]); | ||
position = newPosition; | ||
} | ||
} | ||
static deserialize([id, item], parentToChildren, doc) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
static _deserialize([id, item], parentToChildren, doc) { | ||
const list = new LiveList([]); | ||
list.attach(id, doc); | ||
list._attach(id, doc); | ||
const children = parentToChildren.get(id); | ||
@@ -737,10 +793,13 @@ if (children == null) { | ||
const child = deserialize(entry, parentToChildren, doc); | ||
child.setParent(list); | ||
list._items.push([child, entry[1].parentKey]); | ||
list._items.sort((itemA, itemB) => position_1.compare({ position: itemA[1] }, { position: itemB[1] })); | ||
child._setParent(list); | ||
__classPrivateFieldGet(list, _LiveList_items, "f").push([child, entry[1].parentKey]); | ||
__classPrivateFieldGet(list, _LiveList_items, "f").sort((itemA, itemB) => (0, position_1.compare)({ position: itemA[1] }, { position: itemB[1] })); | ||
} | ||
return list; | ||
} | ||
serialize(parentId, parentKey) { | ||
if (this.id == null) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
_serialize(parentId, parentKey) { | ||
if (this._id == null) { | ||
throw new Error("Cannot serialize item is not attached"); | ||
@@ -753,3 +812,3 @@ } | ||
const op = { | ||
id: this.id, | ||
id: this._id, | ||
type: live_1.OpType.CreateList, | ||
@@ -760,75 +819,89 @@ parentId, | ||
ops.push(op); | ||
for (const [value, key] of this._items) { | ||
ops.push(...value.serialize(this.id, key)); | ||
for (const [value, key] of __classPrivateFieldGet(this, _LiveList_items, "f")) { | ||
ops.push(...value._serialize(this._id, key)); | ||
} | ||
return ops; | ||
} | ||
attach(id, doc) { | ||
super.attach(id, doc); | ||
for (const [item, position] of this._items) { | ||
item.attach(doc.generateId(), doc); | ||
/** | ||
* INTERNAL | ||
*/ | ||
_attach(id, doc) { | ||
super._attach(id, doc); | ||
for (const [item, position] of __classPrivateFieldGet(this, _LiveList_items, "f")) { | ||
item._attach(doc.generateId(), doc); | ||
} | ||
} | ||
detach() { | ||
super.detach(); | ||
for (const [value] of this._items) { | ||
value.detach(); | ||
/** | ||
* INTERNAL | ||
*/ | ||
_detach() { | ||
super._detach(); | ||
for (const [value] of __classPrivateFieldGet(this, _LiveList_items, "f")) { | ||
value._detach(); | ||
} | ||
} | ||
attachChild(id, key, child) { | ||
if (this.doc == null) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
_attachChild(id, key, child) { | ||
if (this._doc == null) { | ||
throw new Error("Can't attach child if doc is not present"); | ||
} | ||
child.attach(id, this.doc); | ||
child.setParent(this); | ||
child._attach(id, this._doc); | ||
child._setParent(this); | ||
// TODO: Handle list conflict | ||
this._items.push([child, key]); | ||
this._items.sort((itemA, itemB) => position_1.compare({ position: itemA[1] }, { position: itemB[1] })); | ||
__classPrivateFieldGet(this, _LiveList_items, "f").push([child, key]); | ||
__classPrivateFieldGet(this, _LiveList_items, "f").sort((itemA, itemB) => (0, position_1.compare)({ position: itemA[1] }, { position: itemB[1] })); | ||
this.notify(); | ||
} | ||
detachChild(child) { | ||
const indexToDelete = this._items.findIndex((item) => item[0] === child); | ||
this._items.splice(indexToDelete, 1); | ||
/** | ||
* INTERNAL | ||
*/ | ||
_detachChild(child) { | ||
const indexToDelete = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((item) => item[0] === child); | ||
__classPrivateFieldGet(this, _LiveList_items, "f").splice(indexToDelete, 1); | ||
if (child) { | ||
child.detach(); | ||
child._detach(); | ||
} | ||
this.notify(); | ||
} | ||
setChildKey(key, child) { | ||
const item = this._items.find((item) => item[0] === child); | ||
/** | ||
* INTERNAL | ||
*/ | ||
_setChildKey(key, child) { | ||
const item = __classPrivateFieldGet(this, _LiveList_items, "f").find((item) => item[0] === child); | ||
if (item) { | ||
item[1] = key; | ||
} | ||
this._items.sort((itemA, itemB) => position_1.compare({ position: itemA[1] }, { position: itemB[1] })); | ||
__classPrivateFieldGet(this, _LiveList_items, "f").sort((itemA, itemB) => (0, position_1.compare)({ position: itemA[1] }, { position: itemB[1] })); | ||
this.notify(); | ||
} | ||
apply(op) { } | ||
push(item) { | ||
const position = this._items.length === 0 | ||
? position_1.makePosition() | ||
: position_1.makePosition(this._items[this._items.length - 1][1]); | ||
const position = __classPrivateFieldGet(this, _LiveList_items, "f").length === 0 | ||
? (0, position_1.makePosition)() | ||
: (0, position_1.makePosition)(__classPrivateFieldGet(this, _LiveList_items, "f")[__classPrivateFieldGet(this, _LiveList_items, "f").length - 1][1]); | ||
const value = selfOrRegister(item); | ||
value.setParent(this); | ||
this._items.push([value, position]); | ||
value._setParent(this); | ||
__classPrivateFieldGet(this, _LiveList_items, "f").push([value, position]); | ||
this.notify(); | ||
if (this.doc && this.id) { | ||
value.attach(this.doc.generateId(), this.doc); | ||
this.doc.dispatch(value.serialize(this.id, position)); | ||
if (this._doc && this._id) { | ||
value._attach(this._doc.generateId(), this._doc); | ||
this._doc.dispatch(value._serialize(this._id, position)); | ||
} | ||
} | ||
insert(item, index) { | ||
if (index < 0 || index > this._items.length) { | ||
throw new Error(`Cannot delete list item at index "${index}". index should be between 0 and ${this._items.length}`); | ||
if (index < 0 || index > __classPrivateFieldGet(this, _LiveList_items, "f").length) { | ||
throw new Error(`Cannot delete list item at index "${index}". index should be between 0 and ${__classPrivateFieldGet(this, _LiveList_items, "f").length}`); | ||
} | ||
let before = this._items[index - 1] ? this._items[index - 1][1] : undefined; | ||
let after = this._items[index] ? this._items[index][1] : undefined; | ||
const position = position_1.makePosition(before, after); | ||
let before = __classPrivateFieldGet(this, _LiveList_items, "f")[index - 1] ? __classPrivateFieldGet(this, _LiveList_items, "f")[index - 1][1] : undefined; | ||
let after = __classPrivateFieldGet(this, _LiveList_items, "f")[index] ? __classPrivateFieldGet(this, _LiveList_items, "f")[index][1] : undefined; | ||
const position = (0, position_1.makePosition)(before, after); | ||
const value = selfOrRegister(item); | ||
value.setParent(this); | ||
this._items.push([value, position]); | ||
this._items.sort((itemA, itemB) => position_1.compare({ position: itemA[1] }, { position: itemB[1] })); | ||
value._setParent(this); | ||
__classPrivateFieldGet(this, _LiveList_items, "f").push([value, position]); | ||
__classPrivateFieldGet(this, _LiveList_items, "f").sort((itemA, itemB) => (0, position_1.compare)({ position: itemA[1] }, { position: itemB[1] })); | ||
this.notify(); | ||
if (this.doc && this.id) { | ||
value.attach(this.doc.generateId(), this.doc); | ||
this.doc.dispatch(value.serialize(this.id, position)); | ||
if (this._doc && this._id) { | ||
value._attach(this._doc.generateId(), this._doc); | ||
this._doc.dispatch(value._serialize(this._id, position)); | ||
} | ||
@@ -840,3 +913,3 @@ } | ||
} | ||
if (targetIndex >= this._items.length) { | ||
if (targetIndex >= __classPrivateFieldGet(this, _LiveList_items, "f").length) { | ||
throw new Error("targetIndex cannot be greater or equal than the list length"); | ||
@@ -847,3 +920,3 @@ } | ||
} | ||
if (index >= this._items.length) { | ||
if (index >= __classPrivateFieldGet(this, _LiveList_items, "f").length) { | ||
throw new Error("index cannot be greater or equal than the list length"); | ||
@@ -855,21 +928,21 @@ } | ||
afterPosition = | ||
targetIndex === this._items.length - 1 | ||
targetIndex === __classPrivateFieldGet(this, _LiveList_items, "f").length - 1 | ||
? undefined | ||
: this._items[targetIndex + 1][1]; | ||
beforePosition = this._items[targetIndex][1]; | ||
: __classPrivateFieldGet(this, _LiveList_items, "f")[targetIndex + 1][1]; | ||
beforePosition = __classPrivateFieldGet(this, _LiveList_items, "f")[targetIndex][1]; | ||
} | ||
else { | ||
afterPosition = this._items[targetIndex][1]; | ||
afterPosition = __classPrivateFieldGet(this, _LiveList_items, "f")[targetIndex][1]; | ||
beforePosition = | ||
targetIndex === 0 ? undefined : this._items[targetIndex - 1][1]; | ||
targetIndex === 0 ? undefined : __classPrivateFieldGet(this, _LiveList_items, "f")[targetIndex - 1][1]; | ||
} | ||
const position = position_1.makePosition(beforePosition, afterPosition); | ||
const item = this._items[index]; | ||
const position = (0, position_1.makePosition)(beforePosition, afterPosition); | ||
const item = __classPrivateFieldGet(this, _LiveList_items, "f")[index]; | ||
item[1] = position; | ||
this._items.sort((itemA, itemB) => position_1.compare({ position: itemA[1] }, { position: itemB[1] })); | ||
__classPrivateFieldGet(this, _LiveList_items, "f").sort((itemA, itemB) => (0, position_1.compare)({ position: itemA[1] }, { position: itemB[1] })); | ||
this.notify(); | ||
if (this.doc && this.id) { | ||
this.doc.dispatch([{ | ||
if (this._doc && this._id) { | ||
this._doc.dispatch([{ | ||
type: live_1.OpType.SetParentKey, | ||
id: item[0].id, | ||
id: item[0]._id, | ||
parentKey: position, | ||
@@ -880,12 +953,12 @@ },]); | ||
delete(index) { | ||
if (index < 0 || index >= this._items.length) { | ||
throw new Error(`Cannot delete list item at index "${index}". index should be between 0 and ${this._items.length - 1}`); | ||
if (index < 0 || index >= __classPrivateFieldGet(this, _LiveList_items, "f").length) { | ||
throw new Error(`Cannot delete list item at index "${index}". index should be between 0 and ${__classPrivateFieldGet(this, _LiveList_items, "f").length - 1}`); | ||
} | ||
const item = this._items[index]; | ||
item[0].detach(); | ||
this._items.splice(index, 1); | ||
if (this.doc) { | ||
const childRecordId = item[0].id; | ||
const item = __classPrivateFieldGet(this, _LiveList_items, "f")[index]; | ||
item[0]._detach(); | ||
__classPrivateFieldGet(this, _LiveList_items, "f").splice(index, 1); | ||
if (this._doc) { | ||
const childRecordId = item[0]._id; | ||
if (childRecordId) { | ||
this.doc.dispatch([ | ||
this._doc.dispatch([ | ||
{ | ||
@@ -901,22 +974,23 @@ id: childRecordId, | ||
toArray() { | ||
return this._items.map((entry) => selfOrRegisterValue(entry[0])); | ||
return __classPrivateFieldGet(this, _LiveList_items, "f").map((entry) => selfOrRegisterValue(entry[0])); | ||
} | ||
get(index) { | ||
return selfOrRegisterValue(this._items[index][0]); | ||
return selfOrRegisterValue(__classPrivateFieldGet(this, _LiveList_items, "f")[index][0]); | ||
} | ||
} | ||
exports.LiveList = LiveList; | ||
_LiveList_items = new WeakMap(); | ||
function deserialize(entry, parentToChildren, doc) { | ||
switch (entry[1].type) { | ||
case live_1.CrdtType.Object: { | ||
return LiveObject.deserialize(entry, parentToChildren, doc); | ||
return LiveObject._deserialize(entry, parentToChildren, doc); | ||
} | ||
case live_1.CrdtType.List: { | ||
return LiveList.deserialize(entry, parentToChildren, doc); | ||
return LiveList._deserialize(entry, parentToChildren, doc); | ||
} | ||
case live_1.CrdtType.Map: { | ||
return LiveMap.deserialize(entry, parentToChildren, doc); | ||
return LiveMap._deserialize(entry, parentToChildren, doc); | ||
} | ||
case live_1.CrdtType.Register: { | ||
return LiveRegister.deserialize(entry, parentToChildren, doc); | ||
return LiveRegister._deserialize(entry, parentToChildren, doc); | ||
} | ||
@@ -923,0 +997,0 @@ default: { |
export declare const min = 32; | ||
export declare const max = 127; | ||
export declare const mid = 79; | ||
export declare function middle(a: number, b: number): number; | ||
export declare const max = 126; | ||
export declare function makePosition(before?: string, after?: string): string; | ||
@@ -6,0 +4,0 @@ export declare function posCodes(str: string): number[]; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.compare = exports.pos = exports.posCodes = exports.makePosition = exports.middle = exports.mid = exports.max = exports.min = void 0; | ||
exports.compare = exports.pos = exports.posCodes = exports.makePosition = exports.max = exports.min = void 0; | ||
exports.min = 32; | ||
exports.max = 127; | ||
exports.mid = 79; | ||
function middle(a, b) { | ||
return (a + b) / 2; | ||
} | ||
exports.middle = middle; | ||
exports.max = 126; | ||
function makePosition(before, after) { | ||
@@ -35,3 +30,3 @@ // No children | ||
if (afterCodes.length - 1 === i) { | ||
result.push(exports.max - 1); | ||
result.push(exports.max); | ||
break; | ||
@@ -52,3 +47,3 @@ } | ||
const code = beforeCodes[i]; | ||
if (code === exports.max - 1) { | ||
if (code === exports.max) { | ||
result.push(code); | ||
@@ -86,3 +81,3 @@ if (beforeCodes.length - 1 === i) { | ||
} | ||
const mid = beforeDigit + Math.floor((afterDigit - beforeDigit) / 2); | ||
const mid = (afterDigit + beforeDigit) >> 1; | ||
result.push(mid); | ||
@@ -89,0 +84,0 @@ break; |
import { Others, Presence, ClientOptions, Room, MyPresenceCallback, OthersEventCallback, AuthEndpoint, EventCallback, User, Connection, ErrorCallback, AuthenticationToken, ConnectionCallback } from "./types"; | ||
import { ClientMessage, Op } from "./live"; | ||
import { LiveObject } from "./doc"; | ||
declare type IdFactory = () => string; | ||
@@ -84,6 +85,6 @@ export declare type State = { | ||
getStorage: <TRoot>() => Promise<{ | ||
root: import("./doc").LiveObject<TRoot>; | ||
root: LiveObject<TRoot>; | ||
}>; | ||
selectors: { | ||
getConnectionState: () => "failed" | "closed" | "open" | "connecting" | "authenticating" | "unavailable"; | ||
getConnectionState: () => "failed" | "closed" | "connecting" | "open" | "authenticating" | "unavailable"; | ||
getSelf: <TPresence extends Presence = Presence>() => User<TPresence> | null; | ||
@@ -90,0 +91,0 @@ getPresence: <T_5 extends Presence>() => T_5; |
@@ -77,4 +77,4 @@ "use strict"; | ||
try { | ||
const token = yield authentication_1.default(context.authEndpoint, context.room); | ||
const parsedToken = authentication_1.parseToken(token); | ||
const token = yield (0, authentication_1.default)(context.authEndpoint, context.room); | ||
const parsedToken = (0, authentication_1.parseToken)(token); | ||
const socket = new WebSocket(`${context.liveblocksServer}/?token=${token}`); | ||
@@ -122,3 +122,3 @@ socket.addEventListener("message", onMessage); | ||
const callbacks = state.listeners[event]; | ||
utils_1.remove(callbacks, callback); | ||
(0, utils_1.remove)(callbacks, callback); | ||
} | ||
@@ -125,0 +125,0 @@ function getConnectionState() { |
import { Op, SerializedCrdtWithId, SerializedList } from "./live"; | ||
declare type Dispatch = (ops: Op[]) => void; | ||
export declare class Doc<T extends Record<string, any> = Record<string, any>> { | ||
private _root; | ||
private actor; | ||
private _dispatch; | ||
private _clock; | ||
private _items; | ||
#private; | ||
private constructor(); | ||
@@ -17,10 +13,2 @@ static from<T>(root: T, actor?: number, dispatch?: Dispatch): Doc<T>; | ||
apply(op: Op): void; | ||
private applyCreateRegister; | ||
private applyDeleteRecordKey; | ||
private applyUpdateRecord; | ||
private applyCreateMap; | ||
private applyCreateList; | ||
private applyCreateObject; | ||
private applyDeleteRecord; | ||
private applySetParentKey; | ||
get root(): LiveObject<T>; | ||
@@ -30,14 +18,30 @@ count(): number; | ||
} | ||
declare class AbstractCrdt { | ||
declare abstract class AbstractCrdt { | ||
#private; | ||
private _listeners; | ||
private _deepListeners; | ||
protected get doc(): Doc<Record<string, any>> | undefined; | ||
get id(): string | undefined; | ||
get parent(): AbstractCrdt | undefined; | ||
setParent(parent: AbstractCrdt): void; | ||
attach(id: string, doc: Doc): void; | ||
attachChild(id: string, key: string, crdt: AbstractCrdt): void; | ||
detach(): void; | ||
detachChild(crdt: AbstractCrdt): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
protected get _doc(): Doc<Record<string, any>> | undefined; | ||
/** | ||
* INTERNAL | ||
*/ | ||
get _id(): string | undefined; | ||
/** | ||
* INTERNAL | ||
*/ | ||
get _parent(): AbstractCrdt | undefined; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_setParent(parent: AbstractCrdt): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_attach(id: string, doc: Doc): void; | ||
abstract _attachChild(id: string, key: string, crdt: AbstractCrdt): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_detach(): void; | ||
abstract _detachChild(crdt: AbstractCrdt): void; | ||
subscribe(listener: () => void): void; | ||
@@ -48,6 +52,6 @@ subscribeDeep(listener: () => void): void; | ||
notify(onlyDeep?: boolean): void; | ||
serialize(parentId: string, parentKey: string): Op[]; | ||
abstract _serialize(parentId: string, parentKey: string): Op[]; | ||
} | ||
export declare class LiveObject<T extends Record<string, any> = Record<string, any>> extends AbstractCrdt { | ||
private _map; | ||
#private; | ||
constructor(object?: T); | ||
@@ -57,14 +61,29 @@ /** | ||
*/ | ||
serialize(parentId?: string, parentKey?: string): Op[]; | ||
static deserialize([id, item]: SerializedCrdtWithId, parentToChildren: Map<string, SerializedCrdtWithId[]>, doc: Doc): LiveObject<{ | ||
_serialize(parentId?: string, parentKey?: string): Op[]; | ||
/** | ||
* INTERNAL | ||
*/ | ||
static _deserialize([id, item]: SerializedCrdtWithId, parentToChildren: Map<string, SerializedCrdtWithId[]>, doc: Doc): LiveObject<{ | ||
[key: string]: any; | ||
}>; | ||
attach(id: string, doc: Doc): void; | ||
attachChild(id: string, key: keyof T, child: AbstractCrdt): void; | ||
detachChild(child: AbstractCrdt): void; | ||
detach(): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
apply(op: Op): void; | ||
_attach(id: string, doc: Doc): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_attachChild(id: string, key: keyof T, child: AbstractCrdt): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_detachChild(child: AbstractCrdt): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_detach(): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_apply(op: Op): void; | ||
toObject(): T; | ||
@@ -76,11 +95,28 @@ set<TKey extends keyof T>(key: TKey, value: T[TKey]): void; | ||
export declare class LiveMap<TKey extends string, TValue> extends AbstractCrdt { | ||
private _map; | ||
#private; | ||
constructor(entries?: readonly (readonly [TKey, TValue])[] | null | undefined); | ||
serialize(parentId?: string, parentKey?: string): Op[]; | ||
static deserialize([id, item]: SerializedCrdtWithId, parentToChildren: Map<string, SerializedCrdtWithId[]>, doc: Doc): LiveMap<string, unknown>; | ||
private apply; | ||
attach(id: string, doc: Doc): void; | ||
attachChild(id: string, key: TKey, child: AbstractCrdt): void; | ||
detach(): void; | ||
detachChild(child: AbstractCrdt): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_serialize(parentId?: string, parentKey?: string): Op[]; | ||
/** | ||
* INTERNAL | ||
*/ | ||
static _deserialize([id, item]: SerializedCrdtWithId, parentToChildren: Map<string, SerializedCrdtWithId[]>, doc: Doc): LiveMap<string, unknown>; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_attach(id: string, doc: Doc): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_attachChild(id: string, key: TKey, child: AbstractCrdt): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_detach(): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_detachChild(child: AbstractCrdt): void; | ||
get(key: TKey): TValue | undefined; | ||
@@ -98,12 +134,32 @@ set(key: TKey, value: TValue): void; | ||
export declare class LiveList<T> extends AbstractCrdt { | ||
private _items; | ||
#private; | ||
constructor(items?: T[]); | ||
static deserialize([id, item]: [id: string, item: SerializedList], parentToChildren: Map<string, SerializedCrdtWithId[]>, doc: Doc): LiveList<never>; | ||
serialize(parentId?: string, parentKey?: string): Op[]; | ||
attach(id: string, doc: Doc): void; | ||
detach(): void; | ||
attachChild(id: string, key: string, child: AbstractCrdt): void; | ||
detachChild(child: AbstractCrdt): void; | ||
setChildKey(key: string, child: AbstractCrdt): void; | ||
private apply; | ||
/** | ||
* INTERNAL | ||
*/ | ||
static _deserialize([id, item]: [id: string, item: SerializedList], parentToChildren: Map<string, SerializedCrdtWithId[]>, doc: Doc): LiveList<never>; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_serialize(parentId?: string, parentKey?: string): Op[]; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_attach(id: string, doc: Doc): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_detach(): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_attachChild(id: string, key: string, child: AbstractCrdt): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_detachChild(child: AbstractCrdt): void; | ||
/** | ||
* INTERNAL | ||
*/ | ||
_setChildKey(key: string, child: AbstractCrdt): void; | ||
push(item: T): void; | ||
@@ -110,0 +166,0 @@ insert(item: T, index: number): void; |
@@ -1,27 +0,28 @@ | ||
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) { | ||
if (!privateMap.has(receiver)) { | ||
throw new TypeError("attempted to get private field on non-instance"); | ||
} | ||
return privateMap.get(receiver); | ||
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { | ||
if (kind === "m") throw new TypeError("Private method is not writable"); | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); | ||
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; | ||
}; | ||
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) { | ||
if (!privateMap.has(receiver)) { | ||
throw new TypeError("attempted to set private field on non-instance"); | ||
} | ||
privateMap.set(receiver, value); | ||
return value; | ||
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); | ||
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); | ||
}; | ||
var _parent, _doc, _id; | ||
var _Doc_instances, _Doc_clock, _Doc_items, _Doc_root, _Doc_actor, _Doc_dispatch, _Doc_applyCreateRegister, _Doc_applyDeleteRecordKey, _Doc_applyUpdateRecord, _Doc_applyCreateMap, _Doc_applyCreateList, _Doc_applyCreateObject, _Doc_applyDeleteRecord, _Doc_applySetParentKey, _AbstractCrdt_listeners, _AbstractCrdt_deepListeners, _AbstractCrdt_parent, _AbstractCrdt_doc, _AbstractCrdt_id, _LiveObject_map, _LiveMap_map, _LiveRegister_data, _LiveList_items; | ||
import { remove } from "./utils"; | ||
import { CrdtType, OpType, } from "./live"; | ||
import { compare, makePosition } from "./position"; | ||
const INTERNAL = Symbol("liveblocks.internal"); | ||
function noOp() { } | ||
export class Doc { | ||
constructor(_root, actor = 0, _dispatch = noOp) { | ||
this._root = _root; | ||
this.actor = actor; | ||
this._dispatch = _dispatch; | ||
this._clock = 0; | ||
this._items = new Map(); | ||
constructor(root, actor = 0, dispatch = noOp) { | ||
_Doc_instances.add(this); | ||
_Doc_clock.set(this, 0); | ||
_Doc_items.set(this, new Map()); | ||
_Doc_root.set(this, void 0); | ||
_Doc_actor.set(this, void 0); | ||
_Doc_dispatch.set(this, void 0); | ||
__classPrivateFieldSet(this, _Doc_root, root, "f"); | ||
__classPrivateFieldSet(this, _Doc_actor, actor, "f"); | ||
__classPrivateFieldSet(this, _Doc_dispatch, dispatch, "f"); | ||
} | ||
@@ -31,4 +32,4 @@ static from(root, actor = 0, dispatch = noOp) { | ||
const storage = new Doc(rootRecord, actor, dispatch); | ||
rootRecord.attach(storage.generateId(), storage); | ||
storage.dispatch(rootRecord.serialize()); | ||
rootRecord._attach(storage.generateId(), storage); | ||
storage.dispatch(rootRecord._serialize()); | ||
return storage; | ||
@@ -61,16 +62,16 @@ } | ||
const doc = new Doc(null, actor, dispatch); | ||
doc._root = LiveObject.deserialize(root, parentToChildren, doc); | ||
__classPrivateFieldSet(doc, _Doc_root, LiveObject._deserialize(root, parentToChildren, doc), "f"); | ||
return doc; | ||
} | ||
dispatch(ops) { | ||
this._dispatch(ops); | ||
__classPrivateFieldGet(this, _Doc_dispatch, "f").call(this, ops); | ||
} | ||
addItem(id, item) { | ||
this._items.set(id, item); | ||
__classPrivateFieldGet(this, _Doc_items, "f").set(id, item); | ||
} | ||
deleteItem(id) { | ||
this._items.delete(id); | ||
__classPrivateFieldGet(this, _Doc_items, "f").delete(id); | ||
} | ||
getItem(id) { | ||
return this._items.get(id); | ||
return __classPrivateFieldGet(this, _Doc_items, "f").get(id); | ||
} | ||
@@ -80,31 +81,31 @@ apply(op) { | ||
case OpType.UpdateObject: { | ||
this.applyUpdateRecord(op); | ||
__classPrivateFieldGet(this, _Doc_instances, "m", _Doc_applyUpdateRecord).call(this, op); | ||
break; | ||
} | ||
case OpType.CreateObject: { | ||
this.applyCreateObject(op); | ||
__classPrivateFieldGet(this, _Doc_instances, "m", _Doc_applyCreateObject).call(this, op); | ||
break; | ||
} | ||
case OpType.CreateMap: { | ||
this.applyCreateMap(op); | ||
__classPrivateFieldGet(this, _Doc_instances, "m", _Doc_applyCreateMap).call(this, op); | ||
break; | ||
} | ||
case OpType.CreateList: { | ||
this.applyCreateList(op); | ||
__classPrivateFieldGet(this, _Doc_instances, "m", _Doc_applyCreateList).call(this, op); | ||
break; | ||
} | ||
case OpType.DeleteCrdt: { | ||
this.applyDeleteRecord(op); | ||
__classPrivateFieldGet(this, _Doc_instances, "m", _Doc_applyDeleteRecord).call(this, op); | ||
break; | ||
} | ||
case OpType.SetParentKey: { | ||
this.applySetParentKey(op); | ||
__classPrivateFieldGet(this, _Doc_instances, "m", _Doc_applySetParentKey).call(this, op); | ||
break; | ||
} | ||
case OpType.DeleteObjectKey: { | ||
this.applyDeleteRecordKey(op); | ||
__classPrivateFieldGet(this, _Doc_instances, "m", _Doc_applyDeleteRecordKey).call(this, op); | ||
break; | ||
} | ||
case OpType.CreateRegister: { | ||
this.applyCreateRegister(op); | ||
__classPrivateFieldGet(this, _Doc_instances, "m", _Doc_applyCreateRegister).call(this, op); | ||
break; | ||
@@ -114,170 +115,174 @@ } | ||
} | ||
applyCreateRegister(op) { | ||
const parent = this._items.get(op.parentId); | ||
if (parent == null) { | ||
return; | ||
} | ||
if (!(parent instanceof LiveMap) && !(parent instanceof LiveList)) { | ||
throw new Error("LiveRegister can only be attached to a LiveMap or LiveList"); | ||
} | ||
const newRegister = new LiveRegister(op.data); | ||
parent.attachChild(op.id, op.parentKey, newRegister); | ||
get root() { | ||
return __classPrivateFieldGet(this, _Doc_root, "f"); | ||
} | ||
applyDeleteRecordKey(op) { | ||
const item = this._items.get(op.id); | ||
if (item && item instanceof LiveObject) { | ||
item.apply(op); | ||
} | ||
count() { | ||
return __classPrivateFieldGet(this, _Doc_items, "f").size; | ||
} | ||
applyUpdateRecord(op) { | ||
const item = this._items.get(op.id); | ||
if (item && item instanceof LiveObject) { | ||
item.apply(op); | ||
} | ||
generateId() { | ||
var _a, _b; | ||
return `${__classPrivateFieldGet(this, _Doc_actor, "f")}:${__classPrivateFieldSet(this, _Doc_clock, (_b = __classPrivateFieldGet(this, _Doc_clock, "f"), _a = _b++, _b), "f"), _a}`; | ||
} | ||
applyCreateMap(op) { | ||
const parent = this._items.get(op.parentId); | ||
if (parent == null) { | ||
return; | ||
} | ||
const newMap = new LiveMap(); | ||
parent.attachChild(op.id, op.parentKey, newMap); | ||
} | ||
_Doc_clock = new WeakMap(), _Doc_items = new WeakMap(), _Doc_root = new WeakMap(), _Doc_actor = new WeakMap(), _Doc_dispatch = new WeakMap(), _Doc_instances = new WeakSet(), _Doc_applyCreateRegister = function _Doc_applyCreateRegister(op) { | ||
const parent = __classPrivateFieldGet(this, _Doc_items, "f").get(op.parentId); | ||
if (parent == null) { | ||
return; | ||
} | ||
applyCreateList(op) { | ||
const parent = this._items.get(op.parentId); | ||
if (parent == null) { | ||
return; | ||
} | ||
const list = new LiveList(); | ||
parent.attachChild(op.id, op.parentKey, list); | ||
if (!(parent instanceof LiveMap) && !(parent instanceof LiveList)) { | ||
throw new Error("LiveRegister can only be attached to a LiveMap or LiveList"); | ||
} | ||
applyCreateObject(op) { | ||
if (op.parentId && op.parentKey) { | ||
const parent = this._items.get(op.parentId); | ||
if (parent == null) { | ||
return; | ||
} | ||
const newObj = new LiveObject(op.data); | ||
parent.attachChild(op.id, op.parentKey, newObj); | ||
} | ||
const newRegister = new LiveRegister(op.data); | ||
parent._attachChild(op.id, op.parentKey, newRegister); | ||
}, _Doc_applyDeleteRecordKey = function _Doc_applyDeleteRecordKey(op) { | ||
const item = __classPrivateFieldGet(this, _Doc_items, "f").get(op.id); | ||
if (item && item instanceof LiveObject) { | ||
item._apply(op); | ||
} | ||
applyDeleteRecord(op) { | ||
const item = this._items.get(op.id); | ||
if (item == null) { | ||
return; | ||
} | ||
const parent = item.parent; | ||
}, _Doc_applyUpdateRecord = function _Doc_applyUpdateRecord(op) { | ||
const item = __classPrivateFieldGet(this, _Doc_items, "f").get(op.id); | ||
if (item && item instanceof LiveObject) { | ||
item._apply(op); | ||
} | ||
}, _Doc_applyCreateMap = function _Doc_applyCreateMap(op) { | ||
const parent = __classPrivateFieldGet(this, _Doc_items, "f").get(op.parentId); | ||
if (parent == null) { | ||
return; | ||
} | ||
const newMap = new LiveMap(); | ||
parent._attachChild(op.id, op.parentKey, newMap); | ||
}, _Doc_applyCreateList = function _Doc_applyCreateList(op) { | ||
const parent = __classPrivateFieldGet(this, _Doc_items, "f").get(op.parentId); | ||
if (parent == null) { | ||
return; | ||
} | ||
const list = new LiveList(); | ||
parent._attachChild(op.id, op.parentKey, list); | ||
}, _Doc_applyCreateObject = function _Doc_applyCreateObject(op) { | ||
if (op.parentId && op.parentKey) { | ||
const parent = __classPrivateFieldGet(this, _Doc_items, "f").get(op.parentId); | ||
if (parent == null) { | ||
return; | ||
} | ||
if (parent) { | ||
parent.detachChild(item); | ||
} | ||
const newObj = new LiveObject(op.data); | ||
parent._attachChild(op.id, op.parentKey, newObj); | ||
} | ||
applySetParentKey(op) { | ||
const item = this._items.get(op.id); | ||
if (item == null) { | ||
return; | ||
} | ||
if (item.parent == null) { | ||
return; | ||
} | ||
if (item.parent instanceof LiveList) { | ||
item.parent.setChildKey(op.parentKey, item); | ||
} | ||
}, _Doc_applyDeleteRecord = function _Doc_applyDeleteRecord(op) { | ||
const item = __classPrivateFieldGet(this, _Doc_items, "f").get(op.id); | ||
if (item == null) { | ||
return; | ||
} | ||
get root() { | ||
return this._root; | ||
const parent = item._parent; | ||
if (parent == null) { | ||
return; | ||
} | ||
count() { | ||
return this._items.size; | ||
if (parent) { | ||
parent._detachChild(item); | ||
} | ||
generateId() { | ||
return `${this.actor}:${this._clock++}`; | ||
}, _Doc_applySetParentKey = function _Doc_applySetParentKey(op) { | ||
const item = __classPrivateFieldGet(this, _Doc_items, "f").get(op.id); | ||
if (item == null) { | ||
return; | ||
} | ||
} | ||
if (item._parent == null) { | ||
return; | ||
} | ||
if (item._parent instanceof LiveList) { | ||
item._parent._setChildKey(op.parentKey, item); | ||
} | ||
}; | ||
class AbstractCrdt { | ||
constructor() { | ||
this._listeners = []; | ||
this._deepListeners = []; | ||
_parent.set(this, void 0); | ||
_doc.set(this, void 0); | ||
_id.set(this, void 0); | ||
_AbstractCrdt_listeners.set(this, []); | ||
_AbstractCrdt_deepListeners.set(this, []); | ||
_AbstractCrdt_parent.set(this, void 0); | ||
_AbstractCrdt_doc.set(this, void 0); | ||
_AbstractCrdt_id.set(this, void 0); | ||
} | ||
get doc() { | ||
return __classPrivateFieldGet(this, _doc); | ||
/** | ||
* INTERNAL | ||
*/ | ||
get _doc() { | ||
return __classPrivateFieldGet(this, _AbstractCrdt_doc, "f"); | ||
} | ||
get id() { | ||
return __classPrivateFieldGet(this, _id); | ||
/** | ||
* INTERNAL | ||
*/ | ||
get _id() { | ||
return __classPrivateFieldGet(this, _AbstractCrdt_id, "f"); | ||
} | ||
get parent() { | ||
return __classPrivateFieldGet(this, _parent); | ||
/** | ||
* INTERNAL | ||
*/ | ||
get _parent() { | ||
return __classPrivateFieldGet(this, _AbstractCrdt_parent, "f"); | ||
} | ||
setParent(parent) { | ||
if (__classPrivateFieldGet(this, _parent)) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
_setParent(parent) { | ||
if (__classPrivateFieldGet(this, _AbstractCrdt_parent, "f")) { | ||
throw new Error("Cannot attach parent if it already exist"); | ||
} | ||
__classPrivateFieldSet(this, _parent, parent); | ||
__classPrivateFieldSet(this, _AbstractCrdt_parent, parent, "f"); | ||
} | ||
attach(id, doc) { | ||
if (__classPrivateFieldGet(this, _id) || __classPrivateFieldGet(this, _doc)) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
_attach(id, doc) { | ||
if (__classPrivateFieldGet(this, _AbstractCrdt_id, "f") || __classPrivateFieldGet(this, _AbstractCrdt_doc, "f")) { | ||
throw new Error("Cannot attach if CRDT is already attached"); | ||
} | ||
doc.addItem(id, this); | ||
__classPrivateFieldSet(this, _id, id); | ||
__classPrivateFieldSet(this, _doc, doc); | ||
__classPrivateFieldSet(this, _AbstractCrdt_id, id, "f"); | ||
__classPrivateFieldSet(this, _AbstractCrdt_doc, doc, "f"); | ||
} | ||
attachChild(id, key, crdt) { | ||
throw new Error("attachChild should be implement by a non abstract CRDT"); | ||
} | ||
detach() { | ||
if (__classPrivateFieldGet(this, _doc) && __classPrivateFieldGet(this, _id)) { | ||
__classPrivateFieldGet(this, _doc).deleteItem(__classPrivateFieldGet(this, _id)); | ||
/** | ||
* INTERNAL | ||
*/ | ||
_detach() { | ||
if (__classPrivateFieldGet(this, _AbstractCrdt_doc, "f") && __classPrivateFieldGet(this, _AbstractCrdt_id, "f")) { | ||
__classPrivateFieldGet(this, _AbstractCrdt_doc, "f").deleteItem(__classPrivateFieldGet(this, _AbstractCrdt_id, "f")); | ||
} | ||
__classPrivateFieldSet(this, _parent, undefined); | ||
__classPrivateFieldSet(this, _doc, undefined); | ||
__classPrivateFieldSet(this, _AbstractCrdt_parent, undefined, "f"); | ||
__classPrivateFieldSet(this, _AbstractCrdt_doc, undefined, "f"); | ||
} | ||
detachChild(crdt) { | ||
throw new Error("detach child should be implement by a non abstract CRDT"); | ||
} | ||
subscribe(listener) { | ||
this._listeners.push(listener); | ||
__classPrivateFieldGet(this, _AbstractCrdt_listeners, "f").push(listener); | ||
} | ||
subscribeDeep(listener) { | ||
this._deepListeners.push(listener); | ||
__classPrivateFieldGet(this, _AbstractCrdt_deepListeners, "f").push(listener); | ||
} | ||
unsubscribe(listener) { | ||
remove(this._listeners, listener); | ||
remove(__classPrivateFieldGet(this, _AbstractCrdt_listeners, "f"), listener); | ||
} | ||
unsubscribeDeep(listener) { | ||
remove(this._deepListeners, listener); | ||
remove(__classPrivateFieldGet(this, _AbstractCrdt_deepListeners, "f"), listener); | ||
} | ||
notify(onlyDeep = false) { | ||
if (onlyDeep === false) { | ||
for (const listener of this._listeners) { | ||
for (const listener of __classPrivateFieldGet(this, _AbstractCrdt_listeners, "f")) { | ||
listener(); | ||
} | ||
} | ||
for (const listener of this._deepListeners) { | ||
for (const listener of __classPrivateFieldGet(this, _AbstractCrdt_deepListeners, "f")) { | ||
listener(); | ||
} | ||
if (this.parent) { | ||
this.parent.notify(true); | ||
if (this._parent) { | ||
this._parent.notify(true); | ||
} | ||
} | ||
serialize(parentId, parentKey) { | ||
throw new Error("serialize should be implement by a non abstract CRDT"); | ||
} | ||
} | ||
_parent = new WeakMap(), _doc = new WeakMap(), _id = new WeakMap(); | ||
_AbstractCrdt_listeners = new WeakMap(), _AbstractCrdt_deepListeners = new WeakMap(), _AbstractCrdt_parent = new WeakMap(), _AbstractCrdt_doc = new WeakMap(), _AbstractCrdt_id = new WeakMap(); | ||
export class LiveObject extends AbstractCrdt { | ||
constructor(object = {}) { | ||
super(); | ||
_LiveObject_map.set(this, void 0); | ||
for (const key in object) { | ||
const value = object[key]; | ||
if (value instanceof AbstractCrdt) { | ||
value.setParent(this); | ||
value._setParent(this); | ||
} | ||
} | ||
this._map = new Map(Object.entries(object)); | ||
__classPrivateFieldSet(this, _LiveObject_map, new Map(Object.entries(object)), "f"); | ||
} | ||
@@ -287,4 +292,4 @@ /** | ||
*/ | ||
serialize(parentId, parentKey) { | ||
if (this.id == null) { | ||
_serialize(parentId, parentKey) { | ||
if (this._id == null) { | ||
throw new Error("Cannot serialize item is not attached"); | ||
@@ -294,3 +299,3 @@ } | ||
const op = { | ||
id: this.id, | ||
id: this._id, | ||
type: OpType.CreateObject, | ||
@@ -302,5 +307,5 @@ parentId, | ||
ops.push(op); | ||
for (const [key, value] of this._map) { | ||
for (const [key, value] of __classPrivateFieldGet(this, _LiveObject_map, "f")) { | ||
if (value instanceof AbstractCrdt) { | ||
ops.push(...value.serialize(this.id, key)); | ||
ops.push(...value._serialize(this._id, key)); | ||
} | ||
@@ -313,3 +318,6 @@ else { | ||
} | ||
static deserialize([id, item], parentToChildren, doc) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
static _deserialize([id, item], parentToChildren, doc) { | ||
if (item.type !== CrdtType.Object) { | ||
@@ -319,3 +327,3 @@ throw new Error(`Tried to deserialize a record but item type is "${item.type}"`); | ||
const object = new LiveObject(item.data); | ||
object.attach(id, doc); | ||
object._attach(id, doc); | ||
const children = parentToChildren.get(id); | ||
@@ -331,44 +339,56 @@ if (children == null) { | ||
const child = deserialize(entry, parentToChildren, doc); | ||
child.setParent(object); | ||
object._map.set(crdt.parentKey, child); | ||
child._setParent(object); | ||
__classPrivateFieldGet(object, _LiveObject_map, "f").set(crdt.parentKey, child); | ||
} | ||
return object; | ||
} | ||
attach(id, doc) { | ||
super.attach(id, doc); | ||
for (const [key, value] of this._map) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
_attach(id, doc) { | ||
super._attach(id, doc); | ||
for (const [key, value] of __classPrivateFieldGet(this, _LiveObject_map, "f")) { | ||
if (value instanceof AbstractCrdt) { | ||
value.attach(doc.generateId(), doc); | ||
value._attach(doc.generateId(), doc); | ||
} | ||
} | ||
} | ||
attachChild(id, key, child) { | ||
if (this.doc == null) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
_attachChild(id, key, child) { | ||
if (this._doc == null) { | ||
throw new Error("Can't attach child if doc is not present"); | ||
} | ||
const previousValue = this._map.get(key); | ||
const previousValue = __classPrivateFieldGet(this, _LiveObject_map, "f").get(key); | ||
if (isCrdt(previousValue)) { | ||
previousValue.detach(); | ||
previousValue._detach(); | ||
} | ||
this._map.set(key, child); | ||
child.setParent(this); | ||
child.attach(id, this.doc); | ||
__classPrivateFieldGet(this, _LiveObject_map, "f").set(key, child); | ||
child._setParent(this); | ||
child._attach(id, this._doc); | ||
this.notify(); | ||
} | ||
detachChild(child) { | ||
for (const [key, value] of this._map) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
_detachChild(child) { | ||
for (const [key, value] of __classPrivateFieldGet(this, _LiveObject_map, "f")) { | ||
if (value === child) { | ||
this._map.delete(key); | ||
__classPrivateFieldGet(this, _LiveObject_map, "f").delete(key); | ||
} | ||
} | ||
if (child) { | ||
child.detach(); | ||
child._detach(); | ||
} | ||
this.notify(); | ||
} | ||
detach() { | ||
super.detach(); | ||
for (const value of this._map.values()) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
_detach() { | ||
super._detach(); | ||
for (const value of __classPrivateFieldGet(this, _LiveObject_map, "f").values()) { | ||
if (isCrdt(value)) { | ||
value.detach(); | ||
value._detach(); | ||
} | ||
@@ -380,11 +400,11 @@ } | ||
*/ | ||
apply(op) { | ||
_apply(op) { | ||
if (op.type === OpType.UpdateObject) { | ||
for (const key in op.data) { | ||
const oldValue = this._map.get(key); | ||
const oldValue = __classPrivateFieldGet(this, _LiveObject_map, "f").get(key); | ||
if (isCrdt(oldValue)) { | ||
oldValue.detach(); | ||
oldValue._detach(); | ||
} | ||
const value = op.data[key]; | ||
this._map.set(key, value); | ||
__classPrivateFieldGet(this, _LiveObject_map, "f").set(key, value); | ||
} | ||
@@ -395,7 +415,7 @@ this.notify(); | ||
const key = op.key; | ||
const oldValue = this._map.get(key); | ||
const oldValue = __classPrivateFieldGet(this, _LiveObject_map, "f").get(key); | ||
if (isCrdt(oldValue)) { | ||
oldValue.detach(); | ||
oldValue._detach(); | ||
} | ||
this._map.delete(key); | ||
__classPrivateFieldGet(this, _LiveObject_map, "f").delete(key); | ||
this.notify(); | ||
@@ -405,3 +425,3 @@ } | ||
toObject() { | ||
return Object.fromEntries(this._map); | ||
return Object.fromEntries(__classPrivateFieldGet(this, _LiveObject_map, "f")); | ||
} | ||
@@ -413,3 +433,3 @@ set(key, value) { | ||
get(key) { | ||
return this._map.get(key); | ||
return __classPrivateFieldGet(this, _LiveObject_map, "f").get(key); | ||
} | ||
@@ -430,6 +450,6 @@ // delete<TKey extends keyof T>(key: TKey) { | ||
update(overrides) { | ||
if (this.doc && this.id) { | ||
if (this._doc && this._id) { | ||
const ops = []; | ||
const updateOp = { | ||
id: this.id, | ||
id: this._id, | ||
type: OpType.UpdateObject, | ||
@@ -440,11 +460,11 @@ data: {} | ||
for (const key in overrides) { | ||
const oldValue = this._map.get(key); | ||
const oldValue = __classPrivateFieldGet(this, _LiveObject_map, "f").get(key); | ||
if (oldValue instanceof LiveObject) { | ||
oldValue.detach(); | ||
oldValue._detach(); | ||
} | ||
const newValue = overrides[key]; | ||
if (newValue instanceof AbstractCrdt) { | ||
newValue.setParent(this); | ||
newValue.attach(this.doc.generateId(), this.doc); | ||
ops.push(...newValue.serialize(this.id, key)); | ||
newValue._setParent(this); | ||
newValue._attach(this._doc.generateId(), this._doc); | ||
ops.push(...newValue._serialize(this._id, key)); | ||
} | ||
@@ -454,5 +474,5 @@ else { | ||
} | ||
this._map.set(key, newValue); | ||
__classPrivateFieldGet(this, _LiveObject_map, "f").set(key, newValue); | ||
} | ||
this.doc.dispatch(ops); | ||
this._doc.dispatch(ops); | ||
this.notify(); | ||
@@ -462,11 +482,11 @@ return; | ||
for (const key in overrides) { | ||
const oldValue = this._map.get(key); | ||
const oldValue = __classPrivateFieldGet(this, _LiveObject_map, "f").get(key); | ||
if (oldValue instanceof AbstractCrdt) { | ||
oldValue.detach(); | ||
oldValue._detach(); | ||
} | ||
const newValue = overrides[key]; | ||
if (newValue instanceof AbstractCrdt) { | ||
newValue.setParent(this); | ||
newValue._setParent(this); | ||
} | ||
this._map.set(key, newValue); | ||
__classPrivateFieldGet(this, _LiveObject_map, "f").set(key, newValue); | ||
} | ||
@@ -476,5 +496,7 @@ this.notify(); | ||
} | ||
_LiveObject_map = new WeakMap(); | ||
export class LiveMap extends AbstractCrdt { | ||
constructor(entries) { | ||
super(); | ||
_LiveMap_map.set(this, void 0); | ||
if (entries) { | ||
@@ -484,13 +506,16 @@ const mappedEntries = []; | ||
const value = selfOrRegister(entry[1]); | ||
value.setParent(this); | ||
value._setParent(this); | ||
mappedEntries.push([entry[0], value]); | ||
} | ||
this._map = new Map(mappedEntries); | ||
__classPrivateFieldSet(this, _LiveMap_map, new Map(mappedEntries), "f"); | ||
} | ||
else { | ||
this._map = new Map(); | ||
__classPrivateFieldSet(this, _LiveMap_map, new Map(), "f"); | ||
} | ||
} | ||
serialize(parentId, parentKey) { | ||
if (this.id == null) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
_serialize(parentId, parentKey) { | ||
if (this._id == null) { | ||
throw new Error("Cannot serialize item is not attached"); | ||
@@ -503,3 +528,3 @@ } | ||
const op = { | ||
id: this.id, | ||
id: this._id, | ||
type: OpType.CreateMap, | ||
@@ -510,8 +535,11 @@ parentId, | ||
ops.push(op); | ||
for (const [key, value] of this._map) { | ||
ops.push(...value.serialize(this.id, key)); | ||
for (const [key, value] of __classPrivateFieldGet(this, _LiveMap_map, "f")) { | ||
ops.push(...value._serialize(this._id, key)); | ||
} | ||
return ops; | ||
} | ||
static deserialize([id, item], parentToChildren, doc) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
static _deserialize([id, item], parentToChildren, doc) { | ||
if (item.type !== CrdtType.Map) { | ||
@@ -521,3 +549,3 @@ throw new Error(`Tried to deserialize a map but item type is "${item.type}"`); | ||
const map = new LiveMap(); | ||
map.attach(id, doc); | ||
map._attach(id, doc); | ||
const children = parentToChildren.get(id); | ||
@@ -533,46 +561,57 @@ if (children == null) { | ||
const child = deserialize(entry, parentToChildren, doc); | ||
child.setParent(map); | ||
map._map.set(crdt.parentKey, child); | ||
child._setParent(map); | ||
__classPrivateFieldGet(map, _LiveMap_map, "f").set(crdt.parentKey, child); | ||
} | ||
return map; | ||
} | ||
apply(op) { } | ||
attach(id, doc) { | ||
super.attach(id, doc); | ||
for (const [key, value] of this._map) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
_attach(id, doc) { | ||
super._attach(id, doc); | ||
for (const [key, value] of __classPrivateFieldGet(this, _LiveMap_map, "f")) { | ||
if (isCrdt(value)) { | ||
value.attach(doc.generateId(), doc); | ||
value._attach(doc.generateId(), doc); | ||
} | ||
} | ||
} | ||
attachChild(id, key, child) { | ||
if (this.doc == null) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
_attachChild(id, key, child) { | ||
if (this._doc == null) { | ||
throw new Error("Can't attach child if doc is not present"); | ||
} | ||
const previousValue = this._map.get(key); | ||
const previousValue = __classPrivateFieldGet(this, _LiveMap_map, "f").get(key); | ||
if (previousValue) { | ||
previousValue.detach(); | ||
previousValue._detach(); | ||
} | ||
child.setParent(this); | ||
child.attach(id, this.doc); | ||
this._map.set(key, child); | ||
child._setParent(this); | ||
child._attach(id, this._doc); | ||
__classPrivateFieldGet(this, _LiveMap_map, "f").set(key, child); | ||
this.notify(); | ||
} | ||
detach() { | ||
super.detach(); | ||
for (const item of this._map.values()) { | ||
item.detach(); | ||
/** | ||
* INTERNAL | ||
*/ | ||
_detach() { | ||
super._detach(); | ||
for (const item of __classPrivateFieldGet(this, _LiveMap_map, "f").values()) { | ||
item._detach(); | ||
} | ||
} | ||
detachChild(child) { | ||
for (const [key, value] of this._map) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
_detachChild(child) { | ||
for (const [key, value] of __classPrivateFieldGet(this, _LiveMap_map, "f")) { | ||
if (value === child) { | ||
this._map.delete(key); | ||
__classPrivateFieldGet(this, _LiveMap_map, "f").delete(key); | ||
} | ||
} | ||
child.detach(); | ||
child._detach(); | ||
this.notify(); | ||
} | ||
get(key) { | ||
const value = this._map.get(key); | ||
const value = __classPrivateFieldGet(this, _LiveMap_map, "f").get(key); | ||
if (value == undefined) { | ||
@@ -584,13 +623,13 @@ return undefined; | ||
set(key, value) { | ||
const oldValue = this._map.get(key); | ||
const oldValue = __classPrivateFieldGet(this, _LiveMap_map, "f").get(key); | ||
if (oldValue) { | ||
oldValue.detach(); | ||
oldValue._detach(); | ||
} | ||
const item = selfOrRegister(value); | ||
item.setParent(this); | ||
this._map.set(key, item); | ||
if (this.doc && this.id) { | ||
item.attach(this.doc.generateId(), this.doc); | ||
const ops = item.serialize(this.id, key); | ||
this.doc.dispatch(ops); | ||
item._setParent(this); | ||
__classPrivateFieldGet(this, _LiveMap_map, "f").set(key, item); | ||
if (this._doc && this._id) { | ||
item._attach(this._doc.generateId(), this._doc); | ||
const ops = item._serialize(this._id, key); | ||
this._doc.dispatch(ops); | ||
} | ||
@@ -600,17 +639,17 @@ this.notify(); | ||
get size() { | ||
return this._map.size; | ||
return __classPrivateFieldGet(this, _LiveMap_map, "f").size; | ||
} | ||
has(key) { | ||
return this._map.has(key); | ||
return __classPrivateFieldGet(this, _LiveMap_map, "f").has(key); | ||
} | ||
delete(key) { | ||
const item = this._map.get(key); | ||
const item = __classPrivateFieldGet(this, _LiveMap_map, "f").get(key); | ||
if (item == null) { | ||
return false; | ||
} | ||
item.detach(); | ||
if (this.doc && item.id) { | ||
this.doc.dispatch([{ type: OpType.DeleteCrdt, id: item.id }]); | ||
item._detach(); | ||
if (this._doc && item._id) { | ||
this._doc.dispatch([{ type: OpType.DeleteCrdt, id: item._id }]); | ||
} | ||
this._map.delete(key); | ||
__classPrivateFieldGet(this, _LiveMap_map, "f").delete(key); | ||
this.notify(); | ||
@@ -620,3 +659,3 @@ return true; | ||
entries() { | ||
const innerIterator = this._map.entries(); | ||
const innerIterator = __classPrivateFieldGet(this, _LiveMap_map, "f").entries(); | ||
return { | ||
@@ -641,10 +680,10 @@ [Symbol.iterator]: function () { | ||
} | ||
[Symbol.iterator]() { | ||
[(_LiveMap_map = new WeakMap(), Symbol.iterator)]() { | ||
return this.entries(); | ||
} | ||
keys() { | ||
return this._map.keys(); | ||
return __classPrivateFieldGet(this, _LiveMap_map, "f").keys(); | ||
} | ||
values() { | ||
const innerIterator = this._map.values(); | ||
const innerIterator = __classPrivateFieldGet(this, _LiveMap_map, "f").values(); | ||
return { | ||
@@ -677,8 +716,12 @@ [Symbol.iterator]: function () { | ||
super(); | ||
this._data = data; | ||
_LiveRegister_data.set(this, void 0); | ||
__classPrivateFieldSet(this, _LiveRegister_data, data, "f"); | ||
} | ||
get data() { | ||
return this._data; | ||
return __classPrivateFieldGet(this, _LiveRegister_data, "f"); | ||
} | ||
static deserialize([id, item], parentToChildren, doc) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
static _deserialize([id, item], parentToChildren, doc) { | ||
if (item.type !== CrdtType.Register) { | ||
@@ -688,7 +731,10 @@ throw new Error(`Tried to deserialize a map but item type is "${item.type}"`); | ||
const register = new LiveRegister(item.data); | ||
register.attach(id, doc); | ||
register._attach(id, doc); | ||
return register; | ||
} | ||
serialize(parentId, parentKey) { | ||
if (this.id == null || parentId == null || parentKey == null) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
_serialize(parentId, parentKey) { | ||
if (this._id == null || parentId == null || parentKey == null) { | ||
throw new Error("Cannot serialize register if parentId or parentKey is undefined"); | ||
@@ -698,3 +744,3 @@ } | ||
type: OpType.CreateRegister, | ||
id: this.id, | ||
id: this._id, | ||
parentId, | ||
@@ -705,3 +751,10 @@ parentKey, | ||
} | ||
_attachChild(id, key, crdt) { | ||
throw new Error("Method not implemented."); | ||
} | ||
_detachChild(crdt) { | ||
throw new Error("Method not implemented."); | ||
} | ||
} | ||
_LiveRegister_data = new WeakMap(); | ||
export class LiveList extends AbstractCrdt { | ||
@@ -711,3 +764,3 @@ constructor(items = []) { | ||
// TODO: Naive array at first, find a better data structure | ||
this._items = []; | ||
_LiveList_items.set(this, []); | ||
let position = undefined; | ||
@@ -717,9 +770,12 @@ for (let i = 0; i < items.length; i++) { | ||
const item = selfOrRegister(items[i]); | ||
this._items.push([item, newPosition]); | ||
__classPrivateFieldGet(this, _LiveList_items, "f").push([item, newPosition]); | ||
position = newPosition; | ||
} | ||
} | ||
static deserialize([id, item], parentToChildren, doc) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
static _deserialize([id, item], parentToChildren, doc) { | ||
const list = new LiveList([]); | ||
list.attach(id, doc); | ||
list._attach(id, doc); | ||
const children = parentToChildren.get(id); | ||
@@ -731,10 +787,13 @@ if (children == null) { | ||
const child = deserialize(entry, parentToChildren, doc); | ||
child.setParent(list); | ||
list._items.push([child, entry[1].parentKey]); | ||
list._items.sort((itemA, itemB) => compare({ position: itemA[1] }, { position: itemB[1] })); | ||
child._setParent(list); | ||
__classPrivateFieldGet(list, _LiveList_items, "f").push([child, entry[1].parentKey]); | ||
__classPrivateFieldGet(list, _LiveList_items, "f").sort((itemA, itemB) => compare({ position: itemA[1] }, { position: itemB[1] })); | ||
} | ||
return list; | ||
} | ||
serialize(parentId, parentKey) { | ||
if (this.id == null) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
_serialize(parentId, parentKey) { | ||
if (this._id == null) { | ||
throw new Error("Cannot serialize item is not attached"); | ||
@@ -747,3 +806,3 @@ } | ||
const op = { | ||
id: this.id, | ||
id: this._id, | ||
type: OpType.CreateList, | ||
@@ -754,75 +813,89 @@ parentId, | ||
ops.push(op); | ||
for (const [value, key] of this._items) { | ||
ops.push(...value.serialize(this.id, key)); | ||
for (const [value, key] of __classPrivateFieldGet(this, _LiveList_items, "f")) { | ||
ops.push(...value._serialize(this._id, key)); | ||
} | ||
return ops; | ||
} | ||
attach(id, doc) { | ||
super.attach(id, doc); | ||
for (const [item, position] of this._items) { | ||
item.attach(doc.generateId(), doc); | ||
/** | ||
* INTERNAL | ||
*/ | ||
_attach(id, doc) { | ||
super._attach(id, doc); | ||
for (const [item, position] of __classPrivateFieldGet(this, _LiveList_items, "f")) { | ||
item._attach(doc.generateId(), doc); | ||
} | ||
} | ||
detach() { | ||
super.detach(); | ||
for (const [value] of this._items) { | ||
value.detach(); | ||
/** | ||
* INTERNAL | ||
*/ | ||
_detach() { | ||
super._detach(); | ||
for (const [value] of __classPrivateFieldGet(this, _LiveList_items, "f")) { | ||
value._detach(); | ||
} | ||
} | ||
attachChild(id, key, child) { | ||
if (this.doc == null) { | ||
/** | ||
* INTERNAL | ||
*/ | ||
_attachChild(id, key, child) { | ||
if (this._doc == null) { | ||
throw new Error("Can't attach child if doc is not present"); | ||
} | ||
child.attach(id, this.doc); | ||
child.setParent(this); | ||
child._attach(id, this._doc); | ||
child._setParent(this); | ||
// TODO: Handle list conflict | ||
this._items.push([child, key]); | ||
this._items.sort((itemA, itemB) => compare({ position: itemA[1] }, { position: itemB[1] })); | ||
__classPrivateFieldGet(this, _LiveList_items, "f").push([child, key]); | ||
__classPrivateFieldGet(this, _LiveList_items, "f").sort((itemA, itemB) => compare({ position: itemA[1] }, { position: itemB[1] })); | ||
this.notify(); | ||
} | ||
detachChild(child) { | ||
const indexToDelete = this._items.findIndex((item) => item[0] === child); | ||
this._items.splice(indexToDelete, 1); | ||
/** | ||
* INTERNAL | ||
*/ | ||
_detachChild(child) { | ||
const indexToDelete = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((item) => item[0] === child); | ||
__classPrivateFieldGet(this, _LiveList_items, "f").splice(indexToDelete, 1); | ||
if (child) { | ||
child.detach(); | ||
child._detach(); | ||
} | ||
this.notify(); | ||
} | ||
setChildKey(key, child) { | ||
const item = this._items.find((item) => item[0] === child); | ||
/** | ||
* INTERNAL | ||
*/ | ||
_setChildKey(key, child) { | ||
const item = __classPrivateFieldGet(this, _LiveList_items, "f").find((item) => item[0] === child); | ||
if (item) { | ||
item[1] = key; | ||
} | ||
this._items.sort((itemA, itemB) => compare({ position: itemA[1] }, { position: itemB[1] })); | ||
__classPrivateFieldGet(this, _LiveList_items, "f").sort((itemA, itemB) => compare({ position: itemA[1] }, { position: itemB[1] })); | ||
this.notify(); | ||
} | ||
apply(op) { } | ||
push(item) { | ||
const position = this._items.length === 0 | ||
const position = __classPrivateFieldGet(this, _LiveList_items, "f").length === 0 | ||
? makePosition() | ||
: makePosition(this._items[this._items.length - 1][1]); | ||
: makePosition(__classPrivateFieldGet(this, _LiveList_items, "f")[__classPrivateFieldGet(this, _LiveList_items, "f").length - 1][1]); | ||
const value = selfOrRegister(item); | ||
value.setParent(this); | ||
this._items.push([value, position]); | ||
value._setParent(this); | ||
__classPrivateFieldGet(this, _LiveList_items, "f").push([value, position]); | ||
this.notify(); | ||
if (this.doc && this.id) { | ||
value.attach(this.doc.generateId(), this.doc); | ||
this.doc.dispatch(value.serialize(this.id, position)); | ||
if (this._doc && this._id) { | ||
value._attach(this._doc.generateId(), this._doc); | ||
this._doc.dispatch(value._serialize(this._id, position)); | ||
} | ||
} | ||
insert(item, index) { | ||
if (index < 0 || index > this._items.length) { | ||
throw new Error(`Cannot delete list item at index "${index}". index should be between 0 and ${this._items.length}`); | ||
if (index < 0 || index > __classPrivateFieldGet(this, _LiveList_items, "f").length) { | ||
throw new Error(`Cannot delete list item at index "${index}". index should be between 0 and ${__classPrivateFieldGet(this, _LiveList_items, "f").length}`); | ||
} | ||
let before = this._items[index - 1] ? this._items[index - 1][1] : undefined; | ||
let after = this._items[index] ? this._items[index][1] : undefined; | ||
let before = __classPrivateFieldGet(this, _LiveList_items, "f")[index - 1] ? __classPrivateFieldGet(this, _LiveList_items, "f")[index - 1][1] : undefined; | ||
let after = __classPrivateFieldGet(this, _LiveList_items, "f")[index] ? __classPrivateFieldGet(this, _LiveList_items, "f")[index][1] : undefined; | ||
const position = makePosition(before, after); | ||
const value = selfOrRegister(item); | ||
value.setParent(this); | ||
this._items.push([value, position]); | ||
this._items.sort((itemA, itemB) => compare({ position: itemA[1] }, { position: itemB[1] })); | ||
value._setParent(this); | ||
__classPrivateFieldGet(this, _LiveList_items, "f").push([value, position]); | ||
__classPrivateFieldGet(this, _LiveList_items, "f").sort((itemA, itemB) => compare({ position: itemA[1] }, { position: itemB[1] })); | ||
this.notify(); | ||
if (this.doc && this.id) { | ||
value.attach(this.doc.generateId(), this.doc); | ||
this.doc.dispatch(value.serialize(this.id, position)); | ||
if (this._doc && this._id) { | ||
value._attach(this._doc.generateId(), this._doc); | ||
this._doc.dispatch(value._serialize(this._id, position)); | ||
} | ||
@@ -834,3 +907,3 @@ } | ||
} | ||
if (targetIndex >= this._items.length) { | ||
if (targetIndex >= __classPrivateFieldGet(this, _LiveList_items, "f").length) { | ||
throw new Error("targetIndex cannot be greater or equal than the list length"); | ||
@@ -841,3 +914,3 @@ } | ||
} | ||
if (index >= this._items.length) { | ||
if (index >= __classPrivateFieldGet(this, _LiveList_items, "f").length) { | ||
throw new Error("index cannot be greater or equal than the list length"); | ||
@@ -849,21 +922,21 @@ } | ||
afterPosition = | ||
targetIndex === this._items.length - 1 | ||
targetIndex === __classPrivateFieldGet(this, _LiveList_items, "f").length - 1 | ||
? undefined | ||
: this._items[targetIndex + 1][1]; | ||
beforePosition = this._items[targetIndex][1]; | ||
: __classPrivateFieldGet(this, _LiveList_items, "f")[targetIndex + 1][1]; | ||
beforePosition = __classPrivateFieldGet(this, _LiveList_items, "f")[targetIndex][1]; | ||
} | ||
else { | ||
afterPosition = this._items[targetIndex][1]; | ||
afterPosition = __classPrivateFieldGet(this, _LiveList_items, "f")[targetIndex][1]; | ||
beforePosition = | ||
targetIndex === 0 ? undefined : this._items[targetIndex - 1][1]; | ||
targetIndex === 0 ? undefined : __classPrivateFieldGet(this, _LiveList_items, "f")[targetIndex - 1][1]; | ||
} | ||
const position = makePosition(beforePosition, afterPosition); | ||
const item = this._items[index]; | ||
const item = __classPrivateFieldGet(this, _LiveList_items, "f")[index]; | ||
item[1] = position; | ||
this._items.sort((itemA, itemB) => compare({ position: itemA[1] }, { position: itemB[1] })); | ||
__classPrivateFieldGet(this, _LiveList_items, "f").sort((itemA, itemB) => compare({ position: itemA[1] }, { position: itemB[1] })); | ||
this.notify(); | ||
if (this.doc && this.id) { | ||
this.doc.dispatch([{ | ||
if (this._doc && this._id) { | ||
this._doc.dispatch([{ | ||
type: OpType.SetParentKey, | ||
id: item[0].id, | ||
id: item[0]._id, | ||
parentKey: position, | ||
@@ -874,12 +947,12 @@ },]); | ||
delete(index) { | ||
if (index < 0 || index >= this._items.length) { | ||
throw new Error(`Cannot delete list item at index "${index}". index should be between 0 and ${this._items.length - 1}`); | ||
if (index < 0 || index >= __classPrivateFieldGet(this, _LiveList_items, "f").length) { | ||
throw new Error(`Cannot delete list item at index "${index}". index should be between 0 and ${__classPrivateFieldGet(this, _LiveList_items, "f").length - 1}`); | ||
} | ||
const item = this._items[index]; | ||
item[0].detach(); | ||
this._items.splice(index, 1); | ||
if (this.doc) { | ||
const childRecordId = item[0].id; | ||
const item = __classPrivateFieldGet(this, _LiveList_items, "f")[index]; | ||
item[0]._detach(); | ||
__classPrivateFieldGet(this, _LiveList_items, "f").splice(index, 1); | ||
if (this._doc) { | ||
const childRecordId = item[0]._id; | ||
if (childRecordId) { | ||
this.doc.dispatch([ | ||
this._doc.dispatch([ | ||
{ | ||
@@ -895,21 +968,22 @@ id: childRecordId, | ||
toArray() { | ||
return this._items.map((entry) => selfOrRegisterValue(entry[0])); | ||
return __classPrivateFieldGet(this, _LiveList_items, "f").map((entry) => selfOrRegisterValue(entry[0])); | ||
} | ||
get(index) { | ||
return selfOrRegisterValue(this._items[index][0]); | ||
return selfOrRegisterValue(__classPrivateFieldGet(this, _LiveList_items, "f")[index][0]); | ||
} | ||
} | ||
_LiveList_items = new WeakMap(); | ||
function deserialize(entry, parentToChildren, doc) { | ||
switch (entry[1].type) { | ||
case CrdtType.Object: { | ||
return LiveObject.deserialize(entry, parentToChildren, doc); | ||
return LiveObject._deserialize(entry, parentToChildren, doc); | ||
} | ||
case CrdtType.List: { | ||
return LiveList.deserialize(entry, parentToChildren, doc); | ||
return LiveList._deserialize(entry, parentToChildren, doc); | ||
} | ||
case CrdtType.Map: { | ||
return LiveMap.deserialize(entry, parentToChildren, doc); | ||
return LiveMap._deserialize(entry, parentToChildren, doc); | ||
} | ||
case CrdtType.Register: { | ||
return LiveRegister.deserialize(entry, parentToChildren, doc); | ||
return LiveRegister._deserialize(entry, parentToChildren, doc); | ||
} | ||
@@ -916,0 +990,0 @@ default: { |
export declare const min = 32; | ||
export declare const max = 127; | ||
export declare const mid = 79; | ||
export declare function middle(a: number, b: number): number; | ||
export declare const max = 126; | ||
export declare function makePosition(before?: string, after?: string): string; | ||
@@ -6,0 +4,0 @@ export declare function posCodes(str: string): number[]; |
export const min = 32; | ||
export const max = 127; | ||
export const mid = 79; | ||
export function middle(a, b) { | ||
return (a + b) / 2; | ||
} | ||
export const max = 126; | ||
export function makePosition(before, after) { | ||
@@ -30,3 +26,3 @@ // No children | ||
if (afterCodes.length - 1 === i) { | ||
result.push(max - 1); | ||
result.push(max); | ||
break; | ||
@@ -47,3 +43,3 @@ } | ||
const code = beforeCodes[i]; | ||
if (code === max - 1) { | ||
if (code === max) { | ||
result.push(code); | ||
@@ -81,3 +77,3 @@ if (beforeCodes.length - 1 === i) { | ||
} | ||
const mid = beforeDigit + Math.floor((afterDigit - beforeDigit) / 2); | ||
const mid = (afterDigit + beforeDigit) >> 1; | ||
result.push(mid); | ||
@@ -84,0 +80,0 @@ break; |
import { Others, Presence, ClientOptions, Room, MyPresenceCallback, OthersEventCallback, AuthEndpoint, EventCallback, User, Connection, ErrorCallback, AuthenticationToken, ConnectionCallback } from "./types"; | ||
import { ClientMessage, Op } from "./live"; | ||
import { LiveObject } from "./doc"; | ||
declare type IdFactory = () => string; | ||
@@ -84,6 +85,6 @@ export declare type State = { | ||
getStorage: <TRoot>() => Promise<{ | ||
root: import("./doc").LiveObject<TRoot>; | ||
root: LiveObject<TRoot>; | ||
}>; | ||
selectors: { | ||
getConnectionState: () => "failed" | "closed" | "open" | "connecting" | "authenticating" | "unavailable"; | ||
getConnectionState: () => "failed" | "closed" | "connecting" | "open" | "authenticating" | "unavailable"; | ||
getSelf: <TPresence extends Presence = Presence>() => User<TPresence> | null; | ||
@@ -90,0 +91,0 @@ getPresence: <T_5 extends Presence>() => T_5; |
{ | ||
"name": "@liveblocks/client", | ||
"version": "0.12.0-beta.6", | ||
"version": "0.12.0-beta.7", | ||
"description": "", | ||
@@ -34,3 +34,3 @@ "main": "./lib/cjs/index.js", | ||
"jest": "^26.6.3", | ||
"typescript": "^4.1.5" | ||
"typescript": "^4.4.0" | ||
}, | ||
@@ -37,0 +37,0 @@ "repository": { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
194569
42
5463