@fluidframework/ai-collab 2.10.0-306579

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 (168) hide show
  1. package/.eslintrc.cjs +26 -0
  2. package/CHANGELOG.md +9 -0
  3. package/LICENSE +21 -0
  4. package/README.md +280 -0
  5. package/alpha.d.ts +11 -0
  6. package/api-extractor/api-extractor-lint-alpha.cjs.json +5 -0
  7. package/api-extractor/api-extractor-lint-alpha.esm.json +5 -0
  8. package/api-extractor/api-extractor-lint-bundle.json +5 -0
  9. package/api-extractor/api-extractor-lint-index.cjs.json +5 -0
  10. package/api-extractor/api-extractor-lint-index.esm.json +5 -0
  11. package/api-extractor/api-extractor-lint-public.cjs.json +5 -0
  12. package/api-extractor/api-extractor-lint-public.esm.json +5 -0
  13. package/api-extractor-lint.json +4 -0
  14. package/api-extractor.json +4 -0
  15. package/api-report/ai-collab.alpha.api.md +164 -0
  16. package/api-report/ai-collab.beta.api.md +7 -0
  17. package/api-report/ai-collab.public.api.md +7 -0
  18. package/biome.jsonc +4 -0
  19. package/dist/aiCollab.d.ts +65 -0
  20. package/dist/aiCollab.d.ts.map +1 -0
  21. package/dist/aiCollab.js +81 -0
  22. package/dist/aiCollab.js.map +1 -0
  23. package/dist/aiCollabApi.d.ts +173 -0
  24. package/dist/aiCollabApi.d.ts.map +1 -0
  25. package/dist/aiCollabApi.js +7 -0
  26. package/dist/aiCollabApi.js.map +1 -0
  27. package/dist/alpha.d.ts +41 -0
  28. package/dist/explicit-strategy/agentEditReducer.d.ts +12 -0
  29. package/dist/explicit-strategy/agentEditReducer.d.ts.map +1 -0
  30. package/dist/explicit-strategy/agentEditReducer.js +394 -0
  31. package/dist/explicit-strategy/agentEditReducer.js.map +1 -0
  32. package/dist/explicit-strategy/agentEditTypes.d.ts +158 -0
  33. package/dist/explicit-strategy/agentEditTypes.d.ts.map +1 -0
  34. package/dist/explicit-strategy/agentEditTypes.js +50 -0
  35. package/dist/explicit-strategy/agentEditTypes.js.map +1 -0
  36. package/dist/explicit-strategy/idGenerator.d.ts +22 -0
  37. package/dist/explicit-strategy/idGenerator.d.ts.map +1 -0
  38. package/dist/explicit-strategy/idGenerator.js +74 -0
  39. package/dist/explicit-strategy/idGenerator.js.map +1 -0
  40. package/dist/explicit-strategy/index.d.ts +51 -0
  41. package/dist/explicit-strategy/index.d.ts.map +1 -0
  42. package/dist/explicit-strategy/index.js +223 -0
  43. package/dist/explicit-strategy/index.js.map +1 -0
  44. package/dist/explicit-strategy/jsonTypes.d.ts +23 -0
  45. package/dist/explicit-strategy/jsonTypes.d.ts.map +1 -0
  46. package/dist/explicit-strategy/jsonTypes.js +7 -0
  47. package/dist/explicit-strategy/jsonTypes.js.map +1 -0
  48. package/dist/explicit-strategy/promptGeneration.d.ts +51 -0
  49. package/dist/explicit-strategy/promptGeneration.d.ts.map +1 -0
  50. package/dist/explicit-strategy/promptGeneration.js +218 -0
  51. package/dist/explicit-strategy/promptGeneration.js.map +1 -0
  52. package/dist/explicit-strategy/typeGeneration.d.ts +15 -0
  53. package/dist/explicit-strategy/typeGeneration.d.ts.map +1 -0
  54. package/dist/explicit-strategy/typeGeneration.js +264 -0
  55. package/dist/explicit-strategy/typeGeneration.js.map +1 -0
  56. package/dist/explicit-strategy/utils.d.ts +37 -0
  57. package/dist/explicit-strategy/utils.d.ts.map +1 -0
  58. package/dist/explicit-strategy/utils.js +47 -0
  59. package/dist/explicit-strategy/utils.js.map +1 -0
  60. package/dist/implicit-strategy/index.d.ts +8 -0
  61. package/dist/implicit-strategy/index.d.ts.map +1 -0
  62. package/dist/implicit-strategy/index.js +18 -0
  63. package/dist/implicit-strategy/index.js.map +1 -0
  64. package/dist/implicit-strategy/sharedTreeBranchManager.d.ts +63 -0
  65. package/dist/implicit-strategy/sharedTreeBranchManager.d.ts.map +1 -0
  66. package/dist/implicit-strategy/sharedTreeBranchManager.js +212 -0
  67. package/dist/implicit-strategy/sharedTreeBranchManager.js.map +1 -0
  68. package/dist/implicit-strategy/sharedTreeDiff.d.ts +102 -0
  69. package/dist/implicit-strategy/sharedTreeDiff.d.ts.map +1 -0
  70. package/dist/implicit-strategy/sharedTreeDiff.js +522 -0
  71. package/dist/implicit-strategy/sharedTreeDiff.js.map +1 -0
  72. package/dist/implicit-strategy/utils.d.ts +21 -0
  73. package/dist/implicit-strategy/utils.d.ts.map +1 -0
  74. package/dist/implicit-strategy/utils.js +49 -0
  75. package/dist/implicit-strategy/utils.js.map +1 -0
  76. package/dist/index.d.ts +16 -0
  77. package/dist/index.d.ts.map +1 -0
  78. package/dist/index.js +24 -0
  79. package/dist/index.js.map +1 -0
  80. package/dist/package.json +3 -0
  81. package/dist/public.d.ts +19 -0
  82. package/eslintrc.cjs +11 -0
  83. package/internal.d.ts +11 -0
  84. package/lib/aiCollab.d.ts +65 -0
  85. package/lib/aiCollab.d.ts.map +1 -0
  86. package/lib/aiCollab.js +77 -0
  87. package/lib/aiCollab.js.map +1 -0
  88. package/lib/aiCollabApi.d.ts +173 -0
  89. package/lib/aiCollabApi.d.ts.map +1 -0
  90. package/lib/aiCollabApi.js +6 -0
  91. package/lib/aiCollabApi.js.map +1 -0
  92. package/lib/alpha.d.ts +41 -0
  93. package/lib/explicit-strategy/agentEditReducer.d.ts +12 -0
  94. package/lib/explicit-strategy/agentEditReducer.d.ts.map +1 -0
  95. package/lib/explicit-strategy/agentEditReducer.js +390 -0
  96. package/lib/explicit-strategy/agentEditReducer.js.map +1 -0
  97. package/lib/explicit-strategy/agentEditTypes.d.ts +158 -0
  98. package/lib/explicit-strategy/agentEditTypes.d.ts.map +1 -0
  99. package/lib/explicit-strategy/agentEditTypes.js +47 -0
  100. package/lib/explicit-strategy/agentEditTypes.js.map +1 -0
  101. package/lib/explicit-strategy/idGenerator.d.ts +22 -0
  102. package/lib/explicit-strategy/idGenerator.d.ts.map +1 -0
  103. package/lib/explicit-strategy/idGenerator.js +70 -0
  104. package/lib/explicit-strategy/idGenerator.js.map +1 -0
  105. package/lib/explicit-strategy/index.d.ts +51 -0
  106. package/lib/explicit-strategy/index.d.ts.map +1 -0
  107. package/lib/explicit-strategy/index.js +219 -0
  108. package/lib/explicit-strategy/index.js.map +1 -0
  109. package/lib/explicit-strategy/jsonTypes.d.ts +23 -0
  110. package/lib/explicit-strategy/jsonTypes.d.ts.map +1 -0
  111. package/lib/explicit-strategy/jsonTypes.js +6 -0
  112. package/lib/explicit-strategy/jsonTypes.js.map +1 -0
  113. package/lib/explicit-strategy/promptGeneration.d.ts +51 -0
  114. package/lib/explicit-strategy/promptGeneration.d.ts.map +1 -0
  115. package/lib/explicit-strategy/promptGeneration.js +208 -0
  116. package/lib/explicit-strategy/promptGeneration.js.map +1 -0
  117. package/lib/explicit-strategy/typeGeneration.d.ts +15 -0
  118. package/lib/explicit-strategy/typeGeneration.d.ts.map +1 -0
  119. package/lib/explicit-strategy/typeGeneration.js +260 -0
  120. package/lib/explicit-strategy/typeGeneration.js.map +1 -0
  121. package/lib/explicit-strategy/utils.d.ts +37 -0
  122. package/lib/explicit-strategy/utils.d.ts.map +1 -0
  123. package/lib/explicit-strategy/utils.js +41 -0
  124. package/lib/explicit-strategy/utils.js.map +1 -0
  125. package/lib/implicit-strategy/index.d.ts +8 -0
  126. package/lib/implicit-strategy/index.d.ts.map +1 -0
  127. package/lib/implicit-strategy/index.js +8 -0
  128. package/lib/implicit-strategy/index.js.map +1 -0
  129. package/lib/implicit-strategy/sharedTreeBranchManager.d.ts +63 -0
  130. package/lib/implicit-strategy/sharedTreeBranchManager.d.ts.map +1 -0
  131. package/lib/implicit-strategy/sharedTreeBranchManager.js +213 -0
  132. package/lib/implicit-strategy/sharedTreeBranchManager.js.map +1 -0
  133. package/lib/implicit-strategy/sharedTreeDiff.d.ts +102 -0
  134. package/lib/implicit-strategy/sharedTreeDiff.d.ts.map +1 -0
  135. package/lib/implicit-strategy/sharedTreeDiff.js +515 -0
  136. package/lib/implicit-strategy/sharedTreeDiff.js.map +1 -0
  137. package/lib/implicit-strategy/utils.d.ts +21 -0
  138. package/lib/implicit-strategy/utils.d.ts.map +1 -0
  139. package/lib/implicit-strategy/utils.js +43 -0
  140. package/lib/implicit-strategy/utils.js.map +1 -0
  141. package/lib/index.d.ts +16 -0
  142. package/lib/index.d.ts.map +1 -0
  143. package/lib/index.js +15 -0
  144. package/lib/index.js.map +1 -0
  145. package/lib/public.d.ts +19 -0
  146. package/lib/tsdoc-metadata.json +11 -0
  147. package/mocharc.cjs +14 -0
  148. package/package.json +165 -0
  149. package/prettier.config.cjs +8 -0
  150. package/src/aiCollab.ts +86 -0
  151. package/src/aiCollabApi.ts +184 -0
  152. package/src/explicit-strategy/agentEditReducer.ts +498 -0
  153. package/src/explicit-strategy/agentEditTypes.ts +177 -0
  154. package/src/explicit-strategy/idGenerator.ts +90 -0
  155. package/src/explicit-strategy/index.ts +364 -0
  156. package/src/explicit-strategy/jsonTypes.ts +27 -0
  157. package/src/explicit-strategy/promptGeneration.ts +294 -0
  158. package/src/explicit-strategy/typeGeneration.ts +374 -0
  159. package/src/explicit-strategy/utils.ts +60 -0
  160. package/src/implicit-strategy/README.md +4 -0
  161. package/src/implicit-strategy/index.ts +21 -0
  162. package/src/implicit-strategy/sharedTreeBranchManager.ts +294 -0
  163. package/src/implicit-strategy/sharedTreeDiff.ts +735 -0
  164. package/src/implicit-strategy/utils.ts +54 -0
  165. package/src/index.ts +39 -0
  166. package/tsconfig.cjs.json +7 -0
  167. package/tsconfig.json +12 -0
  168. package/tsdoc.json +4 -0
