@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.
Files changed (56) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +695 -0
  3. package/dist/Delta/batch.d.mts +57 -0
  4. package/dist/Delta/batch.mjs +61 -0
  5. package/dist/Delta/chop.d.mts +56 -0
  6. package/dist/Delta/chop.mjs +60 -0
  7. package/dist/Delta/clean.d.mts +57 -0
  8. package/dist/Delta/clean.mjs +61 -0
  9. package/dist/Delta/compose.d.mts +58 -0
  10. package/dist/Delta/compose.mjs +100 -0
  11. package/dist/Delta/concat.d.mts +50 -0
  12. package/dist/Delta/concat.mjs +51 -0
  13. package/dist/Delta/diff.d.mts +73 -0
  14. package/dist/Delta/diff.mjs +124 -0
  15. package/dist/Delta/equals.d.mts +43 -0
  16. package/dist/Delta/equals.mjs +50 -0
  17. package/dist/Delta/index.d.mts +26 -0
  18. package/dist/Delta/index.mjs +37 -0
  19. package/dist/Delta/insert.d.mts +52 -0
  20. package/dist/Delta/insert.mjs +57 -0
  21. package/dist/Delta/invert.d.mts +54 -0
  22. package/dist/Delta/invert.mjs +77 -0
  23. package/dist/Delta/length.d.mts +51 -0
  24. package/dist/Delta/length.mjs +51 -0
  25. package/dist/Delta/push.d.mts +51 -0
  26. package/dist/Delta/push.mjs +87 -0
  27. package/dist/Delta/remove.d.mts +41 -0
  28. package/dist/Delta/remove.mjs +46 -0
  29. package/dist/Delta/retain.d.mts +70 -0
  30. package/dist/Delta/retain.mjs +76 -0
  31. package/dist/Delta/slice.d.mts +64 -0
  32. package/dist/Delta/slice.mjs +77 -0
  33. package/dist/Delta/transform.d.mts +63 -0
  34. package/dist/Delta/transform.mjs +91 -0
  35. package/dist/Op/index.d.mts +21 -0
  36. package/dist/OpAttributes/compose.d.mts +6 -0
  37. package/dist/OpAttributes/compose.mjs +25 -0
  38. package/dist/OpAttributes/diff.d.mts +6 -0
  39. package/dist/OpAttributes/diff.mjs +14 -0
  40. package/dist/OpAttributes/index.d.mts +15 -0
  41. package/dist/OpAttributes/invert.d.mts +6 -0
  42. package/dist/OpAttributes/invert.mjs +16 -0
  43. package/dist/OpAttributes/isEqual.d.mts +6 -0
  44. package/dist/OpAttributes/isEqual.mjs +16 -0
  45. package/dist/OpAttributes/transform.d.mts +6 -0
  46. package/dist/OpAttributes/transform.mjs +13 -0
  47. package/dist/OpIterator/create.mjs +11 -0
  48. package/dist/OpIterator/hasNext.mjs +9 -0
  49. package/dist/OpIterator/next.mjs +36 -0
  50. package/dist/OpIterator/peek.mjs +7 -0
  51. package/dist/OpIterator/peekLength.mjs +9 -0
  52. package/dist/OpIterator/peekType.mjs +7 -0
  53. package/dist/index.d.mts +2 -0
  54. package/dist/index.mjs +3 -0
  55. package/dist/internals/hasKeys.mjs +8 -0
  56. package/package.json +42 -0
