lib0 1.0.0-rc.2 → 1.0.0-rc.21

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.
Files changed (141) hide show
  1. package/README.md +0 -1315
  2. package/{types → dist}/buffer.d.ts +2 -10
  3. package/{types → dist}/delta/delta.d.ts +582 -144
  4. package/dist/delta/position.d.ts +65 -0
  5. package/dist/delta/rdt/delta.d.ts +57 -0
  6. package/dist/delta/rdt/dom.d.ts +102 -0
  7. package/dist/delta/rdt.d.ts +180 -0
  8. package/dist/delta/transformer/attr.d.ts +64 -0
  9. package/dist/delta/transformer/attribution-to-format.d.ts +52 -0
  10. package/dist/delta/transformer/children.d.ts +69 -0
  11. package/dist/delta/transformer/conform.d.ts +83 -0
  12. package/dist/delta/transformer/core.d.ts +189 -0
  13. package/dist/delta/transformer/full-attributions.d.ts +37 -0
  14. package/dist/delta/transformer/id.d.ts +2 -0
  15. package/dist/delta/transformer/inline.d.ts +89 -0
  16. package/dist/delta/transformer/pipe.d.ts +182 -0
  17. package/dist/delta/transformer/project.d.ts +223 -0
  18. package/dist/delta/transformer/rename-attrs.d.ts +75 -0
  19. package/dist/delta/transformer/rename.d.ts +41 -0
  20. package/dist/delta/transformer/value.d.ts +92 -0
  21. package/dist/delta/transformer.d.ts +14 -0
  22. package/dist/diff/patience.d.ts +25 -0
  23. package/{types → dist}/environment.d.ts +10 -0
  24. package/dist/hash/fnv1a.d.ts +11 -0
  25. package/{types → dist}/schema.d.ts +49 -38
  26. package/{types → dist}/ts.d.ts +4 -0
  27. package/dist/webcrypto.d.ts +3 -0
  28. package/package.json +148 -82
  29. package/src/bin/0serve.js +11 -3
  30. package/src/broadcastchannel.js +6 -1
  31. package/src/buffer.js +35 -25
  32. package/src/decoding.js +1 -1
  33. package/src/delta/delta.js +2531 -564
  34. package/src/delta/position.js +165 -0
  35. package/src/delta/rdt/delta.js +105 -0
  36. package/src/delta/rdt/dom.js +307 -0
  37. package/src/delta/rdt.js +255 -0
  38. package/src/delta/transformer/attr.js +126 -0
  39. package/src/delta/transformer/attribution-to-format.js +335 -0
  40. package/src/delta/transformer/children.js +219 -0
  41. package/src/delta/transformer/conform.js +401 -0
  42. package/src/delta/transformer/core.js +323 -0
  43. package/src/delta/transformer/full-attributions.js +282 -0
  44. package/src/delta/transformer/id.js +13 -0
  45. package/src/delta/transformer/inline.js +818 -0
  46. package/src/delta/transformer/pipe.js +272 -0
  47. package/src/delta/transformer/project.js +526 -0
  48. package/src/delta/transformer/rename-attrs.js +152 -0
  49. package/src/delta/transformer/rename.js +84 -0
  50. package/src/delta/transformer/value.js +214 -0
  51. package/src/delta/transformer.js +38 -0
  52. package/src/diff/patience.js +22 -11
  53. package/src/dom.js +2 -2
  54. package/src/encoding.js +1 -1
  55. package/src/environment.js +15 -0
  56. package/src/hash/fnv1a.js +82 -0
  57. package/src/number.js +1 -3
  58. package/src/performance.node.js +3 -3
  59. package/src/schema.js +231 -177
  60. package/src/string.js +3 -5
  61. package/src/testing.js +1 -1
  62. package/src/trait/equality.js +1 -1
  63. package/src/trait/fingerprint.js +1 -1
  64. package/src/ts.js +11 -0
  65. package/src/bin/gendocs.js +0 -117
  66. package/src/component.js +0 -414
  67. package/src/delta/binding.js +0 -372
  68. package/src/tree.js +0 -546
  69. package/types/bin/gendocs.d.ts +0 -3
  70. package/types/component.d.ts +0 -86
  71. package/types/delta/binding.d.ts +0 -106
  72. package/types/diff/patience.d.ts +0 -16
  73. package/types/tree.d.ts +0 -96
  74. package/types/webcrypto.d.ts +0 -3
  75. /package/{types → dist}/array.d.ts +0 -0
  76. /package/{types → dist}/bin/0ecdsa-generate-keypair.d.ts +0 -0
  77. /package/{types → dist}/bin/0serve.d.ts +0 -0
  78. /package/{types → dist}/bin/gentesthtml.d.ts +0 -0
  79. /package/{types → dist}/binary.d.ts +0 -0
  80. /package/{types → dist}/broadcastchannel.d.ts +0 -0
  81. /package/{types → dist}/cache.d.ts +0 -0
  82. /package/{types → dist}/conditions.d.ts +0 -0
  83. /package/{types → dist}/crypto/aes-gcm.d.ts +0 -0
  84. /package/{types → dist}/crypto/common.d.ts +0 -0
  85. /package/{types → dist}/crypto/ecdsa.d.ts +0 -0
  86. /package/{types → dist}/crypto/jwt.d.ts +0 -0
  87. /package/{types → dist}/crypto/rsa-oaep.d.ts +0 -0
  88. /package/{types → dist}/decoding.d.ts +0 -0
  89. /package/{types → dist}/diff.d.ts +0 -0
  90. /package/{types → dist}/dom.d.ts +0 -0
  91. /package/{types → dist}/encoding.d.ts +0 -0
  92. /package/{types → dist}/error.d.ts +0 -0
  93. /package/{types → dist}/eventloop.d.ts +0 -0
  94. /package/{types → dist}/function.d.ts +0 -0
  95. /package/{types → dist}/hash/rabin-gf2-polynomial.d.ts +0 -0
  96. /package/{types → dist}/hash/rabin-uncached.d.ts +0 -0
  97. /package/{types → dist}/hash/rabin.d.ts +0 -0
  98. /package/{types → dist}/hash/sha256.d.ts +0 -0
  99. /package/{types → dist}/hash/sha256.node.d.ts +0 -0
  100. /package/{types → dist}/indexeddb.d.ts +0 -0
  101. /package/{types → dist}/indexeddbV2.d.ts +0 -0
  102. /package/{types → dist}/iterator.d.ts +0 -0
  103. /package/{types → dist}/json.d.ts +0 -0
  104. /package/{types → dist}/list.d.ts +0 -0
  105. /package/{types → dist}/logging.common.d.ts +0 -0
  106. /package/{types → dist}/logging.d.ts +0 -0
  107. /package/{types → dist}/logging.node.d.ts +0 -0
  108. /package/{types → dist}/map.d.ts +0 -0
  109. /package/{types → dist}/math.d.ts +0 -0
  110. /package/{types → dist}/metric.d.ts +0 -0
  111. /package/{types → dist}/mutex.d.ts +0 -0
  112. /package/{types → dist}/number.d.ts +0 -0
  113. /package/{types → dist}/object.d.ts +0 -0
  114. /package/{types → dist}/observable.d.ts +0 -0
  115. /package/{types → dist}/pair.d.ts +0 -0
  116. /package/{types → dist}/performance.d.ts +0 -0
  117. /package/{types → dist}/performance.node.d.ts +0 -0
  118. /package/{types → dist}/pledge.d.ts +0 -0
  119. /package/{types → dist}/prng/Mt19937.d.ts +0 -0
  120. /package/{types → dist}/prng/Xoroshiro128plus.d.ts +0 -0
  121. /package/{types → dist}/prng/Xorshift32.d.ts +0 -0
  122. /package/{types → dist}/prng.d.ts +0 -0
  123. /package/{types → dist}/promise.d.ts +0 -0
  124. /package/{types → dist}/queue.d.ts +0 -0
  125. /package/{types → dist}/random.d.ts +0 -0
  126. /package/{types → dist}/set.d.ts +0 -0
  127. /package/{types → dist}/sort.d.ts +0 -0
  128. /package/{types → dist}/statistics.d.ts +0 -0
  129. /package/{types → dist}/storage.d.ts +0 -0
  130. /package/{types → dist}/string.d.ts +0 -0
  131. /package/{types → dist}/symbol.d.ts +0 -0
  132. /package/{types → dist}/testing.d.ts +0 -0
  133. /package/{types → dist}/time.d.ts +0 -0
  134. /package/{types → dist}/trait/equality.d.ts +0 -0
  135. /package/{types → dist}/trait/fingerprint.d.ts +0 -0
  136. /package/{types → dist}/trait/traits.d.ts +0 -0
  137. /package/{types → dist}/url.d.ts +0 -0
  138. /package/{types → dist}/webcrypto.deno.d.ts +0 -0
  139. /package/{types → dist}/webcrypto.node.d.ts +0 -0
  140. /package/{types → dist}/webcrypto.react-native.d.ts +0 -0
  141. /package/{types → dist}/websocket.d.ts +0 -0
@@ -1,4 +1,17 @@
1
1
  /**
2
+ * Provenance metadata on a content/attr op: *who/what* inserted, deleted, or formatted it. The canonical
3
+ * shape below is a convention — apply/diff/equality treat attribution as an **opaque** object (never branching
4
+ * on these field names), so custom keys flow through — with ONE exception: the nested `format` key merges per
5
+ * inner key (one level), so applying `{format:{italic:[…]}}` *adds* italic while keeping a pre-existing
6
+ * `{format:{bold:[…]}}`, and `{format:{bold:null}}` removes just that inner key (an emptied `format` is
7
+ * dropped). Every other key is flat/wholesale. The `format`/`formatAt` part exists only on
8
+ * children (content ops), never on node attribute ops. As an *update value* on `retain`/`modify`/`*Attr`,
9
+ * attribution uses the same unified tri-state as {@link Formats} (`undefined` skip / `null`
10
+ * clear / `{k:v}` set / `{k:null}` remove) — see the delta `readme.md` "Formats & Attributions". The blanket
11
+ * `null`-clear channel caveat on {@link Formats} applies here too; note `rebase` does not
12
+ * reconcile attribution at all (concurrent attribution edits don't converge), so prefer deterministic
13
+ * attribution assignment outside of concurrent editing.
14
+ *
2
15
  * @typedef {{
3
16
  * insert?: string[]
4
17
  * insertAt?: number
@@ -13,21 +26,36 @@
13
26
  */
14
27
  export const $attribution: s.Schema<Attribution>;