@@ -0,0 +1,60 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ /**
7
+ * Subset of Map interface.
8
+ *
9
+ * @remarks originally from tree/src/util/utils.ts
10
+ */
11
+ export interface MapGetSet<K, V> {
12
+ get(key: K): V | undefined;
13
+ set(key: K, value: V): void;
14
+ }
15
+
16
+ /**
17
+ * TBD
18
+ */
19
+ export function fail(message: string): never {
20
+ throw new Error(message);
21
+ }
22
+
23
+ /**
24
+ * Map one iterable to another by transforming each element one at a time
25
+ * @param iterable - the iterable to transform
26
+ * @param map - the transformation function to run on each element of the iterable
27
+ * @returns a new iterable of elements which have been transformed by the `map` function
28
+ *
29
+ * @remarks originally from tree/src/util/utils.ts
30
+ */
31
+ export function* mapIterable<T, U>(
32
+ iterable: Iterable<T>,
33
+ map: (t: T) => U,
34
+ ): IterableIterator<U> {
35
+ for (const t of iterable) {
36
+ yield map(t);
37
+ }
38
+ }
39
+
40
+ /**
41
+ * Retrieve a value from a map with the given key, or create a new entry if the key is not in the map.
42
+ * @param map - The map to query/update
43
+ * @param key - The key to lookup in the map
44
+ * @param defaultValue - a function which returns a default value. This is called and used to set an initial value for the given key in the map if none exists
45
+ * @returns either the existing value for the given key, or the newly-created value (the result of `defaultValue`)
46
+ *
47
+ * @remarks originally from tree/src/util/utils.ts
48
+ */
49
+ export function getOrCreate<K, V>(
50
+ map: MapGetSet<K, V>,
51
+ key: K,
52
+ defaultValue: (key: K) => V,
53
+ ): V {
54
+ let value = map.get(key);
55
+ if (value === undefined) {
56
+ value = defaultValue(key);
57
+ map.set(key, value);
58
+ }
59
+ return value;
60
+ }
@@ -0,0 +1,4 @@
1
+ # Shared Tree Object Diff
2
+
3
+ Shared Tree Object Diff is a fork of https://www.npmjs.com/package/microdiff with additional support for an object ID strategy that
4
+ can support moving objects between indexes within an array and Shared Tree Object, Array & Map nodes.
@@ -0,0 +1,21 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ export {
7
+ type DifferenceCreate,
8
+ type DifferenceChange,
9
+ type DifferenceMove,
10
+ type DifferenceRemove,
11
+ type Difference,
12
+ type ObjectPath,
13
+ type Options,
14
+ sharedTreeDiff,
15
+ createMergableIdDiffSeries,
16
+ createMergableDiffSeries,
17
+ } from "./sharedTreeDiff.js";
18
+
19
+ export { SharedTreeBranchManager } from "./sharedTreeBranchManager.js";
20
+
21
+ export { sharedTreeTraverse, isTreeArrayNode, isTreeMapNode } from "./utils.js";
@@ -0,0 +1,294 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import type {
7
+ ImplicitFieldSchema,
8
+ TreeArrayNode,
9
+ TreeMapNode,
10
+ TreeViewConfiguration,
11
+ } from "@fluidframework/tree";
12
+ import {
13
+ // TODO: Migrate to newer branching API (`TreeContext`)
14
+ // eslint-disable-next-line import/no-deprecated
15
+ getBranch,
16
+ type BranchableTree,
17
+ type TreeBranchFork,
18
+ type TreeViewAlpha,
19
+ // eslint-disable-next-line import/no-internal-modules -- This package depends on the branching APIs in Tree which are currently alpha
20
+ } from "@fluidframework/tree/alpha";
21
+ import type { z } from "zod";
22
+
23
+ import {
24
+ createMergableDiffSeries,
25
+ createMergableIdDiffSeries,
26
+ sharedTreeDiff,
27
+ type Difference,
28
+ type ObjectPath,
29
+ } from "./sharedTreeDiff.js";
30
+ import { isTreeMapNode, isTreeArrayNode, sharedTreeTraverse } from "./utils.js";
31
+
32
+ /**
33
+ * Manages determining the differences between two branches of a SharedTree represented as an actual tree node or a plain javascript object
34
+ * and applies said differences to the original SharedTree branch.
35
+ *
36
+ * @alpha
37
+ */
38
+ export class SharedTreeBranchManager {
39
+ private readonly objectSchema?: z.Schema | undefined;
40
+ private readonly nodeIdAttributeName?: string | undefined;
41
+
42
+ public constructor(params?: { objectSchema?: z.Schema; nodeIdAttributeName?: string }) {
43
+ this.objectSchema = params?.objectSchema;
44
+ this.nodeIdAttributeName = params?.nodeIdAttributeName;
45
+ }
46
+
47
+ /**
48
+ * Compares the differences between either two objects or a TreeNode and a plain object.
49
+ * TODO: Should allow comparing two tree nodes? Should we allow comparing two plain objects? Or just leave as tree node vs object?
50
+ */
51
+ public compare(
52
+ obj: Record<string, unknown> | TreeArrayNode,
53
+ newObj: Record<string, unknown> | unknown[],
54
+ ): Difference[] {
55
+ // By validating that the incoming object matches the schema, we can confirm that any property
56
+ // deletions/updates/additions are valid.
57
+ if (this.objectSchema !== undefined) {
58
+ const res = this.objectSchema.safeParse(newObj);
59
+ if (res.success === false) {
60
+ throw new TypeError("Invalid data");
61
+ }
62
+ }
63
+
64
+ const diffTotality = sharedTreeDiff(obj as Record<string, unknown> | unknown[], newObj, {
65
+ useObjectIds:
66
+ this.nodeIdAttributeName === undefined
67
+ ? undefined
68
+ : { idAttributeName: this.nodeIdAttributeName },
69
+ cyclesFix: true,
70
+ });
71
+
72
+ if (this.nodeIdAttributeName !== undefined) {
73
+ return createMergableIdDiffSeries(obj, diffTotality, this.nodeIdAttributeName);
74
+ }
75
+
76
+ return createMergableDiffSeries(diffTotality);
77
+ }
78
+
79
+ /**
80
+ * Produces a set of differences based on two versions of an object, applies the changes to the first one,
81
+ * and returns the set of differences.
82
+ */
83
+ public mergeObject(
84
+ obj: Record<string, unknown> | TreeArrayNode,
85
+ llmResponse: Record<string, unknown> | unknown[],
86
+ ): Difference[] {
87
+ const differences = this.compare(obj, llmResponse);
88
+ this.mergeDiffs(differences, obj);
89
+ return differences;
90
+ }
91
+
92
+ /**
93
+ * produces a diff between two objects and merges the differences.
94
+ */
95
+ public checkoutNewMergedBranch<T extends ImplicitFieldSchema>(
96
+ treeView: TreeViewAlpha<T>,
97
+ treeViewConfiguration: TreeViewConfiguration<T>,
98
+ absolutePathToObjectNode: ObjectPath,
99
+ llmResponse: Record<string, unknown> | unknown[],
100
+ ): {
101
+ differences: Difference[];
102
+ originalBranch: BranchableTree;
103
+ forkBranch: TreeBranchFork;
104
+ forkView: TreeViewAlpha<T>;
105
+ newBranchTargetNode: Record<string, unknown> | TreeArrayNode;
106
+ } {
107
+ // eslint-disable-next-line import/no-deprecated
108
+ const originalBranch = getBranch(treeView);
109
+ const forkBranch = originalBranch.branch();
110
+ const forkView = forkBranch.viewWith(treeViewConfiguration) as TreeViewAlpha<T>;
111
+
112
+ console.log("traveling to absolute path from root:", absolutePathToObjectNode);
113
+ const newBranchTargetNode = sharedTreeTraverse(
114
+ forkView.root as unknown as TreeMapNode | TreeArrayNode | Record<string, unknown>,
115
+ absolutePathToObjectNode,
116
+ ) as Record<string, unknown> | TreeArrayNode;
117
+
118
+ console.log(
119
+ "initiating compare between old and new branch target nodes",
120
+ { ...newBranchTargetNode },
121
+ { ...llmResponse },
122
+ );
123
+ console.log("newBranchTargetNode", { ...newBranchTargetNode });
124
+ console.log("llmResponse", { ...llmResponse });
125
+
126
+ const differences = this.compare(newBranchTargetNode, llmResponse);
127
+ // const differences = [];
128
+ this.mergeDiffs(differences, newBranchTargetNode);
129
+
130
+ return { differences, originalBranch, forkBranch, forkView, newBranchTargetNode };
131
+ }
132
+
133
+ /**
134
+ * Creates a forked branch of a tree view.
135
+ */
136
+ public checkoutNewMergedBranchV2<T extends ImplicitFieldSchema>(
137
+ treeView: TreeViewAlpha<T>,
138
+ treeViewConfiguration: TreeViewConfiguration<T>,
139
+ absolutePathToObjectNode: ObjectPath,
140
+ // differences: Difference[],
141
+ ): {
142
+ originalBranch: BranchableTree;
143
+ forkBranch: TreeBranchFork;
144
+ forkView: TreeViewAlpha<T>;
145
+ newBranchTargetNode: Record<string, unknown> | TreeArrayNode;
146
+ } {
147
+ // eslint-disable-next-line import/no-deprecated
148
+ const originalBranch = getBranch(treeView);
149
+ const forkBranch = originalBranch.branch();
150
+ const forkView = forkBranch.viewWith(treeViewConfiguration) as TreeViewAlpha<T>;
151
+ const newBranchTargetNode = sharedTreeTraverse(
152
+ forkView.root as TreeMapNode | TreeArrayNode | Record<string, unknown>,
153
+ absolutePathToObjectNode,
154
+ ) as Record<string, unknown> | TreeArrayNode;
155
+ // this.mergeDiffs(differences, newBranchTargetNode);
156
+ return { originalBranch, forkBranch, forkView, newBranchTargetNode };
157
+ }
158
+
159
+ /**
160
+ * Handles applying an array of differences to an object in the proper order and making any necessary adjustments as each diff
161
+ * is applied.
162
+ *
163
+ * @returns an array of differences that were not applied due to some kind of conflict or error.
164
+ */
165
+ public mergeDiffs(
166
+ diffs: Difference[],
167
+ objectToUpdate: Record<string, unknown> | TreeArrayNode,
168
+ ): Set<Difference> {
169
+ const unappliedDiffs = new Set<Difference>();
170
+
171
+ for (const diff of diffs) {
172
+ const isDiffApplied = this.applyDiff(diff, objectToUpdate);
173
+
174
+ if (isDiffApplied === false) {
175
+ unappliedDiffs.add(diff);
176
+ }
177
+ }
178
+
179
+ return unappliedDiffs;
180
+ }
181
+
182
+ /**
183
+ * Applies an individual diff to the objectToUpdate.
184
+ */
185
+ public applyDiff(
186
+ diff: Difference,
187
+ objectToUpdate: Record<string, unknown> | TreeArrayNode,
188
+ ): boolean {
189
+ const targetObject: unknown = getTargetObjectFromPath(diff.path, objectToUpdate);
190
+
191
+ if (isTreeMapNode(targetObject)) {
192
+ switch (diff.type) {
193
+ case "CHANGE":
194
+ case "CREATE": {
195
+ // This code is doing non-schema aware editing, which is not a supported feature of this API.
196
+ // Casting to any is a way to get this unsupported and rather unsafe operation to compile.
197
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any
198
+ targetObject.set(diff.path[diff.path.length - 1] as string, diff.value as any);
199
+ return true;
200
+ }
201
+ case "REMOVE": {
202
+ targetObject.delete(diff.path[diff.path.length - 1] as string);
203
+ return true;
204
+ }
205
+ default: {
206
+ throw new TypeError("Unsupported diff type for Map Tree Node");
207
+ }
208
+ }
209
+ } else if (isTreeArrayNode(targetObject)) {
210
+ const targetIndex = diff.path[diff.path.length - 1] as number;
211
+ const isTargetIndexValid = targetIndex >= 0 && targetIndex <= targetObject.length - 1;
212
+ switch (diff.type) {
213
+ case "CHANGE":
214
+ case "CREATE": {
215
+ if (isTargetIndexValid) {
216
+ // This code is doing non-schema aware editing, which is not a supported feature of this API.
217
+ // Casting to any is a way to get this unsupported and rather unsafe operation to compile.
218
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any
219
+ targetObject.insertAt(targetIndex, diff.value as any);
220
+ return true;
221
+ } else {
222
+ // This code is doing non-schema aware editing, which is not a supported feature of this API.
223
+ // Casting to any is a way to get this unsupported and rather unsafe operation to compile.
224
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any
225
+ targetObject.insertAtEnd(diff.value as any);
226
+ console.warn(
227
+ "CREATE diff specified an invalid index, defaulting to pushing to end of array",
228
+ );
229
+ return false;
230
+ }
231
+ }
232
+ case "MOVE": {
233
+ if (isTargetIndexValid) {
234
+ if (diff.newIndex > targetIndex) {
235
+ // forward move must use i + 1
236
+ targetObject.moveToIndex(diff.newIndex + 1, targetIndex);
237
+ } else if (diff.newIndex < targetIndex) {
238
+ // backwards move, using i directly is fine
239
+ targetObject.moveToIndex(diff.newIndex, targetIndex);
240
+ }
241
+ return true;
242
+ } else {
243
+ console.warn("MOVE diff specified an invalid index, ignoring.");
244
+ return false;
245
+ }
246
+ }
247
+ case "REMOVE": {
248
+ if (isTargetIndexValid) {
249
+ targetObject.removeAt(targetIndex);
250
+ return true;
251
+ } else {
252
+ console.warn("REMOVE diff specified an invalid index, ignoring.");
253
+ return false;
254
+ }
255
+ }
256
+ default: {
257
+ throw new TypeError("Unsupported diff type for Array Tree Node");
258
+ }
259
+ }
260
+ } else if (typeof targetObject === "object" && targetObject !== null) {
261
+ switch (diff.type) {
262
+ case "CHANGE":
263
+ case "CREATE": {
264
+ targetObject[diff.path[diff.path.length - 1] as string] = diff.value;
265
+ return true;
266
+ }
267
+ case "REMOVE": {
268
+ // We can't use the delete keyword on a tree node.
269
+ targetObject[diff.path[diff.path.length - 1] as string] = undefined;
270
+ return false;
271
+ }
272
+ default: {
273
+ throw new TypeError("Unsupported diff type for Object Tree Node");
274
+ }
275
+ }
276
+ } else {
277
+ throw new TypeError("Unsupported object type for diff application");
278
+ }
279
+ }
280
+ }
281
+
282
+ /**
283
+ * Returns the target object that the given diff should be applied to.
284
+ */
285
+ function getTargetObjectFromPath(
286
+ path: ObjectPath,
287
+ object: Record<string, unknown> | TreeArrayNode,
288
+ ): unknown {
289
+ let targetObject: unknown = object;
290
+ if (path.length > 1) {
291
+ targetObject = sharedTreeTraverse(object, path.slice(0, -1));
292
+ }
293
+ return targetObject;
294
+ }