@kyneta/yjs-schema 1.0.0 → 1.1.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/dist/index.d.ts +110 -108
- package/dist/index.js +171 -109
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/bind-yjs.test.ts +19 -19
- package/src/__tests__/create.test.ts +61 -51
- package/src/__tests__/{store-reader.test.ts → reader.test.ts} +30 -33
- package/src/__tests__/record-text-spike.test.ts +29 -21
- package/src/__tests__/structural-merge.test.ts +362 -0
- package/src/__tests__/substrate.test.ts +48 -64
- package/src/__tests__/version.test.ts +7 -16
- package/src/bind-yjs.ts +46 -25
- package/src/change-mapping.ts +20 -35
- package/src/create.ts +32 -27
- package/src/index.ts +24 -30
- package/src/populate.ts +42 -14
- package/src/{store-reader.ts → reader.ts} +7 -12
- package/src/substrate.ts +139 -40
- package/src/sync.ts +26 -26
- package/src/version.ts +2 -4
- package/src/yjs-escape.ts +19 -35
- package/src/yjs-resolve.ts +4 -10
package/dist/index.js
CHANGED
|
@@ -1,14 +1,27 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import {
|
|
3
|
+
applyChanges,
|
|
4
|
+
change,
|
|
5
|
+
Schema,
|
|
6
|
+
subscribe,
|
|
7
|
+
subscribeNode
|
|
8
|
+
} from "@kyneta/schema";
|
|
9
|
+
|
|
1
10
|
// src/create.ts
|
|
2
|
-
import {
|
|
3
|
-
|
|
11
|
+
import {
|
|
12
|
+
changefeed,
|
|
13
|
+
interpret,
|
|
14
|
+
readable,
|
|
15
|
+
registerSubstrate,
|
|
16
|
+
writable
|
|
17
|
+
} from "@kyneta/schema";
|
|
4
18
|
|
|
5
19
|
// src/substrate.ts
|
|
6
|
-
import { buildWritableContext, executeBatch } from "@kyneta/schema";
|
|
20
|
+
import { BACKING_DOC, buildWritableContext, executeBatch } from "@kyneta/schema";
|
|
7
21
|
import * as Y5 from "yjs";
|
|
8
22
|
|
|
9
23
|
// src/change-mapping.ts
|
|
10
|
-
import { advanceSchema as advanceSchema2, expandMapOpsToLeaves } from "@kyneta/schema";
|
|
11
|
-
import { RawPath } from "@kyneta/schema";
|
|
24
|
+
import { advanceSchema as advanceSchema2, expandMapOpsToLeaves, RawPath } from "@kyneta/schema";
|
|
12
25
|
import * as Y2 from "yjs";
|
|
13
26
|
|
|
14
27
|
// src/yjs-resolve.ts
|
|
@@ -23,9 +36,7 @@ function stepIntoYjs(current, segment) {
|
|
|
23
36
|
return current.get(resolved);
|
|
24
37
|
}
|
|
25
38
|
if (current instanceof Y.Text) {
|
|
26
|
-
throw new Error(
|
|
27
|
-
`yjs-resolve: cannot step into Y.Text`
|
|
28
|
-
);
|
|
39
|
+
throw new Error(`yjs-resolve: cannot step into Y.Text`);
|
|
29
40
|
}
|
|
30
41
|
return void 0;
|
|
31
42
|
}
|
|
@@ -166,19 +177,14 @@ function maybeCreateSharedType(value, schema) {
|
|
|
166
177
|
return text2;
|
|
167
178
|
}
|
|
168
179
|
if (tag === "counter" || tag === "movable" || tag === "tree") {
|
|
169
|
-
throw new Error(
|
|
170
|
-
`Yjs substrate does not support "${tag}" annotations.`
|
|
171
|
-
);
|
|
180
|
+
throw new Error(`Yjs substrate does not support "${tag}" annotations.`);
|
|
172
181
|
}
|
|
173
182
|
switch (structural._kind) {
|
|
174
183
|
case "product": {
|
|
175
184
|
if (value === null || value === void 0 || typeof value !== "object" || Array.isArray(value)) {
|
|
176
185
|
return value;
|
|
177
186
|
}
|
|
178
|
-
return createStructuredMap(
|
|
179
|
-
value,
|
|
180
|
-
structural
|
|
181
|
-
);
|
|
187
|
+
return createStructuredMap(value, structural);
|
|
182
188
|
}
|
|
183
189
|
case "sequence": {
|
|
184
190
|
if (!Array.isArray(value)) return value;
|
|
@@ -196,9 +202,7 @@ function maybeCreateSharedType(value, schema) {
|
|
|
196
202
|
}
|
|
197
203
|
const map = new Y2.Map();
|
|
198
204
|
const valueSchema = structural.item;
|
|
199
|
-
for (const [k, v] of Object.entries(
|
|
200
|
-
value
|
|
201
|
-
)) {
|
|
205
|
+
for (const [k, v] of Object.entries(value)) {
|
|
202
206
|
map.set(k, maybeCreateSharedType(v, valueSchema));
|
|
203
207
|
}
|
|
204
208
|
return map;
|
|
@@ -302,18 +306,16 @@ function mapEventToChange(event) {
|
|
|
302
306
|
let hasSet = false;
|
|
303
307
|
let hasDelete = false;
|
|
304
308
|
const target = event.target;
|
|
305
|
-
event.changes.keys.forEach(
|
|
306
|
-
(change2
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
hasDelete = true;
|
|
314
|
-
}
|
|
309
|
+
event.changes.keys.forEach((change2, key) => {
|
|
310
|
+
if (change2.action === "add" || change2.action === "update") {
|
|
311
|
+
const value = target.get(key);
|
|
312
|
+
set[key] = extractEventValue(value);
|
|
313
|
+
hasSet = true;
|
|
314
|
+
} else if (change2.action === "delete") {
|
|
315
|
+
deleteKeys.push(key);
|
|
316
|
+
hasDelete = true;
|
|
315
317
|
}
|
|
316
|
-
);
|
|
318
|
+
});
|
|
317
319
|
if (!hasSet && !hasDelete) return null;
|
|
318
320
|
return {
|
|
319
321
|
type: "map",
|
|
@@ -360,9 +362,9 @@ function pathToString(path) {
|
|
|
360
362
|
}
|
|
361
363
|
|
|
362
364
|
// src/populate.ts
|
|
363
|
-
import { Zero } from "@kyneta/schema";
|
|
365
|
+
import { STRUCTURAL_YJS_CLIENT_ID, Zero } from "@kyneta/schema";
|
|
364
366
|
import * as Y3 from "yjs";
|
|
365
|
-
function ensureContainers(doc, schema) {
|
|
367
|
+
function ensureContainers(doc, schema, conditional = false) {
|
|
366
368
|
const rootMap = doc.getMap("root");
|
|
367
369
|
let rootProduct = schema;
|
|
368
370
|
while (rootProduct._kind === "annotated" && rootProduct.schema !== void 0) {
|
|
@@ -371,11 +373,20 @@ function ensureContainers(doc, schema) {
|
|
|
371
373
|
if (rootProduct._kind !== "product") {
|
|
372
374
|
return;
|
|
373
375
|
}
|
|
374
|
-
doc.
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
376
|
+
const savedClientID = doc.clientID;
|
|
377
|
+
doc.clientID = STRUCTURAL_YJS_CLIENT_ID;
|
|
378
|
+
try {
|
|
379
|
+
doc.transact(() => {
|
|
380
|
+
for (const [key, fieldSchema] of Object.entries(rootProduct.fields).sort(
|
|
381
|
+
([a], [b]) => a.localeCompare(b)
|
|
382
|
+
)) {
|
|
383
|
+
if (conditional && rootMap.has(key)) continue;
|
|
384
|
+
ensureRootField(rootMap, key, fieldSchema);
|
|
385
|
+
}
|
|
386
|
+
});
|
|
387
|
+
} finally {
|
|
388
|
+
doc.clientID = savedClientID;
|
|
389
|
+
}
|
|
379
390
|
}
|
|
380
391
|
function ensureRootField(rootMap, key, fieldSchema) {
|
|
381
392
|
const tag = fieldSchema._kind === "annotated" ? fieldSchema.tag : void 0;
|
|
@@ -423,7 +434,7 @@ function ensureMapContainers(schema) {
|
|
|
423
434
|
if (structural._kind !== "product") return map;
|
|
424
435
|
for (const [key, fieldSchema] of Object.entries(
|
|
425
436
|
structural.fields
|
|
426
|
-
)) {
|
|
437
|
+
).sort(([a], [b]) => a.localeCompare(b))) {
|
|
427
438
|
const tag = fieldSchema._kind === "annotated" ? fieldSchema.tag : void 0;
|
|
428
439
|
if (tag === "text") {
|
|
429
440
|
map.set(key, new Y3.Text());
|
|
@@ -460,7 +471,7 @@ function unwrapAnnotations2(schema) {
|
|
|
460
471
|
return s;
|
|
461
472
|
}
|
|
462
473
|
|
|
463
|
-
// src/
|
|
474
|
+
// src/reader.ts
|
|
464
475
|
import * as Y4 from "yjs";
|
|
465
476
|
function extractValue(resolved) {
|
|
466
477
|
if (resolved instanceof Y4.Text) {
|
|
@@ -474,7 +485,7 @@ function extractValue(resolved) {
|
|
|
474
485
|
}
|
|
475
486
|
return resolved;
|
|
476
487
|
}
|
|
477
|
-
function
|
|
488
|
+
function yjsReader(doc, schema) {
|
|
478
489
|
const rootMap = doc.getMap("root");
|
|
479
490
|
return {
|
|
480
491
|
read(path) {
|
|
@@ -565,9 +576,7 @@ var YjsVersion = class _YjsVersion {
|
|
|
565
576
|
*/
|
|
566
577
|
compare(other) {
|
|
567
578
|
if (!(other instanceof _YjsVersion)) {
|
|
568
|
-
throw new Error(
|
|
569
|
-
"YjsVersion can only be compared with another YjsVersion"
|
|
570
|
-
);
|
|
579
|
+
throw new Error("YjsVersion can only be compared with another YjsVersion");
|
|
571
580
|
}
|
|
572
581
|
const thisMap = decodeStateVector(this.sv);
|
|
573
582
|
const otherMap = decodeStateVector(other.sv);
|
|
@@ -607,41 +616,18 @@ var YjsVersion = class _YjsVersion {
|
|
|
607
616
|
}
|
|
608
617
|
};
|
|
609
618
|
|
|
610
|
-
// src/yjs-escape.ts
|
|
611
|
-
import { unwrap } from "@kyneta/schema";
|
|
612
|
-
var substrateToYjsDoc = /* @__PURE__ */ new WeakMap();
|
|
613
|
-
function registerYjsSubstrate(substrate, doc) {
|
|
614
|
-
substrateToYjsDoc.set(substrate, doc);
|
|
615
|
-
}
|
|
616
|
-
function yjs(ref) {
|
|
617
|
-
let substrate;
|
|
618
|
-
try {
|
|
619
|
-
substrate = unwrap(ref);
|
|
620
|
-
} catch {
|
|
621
|
-
throw new Error(
|
|
622
|
-
"yjs() requires a ref backed by a Yjs substrate. Use a doc created by exchange.get() with a bindYjs() schema, or by createYjsDoc()."
|
|
623
|
-
);
|
|
624
|
-
}
|
|
625
|
-
const doc = substrateToYjsDoc.get(substrate);
|
|
626
|
-
if (!doc) {
|
|
627
|
-
throw new Error(
|
|
628
|
-
"yjs() requires a ref backed by a Yjs substrate. The ref has a substrate but it is not a Yjs substrate. Use a doc created with a bindYjs() schema or createYjsDoc()."
|
|
629
|
-
);
|
|
630
|
-
}
|
|
631
|
-
return doc;
|
|
632
|
-
}
|
|
633
|
-
|
|
634
619
|
// src/substrate.ts
|
|
635
620
|
var KYNETA_ORIGIN = "kyneta-prepare";
|
|
636
621
|
function createYjsSubstrate(doc, schema) {
|
|
637
622
|
const pendingChanges = [];
|
|
638
623
|
let inOurTransaction = false;
|
|
639
|
-
let
|
|
624
|
+
let pendingMergeOrigin;
|
|
640
625
|
let cachedCtx;
|
|
641
626
|
const rootMap = doc.getMap("root");
|
|
642
|
-
const reader =
|
|
627
|
+
const reader = yjsReader(doc, schema);
|
|
643
628
|
const substrate = {
|
|
644
|
-
|
|
629
|
+
[BACKING_DOC]: doc,
|
|
630
|
+
reader,
|
|
645
631
|
prepare(path, change2) {
|
|
646
632
|
if (!inOurTransaction) {
|
|
647
633
|
pendingChanges.push({ path, change: change2 });
|
|
@@ -671,8 +657,9 @@ function createYjsSubstrate(doc, schema) {
|
|
|
671
657
|
version() {
|
|
672
658
|
return new YjsVersion(Y5.encodeStateVector(doc));
|
|
673
659
|
},
|
|
674
|
-
|
|
660
|
+
exportEntirety() {
|
|
675
661
|
return {
|
|
662
|
+
kind: "entirety",
|
|
676
663
|
encoding: "binary",
|
|
677
664
|
data: Y5.encodeStateAsUpdate(doc)
|
|
678
665
|
};
|
|
@@ -680,22 +667,22 @@ function createYjsSubstrate(doc, schema) {
|
|
|
680
667
|
exportSince(since) {
|
|
681
668
|
try {
|
|
682
669
|
const bytes = Y5.encodeStateAsUpdate(doc, since.sv);
|
|
683
|
-
return { encoding: "binary", data: bytes };
|
|
670
|
+
return { kind: "since", encoding: "binary", data: bytes };
|
|
684
671
|
} catch {
|
|
685
672
|
return null;
|
|
686
673
|
}
|
|
687
674
|
},
|
|
688
|
-
|
|
675
|
+
merge(payload, origin) {
|
|
689
676
|
if (payload.encoding !== "binary" || !(payload.data instanceof Uint8Array)) {
|
|
690
677
|
throw new Error(
|
|
691
|
-
"YjsSubstrate.
|
|
678
|
+
"YjsSubstrate.merge expects binary-encoded payloads. If you recently switched CRDT backends, stale clients may be sending incompatible data."
|
|
692
679
|
);
|
|
693
680
|
}
|
|
694
|
-
|
|
681
|
+
pendingMergeOrigin = origin;
|
|
695
682
|
try {
|
|
696
683
|
Y5.applyUpdate(doc, payload.data, origin ?? "remote");
|
|
697
684
|
} finally {
|
|
698
|
-
|
|
685
|
+
pendingMergeOrigin = void 0;
|
|
699
686
|
}
|
|
700
687
|
}
|
|
701
688
|
};
|
|
@@ -707,7 +694,7 @@ function createYjsSubstrate(doc, schema) {
|
|
|
707
694
|
if (ops.length === 0) {
|
|
708
695
|
return;
|
|
709
696
|
}
|
|
710
|
-
const origin =
|
|
697
|
+
const origin = pendingMergeOrigin ?? (typeof transaction.origin === "string" ? transaction.origin : void 0);
|
|
711
698
|
const ctx = substrate.context();
|
|
712
699
|
inOurTransaction = true;
|
|
713
700
|
try {
|
|
@@ -716,25 +703,78 @@ function createYjsSubstrate(doc, schema) {
|
|
|
716
703
|
inOurTransaction = false;
|
|
717
704
|
}
|
|
718
705
|
});
|
|
719
|
-
registerYjsSubstrate(substrate, doc);
|
|
720
706
|
return substrate;
|
|
721
707
|
}
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
708
|
+
function createYjsReplica(doc) {
|
|
709
|
+
return {
|
|
710
|
+
[BACKING_DOC]: doc,
|
|
711
|
+
version() {
|
|
712
|
+
return new YjsVersion(Y5.encodeStateVector(doc));
|
|
713
|
+
},
|
|
714
|
+
exportEntirety() {
|
|
715
|
+
return {
|
|
716
|
+
kind: "entirety",
|
|
717
|
+
encoding: "binary",
|
|
718
|
+
data: Y5.encodeStateAsUpdate(doc)
|
|
719
|
+
};
|
|
720
|
+
},
|
|
721
|
+
exportSince(since) {
|
|
722
|
+
try {
|
|
723
|
+
const bytes = Y5.encodeStateAsUpdate(doc, since.sv);
|
|
724
|
+
return { kind: "since", encoding: "binary", data: bytes };
|
|
725
|
+
} catch {
|
|
726
|
+
return null;
|
|
727
|
+
}
|
|
728
|
+
},
|
|
729
|
+
merge(payload, _origin) {
|
|
730
|
+
if (payload.encoding !== "binary" || !(payload.data instanceof Uint8Array)) {
|
|
731
|
+
throw new Error(
|
|
732
|
+
"YjsReplica.merge expects binary-encoded payloads. If you recently switched CRDT backends, stale clients may be sending incompatible data."
|
|
733
|
+
);
|
|
734
|
+
}
|
|
735
|
+
Y5.applyUpdate(doc, payload.data);
|
|
736
|
+
}
|
|
737
|
+
};
|
|
738
|
+
}
|
|
739
|
+
var yjsReplicaFactory = {
|
|
740
|
+
replicaType: ["yjs", 1, 0],
|
|
741
|
+
createEmpty() {
|
|
742
|
+
return createYjsReplica(new Y5.Doc());
|
|
727
743
|
},
|
|
728
|
-
|
|
744
|
+
fromEntirety(payload) {
|
|
729
745
|
if (payload.encoding !== "binary" || !(payload.data instanceof Uint8Array)) {
|
|
730
746
|
throw new Error(
|
|
731
|
-
"
|
|
747
|
+
"YjsReplicaFactory.fromEntirety only supports binary-encoded payloads"
|
|
732
748
|
);
|
|
733
749
|
}
|
|
734
750
|
const doc = new Y5.Doc();
|
|
735
751
|
Y5.applyUpdate(doc, payload.data);
|
|
752
|
+
return createYjsReplica(doc);
|
|
753
|
+
},
|
|
754
|
+
parseVersion(serialized) {
|
|
755
|
+
return YjsVersion.parse(serialized);
|
|
756
|
+
}
|
|
757
|
+
};
|
|
758
|
+
var yjsSubstrateFactory = {
|
|
759
|
+
replica: yjsReplicaFactory,
|
|
760
|
+
createReplica() {
|
|
761
|
+
return createYjsReplica(new Y5.Doc());
|
|
762
|
+
},
|
|
763
|
+
upgrade(replica, schema) {
|
|
764
|
+
const doc = replica[BACKING_DOC];
|
|
765
|
+
ensureContainers(doc, schema, true);
|
|
736
766
|
return createYjsSubstrate(doc, schema);
|
|
737
767
|
},
|
|
768
|
+
create(schema) {
|
|
769
|
+
const doc = new Y5.Doc();
|
|
770
|
+
ensureContainers(doc, schema);
|
|
771
|
+
return createYjsSubstrate(doc, schema);
|
|
772
|
+
},
|
|
773
|
+
fromEntirety(payload, schema) {
|
|
774
|
+
const replica = this.createReplica();
|
|
775
|
+
replica.merge(payload);
|
|
776
|
+
return this.upgrade(replica, schema);
|
|
777
|
+
},
|
|
738
778
|
parseVersion(serialized) {
|
|
739
779
|
return YjsVersion.parse(serialized);
|
|
740
780
|
}
|
|
@@ -746,7 +786,7 @@ function getSubstrate(doc) {
|
|
|
746
786
|
const s = substrates.get(doc);
|
|
747
787
|
if (!s) {
|
|
748
788
|
throw new Error(
|
|
749
|
-
"version/
|
|
789
|
+
"version/exportEntirety/merge called on an object without a YjsSubstrate. Use a doc created by createYjsDoc() or createYjsDocFromEntirety()."
|
|
750
790
|
);
|
|
751
791
|
}
|
|
752
792
|
return s;
|
|
@@ -767,30 +807,27 @@ var createYjsDoc = (schema, doc) => {
|
|
|
767
807
|
}
|
|
768
808
|
return registerDoc(schema, yjsSubstrateFactory.create(schema));
|
|
769
809
|
};
|
|
770
|
-
var
|
|
810
|
+
var createYjsDocFromEntirety = (schema, payload) => registerDoc(schema, yjsSubstrateFactory.fromEntirety(payload, schema));
|
|
771
811
|
|
|
772
812
|
// src/sync.ts
|
|
773
813
|
function version(doc) {
|
|
774
814
|
return getSubstrate(doc).version();
|
|
775
815
|
}
|
|
776
|
-
function
|
|
777
|
-
return getSubstrate(doc).
|
|
816
|
+
function exportEntirety(doc) {
|
|
817
|
+
return getSubstrate(doc).exportEntirety();
|
|
778
818
|
}
|
|
779
819
|
function exportSince(doc, since) {
|
|
780
820
|
return getSubstrate(doc).exportSince(since);
|
|
781
821
|
}
|
|
782
|
-
function
|
|
783
|
-
getSubstrate(doc).
|
|
822
|
+
function merge(doc, payload, origin) {
|
|
823
|
+
getSubstrate(doc).merge(payload, origin);
|
|
784
824
|
}
|
|
785
825
|
|
|
786
826
|
// src/index.ts
|
|
787
|
-
import { applyChanges, change } from "@kyneta/schema";
|
|
788
|
-
import { subscribe, subscribeNode } from "@kyneta/schema";
|
|
789
|
-
import { Schema } from "@kyneta/schema";
|
|
790
827
|
import { Schema as Schema2 } from "@kyneta/schema";
|
|
791
828
|
|
|
792
829
|
// src/bind-yjs.ts
|
|
793
|
-
import { bind } from "@kyneta/schema";
|
|
830
|
+
import { BACKING_DOC as BACKING_DOC2, bind, STRUCTURAL_YJS_CLIENT_ID as STRUCTURAL_YJS_CLIENT_ID2 } from "@kyneta/schema";
|
|
794
831
|
import * as Y6 from "yjs";
|
|
795
832
|
function hashPeerId(peerId) {
|
|
796
833
|
let hash = 2166136261;
|
|
@@ -798,28 +835,33 @@ function hashPeerId(peerId) {
|
|
|
798
835
|
hash ^= peerId.charCodeAt(i);
|
|
799
836
|
hash = Math.imul(hash, 16777619);
|
|
800
837
|
}
|
|
801
|
-
|
|
838
|
+
const result = hash >>> 0;
|
|
839
|
+
return result === STRUCTURAL_YJS_CLIENT_ID2 ? 1 : result;
|
|
802
840
|
}
|
|
803
841
|
function createYjsFactory(peerId) {
|
|
804
842
|
const numericClientId = hashPeerId(peerId);
|
|
805
843
|
return {
|
|
806
|
-
|
|
807
|
-
|
|
844
|
+
replica: yjsReplicaFactory,
|
|
845
|
+
createReplica() {
|
|
846
|
+
return createYjsReplica(new Y6.Doc());
|
|
847
|
+
},
|
|
848
|
+
upgrade(replica, schema) {
|
|
849
|
+
const doc = replica[BACKING_DOC2];
|
|
808
850
|
doc.clientID = numericClientId;
|
|
809
|
-
ensureContainers(doc, schema);
|
|
851
|
+
ensureContainers(doc, schema, true);
|
|
810
852
|
return createYjsSubstrate(doc, schema);
|
|
811
853
|
},
|
|
812
|
-
|
|
813
|
-
if (payload.encoding !== "binary" || !(payload.data instanceof Uint8Array)) {
|
|
814
|
-
throw new Error(
|
|
815
|
-
"YjsSubstrateFactory.fromSnapshot only supports binary-encoded payloads"
|
|
816
|
-
);
|
|
817
|
-
}
|
|
854
|
+
create(schema) {
|
|
818
855
|
const doc = new Y6.Doc();
|
|
819
856
|
doc.clientID = numericClientId;
|
|
820
|
-
|
|
857
|
+
ensureContainers(doc, schema);
|
|
821
858
|
return createYjsSubstrate(doc, schema);
|
|
822
859
|
},
|
|
860
|
+
fromEntirety(payload, schema) {
|
|
861
|
+
const replica = this.createReplica();
|
|
862
|
+
replica.merge(payload);
|
|
863
|
+
return this.upgrade(replica, schema);
|
|
864
|
+
},
|
|
823
865
|
parseVersion(serialized) {
|
|
824
866
|
return YjsVersion.parse(serialized);
|
|
825
867
|
}
|
|
@@ -833,6 +875,26 @@ function bindYjs(schema) {
|
|
|
833
875
|
});
|
|
834
876
|
}
|
|
835
877
|
|
|
878
|
+
// src/yjs-escape.ts
|
|
879
|
+
import { BACKING_DOC as BACKING_DOC3, unwrap } from "@kyneta/schema";
|
|
880
|
+
function yjs(ref) {
|
|
881
|
+
let substrate;
|
|
882
|
+
try {
|
|
883
|
+
substrate = unwrap(ref);
|
|
884
|
+
} catch {
|
|
885
|
+
throw new Error(
|
|
886
|
+
"yjs() requires a ref backed by a Yjs substrate. Use a doc created by exchange.get() with a bindYjs() schema, or by createYjsDoc()."
|
|
887
|
+
);
|
|
888
|
+
}
|
|
889
|
+
const doc = substrate[BACKING_DOC3];
|
|
890
|
+
if (!doc || typeof doc !== "object" || typeof doc.getMap !== "function" || typeof doc.clientID !== "number") {
|
|
891
|
+
throw new Error(
|
|
892
|
+
"yjs() requires a ref backed by a Yjs substrate. The ref has a substrate but it is not a Yjs substrate. Use a doc created with a bindYjs() schema or createYjsDoc()."
|
|
893
|
+
);
|
|
894
|
+
}
|
|
895
|
+
return doc;
|
|
896
|
+
}
|
|
897
|
+
|
|
836
898
|
// src/index.ts
|
|
837
899
|
function text() {
|
|
838
900
|
return Schema2.annotated("text");
|
|
@@ -845,13 +907,13 @@ export {
|
|
|
845
907
|
bindYjs,
|
|
846
908
|
change,
|
|
847
909
|
createYjsDoc,
|
|
848
|
-
|
|
910
|
+
createYjsDocFromEntirety,
|
|
849
911
|
createYjsSubstrate,
|
|
850
912
|
ensureContainers,
|
|
851
913
|
eventsToOps,
|
|
914
|
+
exportEntirety,
|
|
852
915
|
exportSince,
|
|
853
|
-
|
|
854
|
-
importDelta,
|
|
916
|
+
merge,
|
|
855
917
|
resolveYjsType,
|
|
856
918
|
stepIntoYjs,
|
|
857
919
|
subscribe,
|
|
@@ -859,7 +921,7 @@ export {
|
|
|
859
921
|
text,
|
|
860
922
|
version,
|
|
861
923
|
yjs,
|
|
862
|
-
|
|
924
|
+
yjsReader,
|
|
863
925
|
yjsSubstrateFactory
|
|
864
926
|
};
|
|
865
927
|
//# sourceMappingURL=index.js.map
|