15
28
  /**
16
- * @typedef {{ [key: string]: any }} FormattingAttributes
29
+ * Rich-text formatting attributes (`{ bold: true, }`). As an *update value* on `retain`/`modify` it is a
30
+ * unified tri-state (identical to {@link Attribution}): `undefined`/omitted = skip, `null` = clear all,
31
+ * `{k:v}` = set, `{k:null}` = remove key — see the delta `readme.md` "Formats & Attributions".
32
+ *
33
+ * ⚠️ **Blanket `null` clear is a local-only utility — never send it over a channel.** A `null` clear carries
34
+ * no key information, so it cannot be reconciled key-by-key under `rebase`: a clear *always wins* a concurrent
35
+ * edit (priority-independent — that is what makes it converge), which silently DROPS the other side's set. For
36
+ * collaborative / transmitted data, clear keys individually with `{k:null}` removals instead — those reconcile
37
+ * by priority and converge without data loss (this is what {@link diff} emits and what the rebase fuzz uses).
38
+ *
39
+ * @typedef {{ [key: string]: any }} Formats
40
+ */
41
+ /**
42
+ * @typedef {{ id: string, key: number|string, assoc: 1|-1, attrs?: object }} MarkJSON
17
43
  */
18
44
  /**
19
45
  * @typedef {{
20
46
  * type: 'delta',
21
47
  * name?: string,
22
48
  * attrs?: { [Key in string|number]: DeltaAttrOpJSON },
23
- * children?: Array<DeltaListOpJSON>
49
+ * children?: Array<DeltaListOpJSON>,
50
+ * marks?: Array<MarkJSON>,
51
+ * deleteMarks?: Array<string>
24
52
  * }} DeltaJSON
25
53
  */
26
54
  /**
27
- * @typedef {{ type: 'insert', insert: string|Array<any>, format?: { [key: string]: any }, attribution?: Attribution } | { delete: number } | { type: 'retain', retain: number, format?: { [key:string]: any }, attribution?: Attribution } | { type: 'modify', value: object }} DeltaListOpJSON
55
+ * @typedef {{ type: 'insert', insert: string|Array<any>, format?: { [key: string]: any }, attribution?: Attribution } | { delete: number } | { type: 'retain', retain: number, format?: { [key:string]: any }|null, attribution?: Attribution|null } | { type: 'modify', value: object, format?: { [key:string]: any }|null, attribution?: Attribution|null }} DeltaListOpJSON
28
56
  */
29
57
  /**
30
- * @typedef {{ type: 'insert', value: any, prevValue?: any, attribution?: Attribution } | { type: 'delete', prevValue?: any, attribution?: Attribution } | { type: 'modify', value: DeltaJSON }} DeltaAttrOpJSON
58
+ * @typedef {{ type: 'insert', value: any, attribution?: Attribution } | { type: 'delete', attribution?: Attribution } | { type: 'modify', value: DeltaJSON, attribution?: Attribution|null }} DeltaAttrOpJSON
31
59
  */
32
60
  /**
33
61
  * @typedef {TextOp|InsertOp<any>|DeleteOp|RetainOp|ModifyOp<any>} ChildrenOpAny
@@ -42,13 +70,31 @@ export const $attribution: s.Schema<Attribution>;
42
70
  * @type {s.Schema<DeltaAttrOpJSON>}
43
71
  */
44
72
  export const $deltaMapChangeJson: s.Schema<DeltaAttrOpJSON>;
