@kyneta/yjs-schema 1.8.0 → 2.0.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 +4 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -4
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/src/__tests__/bind-yjs.test.ts +7 -7
- package/src/__tests__/create.test.ts +50 -50
- package/src/__tests__/eager-write-coherence.test.ts +21 -21
- package/src/__tests__/materialize.test.ts +13 -13
- package/src/__tests__/position.test.ts +18 -18
- package/src/__tests__/record-text-spike.test.ts +34 -34
- package/src/__tests__/substrate.test.ts +53 -53
- package/src/bind-yjs.ts +1 -1
- package/src/index.ts +1 -1
- package/src/substrate.ts +36 -4
package/README.md
CHANGED
|
@@ -42,7 +42,7 @@ doc.title() // "My Todos"
|
|
|
42
42
|
doc.items.length // 1
|
|
43
43
|
|
|
44
44
|
// Write
|
|
45
|
-
|
|
45
|
+
batch(doc, (d) => {
|
|
46
46
|
d.title.insert(9, " (v2)")
|
|
47
47
|
d.items.push({ name: "Walk dog", done: false })
|
|
48
48
|
})
|
|
@@ -95,7 +95,7 @@ const docB = createDoc(MyDoc, snapshot)
|
|
|
95
95
|
|
|
96
96
|
// After mutations on A, sync incrementally
|
|
97
97
|
const vBefore = version(docB)
|
|
98
|
-
|
|
98
|
+
batch(docA, (d) => d.title.insert(5, " v2"))
|
|
99
99
|
|
|
100
100
|
const delta = exportSince(docA, vBefore)
|
|
101
101
|
importDelta(docB, delta!)
|
|
@@ -120,7 +120,7 @@ const TodoDoc = yjs.bind(Schema.struct({
|
|
|
120
120
|
const doc = exchange.get("my-todos", TodoDoc)
|
|
121
121
|
```
|
|
122
122
|
|
|
123
|
-
`yjs.bind()` produces a `BoundSchema` with the collaborative `
|
|
123
|
+
`yjs.bind()` produces a `BoundSchema` with the collaborative `SyncMode`, which the exchange uses for bidirectional CRDT sync.
|
|
124
124
|
|
|
125
125
|
## Escape Hatch
|
|
126
126
|
|
|
@@ -163,7 +163,7 @@ Because `yjs(doc)` returns a standard `Y.Doc`, the entire Yjs provider ecosystem
|
|
|
163
163
|
| `exportEntirety(doc)` | Full state as `SubstratePayload` |
|
|
164
164
|
| `exportSince(doc, since)` | Delta since version |
|
|
165
165
|
| `merge(doc, payload, origin?)` | Apply delta from peer |
|
|
166
|
-
| `
|
|
166
|
+
| `batch(doc, fn)` | Transactional mutation |
|
|
167
167
|
| `subscribe(doc, callback)` | Observe changes |
|
|
168
168
|
| `yjs.bind(schema)` | Bind schema for exchange use |
|
|
169
169
|
| `yjs(ref)` | Escape hatch → `Y.Doc` |
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BindingTarget, ChangeBase, DocRef, Instruction, NATIVE, NativeMap, Op, Op as Op$1, Path, PathFoldResult, PathStepper, Position, Ref, ReplicaFactory, Schema, Schema as Schema$1, SchemaBinding, Side, Substrate, SubstrateFactory, SubstratePayload, Version, applyChanges,
|
|
1
|
+
import { BindingTarget, ChangeBase, DocRef, Instruction, NATIVE, NativeMap, Op, Op as Op$1, Path, PathFoldResult, PathStepper, Position, Ref, ReplicaFactory, Schema, Schema as Schema$1, SchemaBinding, Side, Substrate, SubstrateFactory, SubstratePayload, Version, applyChanges, batch, createDoc, createRef, exportEntirety, exportSince, merge, subscribe, subscribeNode, unwrap, version } from "@kyneta/schema";
|
|
2
2
|
import * as Y from "yjs";
|
|
3
3
|
import { Doc } from "yjs";
|
|
4
4
|
import { Changeset } from "@kyneta/changefeed";
|
|
@@ -276,5 +276,5 @@ declare const stepIntoYjs: PathStepper;
|
|
|
276
276
|
*/
|
|
277
277
|
declare function resolveYjsType(rootMap: Y.Map<any>, rootSchema: Schema$1, path: Path, binding?: SchemaBinding): PathFoldResult;
|
|
278
278
|
//#endregion
|
|
279
|
-
export { type Changeset, type DocRef, NATIVE, type Op, type Ref, Schema, type SubstratePayload, type YjsLaws, type YjsNativeMap, YjsPosition, YjsVersion, applyChangeToYjs, applyChanges,
|
|
279
|
+
export { type Changeset, type DocRef, NATIVE, type Op, type Ref, Schema, type SubstratePayload, type YjsLaws, type YjsNativeMap, YjsPosition, YjsVersion, applyChangeToYjs, applyChanges, batch, createDoc, createRef, createYjsSubstrate, ensureContainers, eventsToOps, exportEntirety, exportSince, fromYjsAssoc, merge, resolveYjsType, stepIntoYjs, subscribe, subscribeNode, toYjsAssoc, unwrap, version, yjs, yjsReplicaFactory, yjsSubstrateFactory };
|
|
280
280
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/native-map.ts","../src/bind-yjs.ts","../src/change-mapping.ts","../src/populate.ts","../src/position.ts","../src/version.ts","../src/substrate.ts","../src/yjs-resolve.ts"],"mappings":";;;;;;;;;;AAwBA;;;;;;;;;;;;UAAiB,YAAA,SAAqB,SAAA;EAAA,SAC3B,IAAA,EAAM,CAAA,CAAE,GAAA;EAAA,SACR,IAAA,EAAM,CAAA,CAAE,IAAA;EAAA,SACR,OAAA;EAAA,SACA,IAAA,EAAM,CAAA,CAAE,KAAA;EAAA,SACR,WAAA;EAAA,SACA,MAAA,EAAQ,CAAA,CAAE,GAAA;EAAA,SACV,GAAA,EAAK,CAAA,CAAE,GAAA;EAAA,SACP,IAAA;EAAA,SACA,GAAA;EAAA,SACA,MAAA;EAAA,SACA,GAAA;AAAA;;;;;;;KC8GC,OAAA;;;;;;;;;;;;;;cAmBC,GAAA,EAAK,aAAA,CAAc,OAAA,EAAS,YAAA;;;;;;;AD5IzC;;;;;;;;iBEuCgB,gBAAA,CACd,OAAA,EAAS,CAAA,CAAE,GAAA,OACX,UAAA,EAAY,QAAA,EACZ,IAAA,EAAM,IAAA,EACN,MAAA,EAAQ,UAAA,EACR,OAAA,GAAU,aAAA;;;;;;;;;;;;;;iBAkcI,WAAA,CACd,MAAA,EAAQ,CAAA,CAAE,MAAA,SACV,MAAA,EAAQ,QAAA,EACR,OAAA,GAAU,aAAA,GACT,IAAA;;;;;;;AFlfH;;;;;;;;;;;;;;;;;;;;;;;iBG6BgB,gBAAA,CACd,GAAA,EAAK,CAAA,CAAE,GAAA,EACP,MAAA,EAAQ,QAAA,EACR,OAAA,GAAU,aAAA;;;;iBC9CI,UAAA,CAAW,IAAU,EAAJ,IAAI;;iBAKrB,YAAA,CAAa,KAAA,WAAgB,IAAI;AAAA,cAIpC,WAAA,YAAuB,QAAA;EAAA,iBAIf,IAAA;EAAA,iBACA,GAAA;EAAA,SAJV,IAAA,EAAM,IAAA;cAGI,IAAA,EAAM,CAAA,CAAE,gBAAA,EACR,GAAA,EAAK,CAAA,CAAE,GAAA;EAK1B,OAAA,CAAA;EAQA,MAAA,CAAA,GAAU,UAAA;EAIV,SAAA,CAAU,aAAA,WAAwB,WAAA;AAAA;;;;;;;AJjBpC;;;;;;;;;;;;;;;cK8Ea,UAAA,YAAsB,OAAA;EL5ElB;EAAA,SK8EN,EAAA,EAAI,UAAA;EL7EJ;;;;;EAAA,SKoFA,aAAA,EAAe,UAAA;cAEZ,EAAA,EAAI,UAAA,EAAY,aAAA,GAAgB,UAAA;ELnFzB;;;;;;EAAA,OK+FZ,OAAA,CAAQ,GAAA,EAAK,GAAA,GAAM,UAAA;EL1FjB;;AAAG;;;;AC8Gd;;;ED9GW,OKyGF,aAAA,CACL,GAAA,EAAK,GAAA,EACL,EAAA,EAAI,UAAA,QADI,CAAA,CAC4B,eAAA,IACnC,UAAA;EJEc;AAmBnB;;;;;EIRE,SAAA,CAAA;EJQ6B;;;;;;AAAsB;;;;ACrGrD;;;;EGiHE,OAAA,CAAQ,KAAA,EAAO,OAAA;EH9GT;;;;;;;;;;;;;EG0IN,IAAA,CAAK,KAAA,EAAO,OAAA,GAAU,UAAA;EHxIZ;;;AAAa;AAkczB;;;;;EAlcY,OG6JH,KAAA,CAAM,UAAA,WAAqB,UAAA;AAAA;;;;;;ALzMpC;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/native-map.ts","../src/bind-yjs.ts","../src/change-mapping.ts","../src/populate.ts","../src/position.ts","../src/version.ts","../src/substrate.ts","../src/yjs-resolve.ts"],"mappings":";;;;;;;;;;AAwBA;;;;;;;;;;;;UAAiB,YAAA,SAAqB,SAAA;EAAA,SAC3B,IAAA,EAAM,CAAA,CAAE,GAAA;EAAA,SACR,IAAA,EAAM,CAAA,CAAE,IAAA;EAAA,SACR,OAAA;EAAA,SACA,IAAA,EAAM,CAAA,CAAE,KAAA;EAAA,SACR,WAAA;EAAA,SACA,MAAA,EAAQ,CAAA,CAAE,GAAA;EAAA,SACV,GAAA,EAAK,CAAA,CAAE,GAAA;EAAA,SACP,IAAA;EAAA,SACA,GAAA;EAAA,SACA,MAAA;EAAA,SACA,GAAA;AAAA;;;;;;;KC8GC,OAAA;;;;;;;;;;;;;;cAmBC,GAAA,EAAK,aAAA,CAAc,OAAA,EAAS,YAAA;;;;;;;AD5IzC;;;;;;;;iBEuCgB,gBAAA,CACd,OAAA,EAAS,CAAA,CAAE,GAAA,OACX,UAAA,EAAY,QAAA,EACZ,IAAA,EAAM,IAAA,EACN,MAAA,EAAQ,UAAA,EACR,OAAA,GAAU,aAAA;;;;;;;;;;;;;;iBAkcI,WAAA,CACd,MAAA,EAAQ,CAAA,CAAE,MAAA,SACV,MAAA,EAAQ,QAAA,EACR,OAAA,GAAU,aAAA,GACT,IAAA;;;;;;;AFlfH;;;;;;;;;;;;;;;;;;;;;;;iBG6BgB,gBAAA,CACd,GAAA,EAAK,CAAA,CAAE,GAAA,EACP,MAAA,EAAQ,QAAA,EACR,OAAA,GAAU,aAAA;;;;iBC9CI,UAAA,CAAW,IAAU,EAAJ,IAAI;;iBAKrB,YAAA,CAAa,KAAA,WAAgB,IAAI;AAAA,cAIpC,WAAA,YAAuB,QAAA;EAAA,iBAIf,IAAA;EAAA,iBACA,GAAA;EAAA,SAJV,IAAA,EAAM,IAAA;cAGI,IAAA,EAAM,CAAA,CAAE,gBAAA,EACR,GAAA,EAAK,CAAA,CAAE,GAAA;EAK1B,OAAA,CAAA;EAQA,MAAA,CAAA,GAAU,UAAA;EAIV,SAAA,CAAU,aAAA,WAAwB,WAAA;AAAA;;;;;;;AJjBpC;;;;;;;;;;;;;;;cK8Ea,UAAA,YAAsB,OAAA;EL5ElB;EAAA,SK8EN,EAAA,EAAI,UAAA;EL7EJ;;;;;EAAA,SKoFA,aAAA,EAAe,UAAA;cAEZ,EAAA,EAAI,UAAA,EAAY,aAAA,GAAgB,UAAA;ELnFzB;;;;;;EAAA,OK+FZ,OAAA,CAAQ,GAAA,EAAK,GAAA,GAAM,UAAA;EL1FjB;;AAAG;;;;AC8Gd;;;ED9GW,OKyGF,aAAA,CACL,GAAA,EAAK,GAAA,EACL,EAAA,EAAI,UAAA,QADI,CAAA,CAC4B,eAAA,IACnC,UAAA;EJEc;AAmBnB;;;;;EIRE,SAAA,CAAA;EJQ6B;;;;;;AAAsB;;;;ACrGrD;;;;EGiHE,OAAA,CAAQ,KAAA,EAAO,OAAA;EH9GT;;;;;;;;;;;;;EG0IN,IAAA,CAAK,KAAA,EAAO,OAAA,GAAU,UAAA;EHxIZ;;;AAAa;AAkczB;;;;;EAlcY,OG6JH,KAAA,CAAM,UAAA,WAAqB,UAAA;AAAA;;;;;;ALzMpC;;;;;;;;;;;;;;;;iBMoGgB,kBAAA,CACd,GAAA,EAAK,CAAA,CAAE,GAAA,EACP,MAAA,EAAQ,QAAA,EACR,OAAA,GAAU,aAAA,GACT,SAAA,CAAU,UAAA;AAAA,cAwfA,iBAAA,EAAmB,cAAc,CAAC,UAAA;AAAA,cA8BlC,mBAAA,EAAqB,gBAAgB,CAAC,UAAA;;;;;;;AN9nBnD;;;;;;;;;cOiBa,WAAA,EAAa,WAsBzB;;;;;;;;;;;;iBAiBe,cAAA,CACd,OAAA,EAAS,CAAA,CAAE,GAAA,OACX,UAAA,EAAY,QAAA,EACZ,IAAA,EAAM,IAAA,EACN,OAAA,GAAU,aAAA,GACT,cAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BACKING_DOC, KIND, NATIVE, RECORD_INVERSE, RawPath, STRUCTURAL_YJS_CLIENT_ID, SYNC_COLLABORATIVE, Schema, applyChange, applyChanges, base64ToUint8Array,
|
|
1
|
+
import { BACKING_DOC, DEVTOOLS_HISTORY, KIND, NATIVE, RECORD_INVERSE, RawPath, STRUCTURAL_YJS_CLIENT_ID, SYNC_COLLABORATIVE, Schema, applyChange, applyChanges, base64ToUint8Array, batch, buildWritableContext, createBindingTarget, createDoc, createMaterializeInterpreter, createRef, deepClonePreState, deriveSchemaBinding, executeBatch, expandMapOpsToLeaves, exportEntirety, exportSince, findJsonBoundary, foldPath, interpret, invert, isJsonBoundary, isNonNullObject, isPlainObject, materializeContextFromResolver, merge, pathSchema, plainReader, richTextChange, subscribe, subscribeNode, syncShadow, uint8ArrayToBase64, unwrap, version, versionVectorCompare, versionVectorMeet } from "@kyneta/schema";
|
|
2
2
|
import * as Y from "yjs";
|
|
3
3
|
import { createSnapshot, decodeStateVector, encodeSnapshot, encodeStateVector, snapshot } from "yjs";
|
|
4
4
|
//#region src/populate.ts
|
|
@@ -909,6 +909,7 @@ function createYjsSubstrate(doc, schema, binding) {
|
|
|
909
909
|
}
|
|
910
910
|
const substrate = {
|
|
911
911
|
[BACKING_DOC]: doc,
|
|
912
|
+
[DEVTOOLS_HISTORY]: yjsDevtoolsHistory(() => doc),
|
|
912
913
|
reader,
|
|
913
914
|
prepare(path, change, options) {
|
|
914
915
|
if (options?.replay) return;
|
|
@@ -1012,7 +1013,7 @@ function createYjsSubstrate(doc, schema, binding) {
|
|
|
1012
1013
|
*
|
|
1013
1014
|
* - `create(schema)` — creates a fresh Y.Doc with empty containers
|
|
1014
1015
|
* matching the schema structure. No seed data — initial content
|
|
1015
|
-
* should be applied via `
|
|
1016
|
+
* should be applied via `batch()` after construction.
|
|
1016
1017
|
* - `fromEntirety(payload, schema)` — creates a Y.Doc from an entirety
|
|
1017
1018
|
* payload, returns a substrate.
|
|
1018
1019
|
* - `parseVersion(serialized)` — deserializes a YjsVersion.
|
|
@@ -1043,6 +1044,30 @@ function trivialBinding(schema) {
|
|
|
1043
1044
|
* that need to accumulate state, compute per-peer deltas, and compact
|
|
1044
1045
|
* storage without ever interpreting document fields.
|
|
1045
1046
|
*/
|
|
1047
|
+
/**
|
|
1048
|
+
* Build the `DevtoolsHistory` capability over a Y.Doc accessor.
|
|
1049
|
+
*
|
|
1050
|
+
* `summary()` only: reliable Yjs time-travel (`valueAt`) requires the doc to
|
|
1051
|
+
* be constructed with `gc: false`, which this substrate does not impose (it
|
|
1052
|
+
* wraps a user-provided Y.Doc). So `valueAt` is intentionally omitted.
|
|
1053
|
+
* Context: jj:qpmkoryn.
|
|
1054
|
+
*/
|
|
1055
|
+
function yjsDevtoolsHistory(getDoc) {
|
|
1056
|
+
return { summary() {
|
|
1057
|
+
const sv = Y.encodeStateVector(getDoc());
|
|
1058
|
+
const actors = {};
|
|
1059
|
+
let opCount = 0;
|
|
1060
|
+
for (const [client, clock] of Y.decodeStateVector(sv)) {
|
|
1061
|
+
actors[String(client)] = clock;
|
|
1062
|
+
opCount += clock;
|
|
1063
|
+
}
|
|
1064
|
+
return {
|
|
1065
|
+
version: new YjsVersion(sv).serialize(),
|
|
1066
|
+
opCount,
|
|
1067
|
+
actors
|
|
1068
|
+
};
|
|
1069
|
+
} };
|
|
1070
|
+
}
|
|
1046
1071
|
function createYjsReplica(doc) {
|
|
1047
1072
|
let currentDoc = doc;
|
|
1048
1073
|
let currentBase = new YjsVersion(Y.encodeStateVector(new Y.Doc()));
|
|
@@ -1050,6 +1075,7 @@ function createYjsReplica(doc) {
|
|
|
1050
1075
|
get [BACKING_DOC]() {
|
|
1051
1076
|
return currentDoc;
|
|
1052
1077
|
},
|
|
1078
|
+
[DEVTOOLS_HISTORY]: yjsDevtoolsHistory(() => currentDoc),
|
|
1053
1079
|
version() {
|
|
1054
1080
|
return YjsVersion.fromDoc(currentDoc);
|
|
1055
1081
|
},
|
|
@@ -1206,9 +1232,9 @@ function createYjsFactory(peerId, binding) {
|
|
|
1206
1232
|
const yjs = createBindingTarget({
|
|
1207
1233
|
factory: (ctx) => createYjsFactory(ctx.peerId, ctx.binding),
|
|
1208
1234
|
replicaFactory: yjsReplicaFactory,
|
|
1209
|
-
|
|
1235
|
+
syncMode: SYNC_COLLABORATIVE
|
|
1210
1236
|
});
|
|
1211
1237
|
//#endregion
|
|
1212
|
-
export { NATIVE, Schema, YjsPosition, YjsVersion, applyChangeToYjs, applyChanges,
|
|
1238
|
+
export { NATIVE, Schema, YjsPosition, YjsVersion, applyChangeToYjs, applyChanges, batch, createDoc, createRef, createYjsSubstrate, ensureContainers, eventsToOps, exportEntirety, exportSince, fromYjsAssoc, merge, resolveYjsType, stepIntoYjs, subscribe, subscribeNode, toYjsAssoc, unwrap, version, yjs, yjsReplicaFactory, yjsSubstrateFactory };
|
|
1213
1239
|
|
|
1214
1240
|
//# sourceMappingURL=index.js.map
|