lib0 1.0.0-rc.17 → 1.0.0-rc.19
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 +101 -49
- 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 +397 -182
- 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, attribution?: Attribution }} 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,9 +514,9 @@ export class ModifyAttrOp<Modifier extends DeltaAny = DeltaAny, K extends string
|
|
|
491
514
|
/**
|
|
492
515
|
* @param {K} key
|
|
493
516
|
* @param {Modifier} delta
|
|
494
|
-
* @param {Attribution
|
|
517
|
+
* @param {Attribution|null|undefined} attribution tri-state: `undefined` skip / `null` clear / object merge
|
|
495
518
|
*/
|
|
496
|
-
constructor(key: K, delta: Modifier, attribution: Attribution | null);
|
|
519
|
+
constructor(key: K, delta: Modifier, attribution: Attribution | null | undefined);
|
|
497
520
|
/**
|
|
498
521
|
* @readonly
|
|
499
522
|
* @type {K}
|
|
@@ -506,9 +529,9 @@ export class ModifyAttrOp<Modifier extends DeltaAny = DeltaAny, K extends string
|
|
|
506
529
|
readonly value: Modifier;
|
|
507
530
|
/**
|
|
508
531
|
* @readonly
|
|
509
|
-
* @type {Attribution
|
|
532
|
+
* @type {Attribution|null|undefined}
|
|
510
533
|
*/
|
|
511
|
-
readonly attribution: Attribution | null;
|
|
534
|
+
readonly attribution: Attribution | null | undefined;
|
|
512
535
|
/**
|
|
513
536
|
* @type {string|null}
|
|
514
537
|
*/
|
|
@@ -628,9 +651,9 @@ export class DeltaBuilder<Conf extends DeltaConf = {}, FixedConf extends boolean
|
|
|
628
651
|
*/
|
|
629
652
|
constructor(name: string | null, $schema: s.Schema<Delta<Conf>> | null);
|
|
630
653
|
/**
|
|
631
|
-
* @type {
|
|
654
|
+
* @type {Formats?}
|
|
632
655
|
*/
|
|
633
|
-
|
|
656
|
+
usedFormats: Formats | null;
|
|
634
657
|
/**
|
|
635
658
|
* @type {Attribution?}
|
|
636
659
|
*/
|
|
@@ -640,15 +663,15 @@ export class DeltaBuilder<Conf extends DeltaConf = {}, FixedConf extends boolean
|
|
|
640
663
|
*/
|
|
641
664
|
useAttribution(attribution: Attribution | null): this;
|
|
642
665
|
/**
|
|
643
|
-
* @param {
|
|
666
|
+
* @param {Formats?} attributes
|
|
644
667
|
* @return {this}
|
|
645
668
|
*/
|
|
646
|
-
|
|
669
|
+
useFormats(attributes: Formats | null): this;
|
|
647
670
|
/**
|
|
648
671
|
* @param {string} name
|
|
649
672
|
* @param {any} value
|
|
650
673
|
*/
|
|
651
|
-
|
|
674
|
+
updateUsedFormats(name: string, value: any): this;
|
|
652
675
|
/**
|
|
653
676
|
* @template {keyof Attribution} NAME
|
|
654
677
|
* @param {NAME} name
|
|
@@ -658,14 +681,14 @@ export class DeltaBuilder<Conf extends DeltaConf = {}, FixedConf extends boolean
|
|
|
658
681
|
/**
|
|
659
682
|
* @template {(FixedConf extends true ? never : (Array<any>|string)) | (DeltaConfGetChildren<Conf> extends infer Children ? (Children extends never ? never : Array<Children>) : never) | DeltaConfGetText<Conf>} NewContent
|
|
660
683
|
* @param {NewContent} insert
|
|
661
|
-
* @param {
|
|
684
|
+
* @param {Formats?} [formatting]
|
|
662
685
|
* @param {Attribution?} [attribution]
|
|
663
686
|
* @return {DeltaBuilder<FixedConf extends true ? Conf : DeltaConfOverwrite<Conf,
|
|
664
687
|
* (Exclude<NewContent,string> extends never ? {} : {
|
|
665
688
|
* children: Exclude<NewContent,string>[number]|DeltaConfGetChildren<Conf>
|
|
666
689
|
* }) & (Extract<NewContent,string> extends never ? {} : { text: true })>, FixedConf>}
|
|
667
690
|
*/
|
|
668
|
-
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 ? {} : {
|
|
669
692
|
children: Exclude<NewContent, string>[number] | DeltaConfGetChildren<Conf>;
|
|
670
693
|
}) & (Extract<NewContent, string> extends never ? {} : {
|
|
671
694
|
text: true;
|
|
@@ -673,11 +696,11 @@ export class DeltaBuilder<Conf extends DeltaConf = {}, FixedConf extends boolean
|
|
|
673
696
|
/**
|
|
674
697
|
* @template {Extract<DeltaConfGetAllowedChildren<Conf, FixedConf>,Delta|DeltaData<any,any,any,any>|DeltaBuilder>} NewContent
|
|
675
698
|
* @param {NewContent} modify
|
|
676
|
-
* @param {
|
|
677
|
-
* @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
|
|
678
701
|
* @return {DeltaBuilder<DeltaConfOverwrite<Conf, {children: DeltaConfGetChildren<Conf>|NewContent}>, FixedConf>}
|
|
679
702
|
*/
|
|
680
|
-
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, {
|
|
681
704
|
children: DeltaConfGetChildren<Conf> | NewContent;
|
|
682
705
|
}>, FixedConf>;
|
|
683
706
|
/**
|
|
@@ -706,10 +729,10 @@ export class DeltaBuilder<Conf extends DeltaConf = {}, FixedConf extends boolean
|
|
|
706
729
|
removeMark(pos: import("./position.js").Pos, id: string): this;
|
|
707
730
|
/**
|
|
708
731
|
* @param {number} len
|
|
709
|
-
* @param {
|
|
732
|
+
* @param {Formats?} [format]
|
|
710
733
|
* @param {Attribution?} [attribution]
|
|
711
734
|
*/
|
|
712
|
-
retain(len: number, format?:
|
|
735
|
+
retain(len: number, format?: Formats | null, attribution?: Attribution | null): this;
|
|
713
736
|
/**
|
|
714
737
|
* @param {number} len
|
|
715
738
|
* @param {DeltaBuilder<any>|null} prevValue
|
|
@@ -720,7 +743,7 @@ export class DeltaBuilder<Conf extends DeltaConf = {}, FixedConf extends boolean
|
|
|
720
743
|
* @template {DeltaConfGetAllowedAttrs<Conf, FixedConf>[Key]} Val
|
|
721
744
|
* @param {Key} key
|
|
722
745
|
* @param {Val} val
|
|
723
|
-
* @param {Attribution?} attribution
|
|
746
|
+
* @param {Attribution?} [attribution] provenance for this attr (data: object or `null`/none)
|
|
724
747
|
* @param {Val|undefined} [prevValue]
|
|
725
748
|
* @return {DeltaBuilder<DeltaConfOverwrite<Conf,{attrs:AddToAttrs<DeltaConfGetAttrs<Conf>,Key,Val>}>, FixedConf>}
|
|
726
749
|
*/
|
|
@@ -730,7 +753,7 @@ export class DeltaBuilder<Conf extends DeltaConf = {}, FixedConf extends boolean
|
|
|
730
753
|
/**
|
|
731
754
|
* @template {DeltaConfGetAllowedAttrs<Conf, FixedConf>} NewAttrs
|
|
732
755
|
* @param {NewAttrs} attrs
|
|
733
|
-
* @param {Attribution?} attribution
|
|
756
|
+
* @param {Attribution?} [attribution] provenance applied to each set attr (data: object or `null`/none)
|
|
734
757
|
* @return {DeltaBuilder<DeltaConfOverwrite<
|
|
735
758
|
* Conf,
|
|
736
759
|
* { attrs: MergeAttrs<DeltaConfGetAttrs<Conf>,NewAttrs> }
|
|
@@ -743,7 +766,7 @@ export class DeltaBuilder<Conf extends DeltaConf = {}, FixedConf extends boolean
|
|
|
743
766
|
/**
|
|
744
767
|
* @template {Extract<keyof DeltaConfGetAllowedAttrs<Conf, FixedConf>,string|number>} Key
|
|
745
768
|
* @param {Key} key
|
|
746
|
-
* @param {Attribution?} attribution
|
|
769
|
+
* @param {Attribution?} [attribution] provenance for the deletion (data: object or `null`/none)
|
|
747
770
|
* @param {any} [prevValue]
|
|
748
771
|
* @return {DeltaBuilder<DeltaConfOverwrite<Conf, {
|
|
749
772
|
* attrs: AddToAttrs<DeltaConfGetAttrs<Conf>,Key,never>
|
|
@@ -757,7 +780,7 @@ export class DeltaBuilder<Conf extends DeltaConf = {}, FixedConf extends boolean
|
|
|
757
780
|
* @template {Extract<DeltaConfGetAllowedAttrs<Conf, FixedConf>[Key],DeltaAny>} D
|
|
758
781
|
* @param {Key} key
|
|
759
782
|
* @param {D} modify
|
|
760
|
-
* @param {Attribution?} attribution
|
|
783
|
+
* @param {Attribution?} [attribution] tri-state instruction merged onto the target attr op: omit/`undefined` skip, `null` clear, `{k:v}`/`{k:null}` set/remove
|
|
761
784
|
* @return {DeltaBuilder<DeltaConfOverwrite<Conf,{attrs:AddToAttrs<DeltaConfGetAttrs<Conf>,Key,D>}>, FixedConf>}
|
|
762
785
|
*/
|
|
763
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, {
|
|
@@ -1031,6 +1054,20 @@ export function diffChangesetWithSeparator(changeset: Array<{
|
|
|
1031
1054
|
remove: Array<any>;
|
|
1032
1055
|
insert: Array<any>;
|
|
1033
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
|
+
*/
|
|
1034
1071
|
export type Attribution = {
|
|
1035
1072
|
insert?: string[];
|
|
1036
1073
|
insertAt?: number;
|
|
@@ -1039,7 +1076,18 @@ export type Attribution = {
|
|
|
1039
1076
|
format?: Record<string, string[]>;
|
|
1040
1077
|
formatAt?: number;
|
|
1041
1078
|
};
|
|
1042
|
-
|
|
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 = {
|
|
1043
1091
|
[key: string]: any;
|
|
1044
1092
|
};
|
|
1045
1093
|
export type MarkJSON = {
|
|
@@ -1070,11 +1118,15 @@ export type DeltaListOpJSON = {
|
|
|
1070
1118
|
retain: number;
|
|
1071
1119
|
format?: {
|
|
1072
1120
|
[key: string]: any;
|
|
1073
|
-
};
|
|
1074
|
-
attribution?: Attribution;
|
|
1121
|
+
} | null;
|
|
1122
|
+
attribution?: Attribution | null;
|
|
1075
1123
|
} | {
|
|
1076
1124
|
type: "modify";
|
|
1077
1125
|
value: object;
|
|
1126
|
+
format?: {
|
|
1127
|
+
[key: string]: any;
|
|
1128
|
+
} | null;
|
|
1129
|
+
attribution?: Attribution | null;
|
|
1078
1130
|
};
|
|
1079
1131
|
export type DeltaAttrOpJSON = {
|
|
1080
1132
|
type: "insert";
|
|
@@ -1088,7 +1140,7 @@ export type DeltaAttrOpJSON = {
|
|
|
1088
1140
|
} | {
|
|
1089
1141
|
type: "modify";
|
|
1090
1142
|
value: DeltaJSON;
|
|
1091
|
-
attribution?: Attribution;
|
|
1143
|
+
attribution?: Attribution | null;
|
|
1092
1144
|
};
|
|
1093
1145
|
export type ChildrenOpAny = TextOp | InsertOp<any> | DeleteOp | RetainOp | ModifyOp<any>;
|
|
1094
1146
|
export type AttrOpAny = SetAttrOp<any> | DeleteAttrOp<any> | ModifyAttrOp;
|
|
@@ -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.19",
|
|
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')
|