@monstermann/delta 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +695 -0
- package/dist/Delta/batch.d.mts +57 -0
- package/dist/Delta/batch.mjs +61 -0
- package/dist/Delta/chop.d.mts +56 -0
- package/dist/Delta/chop.mjs +60 -0
- package/dist/Delta/clean.d.mts +57 -0
- package/dist/Delta/clean.mjs +61 -0
- package/dist/Delta/compose.d.mts +58 -0
- package/dist/Delta/compose.mjs +100 -0
- package/dist/Delta/concat.d.mts +50 -0
- package/dist/Delta/concat.mjs +51 -0
- package/dist/Delta/diff.d.mts +73 -0
- package/dist/Delta/diff.mjs +124 -0
- package/dist/Delta/equals.d.mts +43 -0
- package/dist/Delta/equals.mjs +50 -0
- package/dist/Delta/index.d.mts +26 -0
- package/dist/Delta/index.mjs +37 -0
- package/dist/Delta/insert.d.mts +52 -0
- package/dist/Delta/insert.mjs +57 -0
- package/dist/Delta/invert.d.mts +54 -0
- package/dist/Delta/invert.mjs +77 -0
- package/dist/Delta/length.d.mts +51 -0
- package/dist/Delta/length.mjs +51 -0
- package/dist/Delta/push.d.mts +51 -0
- package/dist/Delta/push.mjs +87 -0
- package/dist/Delta/remove.d.mts +41 -0
- package/dist/Delta/remove.mjs +46 -0
- package/dist/Delta/retain.d.mts +70 -0
- package/dist/Delta/retain.mjs +76 -0
- package/dist/Delta/slice.d.mts +64 -0
- package/dist/Delta/slice.mjs +77 -0
- package/dist/Delta/transform.d.mts +63 -0
- package/dist/Delta/transform.mjs +91 -0
- package/dist/Op/index.d.mts +21 -0
- package/dist/OpAttributes/compose.d.mts +6 -0
- package/dist/OpAttributes/compose.mjs +25 -0
- package/dist/OpAttributes/diff.d.mts +6 -0
- package/dist/OpAttributes/diff.mjs +14 -0
- package/dist/OpAttributes/index.d.mts +15 -0
- package/dist/OpAttributes/invert.d.mts +6 -0
- package/dist/OpAttributes/invert.mjs +16 -0
- package/dist/OpAttributes/isEqual.d.mts +6 -0
- package/dist/OpAttributes/isEqual.mjs +16 -0
- package/dist/OpAttributes/transform.d.mts +6 -0
- package/dist/OpAttributes/transform.mjs +13 -0
- package/dist/OpIterator/create.mjs +11 -0
- package/dist/OpIterator/hasNext.mjs +9 -0
- package/dist/OpIterator/next.mjs +36 -0
- package/dist/OpIterator/peek.mjs +7 -0
- package/dist/OpIterator/peekLength.mjs +9 -0
- package/dist/OpIterator/peekType.mjs +7 -0
- package/dist/index.d.mts +2 -0
- package/dist/index.mjs +3 -0
- package/dist/internals/hasKeys.mjs +8 -0
- package/package.json +42 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { OpAttributes } from "../OpAttributes/index.mjs";
|
|
2
|
+
import { Delta } from "./index.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/Delta/batch.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* # batch
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* function Delta.batch<T>(
|
|
11
|
+
* ops: Delta<T>,
|
|
12
|
+
* transform: (delta: Delta<T>) => Delta<T>,
|
|
13
|
+
* ): Delta<T>
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* Batches multiple delta operations together for improved performance.
|
|
17
|
+
*
|
|
18
|
+
* ## Example
|
|
19
|
+
*
|
|
20
|
+
* ```ts [data-first]
|
|
21
|
+
* import { Delta } from "@monstermann/delta";
|
|
22
|
+
*
|
|
23
|
+
* Delta.batch([], (delta) => {
|
|
24
|
+
* // First change copies:
|
|
25
|
+
* delta = Delta.insert(delta, "Hello", { bold: true });
|
|
26
|
+
* // Other changes mutate:
|
|
27
|
+
* delta = Delta.insert(delta, " world");
|
|
28
|
+
* return delta;
|
|
29
|
+
* });
|
|
30
|
+
* // [{ type: "insert", value: "Hello", attributes: { bold: true } },
|
|
31
|
+
* // { type: "insert", value: " world" }]
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* ```ts [data-last]
|
|
35
|
+
* import { Delta } from "@monstermann/delta";
|
|
36
|
+
*
|
|
37
|
+
* pipe(
|
|
38
|
+
* [],
|
|
39
|
+
* Delta.batch((delta) => {
|
|
40
|
+
* // First change copies:
|
|
41
|
+
* delta = Delta.insert(delta, "Hello", { bold: true });
|
|
42
|
+
* // Other changes mutate:
|
|
43
|
+
* delta = Delta.insert(delta, " world");
|
|
44
|
+
* return delta;
|
|
45
|
+
* }),
|
|
46
|
+
* );
|
|
47
|
+
* // [{ type: "insert", value: "Hello", attributes: { bold: true } },
|
|
48
|
+
* // { type: "insert", value: " world" }]
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
*/
|
|
52
|
+
declare const batch: {
|
|
53
|
+
<T extends OpAttributes>(transform: (delta: Delta<NoInfer<T>>) => Delta<NoInfer<T>>): (ops: Delta<T>) => Delta<T>;
|
|
54
|
+
<T extends OpAttributes>(ops: Delta<T>, transform: (delta: Delta<NoInfer<T>>) => Delta<NoInfer<T>>): Delta<T>;
|
|
55
|
+
};
|
|
56
|
+
//#endregion
|
|
57
|
+
export { batch };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { dfdlT } from "@monstermann/dfdl";
|
|
2
|
+
import { endMutations, startMutations } from "@monstermann/remmi";
|
|
3
|
+
|
|
4
|
+
//#region src/Delta/batch.ts
|
|
5
|
+
/**
|
|
6
|
+
* # batch
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* function Delta.batch<T>(
|
|
10
|
+
* ops: Delta<T>,
|
|
11
|
+
* transform: (delta: Delta<T>) => Delta<T>,
|
|
12
|
+
* ): Delta<T>
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* Batches multiple delta operations together for improved performance.
|
|
16
|
+
*
|
|
17
|
+
* ## Example
|
|
18
|
+
*
|
|
19
|
+
* ```ts [data-first]
|
|
20
|
+
* import { Delta } from "@monstermann/delta";
|
|
21
|
+
*
|
|
22
|
+
* Delta.batch([], (delta) => {
|
|
23
|
+
* // First change copies:
|
|
24
|
+
* delta = Delta.insert(delta, "Hello", { bold: true });
|
|
25
|
+
* // Other changes mutate:
|
|
26
|
+
* delta = Delta.insert(delta, " world");
|
|
27
|
+
* return delta;
|
|
28
|
+
* });
|
|
29
|
+
* // [{ type: "insert", value: "Hello", attributes: { bold: true } },
|
|
30
|
+
* // { type: "insert", value: " world" }]
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* ```ts [data-last]
|
|
34
|
+
* import { Delta } from "@monstermann/delta";
|
|
35
|
+
*
|
|
36
|
+
* pipe(
|
|
37
|
+
* [],
|
|
38
|
+
* Delta.batch((delta) => {
|
|
39
|
+
* // First change copies:
|
|
40
|
+
* delta = Delta.insert(delta, "Hello", { bold: true });
|
|
41
|
+
* // Other changes mutate:
|
|
42
|
+
* delta = Delta.insert(delta, " world");
|
|
43
|
+
* return delta;
|
|
44
|
+
* }),
|
|
45
|
+
* );
|
|
46
|
+
* // [{ type: "insert", value: "Hello", attributes: { bold: true } },
|
|
47
|
+
* // { type: "insert", value: " world" }]
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
*/
|
|
51
|
+
const batch = dfdlT((ops, transform) => {
|
|
52
|
+
startMutations();
|
|
53
|
+
try {
|
|
54
|
+
return transform(ops);
|
|
55
|
+
} finally {
|
|
56
|
+
endMutations();
|
|
57
|
+
}
|
|
58
|
+
}, 2);
|
|
59
|
+
|
|
60
|
+
//#endregion
|
|
61
|
+
export { batch };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { OpAttributes } from "../OpAttributes/index.mjs";
|
|
2
|
+
import { Delta } from "./index.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/Delta/chop.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* # chop
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* function Delta.chop<T>(ops: Delta<T>): Delta<T>
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* Removes a trailing retain operation if it has no attributes.
|
|
14
|
+
*
|
|
15
|
+
* ## Example
|
|
16
|
+
*
|
|
17
|
+
* <!-- prettier-ignore -->
|
|
18
|
+
* ```ts [data-first]
|
|
19
|
+
* import { Delta } from "@monstermann/delta";
|
|
20
|
+
*
|
|
21
|
+
* Delta.chop(pipe(
|
|
22
|
+
* [],
|
|
23
|
+
* Delta.insert("Hello"),
|
|
24
|
+
* Delta.retain(5)
|
|
25
|
+
* ));
|
|
26
|
+
* // [{ type: "insert", value: "Hello" }]
|
|
27
|
+
*
|
|
28
|
+
* Delta.chop(pipe(
|
|
29
|
+
* [],
|
|
30
|
+
* Delta.insert("Hello"),
|
|
31
|
+
* Delta.retain(5, { bold: true })
|
|
32
|
+
* ));
|
|
33
|
+
* // [{ type: "insert", value: "Hello" },
|
|
34
|
+
* // { type: "retain", value: 5, attributes: { bold: true } }]
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* <!-- prettier-ignore -->
|
|
38
|
+
* ```ts [data-last]
|
|
39
|
+
* import { Delta } from "@monstermann/delta";
|
|
40
|
+
*
|
|
41
|
+
* pipe(
|
|
42
|
+
* [],
|
|
43
|
+
* Delta.insert("Hello"),
|
|
44
|
+
* Delta.retain(5),
|
|
45
|
+
* Delta.chop()
|
|
46
|
+
* );
|
|
47
|
+
* // [{ type: "insert", value: "Hello" }]
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
*/
|
|
51
|
+
declare const chop: {
|
|
52
|
+
(): <T extends OpAttributes>(ops: Delta<T>) => Delta<T>;
|
|
53
|
+
<T extends OpAttributes>(ops: Delta<T>): Delta<T>;
|
|
54
|
+
};
|
|
55
|
+
//#endregion
|
|
56
|
+
export { chop };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { dfdlT } from "@monstermann/dfdl";
|
|
2
|
+
import { cloneArray } from "@monstermann/remmi";
|
|
3
|
+
|
|
4
|
+
//#region src/Delta/chop.ts
|
|
5
|
+
/**
|
|
6
|
+
* # chop
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* function Delta.chop<T>(ops: Delta<T>): Delta<T>
|
|
10
|
+
* ```
|
|
11
|
+
*
|
|
12
|
+
* Removes a trailing retain operation if it has no attributes.
|
|
13
|
+
*
|
|
14
|
+
* ## Example
|
|
15
|
+
*
|
|
16
|
+
* <!-- prettier-ignore -->
|
|
17
|
+
* ```ts [data-first]
|
|
18
|
+
* import { Delta } from "@monstermann/delta";
|
|
19
|
+
*
|
|
20
|
+
* Delta.chop(pipe(
|
|
21
|
+
* [],
|
|
22
|
+
* Delta.insert("Hello"),
|
|
23
|
+
* Delta.retain(5)
|
|
24
|
+
* ));
|
|
25
|
+
* // [{ type: "insert", value: "Hello" }]
|
|
26
|
+
*
|
|
27
|
+
* Delta.chop(pipe(
|
|
28
|
+
* [],
|
|
29
|
+
* Delta.insert("Hello"),
|
|
30
|
+
* Delta.retain(5, { bold: true })
|
|
31
|
+
* ));
|
|
32
|
+
* // [{ type: "insert", value: "Hello" },
|
|
33
|
+
* // { type: "retain", value: 5, attributes: { bold: true } }]
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* <!-- prettier-ignore -->
|
|
37
|
+
* ```ts [data-last]
|
|
38
|
+
* import { Delta } from "@monstermann/delta";
|
|
39
|
+
*
|
|
40
|
+
* pipe(
|
|
41
|
+
* [],
|
|
42
|
+
* Delta.insert("Hello"),
|
|
43
|
+
* Delta.retain(5),
|
|
44
|
+
* Delta.chop()
|
|
45
|
+
* );
|
|
46
|
+
* // [{ type: "insert", value: "Hello" }]
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
*/
|
|
50
|
+
const chop = dfdlT((ops) => {
|
|
51
|
+
const lastOp = ops[ops.length - 1];
|
|
52
|
+
if (lastOp?.type === "retain" && !lastOp.attributes) {
|
|
53
|
+
ops = cloneArray(ops);
|
|
54
|
+
ops.pop();
|
|
55
|
+
}
|
|
56
|
+
return ops;
|
|
57
|
+
}, 1);
|
|
58
|
+
|
|
59
|
+
//#endregion
|
|
60
|
+
export { chop };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { OpAttributes } from "../OpAttributes/index.mjs";
|
|
2
|
+
import { Delta } from "./index.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/Delta/clean.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* # clean
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* function Delta.clean<T>(ops: Delta<T>): Delta<T>
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* Normalizes the delta by merging consecutive operations of the same type and attributes.
|
|
14
|
+
*
|
|
15
|
+
* ## Example
|
|
16
|
+
*
|
|
17
|
+
* <!-- prettier-ignore -->
|
|
18
|
+
* ```ts [data-first]
|
|
19
|
+
* import { Delta } from "@monstermann/delta";
|
|
20
|
+
*
|
|
21
|
+
* Delta.clean(pipe(
|
|
22
|
+
* [],
|
|
23
|
+
* Delta.insert("Hello"),
|
|
24
|
+
* Delta.insert(" world")
|
|
25
|
+
* ));
|
|
26
|
+
* // [{ type: "insert", value: "Hello world" }]
|
|
27
|
+
*
|
|
28
|
+
* Delta.clean(
|
|
29
|
+
* pipe(
|
|
30
|
+
* [],
|
|
31
|
+
* Delta.insert("Hello", { bold: true }),
|
|
32
|
+
* Delta.insert(" world", { bold: true }),
|
|
33
|
+
* ),
|
|
34
|
+
* );
|
|
35
|
+
* // [{ type: "insert", value: "Hello world", attributes: { bold: true } }]
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* <!-- prettier-ignore -->
|
|
39
|
+
* ```ts [data-last]
|
|
40
|
+
* import { Delta } from "@monstermann/delta";
|
|
41
|
+
*
|
|
42
|
+
* pipe(
|
|
43
|
+
* [],
|
|
44
|
+
* Delta.insert("Hello"),
|
|
45
|
+
* Delta.insert(" world"),
|
|
46
|
+
* Delta.clean()
|
|
47
|
+
* );
|
|
48
|
+
* // [{ type: "insert", value: "Hello world" }]
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
*/
|
|
52
|
+
declare const clean: {
|
|
53
|
+
(): <T extends OpAttributes>(ops: Delta<T>) => Delta<T>;
|
|
54
|
+
<T extends OpAttributes>(ops: Delta<T>): Delta<T>;
|
|
55
|
+
};
|
|
56
|
+
//#endregion
|
|
57
|
+
export { clean };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { push } from "./push.mjs";
|
|
2
|
+
import { dfdlT } from "@monstermann/dfdl";
|
|
3
|
+
import { endMutations, markAsMutable, startMutations } from "@monstermann/remmi";
|
|
4
|
+
|
|
5
|
+
//#region src/Delta/clean.ts
|
|
6
|
+
/**
|
|
7
|
+
* # clean
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* function Delta.clean<T>(ops: Delta<T>): Delta<T>
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* Normalizes the delta by merging consecutive operations of the same type and attributes.
|
|
14
|
+
*
|
|
15
|
+
* ## Example
|
|
16
|
+
*
|
|
17
|
+
* <!-- prettier-ignore -->
|
|
18
|
+
* ```ts [data-first]
|
|
19
|
+
* import { Delta } from "@monstermann/delta";
|
|
20
|
+
*
|
|
21
|
+
* Delta.clean(pipe(
|
|
22
|
+
* [],
|
|
23
|
+
* Delta.insert("Hello"),
|
|
24
|
+
* Delta.insert(" world")
|
|
25
|
+
* ));
|
|
26
|
+
* // [{ type: "insert", value: "Hello world" }]
|
|
27
|
+
*
|
|
28
|
+
* Delta.clean(
|
|
29
|
+
* pipe(
|
|
30
|
+
* [],
|
|
31
|
+
* Delta.insert("Hello", { bold: true }),
|
|
32
|
+
* Delta.insert(" world", { bold: true }),
|
|
33
|
+
* ),
|
|
34
|
+
* );
|
|
35
|
+
* // [{ type: "insert", value: "Hello world", attributes: { bold: true } }]
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* <!-- prettier-ignore -->
|
|
39
|
+
* ```ts [data-last]
|
|
40
|
+
* import { Delta } from "@monstermann/delta";
|
|
41
|
+
*
|
|
42
|
+
* pipe(
|
|
43
|
+
* [],
|
|
44
|
+
* Delta.insert("Hello"),
|
|
45
|
+
* Delta.insert(" world"),
|
|
46
|
+
* Delta.clean()
|
|
47
|
+
* );
|
|
48
|
+
* // [{ type: "insert", value: "Hello world" }]
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
*/
|
|
52
|
+
const clean = dfdlT((ops) => {
|
|
53
|
+
startMutations();
|
|
54
|
+
let newOps = markAsMutable([]);
|
|
55
|
+
for (const op of ops) newOps = push(newOps, op);
|
|
56
|
+
endMutations();
|
|
57
|
+
return newOps.length === ops.length ? ops : newOps;
|
|
58
|
+
}, 1);
|
|
59
|
+
|
|
60
|
+
//#endregion
|
|
61
|
+
export { clean };
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { OpAttributes } from "../OpAttributes/index.mjs";
|
|
2
|
+
import { Delta } from "./index.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/Delta/compose.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* # compose
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* function Delta.compose<T>(a: Delta<T>, b: Delta<T>): Delta<T>
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* Composes two deltas into a single delta that represents applying `a` then `b`.
|
|
14
|
+
*
|
|
15
|
+
* ## Example
|
|
16
|
+
*
|
|
17
|
+
* <!-- prettier-ignore -->
|
|
18
|
+
* ```ts [data-first]
|
|
19
|
+
* import { Delta } from "@monstermann/delta";
|
|
20
|
+
*
|
|
21
|
+
* const a = Delta.insert([], "Hello");
|
|
22
|
+
* const b = pipe(
|
|
23
|
+
* [],
|
|
24
|
+
* Delta.retain(5),
|
|
25
|
+
* Delta.insert(" world")
|
|
26
|
+
* );
|
|
27
|
+
*
|
|
28
|
+
* Delta.compose(a, b);
|
|
29
|
+
* // [{ type: "insert", value: "Hello world" }]
|
|
30
|
+
*
|
|
31
|
+
* const format = Delta.retain([], 5, { bold: true });
|
|
32
|
+
*
|
|
33
|
+
* Delta.compose(a, format);
|
|
34
|
+
* // [{ type: "insert", value: "Hello", attributes: { bold: true } }]
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* <!-- prettier-ignore -->
|
|
38
|
+
* ```ts [data-last]
|
|
39
|
+
* import { Delta } from "@monstermann/delta";
|
|
40
|
+
*
|
|
41
|
+
* const a = Delta.insert([], "Hello");
|
|
42
|
+
* const b = pipe(
|
|
43
|
+
* [],
|
|
44
|
+
* Delta.retain(5),
|
|
45
|
+
* Delta.insert(" world")
|
|
46
|
+
* );
|
|
47
|
+
*
|
|
48
|
+
* pipe(a, Delta.compose(b));
|
|
49
|
+
* // [{ type: "insert", value: "Hello world" }]
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
*/
|
|
53
|
+
declare const compose: {
|
|
54
|
+
<T extends OpAttributes>(b: Delta<NoInfer<T>>): (a: Delta<T>) => Delta<T>;
|
|
55
|
+
<T extends OpAttributes>(a: Delta<T>, b: Delta<NoInfer<T>>): Delta<T>;
|
|
56
|
+
};
|
|
57
|
+
//#endregion
|
|
58
|
+
export { compose };
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { chop } from "./chop.mjs";
|
|
2
|
+
import { push } from "./push.mjs";
|
|
3
|
+
import { compose as compose$1 } from "../OpAttributes/compose.mjs";
|
|
4
|
+
import { create } from "../OpIterator/create.mjs";
|
|
5
|
+
import { peek } from "../OpIterator/peek.mjs";
|
|
6
|
+
import { peekType } from "../OpIterator/peekType.mjs";
|
|
7
|
+
import { peekLength } from "../OpIterator/peekLength.mjs";
|
|
8
|
+
import { next } from "../OpIterator/next.mjs";
|
|
9
|
+
import { hasNext } from "../OpIterator/hasNext.mjs";
|
|
10
|
+
import { dfdlT } from "@monstermann/dfdl";
|
|
11
|
+
import { endMutations, markAsMutable, startMutations } from "@monstermann/remmi";
|
|
12
|
+
|
|
13
|
+
//#region src/Delta/compose.ts
|
|
14
|
+
/**
|
|
15
|
+
* # compose
|
|
16
|
+
*
|
|
17
|
+
* ```ts
|
|
18
|
+
* function Delta.compose<T>(a: Delta<T>, b: Delta<T>): Delta<T>
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* Composes two deltas into a single delta that represents applying `a` then `b`.
|
|
22
|
+
*
|
|
23
|
+
* ## Example
|
|
24
|
+
*
|
|
25
|
+
* <!-- prettier-ignore -->
|
|
26
|
+
* ```ts [data-first]
|
|
27
|
+
* import { Delta } from "@monstermann/delta";
|
|
28
|
+
*
|
|
29
|
+
* const a = Delta.insert([], "Hello");
|
|
30
|
+
* const b = pipe(
|
|
31
|
+
* [],
|
|
32
|
+
* Delta.retain(5),
|
|
33
|
+
* Delta.insert(" world")
|
|
34
|
+
* );
|
|
35
|
+
*
|
|
36
|
+
* Delta.compose(a, b);
|
|
37
|
+
* // [{ type: "insert", value: "Hello world" }]
|
|
38
|
+
*
|
|
39
|
+
* const format = Delta.retain([], 5, { bold: true });
|
|
40
|
+
*
|
|
41
|
+
* Delta.compose(a, format);
|
|
42
|
+
* // [{ type: "insert", value: "Hello", attributes: { bold: true } }]
|
|
43
|
+
* ```
|
|
44
|
+
*
|
|
45
|
+
* <!-- prettier-ignore -->
|
|
46
|
+
* ```ts [data-last]
|
|
47
|
+
* import { Delta } from "@monstermann/delta";
|
|
48
|
+
*
|
|
49
|
+
* const a = Delta.insert([], "Hello");
|
|
50
|
+
* const b = pipe(
|
|
51
|
+
* [],
|
|
52
|
+
* Delta.retain(5),
|
|
53
|
+
* Delta.insert(" world")
|
|
54
|
+
* );
|
|
55
|
+
*
|
|
56
|
+
* pipe(a, Delta.compose(b));
|
|
57
|
+
* // [{ type: "insert", value: "Hello world" }]
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
*/
|
|
61
|
+
const compose = dfdlT((a, b) => {
|
|
62
|
+
const aIter = create(a);
|
|
63
|
+
const bIter = create(b);
|
|
64
|
+
const bHead = peek(bIter);
|
|
65
|
+
startMutations();
|
|
66
|
+
let ops = markAsMutable([]);
|
|
67
|
+
if (bHead?.type === "retain" && bHead.attributes == null) {
|
|
68
|
+
let bRetain = bHead.value;
|
|
69
|
+
while (peekType(aIter) === "insert" && peekLength(aIter) <= bRetain) {
|
|
70
|
+
bRetain -= peekLength(aIter);
|
|
71
|
+
ops.push(next(aIter));
|
|
72
|
+
}
|
|
73
|
+
if (bHead.value - bRetain > 0) next(bIter, bHead.value - bRetain);
|
|
74
|
+
}
|
|
75
|
+
while (hasNext(aIter) || hasNext(bIter)) if (peekType(bIter) === "insert") ops = push(ops, next(bIter));
|
|
76
|
+
else if (peekType(aIter) === "remove") ops = push(ops, next(aIter));
|
|
77
|
+
else {
|
|
78
|
+
const length = Math.min(peekLength(aIter), peekLength(bIter));
|
|
79
|
+
const aOp = next(aIter, length);
|
|
80
|
+
const bOp = next(bIter, length);
|
|
81
|
+
if (bOp.type === "retain") {
|
|
82
|
+
if (aOp.type === "retain") ops = push(ops, {
|
|
83
|
+
attributes: compose$1(aOp.attributes, bOp.attributes, true),
|
|
84
|
+
type: "retain",
|
|
85
|
+
value: length
|
|
86
|
+
});
|
|
87
|
+
else if (aOp.type === "insert") ops = push(ops, {
|
|
88
|
+
attributes: compose$1(aOp.attributes, bOp.attributes),
|
|
89
|
+
type: "insert",
|
|
90
|
+
value: aOp.value
|
|
91
|
+
});
|
|
92
|
+
} else if (bOp.type === "remove" && aOp.type === "retain") ops = push(ops, bOp);
|
|
93
|
+
}
|
|
94
|
+
ops = chop(ops);
|
|
95
|
+
endMutations();
|
|
96
|
+
return ops;
|
|
97
|
+
}, 2);
|
|
98
|
+
|
|
99
|
+
//#endregion
|
|
100
|
+
export { compose };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { OpAttributes } from "../OpAttributes/index.mjs";
|
|
2
|
+
import { Delta } from "./index.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/Delta/concat.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* # concat
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* function Delta.concat<T>(a: Delta<T>, b: Delta<T>): Delta<T>
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* Concatenates two deltas together, merging adjacent operations if possible.
|
|
14
|
+
*
|
|
15
|
+
* ## Example
|
|
16
|
+
*
|
|
17
|
+
* ```ts [data-first]
|
|
18
|
+
* import { Delta } from "@monstermann/delta";
|
|
19
|
+
*
|
|
20
|
+
* const a = Delta.insert([], "Hello");
|
|
21
|
+
* const b = Delta.insert([], " world");
|
|
22
|
+
*
|
|
23
|
+
* Delta.concat(a, b);
|
|
24
|
+
* // [{ type: "insert", value: "Hello world" }]
|
|
25
|
+
*
|
|
26
|
+
* const bold = Delta.insert([], "Hello", { bold: true });
|
|
27
|
+
* const italic = Delta.insert([], " world", { italic: true });
|
|
28
|
+
*
|
|
29
|
+
* Delta.concat(bold, italic);
|
|
30
|
+
* // [{ type: "insert", value: "Hello", attributes: { bold: true } },
|
|
31
|
+
* // { type: "insert", value: " world", attributes: { italic: true } }]
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* ```ts [data-last]
|
|
35
|
+
* import { Delta } from "@monstermann/delta";
|
|
36
|
+
*
|
|
37
|
+
* const a = Delta.insert([], "Hello");
|
|
38
|
+
* const b = Delta.insert([], " world");
|
|
39
|
+
*
|
|
40
|
+
* pipe(a, Delta.concat(b));
|
|
41
|
+
* // [{ type: "insert", value: "Hello world" }]
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
*/
|
|
45
|
+
declare const concat: {
|
|
46
|
+
<T extends OpAttributes>(b: Delta<NoInfer<T>>): (a: Delta<T>) => Delta<T>;
|
|
47
|
+
<T extends OpAttributes>(a: Delta<T>, b: Delta<NoInfer<T>>): Delta<T>;
|
|
48
|
+
};
|
|
49
|
+
//#endregion
|
|
50
|
+
export { concat };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { push } from "./push.mjs";
|
|
2
|
+
import { dfdlT } from "@monstermann/dfdl";
|
|
3
|
+
|
|
4
|
+
//#region src/Delta/concat.ts
|
|
5
|
+
/**
|
|
6
|
+
* # concat
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* function Delta.concat<T>(a: Delta<T>, b: Delta<T>): Delta<T>
|
|
10
|
+
* ```
|
|
11
|
+
*
|
|
12
|
+
* Concatenates two deltas together, merging adjacent operations if possible.
|
|
13
|
+
*
|
|
14
|
+
* ## Example
|
|
15
|
+
*
|
|
16
|
+
* ```ts [data-first]
|
|
17
|
+
* import { Delta } from "@monstermann/delta";
|
|
18
|
+
*
|
|
19
|
+
* const a = Delta.insert([], "Hello");
|
|
20
|
+
* const b = Delta.insert([], " world");
|
|
21
|
+
*
|
|
22
|
+
* Delta.concat(a, b);
|
|
23
|
+
* // [{ type: "insert", value: "Hello world" }]
|
|
24
|
+
*
|
|
25
|
+
* const bold = Delta.insert([], "Hello", { bold: true });
|
|
26
|
+
* const italic = Delta.insert([], " world", { italic: true });
|
|
27
|
+
*
|
|
28
|
+
* Delta.concat(bold, italic);
|
|
29
|
+
* // [{ type: "insert", value: "Hello", attributes: { bold: true } },
|
|
30
|
+
* // { type: "insert", value: " world", attributes: { italic: true } }]
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* ```ts [data-last]
|
|
34
|
+
* import { Delta } from "@monstermann/delta";
|
|
35
|
+
*
|
|
36
|
+
* const a = Delta.insert([], "Hello");
|
|
37
|
+
* const b = Delta.insert([], " world");
|
|
38
|
+
*
|
|
39
|
+
* pipe(a, Delta.concat(b));
|
|
40
|
+
* // [{ type: "insert", value: "Hello world" }]
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
*/
|
|
44
|
+
const concat = dfdlT((a, b) => {
|
|
45
|
+
if (!b.length) return a;
|
|
46
|
+
if (!a.length) return b;
|
|
47
|
+
return push(a, b[0]).concat(b.slice(1));
|
|
48
|
+
}, 2);
|
|
49
|
+
|
|
50
|
+
//#endregion
|
|
51
|
+
export { concat };
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { OpAttributes } from "../OpAttributes/index.mjs";
|
|
2
|
+
import { Delta } from "./index.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/Delta/diff.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* # diff
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* function Delta.diff<T>(a: Delta<T>, b: Delta<T>, cursor?: number): Delta<T>
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* Computes the difference between two document deltas, returning a delta that transforms `a` into `b`.
|
|
14
|
+
*
|
|
15
|
+
* The optional `cursor` parameter provides a hint about where the user's cursor is positioned. This helps produce more intuitive diffs when there are multiple valid ways to represent the same change.
|
|
16
|
+
*
|
|
17
|
+
* ## Example
|
|
18
|
+
*
|
|
19
|
+
* ```ts [data-first]
|
|
20
|
+
* import { Delta } from "@monstermann/delta";
|
|
21
|
+
*
|
|
22
|
+
* const a = Delta.insert([], "Hello");
|
|
23
|
+
* const b = Delta.insert([], "Hello world");
|
|
24
|
+
*
|
|
25
|
+
* Delta.diff(a, b);
|
|
26
|
+
* // [{ type: "retain", value: 5 },
|
|
27
|
+
* // { type: "insert", value: " world" }]
|
|
28
|
+
*
|
|
29
|
+
* const plain = Delta.insert([], "Hello");
|
|
30
|
+
* const bold = Delta.insert([], "Hello", { bold: true });
|
|
31
|
+
*
|
|
32
|
+
* Delta.diff(plain, bold);
|
|
33
|
+
* // [{ type: "retain", value: 5, attributes: { bold: true } }]
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* ```ts [data-last]
|
|
37
|
+
* import { Delta } from "@monstermann/delta";
|
|
38
|
+
*
|
|
39
|
+
* const a = Delta.insert([], "Hello");
|
|
40
|
+
* const b = Delta.insert([], "Hello world");
|
|
41
|
+
*
|
|
42
|
+
* pipe(a, Delta.diff(b));
|
|
43
|
+
* // [{ type: "retain", value: 5 },
|
|
44
|
+
* // { type: "insert", value: " world" }]
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* ## Cursor hint
|
|
48
|
+
*
|
|
49
|
+
* When text changes are ambiguous, the cursor position determines where the change is placed:
|
|
50
|
+
*
|
|
51
|
+
* ```ts
|
|
52
|
+
* import { Delta } from "@monstermann/delta";
|
|
53
|
+
*
|
|
54
|
+
* const a = Delta.insert([], "foo");
|
|
55
|
+
* const b = Delta.insert([], "foo bar foo");
|
|
56
|
+
*
|
|
57
|
+
* // cursor=3: user typed " bar foo" at the end
|
|
58
|
+
* Delta.diff(a, b, 3);
|
|
59
|
+
* // [{ type: "retain", value: 3 },
|
|
60
|
+
* // { type: "insert", value: " bar foo" }]
|
|
61
|
+
*
|
|
62
|
+
* // cursor=0: user typed "foo bar " at the beginning
|
|
63
|
+
* Delta.diff(a, b, 0);
|
|
64
|
+
* // [{ type: "insert", value: "foo bar " }]
|
|
65
|
+
* ```
|
|
66
|
+
*
|
|
67
|
+
*/
|
|
68
|
+
declare const diff: {
|
|
69
|
+
<T extends OpAttributes>(b: Delta<NoInfer<T>>, cursor?: number): (a: Delta<T>) => Delta<T>;
|
|
70
|
+
<T extends OpAttributes>(a: Delta<T>, b: Delta<NoInfer<T>>, cursor?: number): Delta<T>;
|
|
71
|
+
};
|
|
72
|
+
//#endregion
|
|
73
|
+
export { diff };
|