@@ -0,0 +1,124 @@
1
+ import { chop } from "./chop.mjs";
2
+ import { push } from "./push.mjs";
3
+ import { create } from "../OpIterator/create.mjs";
4
+ import { peekLength } from "../OpIterator/peekLength.mjs";
5
+ import { next } from "../OpIterator/next.mjs";
6
+ import { remove } from "./remove.mjs";
7
+ import { retain } from "./retain.mjs";
8
+ import { diff as diff$1 } from "../OpAttributes/diff.mjs";
9
+ import { dfdlT } from "@monstermann/dfdl";
10
+ import { endMutations, markAsMutable, startMutations } from "@monstermann/remmi";
11
+ import fastDiff from "fast-diff";
12
+
13
+ //#region src/Delta/diff.ts
14
+ /**
15
+ * # diff
16
+ *
17
+ * ```ts
18
+ * function Delta.diff<T>(a: Delta<T>, b: Delta<T>, cursor?: number): Delta<T>
19
+ * ```
20
+ *
21
+ * Computes the difference between two document deltas, returning a delta that transforms `a` into `b`.
22
+ *
23
+ * 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.
24
+ *
25
+ * ## Example
26
+ *
27
+ * ```ts [data-first]
28
+ * import { Delta } from "@monstermann/delta";
29
+ *
30
+ * const a = Delta.insert([], "Hello");
31
+ * const b = Delta.insert([], "Hello world");
32
+ *
33
+ * Delta.diff(a, b);
34
+ * // [{ type: "retain", value: 5 },
35
+ * // { type: "insert", value: " world" }]
36
+ *
37
+ * const plain = Delta.insert([], "Hello");
38
+ * const bold = Delta.insert([], "Hello", { bold: true });
39
+ *
40
+ * Delta.diff(plain, bold);
41
+ * // [{ type: "retain", value: 5, attributes: { bold: true } }]
42
+ * ```
43
+ *
44
+ * ```ts [data-last]
45
+ * import { Delta } from "@monstermann/delta";
46
+ *
47
+ * const a = Delta.insert([], "Hello");
48
+ * const b = Delta.insert([], "Hello world");
49
+ *
50
+ * pipe(a, Delta.diff(b));
51
+ * // [{ type: "retain", value: 5 },
52
+ * // { type: "insert", value: " world" }]
53
+ * ```
54
+ *
55
+ * ## Cursor hint
56
+ *
57
+ * When text changes are ambiguous, the cursor position determines where the change is placed:
58
+ *
59
+ * ```ts
60
+ * import { Delta } from "@monstermann/delta";
61
+ *
62
+ * const a = Delta.insert([], "foo");
63
+ * const b = Delta.insert([], "foo bar foo");
64
+ *
65
+ * // cursor=3: user typed " bar foo" at the end
66
+ * Delta.diff(a, b, 3);
67
+ * // [{ type: "retain", value: 3 },
68
+ * // { type: "insert", value: " bar foo" }]
69
+ *
70
+ * // cursor=0: user typed "foo bar " at the beginning
71
+ * Delta.diff(a, b, 0);
72
+ * // [{ type: "insert", value: "foo bar " }]
73
+ * ```
74
+ *
75
+ */
76
+ const diff = dfdlT((a, b, cursor) => {
77
+ if (a === b) return [];
78
+ const aString = toText(a, "Delta.diff(a, b): a is not a document");
79
+ const bString = toText(b, "Delta.diff(a, b): b is not a document");
80
+ startMutations();
81
+ let ops = markAsMutable([]);
82
+ const diffResult = fastDiff(aString, bString, cursor, true);
83
+ const aIter = create(a);
84
+ const bIter = create(b);
85
+ for (const component of diffResult) {
86
+ const [type, text] = component;
87
+ let length = text.length;
88
+ while (length > 0) {
89
+ let opLength = 0;
90
+ if (type === fastDiff.INSERT) {
91
+ opLength = Math.min(peekLength(bIter), length);
92
+ ops = push(ops, next(bIter, opLength));
93
+ } else if (type === fastDiff.DELETE) {
94
+ opLength = Math.min(length, peekLength(aIter));
95
+ next(aIter, opLength);
96
+ ops = remove(ops, opLength);
97
+ } else if (type === fastDiff.EQUAL) {
98
+ opLength = Math.min(peekLength(aIter), peekLength(bIter), length);
99
+ const aOp = next(aIter, opLength);
100
+ const bOp = next(bIter, opLength);
101
+ if (aOp.type === "insert" && bOp.type === "insert" && aOp.value === bOp.value) ops = retain(ops, opLength, diff$1(aOp.attributes, bOp.attributes));
102
+ else {
103
+ ops = push(ops, bOp);
104
+ ops = remove(ops, opLength);
105
+ }
106
+ }
107
+ length -= opLength;
108
+ }
109
+ }
110
+ ops = chop(ops);
111
+ endMutations();
112
+ return ops;
113
+ }, (args) => {
114
+ return Array.isArray(args[0]) && Array.isArray(args[1]);
115
+ });
116
+ function toText(ops, errMsg) {
117
+ return ops.map((op) => {
118
+ if (op.type === "insert") return op.value;
119
+ throw new Error(errMsg);
120
+ }).join("");
121
+ }
122
+
123
+ //#endregion
124
+ export { diff };
@@ -0,0 +1,43 @@
1
+ import { OpAttributes } from "../OpAttributes/index.mjs";
2
+ import { Delta } from "./index.mjs";
3
+
4
+ //#region src/Delta/equals.d.ts
5
+
6
+ /**
7
+ * # equals
8
+ *
9
+ * ```ts
10
+ * function Delta.equals<T>(a: Delta<T>, b: Delta<T>): boolean
11
+ * ```
12
+ *
13
+ * Checks if two deltas are equal by comparing their operations and attributes.
14
+ *
15
+ * ## Example
16
+ *
17
+ * ```ts [data-first]
18
+ * import { Delta } from "@monstermann/delta";
19
+ *
20
+ * const a = Delta.insert([], "Hello", { bold: true });
21
+ * const b = Delta.insert([], "Hello", { bold: true });
22
+ * const c = Delta.insert([], "Hello", { italic: true });
23
+ *
24
+ * Delta.equals(a, b); // true
25
+ * Delta.equals(a, c); // false
26
+ * ```
27
+ *
28
+ * ```ts [data-last]
29
+ * import { Delta } from "@monstermann/delta";
30
+ *
31
+ * const a = Delta.insert([], "Hello", { bold: true });
32
+ * const b = Delta.insert([], "Hello", { bold: true });
33
+ *
34
+ * pipe(a, Delta.equals(b)); // true
35
+ * ```
36
+ *
37
+ */
38
+ declare const equals: {
39
+ <T extends OpAttributes>(b: Delta<NoInfer<T>>): (a: Delta<T>) => boolean;
40
+ <T extends OpAttributes>(a: Delta<T>, b: Delta<NoInfer<T>>): boolean;
41
+ };
42
+ //#endregion
43
+ export { equals };
@@ -0,0 +1,50 @@
1
+ import { isEqual } from "../OpAttributes/isEqual.mjs";
2
+ import { dfdlT } from "@monstermann/dfdl";
3
+
4
+ //#region src/Delta/equals.ts
5
+ /**
6
+ * # equals
7
+ *
8
+ * ```ts
9
+ * function Delta.equals<T>(a: Delta<T>, b: Delta<T>): boolean
10
+ * ```
11
+ *
12
+ * Checks if two deltas are equal by comparing their operations and attributes.
13
+ *
14
+ * ## Example
15
+ *
16
+ * ```ts [data-first]
17
+ * import { Delta } from "@monstermann/delta";
18
+ *
19
+ * const a = Delta.insert([], "Hello", { bold: true });
20
+ * const b = Delta.insert([], "Hello", { bold: true });
21
+ * const c = Delta.insert([], "Hello", { italic: true });
22
+ *
23
+ * Delta.equals(a, b); // true
24
+ * Delta.equals(a, c); // false
25
+ * ```
26
+ *
27
+ * ```ts [data-last]
28
+ * import { Delta } from "@monstermann/delta";
29
+ *
30
+ * const a = Delta.insert([], "Hello", { bold: true });
31
+ * const b = Delta.insert([], "Hello", { bold: true });
32
+ *
33
+ * pipe(a, Delta.equals(b)); // true
34
+ * ```
35
+ *
36
+ */
37
+ const equals = dfdlT((a, b) => {
38
+ if (a.length !== b.length) return false;
39
+ for (let i = 0; i < a.length; i++) {
40
+ const aOp = a[i];
41
+ const bOp = b[i];
42
+ if (aOp.type !== bOp.type) return false;
43
+ if (aOp.value !== bOp.value) return false;
44
+ if (!isEqual(aOp.attributes, bOp.attributes)) return false;
45
+ }
46
+ return true;
47
+ }, 2);
48
+
49
+ //#endregion
50
+ export { equals };
@@ -0,0 +1,26 @@
1
+ import { OpAttributes } from "../OpAttributes/index.mjs";
2
+ import { batch } from "./batch.mjs";
3
+ import { chop } from "./chop.mjs";
4
+ import { clean } from "./clean.mjs";
5
+ import { compose } from "./compose.mjs";
6
+ import { concat } from "./concat.mjs";
7
+ import { diff } from "./diff.mjs";
8
+ import { equals } from "./equals.mjs";
9
+ import { insert } from "./insert.mjs";
10
+ import { invert } from "./invert.mjs";
11
+ import { length } from "./length.mjs";
12
+ import { Op } from "../Op/index.mjs";
13
+ import { push } from "./push.mjs";
14
+ import { remove } from "./remove.mjs";
15
+ import { retain } from "./retain.mjs";
16
+ import { slice } from "./slice.mjs";
17
+ import { transform } from "./transform.mjs";
18
+
19
+ //#region src/Delta/index.d.ts
20
+
21
+ type Delta<T extends OpAttributes = OpAttributes> = Op<T>[];
22
+ declare namespace Delta {
23
+ export { batch, chop, clean, compose, concat, diff, equals, insert, invert, length, push, remove, retain, slice, transform };
24
+ }
25
+ //#endregion
26
+ export { Delta };
@@ -0,0 +1,37 @@
1
+ import { batch } from "./batch.mjs";
2
+ import { chop } from "./chop.mjs";
3
+ import { push } from "./push.mjs";
4
+ import { clean } from "./clean.mjs";
5
+ import { compose } from "./compose.mjs";
6
+ import { concat } from "./concat.mjs";
7
+ import { remove } from "./remove.mjs";
8
+ import { retain } from "./retain.mjs";
9
+ import { diff } from "./diff.mjs";
10
+ import { equals } from "./equals.mjs";
11
+ import { insert } from "./insert.mjs";
12
+ import { slice } from "./slice.mjs";
13
+ import { invert } from "./invert.mjs";
14
+ import { length } from "./length.mjs";
15
+ import { transform } from "./transform.mjs";
16
+
17
+ //#region src/Delta/index.js
18
+ const Delta = {
19
+ batch,
20
+ chop,
21
+ clean,
22
+ compose,
23
+ concat,
24
+ diff,
25
+ equals,
26
+ insert,
27
+ invert,
28
+ length,
29
+ push,
30
+ remove,
31
+ retain,
32
+ slice,
33
+ transform
34
+ };
35
+
36
+ //#endregion
37
+ export { Delta };
@@ -0,0 +1,52 @@
1
+ import { NullableOpAttributes, OpAttributes } from "../OpAttributes/index.mjs";
2
+ import { Delta } from "./index.mjs";
3
+
4
+ //#region src/Delta/insert.d.ts
5
+
6
+ /**
7
+ * # insert
8
+ *
9
+ * ```ts
10
+ * function Delta.insert<T>(
11
+ * ops: Delta<T>,
12
+ * content: string,
13
+ * attributes?: T | null,
14
+ * ): Delta<T>
15
+ * ```
16
+ *
17
+ * Adds an insert operation to the delta.
18
+ *
19
+ * ## Example
20
+ *
21
+ * ```ts [data-first]
22
+ * import { Delta } from "@monstermann/delta";
23
+ *
24
+ * Delta.insert([], "Hello");
25
+ * // [{ type: "insert", value: "Hello" }]
26
+ *
27
+ * Delta.insert([], "Hello", { bold: true });
28
+ * // [{ type: "insert", value: "Hello", attributes: { bold: true } }]
29
+ * ```
30
+ *
31
+ * ```ts [data-last]
32
+ * import { Delta } from "@monstermann/delta";
33
+ *
34
+ * pipe([], Delta.insert("Hello"));
35
+ * // [{ type: "insert", value: "Hello" }]
36
+ *
37
+ * pipe(
38
+ * [],
39
+ * Delta.insert("Hello", { bold: true }),
40
+ * Delta.insert(" world", { italic: true }),
41
+ * );
42
+ * // [{ type: "insert", value: "Hello", attributes: { bold: true } },
43
+ * // { type: "insert", value: " world", attributes: { italic: true } }]
44
+ * ```
45
+ *
46
+ */
47
+ declare const insert: {
48
+ <T extends OpAttributes>(content: string, attributes?: NullableOpAttributes<NoInfer<T>> | null): (ops: Delta<T>) => Delta<T>;
49
+ <T extends OpAttributes>(ops: Delta<T>, content: string, attributes?: NullableOpAttributes<NoInfer<T>> | null): Delta<T>;
50
+ };
51
+ //#endregion
52
+ export { insert };
@@ -0,0 +1,57 @@
1
+ import { push } from "./push.mjs";
2
+ import { hasKeys } from "../internals/hasKeys.mjs";
3
+ import { dfdlT } from "@monstermann/dfdl";
4
+
5
+ //#region src/Delta/insert.ts
6
+ /**
7
+ * # insert
8
+ *
9
+ * ```ts
10
+ * function Delta.insert<T>(
11
+ * ops: Delta<T>,
12
+ * content: string,
13
+ * attributes?: T | null,
14
+ * ): Delta<T>
15
+ * ```
16
+ *
17
+ * Adds an insert operation to the delta.
18
+ *
19
+ * ## Example
20
+ *
21
+ * ```ts [data-first]
22
+ * import { Delta } from "@monstermann/delta";
23
+ *
24
+ * Delta.insert([], "Hello");
25
+ * // [{ type: "insert", value: "Hello" }]
26
+ *
27
+ * Delta.insert([], "Hello", { bold: true });
28
+ * // [{ type: "insert", value: "Hello", attributes: { bold: true } }]
29
+ * ```
30
+ *
31
+ * ```ts [data-last]
32
+ * import { Delta } from "@monstermann/delta";
33
+ *
34
+ * pipe([], Delta.insert("Hello"));
35
+ * // [{ type: "insert", value: "Hello" }]
36
+ *
37
+ * pipe(
38
+ * [],
39
+ * Delta.insert("Hello", { bold: true }),
40
+ * Delta.insert(" world", { italic: true }),
41
+ * );
42
+ * // [{ type: "insert", value: "Hello", attributes: { bold: true } },
43
+ * // { type: "insert", value: " world", attributes: { italic: true } }]
44
+ * ```
45
+ *
46
+ */
47
+ const insert = dfdlT((ops, content, attributes) => {
48
+ if (!content.length) return ops;
49
+ return push(ops, {
50
+ attributes: attributes && hasKeys(attributes) ? attributes : void 0,
51
+ type: "insert",
52
+ value: content
53
+ });
54
+ }, (args) => typeof args[0] !== "string");
55
+
56
+ //#endregion
57
+ export { insert };
@@ -0,0 +1,54 @@
1
+ import { OpAttributes } from "../OpAttributes/index.mjs";
2
+ import { Delta } from "./index.mjs";
3
+
4
+ //#region src/Delta/invert.d.ts
5
+
6
+ /**
7
+ * # invert
8
+ *
9
+ * ```ts
10
+ * function Delta.invert<T>(a: Delta<T>, b: Delta<T>): Delta<T>
11
+ * ```
12
+ *
13
+ * Returns the inverse of a delta against a base document. Applying the inverted delta undoes the original change.
14
+ *
15
+ * ## Example
16
+ *
17
+ * <!-- prettier-ignore -->
18
+ * ```ts [data-first]
19
+ * import { Delta } from "@monstermann/delta";
20
+ *
21
+ * const base = Delta.insert([], "Hello");
22
+ * const change = Delta.retain([], 5, { bold: true });
23
+ *
24
+ * Delta.invert(change, base);
25
+ * // [{ type: "retain", value: 5, attributes: { bold: null } }]
26
+ *
27
+ * const insert = pipe(
28
+ * [],
29
+ * Delta.retain(5),
30
+ * Delta.insert(" world")
31
+ * );
32
+ *
33
+ * Delta.invert(insert, base);
34
+ * // [{ type: "retain", value: 5 },
35
+ * // { type: "remove", value: 6 }]
36
+ * ```
37
+ *
38
+ * ```ts [data-last]
39
+ * import { Delta } from "@monstermann/delta";
40
+ *
41
+ * const base = Delta.insert([], "Hello");
42
+ * const change = Delta.retain([], 5, { bold: true });
43
+ *
44
+ * pipe(change, Delta.invert(base));
45
+ * // [{ type: "retain", value: 5, attributes: { bold: null } }]
46
+ * ```
47
+ *
48
+ */
49
+ declare const invert: {
50
+ <T extends OpAttributes>(b: Delta<NoInfer<T>>): (a: Delta<T>) => Delta<T>;
51
+ <T extends OpAttributes>(a: Delta<T>, b: Delta<NoInfer<T>>): Delta<T>;
52
+ };
53
+ //#endregion
54
+ export { invert };
@@ -0,0 +1,77 @@
1
+ import { chop } from "./chop.mjs";
2
+ import { push } from "./push.mjs";
3
+ import { remove } from "./remove.mjs";
4
+ import { retain } from "./retain.mjs";
5
+ import { slice } from "./slice.mjs";
6
+ import { invert as invert$1 } from "../OpAttributes/invert.mjs";
7
+ import { dfdlT } from "@monstermann/dfdl";
8
+ import { endMutations, markAsMutable, startMutations } from "@monstermann/remmi";
9
+
10
+ //#region src/Delta/invert.ts
11
+ /**
12
+ * # invert
13
+ *
14
+ * ```ts
15
+ * function Delta.invert<T>(a: Delta<T>, b: Delta<T>): Delta<T>
16
+ * ```
17
+ *
18
+ * Returns the inverse of a delta against a base document. Applying the inverted delta undoes the original change.
19
+ *
20
+ * ## Example
21
+ *
22
+ * <!-- prettier-ignore -->
23
+ * ```ts [data-first]
24
+ * import { Delta } from "@monstermann/delta";
25
+ *
26
+ * const base = Delta.insert([], "Hello");
27
+ * const change = Delta.retain([], 5, { bold: true });
28
+ *
29
+ * Delta.invert(change, base);
30
+ * // [{ type: "retain", value: 5, attributes: { bold: null } }]
31
+ *
32
+ * const insert = pipe(
33
+ * [],
34
+ * Delta.retain(5),
35
+ * Delta.insert(" world")
36
+ * );
37
+ *
38
+ * Delta.invert(insert, base);
39
+ * // [{ type: "retain", value: 5 },
40
+ * // { type: "remove", value: 6 }]
41
+ * ```
42
+ *
43
+ * ```ts [data-last]
44
+ * import { Delta } from "@monstermann/delta";
45
+ *
46
+ * const base = Delta.insert([], "Hello");
47
+ * const change = Delta.retain([], 5, { bold: true });
48
+ *
49
+ * pipe(change, Delta.invert(base));
50
+ * // [{ type: "retain", value: 5, attributes: { bold: null } }]
51
+ * ```
52
+ *
53
+ */
54
+ const invert = dfdlT((a, b) => {
55
+ startMutations();
56
+ let newOps = markAsMutable([]);
57
+ let baseIndex = 0;
58
+ for (const aOp of a) if (aOp.type === "insert") newOps = remove(newOps, aOp.value.length);
59
+ else if (aOp.type === "retain" && aOp.attributes == null) {
60
+ newOps = retain(newOps, aOp.value);
61
+ baseIndex += aOp.value;
62
+ } else {
63
+ const length = aOp.value;
64
+ for (const bOp of slice(b, baseIndex, baseIndex + length)) if (aOp.type === "remove") newOps = push(newOps, bOp);
65
+ else if (aOp.attributes) {
66
+ const bOpLength = bOp.type === "insert" ? bOp.value.length : bOp.value;
67
+ newOps = retain(newOps, bOpLength, invert$1(aOp.attributes, bOp.attributes));
68
+ }
69
+ baseIndex += length;
70
+ }
71
+ newOps = chop(newOps);
72
+ endMutations();
73
+ return newOps;
74
+ }, 2);
75
+
76
+ //#endregion
77
+ export { invert };
@@ -0,0 +1,51 @@
1
+ import { OpAttributes } from "../OpAttributes/index.mjs";
2
+ import { Delta } from "./index.mjs";
3
+
4
+ //#region src/Delta/length.d.ts
5
+
6
+ /**
7
+ * # length
8
+ *
9
+ * ```ts
10
+ * function Delta.length<T>(ops: Delta<T>): number
11
+ * ```
12
+ *
13
+ * Returns the total length of the delta (sum of all operation lengths).
14
+ *
15
+ * ## Example
16
+ *
17
+ * <!-- prettier-ignore -->
18
+ * ```ts [data-first]
19
+ * import { Delta } from "@monstermann/delta";
20
+ *
21
+ * Delta.length(Delta.insert([], "Hello")); // 5
22
+ *
23
+ * Delta.length(pipe(
24
+ * [],
25
+ * Delta.insert("Hello"),
26
+ * Delta.retain(3),
27
+ * Delta.remove(2)
28
+ * )); // 10
29
+ * ```
30
+ *
31
+ * ```ts [data-last]
32
+ * import { Delta } from "@monstermann/delta";
33
+ *
34
+ * pipe([], Delta.insert("Hello"), Delta.length()); // 5
35
+ *
36
+ * pipe(
37
+ * [],
38
+ * Delta.insert("Hello"),
39
+ * Delta.retain(3),
40
+ * Delta.remove(2),
41
+ * Delta.length(),
42
+ * ); // 10
43
+ * ```
44
+ *
45
+ */
46
+ declare const length: {
47
+ (): <T extends OpAttributes>(ops: Delta<T>) => number;
48
+ <T extends OpAttributes>(ops: Delta<T>): number;
49
+ };
50
+ //#endregion
51
+ export { length };
@@ -0,0 +1,51 @@
1
+ import { dfdlT } from "@monstermann/dfdl";
2
+
3
+ //#region src/Delta/length.ts
4
+ /**
5
+ * # length
6
+ *
7
+ * ```ts
8
+ * function Delta.length<T>(ops: Delta<T>): number
9
+ * ```
10
+ *
11
+ * Returns the total length of the delta (sum of all operation lengths).
12
+ *
13
+ * ## Example
14
+ *
15
+ * <!-- prettier-ignore -->
16
+ * ```ts [data-first]
17
+ * import { Delta } from "@monstermann/delta";
18
+ *
19
+ * Delta.length(Delta.insert([], "Hello")); // 5
20
+ *
21
+ * Delta.length(pipe(
22
+ * [],
23
+ * Delta.insert("Hello"),
24
+ * Delta.retain(3),
25
+ * Delta.remove(2)
26
+ * )); // 10
27
+ * ```
28
+ *
29
+ * ```ts [data-last]
30
+ * import { Delta } from "@monstermann/delta";
31
+ *
32
+ * pipe([], Delta.insert("Hello"), Delta.length()); // 5
33
+ *
34
+ * pipe(
35
+ * [],
36
+ * Delta.insert("Hello"),
37
+ * Delta.retain(3),
38
+ * Delta.remove(2),
39
+ * Delta.length(),
40
+ * ); // 10
41
+ * ```
42
+ *
43
+ */
44
+ const length = dfdlT((ops) => {
45
+ return ops.reduce((acc, op) => {
46
+ return acc + (op.type === "insert" ? op.value.length : op.value);
47
+ }, 0);
48
+ }, 1);
49
+
50
+ //#endregion
51
+ export { length };
@@ -0,0 +1,51 @@
1
+ import { OpAttributes } from "../OpAttributes/index.mjs";
2
+ import { Op } from "../Op/index.mjs";
3
+ import { Delta } from "./index.mjs";
4
+
5
+ //#region src/Delta/push.d.ts
6
+
7
+ /**
8
+ * # push
9
+ *
10
+ * ```ts
11
+ * function Delta.push<T>(ops: Delta<T>, op: Op<T>): Delta<T>
12
+ * ```
13
+ *
14
+ * Pushes an operation onto the delta, merging with the previous operation if possible.
15
+ *
16
+ * ## Example
17
+ *
18
+ * ```ts [data-first]
19
+ * import { Delta } from "@monstermann/delta";
20
+ *
21
+ * Delta.push([], { type: "insert", value: "Hello" });
22
+ * // [{ type: "insert", value: "Hello" }]
23
+ *
24
+ * Delta.push(Delta.push([], { type: "insert", value: "Hello" }), {
25
+ * type: "insert",
26
+ * value: " world",
27
+ * });
28
+ * // [{ type: "insert", value: "Hello world" }]
29
+ * ```
30
+ *
31
+ * ```ts [data-last]
32
+ * import { Delta } from "@monstermann/delta";
33
+ *
34
+ * pipe([], Delta.push({ type: "insert", value: "Hello" }));
35
+ * // [{ type: "insert", value: "Hello" }]
36
+ *
37
+ * pipe(
38
+ * [],
39
+ * Delta.push({ type: "insert", value: "Hello" }),
40
+ * Delta.push({ type: "insert", value: " world" }),
41
+ * );
42
+ * // [{ type: "insert", value: "Hello world" }]
43
+ * ```
44
+ *
45
+ */
46
+ declare const push: {
47
+ <T extends OpAttributes>(op: Op<NoInfer<T>>): (ops: Delta<T>) => Delta<T>;
48
+ <T extends OpAttributes>(ops: Delta<T>, op: Op<NoInfer<T>>): Delta<T>;
49
+ };
50
+ //#endregion
51
+ export { push };