@y/y 14.0.0-21 → 14.0.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -9
- package/dist/src/utils/AttributionManager.d.ts +1 -1
- package/dist/src/utils/AttributionManager.d.ts.map +1 -1
- package/dist/src/utils/UndoManager.d.ts +1 -1
- package/dist/src/utils/UndoManager.d.ts.map +1 -1
- package/dist/src/utils/encoding.d.ts +2 -2
- package/dist/src/utils/encoding.d.ts.map +1 -1
- package/dist/src/utils/updates.d.ts +7 -7
- package/dist/src/utils/updates.d.ts.map +1 -1
- package/dist/tests/attribution.tests.d.ts.map +1 -1
- package/dist/tests/testHelper.d.ts +1 -1
- package/dist/tests/updates.tests.d.ts +3 -3
- package/dist/tests/updates.tests.d.ts.map +1 -1
- package/dist/tests/y-text.tests.d.ts.map +1 -1
- package/package.json +7 -5
- package/src/utils/AttributionManager.js +1 -1
- package/src/utils/UndoManager.js +3 -2
- package/src/utils/encoding.js +2 -2
- package/src/utils/updates.js +12 -12
- package/src/ytype.js +1 -1
- package/tests/testHelper.js +594 -0
package/README.md
CHANGED
|
@@ -229,19 +229,25 @@ are available. Communication over the signaling servers can be encrypted by
|
|
|
229
229
|
providing a shared secret, keeping the connection information and the shared
|
|
230
230
|
document private.
|
|
231
231
|
</dd>
|
|
232
|
-
<dt><a href="https://github.com/
|
|
232
|
+
<dt><a href="https://github.com/ueberdosis/hocuspocus">Hocuspocus</a> 🌟</dt>
|
|
233
233
|
<dd>
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
</a>
|
|
234
|
+
A standalone extensible yjs server with sqlite persistence, webhooks, auth and more.
|
|
235
|
+
</dd>
|
|
236
|
+
<dt><a href="https://velt.dev/libraries/yjs">Velt YJs</a> ⭐</dt>
|
|
237
|
+
<dd><a href="https://docs.velt.dev/realtime-collaboration/crdt/overview">Velt</a>
|
|
238
|
+
A managed Yjs backend with realtime WebSocket sync and persistent storage - no
|
|
239
|
+
server setup required. Includes offline support with automatic reconnection,
|
|
240
|
+
version history, end-to-end custom encryption. Additionally it also provides Yjs
|
|
241
|
+
webhook events, REST API to read and update Yjs documents, and a browser
|
|
242
|
+
DevTools extension.
|
|
243
|
+
</dd>
|
|
244
|
+
<dt><a href="https://github.com/liveblocks/liveblocks">@liveblocks/yjs</a> ⭐</dt>
|
|
245
|
+
<dd>
|
|
246
|
+
<a href="https://liveblocks.io/docs/api-reference/liveblocks-yjs">Liveblocks Yjs</a>
|
|
237
247
|
provides a fully hosted WebSocket infrastructure and persisted data
|
|
238
248
|
store for Yjs documents. No configuration or maintenance is required. It
|
|
239
249
|
also features Yjs webhook events, REST API to read and update Yjs
|
|
240
250
|
documents, and a browser DevTools extension.
|
|
241
|
-
</dd>
|
|
242
|
-
<dt><a href="https://github.com/ueberdosis/hocuspocus">Hocuspocus</a> ⭐</dt>
|
|
243
|
-
<dd>
|
|
244
|
-
A standalone extensible yjs server with sqlite persistence, webhooks, auth and more.
|
|
245
251
|
</dd>
|
|
246
252
|
<dt><a href="https://github.com/nperez0111/teleportal">teleportal</a></dt>
|
|
247
253
|
<dd>
|
|
@@ -367,7 +373,6 @@ A database and connection provider for Yjs based on Firestore.
|
|
|
367
373
|
<dd>
|
|
368
374
|
Yjs persistence provider for op-sqlite
|
|
369
375
|
</dd>
|
|
370
|
-
|
|
371
376
|
</dl>
|
|
372
377
|
|
|
373
378
|
### Tooling
|
|
@@ -375,6 +380,7 @@ A database and connection provider for Yjs based on Firestore.
|
|
|
375
380
|
* [y-sweet debugger](https://y-sweet.cloud/advanced/debugger)
|
|
376
381
|
* [liveblocks devtools](https://liveblocks.io/devtools)
|
|
377
382
|
* [Yjs inspector](https://inspector.yjs.dev)
|
|
383
|
+
* [velt devtools](https://velt.dev/devtools)
|
|
378
384
|
|
|
379
385
|
### Ports
|
|
380
386
|
|
|
@@ -184,7 +184,7 @@ export class DiffAttributionManager extends ObservableV2<{
|
|
|
184
184
|
contentLength(item: Item): number;
|
|
185
185
|
}
|
|
186
186
|
export function createAttributionManagerFromDiff(prevDoc: Doc, nextDoc: Doc, options?: {
|
|
187
|
-
attrs?:
|
|
187
|
+
attrs?: import("./meta.js").ContentMap | null | undefined;
|
|
188
188
|
}): DiffAttributionManager;
|
|
189
189
|
/**
|
|
190
190
|
* Intended for projects that used the v13 snapshot feature. With this AttributionManager you can
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AttributionManager.d.ts","sourceRoot":"","sources":["../../../src/utils/AttributionManager.js"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"AttributionManager.d.ts","sourceRoot":"","sources":["../../../src/utils/AttributionManager.js"],"names":[],"mappings":"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"}
|
|
@@ -150,7 +150,7 @@ export class UndoManager extends ObservableV2<{
|
|
|
150
150
|
*/
|
|
151
151
|
canRedo(): boolean;
|
|
152
152
|
}
|
|
153
|
-
export function undoContentIds(ydoc: Doc, contentIds: import("./meta.js").ContentIds): void;
|
|
153
|
+
export function undoContentIds(ydoc: Doc, contentIds: import("./meta.js").ContentIds, opts?: UndoManagerOptions): void;
|
|
154
154
|
export type UndoManagerOptions = {
|
|
155
155
|
captureTimeout?: number | undefined;
|
|
156
156
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UndoManager.d.ts","sourceRoot":"","sources":["../../../src/utils/UndoManager.js"],"names":[],"mappings":"AAmBA;IACE;;;OAGG;IACH,wBAHW,KAAK,aACL,KAAK,EASf;IANC,eAAyB;IACzB,eAAwB;IACxB;;OAEG;IACH,oBAAqB;CAExB;AAgGD;;;;;;;;;;;GAWG;AAEH;;;;;;GAMG;AAEH;;;;;;;;GAQG;AACH;wBAF8C,CAAS,IAAc,EAAd,cAAc,EAAE,IAAW,EAAX,WAAW,KAAE,IAAI;yBAAuB,CAAS,IAAc,EAAd,cAAc,EAAE,IAAW,EAAX,WAAW,KAAE,IAAI;qBAAmB,CAAS,IAAwD,EAAxD;QAAE,gBAAgB,EAAE,OAAO,CAAC;QAAC,gBAAgB,EAAE,OAAO,CAAA;KAAE,KAAE,IAAI;0BAAwB,CAAS,IAAc,EAAd,cAAc,EAAE,IAAW,EAAX,WAAW,KAAE,IAAI;;IAGnT;;;OAGG;IACH,uBAHW,GAAG,GAAC,KAAK,GAAC,KAAK,CAAC,KAAK,CAAC,sGACtB,kBAAkB,EAsG5B;IA3FC;;OAEG;IACH,OAFU,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,CAEb;IACf,SAAc;IAEd,qBA9CmB,IAAI,KAAE,OAAO,CA8CA;IAEhC,yBAAoC;IACpC,2BAlDmB,WAAW,KAAE,OAAO,CAkDK;IAC5C;;OAEG;IACH,WAFU,KAAK,CAAC,SAAS,CAAC,CAEP;IACnB;;OAEG;IACH,WAFU,KAAK,CAAC,SAAS,CAAC,CAEP;IACnB;;;;OAIG;IACH,SAFU,OAAO,CAEG;IACpB,iBAAoB;IACpB;;;;OAIG;IACH,eAFU,SAAS,GAAC,IAAI,CAEC;IACzB,mBAAmB;IACnB,gCAAoD;IACpD,uBAAoC;IACpC;;OAEG;IACH,uCAFW,WAAW,UAmDrB;IAOH;;;;OAIG;IACH,mBAFW,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,KAAK,GAAG,GAAG,QAY1C;IAED;;OAEG;IACH,yBAFW,GAAG,QAIb;IAED;;OAEG;IACH,4BAFW,GAAG,QAIb;IAED,gEAcC;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACH,sBAEC;IAED;;;;OAIG;IACH,QAFY,SAAS,OAAC,CAWrB;IAED;;;;OAIG;IACH,QAFY,SAAS,OAAC,CAWrB;IAED;;;;OAIG;IACH,WAFY,OAAO,CAIlB;IAED;;;;OAIG;IACH,WAFY,OAAO,CAIlB;CAOF;
|
|
1
|
+
{"version":3,"file":"UndoManager.d.ts","sourceRoot":"","sources":["../../../src/utils/UndoManager.js"],"names":[],"mappings":"AAmBA;IACE;;;OAGG;IACH,wBAHW,KAAK,aACL,KAAK,EASf;IANC,eAAyB;IACzB,eAAwB;IACxB;;OAEG;IACH,oBAAqB;CAExB;AAgGD;;;;;;;;;;;GAWG;AAEH;;;;;;GAMG;AAEH;;;;;;;;GAQG;AACH;wBAF8C,CAAS,IAAc,EAAd,cAAc,EAAE,IAAW,EAAX,WAAW,KAAE,IAAI;yBAAuB,CAAS,IAAc,EAAd,cAAc,EAAE,IAAW,EAAX,WAAW,KAAE,IAAI;qBAAmB,CAAS,IAAwD,EAAxD;QAAE,gBAAgB,EAAE,OAAO,CAAC;QAAC,gBAAgB,EAAE,OAAO,CAAA;KAAE,KAAE,IAAI;0BAAwB,CAAS,IAAc,EAAd,cAAc,EAAE,IAAW,EAAX,WAAW,KAAE,IAAI;;IAGnT;;;OAGG;IACH,uBAHW,GAAG,GAAC,KAAK,GAAC,KAAK,CAAC,KAAK,CAAC,sGACtB,kBAAkB,EAsG5B;IA3FC;;OAEG;IACH,OAFU,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,CAEb;IACf,SAAc;IAEd,qBA9CmB,IAAI,KAAE,OAAO,CA8CA;IAEhC,yBAAoC;IACpC,2BAlDmB,WAAW,KAAE,OAAO,CAkDK;IAC5C;;OAEG;IACH,WAFU,KAAK,CAAC,SAAS,CAAC,CAEP;IACnB;;OAEG;IACH,WAFU,KAAK,CAAC,SAAS,CAAC,CAEP;IACnB;;;;OAIG;IACH,SAFU,OAAO,CAEG;IACpB,iBAAoB;IACpB;;;;OAIG;IACH,eAFU,SAAS,GAAC,IAAI,CAEC;IACzB,mBAAmB;IACnB,gCAAoD;IACpD,uBAAoC;IACpC;;OAEG;IACH,uCAFW,WAAW,UAmDrB;IAOH;;;;OAIG;IACH,mBAFW,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,KAAK,GAAG,GAAG,QAY1C;IAED;;OAEG;IACH,yBAFW,GAAG,QAIb;IAED;;OAEG;IACH,4BAFW,GAAG,QAIb;IAED,gEAcC;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACH,sBAEC;IAED;;;;OAIG;IACH,QAFY,SAAS,OAAC,CAWrB;IAED;;;;OAIG;IACH,QAFY,SAAS,OAAC,CAWrB;IAED;;;;OAIG;IACH,WAFY,OAAO,CAIlB;IAED;;;;OAIG;IACH,WAFY,OAAO,CAIlB;CAOF;AAWM,qCAJI,GAAG,cACH,OAAO,WAAW,EAAE,UAAU,SAC9B,kBAAkB,QAM5B;;;;;;iCAnRsB,WAAW,KAAE,OAAO;;;;;;;2BACpB,IAAI,KAAE,OAAO;;;;;;;;;;;;eAWtB,SAAS;YACT,GAAG;UACH,MAAM,GAAC,MAAM;wBACb,GAAG,CAAC,KAAK,EAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;;sBAtIpC,iBAAiB;6BAKK,iBAAiB;sBALvC,iBAAiB;oBAAjB,iBAAiB;qBAAjB,iBAAiB;4BAAjB,iBAAiB;uBAAjB,iBAAiB"}
|
|
@@ -12,8 +12,8 @@ export function readStateVector(decoder: IdSetDecoderV1 | IdSetDecoderV2): Map<n
|
|
|
12
12
|
export function decodeStateVector(decodedState: Uint8Array): Map<number, number>;
|
|
13
13
|
export function writeStateVector(encoder: IdSetEncoderV1 | IdSetEncoderV2, sv: Map<number, number>): IdSetEncoderV1 | IdSetEncoderV2;
|
|
14
14
|
export function writeDocumentStateVector(encoder: IdSetEncoderV1 | IdSetEncoderV2, doc: Doc): IdSetEncoderV1 | IdSetEncoderV2;
|
|
15
|
-
export function encodeStateVectorV2(doc: Doc | Map<number, number>, encoder?: IdSetEncoderV1 | IdSetEncoderV2): Uint8Array
|
|
16
|
-
export function encodeStateVector(doc: Doc | Map<number, number>): Uint8Array
|
|
15
|
+
export function encodeStateVectorV2(doc: Doc | Map<number, number>, encoder?: IdSetEncoderV1 | IdSetEncoderV2): Uint8Array<ArrayBuffer>;
|
|
16
|
+
export function encodeStateVector(doc: Doc | Map<number, number>): Uint8Array<ArrayBuffer>;
|
|
17
17
|
import { UpdateEncoderV1 } from '../internals.js';
|
|
18
18
|
import { UpdateEncoderV2 } from '../internals.js';
|
|
19
19
|
import { StructStore } from '../internals.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encoding.d.ts","sourceRoot":"","sources":["../../../src/utils/encoding.js"],"names":[],"mappings":"AAkHO,6CAPI,eAAe,GAAG,eAAe,SACjC,WAAW,OACX,GAAG,CAAC,MAAM,EAAC,MAAM,CAAC,QA4B5B;AAYM,+CATI,eAAe,GAAG,eAAe,SACjC,WAAW,SACX,KAAK,QAiBf;AA6KM,qDANI,eAAe,GAAG,eAAe,eACjC,WAAW,QAK2H;AAc1I,sCAPI,QAAQ,CAAC,OAAO,QAChB,GAAG,sBACH,GAAG,kBACH,eAAe,GAAG,eAAe,QAqFd;AAavB,oCANI,QAAQ,CAAC,OAAO,QAChB,GAAG,sBACH,GAAG,QAI8H;AAcrI,oCAPI,GAAG,UACH,UAAU,sBACV,GAAG,aACH,OAAO,eAAe,GAAG,OAAO,eAAe,QAOzD;AAaM,kCANI,GAAG,UACH,UAAU,sBACV,GAAG,QAIiH;AAYxH,4CANI,eAAe,GAAG,eAAe,OACjC,GAAG,sBACH,GAAG,CAAC,MAAM,EAAC,MAAM,CAAC,QAO5B;AAeM,2CAPI,GAAG,6BACH,UAAU,YACV,eAAe,GAAG,eAAe,GAChC,UAAU,CAAC,WAAW,CAAC,CAuBlC;AAcM,yCANI,GAAG,6BACH,UAAU,GACT,UAAU,CAAC,WAAW,CAAC,CAI8G;AAU1I,yCALI,cAAc,GAAG,cAAc,GAC9B,GAAG,CAAC,MAAM,EAAC,MAAM,CAAC,CAa7B;AAoBM,gDALI,UAAU,GACT,GAAG,CAAC,MAAM,EAAC,MAAM,CAAC,CAI4F;AAOnH,0CAJI,cAAc,GAAG,cAAc,MAC/B,GAAG,CAAC,MAAM,EAAC,MAAM,CAAC,mCAU5B;AAQM,kDALI,cAAc,GAAG,cAAc,OAC/B,GAAG,mCAIgG;AAWvG,yCANI,GAAG,GAAC,GAAG,CAAC,MAAM,EAAC,MAAM,CAAC,YACtB,cAAc,GAAG,cAAc,GAC9B,UAAU,
|
|
1
|
+
{"version":3,"file":"encoding.d.ts","sourceRoot":"","sources":["../../../src/utils/encoding.js"],"names":[],"mappings":"AAkHO,6CAPI,eAAe,GAAG,eAAe,SACjC,WAAW,OACX,GAAG,CAAC,MAAM,EAAC,MAAM,CAAC,QA4B5B;AAYM,+CATI,eAAe,GAAG,eAAe,SACjC,WAAW,SACX,KAAK,QAiBf;AA6KM,qDANI,eAAe,GAAG,eAAe,eACjC,WAAW,QAK2H;AAc1I,sCAPI,QAAQ,CAAC,OAAO,QAChB,GAAG,sBACH,GAAG,kBACH,eAAe,GAAG,eAAe,QAqFd;AAavB,oCANI,QAAQ,CAAC,OAAO,QAChB,GAAG,sBACH,GAAG,QAI8H;AAcrI,oCAPI,GAAG,UACH,UAAU,sBACV,GAAG,aACH,OAAO,eAAe,GAAG,OAAO,eAAe,QAOzD;AAaM,kCANI,GAAG,UACH,UAAU,sBACV,GAAG,QAIiH;AAYxH,4CANI,eAAe,GAAG,eAAe,OACjC,GAAG,sBACH,GAAG,CAAC,MAAM,EAAC,MAAM,CAAC,QAO5B;AAeM,2CAPI,GAAG,6BACH,UAAU,YACV,eAAe,GAAG,eAAe,GAChC,UAAU,CAAC,WAAW,CAAC,CAuBlC;AAcM,yCANI,GAAG,6BACH,UAAU,GACT,UAAU,CAAC,WAAW,CAAC,CAI8G;AAU1I,yCALI,cAAc,GAAG,cAAc,GAC9B,GAAG,CAAC,MAAM,EAAC,MAAM,CAAC,CAa7B;AAoBM,gDALI,UAAU,GACT,GAAG,CAAC,MAAM,EAAC,MAAM,CAAC,CAI4F;AAOnH,0CAJI,cAAc,GAAG,cAAc,MAC/B,GAAG,CAAC,MAAM,EAAC,MAAM,CAAC,mCAU5B;AAQM,kDALI,cAAc,GAAG,cAAc,OAC/B,GAAG,mCAIgG;AAWvG,yCANI,GAAG,GAAC,GAAG,CAAC,MAAM,EAAC,MAAM,CAAC,YACtB,cAAc,GAAG,cAAc,GAC9B,UAAU,CAAC,WAAW,CAAC,CAWlC;AAUM,uCALI,GAAG,GAAC,GAAG,CAAC,MAAM,EAAC,MAAM,CAAC,GACrB,UAAU,CAAC,WAAW,CAAC,CAImD;gCArkB/E,iBAAiB;gCAAjB,iBAAiB;4BAAjB,iBAAiB;sBAAjB,iBAAiB;4BAAjB,iBAAiB;0BAGE,eAAe;oBAHlC,iBAAiB;gCAAjB,iBAAiB;gCAAjB,iBAAiB;+BAAjB,iBAAiB;+BAAjB,iBAAiB;+BAAjB,iBAAiB;+BAAjB,iBAAiB"}
|
|
@@ -51,22 +51,22 @@ export class LazyStructWriter {
|
|
|
51
51
|
}>;
|
|
52
52
|
}
|
|
53
53
|
export function mergeUpdates(updates: Array<Uint8Array<ArrayBuffer>>): Uint8Array<ArrayBuffer>;
|
|
54
|
-
export function encodeStateVectorFromUpdateV2(update: Uint8Array, YEncoder?: typeof IdSetEncoderV1 | typeof IdSetEncoderV2, YDecoder?: typeof UpdateDecoderV1 | typeof UpdateDecoderV2): Uint8Array
|
|
55
|
-
export function encodeStateVectorFromUpdate(update: Uint8Array): Uint8Array
|
|
54
|
+
export function encodeStateVectorFromUpdateV2(update: Uint8Array, YEncoder?: typeof IdSetEncoderV1 | typeof IdSetEncoderV2, YDecoder?: typeof UpdateDecoderV1 | typeof UpdateDecoderV2): Uint8Array<ArrayBuffer>;
|
|
55
|
+
export function encodeStateVectorFromUpdate(update: Uint8Array): Uint8Array<ArrayBuffer>;
|
|
56
56
|
export function createContentIdsFromUpdateV2(update: Uint8Array, YDecoder?: typeof UpdateDecoderV2 | typeof UpdateDecoderV1): import("./meta.js").ContentIds;
|
|
57
57
|
export function createContentIdsFromUpdate(update: Uint8Array): import("./meta.js").ContentIds;
|
|
58
58
|
export function mergeUpdatesV2(updates: Array<Uint8Array<ArrayBuffer>>, YDecoder?: typeof UpdateDecoderV1 | typeof UpdateDecoderV2, YEncoder?: typeof UpdateEncoderV1 | typeof UpdateEncoderV2): Uint8Array<ArrayBuffer>;
|
|
59
59
|
export function diffUpdateV2(update: Uint8Array, sv: Uint8Array, YDecoder?: typeof UpdateDecoderV1 | typeof UpdateDecoderV2, YEncoder?: typeof UpdateEncoderV1 | typeof UpdateEncoderV2): Uint8Array<ArrayBuffer>;
|
|
60
|
-
export function diffUpdate(update: Uint8Array
|
|
60
|
+
export function diffUpdate(update: Uint8Array<ArrayBuffer>, sv: Uint8Array<ArrayBuffer>): Uint8Array<ArrayBuffer>;
|
|
61
61
|
export function convertUpdateFormat(update: Uint8Array, blockTransformer: (arg0: Item | GC | Skip) => Item | GC | Skip, YDecoder: typeof UpdateDecoderV2 | typeof UpdateDecoderV1, YEncoder: typeof UpdateEncoderV2 | typeof UpdateEncoderV1): Uint8Array<ArrayBuffer>;
|
|
62
62
|
export function obfuscateUpdate(update: Uint8Array, opts?: ObfuscatorOptions): Uint8Array<ArrayBuffer>;
|
|
63
63
|
export function obfuscateUpdateV2(update: Uint8Array, opts?: ObfuscatorOptions): Uint8Array<ArrayBuffer>;
|
|
64
64
|
export function convertUpdateFormatV1ToV2(update: Uint8Array): Uint8Array<ArrayBuffer>;
|
|
65
65
|
export function convertUpdateFormatV2ToV1(update: Uint8Array): Uint8Array<ArrayBuffer>;
|
|
66
|
-
export function intersectUpdateWithContentIdsV2(update: Uint8Array, contentIds: import("./meta.js").ContentIds, YDecoder?: typeof UpdateDecoderV1 | typeof UpdateDecoderV2, YEncoder?: typeof UpdateEncoderV1 | typeof UpdateEncoderV2): Uint8Array
|
|
67
|
-
export function intersectUpdateWithContentIds(update: Uint8Array, contentIds: import("./meta.js").ContentIds): Uint8Array
|
|
68
|
-
export function createDocFromUpdate(update: Uint8Array): Doc;
|
|
69
|
-
export function createDocFromUpdateV2(update: Uint8Array): Doc;
|
|
66
|
+
export function intersectUpdateWithContentIdsV2(update: Uint8Array, contentIds: import("./meta.js").ContentIds, YDecoder?: typeof UpdateDecoderV1 | typeof UpdateDecoderV2, YEncoder?: typeof UpdateEncoderV1 | typeof UpdateEncoderV2): Uint8Array<ArrayBuffer>;
|
|
67
|
+
export function intersectUpdateWithContentIds(update: Uint8Array, contentIds: import("./meta.js").ContentIds): Uint8Array<ArrayBuffer>;
|
|
68
|
+
export function createDocFromUpdate(update: Uint8Array, opts?: import("./Doc.js").DocOpts): Doc;
|
|
69
|
+
export function createDocFromUpdateV2(update: Uint8Array, opts?: import("./Doc.js").DocOpts): Doc;
|
|
70
70
|
export type ObfuscatorOptions = {
|
|
71
71
|
formatting?: boolean | undefined;
|
|
72
72
|
subdocs?: boolean | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"updates.d.ts","sourceRoot":"","sources":["../../../src/utils/updates.js"],"names":[],"mappings":"AAuFA;IACE;;;OAGG;IACH,qBAHW,eAAe,GAAG,eAAe,eACjC,OAAO,EAWjB;IARC,gDAA6C;IAC7C;;OAEG;IACH,MAFU,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,EAAE,CAEjB;IAChB,cAAiB;IACjB,qBAA8B;IAIhC;;OAEG;IACH,QAFY,IAAI,GAAG,EAAE,GAAG,IAAI,GAAE,IAAI,CAQjC;CACF;
|
|
1
|
+
{"version":3,"file":"updates.d.ts","sourceRoot":"","sources":["../../../src/utils/updates.js"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attribution.tests.d.ts","sourceRoot":"","sources":["../../tests/attribution.tests.js"],"names":[],"mappings":"AAeO,2CAFI,CAAC,CAAC,QAAQ,QAepB;AAKM,0CAFI,CAAC,CAAC,QAAQ,QAqBpB;AAKM,4DAFI,CAAC,CAAC,QAAQ,QAepB;AAKM,yDAFI,CAAC,CAAC,QAAQ,QAepB;AAEM,
|
|
1
|
+
{"version":3,"file":"attribution.tests.d.ts","sourceRoot":"","sources":["../../tests/attribution.tests.js"],"names":[],"mappings":"AAeO,2CAFI,CAAC,CAAC,QAAQ,QAepB;AAKM,0CAFI,CAAC,CAAC,QAAQ,QAqBpB;AAKM,4DAFI,CAAC,CAAC,QAAQ,QAepB;AAKM,yDAFI,CAAC,CAAC,QAAQ,QAepB;AAEM,qCAoBN;AAEM,6CAqBN;AAKM,4CAFI,CAAC,CAAC,QAAQ,QAqCpB;mBArKkB,cAAc"}
|
|
@@ -6,7 +6,7 @@ export namespace encV1 {
|
|
|
6
6
|
let applyUpdate: (ydoc: Y.Doc, update: Uint8Array, transactionOrigin?: any) => void;
|
|
7
7
|
let logUpdate: (update: Uint8Array) => void;
|
|
8
8
|
let updateEventName: "update";
|
|
9
|
-
let diffUpdate: (update: Uint8Array
|
|
9
|
+
let diffUpdate: (update: Uint8Array<ArrayBuffer>, sv: Uint8Array<ArrayBuffer>) => Uint8Array<ArrayBuffer>;
|
|
10
10
|
}
|
|
11
11
|
export namespace encV2 {
|
|
12
12
|
let encodeStateAsUpdate_1: (doc: Y.Doc, encodedTargetStateVector?: Uint8Array, encoder?: Y.UpdateEncoderV1 | Y.UpdateEncoderV2) => Uint8Array<ArrayBuffer>;
|
|
@@ -14,11 +14,11 @@ export type Enc = {
|
|
|
14
14
|
deletes: Y.IdSet;
|
|
15
15
|
inserts: Y.IdSet;
|
|
16
16
|
};
|
|
17
|
-
encodeStateVector: (arg0: Y.Doc) => Uint8Array
|
|
18
|
-
encodeStateVectorFromUpdate: (arg0: Uint8Array) => Uint8Array
|
|
17
|
+
encodeStateVector: (arg0: Y.Doc) => Uint8Array<ArrayBuffer>;
|
|
18
|
+
encodeStateVectorFromUpdate: (arg0: Uint8Array) => Uint8Array<ArrayBuffer>;
|
|
19
19
|
updateEventName: "update" | "updateV2";
|
|
20
20
|
description: string;
|
|
21
|
-
diffUpdate: (arg0: Uint8Array
|
|
21
|
+
diffUpdate: (arg0: Uint8Array<ArrayBuffer>, arg1: Uint8Array<ArrayBuffer>) => Uint8Array<ArrayBuffer>;
|
|
22
22
|
};
|
|
23
23
|
import * as t from 'lib0/testing';
|
|
24
24
|
import * as Y from '../src/index.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"updates.tests.d.ts","sourceRoot":"","sources":["../../tests/updates.tests.js"],"names":[],"mappings":"AAwGO,qCAFI,CAAC,CAAC,QAAQ,QAapB;AAKM,oCAFI,CAAC,CAAC,QAAQ,QAuBpB;AA0FM,uCAFI,CAAC,CAAC,QAAQ,QAepB;AAKM,uCAFI,CAAC,CAAC,QAAQ,QAepB;AAKM,6CAFI,CAAC,CAAC,QAAQ,QA4CpB;AAKM,0CAFI,CAAC,CAAC,QAAQ,QAgDpB;AAEM,yCAUN;;kBAxWa,CAAS,IAA8B,EAA9B,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,KAAE,UAAU,CAAC,WAAW,CAAC;yBAChE,CAAS,IAAK,EAAL,CAAC,CAAC,GAAG,KAAE,UAAU,CAAC,WAAW,CAAC;iBACvC,CAAS,IAAK,EAAL,CAAC,CAAC,GAAG,EAAE,IAAU,EAAV,UAAU,KAAE,IAAI;eAChC,CAAS,IAAU,EAAV,UAAU,KAAE,IAAI;4BACzB,CAAS,IAAU,EAAV,UAAU,KAAE;QAAC,OAAO,EAAC,CAAC,CAAC,KAAK,CAAC;QAAA,OAAO,EAAC,CAAC,CAAC,KAAK,CAAA;KAAC;uBACtD,CAAS,IAAK,EAAL,CAAC,CAAC,GAAG,KAAE,UAAU;
|
|
1
|
+
{"version":3,"file":"updates.tests.d.ts","sourceRoot":"","sources":["../../tests/updates.tests.js"],"names":[],"mappings":"AAwGO,qCAFI,CAAC,CAAC,QAAQ,QAapB;AAKM,oCAFI,CAAC,CAAC,QAAQ,QAuBpB;AA0FM,uCAFI,CAAC,CAAC,QAAQ,QAepB;AAKM,uCAFI,CAAC,CAAC,QAAQ,QAepB;AAKM,6CAFI,CAAC,CAAC,QAAQ,QA4CpB;AAKM,0CAFI,CAAC,CAAC,QAAQ,QAgDpB;AAEM,yCAUN;;kBAxWa,CAAS,IAA8B,EAA9B,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,KAAE,UAAU,CAAC,WAAW,CAAC;yBAChE,CAAS,IAAK,EAAL,CAAC,CAAC,GAAG,KAAE,UAAU,CAAC,WAAW,CAAC;iBACvC,CAAS,IAAK,EAAL,CAAC,CAAC,GAAG,EAAE,IAAU,EAAV,UAAU,KAAE,IAAI;eAChC,CAAS,IAAU,EAAV,UAAU,KAAE,IAAI;4BACzB,CAAS,IAAU,EAAV,UAAU,KAAE;QAAC,OAAO,EAAC,CAAC,CAAC,KAAK,CAAC;QAAA,OAAO,EAAC,CAAC,CAAC,KAAK,CAAA;KAAC;uBACtD,CAAS,IAAK,EAAL,CAAC,CAAC,GAAG,KAAE,UAAU,CAAC,WAAW,CAAC;iCACvC,CAAS,IAAU,EAAV,UAAU,KAAE,UAAU,CAAC,WAAW,CAAC;qBAC5C,QAAQ,GAAC,UAAU;iBACnB,MAAM;gBACN,CAAS,IAAuB,EAAvB,UAAU,CAAC,WAAW,CAAC,EAAE,IAAuB,EAAvB,UAAU,CAAC,WAAW,CAAC,KAAE,UAAU,CAAC,WAAW,CAAC;;mBArB7E,cAAc;mBACd,iBAAiB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"y-text.tests.d.ts","sourceRoot":"","sources":["../../tests/y-text.tests.js"],"names":[],"mappings":"AAcO,kCAFI,CAAC,CAAC,QAAQ,QAgSpB;AAMM,mCAFI,CAAC,CAAC,QAAQ,QAu5BpB;AASM,uDAFI,CAAC,CAAC,QAAQ,QAoBpB;AAKM,6CAFI,CAAC,CAAC,QAAQ,QAgCpB;AAKM,oCAFI,CAAC,CAAC,QAAQ,QAmCpB;AAKM,qCAFI,CAAC,CAAC,QAAQ,QAkBpB;AAKM,yCAFI,CAAC,CAAC,QAAQ,QAuBpB;AAKM,kDAFI,CAAC,CAAC,QAAQ,QAoBpB;AAKM,yDAFI,CAAC,CAAC,QAAQ,
|
|
1
|
+
{"version":3,"file":"y-text.tests.d.ts","sourceRoot":"","sources":["../../tests/y-text.tests.js"],"names":[],"mappings":"AAcO,kCAFI,CAAC,CAAC,QAAQ,QAgSpB;AAMM,mCAFI,CAAC,CAAC,QAAQ,QAu5BpB;AASM,uDAFI,CAAC,CAAC,QAAQ,QAoBpB;AAKM,6CAFI,CAAC,CAAC,QAAQ,QAgCpB;AAKM,oCAFI,CAAC,CAAC,QAAQ,QAmCpB;AAKM,qCAFI,CAAC,CAAC,QAAQ,QAkBpB;AAKM,yCAFI,CAAC,CAAC,QAAQ,QAuBpB;AAKM,kDAFI,CAAC,CAAC,QAAQ,QAoBpB;AAKM,yDAFI,CAAC,CAAC,QAAQ,QAsBpB;AAKM,2CAFI,CAAC,CAAC,QAAQ,QAUpB;AAKM,qCAFI,CAAC,CAAC,QAAQ,QAqBpB;AAKM,iCAFI,CAAC,CAAC,QAAQ,QAiCpB;AAKM,4CAFI,CAAC,CAAC,QAAQ,QAkBpB;AAKM,qCAFI,CAAC,CAAC,QAAQ,QAMpB;AAKM,+CAFI,CAAC,CAAC,QAAQ,QAepB;AAKM,iDAFI,CAAC,CAAC,QAAQ,QAgBpB;AAKM,0CAFI,CAAC,CAAC,QAAQ,QAQpB;AAKM,mDAFI,CAAC,CAAC,QAAQ,QAQpB;AAOM,kEAFI,CAAC,CAAC,QAAQ,QA4BpB;AAKM,yDAFI,CAAC,CAAC,QAAQ,QA2BpB;AAKM,oCAFI,CAAC,CAAC,QAAQ,QAWpB;AAUM,kCAFI,CAAC,CAAC,QAAQ,QA4BpB;AAaM,iDAFI,CAAC,CAAC,QAAQ,QA6BpB;AAKM,gFAFI,CAAC,CAAC,QAAQ,QAiCpB;AASM,gDAFI,CAAC,CAAC,QAAQ,QA2BpB;AAOM,yCAFI,CAAC,CAAC,QAAQ,QAiCpB;AAKM,uCAFI,CAAC,CAAC,QAAQ,iBAmBpB;AAOM,0CAFI,CAAC,CAAC,QAAQ,QAwBpB;AAKM,2CAFI,CAAC,CAAC,QAAQ,QA0BpB;AAKM,2CAFI,CAAC,CAAC,QAAQ,QA6BpB;AA0CM,mDAFI,CAAC,CAAC,QAAQ,QAMpB;AAKM,oDAFI,CAAC,CAAC,QAAQ,QAMpB;AAKM,oDAFI,CAAC,CAAC,QAAQ,QAMpB;AAKM,oDAFI,CAAC,CAAC,QAAQ,QAMpB;AAKM,oDAFI,CAAC,CAAC,QAAQ,QAMpB;AAKM,oDAFI,CAAC,CAAC,QAAQ,QAMpB;AAKM,qDAFI,CAAC,CAAC,QAAQ,QAMpB;AAuIM,6DAFI,CAAC,CAAC,QAAQ,QAgCpB;AAKM,oDAFI,CAAC,CAAC,QAAQ,QAMpB;AAKM,oDAFI,CAAC,CAAC,QAAQ,QAMpB;AAKM,0DAFI,CAAC,CAAC,QAAQ,QAQpB;AAKM,oDAFI,CAAC,CAAC,QAAQ,QAIpB;AAKM,qDAFI,CAAC,CAAC,QAAQ,QAIpB;AAKM,qDAFI,CAAC,CAAC,QAAQ,QAIpB;AAKM,qDAFI,CAAC,CAAC,QAAQ,QAIpB;AAKM,sDAFI,CAAC,CAAC,QAAQ,QAIpB;AAKM,sDAFI,CAAC,CAAC,QAAQ,QAIpB;mBAhvEkB,cAAc"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@y/y",
|
|
3
|
-
"version": "14.0.0-
|
|
3
|
+
"version": "14.0.0-rc.0",
|
|
4
4
|
"description": "Shared Editing Library",
|
|
5
5
|
"types": "./dist/src/index.d.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -43,7 +43,8 @@
|
|
|
43
43
|
},
|
|
44
44
|
"files": [
|
|
45
45
|
"src",
|
|
46
|
-
"dist"
|
|
46
|
+
"dist",
|
|
47
|
+
"tests/testHelper.js"
|
|
47
48
|
],
|
|
48
49
|
"dictionaries": {
|
|
49
50
|
"test": "tests"
|
|
@@ -75,15 +76,16 @@
|
|
|
75
76
|
},
|
|
76
77
|
"homepage": "https://docs.yjs.dev",
|
|
77
78
|
"dependencies": {
|
|
78
|
-
"lib0": "^1.0.0-
|
|
79
|
+
"lib0": "^1.0.0-rc.2"
|
|
79
80
|
},
|
|
80
81
|
"devDependencies": {
|
|
81
82
|
"@types/node": "^22.14.1",
|
|
82
|
-
"@y/protocols": "^1.0.6-1",
|
|
83
|
+
"@y/protocols": "^1.0.6-rc.1",
|
|
83
84
|
"markdownlint": "^0.40.0",
|
|
84
85
|
"markdownlint-cli": "^0.45.0",
|
|
85
86
|
"standard": "^17.1.2",
|
|
86
|
-
"typescript": "^5.9.3"
|
|
87
|
+
"typescript": "^5.9.3",
|
|
88
|
+
"@y/y": "."
|
|
87
89
|
},
|
|
88
90
|
"engines": {
|
|
89
91
|
"npm": ">=8.0.0",
|
|
@@ -569,7 +569,7 @@ export class DiffAttributionManager extends ObservableV2 {
|
|
|
569
569
|
* @param {Doc} prevDoc
|
|
570
570
|
* @param {Doc} nextDoc
|
|
571
571
|
* @param {Object} [options] - options for the attribution manager
|
|
572
|
-
* @param {
|
|
572
|
+
* @param {import('./meta.js').ContentMap?} [options.attrs] - the attributes to apply to the diff
|
|
573
573
|
*/
|
|
574
574
|
export const createAttributionManagerFromDiff = (prevDoc, nextDoc, options) => new DiffAttributionManager(prevDoc, nextDoc, options)
|
|
575
575
|
|
package/src/utils/UndoManager.js
CHANGED
|
@@ -398,9 +398,10 @@ export class UndoManager extends ObservableV2 {
|
|
|
398
398
|
*
|
|
399
399
|
* @param {Doc} ydoc
|
|
400
400
|
* @param {import('./meta.js').ContentIds} contentIds
|
|
401
|
+
* @param {UndoManagerOptions} opts
|
|
401
402
|
*/
|
|
402
|
-
export const undoContentIds = (ydoc, contentIds) => {
|
|
403
|
-
const um = new UndoManager(ydoc)
|
|
403
|
+
export const undoContentIds = (ydoc, contentIds, opts = {}) => {
|
|
404
|
+
const um = new UndoManager(ydoc, opts)
|
|
404
405
|
um.undoStack.push(new StackItem(diffIdSet(contentIds.inserts, contentIds.deletes), diffIdSet(contentIds.deletes, contentIds.inserts)))
|
|
405
406
|
um.undo()
|
|
406
407
|
}
|
package/src/utils/encoding.js
CHANGED
|
@@ -599,7 +599,7 @@ export const writeDocumentStateVector = (encoder, doc) => writeStateVector(encod
|
|
|
599
599
|
*
|
|
600
600
|
* @param {Doc|Map<number,number>} doc
|
|
601
601
|
* @param {IdSetEncoderV1 | IdSetEncoderV2} [encoder]
|
|
602
|
-
* @return {Uint8Array}
|
|
602
|
+
* @return {Uint8Array<ArrayBuffer>}
|
|
603
603
|
*
|
|
604
604
|
* @function
|
|
605
605
|
*/
|
|
@@ -616,7 +616,7 @@ export const encodeStateVectorV2 = (doc, encoder = new IdSetEncoderV2()) => {
|
|
|
616
616
|
* Encode State as Uint8Array.
|
|
617
617
|
*
|
|
618
618
|
* @param {Doc|Map<number,number>} doc
|
|
619
|
-
* @return {Uint8Array}
|
|
619
|
+
* @return {Uint8Array<ArrayBuffer>}
|
|
620
620
|
*
|
|
621
621
|
* @function
|
|
622
622
|
*/
|
package/src/utils/updates.js
CHANGED
|
@@ -115,7 +115,6 @@ export class LazyStructReader {
|
|
|
115
115
|
|
|
116
116
|
/**
|
|
117
117
|
* @param {Uint8Array} update
|
|
118
|
-
*
|
|
119
118
|
*/
|
|
120
119
|
export const logUpdate = update => logUpdateV2(update, UpdateDecoderV1)
|
|
121
120
|
|
|
@@ -137,7 +136,6 @@ export const logUpdateV2 = (update, YDecoder = UpdateDecoderV2) => {
|
|
|
137
136
|
|
|
138
137
|
/**
|
|
139
138
|
* @param {Uint8Array} update
|
|
140
|
-
*
|
|
141
139
|
*/
|
|
142
140
|
export const decodeUpdate = (update) => decodeUpdateV2(update, UpdateDecoderV1)
|
|
143
141
|
|
|
@@ -192,7 +190,7 @@ export const mergeUpdates = updates => mergeUpdatesV2(updates, UpdateDecoderV1,
|
|
|
192
190
|
* @param {Uint8Array} update
|
|
193
191
|
* @param {typeof IdSetEncoderV1 | typeof IdSetEncoderV2} YEncoder
|
|
194
192
|
* @param {typeof UpdateDecoderV1 | typeof UpdateDecoderV2} YDecoder
|
|
195
|
-
* @return {Uint8Array}
|
|
193
|
+
* @return {Uint8Array<ArrayBuffer>}
|
|
196
194
|
*/
|
|
197
195
|
export const encodeStateVectorFromUpdateV2 = (update, YEncoder = IdSetEncoderV2, YDecoder = UpdateDecoderV2) => {
|
|
198
196
|
const encoder = new YEncoder()
|
|
@@ -244,7 +242,7 @@ export const encodeStateVectorFromUpdateV2 = (update, YEncoder = IdSetEncoderV2,
|
|
|
244
242
|
|
|
245
243
|
/**
|
|
246
244
|
* @param {Uint8Array} update
|
|
247
|
-
* @return {Uint8Array}
|
|
245
|
+
* @return {Uint8Array<ArrayBuffer>}
|
|
248
246
|
*/
|
|
249
247
|
export const encodeStateVectorFromUpdate = update => encodeStateVectorFromUpdateV2(update, IdSetEncoderV1, UpdateDecoderV1)
|
|
250
248
|
|
|
@@ -502,8 +500,8 @@ export const diffUpdateV2 = (update, sv, YDecoder = UpdateDecoderV2, YEncoder =
|
|
|
502
500
|
* @deprecated
|
|
503
501
|
* @todo remove this in favor of intersectupdate
|
|
504
502
|
*
|
|
505
|
-
* @param {Uint8Array} update
|
|
506
|
-
* @param {Uint8Array} sv
|
|
503
|
+
* @param {Uint8Array<ArrayBuffer>} update
|
|
504
|
+
* @param {Uint8Array<ArrayBuffer>} sv
|
|
507
505
|
*/
|
|
508
506
|
export const diffUpdate = (update, sv) => diffUpdateV2(update, sv, UpdateDecoderV1, UpdateEncoderV1)
|
|
509
507
|
|
|
@@ -734,7 +732,7 @@ export const convertUpdateFormatV2ToV1 = update => convertUpdateFormat(update, f
|
|
|
734
732
|
* @param {import('./meta.js').ContentIds} contentIds - Pattern specifying which content to include
|
|
735
733
|
* @param {typeof UpdateDecoderV1 | typeof UpdateDecoderV2} [YDecoder]
|
|
736
734
|
* @param {typeof UpdateEncoderV1 | typeof UpdateEncoderV2} [YEncoder]
|
|
737
|
-
* @return {Uint8Array}
|
|
735
|
+
* @return {Uint8Array<ArrayBuffer>}
|
|
738
736
|
*/
|
|
739
737
|
export const intersectUpdateWithContentIdsV2 = (update, contentIds, YDecoder = UpdateDecoderV2, YEncoder = UpdateEncoderV2) => {
|
|
740
738
|
const { inserts, deletes } = contentIds
|
|
@@ -778,25 +776,27 @@ export const intersectUpdateWithContentIdsV2 = (update, contentIds, YDecoder = U
|
|
|
778
776
|
*
|
|
779
777
|
* @param {Uint8Array} update
|
|
780
778
|
* @param {import('./meta.js').ContentIds} contentIds - Pattern specifying which content to include
|
|
781
|
-
* @return {Uint8Array}
|
|
779
|
+
* @return {Uint8Array<ArrayBuffer>}
|
|
782
780
|
*/
|
|
783
781
|
export const intersectUpdateWithContentIds = (update, contentIds) =>
|
|
784
782
|
intersectUpdateWithContentIdsV2(update, contentIds, UpdateDecoderV1, UpdateEncoderV1)
|
|
785
783
|
|
|
786
784
|
/**
|
|
787
785
|
* @param {Uint8Array} update
|
|
786
|
+
* @param {import('./Doc.js').DocOpts} opts
|
|
788
787
|
*/
|
|
789
|
-
export const createDocFromUpdate = update => {
|
|
790
|
-
const ydoc = new Doc()
|
|
788
|
+
export const createDocFromUpdate = (update, opts = {}) => {
|
|
789
|
+
const ydoc = new Doc(opts)
|
|
791
790
|
applyUpdate(ydoc, update)
|
|
792
791
|
return ydoc
|
|
793
792
|
}
|
|
794
793
|
|
|
795
794
|
/**
|
|
796
795
|
* @param {Uint8Array} update
|
|
796
|
+
* @param {import('./Doc.js').DocOpts} opts
|
|
797
797
|
*/
|
|
798
|
-
export const createDocFromUpdateV2 = update => {
|
|
799
|
-
const ydoc = new Doc()
|
|
798
|
+
export const createDocFromUpdateV2 = (update, opts = {}) => {
|
|
799
|
+
const ydoc = new Doc(opts)
|
|
800
800
|
applyUpdateV2(ydoc, update)
|
|
801
801
|
return ydoc
|
|
802
802
|
}
|
package/src/ytype.js
CHANGED
|
@@ -1179,7 +1179,7 @@ export class YType {
|
|
|
1179
1179
|
* @param {delta.FormattingAttributes} [format]
|
|
1180
1180
|
*/
|
|
1181
1181
|
insert (index, content, format) {
|
|
1182
|
-
this.applyDelta(delta.create().retain(index).insert(/** @type {any} */ (content), format))
|
|
1182
|
+
this.applyDelta(delta.create().retain(index).insert(/** @type {any} */ (content), format).done())
|
|
1183
1183
|
}
|
|
1184
1184
|
|
|
1185
1185
|
/**
|
|
@@ -0,0 +1,594 @@
|
|
|
1
|
+
import * as t from 'lib0/testing'
|
|
2
|
+
import * as prng from 'lib0/prng'
|
|
3
|
+
import * as encoding from 'lib0/encoding'
|
|
4
|
+
import * as decoding from 'lib0/decoding'
|
|
5
|
+
import * as syncProtocol from '@y/protocols/sync'
|
|
6
|
+
import * as object from 'lib0/object'
|
|
7
|
+
import * as map from 'lib0/map'
|
|
8
|
+
import * as Y from '../src/index.js'
|
|
9
|
+
import * as math from 'lib0/math'
|
|
10
|
+
import * as list from 'lib0/list'
|
|
11
|
+
import * as delta from 'lib0/delta'
|
|
12
|
+
import {
|
|
13
|
+
createIdSet, createIdMap, addToIdSet, encodeIdMap
|
|
14
|
+
} from '../src/internals.js'
|
|
15
|
+
|
|
16
|
+
export * from '../src/index.js'
|
|
17
|
+
|
|
18
|
+
if (typeof window !== 'undefined') {
|
|
19
|
+
// @ts-ignore
|
|
20
|
+
window.Y = Y // eslint-disable-line
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @param {TestYInstance} y // publish message created by `y` to all other online clients
|
|
25
|
+
* @param {Uint8Array} m
|
|
26
|
+
*/
|
|
27
|
+
const broadcastMessage = (y, m) => {
|
|
28
|
+
if (y.tc.onlineConns.has(y)) {
|
|
29
|
+
y.tc.onlineConns.forEach(remoteYInstance => {
|
|
30
|
+
if (remoteYInstance !== y) {
|
|
31
|
+
remoteYInstance._receive(m, y)
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export let useV2 = false
|
|
38
|
+
|
|
39
|
+
export const encV1 = {
|
|
40
|
+
encodeStateAsUpdate: Y.encodeStateAsUpdate,
|
|
41
|
+
mergeUpdates: Y.mergeUpdates,
|
|
42
|
+
applyUpdate: Y.applyUpdate,
|
|
43
|
+
logUpdate: Y.logUpdate,
|
|
44
|
+
updateEventName: /** @type {'update'} */ ('update'),
|
|
45
|
+
diffUpdate: Y.diffUpdate
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export const encV2 = {
|
|
49
|
+
encodeStateAsUpdate: Y.encodeStateAsUpdateV2,
|
|
50
|
+
mergeUpdates: Y.mergeUpdatesV2,
|
|
51
|
+
applyUpdate: Y.applyUpdateV2,
|
|
52
|
+
logUpdate: Y.logUpdateV2,
|
|
53
|
+
updateEventName: /** @type {'updateV2'} */ ('updateV2'),
|
|
54
|
+
diffUpdate: Y.diffUpdateV2
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export let enc = encV1
|
|
58
|
+
|
|
59
|
+
const useV1Encoding = () => {
|
|
60
|
+
useV2 = false
|
|
61
|
+
enc = encV1
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const useV2Encoding = () => {
|
|
65
|
+
console.error('sync protocol doesnt support v2 protocol yet, fallback to v1 encoding') // @Todo
|
|
66
|
+
useV2 = false
|
|
67
|
+
enc = encV1
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export class TestYInstance extends Y.Doc {
|
|
71
|
+
/**
|
|
72
|
+
* @param {TestConnector} testConnector
|
|
73
|
+
* @param {number} clientID
|
|
74
|
+
*/
|
|
75
|
+
constructor (testConnector, clientID) {
|
|
76
|
+
super()
|
|
77
|
+
this.userID = clientID // overwriting clientID
|
|
78
|
+
/**
|
|
79
|
+
* @type {TestConnector}
|
|
80
|
+
*/
|
|
81
|
+
this.tc = testConnector
|
|
82
|
+
/**
|
|
83
|
+
* @type {Map<TestYInstance, Array<Uint8Array>>}
|
|
84
|
+
*/
|
|
85
|
+
this.receiving = new Map()
|
|
86
|
+
testConnector.allConns.add(this)
|
|
87
|
+
/**
|
|
88
|
+
* The list of received updates.
|
|
89
|
+
* We are going to merge them later using Y.mergeUpdates and check if the resulting document is correct.
|
|
90
|
+
* @type {Array<Uint8Array<ArrayBuffer>>}
|
|
91
|
+
*/
|
|
92
|
+
this.updates = []
|
|
93
|
+
// set up observe on local model
|
|
94
|
+
this.on(enc.updateEventName, (update, origin) => {
|
|
95
|
+
if (origin !== testConnector) {
|
|
96
|
+
const encoder = encoding.createEncoder()
|
|
97
|
+
syncProtocol.writeUpdate(encoder, update)
|
|
98
|
+
broadcastMessage(this, encoding.toUint8Array(encoder))
|
|
99
|
+
}
|
|
100
|
+
this.updates.push(update)
|
|
101
|
+
})
|
|
102
|
+
this.connect()
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Disconnect from TestConnector.
|
|
107
|
+
*/
|
|
108
|
+
disconnect () {
|
|
109
|
+
this.receiving = new Map()
|
|
110
|
+
this.tc.onlineConns.delete(this)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Append yourself to the list of known Y instances in testconnector.
|
|
115
|
+
* Also initiate sync with all clients.
|
|
116
|
+
*/
|
|
117
|
+
connect () {
|
|
118
|
+
if (!this.tc.onlineConns.has(this)) {
|
|
119
|
+
this.tc.onlineConns.add(this)
|
|
120
|
+
const encoder = encoding.createEncoder()
|
|
121
|
+
syncProtocol.writeSyncStep1(encoder, this)
|
|
122
|
+
// publish SyncStep1
|
|
123
|
+
broadcastMessage(this, encoding.toUint8Array(encoder))
|
|
124
|
+
this.tc.onlineConns.forEach(remoteYInstance => {
|
|
125
|
+
if (remoteYInstance !== this) {
|
|
126
|
+
// remote instance sends instance to this instance
|
|
127
|
+
const encoder = encoding.createEncoder()
|
|
128
|
+
syncProtocol.writeSyncStep1(encoder, remoteYInstance)
|
|
129
|
+
this._receive(encoding.toUint8Array(encoder), remoteYInstance)
|
|
130
|
+
}
|
|
131
|
+
})
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Receive a message from another client. This message is only appended to the list of receiving messages.
|
|
137
|
+
* TestConnector decides when this client actually reads this message.
|
|
138
|
+
*
|
|
139
|
+
* @param {Uint8Array} message
|
|
140
|
+
* @param {TestYInstance} remoteClient
|
|
141
|
+
*/
|
|
142
|
+
_receive (message, remoteClient) {
|
|
143
|
+
map.setIfUndefined(this.receiving, remoteClient, () => /** @type {Array<Uint8Array>} */ ([])).push(message)
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Keeps track of TestYInstances.
|
|
149
|
+
*
|
|
150
|
+
* The TestYInstances add/remove themselves from the list of connections maiained in this object.
|
|
151
|
+
* I think it makes sense. Deal with it.
|
|
152
|
+
*/
|
|
153
|
+
export class TestConnector {
|
|
154
|
+
/**
|
|
155
|
+
* @param {prng.PRNG} gen
|
|
156
|
+
*/
|
|
157
|
+
constructor (gen) {
|
|
158
|
+
/**
|
|
159
|
+
* @type {Set<TestYInstance>}
|
|
160
|
+
*/
|
|
161
|
+
this.allConns = new Set()
|
|
162
|
+
/**
|
|
163
|
+
* @type {Set<TestYInstance>}
|
|
164
|
+
*/
|
|
165
|
+
this.onlineConns = new Set()
|
|
166
|
+
/**
|
|
167
|
+
* @type {prng.PRNG}
|
|
168
|
+
*/
|
|
169
|
+
this.prng = gen
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Create a new Y instance and add it to the list of connections
|
|
174
|
+
* @param {number} clientID
|
|
175
|
+
*/
|
|
176
|
+
createY (clientID) {
|
|
177
|
+
return new TestYInstance(this, clientID)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Choose random connection and flush a random message from a random sender.
|
|
182
|
+
*
|
|
183
|
+
* If this function was unable to flush a message, because there are no more messages to flush, it returns false. true otherwise.
|
|
184
|
+
* @return {boolean}
|
|
185
|
+
*/
|
|
186
|
+
flushRandomMessage () {
|
|
187
|
+
const gen = this.prng
|
|
188
|
+
const conns = Array.from(this.onlineConns).filter(conn => conn.receiving.size > 0)
|
|
189
|
+
if (conns.length > 0) {
|
|
190
|
+
const receiver = prng.oneOf(gen, conns)
|
|
191
|
+
const [sender, messages] = prng.oneOf(gen, Array.from(receiver.receiving))
|
|
192
|
+
const m = messages.shift()
|
|
193
|
+
if (messages.length === 0) {
|
|
194
|
+
receiver.receiving.delete(sender)
|
|
195
|
+
}
|
|
196
|
+
if (m === undefined) {
|
|
197
|
+
return this.flushRandomMessage()
|
|
198
|
+
}
|
|
199
|
+
const encoder = encoding.createEncoder()
|
|
200
|
+
// console.log('receive (' + sender.userID + '->' + receiver.userID + '):\n', syncProtocol.stringifySyncMessage(decoding.createDecoder(m), receiver))
|
|
201
|
+
// do not publish data created when this function is executed (could be ss2 or update message)
|
|
202
|
+
syncProtocol.readSyncMessage(decoding.createDecoder(m), encoder, receiver, receiver.tc)
|
|
203
|
+
if (encoding.length(encoder) > 0) {
|
|
204
|
+
// send reply message
|
|
205
|
+
sender._receive(encoding.toUint8Array(encoder), receiver)
|
|
206
|
+
}
|
|
207
|
+
return true
|
|
208
|
+
}
|
|
209
|
+
return false
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* @return {boolean} True iff this function actually flushed something
|
|
214
|
+
*/
|
|
215
|
+
flushAllMessages () {
|
|
216
|
+
let didSomething = false
|
|
217
|
+
while (this.flushRandomMessage()) {
|
|
218
|
+
didSomething = true
|
|
219
|
+
}
|
|
220
|
+
return didSomething
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
reconnectAll () {
|
|
224
|
+
this.allConns.forEach(conn => conn.connect())
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
disconnectAll () {
|
|
228
|
+
this.allConns.forEach(conn => conn.disconnect())
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
syncAll () {
|
|
232
|
+
this.reconnectAll()
|
|
233
|
+
this.flushAllMessages()
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* @return {boolean} Whether it was possible to disconnect a random connection.
|
|
238
|
+
*/
|
|
239
|
+
disconnectRandom () {
|
|
240
|
+
if (this.onlineConns.size === 0) {
|
|
241
|
+
return false
|
|
242
|
+
}
|
|
243
|
+
prng.oneOf(this.prng, Array.from(this.onlineConns)).disconnect()
|
|
244
|
+
return true
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* @return {boolean} Whether it was possible to reconnect a random connection.
|
|
249
|
+
*/
|
|
250
|
+
reconnectRandom () {
|
|
251
|
+
/**
|
|
252
|
+
* @type {Array<TestYInstance>}
|
|
253
|
+
*/
|
|
254
|
+
const reconnectable = []
|
|
255
|
+
this.allConns.forEach(conn => {
|
|
256
|
+
if (!this.onlineConns.has(conn)) {
|
|
257
|
+
reconnectable.push(conn)
|
|
258
|
+
}
|
|
259
|
+
})
|
|
260
|
+
if (reconnectable.length === 0) {
|
|
261
|
+
return false
|
|
262
|
+
}
|
|
263
|
+
prng.oneOf(this.prng, reconnectable).connect()
|
|
264
|
+
return true
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* @template T
|
|
270
|
+
* @param {t.TestCase} tc
|
|
271
|
+
* @param {{users?:number}} conf
|
|
272
|
+
* @param {InitTestObjectCallback<T>} [initTestObject]
|
|
273
|
+
* @return {{testObjects:Array<any>,testConnector:TestConnector,users:Array<TestYInstance>,array0:Y.Type<any>,array1:Y.Type<any>,array2:Y.Type<any>,map0:Y.Type<any>,map1:Y.Type<any>,map2:Y.Type<any>,map3:Y.Type<any>,text0:Y.Type,text1:Y.Type,text2:Y.Type,xml0:Y.Type,xml1:Y.Type,xml2:Y.Type}}
|
|
274
|
+
*/
|
|
275
|
+
export const init = (tc, { users = 5 } = {}, initTestObject) => {
|
|
276
|
+
/**
|
|
277
|
+
* @type {Object<string,any>}
|
|
278
|
+
*/
|
|
279
|
+
const result = {
|
|
280
|
+
users: []
|
|
281
|
+
}
|
|
282
|
+
const gen = tc.prng
|
|
283
|
+
// choose an encoding approach at random
|
|
284
|
+
if (prng.bool(gen)) {
|
|
285
|
+
useV2Encoding()
|
|
286
|
+
} else {
|
|
287
|
+
useV1Encoding()
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
const testConnector = new TestConnector(gen)
|
|
291
|
+
result.testConnector = testConnector
|
|
292
|
+
for (let i = 0; i < users; i++) {
|
|
293
|
+
const y = testConnector.createY(i)
|
|
294
|
+
y.clientID = i
|
|
295
|
+
result.users.push(y)
|
|
296
|
+
result['array' + i] = y.get('array')
|
|
297
|
+
result['map' + i] = y.get('map')
|
|
298
|
+
result['xml' + i] = y.get('xml')
|
|
299
|
+
result['text' + i] = y.get('text')
|
|
300
|
+
}
|
|
301
|
+
testConnector.syncAll()
|
|
302
|
+
result.testObjects = result.users.map(initTestObject || (() => null))
|
|
303
|
+
useV1Encoding()
|
|
304
|
+
return /** @type {any} */ (result)
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* @param {Y.IdSet} idSet1
|
|
309
|
+
* @param {Y.IdSet} idSet2
|
|
310
|
+
*/
|
|
311
|
+
export const compareIdSets = (idSet1, idSet2) => {
|
|
312
|
+
t.assert(idSet1.clients.size === idSet2.clients.size)
|
|
313
|
+
for (const [client, _items1] of idSet1.clients.entries()) {
|
|
314
|
+
const items1 = _items1.getIds()
|
|
315
|
+
const items2 = idSet2.clients.get(client)?.getIds()
|
|
316
|
+
t.assert(items2 !== undefined && items1.length === items2.length)
|
|
317
|
+
for (let i = 0; i < items1.length; i++) {
|
|
318
|
+
const di1 = items1[i]
|
|
319
|
+
const di2 = /** @type {Array<import('../src/utils/IdSet.js').IdRange>} */ (items2)[i]
|
|
320
|
+
t.assert(di1.clock === di2.clock && di1.len === di2.len)
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return true
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* only use for testing
|
|
328
|
+
*
|
|
329
|
+
* @template T
|
|
330
|
+
* @param {Array<Y.ContentAttribute<T>>} attrs
|
|
331
|
+
* @param {Y.ContentAttribute<T>} attr
|
|
332
|
+
*
|
|
333
|
+
*/
|
|
334
|
+
const _idmapAttrsHas = (attrs, attr) => {
|
|
335
|
+
const hash = attr.hash()
|
|
336
|
+
return attrs.find(a => a.hash() === hash)
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* only use for testing
|
|
341
|
+
*
|
|
342
|
+
* @template T
|
|
343
|
+
* @param {Array<Y.ContentAttribute<T>>} a
|
|
344
|
+
* @param {Array<Y.ContentAttribute<T>>} b
|
|
345
|
+
*/
|
|
346
|
+
export const _idmapAttrsEqual = (a, b) => a.length === b.length && a.every(v => _idmapAttrsHas(b, v))
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Ensure that all attributes exist. Also create a copy and compare it to the original.
|
|
350
|
+
*
|
|
351
|
+
* @template T
|
|
352
|
+
* @param {Y.IdMap<T>} idmap
|
|
353
|
+
*/
|
|
354
|
+
export const validateIdMap = idmap => {
|
|
355
|
+
const copy = Y.createIdMap()
|
|
356
|
+
idmap.clients.forEach((ranges, client) => {
|
|
357
|
+
ranges.getIds().forEach(range => {
|
|
358
|
+
range.attrs.forEach(attr => {
|
|
359
|
+
t.assert(idmap.attrs.has(attr))
|
|
360
|
+
t.assert(idmap.attrsH.get(attr.hash()) === attr)
|
|
361
|
+
copy.add(client, range.clock, range.len, range.attrs.slice())
|
|
362
|
+
})
|
|
363
|
+
})
|
|
364
|
+
t.assert(copy.clients.get(client)?.getIds().length === ranges.getIds().length)
|
|
365
|
+
})
|
|
366
|
+
t.assert(idmap.attrsH.size === idmap.attrs.size)
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* @template T
|
|
371
|
+
* @param {Y.IdMap<T>} idmap1
|
|
372
|
+
* @param {Y.IdMap<T>} idmap2
|
|
373
|
+
*/
|
|
374
|
+
export const compareIdmaps = (idmap1, idmap2) => {
|
|
375
|
+
t.assert(idmap1.clients.size === idmap2.clients.size)
|
|
376
|
+
for (const [client, _items1] of idmap1.clients.entries()) {
|
|
377
|
+
const items1 = _items1.getIds()
|
|
378
|
+
const items2 = idmap2.clients.get(client)?.getIds()
|
|
379
|
+
t.assert(items2 !== undefined && items1.length === items2.length)
|
|
380
|
+
for (let i = 0; i < items1.length; i++) {
|
|
381
|
+
const di1 = items1[i]
|
|
382
|
+
const di2 = /** @type {Array<import('../src/utils/IdMap.js').AttrRange<T>>} */ (items2)[i]
|
|
383
|
+
t.assert(di1.clock === di2.clock && di1.len === di2.len && _idmapAttrsEqual(di1.attrs, di2.attrs))
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
validateIdMap(idmap1)
|
|
387
|
+
validateIdMap(idmap2)
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* @param {prng.PRNG} gen
|
|
392
|
+
* @param {number} clients
|
|
393
|
+
* @param {number} clockRange (max clock - exclusive - by each client)
|
|
394
|
+
*/
|
|
395
|
+
export const createRandomIdSet = (gen, clients, clockRange) => {
|
|
396
|
+
const maxOpLen = 5
|
|
397
|
+
const numOfOps = math.ceil((clients * clockRange) / maxOpLen)
|
|
398
|
+
const idset = createIdSet()
|
|
399
|
+
for (let i = 0; i < numOfOps; i++) {
|
|
400
|
+
const client = prng.uint32(gen, 0, clients - 1)
|
|
401
|
+
const clockStart = prng.uint32(gen, 0, clockRange)
|
|
402
|
+
const len = prng.uint32(gen, 0, clockRange - clockStart)
|
|
403
|
+
addToIdSet(idset, client, clockStart, len)
|
|
404
|
+
}
|
|
405
|
+
if (idset.clients.size === clients && clients > 1 && prng.bool(gen)) {
|
|
406
|
+
idset.clients.delete(prng.uint32(gen, 0, clients))
|
|
407
|
+
}
|
|
408
|
+
return idset
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* @template T
|
|
413
|
+
* @param {prng.PRNG} gen
|
|
414
|
+
* @param {number} clients
|
|
415
|
+
* @param {number} clockRange (max clock - exclusive - by each client)
|
|
416
|
+
* @param {Array<T>} attrChoices (max clock - exclusive - by each client)
|
|
417
|
+
* @return {Y.IdMap<T>}
|
|
418
|
+
*/
|
|
419
|
+
export const createRandomIdMap = (gen, clients, clockRange, attrChoices) => {
|
|
420
|
+
const maxOpLen = 5
|
|
421
|
+
const numOfOps = math.ceil((clients * clockRange) / maxOpLen)
|
|
422
|
+
const idMap = createIdMap()
|
|
423
|
+
for (let i = 0; i < numOfOps; i++) {
|
|
424
|
+
const client = prng.uint32(gen, 0, clients - 1)
|
|
425
|
+
const clockStart = prng.uint32(gen, 0, clockRange)
|
|
426
|
+
const len = prng.uint32(gen, 0, clockRange - clockStart)
|
|
427
|
+
const attrs = [prng.oneOf(gen, attrChoices)]
|
|
428
|
+
// maybe add another attr
|
|
429
|
+
if (prng.bool(gen)) {
|
|
430
|
+
const a = prng.oneOf(gen, attrChoices)
|
|
431
|
+
if (attrs.find(attr => attr === a) == null) {
|
|
432
|
+
attrs.push(a)
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
idMap.add(client, clockStart, len, attrs.map(v => Y.createContentAttribute('', v)))
|
|
436
|
+
}
|
|
437
|
+
t.info(`Created IdMap with ${numOfOps} ranges and ${attrChoices.length} different attributes. Encoded size: ${encodeIdMap(idMap).byteLength}`)
|
|
438
|
+
return idMap
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* 1. reconnect and flush all
|
|
443
|
+
* 2. user 0 gc
|
|
444
|
+
* 3. get type content
|
|
445
|
+
* 4. disconnect & reconnect all (so gc is propagated)
|
|
446
|
+
* 5. compare os, ds, ss
|
|
447
|
+
*
|
|
448
|
+
* @param {Array<TestYInstance>} users
|
|
449
|
+
*/
|
|
450
|
+
export const compare = users => {
|
|
451
|
+
users.forEach(u => u.connect())
|
|
452
|
+
while (users[0].tc.flushAllMessages()) {} // eslint-disable-line
|
|
453
|
+
// For each document, merge all received document updates with Y.mergeUpdates and create a new document which will be added to the list of "users"
|
|
454
|
+
// This ensures that mergeUpdates works correctly
|
|
455
|
+
const mergedDocs = users.map(user => {
|
|
456
|
+
const ydoc = new Y.Doc()
|
|
457
|
+
enc.applyUpdate(ydoc, enc.mergeUpdates(user.updates))
|
|
458
|
+
return ydoc
|
|
459
|
+
})
|
|
460
|
+
users.push(.../** @type {any} */(mergedDocs))
|
|
461
|
+
const userArrayValues = users.map(u => u.get('array').toJSON().children ?? [])
|
|
462
|
+
const userMapValues = users.map(u => u.get('map').toJSON().attrs ?? {})
|
|
463
|
+
// @todo fix type error here
|
|
464
|
+
// @ts-ignore
|
|
465
|
+
const userXmlValues = users.map(u => u.get('xml').toString())
|
|
466
|
+
const userTextValues = users.map(u => u.get('text').toDeltaDeep())
|
|
467
|
+
for (const u of users) {
|
|
468
|
+
t.assert(u.store.pendingDs === null)
|
|
469
|
+
t.assert(u.store.pendingStructs === null)
|
|
470
|
+
}
|
|
471
|
+
// Test Map iterator
|
|
472
|
+
const ymapkeys = Array.from(users[0].get('map').attrKeys())
|
|
473
|
+
t.assert(ymapkeys.length === Object.keys(userMapValues[0]).length)
|
|
474
|
+
ymapkeys.forEach(key => t.assert(object.hasProperty(userMapValues[0], key)))
|
|
475
|
+
// Compare all users
|
|
476
|
+
for (let i = 0; i < users.length - 1; i++) {
|
|
477
|
+
t.compare(userArrayValues[i].length, users[i].get('array').length)
|
|
478
|
+
t.compare(userArrayValues[i], userArrayValues[i + 1])
|
|
479
|
+
t.compare(userMapValues[i], userMapValues[i + 1])
|
|
480
|
+
t.compare(userXmlValues[i], userXmlValues[i + 1])
|
|
481
|
+
t.compare(list.toArray(userTextValues[i].children).map(a => (delta.$textOp.check(a) || delta.$insertOp.check(a)) ? a.insert.length : 0).reduce((a, b) => a + b, 0), users[i].get('text').length)
|
|
482
|
+
t.compare(userTextValues[i], userTextValues[i + 1], '', (_constructor, a, b) => {
|
|
483
|
+
if (a instanceof Y.Type) {
|
|
484
|
+
t.compare(a.toJSON(), b.toJSON())
|
|
485
|
+
} else if (a !== b) {
|
|
486
|
+
t.fail('Deltas dont match')
|
|
487
|
+
}
|
|
488
|
+
return true
|
|
489
|
+
})
|
|
490
|
+
t.compare(Y.encodeStateVector(users[i]), Y.encodeStateVector(users[i + 1]))
|
|
491
|
+
Y.equalIdSets(Y.createDeleteSetFromStructStore(users[i].store), Y.createDeleteSetFromStructStore(users[i + 1].store))
|
|
492
|
+
compareStructStores(users[i].store, users[i + 1].store)
|
|
493
|
+
t.compare(Y.encodeSnapshot(Y.snapshot(users[i])), Y.encodeSnapshot(Y.snapshot(users[i + 1])))
|
|
494
|
+
}
|
|
495
|
+
users.forEach(user => {
|
|
496
|
+
compareIdSets(user.store.ds, Y.createDeleteSetFromStructStore(user.store))
|
|
497
|
+
})
|
|
498
|
+
users.map(u => u.destroy())
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* @param {Y.Item?} a
|
|
503
|
+
* @param {Y.Item?} b
|
|
504
|
+
* @return {boolean}
|
|
505
|
+
*/
|
|
506
|
+
export const compareItemIDs = (a, b) => a === b || (a !== null && b != null && Y.compareIDs(a.id, b.id))
|
|
507
|
+
|
|
508
|
+
/**
|
|
509
|
+
* @param {import('../src/internals.js').StructStore} ss1
|
|
510
|
+
* @param {import('../src/internals.js').StructStore} ss2
|
|
511
|
+
*/
|
|
512
|
+
export const compareStructStores = (ss1, ss2) => {
|
|
513
|
+
t.assert(ss1.clients.size === ss2.clients.size)
|
|
514
|
+
for (const [client, structs1] of ss1.clients) {
|
|
515
|
+
const structs2 = /** @type {Array<Y.AbstractStruct>} */ (ss2.clients.get(client))
|
|
516
|
+
t.assert(structs2 !== undefined && structs1.length === structs2.length)
|
|
517
|
+
for (let i = 0; i < structs1.length; i++) {
|
|
518
|
+
const s1 = structs1[i]
|
|
519
|
+
const s2 = structs2[i]
|
|
520
|
+
// checks for abstract struct
|
|
521
|
+
if (
|
|
522
|
+
s1.constructor !== s2.constructor ||
|
|
523
|
+
!Y.compareIDs(s1.id, s2.id) ||
|
|
524
|
+
s1.deleted !== s2.deleted ||
|
|
525
|
+
// @ts-ignore
|
|
526
|
+
s1.length !== s2.length
|
|
527
|
+
) {
|
|
528
|
+
t.fail('Structs dont match')
|
|
529
|
+
}
|
|
530
|
+
if (s1 instanceof Y.Item) {
|
|
531
|
+
if (
|
|
532
|
+
!(s2 instanceof Y.Item) ||
|
|
533
|
+
!((s1.left === null && s2.left === null) || (s1.left !== null && s2.left !== null && Y.compareIDs(s1.left.lastId, s2.left.lastId))) ||
|
|
534
|
+
!compareItemIDs(s1.right, s2.right) ||
|
|
535
|
+
!Y.compareIDs(s1.origin, s2.origin) ||
|
|
536
|
+
!Y.compareIDs(s1.rightOrigin, s2.rightOrigin) ||
|
|
537
|
+
s1.parentSub !== s2.parentSub
|
|
538
|
+
) {
|
|
539
|
+
return t.fail('Items dont match')
|
|
540
|
+
}
|
|
541
|
+
// make sure that items are connected correctly
|
|
542
|
+
t.assert(s1.left === null || s1.left.right === s1)
|
|
543
|
+
t.assert(s1.right === null || s1.right.left === s1)
|
|
544
|
+
t.assert(s2.left === null || s2.left.right === s2)
|
|
545
|
+
t.assert(s2.right === null || s2.right.left === s2)
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* @template T
|
|
553
|
+
* @callback InitTestObjectCallback
|
|
554
|
+
* @param {TestYInstance} y
|
|
555
|
+
* @return {T}
|
|
556
|
+
*/
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* @template T
|
|
560
|
+
* @param {t.TestCase} tc
|
|
561
|
+
* @param {Array<function(Y.Doc,prng.PRNG,T):void>} mods
|
|
562
|
+
* @param {number} iterations
|
|
563
|
+
* @param {InitTestObjectCallback<T>} [initTestObject]
|
|
564
|
+
*/
|
|
565
|
+
export const applyRandomTests = (tc, mods, iterations, initTestObject) => {
|
|
566
|
+
const gen = tc.prng
|
|
567
|
+
const result = init(tc, { users: 5 }, initTestObject)
|
|
568
|
+
const { testConnector, users } = result
|
|
569
|
+
for (let i = 0; i < iterations; i++) {
|
|
570
|
+
if (prng.int32(gen, 0, 100) <= 2) {
|
|
571
|
+
// 2% chance to disconnect/reconnect a random user
|
|
572
|
+
if (prng.bool(gen)) {
|
|
573
|
+
testConnector.disconnectRandom()
|
|
574
|
+
} else {
|
|
575
|
+
testConnector.reconnectRandom()
|
|
576
|
+
}
|
|
577
|
+
} else if (prng.int32(gen, 0, 100) <= 1) {
|
|
578
|
+
// 1% chance to flush all
|
|
579
|
+
testConnector.flushAllMessages()
|
|
580
|
+
} else if (prng.int32(gen, 0, 100) <= 50) {
|
|
581
|
+
// 50% chance to flush a random message
|
|
582
|
+
testConnector.flushRandomMessage()
|
|
583
|
+
}
|
|
584
|
+
const user = prng.int32(gen, 0, users.length - 1)
|
|
585
|
+
const test = prng.oneOf(gen, mods)
|
|
586
|
+
test(users[user], gen, result.testObjects[user])
|
|
587
|
+
}
|
|
588
|
+
compare(users)
|
|
589
|
+
return result
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
/**
|
|
593
|
+
* @typedef {ReturnType<typeof applyRandomTests>} ApplyRandomTestsResult
|
|
594
|
+
*/
|