lib0 1.0.0-rc.16 → 1.0.0-rc.18
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/delta/delta.d.ts +106 -45
- package/dist/delta/rdt/delta.d.ts +1 -1
- package/dist/delta/rdt/dom.d.ts +1 -1
- package/dist/delta/rdt.d.ts +38 -3
- package/dist/delta/transformer/attribution-to-format.d.ts +52 -0
- package/dist/delta/transformer/full-attributions.d.ts +37 -0
- package/dist/delta/transformer.d.ts +2 -0
- package/package.json +9 -1
- package/src/bin/0serve.js +1 -1
- package/src/delta/delta.js +462 -159
- package/src/delta/rdt/delta.js +2 -2
- package/src/delta/rdt/dom.js +1 -1
- package/src/delta/rdt.js +24 -7
- package/src/delta/transformer/attribution-to-format.js +335 -0
- package/src/delta/transformer/full-attributions.js +282 -0
- package/src/delta/transformer/inline.js +3 -3
- package/src/delta/transformer.js +4 -0
package/dist/delta/delta.d.ts
CHANGED
|
@@ -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,7 +26,17 @@
|
|
|
13
26
|
*/
|
|
14
27
|
export const $attribution: s.Schema<Attribution>;
|
|
15
28
|
/**
|
|
16
|
-
*
|
|
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
|
|
17
40
|
*/
|
|
18
41
|
/**
|
|
19
42
|
* @typedef {{ id: string, key: number|string, assoc: 1|-1, attrs?: object }} MarkJSON
|
|
@@ -29,10 +52,10 @@ export const $attribution: s.Schema<Attribution>;
|
|
|
29
52
|
* }} DeltaJSON
|
|
30
53
|
*/
|
|
31
54
|
/**
|
|
32
|
-
* @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
|
|
33
56
|
*/
|
|
34
57
|
/**
|
|
35
|
-
* @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, prevValue?: any, attribution?: Attribution } | { type: 'delete', prevValue?: any, attribution?: Attribution } | { type: 'modify', value: DeltaJSON, attribution?: Attribution|null }} DeltaAttrOpJSON
|
|
36
59
|
*/
|
|
37
60
|
/**
|
|
38
61
|
* @typedef {TextOp|InsertOp<any>|DeleteOp|RetainOp|ModifyOp<any>} ChildrenOpAny
|
|
@@ -68,10 +91,10 @@ export const $deltaMapChangeJson: s.Schema<DeltaAttrOpJSON>;
|
|
|
68
91
|
export class TextOp extends list.ListNode {
|
|
69
92
|
/**
|
|
70
93
|
* @param {string} insert
|
|
71
|
-
* @param {
|
|
94
|
+
* @param {Formats|null} format
|
|
72
95
|
* @param {Attribution?} attribution
|
|
73
96
|
*/
|
|
74
|
-
constructor(insert: string, format:
|
|
97
|
+
constructor(insert: string, format: Formats | null, attribution: Attribution | null);
|
|
75
98
|
/**
|
|
76
99
|
* @readonly
|
|
77
100
|
* @type {string}
|
|
@@ -79,9 +102,9 @@ export class TextOp extends list.ListNode {
|
|
|
79
102
|
readonly insert: string;
|
|
80
103
|
/**
|
|
81
104
|
* @readonly
|
|
82
|
-
* @type {
|
|
105
|
+
* @type {Formats|null}
|
|
83
106
|
*/
|
|
84
|
-
readonly format:
|
|
107
|
+
readonly format: Formats | null;
|
|
85
108
|
attribution: Attribution | null;
|
|
86
109
|
/**
|
|
87
110
|
* @type {string?}
|
|
@@ -129,10 +152,10 @@ export class TextOp extends list.ListNode {
|
|
|
129
152
|
export class InsertOp<ArrayContent extends unknown> extends list.ListNode {
|
|
130
153
|
/**
|
|
131
154
|
* @param {Array<ArrayContent>} insert
|
|
132
|
-
* @param {
|
|
155
|
+
* @param {Formats|null} format
|
|
133
156
|
* @param {Attribution?} attribution
|
|
134
157
|
*/
|
|
135
|
-
constructor(insert: Array<ArrayContent>, format:
|
|
158
|
+
constructor(insert: Array<ArrayContent>, format: Formats | null, attribution: Attribution | null);
|
|
136
159
|
/**
|
|
137
160
|
* @readonly
|
|
138
161
|
* @type {Array<ArrayContent>}
|
|
@@ -140,9 +163,9 @@ export class InsertOp<ArrayContent extends unknown> extends list.ListNode {
|
|
|
140
163
|
readonly insert: Array<ArrayContent>;
|
|
141
164
|
/**
|
|
142
165
|
* @readonly
|
|
143
|
-
* @type {
|
|
166
|
+
* @type {Formats?}
|
|
144
167
|
*/
|
|
145
|
-
readonly format:
|
|
168
|
+
readonly format: Formats | null;
|
|
146
169
|
/**
|
|
147
170
|
* @readonly
|
|
148
171
|
* @type {Attribution?}
|
|
@@ -247,10 +270,10 @@ export class DeleteOp<Conf extends DeltaConf = {}> extends list.ListNode {
|
|
|
247
270
|
export class RetainOp extends list.ListNode {
|
|
248
271
|
/**
|
|
249
272
|
* @param {number} retain
|
|
250
|
-
* @param {
|
|
251
|
-
* @param {Attribution
|
|
273
|
+
* @param {Formats|null|undefined} format tri-state: `undefined` skip / `null` clear / object merge
|
|
274
|
+
* @param {Attribution|null|undefined} attribution tri-state: `undefined` skip / `null` clear / object merge
|
|
252
275
|
*/
|
|
253
|
-
constructor(retain: number, format:
|
|
276
|
+
constructor(retain: number, format: Formats | null | undefined, attribution: Attribution | null | undefined);
|
|
254
277
|
/**
|
|
255
278
|
* @readonly
|
|
256
279
|
* @type {number}
|
|
@@ -258,14 +281,14 @@ export class RetainOp extends list.ListNode {
|
|
|
258
281
|
readonly retain: number;
|
|
259
282
|
/**
|
|
260
283
|
* @readonly
|
|
261
|
-
* @type {
|
|
284
|
+
* @type {Formats|null|undefined}
|
|
262
285
|
*/
|
|
263
|
-
readonly format:
|
|
286
|
+
readonly format: Formats | null | undefined;
|
|
264
287
|
/**
|
|
265
288
|
* @readonly
|
|
266
|
-
* @type {Attribution
|
|
289
|
+
* @type {Attribution|null|undefined}
|
|
267
290
|
*/
|
|
268
|
-
readonly attribution: Attribution | null;
|
|
291
|
+
readonly attribution: Attribution | null | undefined;
|
|
269
292
|
/**
|
|
270
293
|
* @type {string|null}
|
|
271
294
|
*/
|
|
@@ -310,10 +333,10 @@ export class RetainOp extends list.ListNode {
|
|
|
310
333
|
export class ModifyOp<DTypes extends Delta = DeltaAny> extends list.ListNode {
|
|
311
334
|
/**
|
|
312
335
|
* @param {DTypes} delta
|
|
313
|
-
* @param {
|
|
314
|
-
* @param {Attribution
|
|
336
|
+
* @param {Formats|null|undefined} format tri-state: `undefined` skip / `null` clear / object merge
|
|
337
|
+
* @param {Attribution|null|undefined} attribution tri-state: `undefined` skip / `null` clear / object merge
|
|
315
338
|
*/
|
|
316
|
-
constructor(delta: DTypes, format:
|
|
339
|
+
constructor(delta: DTypes, format: Formats | null | undefined, attribution: Attribution | null | undefined);
|
|
317
340
|
/**
|
|
318
341
|
* @readonly
|
|
319
342
|
* @type {DTypes}
|
|
@@ -321,14 +344,14 @@ export class ModifyOp<DTypes extends Delta = DeltaAny> extends list.ListNode {
|
|
|
321
344
|
readonly value: DTypes;
|
|
322
345
|
/**
|
|
323
346
|
* @readonly
|
|
324
|
-
* @type {
|
|
347
|
+
* @type {Formats|null|undefined}
|
|
325
348
|
*/
|
|
326
|
-
readonly format:
|
|
349
|
+
readonly format: Formats | null | undefined;
|
|
327
350
|
/**
|
|
328
351
|
* @readonly
|
|
329
|
-
* @type {Attribution
|
|
352
|
+
* @type {Attribution|null|undefined}
|
|
330
353
|
*/
|
|
331
|
-
readonly attribution: Attribution | null;
|
|
354
|
+
readonly attribution: Attribution | null | undefined;
|
|
332
355
|
/**
|
|
333
356
|
* @type {string|null}
|
|
334
357
|
*/
|
|
@@ -491,8 +514,9 @@ export class ModifyAttrOp<Modifier extends DeltaAny = DeltaAny, K extends string
|
|
|
491
514
|
/**
|
|
492
515
|
* @param {K} key
|
|
493
516
|
* @param {Modifier} delta
|
|
517
|
+
* @param {Attribution|null|undefined} attribution tri-state: `undefined` skip / `null` clear / object merge
|
|
494
518
|
*/
|
|
495
|
-
constructor(key: K, delta: Modifier);
|
|
519
|
+
constructor(key: K, delta: Modifier, attribution: Attribution | null | undefined);
|
|
496
520
|
/**
|
|
497
521
|
* @readonly
|
|
498
522
|
* @type {K}
|
|
@@ -503,6 +527,11 @@ export class ModifyAttrOp<Modifier extends DeltaAny = DeltaAny, K extends string
|
|
|
503
527
|
* @type {Modifier}
|
|
504
528
|
*/
|
|
505
529
|
readonly value: Modifier;
|
|
530
|
+
/**
|
|
531
|
+
* @readonly
|
|
532
|
+
* @type {Attribution|null|undefined}
|
|
533
|
+
*/
|
|
534
|
+
readonly attribution: Attribution | null | undefined;
|
|
506
535
|
/**
|
|
507
536
|
* @type {string|null}
|
|
508
537
|
*/
|
|
@@ -622,9 +651,9 @@ export class DeltaBuilder<Conf extends DeltaConf = {}, FixedConf extends boolean
|
|
|
622
651
|
*/
|
|
623
652
|
constructor(name: string | null, $schema: s.Schema<Delta<Conf>> | null);
|
|
624
653
|
/**
|
|
625
|
-
* @type {
|
|
654
|
+
* @type {Formats?}
|
|
626
655
|
*/
|
|
627
|
-
|
|
656
|
+
usedFormats: Formats | null;
|
|
628
657
|
/**
|
|
629
658
|
* @type {Attribution?}
|
|
630
659
|
*/
|
|
@@ -634,15 +663,15 @@ export class DeltaBuilder<Conf extends DeltaConf = {}, FixedConf extends boolean
|
|
|
634
663
|
*/
|
|
635
664
|
useAttribution(attribution: Attribution | null): this;
|
|
636
665
|
/**
|
|
637
|
-
* @param {
|
|
666
|
+
* @param {Formats?} attributes
|
|
638
667
|
* @return {this}
|
|
639
668
|
*/
|
|
640
|
-
|
|
669
|
+
useFormats(attributes: Formats | null): this;
|
|
641
670
|
/**
|
|
642
671
|
* @param {string} name
|
|
643
672
|
* @param {any} value
|
|
644
673
|
*/
|
|
645
|
-
|
|
674
|
+
updateUsedFormats(name: string, value: any): this;
|
|
646
675
|
/**
|
|
647
676
|
* @template {keyof Attribution} NAME
|
|
648
677
|
* @param {NAME} name
|
|
@@ -652,14 +681,14 @@ export class DeltaBuilder<Conf extends DeltaConf = {}, FixedConf extends boolean
|
|
|
652
681
|
/**
|
|
653
682
|
* @template {(FixedConf extends true ? never : (Array<any>|string)) | (DeltaConfGetChildren<Conf> extends infer Children ? (Children extends never ? never : Array<Children>) : never) | DeltaConfGetText<Conf>} NewContent
|
|
654
683
|
* @param {NewContent} insert
|
|
655
|
-
* @param {
|
|
684
|
+
* @param {Formats?} [formatting]
|
|
656
685
|
* @param {Attribution?} [attribution]
|
|
657
686
|
* @return {DeltaBuilder<FixedConf extends true ? Conf : DeltaConfOverwrite<Conf,
|
|
658
687
|
* (Exclude<NewContent,string> extends never ? {} : {
|
|
659
688
|
* children: Exclude<NewContent,string>[number]|DeltaConfGetChildren<Conf>
|
|
660
689
|
* }) & (Extract<NewContent,string> extends never ? {} : { text: true })>, FixedConf>}
|
|
661
690
|
*/
|
|
662
|
-
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?:
|
|
691
|
+
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 ? {} : {
|
|
663
692
|
children: Exclude<NewContent, string>[number] | DeltaConfGetChildren<Conf>;
|
|
664
693
|
}) & (Extract<NewContent, string> extends never ? {} : {
|
|
665
694
|
text: true;
|
|
@@ -667,11 +696,11 @@ export class DeltaBuilder<Conf extends DeltaConf = {}, FixedConf extends boolean
|
|
|
667
696
|
/**
|
|
668
697
|
* @template {Extract<DeltaConfGetAllowedChildren<Conf, FixedConf>,Delta|DeltaData<any,any,any,any>|DeltaBuilder>} NewContent
|
|
669
698
|
* @param {NewContent} modify
|
|
670
|
-
* @param {
|
|
671
|
-
* @param {Attribution?} attribution
|
|
699
|
+
* @param {Formats?} [formatting] tri-state: omit/`undefined` skip, `null` clear, `{k:v}`/`{k:null}` set/remove
|
|
700
|
+
* @param {Attribution?} [attribution] tri-state: omit/`undefined` skip, `null` clear, `{k:v}`/`{k:null}` set/remove
|
|
672
701
|
* @return {DeltaBuilder<DeltaConfOverwrite<Conf, {children: DeltaConfGetChildren<Conf>|NewContent}>, FixedConf>}
|
|
673
702
|
*/
|
|
674
|
-
modify<NewContent extends Extract<DeltaConfGetAllowedChildren<Conf, FixedConf>, Delta | DeltaData<any, any, any, any> | DeltaBuilder>>(modify: NewContent, formatting?:
|
|
703
|
+
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, {
|
|
675
704
|
children: DeltaConfGetChildren<Conf> | NewContent;
|
|
676
705
|
}>, FixedConf>;
|
|
677
706
|
/**
|
|
@@ -700,10 +729,10 @@ export class DeltaBuilder<Conf extends DeltaConf = {}, FixedConf extends boolean
|
|
|
700
729
|
removeMark(pos: import("./position.js").Pos, id: string): this;
|
|
701
730
|
/**
|
|
702
731
|
* @param {number} len
|
|
703
|
-
* @param {
|
|
732
|
+
* @param {Formats?} [format]
|
|
704
733
|
* @param {Attribution?} [attribution]
|
|
705
734
|
*/
|
|
706
|
-
retain(len: number, format?:
|
|
735
|
+
retain(len: number, format?: Formats | null, attribution?: Attribution | null): this;
|
|
707
736
|
/**
|
|
708
737
|
* @param {number} len
|
|
709
738
|
* @param {DeltaBuilder<any>|null} prevValue
|
|
@@ -714,7 +743,7 @@ export class DeltaBuilder<Conf extends DeltaConf = {}, FixedConf extends boolean
|
|
|
714
743
|
* @template {DeltaConfGetAllowedAttrs<Conf, FixedConf>[Key]} Val
|
|
715
744
|
* @param {Key} key
|
|
716
745
|
* @param {Val} val
|
|
717
|
-
* @param {Attribution?} attribution
|
|
746
|
+
* @param {Attribution?} [attribution] provenance for this attr (data: object or `null`/none)
|
|
718
747
|
* @param {Val|undefined} [prevValue]
|
|
719
748
|
* @return {DeltaBuilder<DeltaConfOverwrite<Conf,{attrs:AddToAttrs<DeltaConfGetAttrs<Conf>,Key,Val>}>, FixedConf>}
|
|
720
749
|
*/
|
|
@@ -724,7 +753,7 @@ export class DeltaBuilder<Conf extends DeltaConf = {}, FixedConf extends boolean
|
|
|
724
753
|
/**
|
|
725
754
|
* @template {DeltaConfGetAllowedAttrs<Conf, FixedConf>} NewAttrs
|
|
726
755
|
* @param {NewAttrs} attrs
|
|
727
|
-
* @param {Attribution?} attribution
|
|
756
|
+
* @param {Attribution?} [attribution] provenance applied to each set attr (data: object or `null`/none)
|
|
728
757
|
* @return {DeltaBuilder<DeltaConfOverwrite<
|
|
729
758
|
* Conf,
|
|
730
759
|
* { attrs: MergeAttrs<DeltaConfGetAttrs<Conf>,NewAttrs> }
|
|
@@ -737,7 +766,7 @@ export class DeltaBuilder<Conf extends DeltaConf = {}, FixedConf extends boolean
|
|
|
737
766
|
/**
|
|
738
767
|
* @template {Extract<keyof DeltaConfGetAllowedAttrs<Conf, FixedConf>,string|number>} Key
|
|
739
768
|
* @param {Key} key
|
|
740
|
-
* @param {Attribution?} attribution
|
|
769
|
+
* @param {Attribution?} [attribution] provenance for the deletion (data: object or `null`/none)
|
|
741
770
|
* @param {any} [prevValue]
|
|
742
771
|
* @return {DeltaBuilder<DeltaConfOverwrite<Conf, {
|
|
743
772
|
* attrs: AddToAttrs<DeltaConfGetAttrs<Conf>,Key,never>
|
|
@@ -751,9 +780,10 @@ export class DeltaBuilder<Conf extends DeltaConf = {}, FixedConf extends boolean
|
|
|
751
780
|
* @template {Extract<DeltaConfGetAllowedAttrs<Conf, FixedConf>[Key],DeltaAny>} D
|
|
752
781
|
* @param {Key} key
|
|
753
782
|
* @param {D} modify
|
|
783
|
+
* @param {Attribution?} [attribution] tri-state instruction merged onto the target attr op: omit/`undefined` skip, `null` clear, `{k:v}`/`{k:null}` set/remove
|
|
754
784
|
* @return {DeltaBuilder<DeltaConfOverwrite<Conf,{attrs:AddToAttrs<DeltaConfGetAttrs<Conf>,Key,D>}>, FixedConf>}
|
|
755
785
|
*/
|
|
756
|
-
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, {
|
|
786
|
+
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, {
|
|
757
787
|
attrs: AddToAttrs<DeltaConfGetAttrs<Conf>, Key, D>;
|
|
758
788
|
}>, FixedConf>;
|
|
759
789
|
/**
|
|
@@ -891,6 +921,7 @@ export function random<Conf_1 extends DeltaConf>(gen: prng.PRNG, $d: s.Schema<De
|
|
|
891
921
|
source?: DeltaAny | null | undefined;
|
|
892
922
|
minChildOps?: number | undefined;
|
|
893
923
|
maxChildOps?: number | undefined;
|
|
924
|
+
attribution?: boolean | undefined;
|
|
894
925
|
}): DeltaBuilder<Conf_1>;
|
|
895
926
|
/**
|
|
896
927
|
* @overload
|
|
@@ -1023,6 +1054,20 @@ export function diffChangesetWithSeparator(changeset: Array<{
|
|
|
1023
1054
|
remove: Array<any>;
|
|
1024
1055
|
insert: Array<any>;
|
|
1025
1056
|
}>, separator: RegExp): any[];
|
|
1057
|
+
/**
|
|
1058
|
+
* Provenance metadata on a content/attr op: *who/what* inserted, deleted, or formatted it. The canonical
|
|
1059
|
+
* shape below is a convention — apply/diff/equality treat attribution as an **opaque** object (never branching
|
|
1060
|
+
* on these field names), so custom keys flow through — with ONE exception: the nested `format` key merges per
|
|
1061
|
+
* inner key (one level), so applying `{format:{italic:[…]}}` *adds* italic while keeping a pre-existing
|
|
1062
|
+
* `{format:{bold:[…]}}`, and `{format:{bold:null}}` removes just that inner key (an emptied `format` is
|
|
1063
|
+
* dropped). Every other key is flat/wholesale. The `format`/`formatAt` part exists only on
|
|
1064
|
+
* children (content ops), never on node attribute ops. As an *update value* on `retain`/`modify`/`*Attr`,
|
|
1065
|
+
* attribution uses the same unified tri-state as {@link Formats} (`undefined` skip / `null`
|
|
1066
|
+
* clear / `{k:v}` set / `{k:null}` remove) — see the delta `readme.md` "Formats & Attributions". The blanket
|
|
1067
|
+
* `null`-clear channel caveat on {@link Formats} applies here too; note `rebase` does not
|
|
1068
|
+
* reconcile attribution at all (concurrent attribution edits don't converge), so prefer deterministic
|
|
1069
|
+
* attribution assignment outside of concurrent editing.
|
|
1070
|
+
*/
|
|
1026
1071
|
export type Attribution = {
|
|
1027
1072
|
insert?: string[];
|
|
1028
1073
|
insertAt?: number;
|
|
@@ -1031,7 +1076,18 @@ export type Attribution = {
|
|
|
1031
1076
|
format?: Record<string, string[]>;
|
|
1032
1077
|
formatAt?: number;
|
|
1033
1078
|
};
|
|
1034
|
-
|
|
1079
|
+
/**
|
|
1080
|
+
* Rich-text formatting attributes (`{ bold: true, … }`). As an *update value* on `retain`/`modify` it is a
|
|
1081
|
+
* unified tri-state (identical to {@link Attribution}): `undefined`/omitted = skip, `null` = clear all,
|
|
1082
|
+
* `{k:v}` = set, `{k:null}` = remove key — see the delta `readme.md` "Formats & Attributions".
|
|
1083
|
+
*
|
|
1084
|
+
* ⚠️ **Blanket `null` clear is a local-only utility — never send it over a channel.** A `null` clear carries
|
|
1085
|
+
* no key information, so it cannot be reconciled key-by-key under `rebase`: a clear *always wins* a concurrent
|
|
1086
|
+
* edit (priority-independent — that is what makes it converge), which silently DROPS the other side's set. For
|
|
1087
|
+
* collaborative / transmitted data, clear keys individually with `{k:null}` removals instead — those reconcile
|
|
1088
|
+
* by priority and converge without data loss (this is what {@link diff} emits and what the rebase fuzz uses).
|
|
1089
|
+
*/
|
|
1090
|
+
export type Formats = {
|
|
1035
1091
|
[key: string]: any;
|
|
1036
1092
|
};
|
|
1037
1093
|
export type MarkJSON = {
|
|
@@ -1062,11 +1118,15 @@ export type DeltaListOpJSON = {
|
|
|
1062
1118
|
retain: number;
|
|
1063
1119
|
format?: {
|
|
1064
1120
|
[key: string]: any;
|
|
1065
|
-
};
|
|
1066
|
-
attribution?: Attribution;
|
|
1121
|
+
} | null;
|
|
1122
|
+
attribution?: Attribution | null;
|
|
1067
1123
|
} | {
|
|
1068
1124
|
type: "modify";
|
|
1069
1125
|
value: object;
|
|
1126
|
+
format?: {
|
|
1127
|
+
[key: string]: any;
|
|
1128
|
+
} | null;
|
|
1129
|
+
attribution?: Attribution | null;
|
|
1070
1130
|
};
|
|
1071
1131
|
export type DeltaAttrOpJSON = {
|
|
1072
1132
|
type: "insert";
|
|
@@ -1080,6 +1140,7 @@ export type DeltaAttrOpJSON = {
|
|
|
1080
1140
|
} | {
|
|
1081
1141
|
type: "modify";
|
|
1082
1142
|
value: DeltaJSON;
|
|
1143
|
+
attribution?: Attribution | null;
|
|
1083
1144
|
};
|
|
1084
1145
|
export type ChildrenOpAny = TextOp | InsertOp<any> | DeleteOp | RetainOp | ModifyOp<any>;
|
|
1085
1146
|
export type AttrOpAny = SetAttrOp<any> | DeleteAttrOp<any> | ModifyAttrOp;
|
package/dist/delta/rdt/dom.d.ts
CHANGED
package/dist/delta/rdt.d.ts
CHANGED
|
@@ -1,4 +1,39 @@
|
|
|
1
1
|
export { deltaRDT } from "./rdt/delta.js";
|
|
2
|
+
/**
|
|
3
|
+
* @template T
|
|
4
|
+
* @typedef {import('../schema.js').Schema<T>} Schema
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Abstract interface for a delta-based Replicated Data Type.
|
|
8
|
+
*
|
|
9
|
+
* An RDT is an observable that emits a `'delta'` (and, on teardown, a `'destroy'`) event, exposes the
|
|
10
|
+
* {@link Schema schema} of the deltas it produces via `$delta` (so a {@link Binding} can initialize a
|
|
11
|
+
* transformer for it), exposes its current state as a delta via the `delta` getter, and accepts foreign
|
|
12
|
+
* deltas via `applyDelta`.
|
|
13
|
+
*
|
|
14
|
+
* `applyDelta(d)` applies `d` and then, if the change would violate the RDT's own invariants, applies
|
|
15
|
+
* a **fix** of its own (e.g. reversing part of `d`, or inserting missing content) and returns that fix
|
|
16
|
+
* — `null` when none was needed. The fix is a regular change on this RDT, so a {@link Binding} maps it
|
|
17
|
+
* onto the other side just like any other change. `applyDelta` also emits the *effective* change
|
|
18
|
+
* (`d` together with the fix) on the `'delta'` channel.
|
|
19
|
+
*
|
|
20
|
+
* @template {import('./delta.js').DeltaAny} D
|
|
21
|
+
* @typedef {import('../observable.js').ObservableV2<{ delta: (delta: D) => void, destroy: (rdt: RDT<D>) => void }> & {
|
|
22
|
+
* $delta: Schema<D>,
|
|
23
|
+
* delta: D,
|
|
24
|
+
* applyDelta: (delta: D) => D | null,
|
|
25
|
+
* destroy: () => void
|
|
26
|
+
* }} RDT
|
|
27
|
+
*/
|
|
28
|
+
/**
|
|
29
|
+
* Schema guard for any {@link RDT}. RDTs are **duck-typed** — they have several independent
|
|
30
|
+
* implementations (`deltaRDT`, `domRDT`, …) and no common constructor — so this matches by shape
|
|
31
|
+
* rather than by `instanceof`: an object exposing a `$delta` {@link Schema}, an `applyDelta` method,
|
|
32
|
+
* and the observable `on`/`destroy` channel. The (possibly expensive) `delta` getter is not invoked.
|
|
33
|
+
*
|
|
34
|
+
* @type {Schema<RDT<any>>}
|
|
35
|
+
*/
|
|
36
|
+
export const $rdt: Schema<RDT<any>>;
|
|
2
37
|
/**
|
|
3
38
|
* Connects two RDTs so that changes on either side are transformed and reflected on the other.
|
|
4
39
|
*
|
|
@@ -41,8 +76,8 @@ export type Schema<T> = import("../schema.js").Schema<T>;
|
|
|
41
76
|
*
|
|
42
77
|
* An RDT is an observable that emits a `'delta'` (and, on teardown, a `'destroy'`) event, exposes the
|
|
43
78
|
* {@link Schema schema} of the deltas it produces via `$delta` (so a {@link Binding} can initialize a
|
|
44
|
-
* transformer for it), exposes its current state as a delta via `
|
|
45
|
-
* via `applyDelta`.
|
|
79
|
+
* transformer for it), exposes its current state as a delta via the `delta` getter, and accepts foreign
|
|
80
|
+
* deltas via `applyDelta`.
|
|
46
81
|
*
|
|
47
82
|
* `applyDelta(d)` applies `d` and then, if the change would violate the RDT's own invariants, applies
|
|
48
83
|
* a **fix** of its own (e.g. reversing part of `d`, or inserting missing content) and returns that fix
|
|
@@ -55,7 +90,7 @@ export type RDT<D extends import("./delta.js").DeltaAny> = import("../observable
|
|
|
55
90
|
destroy: (rdt: RDT<D>) => void;
|
|
56
91
|
}> & {
|
|
57
92
|
$delta: Schema<D>;
|
|
58
|
-
|
|
93
|
+
delta: D;
|
|
59
94
|
applyDelta: (delta: D) => D | null;
|
|
60
95
|
destroy: () => void;
|
|
61
96
|
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stateless transformer (holds only its `conf`); a single shared instance per template suffices.
|
|
3
|
+
*
|
|
4
|
+
* @extends {Transformer<any,any>}
|
|
5
|
+
*/
|
|
6
|
+
export class AttributionToFormatTransformer extends Transformer<any, any> {
|
|
7
|
+
/**
|
|
8
|
+
* @param {import('../../schema.js').Schema<delta.Delta<any>>} $in
|
|
9
|
+
* @param {import('../../schema.js').Schema<delta.Delta<any>>} $out
|
|
10
|
+
* @param {Conf} conf
|
|
11
|
+
*/
|
|
12
|
+
constructor($in: import("../../schema.js").Schema<delta.Delta<any>>, $out: import("../../schema.js").Schema<delta.Delta<any>>, conf: Conf);
|
|
13
|
+
conf: Conf;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Template for {@link AttributionToFormatTransformer}.
|
|
17
|
+
*
|
|
18
|
+
* @template {delta.DeltaConf} [IN=any]
|
|
19
|
+
* @extends {Template<IN, any>}
|
|
20
|
+
*/
|
|
21
|
+
export class AttributionToFormat<IN extends delta.DeltaConf = any> extends Template<IN, any> {
|
|
22
|
+
/**
|
|
23
|
+
* @param {import('../../schema.js').Schema<delta.Delta<IN>>} $d
|
|
24
|
+
* @param {Conf} conf
|
|
25
|
+
*/
|
|
26
|
+
constructor($d: import("../../schema.js").Schema<delta.Delta<IN>>, conf: Conf);
|
|
27
|
+
/**
|
|
28
|
+
* @type {Conf}
|
|
29
|
+
*/
|
|
30
|
+
conf: Conf;
|
|
31
|
+
}
|
|
32
|
+
export function attributionToFormat<IN extends delta.DeltaConf>($d: import("../../schema.js").Schema<delta.Delta<IN>>, conf: Conf): AttributionToFormat<IN>;
|
|
33
|
+
/**
|
|
34
|
+
* Maps an attribution object to the format value placed under its namespaced key (or `null` to clear
|
|
35
|
+
* that key, `{}`/`undefined` to leave it unchanged).
|
|
36
|
+
*/
|
|
37
|
+
export type Handler = (attribution: import("../delta.js").Attribution) => any;
|
|
38
|
+
/**
|
|
39
|
+
* Per-dimension handlers. Each fires when the op's attribution has a key with that dimension's prefix
|
|
40
|
+
* (`insert`/`insertAt` → `insert`, etc.); the whole attribution object is passed in. A missing handler
|
|
41
|
+
* means "do not render that dimension".
|
|
42
|
+
*/
|
|
43
|
+
export type Conf = {
|
|
44
|
+
insert?: Handler;
|
|
45
|
+
delete?: Handler;
|
|
46
|
+
format?: Handler;
|
|
47
|
+
attrs?: Handler;
|
|
48
|
+
};
|
|
49
|
+
import { Transformer } from './core.js';
|
|
50
|
+
import * as delta from '../delta.js';
|
|
51
|
+
import { Template } from './core.js';
|
|
52
|
+
//# sourceMappingURL=attribution-to-format.d.ts.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stateful transformer holding the accumulated attribution overlay.
|
|
3
|
+
*
|
|
4
|
+
* @extends {Transformer<any,any>}
|
|
5
|
+
*/
|
|
6
|
+
export class FullAttributionsTransformer extends Transformer<any, any> {
|
|
7
|
+
/**
|
|
8
|
+
* @param {import('../../schema.js').Schema<delta.Delta<any>>} $in
|
|
9
|
+
* @param {import('../../schema.js').Schema<delta.Delta<any>>} $out
|
|
10
|
+
*/
|
|
11
|
+
constructor($in: import("../../schema.js").Schema<delta.Delta<any>>, $out: import("../../schema.js").Schema<delta.Delta<any>>);
|
|
12
|
+
/**
|
|
13
|
+
* Content-free overlay: the full accumulated attribution at every document position (instruction
|
|
14
|
+
* form). Mutated in place each change by `rebase` + `apply`.
|
|
15
|
+
*
|
|
16
|
+
* @type {delta.DeltaBuilderAny}
|
|
17
|
+
*/
|
|
18
|
+
overlay: delta.DeltaBuilderAny;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Template for {@link FullAttributionsTransformer}. The transform touches only the `attribution`
|
|
22
|
+
* dimension (metadata, not part of the delta schema), so the output schema equals the input schema.
|
|
23
|
+
*
|
|
24
|
+
* @template {delta.DeltaConf} [IN=any]
|
|
25
|
+
* @extends {Template<IN, IN>}
|
|
26
|
+
*/
|
|
27
|
+
export class FullAttributions<IN extends delta.DeltaConf = any> extends Template<IN, IN> {
|
|
28
|
+
/**
|
|
29
|
+
* @param {import('../../schema.js').Schema<delta.Delta<IN>>} $d
|
|
30
|
+
*/
|
|
31
|
+
constructor($d: import("../../schema.js").Schema<delta.Delta<IN>>);
|
|
32
|
+
}
|
|
33
|
+
export function fullAttributions<IN extends delta.DeltaConf>($d: import("../../schema.js").Schema<delta.Delta<IN>>): FullAttributions<IN>;
|
|
34
|
+
import { Transformer } from './core.js';
|
|
35
|
+
import * as delta from '../delta.js';
|
|
36
|
+
import { Template } from './core.js';
|
|
37
|
+
//# sourceMappingURL=full-attributions.d.ts.map
|
|
@@ -9,4 +9,6 @@ export * from "./transformer/children.js";
|
|
|
9
9
|
export * from "./transformer/project.js";
|
|
10
10
|
export * from "./transformer/value.js";
|
|
11
11
|
export * from "./transformer/rename-attrs.js";
|
|
12
|
+
export * from "./transformer/attribution-to-format.js";
|
|
13
|
+
export * from "./transformer/full-attributions.js";
|
|
12
14
|
//# sourceMappingURL=transformer.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lib0",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.18",
|
|
4
4
|
"description": "",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"type": "module",
|
|
@@ -106,6 +106,14 @@
|
|
|
106
106
|
"types": "./dist/delta/transformer/rename-attrs.d.ts",
|
|
107
107
|
"default": "./src/delta/transformer/rename-attrs.js"
|
|
108
108
|
},
|
|
109
|
+
"./delta/transformer/attribution-to-format": {
|
|
110
|
+
"types": "./dist/delta/transformer/attribution-to-format.d.ts",
|
|
111
|
+
"default": "./src/delta/transformer/attribution-to-format.js"
|
|
112
|
+
},
|
|
113
|
+
"./delta/transformer/full-attributions": {
|
|
114
|
+
"types": "./dist/delta/transformer/full-attributions.d.ts",
|
|
115
|
+
"default": "./src/delta/transformer/full-attributions.js"
|
|
116
|
+
},
|
|
109
117
|
"./delta/rdt": {
|
|
110
118
|
"types": "./dist/delta/rdt.d.ts",
|
|
111
119
|
"default": "./src/delta/rdt.js"
|
package/src/bin/0serve.js
CHANGED
|
@@ -13,7 +13,7 @@ import * as env from '../environment.js'
|
|
|
13
13
|
import * as number from '../number.js'
|
|
14
14
|
import * as logging from 'lib0/logging'
|
|
15
15
|
|
|
16
|
-
const host = env.getParam('--host', '
|
|
16
|
+
const host = env.getParam('--host', '127.0.0.1')
|
|
17
17
|
const port = number.parseInt(env.getParam('--port', '8000'))
|
|
18
18
|
const paramOpenFile = env.getParam('-o', '')
|
|
19
19
|
const debugBrowser = env.getConf('DEBUG_BROWSER')
|