73
+ /**
74
+ * Invariants shared by all op classes below (TextOp, InsertOp, DeleteOp,
75
+ * RetainOp, ModifyOp, SetAttrOp, DeleteAttrOp, ModifyAttrOp):
76
+ *
77
+ * - **Only code inside `delta.js` may mutate op fields.** External consumers
78
+ * treat ops as immutable; structural fields are JSDoc-annotated `@readonly`
79
+ * to reinforce this. Mutation is permitted only while the owning Delta is
80
+ * not `done` — every builder entry point routes through `modDeltaCheck`
81
+ * to enforce this at runtime.
82
+ * - **Any mutation of a fingerprinted field MUST null `_fingerprint`.** The
83
+ * fingerprint is a lazy cache; if it has already been computed and the
84
+ * underlying data changes without invalidating it, every subsequent
85
+ * fingerprint read (and any `diff` / equality check that relies on it) is
86
+ * wrong. Fields covered: insert, delete, retain, format, attribution,
87
+ * value, key.
88
+ *
89
+ * @internal not part of the consumer API — a content op; build deltas via {@link create}/{@link DeltaBuilder}.
90
+ */
45
91
  export class TextOp extends list.ListNode {
46
92
  /**
47
93
  * @param {string} insert
48
- * @param {FormattingAttributes|null} format
94
+ * @param {Formats|null} format
49
95
  * @param {Attribution?} attribution
50
96
  */
51
- constructor(insert: string, format: FormattingAttributes | null, attribution: Attribution | null);
97
+ constructor(insert: string, format: Formats | null, attribution: Attribution | null);
52
98
  /**
53
99
  * @readonly
54
100
  * @type {string}
@@ -56,15 +102,14 @@ export class TextOp extends list.ListNode {
56
102
  readonly insert: string;
57
103
  /**
58
104
  * @readonly
59
- * @type {FormattingAttributes|null}
105
+ * @type {Formats|null}
60
106
  */
61
- readonly format: FormattingAttributes | null;
107
+ readonly format: Formats | null;
62
108
  attribution: Attribution | null;
63
109
  /**
64
110
  * @type {string?}
65
111
  */
66
112
  _fingerprint: string | null;
67
- get $type(): s.Schema<TextOp>;
68
113
  /**
69
114
  * @param {string} newVal
70
115
  */
@@ -87,9 +132,14 @@ export class TextOp extends list.ListNode {
87
132
  */
88
133
  toJSON(): DeltaListOpJSON;
89
134
  /**
135
+ * @param {number} [start]
136
+ * @param {number} [end]
137
+ * @param {boolean} [_markAsDone] accepted for a uniform children-op `clone` signature; ignored (text
138
+ * holds no nested deltas to freeze).
90
139
  * @return {TextOp}
91
140
  */
92
- clone(start?: number, end?: number): TextOp;
141
+ clone(start?: number, end?: number, _markAsDone?: boolean): TextOp;
142
+ $type: s.Schema<TextOp>;
93
143
  /**
94
144
  * @param {TextOp} other
95
145
  */
@@ -97,14 +147,15 @@ export class TextOp extends list.ListNode {
97
147
  }
98
148
  /**
99
149
  * @template {any} ArrayContent
150
+ * @internal not part of the consumer API — a content op; build deltas via {@link create}/{@link DeltaBuilder}.
100
151
  */
101
152
  export class InsertOp<ArrayContent extends unknown> extends list.ListNode {
102
153
  /**
103
154
  * @param {Array<ArrayContent>} insert
104
- * @param {FormattingAttributes|null} format
155
+ * @param {Formats|null} format
105
156
  * @param {Attribution?} attribution
106
157
  */
107
- constructor(insert: Array<ArrayContent>, format: FormattingAttributes | null, attribution: Attribution | null);
158
+ constructor(insert: Array<ArrayContent>, format: Formats | null, attribution: Attribution | null);
108
159
  /**
109
160
  * @readonly
110
161
  * @type {Array<ArrayContent>}
@@ -112,9 +163,9 @@ export class InsertOp<ArrayContent extends unknown> extends list.ListNode {
112
163
  readonly insert: Array<ArrayContent>;
113
164
  /**
114
165
  * @readonly
115
- * @type {FormattingAttributes?}
166
+ * @type {Formats?}
116
167
  */
117
- readonly format: FormattingAttributes | null;
168
+ readonly format: Formats | null;
118
169
  /**
119
170
  * @readonly
120
171
  * @type {Attribution?}
@@ -124,11 +175,10 @@ export class InsertOp<ArrayContent extends unknown> extends list.ListNode {
124
175
  * @type {string?}
125
176
  */
126
177
  _fingerprint: string | null;
127
- get $type(): s.Schema<InsertOp<any>>;
128
178
  /**
129
- * @param {ArrayContent} newVal
179
+ * @param {ArrayContent} _newVal
130
180
  */
131
- _updateInsert(newVal: ArrayContent): void;
181
+ _updateInsert(_newVal: ArrayContent): void;
132
182
  /**
133
183
  * @return {'insert'}
134
184
  */
@@ -152,9 +202,16 @@ export class InsertOp<ArrayContent extends unknown> extends list.ListNode {
152
202
  */
153
203
  toJSON(): DeltaListOpJSON;
154
204
  /**
205
+ * @param {number} [start]
206
+ * @param {number} [end]
207
+ * @param {boolean} [markAsDone] freeze the cloned child deltas (the default — a shared clone must be
208
+ * immutable). Pass `false` only when the caller is the SOLE owner of the cloned range (a *move*, e.g.
209
+ * `splitHere` which `_splice`s the range out of the source), so the content can stay mutable and is
210
+ * not re-cloned on the next modify (see {@link modValue}).
155
211
  * @return {InsertOp<ArrayContent>}
156
212
  */
157
- clone(start?: number, end?: number): InsertOp<ArrayContent>;
213
+ clone(start?: number, end?: number, markAsDone?: boolean): InsertOp<ArrayContent>;
214
+ $type: s.Schema<InsertOp<any>>;
158
215
  /**
159
216
  * @param {InsertOp<ArrayContent>} other
160
217
  */
@@ -162,6 +219,7 @@ export class InsertOp<ArrayContent extends unknown> extends list.ListNode {
162
219
  }
163
220
  /**
164
221
  * @template {DeltaConf} [Conf={}]
222
+ * @internal not part of the consumer API — a content op; build deltas via {@link create}/{@link DeltaBuilder}.
165
223
  */
166
224
  export class DeleteOp<Conf extends DeltaConf = {}> extends list.ListNode {
167
225
  /**
@@ -169,15 +227,10 @@ export class DeleteOp<Conf extends DeltaConf = {}> extends list.ListNode {
169
227
  */
170
228
  constructor(len: number);
171
229
  delete: number;
172
- /**
173
- * @type {Delta<Conf>?}
174
- */
175
- prevValue: Delta<Conf> | null;
176
230
  /**
177
231
  * @type {string|null}
178
232
  */
179
233
  _fingerprint: string | null;
180
- get $type(): s.Schema<DeleteOp<any>>;
181
234
  /**
182
235
  * @return {'delete'}
183
236
  */
@@ -196,23 +249,29 @@ export class DeleteOp<Conf extends DeltaConf = {}> extends list.ListNode {
196
249
  */
197
250
  toJSON(): DeltaListOpJSON;
198
251
  /**
199
- * @param {number} start
200
- * @param {number} end
252
+ * @param {number} [start]
253
+ * @param {number} [end]
254
+ * @param {boolean} [_markAsDone] accepted for a uniform children-op `clone` signature; ignored (a
255
+ * delete holds no nested content).
201
256
  * @return {DeleteOp}
202
257
  */
203
- clone(start?: number, end?: number): DeleteOp;
258
+ clone(start?: number, end?: number, _markAsDone?: boolean): DeleteOp;
259
+ $type: s.Schema<DeleteOp<any>>;
204
260
  /**
205
261
  * @param {DeleteOp} other
206
262
  */
207
263
  [equalityTrait.EqualityTraitSymbol](other: DeleteOp): boolean;
208
264
  }
265
+ /**
266
+ * @internal not part of the consumer API — a content op; build deltas via {@link create}/{@link DeltaBuilder}.
267
+ */
209
268
  export class RetainOp extends list.ListNode {
210
269
  /**
211
270
  * @param {number} retain
212
- * @param {FormattingAttributes|null} format
213
- * @param {Attribution?} attribution
271
+ * @param {Formats|null|undefined} format tri-state: `undefined` skip / `null` clear / object merge
272
+ * @param {Attribution|null|undefined} attribution tri-state: `undefined` skip / `null` clear / object merge
214
273
  */
215
- constructor(retain: number, format: FormattingAttributes | null, attribution: Attribution | null);
274
+ constructor(retain: number, format: Formats | null | undefined, attribution: Attribution | null | undefined);
216
275
  /**
217
276
  * @readonly
218
277
  * @type {number}
@@ -220,19 +279,18 @@ export class RetainOp extends list.ListNode {
220
279
  readonly retain: number;
221
280
  /**
222
281
  * @readonly
223
- * @type {FormattingAttributes?}
282
+ * @type {Formats|null|undefined}
224
283
  */
225
- readonly format: FormattingAttributes | null;
284
+ readonly format: Formats | null | undefined;
226
285
  /**
227
286
  * @readonly
228
- * @type {Attribution?}
287
+ * @type {Attribution|null|undefined}
229
288
  */
230
- readonly attribution: Attribution | null;
289
+ readonly attribution: Attribution | null | undefined;
231
290
  /**
232
291
  * @type {string|null}
233
292
  */
234
293
  _fingerprint: string | null;
235
- get $type(): s.Schema<RetainOp>;
236
294
  /**
237
295
  * @return {'retain'}
238
296
  */
@@ -250,7 +308,15 @@ export class RetainOp extends list.ListNode {
250
308
  * @return {DeltaListOpJSON}
251
309
  */
252
310
  toJSON(): DeltaListOpJSON;
253
- clone(start?: number, end?: number): RetainOp;
311
+ /**
312
+ * @param {number} [start]
313
+ * @param {number} [end]
314
+ * @param {boolean} [_markAsDone] accepted for a uniform children-op `clone` signature; ignored (retain
315
+ * holds no nested deltas).
316
+ * @return {RetainOp}
317
+ */
318
+ clone(start?: number, end?: number, _markAsDone?: boolean): RetainOp;
319
+ $type: s.Schema<RetainOp>;
254
320
  /**
255
321
  * @param {RetainOp} other
256
322
  */
@@ -260,14 +326,15 @@ export class RetainOp extends list.ListNode {
260
326
  * Delta that can be applied on a YType Embed
261
327
  *
262
328
  * @template {Delta} [DTypes=DeltaAny]
329
+ * @internal not part of the consumer API — a content op; build deltas via {@link create}/{@link DeltaBuilder}.
263
330
  */
264
331
  export class ModifyOp<DTypes extends Delta = DeltaAny> extends list.ListNode {
265
332
  /**
266
333
  * @param {DTypes} delta
267
- * @param {FormattingAttributes|null} format
268
- * @param {Attribution?} attribution
334
+ * @param {Formats|null|undefined} format tri-state: `undefined` skip / `null` clear / object merge
335
+ * @param {Attribution|null|undefined} attribution tri-state: `undefined` skip / `null` clear / object merge
269
336
  */
270
- constructor(delta: DTypes, format: FormattingAttributes | null, attribution: Attribution | null);
337
+ constructor(delta: DTypes, format: Formats | null | undefined, attribution: Attribution | null | undefined);
271
338
  /**
272
339
  * @readonly
273
340
  * @type {DTypes}
@@ -275,19 +342,18 @@ export class ModifyOp<DTypes extends Delta = DeltaAny> extends list.ListNode {
275
342
  readonly value: DTypes;
276
343
  /**
277
344
  * @readonly
278
- * @type {FormattingAttributes?}
345
+ * @type {Formats|null|undefined}
279
346
  */
280
- readonly format: FormattingAttributes | null;
347
+ readonly format: Formats | null | undefined;
281
348
  /**
282
349
  * @readonly
283
- * @type {Attribution?}
350
+ * @type {Attribution|null|undefined}
284
351
  */
285
- readonly attribution: Attribution | null;
352
+ readonly attribution: Attribution | null | undefined;
286
353
  /**
287
354
  * @type {string|null}
288
355
  */
289
356
  _fingerprint: string | null;
290
- get $type(): s.Schema<ModifyOp<DeltaAny>>;
291
357
  /**
292
358
  * @return {'modify'}
293
359
  */
@@ -310,9 +376,14 @@ export class ModifyOp<DTypes extends Delta = DeltaAny> extends list.ListNode {
310
376
  */
311
377
  toJSON(): DeltaListOpJSON;
312
378
  /**
379
+ * @param {number} [_start] ignored (a modify is atomic); accepted for a uniform children-op signature.
380
+ * @param {number} [_end] ignored.
381
+ * @param {boolean} [markAsDone] freeze the cloned value (default); `false` shares it mutable — see
382
+ * {@link InsertOp#clone}. The op itself is still a fresh node; only its `value` is consumed.
313
383
  * @return {ModifyOp<DTypes>}
314
384
  */
315
- clone(): ModifyOp<DTypes>;
385
+ clone(_start?: number, _end?: number, markAsDone?: boolean): ModifyOp<DTypes>;
386
+ $type: s.Schema<ModifyOp<Delta<any>>>;
316
387
  /**
317
388
  * @param {ModifyOp<any>} other
318
389
  */
@@ -321,15 +392,15 @@ export class ModifyOp<DTypes extends Delta = DeltaAny> extends list.ListNode {
321
392
  /**
322
393
  * @template {any} [V=any]
323
394
  * @template {string|number} [K=any]
395
+ * @internal not part of the consumer API — an attribute op; build deltas via {@link create}/{@link DeltaBuilder}.
324
396
  */
325
397
  export class SetAttrOp<V extends unknown = any, K extends string | number = any> {
326
398
  /**
327
399
  * @param {K} key
328
400
  * @param {V} value
329
- * @param {V|undefined} prevValue
330
401
  * @param {Attribution?} attribution
331
402
  */
332
- constructor(key: K, value: V, prevValue: V | undefined, attribution: Attribution | null);
403
+ constructor(key: K, value: V, attribution: Attribution | null);
333
404
  /**
334
405
  * @readonly
335
406
  * @type {K}
@@ -340,11 +411,6 @@ export class SetAttrOp<V extends unknown = any, K extends string | number = any>
340
411
  * @type {V}
341
412
  */
342
413
  readonly value: V;
343
- /**
344
- * @readonly
345
- * @type {V|undefined}
346
- */
347
- readonly prevValue: V | undefined;
348
414
  /**
349
415
  * @readonly
350
416
  * @type {Attribution?}
@@ -354,7 +420,6 @@ export class SetAttrOp<V extends unknown = any, K extends string | number = any>
354
420
  * @type {string|null}
355
421
  */
356
422
  _fingerprint: string | null;
357
- get $type(): s.Schema<SetAttrOp<any, any>>;
358
423
  /**
359
424
  * @return {'insert'}
360
425
  */
@@ -366,16 +431,20 @@ export class SetAttrOp<V extends unknown = any, K extends string | number = any>
366
431
  get fingerprint(): string;
367
432
  toJSON(): {
368
433
  type: "insert";
369
- value: DeltaJSON | V;
434
+ value: V | DeltaJSON;
370
435
  } & ({
371
436
  attribution: Attribution;
372
437
  } | {
373
438
  attribution?: undefined;
374
439
  });
375
440
  /**
441
+ * Full (frozen) clone. A `move` apply reuses the source op instead of cloning, so there is no
442
+ * shared-mutable variant — see {@link DeltaBuilder#apply}.
443
+ *
376
444
  * @return {SetAttrOp<V,K>}
377
445
  */
378
446
  clone(): SetAttrOp<V, K>;
447
+ $type: s.Schema<SetAttrOp<any, any>>;
379
448
  /**
380
449
  * @param {SetAttrOp<V>} other
381
450
  */
@@ -384,28 +453,23 @@ export class SetAttrOp<V extends unknown = any, K extends string | number = any>
384
453
  /**
385
454
  * @template [V=any]
386
455
  * @template {string|number} [K=string|number]
456
+ * @internal not part of the consumer API — an attribute op; build deltas via {@link create}/{@link DeltaBuilder}.
387
457
  */
388
458
  export class DeleteAttrOp<V = any, K extends string | number = string | number> {
389
459
  /**
390
460
  * @param {K} key
391
- * @param {V|undefined} prevValue
392
461
  * @param {Attribution?} attribution
393
462
  */
394
- constructor(key: K, prevValue: V | undefined, attribution: Attribution | null);
463
+ constructor(key: K, attribution: Attribution | null);
395
464
  /**
396
465
  * @type {K}
397
466
  */
398
467
  key: K;
399
- /**
400
- * @type {V|undefined}
401
- */
402
- prevValue: V | undefined;
403
468
  attribution: Attribution | null;
404
469
  /**
405
470
  * @type {string|null}
406
471
  */
407
472
  _fingerprint: string | null;
408
- get $type(): s.Schema<DeleteAttrOp<any, string | number>>;
409
473
  /**
410
474
  * @type {'delete'}
411
475
  */
@@ -416,7 +480,13 @@ export class DeleteAttrOp<V = any, K extends string | number = string | number>
416
480
  * @return {DeltaAttrOpJSON}
417
481
  */
418
482
  toJSON(): DeltaAttrOpJSON;
483
+ /**
484
+ * Full (frozen) clone; a `move` apply reuses the source op instead — see {@link DeltaBuilder#apply}.
485
+ *
486
+ * @return {DeleteAttrOp<V,K>}
487
+ */
419
488
  clone(): DeleteAttrOp<V, K>;
489
+ $type: s.Schema<DeleteAttrOp<any, string | number>>;
420
490
  /**
421
491
  * @param {DeleteAttrOp<V>} other
422
492
  */
@@ -425,13 +495,15 @@ export class DeleteAttrOp<V = any, K extends string | number = string | number>
425
495
  /**
426
496
  * @template {DeltaAny} [Modifier=DeltaAny]
427
497
  * @template {string|number} [K=string]
498
+ * @internal not part of the consumer API — an attribute op; build deltas via {@link create}/{@link DeltaBuilder}.
428
499
  */
429
500
  export class ModifyAttrOp<Modifier extends DeltaAny = DeltaAny, K extends string | number = string> {
430
501
  /**
431
502
  * @param {K} key
432
503
  * @param {Modifier} delta
504
+ * @param {Attribution|null|undefined} attribution tri-state: `undefined` skip / `null` clear / object merge
433
505
  */
434
- constructor(key: K, delta: Modifier);
506
+ constructor(key: K, delta: Modifier, attribution: Attribution | null | undefined);
435
507
  /**
436
508
  * @readonly
437
509
  * @type {K}
@@ -442,11 +514,15 @@ export class ModifyAttrOp<Modifier extends DeltaAny = DeltaAny, K extends string
442
514
  * @type {Modifier}
443
515
  */
444
516
  readonly value: Modifier;
517
+ /**
518
+ * @readonly
519
+ * @type {Attribution|null|undefined}
520
+ */
521
+ readonly attribution: Attribution | null | undefined;
445
522
  /**
446
523
  * @type {string|null}
447
524
  */
448
525
  _fingerprint: string | null;
449
- get $type(): s.Schema<ModifyAttrOp<any, string | number>>;
450
526
  /**
451
527
  * @type {'modify'}
452
528
  */
@@ -461,28 +537,33 @@ export class ModifyAttrOp<Modifier extends DeltaAny = DeltaAny, K extends string
461
537
  */
462
538
  toJSON(): DeltaAttrOpJSON;
463
539
  /**
540
+ * Full (frozen) clone; a `move` apply reuses the source op instead — see {@link DeltaBuilder#apply}.
541
+ *
464
542
  * @return {ModifyAttrOp<Modifier,K>}
465
543
  */
466
544
  clone(): ModifyAttrOp<Modifier, K>;
545
+ $type: s.Schema<ModifyAttrOp<any, string>>;
467
546
  /**
468
547
  * @param {ModifyAttrOp<Modifier>} other
469
548
  */
470
549
  [equalityTrait.EqualityTraitSymbol](other: ModifyAttrOp<Modifier>): boolean;
471
550
  }
472
551
  export const $insertOp: s.Schema<InsertOp<any>>;
473
- export const $modifyOp: s.Schema<ModifyOp>;
552
+ export const $modifyOp: s.Schema<ModifyOp<Delta<any>>>;
474
553
  export const $textOp: s.Schema<TextOp>;
475
554
  export const $deleteOp: s.Schema<DeleteOp<any>>;
476
555
  export const $retainOp: s.Schema<RetainOp>;
477
- export const $anyOp: s.Schema<TextOp | InsertOp<any> | DeleteOp<any> | ModifyOp<DeltaAny>>;
556
+ export const $anyOp: s.Schema<DeleteOp<any> | TextOp | InsertOp<any> | ModifyOp<Delta<any>>>;
478
557
  export const $setAttrOp: s.Schema<SetAttrOp<any>>;
479
- export const $modifyAttrOp: s.Schema<ModifyAttrOp<any, string | number>>;
480
- export const $deleteAttrOp: s.Schema<DeleteAttrOp<any, string | number>>;
481
- export const $anyAttrOp: s.Schema<SetAttrOp<any, any> | DeleteAttrOp<any, string | number> | ModifyAttrOp<any, string | number>>;
558
+ export const $modifyAttrOp: s.Schema<ModifyAttrOp<any>>;
559
+ export const $deleteAttrOp: s.Schema<DeleteAttrOp<any>>;
560
+ export const $anyAttrOp: s.Schema<ModifyAttrOp<any, string> | SetAttrOp<any, any> | DeleteAttrOp<any, string | number>>;
482
561
  export function $setAttrOpWith<Content extends fingerprintTrait.Fingerprintable>($content: s.Schema<Content>): s.Schema<SetAttrOp<Content>>;
483
562
  export function $insertOpWith<Content extends fingerprintTrait.Fingerprintable>($content: s.Schema<Content>): s.Schema<InsertOp<Content>>;
484
563
  export function $modifyOpWith<Modify extends DeltaAny>($content: s.Schema<Modify>): s.Schema<ModifyOp<Modify>>;
485
564
  export function $modifyAttrOpWith<Modify extends DeltaAny>($content: s.Schema<Modify>): s.Schema<ModifyAttrOp<Modify>>;
565
+ export const $mark: s.Schema<Mark>;
566
+ export function createMark(key: number | string, id?: string, assoc?: 1 | -1, attrs?: object | null): Mark;
486
567
  /**
487
568
  * @template {DeltaConf} [Conf={}]
488
569
  * @extends {DeltaData<
@@ -505,7 +586,6 @@ export class Delta<Conf extends DeltaConf = {}> extends DeltaData<DeltaConfGetNa
505
586
  * @param {s.Schema<Delta<any>>?} $schema
506
587
  */
507
588
  constructor(name: string | null, $schema: s.Schema<Delta<any>> | null);
508
- get $type(): s.Schema<DeltaAny>;
509
589
  /**
510
590
  * @type {string}
511
591
  */
@@ -528,6 +608,7 @@ export class Delta<Conf extends DeltaConf = {}> extends DeltaData<DeltaConfGetNa
528
608
  * @return {Delta<Conf>}
529
609
  */
530
610
  done(markAsDone?: boolean): Delta<Conf>;
611
+ $type: s.Schema<Delta<any>>;
531
612
  [fingerprintTrait.FingerprintTraitSymbol](): string;
532
613
  /**
533
614
  * @param {any} other
@@ -537,6 +618,15 @@ export class Delta<Conf extends DeltaConf = {}> extends DeltaData<DeltaConfGetNa
537
618
  }
538
619
  export function slice<Conf_1 extends DeltaConf>(d: Delta<Conf_1>, start?: number, end?: number, currNode?: ChildrenOpAny | null): DeltaBuilder<Conf_1>;
539
620
  export function clone<D extends DeltaAny>(d: D): D extends Delta<infer Conf_1> ? DeltaBuilder<Conf_1> : never;
621
+ export function cloneDeep<Conf_1 extends DeltaConf>(d: Delta<Conf_1>): DeltaBuilder<Conf_1>;
622
+ export function cloneShallow<D extends DeltaAny>(d: D): D extends Delta<infer Conf_1> ? DeltaBuilder<Conf_1> : never;
623
+ export function _mergeChildWithPrev(d: DeltaBuilderAny, op: InsertOp<any> | RetainOp | DeleteOp<any> | TextOp | ModifyOp<any>): boolean;
624
+ export function _splitChildAt(d: DeltaBuilderAny, op: ChildrenOpAny, offset: number): ChildrenOpAny;
625
+ export function _insertChild(d: DeltaBuilderAny, ref: ChildrenOpAny | null, op: ChildrenOpAny): ChildrenOpAny;
626
+ export function _removeChild(d: DeltaBuilderAny, op: ChildrenOpAny): void;
627
+ export function _shrinkChild(d: DeltaBuilderAny, op: ChildrenOpAny, offset: number, len: number): void;
628
+ export function _growRun(d: DeltaBuilderAny, op: RetainOp | DeleteOp<any>, n: number): void;
629
+ export function _spliceInsert(d: DeltaBuilderAny, op: InsertOp<any>, offset: number, elems: Array<any>): void;
540
630
  /**
541
631
  * @template {DeltaConf} [Conf={}]
542
632
  * @template {boolean} [FixedConf=false]
@@ -549,27 +639,79 @@ export class DeltaBuilder<Conf extends DeltaConf = {}, FixedConf extends boolean
549
639
  */
550
640
  constructor(name: string | null, $schema: s.Schema<Delta<Conf>> | null);
551
641
  /**
552
- * @type {FormattingAttributes?}
642
+ * @type {Formats?}
553
643
  */
554
- usedAttributes: FormattingAttributes | null;
644
+ _usedFormats: Formats | null;
555
645
  /**
556
646
  * @type {Attribution?}
557
647
  */
558
- usedAttribution: Attribution | null;
648
+ _usedAttribution: Attribution | null;
649
+ /**
650
+ * Resolved data-companion cache for the `used*` contexts ({@link resolveUsedData}): what data
651
+ * ops inherit instead of the raw context. `undefined` = stale, recomputed on the next data-op
652
+ * consumption ({@link DeltaBuilder#_getUsedFormatsData}) — {@link DeltaBuilder#useFormats} & co
653
+ * clear it whenever they swap the context (which is why the public slots are read-only).
654
+ *
655
+ * @type {Formats|null|undefined}
656
+ */
657
+ _usedFormatsData: Formats | null | undefined;
658
+ /**
659
+ * @type {Attribution|null|undefined}
660
+ */
661
+ _usedAttributionData: Attribution | null | undefined;
662
+ /**
663
+ * The ambient formats context inherited by subsequent ops. Read-only: set it via
664
+ * {@link DeltaBuilder#useFormats} / {@link DeltaBuilder#updateUsedFormats}, which also invalidate
665
+ * the cached data companion — a direct overwrite would leave it stale.
666
+ *
667
+ * @return {Formats?}
668
+ */
669
+ get usedFormats(): Formats | null;
670
+ /**
671
+ * The ambient attribution context inherited by subsequent ops. Read-only — see
672
+ * {@link DeltaBuilder#usedFormats}; set it via {@link DeltaBuilder#useAttribution} /
673
+ * {@link DeltaBuilder#updateUsedAttribution}.
674
+ *
675
+ * @return {Attribution?}
676
+ */
677
+ get usedAttribution(): Attribution | null;
559
678
  /**
679
+ * Set the ambient attribution context inherited by subsequent ops (`undefined`/empty dim args).
680
+ * The object is interned — instruction ops store it, and data ops store its resolved companion
681
+ * ({@link resolveUsedData}), BY REFERENCE. Never mutate it after setting; pass a fresh object
682
+ * instead (same invariant as the objects stored on ops).
683
+ *
560
684
  * @param {Attribution?} attribution
561
685
  */
562
686
  useAttribution(attribution: Attribution | null): this;
563
687
  /**
564
- * @param {FormattingAttributes?} attributes
688
+ * Set the ambient formats context inherited by subsequent ops (`undefined`/empty dim args). The
689
+ * object is interned — see {@link DeltaBuilder#useAttribution}: never mutate it after setting.
690
+ *
691
+ * @param {Formats?} attributes
565
692
  * @return {this}
566
693
  */
567
- useAttributes(attributes: FormattingAttributes | null): this;
694
+ useFormats(attributes: Formats | null): this;
695
+ /**
696
+ * The `usedFormats` context resolved for data-op consumption ({@link resolveUsedData}): the slot
697
+ * object itself when it carries no `{k:null}` removals, one shared stripped copy otherwise.
698
+ * Cached until the context is swapped — no per-op traversal.
699
+ *
700
+ * @return {Formats?}
701
+ */
702
+ _getUsedFormatsData(): Formats | null;
703
+ /**
704
+ * See {@link DeltaBuilder#_getUsedFormatsData} — the `usedAttribution` analogue (its `format` key
705
+ * resolves one level deeper).
706
+ *
707
+ * @return {Attribution?}
708
+ */
709
+ _getUsedAttributionData(): Attribution | null;
568
710
  /**
569
711
  * @param {string} name
570
712
  * @param {any} value
571
713
  */
572
- updateUsedAttributes(name: string, value: any): this;
714
+ updateUsedFormats(name: string, value: any): this;
573
715
  /**
574
716
  * @template {keyof Attribution} NAME
575
717
  * @param {NAME} name
@@ -579,34 +721,58 @@ export class DeltaBuilder<Conf extends DeltaConf = {}, FixedConf extends boolean
579
721
  /**
580
722
  * @template {(FixedConf extends true ? never : (Array<any>|string)) | (DeltaConfGetChildren<Conf> extends infer Children ? (Children extends never ? never : Array<Children>) : never) | DeltaConfGetText<Conf>} NewContent
581
723
  * @param {NewContent} insert
582
- * @param {FormattingAttributes?} [formatting]
724
+ * @param {Formats?} [formatting]
583
725
  * @param {Attribution?} [attribution]
584
726
  * @return {DeltaBuilder<FixedConf extends true ? Conf : DeltaConfOverwrite<Conf,
585
727
  * (Exclude<NewContent,string> extends never ? {} : {
586
728
  * children: Exclude<NewContent,string>[number]|DeltaConfGetChildren<Conf>
587
729
  * }) & (Extract<NewContent,string> extends never ? {} : { text: true })>, FixedConf>}
588
730
  */
589
- insert<NewContent extends (FixedConf extends true ? never : (Array<any> | string)) | (DeltaConfGetChildren<Conf> extends infer Children_1 ? (Children_1 extends never ? never : Array<Children_1>) : never) | DeltaConfGetText<Conf>>(insert: NewContent, formatting?: FormattingAttributes | null, attribution?: Attribution | null): DeltaBuilder<FixedConf extends true ? Conf : DeltaConfOverwrite<Conf, (Exclude<NewContent, string> extends never ? {} : {
731
+ insert<NewContent extends (FixedConf extends true ? never : (Array<any> | string)) | (DeltaConfGetChildren<Conf> extends infer Children_1 ? (Children_1 extends never ? never : Array<Children_1>) : never) | DeltaConfGetText<Conf>>(insert: NewContent, formatting?: Formats | null, attribution?: Attribution | null): DeltaBuilder<FixedConf extends true ? Conf : DeltaConfOverwrite<Conf, (Exclude<NewContent, string> extends never ? {} : {
590
732
  children: Exclude<NewContent, string>[number] | DeltaConfGetChildren<Conf>;
591
733
  }) & (Extract<NewContent, string> extends never ? {} : {
592
734
  text: true;
593
735
  })>, FixedConf>;
594
736
  /**
595
- * @template {Extract<DeltaConfGetAllowedChildren<Conf, FixedConf>,Delta>} NewContent
737
+ * @template {Extract<DeltaConfGetAllowedChildren<Conf, FixedConf>,Delta|DeltaData<any,any,any,any>|DeltaBuilder>} NewContent
596
738
  * @param {NewContent} modify
597
- * @param {FormattingAttributes?} formatting
598
- * @param {Attribution?} attribution
739
+ * @param {Formats?} [formatting] tri-state: omit/`undefined` skip, `null` clear, `{k:v}`/`{k:null}` set/remove
740
+ * @param {Attribution?} [attribution] tri-state: omit/`undefined` skip, `null` clear, `{k:v}`/`{k:null}` set/remove
599
741
  * @return {DeltaBuilder<DeltaConfOverwrite<Conf, {children: DeltaConfGetChildren<Conf>|NewContent}>, FixedConf>}
600
742
  */
601
- modify<NewContent extends Extract<DeltaConfGetAllowedChildren<Conf, FixedConf>, Delta>>(modify: NewContent, formatting?: FormattingAttributes | null, attribution?: Attribution | null): DeltaBuilder<DeltaConfOverwrite<Conf, {
743
+ modify<NewContent extends Extract<DeltaConfGetAllowedChildren<Conf, FixedConf>, Delta | DeltaData<any, any, any, any> | DeltaBuilder>>(modify: NewContent, formatting?: Formats | null, attribution?: Attribution | null): DeltaBuilder<DeltaConfOverwrite<Conf, {
602
744
  children: DeltaConfGetChildren<Conf> | NewContent;
603
745
  }>, FixedConf>;
746
+ /**
747
+ * Add a cursor/selection {@link Mark} at `pos` — a {@link import('./position.js').Pos}: a `path` of
748
+ * content-index / attribute-key steps plus an `assoc` and optional immutable `attrs` (user data
749
+ * carried with the mark). Returns `this` for chaining (like every other builder method). Pass an
750
+ * explicit `id` to reference the mark later — re-adding the same `id` replaces it (e.g. to move a
751
+ * cursor or update its `attrs`) and {@link DeltaBuilder#removeMark} deletes it; an anonymous one-shot
752
+ * mark gets a fresh GUID otherwise.
753
+ *
754
+ * @param {import('./position.js').Pos} pos
755
+ * @param {string} [id]
756
+ * @return {this}
757
+ */
758
+ addMark(pos: import("./position.js").Pos, id?: string): this;
759
+ /**
760
+ * Remove the mark with `id`, located via `pos` (the position it was added at). On a settled document
761
+ * that holds the mark this removes it in place; on a fresh/markless builder it records a transmittable
762
+ * `deleteMarks` change (symmetric to {@link DeltaBuilder#addMark}), so
763
+ * `delta.create().removeMark(pos, id)` yields the delete-mark change to apply / rebase / transmit.
764
+ *
765
+ * @param {import('./position.js').Pos} pos
766
+ * @param {string} id
767
+ * @return {this}
768
+ */
769
+ removeMark(pos: import("./position.js").Pos, id: string): this;
604
770
  /**
605
771
  * @param {number} len
606
- * @param {FormattingAttributes?} [format]
772
+ * @param {Formats?} [format]
607
773
  * @param {Attribution?} [attribution]
608
774
  */
609
- retain(len: number, format?: FormattingAttributes | null, attribution?: Attribution | null): this;
775
+ retain(len: number, format?: Formats | null, attribution?: Attribution | null): this;
610
776
  /**
611
777
  * @param {number} len
612
778
  */
@@ -616,17 +782,16 @@ export class DeltaBuilder<Conf extends DeltaConf = {}, FixedConf extends boolean
616
782
  * @template {DeltaConfGetAllowedAttrs<Conf, FixedConf>[Key]} Val
617
783
  * @param {Key} key
618
784
  * @param {Val} val
619
- * @param {Attribution?} attribution
620
- * @param {Val|undefined} [prevValue]
785
+ * @param {Attribution?} [attribution] provenance for this attr (data: object or `null`/none)
621
786
  * @return {DeltaBuilder<DeltaConfOverwrite<Conf,{attrs:AddToAttrs<DeltaConfGetAttrs<Conf>,Key,Val>}>, FixedConf>}
622
787
  */
623
- setAttr<Key extends Extract<keyof DeltaConfGetAllowedAttrs<Conf, FixedConf>, string | number>, Val extends DeltaConfGetAllowedAttrs<Conf, FixedConf>[Key]>(key: Key, val: Val, attribution?: Attribution | null, prevValue?: Val | undefined): DeltaBuilder<DeltaConfOverwrite<Conf, {
788
+ setAttr<Key extends Extract<keyof DeltaConfGetAllowedAttrs<Conf, FixedConf>, string | number>, Val extends DeltaConfGetAllowedAttrs<Conf, FixedConf>[Key]>(key: Key, val: Val, attribution?: Attribution | null): DeltaBuilder<DeltaConfOverwrite<Conf, {
624
789
  attrs: AddToAttrs<DeltaConfGetAttrs<Conf>, Key, Val>;
625
790
  }>, FixedConf>;
626
791
  /**
627
792
  * @template {DeltaConfGetAllowedAttrs<Conf, FixedConf>} NewAttrs
628
793
  * @param {NewAttrs} attrs
629
- * @param {Attribution?} attribution
794
+ * @param {Attribution?} [attribution] provenance applied to each set attr (data: object or `null`/none)
630
795
  * @return {DeltaBuilder<DeltaConfOverwrite<
631
796
  * Conf,
632
797
  * { attrs: MergeAttrs<DeltaConfGetAttrs<Conf>,NewAttrs> }
@@ -639,13 +804,12 @@ export class DeltaBuilder<Conf extends DeltaConf = {}, FixedConf extends boolean
639
804
  /**
640
805
  * @template {Extract<keyof DeltaConfGetAllowedAttrs<Conf, FixedConf>,string|number>} Key
641
806
  * @param {Key} key
642
- * @param {Attribution?} attribution
643
- * @param {any} [prevValue]
807
+ * @param {Attribution?} [attribution] provenance for the deletion (data: object or `null`/none)
644
808
  * @return {DeltaBuilder<DeltaConfOverwrite<Conf, {
645
809
  * attrs: AddToAttrs<DeltaConfGetAttrs<Conf>,Key,never>
646
810
  * }>, FixedConf>}
647
811
  */
648
- deleteAttr<Key extends Extract<keyof DeltaConfGetAllowedAttrs<Conf, FixedConf>, string | number>>(key: Key, attribution?: Attribution | null, prevValue?: any): DeltaBuilder<DeltaConfOverwrite<Conf, {
812
+ deleteAttr<Key extends Extract<keyof DeltaConfGetAllowedAttrs<Conf, FixedConf>, string | number>>(key: Key, attribution?: Attribution | null): DeltaBuilder<DeltaConfOverwrite<Conf, {
649
813
  attrs: AddToAttrs<DeltaConfGetAttrs<Conf>, Key, never>;
650
814
  }>, FixedConf>;
651
815
  /**
@@ -653,16 +817,39 @@ export class DeltaBuilder<Conf extends DeltaConf = {}, FixedConf extends boolean
653
817
  * @template {Extract<DeltaConfGetAllowedAttrs<Conf, FixedConf>[Key],DeltaAny>} D
654
818
  * @param {Key} key
655
819
  * @param {D} modify
820
+ * @param {Attribution?} [attribution] tri-state instruction merged onto the target attr op: omit/`undefined` skip, `null` clear, `{k:v}`/`{k:null}` set/remove
656
821
  * @return {DeltaBuilder<DeltaConfOverwrite<Conf,{attrs:AddToAttrs<DeltaConfGetAttrs<Conf>,Key,D>}>, FixedConf>}
657
822
  */
658
- modifyAttr<Key extends DeltaConfGetAllowedAttrs<Conf, FixedConf> extends infer As ? { [K in keyof As]: Extract<As[K], DeltaAny> extends never ? never : K; }[keyof As] : never, D extends Extract<DeltaConfGetAllowedAttrs<Conf, FixedConf>[Key], DeltaAny>>(key: Key, modify: D): DeltaBuilder<DeltaConfOverwrite<Conf, {
823
+ modifyAttr<Key extends DeltaConfGetAllowedAttrs<Conf, FixedConf> extends infer As ? { [K in keyof As]: Extract<As[K], DeltaAny> extends never ? never : K; }[keyof As] : never, D extends Extract<DeltaConfGetAllowedAttrs<Conf, FixedConf>[Key], DeltaAny>>(key: Key, modify: D, attribution?: Attribution | null): DeltaBuilder<DeltaConfOverwrite<Conf, {
659
824
  attrs: AddToAttrs<DeltaConfGetAttrs<Conf>, Key, D>;
660
825
  }>, FixedConf>;
661
826
  /**
662
- * @param {Delta<Conf>} other
663
- */
664
- apply(other: Delta<Conf>): this;
665
- /**
827
+ * Apply other delta on this op. The result is the merged op of both of them.
828
+ *
829
+ * a.apply(b.apply(c))
830
+ *
831
+ * is equivalent to
832
+ *
833
+ * a.apply(b).apply(c)
834
+ *
835
+ * If `final = true`, we consider this delta the final state and drop deleteAttrOps from
836
+ * attributes. (E.g. if `otherOp` deletes an attribute, this op will simply not have the
837
+ * attribute). Any kind of `delete` op might be considered a bug. A final delta is not idempotent.
838
+ *
839
+ * @param {Delta<Conf>?} other
840
+ * @param {{ final?: boolean, move?: boolean }} [opts] `move`: the caller donates `other` (it is not
841
+ * read again), so its content is consumed (shared mutable) rather than frozen-cloned — see {@link
842
+ * InsertOp#clone}. UNSAFE if the caller keeps using `other`.
843
+ * @return {DeltaBuilder<Conf>}
844
+ */
845
+ apply(other: Delta<Conf> | null, { final, move }?: {
846
+ final?: boolean;
847
+ move?: boolean;
848
+ }): DeltaBuilder<Conf>;
849
+ /**
850
+ * Rebase this op against a concurrent op. We can apply this op on a doc that already applied
851
+ * `other` op.
852
+ *
666
853
  * @param {DeltaAny} other
667
854
  * @param {boolean} priority
668
855
  */
@@ -693,9 +880,14 @@ export class DeltaBuilder<Conf extends DeltaConf = {}, FixedConf extends boolean
693
880
  text: true;
694
881
  } : never)>, FixedConf>;
695
882
  }
883
+ export function remapRootMarks(node: DeltaAny, mapKey: (key: number | string) => number | string | null): void;
884
+ export function addRootMark(node: DeltaAny, mark: Mark): void;
885
+ export function deleteRootMark(node: DeltaAny, id: string): void;
886
+ export function mergeRootMarks(target: DeltaAny, source: DeltaAny, mapKey?: (key: number | string) => number | string | null): void;
696
887
  /**
697
888
  * @template {DeltaConf} Conf
698
889
  * @extends {s.Schema<Delta<Conf>>}
890
+ * @internal use the {@link $delta} factory; this class is exported only for the `$$delta` predicate.
699
891
  */
700
892
  export class $Delta<Conf extends DeltaConf> extends s.Schema<Delta<Conf>> {
701
893
  /**
@@ -730,40 +922,44 @@ export class $Delta<Conf extends DeltaConf> extends s.Schema<Delta<Conf>> {
730
922
  }>;
731
923
  };
732
924
  }
733
- export function $delta<NodeNameSchema extends s.Schema<string> | string | Array<string> = s.Schema<any>, AttrsSchema extends s.Schema<{
734
- [key: string | number]: any;
735
- }> | {
736
- [key: string | number]: any;
737
- } = s.Schema<{}>, ChildrenSchema extends unknown = s.Schema<never>, HasText extends boolean = false, RecursiveChildren extends boolean = false, Formats extends {
738
- [k: string]: any;
739
- } = {
740
- [k: string]: any;
741
- }>({ name, attrs, children, text, formats, recursiveChildren: recursive }: {
742
- name?: NodeNameSchema | null | undefined;
743
- attrs?: AttrsSchema | null | undefined;
744
- children?: ChildrenSchema | null | undefined;
745
- text?: HasText | undefined;
746
- formats?: Formats | undefined;
747
- recursiveChildren?: RecursiveChildren | undefined;
748
- }): [s.ReadSchemaUnwrapped<NodeNameSchema>, s.ReadSchemaUnwrapped<AttrsSchema>, s.ReadSchemaUnwrapped<ChildrenSchema>] extends [infer NodeName_1, infer Attrs_1, infer Children_1] ? s.Schema<Delta<PrettifyDeltaConf<(import("../ts.js").TypeIsAny<NodeName_1, {}, {
749
- name: NodeName_1;
750
- }> & ({} extends Attrs_1 ? {} : {
751
- attrs: Attrs_1;
752
- }) & ([Children_1] extends [never] ? {} : {
753
- children: Children_1;
754
- }) & (HasText extends false ? {} : {
755
- text: HasText;
756
- }) & (RecursiveChildren extends false ? {} : {
757
- recursiveChildren: RecursiveChildren;
758
- })) extends infer DC extends DeltaConf ? DC : never>>> : never;
925
+ /**
926
+ * Name-first form: a string-literal `name` as the first argument is preserved as a literal type
927
+ * (generic argument inference), so callers don't need `s.$literal('x')` / `@type {const}` to keep the
928
+ * node name literal. The remaining options follow in `opts`.
929
+ *
930
+ * @template {string} Name
931
+ * @template {Omit<ReadableDeltaConf, 'name'>} [Opts={}]
932
+ * @overload
933
+ * @param {Name} name
934
+ * @param {Opts} [opts]
935
+ * @return {s.Schema<Delta<ReadDeltaConf<Opts & { name: Name }>>>}
936
+ */
937
+ export function $delta<Name extends string, Opts extends Omit<ReadableDeltaConf, "name"> = {}>(name: Name, opts?: Opts | undefined): s.Schema<Delta<ReadDeltaConf<Opts & {
938
+ name: Name;
939
+ }>>>;
940
+ /**
941
+ * @template {ReadableDeltaConf} [Conf={}]
942
+ * @overload
943
+ * @param {Conf} opts
944
+ * @return {s.Schema<Delta<ReadDeltaConf<Conf>>>}
945
+ */
946
+ export function $delta<Conf extends ReadableDeltaConf = {}>(opts: Conf): s.Schema<Delta<ReadDeltaConf<Conf>>>;
759
947
  export const $$delta: s.Schema<$Delta<DeltaConf>>;
760
- export const $deltaAny: s.Schema<DeltaAny>;
948
+ export const $deltaAny: s.Schema<Delta<any>>;
761
949
  export const $deltaBuilderAny: s.Schema<DeltaBuilderAny>;
762
- export function mergeAttrs<T extends {
950
+ export function mergeAttributions<T extends {
951
+ [key: string]: any;
952
+ }>(a: T | null, b: T | null): T | null;
953
+ export function mergeFormats<T extends {
763
954
  [key: string]: any;
764
955
  }>(a: T | null, b: T | null): T | null;
765
956
  export function mergeDeltas<D extends DeltaAny | null>(a: D, b: D): D;
766
- export function random<Conf_1 extends DeltaConf>(gen: prng.PRNG, $d: s.Schema<Delta<Conf_1>>): DeltaBuilder<Conf_1>;
957
+ export function random<Conf_1 extends DeltaConf>(gen: prng.PRNG, $d: s.Schema<Delta<Conf_1>>, conf?: {
958
+ source?: DeltaAny | null | undefined;
959
+ minChildOps?: number | undefined;
960
+ maxChildOps?: number | undefined;
961
+ attribution?: boolean | undefined;
962
+ }): DeltaBuilder<Conf_1>;
767
963
  /**
768
964
  * @overload
769
965
  * @return {DeltaBuilder<{}>}
@@ -780,13 +976,13 @@ export function create<NodeName extends string | null>(nodeName: NodeName): Delt
780
976
  } : {}>;
781
977
  /**
782
978
  * @template {string} NodeName
783
- * @template {DeltaConf} Conf
979
+ * @template {s.Schema<DeltaAny>} Schema
784
980
  * @overload
785
981
  * @param {NodeName} nodeName
786
- * @param {s.Schema<Delta<Conf>>} schema
787
- * @return {DeltaBuilder<Conf, true>}
982
+ * @param {Schema} schema
983
+ * @return {Schema extends s.Schema<Delta<infer Conf>> ? DeltaBuilder<Conf, true> : never}
788
984
  */
789
- export function create<NodeName extends string | null, Conf extends DeltaConf>(nodeName: NodeName, schema: s.Schema<Delta<Conf>>): DeltaBuilder<Conf, true>;
985
+ export function create<NodeName extends string | null, Schema extends s.Schema<DeltaAny>>(nodeName: NodeName, schema: Schema): Schema extends s.Schema<Delta<infer Conf_1>> ? DeltaBuilder<Conf_1, true> : never;
790
986
  /**
791
987
  * @template {s.Schema<DeltaAny>} Schema
792
988
  * @overload
@@ -802,8 +998,7 @@ export function create<Schema extends s.Schema<DeltaAny>>(schema: Schema): Schem
802
998
  * @param {NodeName} nodeName
803
999
  * @param {Attrs} attrs
804
1000
  * @param {Children} [children]
805
- * @return {DeltaBuilder<{
806
- * name: NodeName,
1001
+ * @return {DeltaBuilder<(NodeName extends string ? { name: NodeName } : {}) & {
807
1002
  * attrs: Attrs extends null ? {} : Attrs,
808
1003
  * children: Extract<Children,Array<any>> extends Array<infer Ac> ? (unknown extends Ac ? never : Ac) : never,
809
1004
  * text: Extract<Children,string> extends never ? false : true
@@ -811,8 +1006,9 @@ export function create<Schema extends s.Schema<DeltaAny>>(schema: Schema): Schem
811
1006
  */
812
1007
  export function create<NodeName extends string | null, Attrs extends {
813
1008
  [k: string | number]: any;
814
- } | null, Children extends Array<any> | string = never>(nodeName: NodeName, attrs: Attrs, children?: Children | undefined): DeltaBuilder<{
1009
+ } | null, Children extends Array<any> | string = never>(nodeName: NodeName, attrs: Attrs, children?: Children | undefined): DeltaBuilder<(NodeName extends string ? {
815
1010
  name: NodeName;
1011
+ } : {}) & {
816
1012
  attrs: Attrs extends null ? {} : Attrs;
817
1013
  children: Extract<Children, Array<any>> extends Array<infer Ac> ? (unknown extends Ac ? never : Ac) : never;
818
1014
  text: Extract<Children, string> extends never ? false : true;
@@ -823,14 +1019,14 @@ export function create<NodeName extends string | null, Attrs extends {
823
1019
  * @overload
824
1020
  * @param {NodeName} nodeName
825
1021
  * @param {...Array<Children>} children
826
- * @return {DeltaBuilder<{
827
- * name: NodeName,
1022
+ * @return {DeltaBuilder<(NodeName extends string ? { name: NodeName } : {}) & {
828
1023
  * children: Extract<Children,Array<any>> extends Array<infer Ac> ? (unknown extends Ac ? never : Ac) : never,
829
1024
  * text: Extract<Children,string> extends never ? false : true
830
1025
  * }>}
831
1026
  */
832
- export function from<NodeName extends string | null, Children extends Array<any> | string = never>(nodeName: NodeName, ...children: Array<Children>[]): DeltaBuilder<{
1027
+ export function from<NodeName extends string | null, Children extends Array<any> | string = never>(nodeName: NodeName, ...children: Array<Children>[]): DeltaBuilder<(NodeName extends string ? {
833
1028
  name: NodeName;
1029
+ } : {}) & {
834
1030
  children: Extract<Children, Array<any>> extends Array<infer Ac> ? (unknown extends Ac ? never : Ac) : never;
835
1031
  text: Extract<Children, string> extends never ? false : true;
836
1032
  }>;
@@ -874,8 +1070,7 @@ export function from<Attrs extends {
874
1070
  * @param {NodeName} nodeName
875
1071
  * @param {Attrs} attrs
876
1072
  * @param {...Array<Children>} children
877
- * @return {DeltaBuilder<{
878
- * name: NodeName,
1073
+ * @return {DeltaBuilder<(NodeName extends string ? { name: NodeName } : {}) & {
879
1074
  * attrs: Attrs extends null ? {} : Attrs,
880
1075
  * children: Extract<Children,Array<any>> extends Array<infer Ac> ? (unknown extends Ac ? never : Ac) : never,
881
1076
  * text: Extract<Children,string> extends never ? false : true
@@ -883,13 +1078,34 @@ export function from<Attrs extends {
883
1078
  */
884
1079
  export function from<NodeName extends string | null, Attrs extends {
885
1080
  [k: string | number]: any;
886
- } | null, Children extends Array<any> | string = never>(nodeName: NodeName, attrs: Attrs, ...children: Array<Children>[]): DeltaBuilder<{
1081
+ } | null, Children extends Array<any> | string = never>(nodeName: NodeName, attrs: Attrs, ...children: Array<Children>[]): DeltaBuilder<(NodeName extends string ? {
887
1082
  name: NodeName;
1083
+ } : {}) & {
888
1084
  attrs: Attrs extends null ? {} : Attrs;
889
1085
  children: Extract<Children, Array<any>> extends Array<infer Ac> ? (unknown extends Ac ? never : Ac) : never;
890
1086
  text: Extract<Children, string> extends never ? false : true;
891
1087
  }>;
892
- export function diff<Conf_1 extends DeltaConf>(d1: Delta<Conf_1>, d2: NoInfer<Delta<Conf_1>>): DeltaBuilder<Conf_1>;
1088
+ export function diff<Conf_1 extends DeltaConf>(d1: Delta<Conf_1>, d2: NoInfer<Delta<Conf_1>>, options?: DiffOptions): Delta<Conf_1>;
1089
+ export function inverse<Conf_1 extends DeltaConf>(d: DeltaAny, base: Delta<Conf_1>): Delta<Conf_1>;
1090
+ export function diffChangesetWithSeparator(changeset: Array<{
1091
+ index: number;
1092
+ remove: Array<any>;
1093
+ insert: Array<any>;
1094
+ }>, separator: RegExp): any[];
1095
+ /**
1096
+ * Provenance metadata on a content/attr op: *who/what* inserted, deleted, or formatted it. The canonical
1097
+ * shape below is a convention — apply/diff/equality treat attribution as an **opaque** object (never branching
1098
+ * on these field names), so custom keys flow through — with ONE exception: the nested `format` key merges per
1099
+ * inner key (one level), so applying `{format:{italic:[…]}}` *adds* italic while keeping a pre-existing
1100
+ * `{format:{bold:[…]}}`, and `{format:{bold:null}}` removes just that inner key (an emptied `format` is
1101
+ * dropped). Every other key is flat/wholesale. The `format`/`formatAt` part exists only on
1102
+ * children (content ops), never on node attribute ops. As an *update value* on `retain`/`modify`/`*Attr`,
1103
+ * attribution uses the same unified tri-state as {@link Formats} (`undefined` skip / `null`
1104
+ * clear / `{k:v}` set / `{k:null}` remove) — see the delta `readme.md` "Formats & Attributions". The blanket
1105
+ * `null`-clear channel caveat on {@link Formats} applies here too; note `rebase` does not
1106
+ * reconcile attribution at all (concurrent attribution edits don't converge), so prefer deterministic
1107
+ * attribution assignment outside of concurrent editing.
1108
+ */
893
1109
  export type Attribution = {
894
1110
  insert?: string[];
895
1111
  insertAt?: number;
@@ -898,14 +1114,33 @@ export type Attribution = {
898
1114
  format?: Record<string, string[]>;
899
1115
  formatAt?: number;
900
1116
  };
901
- export type FormattingAttributes = {
1117
+ /**
1118
+ * Rich-text formatting attributes (`{ bold: true, … }`). As an *update value* on `retain`/`modify` it is a
1119
+ * unified tri-state (identical to {@link Attribution}): `undefined`/omitted = skip, `null` = clear all,
1120
+ * `{k:v}` = set, `{k:null}` = remove key — see the delta `readme.md` "Formats & Attributions".
1121
+ *
1122
+ * ⚠️ **Blanket `null` clear is a local-only utility — never send it over a channel.** A `null` clear carries
1123
+ * no key information, so it cannot be reconciled key-by-key under `rebase`: a clear *always wins* a concurrent
1124
+ * edit (priority-independent — that is what makes it converge), which silently DROPS the other side's set. For
1125
+ * collaborative / transmitted data, clear keys individually with `{k:null}` removals instead — those reconcile
1126
+ * by priority and converge without data loss (this is what {@link diff} emits and what the rebase fuzz uses).
1127
+ */
1128
+ export type Formats = {
902
1129
  [key: string]: any;
903
1130
  };
1131
+ export type MarkJSON = {
1132
+ id: string;
1133
+ key: number | string;
1134
+ assoc: 1 | -1;
1135
+ attrs?: object;
1136
+ };
904
1137
  export type DeltaJSON = {
905
1138
  type: "delta";
906
1139
  name?: string;
907
1140
  attrs?: { [Key in string | number]: DeltaAttrOpJSON; };
908
1141
  children?: Array<DeltaListOpJSON>;
1142
+ marks?: Array<MarkJSON>;
1143
+ deleteMarks?: Array<string>;
909
1144
  };
910
1145
  export type DeltaListOpJSON = {
911
1146
  type: "insert";
@@ -921,24 +1156,27 @@ export type DeltaListOpJSON = {
921
1156
  retain: number;
922
1157
  format?: {
923
1158
  [key: string]: any;
924
- };
925
- attribution?: Attribution;
1159
+ } | null;
1160
+ attribution?: Attribution | null;
926
1161
  } | {
927
1162
  type: "modify";
928
1163
  value: object;
1164
+ format?: {
1165
+ [key: string]: any;
1166
+ } | null;
1167
+ attribution?: Attribution | null;
929
1168
  };
930
1169
  export type DeltaAttrOpJSON = {
931
1170
  type: "insert";
932
1171
  value: any;
933
- prevValue?: any;
934
1172
  attribution?: Attribution;
935
1173
  } | {
936
1174
  type: "delete";
937
- prevValue?: any;
938
1175
  attribution?: Attribution;
939
1176
  } | {
940
1177
  type: "modify";
941
1178
  value: DeltaJSON;
1179
+ attribution?: Attribution | null;
942
1180
  };
943
1181
  export type ChildrenOpAny = TextOp | InsertOp<any> | DeleteOp | RetainOp | ModifyOp<any>;
944
1182
  export type AttrOpAny = SetAttrOp<any> | DeleteAttrOp<any> | ModifyAttrOp;
@@ -958,9 +1196,16 @@ export type DeltaConf = {
958
1196
  recursiveChildren?: boolean | undefined;
959
1197
  recursiveAttrs?: boolean | undefined;
960
1198
  };
1199
+ /**
1200
+ * Coerce a computed conf to provably satisfy the `DeltaConf` constraint. Declaration emit re-checks
1201
+ * type arguments eagerly, so a deeply-computed conf (mapped/recursive) passed to `Delta<…>` /
1202
+ * `Transformer<…>` must be wrapped here: the conditional exposes `DeltaConf` as its upper bound,
1203
+ * letting the constraint resolve without forcing TS to expand the (self-referential) body.
1204
+ */
1205
+ export type AsDeltaConf<T> = T extends infer DC extends DeltaConf ? DC : never;
961
1206
  export type DeltaConfGetName<Conf_1 extends DeltaConf> = Conf_1 extends {
962
- name: infer Name;
963
- } ? (unknown extends Name ? any : (Exclude<Name, undefined>)) : any;
1207
+ name: infer Name_1;
1208
+ } ? (unknown extends Name_1 ? any : (Exclude<Name_1, undefined>)) : any;
964
1209
  export type DeltaConfGetChildren<Conf_1 extends DeltaConf> = (Conf_1 extends {
965
1210
  children: infer Children_1;
966
1211
  } ? (unknown extends Children_1 ? any : Children_1) : never) | (Conf_1 extends {
@@ -990,6 +1235,61 @@ export type DeltaConfigGetRecursiveAttrs<Conf_1 extends DeltaConf> = Conf_1 exte
990
1235
  export type _SanifyDelta<V> = V extends never ? never : (import("../ts.js").TypeIsAny<V, any, V extends Delta<infer Conf_1> ? Delta<Conf_1> : V>);
991
1236
  export type PrettifyDeltaConf<Conf_1 extends DeltaConf> = import("../ts.js").Prettify<{ [K in keyof Conf_1]: K extends "attrs" ? import("../ts.js").Prettify<{ [KA in keyof Conf_1[K]]: _SanifyDelta<Conf_1[K][KA]>; }, 1> : (K extends "children" ? _SanifyDelta<Conf_1[K]> : Conf_1[K]); }, 1>;
992
1237
  export type DeltaConfOverwrite<D1 extends DeltaConf, D2> = (import("../ts.js").TypeIsAny<D1, any, PrettifyDeltaConf<{ [K in (keyof D1 | keyof D2)]: K extends keyof D2 ? D2[K] : (K extends keyof D1 ? D1[K] : never); }>> & {}) extends infer DC extends DeltaConf ? DC : never;
1238
+ export type ReadableDeltaConf = {
1239
+ name?: s.Schema<string> | string | Array<string>;
1240
+ attrs?: s.Schema<{
1241
+ [key: string | number]: any;
1242
+ }> | {
1243
+ [key: string | number]: any;
1244
+ };
1245
+ children?: any;
1246
+ text?: boolean;
1247
+ recursiveChildren?: boolean;
1248
+ formats?: {
1249
+ [k: string]: any;
1250
+ };
1251
+ };
1252
+ /**
1253
+ * Transforms a ReadableDeltaConf (the input shape of `$delta(spec)`) to a DeltaConf.
1254
+ */
1255
+ export type ReadDeltaConf<DConfSpec extends ReadableDeltaConf> = [DConfSpec extends {
1256
+ name: infer N;
1257
+ } ? s.ReadSchemaUnwrapped<N> : any, DConfSpec extends {
1258
+ attrs: infer A;
1259
+ } ? s.ReadSchemaUnwrapped<A> : {}, DConfSpec extends {
1260
+ children: infer C;
1261
+ } ? s.ReadSchemaUnwrapped<C> : never] extends [infer NodeName_1, infer Attrs_1, infer Children_1] ? AsDeltaConf<PrettifyDeltaConf<(import("../ts.js").TypeIsAny<NodeName_1, {}, {
1262
+ name: NodeName_1;
1263
+ }> & ([keyof Attrs_1] extends [never] ? {} : {
1264
+ attrs: Attrs_1;
1265
+ }) & ([Children_1] extends [never] ? {} : {
1266
+ children: Children_1;
1267
+ }) & (DConfSpec extends {
1268
+ text: true;
1269
+ } ? {
1270
+ text: true;
1271
+ } : {}) & (DConfSpec extends {
1272
+ recursiveChildren: true;
1273
+ } ? {
1274
+ recursiveChildren: true;
1275
+ } : {}))>> : never;
1276
+ export type DiffOptions = {
1277
+ /**
1278
+ * Predicate deciding when two nodes
1279
+ * are paired into a `modify` (vs. replaced wholesale). Defaults to comparing names
1280
+ * (`(d1, d2) => d1.name === d2.name`). Called as `compare(fromNode, toNode)`.
1281
+ */
1282
+ compare?: ((d1: DeltaAny, d2: DeltaAny) => boolean) | undefined;
1283
+ /**
1284
+ * By default `diff` does **not** produce a fully fresh delta: wherever
1285
+ * it emits content from `d2` — a wholesale-inserted child node, or a delta-valued attribute — it *shares*
1286
+ * that nested delta by reference, so the result aliases `d2`'s subtrees. Set `true` to
1287
+ * {@link cloneDeep deep-clone} every such delta (children **and** attributes) as it is included in the
1288
+ * output, yielding a result that shares no structure with `d2` (and is safe to hand to something that
1289
+ * manipulates deltas in place, e.g. a transformer).
1290
+ */
1291
+ clone?: boolean | undefined;
1292
+ };
993
1293
  import * as s from '../schema.js';
994
1294
  import * as list from '../list.js';
995
1295
  import * as equalityTrait from '../trait/equality.js';
@@ -1005,6 +1305,67 @@ import * as fingerprintTrait from '../trait/fingerprint.js';
1005
1305
  * @template {{[Key in string|number|symbol]: any}} NewAttrs
1006
1306
  * @typedef {{ [K in (keyof NewAttrs | keyof Attrs)]: (unknown extends Attrs[K] ? never : Attrs[K]) | (unknown extends NewAttrs[K] ? never : NewAttrs[K]) }} MergeAttrs
1007
1307
  */
1308
+ /**
1309
+ * A cursor/selection anchor stored inside a delta tree (see {@link import('./position.js').marksToPositions}).
1310
+ *
1311
+ * - `key` — the *terminal* step of the position: a content offset (number) or an attribute key
1312
+ * (string) within the node that holds the mark.
1313
+ * - `id` — a unique, user-defined identifier.
1314
+ * - `assoc` — the gravity at a boundary (left `-1` / right `1`).
1315
+ * - `attrs` — optional user-supplied data carried with the mark **by reference**: the same
1316
+ * object is shared across the mark, its `copy`/`clone`s, `toJSON`, and every `MarkPos` from
1317
+ * `marksToPositions`, so the caller must treat it as immutable (do not mutate it after attaching).
1318
+ *
1319
+ * A `Mark` is **immutable** — never mutate one in place; to "move" a mark, replace it with a fresh
1320
+ * `Mark` via {@link Mark#copy} (the {@link Marks} set keys by id, so re-adding the same id replaces
1321
+ * it). Immutability lets a `Mark` be shared freely across a delta and its clones. The class is not
1322
+ * exported — construct via {@link createMark} and validate via {@link $mark}.
1323
+ */
1324
+ declare class Mark {
1325
+ /**
1326
+ * @param {number|string} key
1327
+ * @param {string} [id] unique id; defaults to a fresh GUID
1328
+ * @param {1|-1} [assoc] gravity at a boundary; defaults to right (`1`)
1329
+ * @param {object?} [attrs] optional user data, stored by reference; treat as immutable
1330
+ */
1331
+ constructor(key: number | string, id?: string, assoc?: 1 | -1, attrs?: object | null);
1332
+ /**
1333
+ * @readonly
1334
+ * @type {number|string}
1335
+ */
1336
+ readonly key: number | string;
1337
+ /**
1338
+ * @readonly
1339
+ * @type {string}
1340
+ */
1341
+ readonly id: string;
1342
+ /**
1343
+ * @readonly
1344
+ * @type {1|-1}
1345
+ */
1346
+ readonly assoc: 1 | -1;
1347
+ /**
1348
+ * @readonly
1349
+ * @type {object?}
1350
+ */
1351
+ readonly attrs: object | null;
1352
+ /**
1353
+ * A copy of this mark, optionally at a different `key` (used to "move" an otherwise-immutable mark).
1354
+ *
1355
+ * @param {number|string} [key]
1356
+ * @return {Mark}
1357
+ */
1358
+ copy(key?: number | string): Mark;
1359
+ /**
1360
+ * @return {MarkJSON}
1361
+ */
1362
+ toJSON(): MarkJSON;
1363
+ $type: s.Schema<Mark>;
1364
+ /**
1365
+ * @param {Mark} other
1366
+ */
1367
+ [equalityTrait.EqualityTraitSymbol](other: Mark): boolean;
1368
+ }
1008
1369
  /**
1009
1370
  * @typedef {Delta<any>} DeltaAny
1010
1371
  */
@@ -1020,6 +1381,15 @@ import * as fingerprintTrait from '../trait/fingerprint.js';
1020
1381
  * @property {boolean} [DeltaConf.recursiveChildren=false]
1021
1382
  * @property {boolean} [DeltaConf.recursiveAttrs=false]
1022
1383
  */
1384
+ /**
1385
+ * Coerce a computed conf to provably satisfy the `DeltaConf` constraint. Declaration emit re-checks
1386
+ * type arguments eagerly, so a deeply-computed conf (mapped/recursive) passed to `Delta<…>` /
1387
+ * `Transformer<…>` must be wrapped here: the conditional exposes `DeltaConf` as its upper bound,
1388
+ * letting the constraint resolve without forcing TS to expand the (self-referential) body.
1389
+ *
1390
+ * @template T
1391
+ * @typedef {T extends infer DC extends DeltaConf ? DC : never} AsDeltaConf
1392
+ */
1023
1393
  /**
1024
1394
  * @template {DeltaConf} Conf
1025
1395
  * @typedef {Conf extends {name:infer Name} ? (unknown extends Name ? any : (Exclude<Name,undefined>)) : any} DeltaConfGetName
@@ -1098,6 +1468,9 @@ declare class DeltaData<Name extends string, Attrs extends { [K in string | numb
1098
1468
  * >}
1099
1469
  */
1100
1470
  children: list.List<(Text extends true ? (RetainOp | TextOp | DeleteOp<any>) : never) | (RetainOp | InsertOp<Children> | DeleteOp<any> | (Delta extends Children ? ModifyOp<Extract<Children, Delta>> : never))>;
1471
+ /**
1472
+ * All child-ops sizes combined. Note that delete-ops also have a length
1473
+ */
1101
1474
  childCnt: number;
1102
1475
  /**
1103
1476
  * @type {any}
@@ -1108,7 +1481,72 @@ declare class DeltaData<Name extends string, Attrs extends { [K in string | numb
1108
1481
  */
1109
1482
  _fingerprint: string | null;
1110
1483
  isDone: boolean;
1484
+ /**
1485
+ * Is the final document and does not contain delete, modify, or retain ops.
1486
+ */
1487
+ isFinal: boolean;
1488
+ /**
1489
+ * Leaf {@link Mark marks} whose cursor sits in THIS node (in a settled delta), or the marks to ADD
1490
+ * to the target node (in a change delta). Local/ephemeral cursor state — NOT part of the document
1491
+ * fingerprint or equality. `null` when there are none. See {@link Marks}.
1492
+ *
1493
+ * @type {Marks?}
1494
+ */
1495
+ marks: Marks | null;
1496
+ /**
1497
+ * Mark ids to DELETE (tombstones). Only present in a (non-settled) change delta — like a
1498
+ * `DeleteAttrOp`, a deletion is dropped from a final delta (a materialized document carries none, at
1499
+ * any depth). `null` when there are none. Marks follow *last-writer-wins*, treating each op as an
1500
+ * absolute per-id assignment (present vs absent): adding a mark cancels a pending delete of the same
1501
+ * id ({@link addMarkTo}) and a delete cancels a present add ({@link deleteMarkTo}), so a node never
1502
+ * holds both an add and a delete for one id. {@link deleteMarkTo} is the sole writer of this set
1503
+ * (and `addMarkTo`'s mirror); see {@link applyMarkOps}.
1504
+ *
1505
+ * @type {Set<string>?}
1506
+ */
1507
+ deleteMarks: Set<string> | null;
1508
+ /**
1509
+ * Conservative "this subtree might hold a {@link Mark}" flag (own {@link DeltaData#marks} or any
1510
+ * descendant's). Set `true` when a mark is introduced and OR-propagated up to every ancestor; it is
1511
+ * **never** decremented (removal leaves it conservatively `true`). {@link
1512
+ * import('./position.js').marksToPositions} is the sole resetter: it prunes subtrees where this is
1513
+ * `false` (a guaranteed-empty subtree) and lazily clears a stale `true` to `false` when a descended
1514
+ * subtree turns out to hold none. `false` therefore *guarantees* no marks; `true` only *maybe*.
1515
+ */
1516
+ maybeHasMarks: boolean;
1111
1517
  }
1112
1518
  import * as prng from '../prng.js';
1519
+ /**
1520
+ * The set of leaf {@link Mark marks} on a single delta node, deduplicated by id (so adding the same id
1521
+ * again replaces it). An internal data-shape class (never a public/`new`-from-outside class): every
1522
+ * mutation goes through its methods, so a stored {@link Mark} is treated as immutable and is never
1523
+ * manipulated in place — to "move" a mark you replace it with a fresh `Mark`. {@link clone}/{@link
1524
+ * slice} copy the set so a `done` delta's marks are never mutated through a shared reference. Marks are
1525
+ * local/ephemeral cursor state
1526
+ * and not part of a delta's identity, so this set has no fingerprint/equality of its own.
1527
+ */
1528
+ declare class Marks {
1529
+ /**
1530
+ * @type {Array<Mark>}
1531
+ */
1532
+ _marks: Array<Mark>;
1533
+ get size(): number;
1534
+ /**
1535
+ * Add or replace `mark` (by id). Returns `true` if it was added as a new mark, `false` if it
1536
+ * replaced an existing one with the same id.
1537
+ *
1538
+ * @param {Mark} mark
1539
+ * @return {boolean}
1540
+ */
1541
+ add(mark: Mark): boolean;
1542
+ /**
1543
+ * Remove the mark with `id`. Returns `true` if a mark was present and removed, `false` if absent.
1544
+ *
1545
+ * @param {string} id
1546
+ * @return {boolean}
1547
+ */
1548
+ delete(id: string): boolean;
1549
+ [Symbol.iterator](): ArrayIterator<Mark>;
1550
+ }
1113
1551
  export {};
1114
1552
  //# sourceMappingURL=delta.d.ts.map