@fluidframework/tree 2.60.0 → 2.61.0-355516

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 (126) hide show
  1. package/.mocharc.cjs +2 -3
  2. package/api-report/tree.alpha.api.md +11 -28
  3. package/api-report/tree.beta.api.md +6 -23
  4. package/api-report/tree.legacy.beta.api.md +71 -22
  5. package/api-report/tree.legacy.public.api.md +5 -22
  6. package/api-report/tree.public.api.md +5 -22
  7. package/dist/alpha.d.ts +10 -5
  8. package/dist/beta.d.ts +8 -4
  9. package/dist/core/tree/anchorSet.d.ts +3 -3
  10. package/dist/core/tree/anchorSet.d.ts.map +1 -1
  11. package/dist/core/tree/anchorSet.js.map +1 -1
  12. package/dist/index.d.ts +1 -1
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js.map +1 -1
  15. package/dist/legacy.d.ts +22 -4
  16. package/dist/packageVersion.d.ts +1 -1
  17. package/dist/packageVersion.d.ts.map +1 -1
  18. package/dist/packageVersion.js +1 -1
  19. package/dist/packageVersion.js.map +1 -1
  20. package/dist/public.d.ts +6 -3
  21. package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
  22. package/dist/shared-tree/treeCheckout.js +1 -0
  23. package/dist/shared-tree/treeCheckout.js.map +1 -1
  24. package/dist/simple-tree/api/index.d.ts +1 -1
  25. package/dist/simple-tree/api/index.d.ts.map +1 -1
  26. package/dist/simple-tree/api/index.js.map +1 -1
  27. package/dist/simple-tree/api/schemaFactory.d.ts +11 -83
  28. package/dist/simple-tree/api/schemaFactory.d.ts.map +1 -1
  29. package/dist/simple-tree/api/schemaFactory.js +26 -82
  30. package/dist/simple-tree/api/schemaFactory.js.map +1 -1
  31. package/dist/simple-tree/api/schemaFactoryRecursive.d.ts +5 -3
  32. package/dist/simple-tree/api/schemaFactoryRecursive.d.ts.map +1 -1
  33. package/dist/simple-tree/api/schemaFactoryRecursive.js.map +1 -1
  34. package/dist/simple-tree/core/index.d.ts +1 -1
  35. package/dist/simple-tree/core/index.d.ts.map +1 -1
  36. package/dist/simple-tree/core/index.js +2 -1
  37. package/dist/simple-tree/core/index.js.map +1 -1
  38. package/dist/simple-tree/core/treeNodeKernel.d.ts +12 -1
  39. package/dist/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
  40. package/dist/simple-tree/core/treeNodeKernel.js +188 -43
  41. package/dist/simple-tree/core/treeNodeKernel.js.map +1 -1
  42. package/dist/simple-tree/core/unhydratedFlexTree.d.ts +4 -3
  43. package/dist/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
  44. package/dist/simple-tree/core/unhydratedFlexTree.js +22 -6
  45. package/dist/simple-tree/core/unhydratedFlexTree.js.map +1 -1
  46. package/dist/simple-tree/index.d.ts +2 -2
  47. package/dist/simple-tree/index.d.ts.map +1 -1
  48. package/dist/simple-tree/index.js +3 -2
  49. package/dist/simple-tree/index.js.map +1 -1
  50. package/dist/simple-tree/node-kinds/array/arrayNode.d.ts.map +1 -1
  51. package/dist/simple-tree/node-kinds/array/arrayNode.js +13 -6
  52. package/dist/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
  53. package/dist/tableSchema.d.ts.map +1 -1
  54. package/dist/tableSchema.js +15 -10
  55. package/dist/tableSchema.js.map +1 -1
  56. package/dist/util/breakable.d.ts.map +1 -1
  57. package/dist/util/breakable.js +7 -1
  58. package/dist/util/breakable.js.map +1 -1
  59. package/lib/alpha.d.ts +10 -5
  60. package/lib/beta.d.ts +8 -4
  61. package/lib/core/tree/anchorSet.d.ts +3 -3
  62. package/lib/core/tree/anchorSet.d.ts.map +1 -1
  63. package/lib/core/tree/anchorSet.js.map +1 -1
  64. package/lib/index.d.ts +1 -1
  65. package/lib/index.d.ts.map +1 -1
  66. package/lib/index.js.map +1 -1
  67. package/lib/legacy.d.ts +22 -4
  68. package/lib/packageVersion.d.ts +1 -1
  69. package/lib/packageVersion.d.ts.map +1 -1
  70. package/lib/packageVersion.js +1 -1
  71. package/lib/packageVersion.js.map +1 -1
  72. package/lib/public.d.ts +6 -3
  73. package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
  74. package/lib/shared-tree/treeCheckout.js +1 -0
  75. package/lib/shared-tree/treeCheckout.js.map +1 -1
  76. package/lib/simple-tree/api/index.d.ts +1 -1
  77. package/lib/simple-tree/api/index.d.ts.map +1 -1
  78. package/lib/simple-tree/api/index.js.map +1 -1
  79. package/lib/simple-tree/api/schemaFactory.d.ts +11 -83
  80. package/lib/simple-tree/api/schemaFactory.d.ts.map +1 -1
  81. package/lib/simple-tree/api/schemaFactory.js +25 -81
  82. package/lib/simple-tree/api/schemaFactory.js.map +1 -1
  83. package/lib/simple-tree/api/schemaFactoryRecursive.d.ts +5 -3
  84. package/lib/simple-tree/api/schemaFactoryRecursive.d.ts.map +1 -1
  85. package/lib/simple-tree/api/schemaFactoryRecursive.js.map +1 -1
  86. package/lib/simple-tree/core/index.d.ts +1 -1
  87. package/lib/simple-tree/core/index.d.ts.map +1 -1
  88. package/lib/simple-tree/core/index.js +1 -1
  89. package/lib/simple-tree/core/index.js.map +1 -1
  90. package/lib/simple-tree/core/treeNodeKernel.d.ts +12 -1
  91. package/lib/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
  92. package/lib/simple-tree/core/treeNodeKernel.js +187 -43
  93. package/lib/simple-tree/core/treeNodeKernel.js.map +1 -1
  94. package/lib/simple-tree/core/unhydratedFlexTree.d.ts +4 -3
  95. package/lib/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
  96. package/lib/simple-tree/core/unhydratedFlexTree.js +22 -6
  97. package/lib/simple-tree/core/unhydratedFlexTree.js.map +1 -1
  98. package/lib/simple-tree/index.d.ts +2 -2
  99. package/lib/simple-tree/index.d.ts.map +1 -1
  100. package/lib/simple-tree/index.js +1 -1
  101. package/lib/simple-tree/index.js.map +1 -1
  102. package/lib/simple-tree/node-kinds/array/arrayNode.d.ts.map +1 -1
  103. package/lib/simple-tree/node-kinds/array/arrayNode.js +14 -7
  104. package/lib/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
  105. package/lib/tableSchema.d.ts.map +1 -1
  106. package/lib/tableSchema.js +16 -11
  107. package/lib/tableSchema.js.map +1 -1
  108. package/lib/tsdoc-metadata.json +1 -1
  109. package/lib/util/breakable.d.ts.map +1 -1
  110. package/lib/util/breakable.js +7 -1
  111. package/lib/util/breakable.js.map +1 -1
  112. package/package.json +27 -27
  113. package/src/core/tree/anchorSet.ts +2 -2
  114. package/src/index.ts +1 -0
  115. package/src/packageVersion.ts +1 -1
  116. package/src/shared-tree/treeCheckout.ts +1 -0
  117. package/src/simple-tree/api/index.ts +1 -0
  118. package/src/simple-tree/api/schemaFactory.ts +31 -103
  119. package/src/simple-tree/api/schemaFactoryRecursive.ts +41 -40
  120. package/src/simple-tree/core/index.ts +1 -0
  121. package/src/simple-tree/core/treeNodeKernel.ts +242 -44
  122. package/src/simple-tree/core/unhydratedFlexTree.ts +26 -3
  123. package/src/simple-tree/index.ts +2 -0
  124. package/src/simple-tree/node-kinds/array/arrayNode.ts +19 -11
  125. package/src/tableSchema.ts +15 -9
  126. package/src/util/breakable.ts +9 -1
@@ -1 +1 @@
1
- {"version":3,"file":"treeNodeKernel.d.ts","sourceRoot":"","sources":["../../../src/simple-tree/core/treeNodeKernel.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"treeNodeKernel.d.ts","sourceRoot":"","sources":["../../../src/simple-tree/core/treeNodeKernel.ts"],"names":[],"mappings":"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"}
@@ -2,20 +2,20 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
6
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
7
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
8
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
9
- };
10
5
  var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
11
6
  if (kind === "m") throw new TypeError("Private method is not writable");
12
7
  if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
13
8
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
14
9
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
15
10
  };
16
- var _TreeNodeKernel_hydrationState, _TreeNodeKernel_unhydratedEvents;
11
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
12
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
13
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
14
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
15
+ };
16
+ var _TreeNodeKernel_hydrationState, _TreeNodeKernel_eventBuffer, _KernelEventBuffer_instances, _KernelEventBuffer_disposed, _KernelEventBuffer_disposeOnFlushListener, _KernelEventBuffer_events, _KernelEventBuffer_eventSource, _KernelEventBuffer_disposeSourceListeners, _KernelEventBuffer_childrenChangedBuffer, _KernelEventBuffer_subTreeChangedBuffer, _KernelEventBuffer_emit, _KernelEventBuffer_handleChildrenChangedAfterBatch, _KernelEventBuffer_handleSubtreeChangedAfterBatch, _KernelEventBuffer_assertNotDisposed;
17
17
  import { createEmitter } from "@fluid-internal/client-utils";
18
- import { assert, Lazy, fail, debugAssert } from "@fluidframework/core-utils/internal";
18
+ import { assert, fail, debugAssert, unreachableCase, } from "@fluidframework/core-utils/internal";
19
19
  import { UsageError } from "@fluidframework/telemetry-utils/internal";
20
20
  import { anchorSlot, } from "../../core/index.js";
21
21
  import { getOrCreateHydratedFlexTreeNode } from "../../feature-libraries/index.js";
@@ -98,7 +98,7 @@ export class TreeNodeKernel {
98
98
  * This means optimizations like skipping processing data in subtrees where no subtreeChanged events are subscribed to would be able to work,
99
99
  * since the kernel does not unconditionally subscribe to those events (like a design which simply forwards all events would).
100
100
  */
101
- _TreeNodeKernel_unhydratedEvents.set(this, new Lazy((createEmitter)));
101
+ _TreeNodeKernel_eventBuffer.set(this, void 0);
102
102
  splitInnerNodeType(innerNode);
103
103
  assert(!treeNodeToKernel.has(node), 0xa1a /* only one kernel per node can be made */);
104
104
  treeNodeToKernel.set(node, this);
@@ -106,32 +106,16 @@ export class TreeNodeKernel {
106
106
  // Unhydrated case
107
107
  debugAssert(() => innerNode.treeNode === undefined);
108
108
  innerNode.treeNode = node;
109
- // Register for change events from the unhydrated flex node.
110
- // These will be fired if the unhydrated node is edited, and will also be forwarded later to the hydrated node.
111
109
  __classPrivateFieldSet(this, _TreeNodeKernel_hydrationState, {
112
110
  innerNode,
113
- off: innerNode.events.on("childrenChangedAfterBatch", ({ changedFields }) => {
114
- __classPrivateFieldGet(this, _TreeNodeKernel_unhydratedEvents, "f").value.emit("childrenChangedAfterBatch", {
115
- changedFields,
116
- });
117
- let unhydratedNode = innerNode;
118
- while (unhydratedNode !== undefined) {
119
- const treeNode = unhydratedNode.treeNode;
120
- if (treeNode !== undefined) {
121
- const kernel = getKernel(treeNode);
122
- __classPrivateFieldGet(kernel, _TreeNodeKernel_unhydratedEvents, "f").value.emit("subtreeChangedAfterBatch");
123
- }
124
- const parentNode = unhydratedNode.parentField.parent.parent;
125
- assert(parentNode === undefined || parentNode instanceof UnhydratedFlexTreeNode, 0xb76 /* Unhydrated node's parent should be an unhydrated node */);
126
- unhydratedNode = parentNode;
127
- }
128
- }),
129
111
  }, "f");
112
+ __classPrivateFieldSet(this, _TreeNodeKernel_eventBuffer, new KernelEventBuffer(innerNode.events), "f");
130
113
  }
131
114
  else {
132
115
  // Hydrated case
133
116
  __classPrivateFieldSet(this, _TreeNodeKernel_hydrationState, this.createHydratedState(innerNode.anchorNode), "f");
134
117
  __classPrivateFieldGet(this, _TreeNodeKernel_hydrationState, "f").innerNode = innerNode;
118
+ __classPrivateFieldSet(this, _TreeNodeKernel_eventBuffer, new KernelEventBuffer(innerNode.anchorNode.events), "f");
135
119
  }
136
120
  }
137
121
  get context() {
@@ -156,18 +140,8 @@ export class TreeNodeKernel {
156
140
  const anchorNode = anchors.locate(anchor) ?? fail(0xb42 /* Expected anchor node to be present */);
157
141
  __classPrivateFieldSet(this, _TreeNodeKernel_hydrationState, this.createHydratedState(anchorNode), "f");
158
142
  __classPrivateFieldGet(this, _TreeNodeKernel_hydrationState, "f").offAnchorNode.add(() => anchors.forget(anchor));
159
- // If needed, register forwarding emitters for events from before hydration
160
- if (__classPrivateFieldGet(this, _TreeNodeKernel_unhydratedEvents, "f").evaluated) {
161
- const events = __classPrivateFieldGet(this, _TreeNodeKernel_unhydratedEvents, "f").value;
162
- for (const eventName of kernelEvents) {
163
- if (events.hasListeners(eventName)) {
164
- __classPrivateFieldGet(this, _TreeNodeKernel_hydrationState, "f").offAnchorNode.add(
165
- // Argument is forwarded between matching events, so the type should be correct.
166
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
167
- anchorNode.events.on(eventName, (arg) => events.emit(eventName, arg)));
168
- }
169
- }
170
- }
143
+ // Lazily migrate existing event listeners to the anchor node
144
+ __classPrivateFieldGet(this, _TreeNodeKernel_eventBuffer, "f").migrateEventSource(anchorNode.events);
171
145
  }
172
146
  createHydratedState(anchorNode) {
173
147
  assert(!anchorNode.slots.has(simpleTreeNodeSlot), 0x7f5 /* Cannot associate an flex node with multiple simple-tree nodes */);
@@ -201,10 +175,7 @@ export class TreeNodeKernel {
201
175
  return treeStatusFromAnchorCache(__classPrivateFieldGet(this, _TreeNodeKernel_hydrationState, "f").anchorNode);
202
176
  }
203
177
  get events() {
204
- // Retrieve the correct events object based on whether this node is pre or post hydration.
205
- return isHydrated(__classPrivateFieldGet(this, _TreeNodeKernel_hydrationState, "f"))
206
- ? __classPrivateFieldGet(this, _TreeNodeKernel_hydrationState, "f").anchorNode.events
207
- : __classPrivateFieldGet(this, _TreeNodeKernel_unhydratedEvents, "f").value;
178
+ return __classPrivateFieldGet(this, _TreeNodeKernel_eventBuffer, "f");
208
179
  }
209
180
  dispose() {
210
181
  debugAssert(() => !this.disposed || "Cannot dispose a disposed node");
@@ -214,6 +185,7 @@ export class TreeNodeKernel {
214
185
  off();
215
186
  }
216
187
  }
188
+ __classPrivateFieldGet(this, _TreeNodeKernel_eventBuffer, "f").dispose();
217
189
  // TODO: go to the context and remove myself from withAnchors
218
190
  }
219
191
  isHydrated() {
@@ -272,8 +244,180 @@ export class TreeNodeKernel {
272
244
  return __classPrivateFieldGet(this, _TreeNodeKernel_hydrationState, "f").innerNode;
273
245
  }
274
246
  }
275
- _TreeNodeKernel_hydrationState = new WeakMap(), _TreeNodeKernel_unhydratedEvents = new WeakMap();
247
+ _TreeNodeKernel_hydrationState = new WeakMap(), _TreeNodeKernel_eventBuffer = new WeakMap();
276
248
  const kernelEvents = ["childrenChangedAfterBatch", "subtreeChangedAfterBatch"];
249
+ // #region TreeNodeEventBuffer
250
+ /**
251
+ * Whether or not events from {@link TreeNodeKernel} should be buffered instead of emitted immediately.
252
+ */
253
+ let bufferTreeEvents = false;
254
+ /**
255
+ * Call the provided callback with {@link TreeNode}s' events paused until after the callback's completion.
256
+ *
257
+ * Events that would otherwise have been emitted immediately are merged and buffered until after the
258
+ * provided callback has been completed.
259
+ *
260
+ * @remarks
261
+ * Note: this should be used with caution. User application behaviors are implicitly coupled to event timing.
262
+ * Disrupting this timing can lead to unexpected behavior.
263
+ */
264
+ export function withBufferedTreeEvents(callback) {
265
+ if (bufferTreeEvents) {
266
+ // Already buffering - just run the callback
267
+ callback();
268
+ }
269
+ else {
270
+ bufferTreeEvents = true;
271
+ try {
272
+ callback();
273
+ }
274
+ finally {
275
+ bufferTreeEvents = false;
276
+ flushEventsEmitter.emit("flush");
277
+ }
278
+ }
279
+ }
280
+ /**
281
+ * Event emitter to notify subscribers when tree events buffered due to {@link withBufferedTreeEvents} should be flushed.
282
+ */
283
+ const flushEventsEmitter = createEmitter();
284
+ /**
285
+ * Event emitter for {@link TreeNodeKernel}, which optionally buffers events based on {@link bufferTreeEvents}.
286
+ * @remarks Listens to {@link flushEventsEmitter} to know when to flush any buffered events.
287
+ */
288
+ class KernelEventBuffer {
289
+ constructor(
290
+ /**
291
+ * Source of the kernel events.
292
+ * Subscriptions will be created on-demand when listeners are added to this.events,
293
+ * and those subscriptions will be cleaned up when all corresponding listeners have been removed.
294
+ */
295
+ eventSource) {
296
+ _KernelEventBuffer_instances.add(this);
297
+ _KernelEventBuffer_disposed.set(this, false);
298
+ /**
299
+ * Listen to {@link flushEventsEmitter} to know when to flush buffered events.
300
+ */
301
+ _KernelEventBuffer_disposeOnFlushListener.set(this, flushEventsEmitter.on("flush", () => {
302
+ this.flush();
303
+ }));
304
+ _KernelEventBuffer_events.set(this, createEmitter());
305
+ _KernelEventBuffer_eventSource.set(this, void 0);
306
+ _KernelEventBuffer_disposeSourceListeners.set(this, new Map());
307
+ /**
308
+ * Buffer of fields that have changed since events were paused.
309
+ * When events are flushed, a single {@link AnchorEvents.childrenChangedAfterBatch} event will be emitted
310
+ * containing the accumulated set of changed fields.
311
+ */
312
+ _KernelEventBuffer_childrenChangedBuffer.set(this, new Set());
313
+ /**
314
+ * Whether or not the subtree has changed since events were paused.
315
+ * When events are flushed, a single {@link AnchorEvents.subTreeChanged} event will be emitted if and only
316
+ * if the subtree has changed.
317
+ */
318
+ _KernelEventBuffer_subTreeChangedBuffer.set(this, false);
319
+ __classPrivateFieldSet(this, _KernelEventBuffer_eventSource, eventSource, "f");
320
+ }
321
+ /**
322
+ * Migrate this event buffer to a new event source.
323
+ *
324
+ * @remarks
325
+ * Cleans up any existing event subscriptions from the old source.
326
+ * Binds events to the new source for each event with active listeners.
327
+ */
328
+ migrateEventSource(newSource) {
329
+ // Unsubscribe from the old source
330
+ __classPrivateFieldGet(this, _KernelEventBuffer_disposeSourceListeners, "f").forEach((off) => off());
331
+ __classPrivateFieldGet(this, _KernelEventBuffer_disposeSourceListeners, "f").clear();
332
+ __classPrivateFieldSet(this, _KernelEventBuffer_eventSource, newSource, "f");
333
+ if (__classPrivateFieldGet(this, _KernelEventBuffer_events, "f").hasListeners("childrenChangedAfterBatch")) {
334
+ const off = __classPrivateFieldGet(this, _KernelEventBuffer_eventSource, "f").on("childrenChangedAfterBatch", ({ changedFields }) => __classPrivateFieldGet(this, _KernelEventBuffer_instances, "m", _KernelEventBuffer_emit).call(this, "childrenChangedAfterBatch", { changedFields }));
335
+ __classPrivateFieldGet(this, _KernelEventBuffer_disposeSourceListeners, "f").set("childrenChangedAfterBatch", off);
336
+ }
337
+ if (__classPrivateFieldGet(this, _KernelEventBuffer_events, "f").hasListeners("subtreeChangedAfterBatch")) {
338
+ const off = __classPrivateFieldGet(this, _KernelEventBuffer_eventSource, "f").on("subtreeChangedAfterBatch", () => __classPrivateFieldGet(this, _KernelEventBuffer_instances, "m", _KernelEventBuffer_emit).call(this, "subtreeChangedAfterBatch"));
339
+ __classPrivateFieldGet(this, _KernelEventBuffer_disposeSourceListeners, "f").set("subtreeChangedAfterBatch", off);
340
+ }
341
+ }
342
+ on(eventName, listener) {
343
+ // Lazily bind event listeners to the source.
344
+ // If we do not have any existing listeners for this event, then we need to bind to the source.
345
+ if (!__classPrivateFieldGet(this, _KernelEventBuffer_events, "f").hasListeners(eventName)) {
346
+ assert(!__classPrivateFieldGet(this, _KernelEventBuffer_disposeSourceListeners, "f").has(eventName), "Should not have a dispose function without listeners");
347
+ const off = __classPrivateFieldGet(this, _KernelEventBuffer_eventSource, "f").on(eventName, (args) => __classPrivateFieldGet(this, _KernelEventBuffer_instances, "m", _KernelEventBuffer_emit).call(this, eventName, args));
348
+ __classPrivateFieldGet(this, _KernelEventBuffer_disposeSourceListeners, "f").set(eventName, off);
349
+ }
350
+ __classPrivateFieldGet(this, _KernelEventBuffer_events, "f").on(eventName, listener);
351
+ return () => this.off(eventName, listener);
352
+ }
353
+ off(eventName, listener) {
354
+ __classPrivateFieldGet(this, _KernelEventBuffer_events, "f").off(eventName, listener);
355
+ // If there are no remaining listeners for the event, unbind from the source
356
+ if (!__classPrivateFieldGet(this, _KernelEventBuffer_events, "f").hasListeners(eventName)) {
357
+ const off = __classPrivateFieldGet(this, _KernelEventBuffer_disposeSourceListeners, "f").get(eventName);
358
+ off?.();
359
+ __classPrivateFieldGet(this, _KernelEventBuffer_disposeSourceListeners, "f").delete(eventName);
360
+ }
361
+ }
362
+ /**
363
+ * Flushes any events buffered due to {@link withBufferedTreeEvents}.
364
+ */
365
+ flush() {
366
+ __classPrivateFieldGet(this, _KernelEventBuffer_instances, "m", _KernelEventBuffer_assertNotDisposed).call(this);
367
+ if (__classPrivateFieldGet(this, _KernelEventBuffer_childrenChangedBuffer, "f").size > 0) {
368
+ __classPrivateFieldGet(this, _KernelEventBuffer_events, "f").emit("childrenChangedAfterBatch", {
369
+ changedFields: __classPrivateFieldGet(this, _KernelEventBuffer_childrenChangedBuffer, "f"),
370
+ });
371
+ __classPrivateFieldGet(this, _KernelEventBuffer_childrenChangedBuffer, "f").clear();
372
+ }
373
+ if (__classPrivateFieldGet(this, _KernelEventBuffer_subTreeChangedBuffer, "f")) {
374
+ __classPrivateFieldGet(this, _KernelEventBuffer_events, "f").emit("subtreeChangedAfterBatch");
375
+ __classPrivateFieldSet(this, _KernelEventBuffer_subTreeChangedBuffer, false, "f");
376
+ }
377
+ }
378
+ dispose() {
379
+ if (__classPrivateFieldGet(this, _KernelEventBuffer_disposed, "f")) {
380
+ return;
381
+ }
382
+ assert(__classPrivateFieldGet(this, _KernelEventBuffer_childrenChangedBuffer, "f").size === 0 && !__classPrivateFieldGet(this, _KernelEventBuffer_subTreeChangedBuffer, "f"), "Buffered kernel events should have been flushed before disposing.");
383
+ __classPrivateFieldGet(this, _KernelEventBuffer_disposeOnFlushListener, "f").call(this);
384
+ __classPrivateFieldGet(this, _KernelEventBuffer_disposeSourceListeners, "f").forEach((off) => off());
385
+ __classPrivateFieldGet(this, _KernelEventBuffer_disposeSourceListeners, "f").clear();
386
+ __classPrivateFieldGet(this, _KernelEventBuffer_childrenChangedBuffer, "f").clear();
387
+ __classPrivateFieldSet(this, _KernelEventBuffer_subTreeChangedBuffer, false, "f");
388
+ __classPrivateFieldSet(this, _KernelEventBuffer_disposed, true, "f");
389
+ }
390
+ }
391
+ _KernelEventBuffer_disposed = new WeakMap(), _KernelEventBuffer_disposeOnFlushListener = new WeakMap(), _KernelEventBuffer_events = new WeakMap(), _KernelEventBuffer_eventSource = new WeakMap(), _KernelEventBuffer_disposeSourceListeners = new WeakMap(), _KernelEventBuffer_childrenChangedBuffer = new WeakMap(), _KernelEventBuffer_subTreeChangedBuffer = new WeakMap(), _KernelEventBuffer_instances = new WeakSet(), _KernelEventBuffer_emit = function _KernelEventBuffer_emit(eventName, arg) {
392
+ __classPrivateFieldGet(this, _KernelEventBuffer_instances, "m", _KernelEventBuffer_assertNotDisposed).call(this);
393
+ switch (eventName) {
394
+ case "childrenChangedAfterBatch":
395
+ assert(arg !== undefined, "childrenChangedAfterBatch should have arg");
396
+ return __classPrivateFieldGet(this, _KernelEventBuffer_instances, "m", _KernelEventBuffer_handleChildrenChangedAfterBatch).call(this, arg.changedFields);
397
+ case "subtreeChangedAfterBatch":
398
+ return __classPrivateFieldGet(this, _KernelEventBuffer_instances, "m", _KernelEventBuffer_handleSubtreeChangedAfterBatch).call(this);
399
+ default:
400
+ unreachableCase(eventName);
401
+ }
402
+ }, _KernelEventBuffer_handleChildrenChangedAfterBatch = function _KernelEventBuffer_handleChildrenChangedAfterBatch(changedFields) {
403
+ if (bufferTreeEvents) {
404
+ for (const fieldKey of changedFields) {
405
+ __classPrivateFieldGet(this, _KernelEventBuffer_childrenChangedBuffer, "f").add(fieldKey);
406
+ }
407
+ }
408
+ else {
409
+ __classPrivateFieldGet(this, _KernelEventBuffer_events, "f").emit("childrenChangedAfterBatch", { changedFields });
410
+ }
411
+ }, _KernelEventBuffer_handleSubtreeChangedAfterBatch = function _KernelEventBuffer_handleSubtreeChangedAfterBatch() {
412
+ if (bufferTreeEvents) {
413
+ __classPrivateFieldSet(this, _KernelEventBuffer_subTreeChangedBuffer, true, "f");
414
+ }
415
+ else {
416
+ __classPrivateFieldGet(this, _KernelEventBuffer_events, "f").emit("subtreeChangedAfterBatch");
417
+ }
418
+ }, _KernelEventBuffer_assertNotDisposed = function _KernelEventBuffer_assertNotDisposed() {
419
+ assert(!__classPrivateFieldGet(this, _KernelEventBuffer_disposed, "f"), "Event handler disposed.");
420
+ };
277
421
  /**
278
422
  * Narrows innerNode to either {@link UnhydratedFlexTreeNode} or {@link HydratedFlexTreeNode}.
279
423
  */
@@ -1 +1 @@
1
- {"version":3,"file":"treeNodeKernel.js","sourceRoot":"","sources":["../../../src/simple-tree/core/treeNodeKernel.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { createEmitter } from \"@fluid-internal/client-utils\";\nimport type { Listenable, Off } from \"@fluidframework/core-interfaces\";\nimport { assert, Lazy, fail, debugAssert } from \"@fluidframework/core-utils/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport {\n\tanchorSlot,\n\ttype AnchorEvents,\n\ttype AnchorNode,\n\ttype AnchorSet,\n\ttype TreeValue,\n\ttype UpPath,\n} from \"../../core/index.js\";\nimport { getOrCreateHydratedFlexTreeNode } from \"../../feature-libraries/index.js\";\nimport {\n\tassertFlexTreeEntityNotFreed,\n\tContextSlot,\n\tflexTreeSlot,\n\tLazyEntity,\n\tTreeStatus,\n\ttreeStatusFromAnchorCache,\n\ttype FlexTreeNode,\n\ttype HydratedFlexTreeNode,\n} from \"../../feature-libraries/index.js\";\n\nimport type { Context, HydratedContext } from \"./context.js\";\nimport type { TreeNode } from \"./treeNode.js\";\nimport type { TreeNodeSchema } from \"./treeNodeSchema.js\";\nimport type { InternalTreeNode, Unhydrated } from \"./types.js\";\nimport { UnhydratedFlexTreeNode } from \"./unhydratedFlexTree.js\";\n\nconst treeNodeToKernel = new WeakMap<TreeNode, TreeNodeKernel>();\n\nexport function getKernel(node: TreeNode): TreeNodeKernel {\n\tconst kernel = treeNodeToKernel.get(node);\n\tassert(kernel !== undefined, 0x9b1 /* Expected tree node to have kernel */);\n\treturn kernel;\n}\n\n/**\n * Detects if the given 'candidate' is a TreeNode.\n *\n * @remarks\n * Supports both Hydrated and {@link Unhydrated} TreeNodes, both of which return true.\n *\n * Because the common usage is to check if a value being inserted/set is a TreeNode,\n * this function permits calling with primitives as well as objects.\n *\n * Primitives will always return false (as they are copies of data, not references to nodes).\n *\n * @param candidate - Value which may be a TreeNode\n * @returns true if the given 'candidate' is a hydrated TreeNode.\n */\nexport function isTreeNode(candidate: unknown): candidate is TreeNode | Unhydrated<TreeNode> {\n\treturn treeNodeToKernel.has(candidate as TreeNode);\n}\n\n/**\n * Returns a schema for a value if the value is a {@link TreeNode}.\n *\n * Returns undefined for other values.\n * @remarks\n * Does not give schema for a {@link TreeLeafValue}.\n */\nexport function tryGetTreeNodeSchema(value: unknown): undefined | TreeNodeSchema {\n\tconst kernel = treeNodeToKernel.get(value as TreeNode);\n\treturn kernel?.schema;\n}\n\n/** The {@link HydrationState} of a {@link TreeNodeKernel} before the kernel is hydrated */\ninterface UnhydratedState {\n\toff: Off;\n\treadonly innerNode: UnhydratedFlexTreeNode;\n}\n\n/** The {@link HydrationState} of a {@link TreeNodeKernel} after the kernel is hydrated */\ninterface HydratedState {\n\t/** The flex node for this kernel (lazy - undefined if it has not yet been demanded) */\n\tinnerNode?: FlexTreeNode;\n\t/** The {@link AnchorNode} that this node is associated with. */\n\treadonly anchorNode: AnchorNode;\n\t/** All {@link Off | event deregistration functions} that should be run when the kernel is disposed. */\n\treadonly offAnchorNode: Set<Off>;\n}\n\n/** State within a {@link TreeNodeKernel} that is related to the hydration process */\ntype HydrationState = UnhydratedState | HydratedState;\n\n/** True if and only if the given {@link HydrationState} is post-hydration */\nfunction isHydrated(state: HydrationState): state is HydratedState {\n\treturn (state as Partial<HydratedState>).anchorNode !== undefined;\n}\n\n/**\n * Contains state and an internal API for managing {@link TreeNode}s.\n * @remarks All {@link TreeNode}s have an associated kernel object.\n * The kernel has the same lifetime as the node and spans both its unhydrated and hydrated states.\n */\nexport class TreeNodeKernel {\n\tprivate disposed = false;\n\n\t/**\n\t * Generation number which is incremented any time we have an edit on the node.\n\t * Used during iteration to make sure there has been no edits that were concurrently made.\n\t * @remarks\n\t * This is updated monotonically by this class when edits are applied.\n\t * TODO: update this when applying edits to unhydrated trees.\n\t *\n\t * If TypeScript supported making this immutable from outside the class without making it readonly from inside, that would be used here,\n\t * but they only way to do that is add a separate public accessor and make it private, which was deemed not worth the boilerplate, runtime overhead and bundle size.\n\t */\n\tpublic generationNumber: number = 0;\n\n\t#hydrationState: HydrationState;\n\n\t/**\n\t * Events registered before hydration.\n\t * @remarks\n\t * Since these are usually not used, they are allocated lazily as an optimization.\n\t * The laziness also avoids extra forwarding overhead for events from this kernel's anchor node and also avoids registering for events that are unneeded.\n\t * This means optimizations like skipping processing data in subtrees where no subtreeChanged events are subscribed to would be able to work,\n\t * since the kernel does not unconditionally subscribe to those events (like a design which simply forwards all events would).\n\t */\n\treadonly #unhydratedEvents = new Lazy(createEmitter<KernelEvents>);\n\n\t/**\n\t * Create a TreeNodeKernel which can be looked up with {@link getKernel}.\n\t *\n\t * @param initialContext - context from when this node was originally created. Only used when unhydrated.\n\t * @param innerNode - When unhydrated/raw or marinated the MapTreeNode. FlexTreeNode when cooked.\n\t * @remarks\n\t * Exactly one kernel per TreeNode should be created.\n\t */\n\tpublic constructor(\n\t\tpublic readonly node: TreeNode,\n\t\tpublic readonly schema: TreeNodeSchema,\n\t\tinnerNode: InnerNode,\n\t\tprivate readonly initialContext: Context,\n\t) {\n\t\tsplitInnerNodeType(innerNode);\n\n\t\tassert(!treeNodeToKernel.has(node), 0xa1a /* only one kernel per node can be made */);\n\t\ttreeNodeToKernel.set(node, this);\n\n\t\tif (innerNode instanceof UnhydratedFlexTreeNode) {\n\t\t\t// Unhydrated case\n\t\t\tdebugAssert(() => innerNode.treeNode === undefined);\n\t\t\tinnerNode.treeNode = node;\n\t\t\t// Register for change events from the unhydrated flex node.\n\t\t\t// These will be fired if the unhydrated node is edited, and will also be forwarded later to the hydrated node.\n\t\t\tthis.#hydrationState = {\n\t\t\t\tinnerNode,\n\t\t\t\toff: innerNode.events.on(\"childrenChangedAfterBatch\", ({ changedFields }) => {\n\t\t\t\t\tthis.#unhydratedEvents.value.emit(\"childrenChangedAfterBatch\", {\n\t\t\t\t\t\tchangedFields,\n\t\t\t\t\t});\n\n\t\t\t\t\tlet unhydratedNode: UnhydratedFlexTreeNode | undefined = innerNode;\n\t\t\t\t\twhile (unhydratedNode !== undefined) {\n\t\t\t\t\t\tconst treeNode = unhydratedNode.treeNode;\n\t\t\t\t\t\tif (treeNode !== undefined) {\n\t\t\t\t\t\t\tconst kernel = getKernel(treeNode);\n\t\t\t\t\t\t\tkernel.#unhydratedEvents.value.emit(\"subtreeChangedAfterBatch\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst parentNode: FlexTreeNode | undefined =\n\t\t\t\t\t\t\tunhydratedNode.parentField.parent.parent;\n\t\t\t\t\t\tassert(\n\t\t\t\t\t\t\tparentNode === undefined || parentNode instanceof UnhydratedFlexTreeNode,\n\t\t\t\t\t\t\t0xb76 /* Unhydrated node's parent should be an unhydrated node */,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tunhydratedNode = parentNode;\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t};\n\t\t} else {\n\t\t\t// Hydrated case\n\t\t\tthis.#hydrationState = this.createHydratedState(innerNode.anchorNode);\n\t\t\tthis.#hydrationState.innerNode = innerNode;\n\t\t}\n\t}\n\n\tpublic get context(): Context {\n\t\tif (isHydrated(this.#hydrationState)) {\n\t\t\t// This can't be cached on this.#hydrated during hydration since initial tree is hydrated before the context is cached on the anchorSet.\n\t\t\treturn (\n\t\t\t\tthis.#hydrationState?.anchorNode.anchorSet.slots.get(SimpleContextSlot) ??\n\t\t\t\tfail(0xb40 /* missing simple-tree context */)\n\t\t\t);\n\t\t}\n\t\treturn this.initialContext;\n\t}\n\n\t/**\n\t * Transition from {@link Unhydrated} to hydrated.\n\t * Bi-directionally associates the given hydrated TreeNode to the anchor node at the provided path.\n\t * @remarks\n\t * Happens at most once for any given node.\n\t * Cleans up mappings to {@link UnhydratedFlexTreeNode} - it is assumed that they are no longer needed once this node has an anchor node.\n\t */\n\tpublic hydrate(anchors: AnchorSet, path: UpPath): void {\n\t\tassert(!this.disposed, 0xa2a /* cannot hydrate a disposed node */);\n\t\tassert(!isHydrated(this.#hydrationState), 0xa2b /* hydration should only happen once */);\n\n\t\tconst anchor = anchors.track(path);\n\t\tconst anchorNode =\n\t\t\tanchors.locate(anchor) ?? fail(0xb42 /* Expected anchor node to be present */);\n\n\t\tthis.#hydrationState = this.createHydratedState(anchorNode);\n\t\tthis.#hydrationState.offAnchorNode.add(() => anchors.forget(anchor));\n\n\t\t// If needed, register forwarding emitters for events from before hydration\n\t\tif (this.#unhydratedEvents.evaluated) {\n\t\t\tconst events = this.#unhydratedEvents.value;\n\t\t\tfor (const eventName of kernelEvents) {\n\t\t\t\tif (events.hasListeners(eventName)) {\n\t\t\t\t\tthis.#hydrationState.offAnchorNode.add(\n\t\t\t\t\t\t// Argument is forwarded between matching events, so the type should be correct.\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\t\t\t\tanchorNode.events.on(eventName, (arg: any) => events.emit(eventName, arg)),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate createHydratedState(anchorNode: AnchorNode): HydratedState {\n\t\tassert(\n\t\t\t!anchorNode.slots.has(simpleTreeNodeSlot),\n\t\t\t0x7f5 /* Cannot associate an flex node with multiple simple-tree nodes */,\n\t\t);\n\t\tanchorNode.slots.set(simpleTreeNodeSlot, this.node);\n\t\treturn {\n\t\t\tanchorNode,\n\t\t\toffAnchorNode: new Set([\n\t\t\t\tanchorNode.events.on(\"afterDestroy\", () => this.dispose()),\n\t\t\t\t// TODO: this should be triggered on change even for unhydrated nodes.\n\t\t\t\tanchorNode.events.on(\"childrenChanging\", () => {\n\t\t\t\t\tthis.generationNumber += 1;\n\t\t\t\t}),\n\t\t\t]),\n\t\t};\n\t}\n\n\tpublic getStatus(): TreeStatus {\n\t\tif (this.disposed) {\n\t\t\treturn TreeStatus.Deleted;\n\t\t}\n\t\tif (!isHydrated(this.#hydrationState)) {\n\t\t\treturn TreeStatus.New;\n\t\t}\n\n\t\t// TODO: Replace this check with the proper check against the cursor state when the cursor becomes part of the kernel\n\t\tconst flex = this.#hydrationState.anchorNode.slots.get(flexTreeSlot);\n\t\tif (flex !== undefined) {\n\t\t\tassert(flex instanceof LazyEntity, 0x9b4 /* Unexpected flex node implementation */);\n\t\t\tif (flex.isFreed()) {\n\t\t\t\treturn TreeStatus.Deleted;\n\t\t\t}\n\t\t}\n\n\t\treturn treeStatusFromAnchorCache(this.#hydrationState.anchorNode);\n\t}\n\n\tpublic get events(): Listenable<KernelEvents> {\n\t\t// Retrieve the correct events object based on whether this node is pre or post hydration.\n\t\treturn isHydrated(this.#hydrationState)\n\t\t\t? this.#hydrationState.anchorNode.events\n\t\t\t: this.#unhydratedEvents.value;\n\t}\n\n\tpublic dispose(): void {\n\t\tdebugAssert(() => !this.disposed || \"Cannot dispose a disposed node\");\n\t\tthis.disposed = true;\n\t\tif (isHydrated(this.#hydrationState)) {\n\t\t\tfor (const off of this.#hydrationState.offAnchorNode) {\n\t\t\t\toff();\n\t\t\t}\n\t\t}\n\t\t// TODO: go to the context and remove myself from withAnchors\n\t}\n\n\tpublic isHydrated(): this is { anchorNode: AnchorNode; context: HydratedContext } {\n\t\treturn isHydrated(this.#hydrationState);\n\t}\n\n\tpublic get anchorNode(): AnchorNode | undefined {\n\t\treturn isHydrated(this.#hydrationState) ? this.#hydrationState.anchorNode : undefined;\n\t}\n\n\t/**\n\t * Retrieves the flex node associated with the given target.\n\t * @remarks\n\t * For {@link Unhydrated} nodes, this returns the MapTreeNode.\n\t *\n\t * For hydrated nodes it returns a FlexTreeNode backed by the forest.\n\t * Note that for \"marinated\" nodes, this FlexTreeNode exists and returns it: it does not return the MapTreeNode which is the current InnerNode.\n\t *\n\t * @throws A {@link @fluidframework/telemetry-utils#UsageError} if the node has been deleted.\n\t */\n\tpublic getOrCreateInnerNode(): InnerNode {\n\t\tif (!isHydrated(this.#hydrationState)) {\n\t\t\tdebugAssert(\n\t\t\t\t() =>\n\t\t\t\t\tthis.#hydrationState.innerNode?.context.isDisposed() === false ||\n\t\t\t\t\t\"Unhydrated node should never be disposed\",\n\t\t\t);\n\t\t\treturn this.#hydrationState.innerNode; // Unhydrated case\n\t\t}\n\n\t\tif (this.disposed) {\n\t\t\tthrow new UsageError(\"Cannot access a deleted node.\");\n\t\t}\n\n\t\tif (this.#hydrationState.innerNode === undefined) {\n\t\t\t// Marinated case -> cooked\n\t\t\tconst anchorNode = this.#hydrationState.anchorNode;\n\t\t\t// This TreeNode is bound to an anchor node, but it may or may not have an actual flex node yet\n\t\t\tconst flexNode = anchorNode.slots.get(flexTreeSlot);\n\t\t\tif (flexNode !== undefined) {\n\t\t\t\t// If the flex node already exists, use it...\n\t\t\t\tthis.#hydrationState.innerNode = flexNode;\n\t\t\t} else {\n\t\t\t\t// ...otherwise, the flex node must be created\n\t\t\t\tconst context =\n\t\t\t\t\tanchorNode.anchorSet.slots.get(ContextSlot) ?? fail(0xb41 /* missing context */);\n\t\t\t\tconst cursor = context.checkout.forest.allocateCursor(\"getFlexNode\");\n\t\t\t\tcontext.checkout.forest.moveCursorToPath(anchorNode, cursor);\n\t\t\t\tthis.#hydrationState.innerNode = getOrCreateHydratedFlexTreeNode(context, cursor);\n\t\t\t\tcursor.free();\n\t\t\t\tassertFlexTreeEntityNotFreed(this.#hydrationState.innerNode);\n\t\t\t}\n\t\t}\n\n\t\treturn this.#hydrationState.innerNode;\n\t}\n\n\t/**\n\t * Retrieves the {@link UnhydratedFlexTreeNode} if unhydrated. otherwise undefined.\n\t */\n\tpublic getInnerNodeIfUnhydrated(): UnhydratedFlexTreeNode | undefined {\n\t\tif (isHydrated(this.#hydrationState)) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn this.#hydrationState.innerNode;\n\t}\n}\n\nconst kernelEvents = [\"childrenChangedAfterBatch\", \"subtreeChangedAfterBatch\"] as const;\n\ntype KernelEvents = Pick<AnchorEvents, (typeof kernelEvents)[number]>;\n\n/**\n * For \"cooked\" nodes this is a HydratedFlexTreeNode thats a projection of forest content.\n * For {@link Unhydrated} nodes this is a UnhydratedFlexTreeNode.\n *\n * For \"marinated\" nodes, some code (ex: getOrCreateInnerNode) returns the FlexTreeNode thats a projection of forest content, and some code (ex: tryGetInnerNode) returns undefined.\n */\nexport type InnerNode = FlexTreeNode;\n\n/**\n * Narrows innerNode to either {@link UnhydratedFlexTreeNode} or {@link HydratedFlexTreeNode}.\n */\nexport function splitInnerNodeType(\n\tinnerNode: InnerNode,\n): asserts innerNode is UnhydratedFlexTreeNode | HydratedFlexTreeNode {\n\tassert(\n\t\tinnerNode instanceof UnhydratedFlexTreeNode || innerNode.isHydrated(),\n\t\t0xbc8 /* Invalid inner node type */,\n\t);\n}\n\n/**\n * An anchor slot which associates an anchor with its corresponding {@link TreeNode}, if there is one.\n * @remarks\n * For this to work, we have to require that there is at most a single view using a given AnchorSet.\n * FlexTree already has this assumption, and we also assume there is a single simple-tree per FlexTree, so this is valid.\n */\nexport const simpleTreeNodeSlot = anchorSlot<TreeNode>();\n\n/**\n * Dispose a TreeNode (if any) for an existing anchor without disposing the anchor.\n */\nexport function tryDisposeTreeNode(anchorNode: AnchorNode): void {\n\tconst treeNode = anchorNode.slots.get(simpleTreeNodeSlot);\n\tif (treeNode !== undefined) {\n\t\tconst kernel = getKernel(treeNode);\n\t\tkernel.dispose();\n\t\tanchorNode.slots.delete(simpleTreeNodeSlot);\n\t}\n}\n\n/**\n * Gets the {@link TreeNodeSchema} for the {@link InnerNode}.\n */\nexport function getSimpleNodeSchemaFromInnerNode(innerNode: InnerNode): TreeNodeSchema {\n\tconst context: Context = getSimpleContextFromInnerNode(innerNode);\n\treturn context.schema.get(innerNode.type) ?? fail(0xb3f /* missing schema from context */);\n}\n\n/**\n * Gets the {@link Context} for the {@link InnerNode}.\n */\nexport function getSimpleContextFromInnerNode(innerNode: InnerNode): Context {\n\tsplitInnerNodeType(innerNode);\n\tif (innerNode instanceof UnhydratedFlexTreeNode) {\n\t\treturn innerNode.simpleContext;\n\t}\n\n\tconst context = innerNode.anchorNode.anchorSet.slots.get(SimpleContextSlot);\n\tassert(context !== undefined, 0xa55 /* missing simple tree context */);\n\n\treturn context;\n}\n\n/**\n * Retrieves the flex node associated with the given target.\n * @remarks\n * For {@link Unhydrated} nodes, this returns the MapTreeNode.\n *\n * For hydrated nodes it returns a FlexTreeNode backed by the forest.\n * Note that for \"marinated\" nodes, this FlexTreeNode exists and returns it: it does not return the MapTreeNode which is the current InnerNode.\n *\n * @throws A {@link @fluidframework/telemetry-utils#UsageError} if the node has been deleted.\n */\nexport function getOrCreateInnerNode(treeNode: TreeNode): InnerNode {\n\tconst kernel = getKernel(treeNode);\n\treturn kernel.getOrCreateInnerNode();\n}\n\n/**\n * Gets a flex node from an anchor node\n */\nfunction flexNodeFromAnchor(anchorNode: AnchorNode): HydratedFlexTreeNode {\n\tconst flexNode = anchorNode.slots.get(flexTreeSlot);\n\tif (flexNode !== undefined) {\n\t\treturn flexNode; // If it does have a flex node, return it...\n\t} // ...otherwise, the flex node must be created\n\tconst context =\n\t\tanchorNode.anchorSet.slots.get(ContextSlot) ?? fail(0xb45 /* missing context */);\n\tconst cursor = context.checkout.forest.allocateCursor(\"getFlexNode\");\n\tcontext.checkout.forest.moveCursorToPath(anchorNode, cursor);\n\tconst newFlexNode = getOrCreateHydratedFlexTreeNode(context, cursor);\n\tcursor.free();\n\treturn newFlexNode;\n}\n\n/**\n * Gets a tree node from an anchor node\n */\nexport function treeNodeFromAnchor(anchorNode: AnchorNode): TreeNode | TreeValue {\n\tconst cached = anchorNode.slots.get(simpleTreeNodeSlot);\n\tif (cached !== undefined) {\n\t\treturn cached;\n\t}\n\n\tconst flexNode = flexNodeFromAnchor(anchorNode);\n\treturn createTreeNodeFromInner(flexNode);\n}\n\n/**\n * Constructs a TreeNode from an InnerNode.\n * @remarks\n * This does not do caching or validation: caller must ensure duplicate nodes for a given inner node are not created, and that the inner node is valid.\n */\nexport function createTreeNodeFromInner(innerNode: InnerNode): TreeNode | TreeValue {\n\tconst classSchema = getSimpleNodeSchemaFromInnerNode(innerNode);\n\tconst internal = innerNode as unknown as InternalTreeNode;\n\treturn typeof classSchema === \"function\"\n\t\t? new classSchema(internal)\n\t\t: (classSchema as { create(data: InternalTreeNode): TreeNode | TreeValue }).create(\n\t\t\t\tinternal,\n\t\t\t);\n}\n\n/**\n * Creating multiple simple tree contexts for the same branch, and thus with the same underlying AnchorSet does not work due to how TreeNode caching works.\n * This slot is used to detect if one already exists and error if creating a second.\n * @remarks\n * See also {@link ContextSlot} in which the flex-tree context is stored.\n */\nexport const SimpleContextSlot = anchorSlot<HydratedContext>();\n"]}
1
+ {"version":3,"file":"treeNodeKernel.js","sourceRoot":"","sources":["../../../src/simple-tree/core/treeNodeKernel.ts"],"names":[],"mappings":"AAAA;;;GAGG;;;;;;;;;;;;;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAE7D,OAAO,EACN,MAAM,EACN,IAAI,EACJ,WAAW,EACX,eAAe,GACf,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAEtE,OAAO,EACN,UAAU,GAOV,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,+BAA+B,EAAE,MAAM,kCAAkC,CAAC;AACnF,OAAO,EACN,4BAA4B,EAC5B,WAAW,EACX,YAAY,EACZ,UAAU,EACV,UAAU,EACV,yBAAyB,GAGzB,MAAM,kCAAkC,CAAC;AAM1C,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,MAAM,gBAAgB,GAAG,IAAI,OAAO,EAA4B,CAAC;AAEjE,MAAM,UAAU,SAAS,CAAC,IAAc;IACvC,MAAM,MAAM,GAAG,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC5E,OAAO,MAAM,CAAC;AACf,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,UAAU,CAAC,SAAkB;IAC5C,OAAO,gBAAgB,CAAC,GAAG,CAAC,SAAqB,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAc;IAClD,MAAM,MAAM,GAAG,gBAAgB,CAAC,GAAG,CAAC,KAAiB,CAAC,CAAC;IACvD,OAAO,MAAM,EAAE,MAAM,CAAC;AACvB,CAAC;AAoBD,6EAA6E;AAC7E,SAAS,UAAU,CAAC,KAAqB;IACxC,OAAQ,KAAgC,CAAC,UAAU,KAAK,SAAS,CAAC;AACnE,CAAC;AAED;;;;GAIG;AACH,MAAM,OAAO,cAAc;IA2B1B;;;;;;;OAOG;IACH,YACiB,IAAc,EACd,MAAsB,EACtC,SAAoB,EACH,cAAuB;QAHxB,SAAI,GAAJ,IAAI,CAAU;QACd,WAAM,GAAN,MAAM,CAAgB;QAErB,mBAAc,GAAd,cAAc,CAAS;QAtCjC,aAAQ,GAAG,KAAK,CAAC;QAEzB;;;;;;;;;WASG;QACI,qBAAgB,GAAW,CAAC,CAAC;QAEpC,iDAAgC;QAEhC;;;;;;;WAOG;QACM,8CAAgC;QAgBxC,kBAAkB,CAAC,SAAS,CAAC,CAAC;QAE9B,MAAM,CAAC,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,0CAA0C,CAAC,CAAC;QACtF,gBAAgB,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAEjC,IAAI,SAAS,YAAY,sBAAsB,EAAE,CAAC;YACjD,kBAAkB;YAElB,WAAW,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC;YACpD,SAAS,CAAC,QAAQ,GAAG,IAAI,CAAC;YAE1B,uBAAA,IAAI,kCAAmB;gBACtB,SAAS;aACT,MAAA,CAAC;YAEF,uBAAA,IAAI,+BAAgB,IAAI,iBAAiB,CAAC,SAAS,CAAC,MAAM,CAAC,MAAA,CAAC;QAC7D,CAAC;aAAM,CAAC;YACP,gBAAgB;YAChB,uBAAA,IAAI,kCAAmB,IAAI,CAAC,mBAAmB,CAAC,SAAS,CAAC,UAAU,CAAC,MAAA,CAAC;YACtE,uBAAA,IAAI,sCAAgB,CAAC,SAAS,GAAG,SAAS,CAAC;YAE3C,uBAAA,IAAI,+BAAgB,IAAI,iBAAiB,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,MAAA,CAAC;QACxE,CAAC;IACF,CAAC;IAED,IAAW,OAAO;QACjB,IAAI,UAAU,CAAC,uBAAA,IAAI,sCAAgB,CAAC,EAAE,CAAC;YACtC,wIAAwI;YACxI,OAAO,CACN,uBAAA,IAAI,sCAAgB,EAAE,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC;gBACvE,IAAI,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAC7C,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC,cAAc,CAAC;IAC5B,CAAC;IAED;;;;;;OAMG;IACI,OAAO,CAAC,OAAkB,EAAE,IAAY;QAC9C,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACnE,MAAM,CAAC,CAAC,UAAU,CAAC,uBAAA,IAAI,sCAAgB,CAAC,EAAE,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAEzF,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,UAAU,GACf,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAEhF,uBAAA,IAAI,kCAAmB,IAAI,CAAC,mBAAmB,CAAC,UAAU,CAAC,MAAA,CAAC;QAC5D,uBAAA,IAAI,sCAAgB,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QAErE,6DAA6D;QAC7D,uBAAA,IAAI,mCAAa,CAAC,kBAAkB,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IACzD,CAAC;IAEO,mBAAmB,CAAC,UAAsB;QACjD,MAAM,CACL,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAkB,CAAC,EACzC,KAAK,CAAC,mEAAmE,CACzE,CAAC;QACF,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACpD,OAAO;YACN,UAAU;YACV,aAAa,EAAE,IAAI,GAAG,CAAC;gBACtB,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,cAAc,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBAC1D,sEAAsE;gBACtE,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE;oBAC7C,IAAI,CAAC,gBAAgB,IAAI,CAAC,CAAC;gBAC5B,CAAC,CAAC;aACF,CAAC;SACF,CAAC;IACH,CAAC;IAEM,SAAS;QACf,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,OAAO,UAAU,CAAC,OAAO,CAAC;QAC3B,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,uBAAA,IAAI,sCAAgB,CAAC,EAAE,CAAC;YACvC,OAAO,UAAU,CAAC,GAAG,CAAC;QACvB,CAAC;QAED,qHAAqH;QACrH,MAAM,IAAI,GAAG,uBAAA,IAAI,sCAAgB,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QACrE,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACxB,MAAM,CAAC,IAAI,YAAY,UAAU,EAAE,KAAK,CAAC,yCAAyC,CAAC,CAAC;YACpF,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;gBACpB,OAAO,UAAU,CAAC,OAAO,CAAC;YAC3B,CAAC;QACF,CAAC;QAED,OAAO,yBAAyB,CAAC,uBAAA,IAAI,sCAAgB,CAAC,UAAU,CAAC,CAAC;IACnE,CAAC;IAED,IAAW,MAAM;QAChB,OAAO,uBAAA,IAAI,mCAAa,CAAC;IAC1B,CAAC;IAEM,OAAO;QACb,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,IAAI,gCAAgC,CAAC,CAAC;QACtE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,UAAU,CAAC,uBAAA,IAAI,sCAAgB,CAAC,EAAE,CAAC;YACtC,KAAK,MAAM,GAAG,IAAI,uBAAA,IAAI,sCAAgB,CAAC,aAAa,EAAE,CAAC;gBACtD,GAAG,EAAE,CAAC;YACP,CAAC;QACF,CAAC;QACD,uBAAA,IAAI,mCAAa,CAAC,OAAO,EAAE,CAAC;QAC5B,6DAA6D;IAC9D,CAAC;IAEM,UAAU;QAChB,OAAO,UAAU,CAAC,uBAAA,IAAI,sCAAgB,CAAC,CAAC;IACzC,CAAC;IAED,IAAW,UAAU;QACpB,OAAO,UAAU,CAAC,uBAAA,IAAI,sCAAgB,CAAC,CAAC,CAAC,CAAC,uBAAA,IAAI,sCAAgB,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;IACvF,CAAC;IAED;;;;;;;;;OASG;IACI,oBAAoB;QAC1B,IAAI,CAAC,UAAU,CAAC,uBAAA,IAAI,sCAAgB,CAAC,EAAE,CAAC;YACvC,WAAW,CACV,GAAG,EAAE,CACJ,uBAAA,IAAI,sCAAgB,CAAC,SAAS,EAAE,OAAO,CAAC,UAAU,EAAE,KAAK,KAAK;gBAC9D,0CAA0C,CAC3C,CAAC;YACF,OAAO,uBAAA,IAAI,sCAAgB,CAAC,SAAS,CAAC,CAAC,kBAAkB;QAC1D,CAAC;QAED,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,MAAM,IAAI,UAAU,CAAC,+BAA+B,CAAC,CAAC;QACvD,CAAC;QAED,IAAI,uBAAA,IAAI,sCAAgB,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YAClD,2BAA2B;YAC3B,MAAM,UAAU,GAAG,uBAAA,IAAI,sCAAgB,CAAC,UAAU,CAAC;YACnD,+FAA+F;YAC/F,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YACpD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;gBAC5B,6CAA6C;gBAC7C,uBAAA,IAAI,sCAAgB,CAAC,SAAS,GAAG,QAAQ,CAAC;YAC3C,CAAC;iBAAM,CAAC;gBACP,8CAA8C;gBAC9C,MAAM,OAAO,GACZ,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;gBAClF,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;gBACrE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;gBAC7D,uBAAA,IAAI,sCAAgB,CAAC,SAAS,GAAG,+BAA+B,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;gBAClF,MAAM,CAAC,IAAI,EAAE,CAAC;gBACd,4BAA4B,CAAC,uBAAA,IAAI,sCAAgB,CAAC,SAAS,CAAC,CAAC;YAC9D,CAAC;QACF,CAAC;QAED,OAAO,uBAAA,IAAI,sCAAgB,CAAC,SAAS,CAAC;IACvC,CAAC;IAED;;OAEG;IACI,wBAAwB;QAC9B,IAAI,UAAU,CAAC,uBAAA,IAAI,sCAAgB,CAAC,EAAE,CAAC;YACtC,OAAO,SAAS,CAAC;QAClB,CAAC;QACD,OAAO,uBAAA,IAAI,sCAAgB,CAAC,SAAS,CAAC;IACvC,CAAC;CACD;;AAED,MAAM,YAAY,GAAG,CAAC,2BAA2B,EAAE,0BAA0B,CAAU,CAAC;AAIxF,8BAA8B;AAE9B;;GAEG;AACH,IAAI,gBAAgB,GAAY,KAAK,CAAC;AAEtC;;;;;;;;;GASG;AACH,MAAM,UAAU,sBAAsB,CAAC,QAAoB;IAC1D,IAAI,gBAAgB,EAAE,CAAC;QACtB,4CAA4C;QAC5C,QAAQ,EAAE,CAAC;IACZ,CAAC;SAAM,CAAC;QACP,gBAAgB,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC;YACJ,QAAQ,EAAE,CAAC;QACZ,CAAC;gBAAS,CAAC;YACV,gBAAgB,GAAG,KAAK,CAAC;YACzB,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAClC,CAAC;IACF,CAAC;AACF,CAAC;AAED;;GAEG;AACH,MAAM,kBAAkB,GAAG,aAAa,EAEpC,CAAC;AAEL;;;GAGG;AACH,MAAM,iBAAiB;IA6BtB;IACC;;;;OAIG;IACH,WAAkE;;QAlCnE,sCAAqB,KAAK,EAAC;QAE3B;;WAEG;QACM,oDAA0B,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACtE,IAAI,CAAC,KAAK,EAAE,CAAC;QACd,CAAC,CAAC,EAAC;QAEM,oCAAU,aAAa,EAAgB,EAAC;QAEjD,iDAAoE;QACpE,oDAAwD,IAAI,GAAG,EAAE,EAAC;QAElE;;;;WAIG;QACM,mDAAwC,IAAI,GAAG,EAAE,EAAC;QAE3D;;;;WAIG;QACH,kDAAiC,KAAK,EAAC;QAUtC,uBAAA,IAAI,kCAAgB,WAAW,MAAA,CAAC;IACjC,CAAC;IAED;;;;;;OAMG;IACI,kBAAkB,CACxB,SAAgE;QAEhE,kCAAkC;QAClC,uBAAA,IAAI,iDAAwB,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;QACrD,uBAAA,IAAI,iDAAwB,CAAC,KAAK,EAAE,CAAC;QAErC,uBAAA,IAAI,kCAAgB,SAAS,MAAA,CAAC;QAE9B,IAAI,uBAAA,IAAI,iCAAQ,CAAC,YAAY,CAAC,2BAA2B,CAAC,EAAE,CAAC;YAC5D,MAAM,GAAG,GAAG,uBAAA,IAAI,sCAAa,CAAC,EAAE,CAAC,2BAA2B,EAAE,CAAC,EAAE,aAAa,EAAE,EAAE,EAAE,CACnF,uBAAA,IAAI,6DAAM,MAAV,IAAI,EAAO,2BAA2B,EAAE,EAAE,aAAa,EAAE,CAAC,CAC1D,CAAC;YACF,uBAAA,IAAI,iDAAwB,CAAC,GAAG,CAAC,2BAA2B,EAAE,GAAG,CAAC,CAAC;QACpE,CAAC;QACD,IAAI,uBAAA,IAAI,iCAAQ,CAAC,YAAY,CAAC,0BAA0B,CAAC,EAAE,CAAC;YAC3D,MAAM,GAAG,GAAG,uBAAA,IAAI,sCAAa,CAAC,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE,CACjE,uBAAA,IAAI,6DAAM,MAAV,IAAI,EAAO,0BAA0B,CAAC,CACtC,CAAC;YACF,uBAAA,IAAI,iDAAwB,CAAC,GAAG,CAAC,0BAA0B,EAAE,GAAG,CAAC,CAAC;QACnE,CAAC;IACF,CAAC;IAEM,EAAE,CAAC,SAA6B,EAAE,QAAwC;QAChF,6CAA6C;QAC7C,+FAA+F;QAC/F,IAAI,CAAC,uBAAA,IAAI,iCAAQ,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3C,MAAM,CACL,CAAC,uBAAA,IAAI,iDAAwB,CAAC,GAAG,CAAC,SAAS,CAAC,EAC5C,sDAAsD,CACtD,CAAC;YAEF,MAAM,GAAG,GAAG,uBAAA,IAAI,sCAAa,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,uBAAA,IAAI,6DAAM,MAAV,IAAI,EAAO,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC;YACnF,uBAAA,IAAI,iDAAwB,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QAClD,CAAC;QAED,uBAAA,IAAI,iCAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QACrC,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAC5C,CAAC;IAEM,GAAG,CAAC,SAA6B,EAAE,QAAwC;QACjF,uBAAA,IAAI,iCAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QAEtC,4EAA4E;QAC5E,IAAI,CAAC,uBAAA,IAAI,iCAAQ,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3C,MAAM,GAAG,GAAG,uBAAA,IAAI,iDAAwB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACxD,GAAG,EAAE,EAAE,CAAC;YACR,uBAAA,IAAI,iDAAwB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAChD,CAAC;IACF,CAAC;IAsCD;;OAEG;IACI,KAAK;QACX,uBAAA,IAAI,0EAAmB,MAAvB,IAAI,CAAqB,CAAC;QAE1B,IAAI,uBAAA,IAAI,gDAAuB,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YAC1C,uBAAA,IAAI,iCAAQ,CAAC,IAAI,CAAC,2BAA2B,EAAE;gBAC9C,aAAa,EAAE,uBAAA,IAAI,gDAAuB;aAC1C,CAAC,CAAC;YACH,uBAAA,IAAI,gDAAuB,CAAC,KAAK,EAAE,CAAC;QACrC,CAAC;QAED,IAAI,uBAAA,IAAI,+CAAsB,EAAE,CAAC;YAChC,uBAAA,IAAI,iCAAQ,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;YAC9C,uBAAA,IAAI,2CAAyB,KAAK,MAAA,CAAC;QACpC,CAAC;IACF,CAAC;IAMM,OAAO;QACb,IAAI,uBAAA,IAAI,mCAAU,EAAE,CAAC;YACpB,OAAO;QACR,CAAC;QAED,MAAM,CACL,uBAAA,IAAI,gDAAuB,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,uBAAA,IAAI,+CAAsB,EACrE,mEAAmE,CACnE,CAAC;QAEF,uBAAA,IAAI,iDAAwB,MAA5B,IAAI,CAA0B,CAAC;QAC/B,uBAAA,IAAI,iDAAwB,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;QACrD,uBAAA,IAAI,iDAAwB,CAAC,KAAK,EAAE,CAAC;QAErC,uBAAA,IAAI,gDAAuB,CAAC,KAAK,EAAE,CAAC;QACpC,uBAAA,IAAI,2CAAyB,KAAK,MAAA,CAAC;QAEnC,uBAAA,IAAI,+BAAa,IAAI,MAAA,CAAC;IACvB,CAAC;CACD;0dA7EC,SAA6B,EAC7B,GAEC;IAED,uBAAA,IAAI,0EAAmB,MAAvB,IAAI,CAAqB,CAAC;IAC1B,QAAQ,SAAS,EAAE,CAAC;QACnB,KAAK,2BAA2B;YAC/B,MAAM,CAAC,GAAG,KAAK,SAAS,EAAE,2CAA2C,CAAC,CAAC;YACvE,OAAO,uBAAA,IAAI,wFAAiC,MAArC,IAAI,EAAkC,GAAG,CAAC,aAAa,CAAC,CAAC;QACjE,KAAK,0BAA0B;YAC9B,OAAO,uBAAA,IAAI,uFAAgC,MAApC,IAAI,CAAkC,CAAC;QAC/C;YACC,eAAe,CAAC,SAAS,CAAC,CAAC;IAC7B,CAAC;AACF,CAAC,mHAEgC,aAAoC;IACpE,IAAI,gBAAgB,EAAE,CAAC;QACtB,KAAK,MAAM,QAAQ,IAAI,aAAa,EAAE,CAAC;YACtC,uBAAA,IAAI,gDAAuB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC3C,CAAC;IACF,CAAC;SAAM,CAAC;QACP,uBAAA,IAAI,iCAAQ,CAAC,IAAI,CAAC,2BAA2B,EAAE,EAAE,aAAa,EAAE,CAAC,CAAC;IACnE,CAAC;AACF,CAAC;IAGA,IAAI,gBAAgB,EAAE,CAAC;QACtB,uBAAA,IAAI,2CAAyB,IAAI,MAAA,CAAC;IACnC,CAAC;SAAM,CAAC;QACP,uBAAA,IAAI,iCAAQ,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IAC/C,CAAC;AACF,CAAC;IAsBA,MAAM,CAAC,CAAC,uBAAA,IAAI,mCAAU,EAAE,yBAAyB,CAAC,CAAC;AACpD,CAAC;AAiCF;;GAEG;AACH,MAAM,UAAU,kBAAkB,CACjC,SAAoB;IAEpB,MAAM,CACL,SAAS,YAAY,sBAAsB,IAAI,SAAS,CAAC,UAAU,EAAE,EACrE,KAAK,CAAC,6BAA6B,CACnC,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,UAAU,EAAY,CAAC;AAEzD;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,UAAsB;IACxD,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAC1D,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;QACnC,MAAM,CAAC,OAAO,EAAE,CAAC;QACjB,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;IAC7C,CAAC;AACF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gCAAgC,CAAC,SAAoB;IACpE,MAAM,OAAO,GAAY,6BAA6B,CAAC,SAAS,CAAC,CAAC;IAClE,OAAO,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;AAC5F,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,6BAA6B,CAAC,SAAoB;IACjE,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAC9B,IAAI,SAAS,YAAY,sBAAsB,EAAE,CAAC;QACjD,OAAO,SAAS,CAAC,aAAa,CAAC;IAChC,CAAC;IAED,MAAM,OAAO,GAAG,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAC5E,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,KAAK,CAAC,iCAAiC,CAAC,CAAC;IAEvE,OAAO,OAAO,CAAC;AAChB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,oBAAoB,CAAC,QAAkB;IACtD,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IACnC,OAAO,MAAM,CAAC,oBAAoB,EAAE,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,SAAS,kBAAkB,CAAC,UAAsB;IACjD,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACpD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC5B,OAAO,QAAQ,CAAC,CAAC,4CAA4C;IAC9D,CAAC,CAAC,8CAA8C;IAChD,MAAM,OAAO,GACZ,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;IAClF,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;IACrE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAC7D,MAAM,WAAW,GAAG,+BAA+B,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACrE,MAAM,CAAC,IAAI,EAAE,CAAC;IACd,OAAO,WAAW,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,UAAsB;IACxD,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IACxD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,MAAM,CAAC;IACf,CAAC;IAED,MAAM,QAAQ,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;IAChD,OAAO,uBAAuB,CAAC,QAAQ,CAAC,CAAC;AAC1C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,SAAoB;IAC3D,MAAM,WAAW,GAAG,gCAAgC,CAAC,SAAS,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,SAAwC,CAAC;IAC1D,OAAO,OAAO,WAAW,KAAK,UAAU;QACvC,CAAC,CAAC,IAAI,WAAW,CAAC,QAAQ,CAAC;QAC3B,CAAC,CAAE,WAAwE,CAAC,MAAM,CAChF,QAAQ,CACR,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,UAAU,EAAmB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { createEmitter } from \"@fluid-internal/client-utils\";\nimport type { HasListeners, Listenable, Off } from \"@fluidframework/core-interfaces/internal\";\nimport {\n\tassert,\n\tfail,\n\tdebugAssert,\n\tunreachableCase,\n} from \"@fluidframework/core-utils/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport {\n\tanchorSlot,\n\ttype AnchorEvents,\n\ttype AnchorNode,\n\ttype AnchorSet,\n\ttype FieldKey,\n\ttype TreeValue,\n\ttype UpPath,\n} from \"../../core/index.js\";\nimport { getOrCreateHydratedFlexTreeNode } from \"../../feature-libraries/index.js\";\nimport {\n\tassertFlexTreeEntityNotFreed,\n\tContextSlot,\n\tflexTreeSlot,\n\tLazyEntity,\n\tTreeStatus,\n\ttreeStatusFromAnchorCache,\n\ttype FlexTreeNode,\n\ttype HydratedFlexTreeNode,\n} from \"../../feature-libraries/index.js\";\n\nimport type { Context, HydratedContext } from \"./context.js\";\nimport type { TreeNode } from \"./treeNode.js\";\nimport type { TreeNodeSchema } from \"./treeNodeSchema.js\";\nimport type { InternalTreeNode, Unhydrated } from \"./types.js\";\nimport { UnhydratedFlexTreeNode } from \"./unhydratedFlexTree.js\";\n\nconst treeNodeToKernel = new WeakMap<TreeNode, TreeNodeKernel>();\n\nexport function getKernel(node: TreeNode): TreeNodeKernel {\n\tconst kernel = treeNodeToKernel.get(node);\n\tassert(kernel !== undefined, 0x9b1 /* Expected tree node to have kernel */);\n\treturn kernel;\n}\n\n/**\n * Detects if the given 'candidate' is a TreeNode.\n *\n * @remarks\n * Supports both Hydrated and {@link Unhydrated} TreeNodes, both of which return true.\n *\n * Because the common usage is to check if a value being inserted/set is a TreeNode,\n * this function permits calling with primitives as well as objects.\n *\n * Primitives will always return false (as they are copies of data, not references to nodes).\n *\n * @param candidate - Value which may be a TreeNode\n * @returns true if the given 'candidate' is a hydrated TreeNode.\n */\nexport function isTreeNode(candidate: unknown): candidate is TreeNode | Unhydrated<TreeNode> {\n\treturn treeNodeToKernel.has(candidate as TreeNode);\n}\n\n/**\n * Returns a schema for a value if the value is a {@link TreeNode}.\n *\n * Returns undefined for other values.\n * @remarks\n * Does not give schema for a {@link TreeLeafValue}.\n */\nexport function tryGetTreeNodeSchema(value: unknown): undefined | TreeNodeSchema {\n\tconst kernel = treeNodeToKernel.get(value as TreeNode);\n\treturn kernel?.schema;\n}\n\n/** The {@link HydrationState} of a {@link TreeNodeKernel} before the kernel is hydrated */\ninterface UnhydratedState {\n\treadonly innerNode: UnhydratedFlexTreeNode;\n}\n\n/** The {@link HydrationState} of a {@link TreeNodeKernel} after the kernel is hydrated */\ninterface HydratedState {\n\t/** The flex node for this kernel (lazy - undefined if it has not yet been demanded) */\n\tinnerNode?: FlexTreeNode;\n\t/** The {@link AnchorNode} that this node is associated with. */\n\treadonly anchorNode: AnchorNode;\n\t/** All {@link Off | event deregistration functions} that should be run when the kernel is disposed. */\n\treadonly offAnchorNode: Set<Off>;\n}\n\n/** State within a {@link TreeNodeKernel} that is related to the hydration process */\ntype HydrationState = UnhydratedState | HydratedState;\n\n/** True if and only if the given {@link HydrationState} is post-hydration */\nfunction isHydrated(state: HydrationState): state is HydratedState {\n\treturn (state as Partial<HydratedState>).anchorNode !== undefined;\n}\n\n/**\n * Contains state and an internal API for managing {@link TreeNode}s.\n * @remarks All {@link TreeNode}s have an associated kernel object.\n * The kernel has the same lifetime as the node and spans both its unhydrated and hydrated states.\n */\nexport class TreeNodeKernel {\n\tprivate disposed = false;\n\n\t/**\n\t * Generation number which is incremented any time we have an edit on the node.\n\t * Used during iteration to make sure there has been no edits that were concurrently made.\n\t * @remarks\n\t * This is updated monotonically by this class when edits are applied.\n\t * TODO: update this when applying edits to unhydrated trees.\n\t *\n\t * If TypeScript supported making this immutable from outside the class without making it readonly from inside, that would be used here,\n\t * but they only way to do that is add a separate public accessor and make it private, which was deemed not worth the boilerplate, runtime overhead and bundle size.\n\t */\n\tpublic generationNumber: number = 0;\n\n\t#hydrationState: HydrationState;\n\n\t/**\n\t * Events registered before hydration.\n\t * @remarks\n\t * Since these are usually not used, they are allocated lazily as an optimization.\n\t * The laziness also avoids extra forwarding overhead for events from this kernel's anchor node and also avoids registering for events that are unneeded.\n\t * This means optimizations like skipping processing data in subtrees where no subtreeChanged events are subscribed to would be able to work,\n\t * since the kernel does not unconditionally subscribe to those events (like a design which simply forwards all events would).\n\t */\n\treadonly #eventBuffer: KernelEventBuffer;\n\n\t/**\n\t * Create a TreeNodeKernel which can be looked up with {@link getKernel}.\n\t *\n\t * @param initialContext - context from when this node was originally created. Only used when unhydrated.\n\t * @param innerNode - When unhydrated/raw or marinated the MapTreeNode. FlexTreeNode when cooked.\n\t * @remarks\n\t * Exactly one kernel per TreeNode should be created.\n\t */\n\tpublic constructor(\n\t\tpublic readonly node: TreeNode,\n\t\tpublic readonly schema: TreeNodeSchema,\n\t\tinnerNode: InnerNode,\n\t\tprivate readonly initialContext: Context,\n\t) {\n\t\tsplitInnerNodeType(innerNode);\n\n\t\tassert(!treeNodeToKernel.has(node), 0xa1a /* only one kernel per node can be made */);\n\t\ttreeNodeToKernel.set(node, this);\n\n\t\tif (innerNode instanceof UnhydratedFlexTreeNode) {\n\t\t\t// Unhydrated case\n\n\t\t\tdebugAssert(() => innerNode.treeNode === undefined);\n\t\t\tinnerNode.treeNode = node;\n\n\t\t\tthis.#hydrationState = {\n\t\t\t\tinnerNode,\n\t\t\t};\n\n\t\t\tthis.#eventBuffer = new KernelEventBuffer(innerNode.events);\n\t\t} else {\n\t\t\t// Hydrated case\n\t\t\tthis.#hydrationState = this.createHydratedState(innerNode.anchorNode);\n\t\t\tthis.#hydrationState.innerNode = innerNode;\n\n\t\t\tthis.#eventBuffer = new KernelEventBuffer(innerNode.anchorNode.events);\n\t\t}\n\t}\n\n\tpublic get context(): Context {\n\t\tif (isHydrated(this.#hydrationState)) {\n\t\t\t// This can't be cached on this.#hydrated during hydration since initial tree is hydrated before the context is cached on the anchorSet.\n\t\t\treturn (\n\t\t\t\tthis.#hydrationState?.anchorNode.anchorSet.slots.get(SimpleContextSlot) ??\n\t\t\t\tfail(0xb40 /* missing simple-tree context */)\n\t\t\t);\n\t\t}\n\t\treturn this.initialContext;\n\t}\n\n\t/**\n\t * Transition from {@link Unhydrated} to hydrated.\n\t * Bi-directionally associates the given hydrated TreeNode to the anchor node at the provided path.\n\t * @remarks\n\t * Happens at most once for any given node.\n\t * Cleans up mappings to {@link UnhydratedFlexTreeNode} - it is assumed that they are no longer needed once this node has an anchor node.\n\t */\n\tpublic hydrate(anchors: AnchorSet, path: UpPath): void {\n\t\tassert(!this.disposed, 0xa2a /* cannot hydrate a disposed node */);\n\t\tassert(!isHydrated(this.#hydrationState), 0xa2b /* hydration should only happen once */);\n\n\t\tconst anchor = anchors.track(path);\n\t\tconst anchorNode =\n\t\t\tanchors.locate(anchor) ?? fail(0xb42 /* Expected anchor node to be present */);\n\n\t\tthis.#hydrationState = this.createHydratedState(anchorNode);\n\t\tthis.#hydrationState.offAnchorNode.add(() => anchors.forget(anchor));\n\n\t\t// Lazily migrate existing event listeners to the anchor node\n\t\tthis.#eventBuffer.migrateEventSource(anchorNode.events);\n\t}\n\n\tprivate createHydratedState(anchorNode: AnchorNode): HydratedState {\n\t\tassert(\n\t\t\t!anchorNode.slots.has(simpleTreeNodeSlot),\n\t\t\t0x7f5 /* Cannot associate an flex node with multiple simple-tree nodes */,\n\t\t);\n\t\tanchorNode.slots.set(simpleTreeNodeSlot, this.node);\n\t\treturn {\n\t\t\tanchorNode,\n\t\t\toffAnchorNode: new Set([\n\t\t\t\tanchorNode.events.on(\"afterDestroy\", () => this.dispose()),\n\t\t\t\t// TODO: this should be triggered on change even for unhydrated nodes.\n\t\t\t\tanchorNode.events.on(\"childrenChanging\", () => {\n\t\t\t\t\tthis.generationNumber += 1;\n\t\t\t\t}),\n\t\t\t]),\n\t\t};\n\t}\n\n\tpublic getStatus(): TreeStatus {\n\t\tif (this.disposed) {\n\t\t\treturn TreeStatus.Deleted;\n\t\t}\n\t\tif (!isHydrated(this.#hydrationState)) {\n\t\t\treturn TreeStatus.New;\n\t\t}\n\n\t\t// TODO: Replace this check with the proper check against the cursor state when the cursor becomes part of the kernel\n\t\tconst flex = this.#hydrationState.anchorNode.slots.get(flexTreeSlot);\n\t\tif (flex !== undefined) {\n\t\t\tassert(flex instanceof LazyEntity, 0x9b4 /* Unexpected flex node implementation */);\n\t\t\tif (flex.isFreed()) {\n\t\t\t\treturn TreeStatus.Deleted;\n\t\t\t}\n\t\t}\n\n\t\treturn treeStatusFromAnchorCache(this.#hydrationState.anchorNode);\n\t}\n\n\tpublic get events(): Listenable<KernelEvents> {\n\t\treturn this.#eventBuffer;\n\t}\n\n\tpublic dispose(): void {\n\t\tdebugAssert(() => !this.disposed || \"Cannot dispose a disposed node\");\n\t\tthis.disposed = true;\n\t\tif (isHydrated(this.#hydrationState)) {\n\t\t\tfor (const off of this.#hydrationState.offAnchorNode) {\n\t\t\t\toff();\n\t\t\t}\n\t\t}\n\t\tthis.#eventBuffer.dispose();\n\t\t// TODO: go to the context and remove myself from withAnchors\n\t}\n\n\tpublic isHydrated(): this is { anchorNode: AnchorNode; context: HydratedContext } {\n\t\treturn isHydrated(this.#hydrationState);\n\t}\n\n\tpublic get anchorNode(): AnchorNode | undefined {\n\t\treturn isHydrated(this.#hydrationState) ? this.#hydrationState.anchorNode : undefined;\n\t}\n\n\t/**\n\t * Retrieves the flex node associated with the given target.\n\t * @remarks\n\t * For {@link Unhydrated} nodes, this returns the MapTreeNode.\n\t *\n\t * For hydrated nodes it returns a FlexTreeNode backed by the forest.\n\t * Note that for \"marinated\" nodes, this FlexTreeNode exists and returns it: it does not return the MapTreeNode which is the current InnerNode.\n\t *\n\t * @throws A {@link @fluidframework/telemetry-utils#UsageError} if the node has been deleted.\n\t */\n\tpublic getOrCreateInnerNode(): InnerNode {\n\t\tif (!isHydrated(this.#hydrationState)) {\n\t\t\tdebugAssert(\n\t\t\t\t() =>\n\t\t\t\t\tthis.#hydrationState.innerNode?.context.isDisposed() === false ||\n\t\t\t\t\t\"Unhydrated node should never be disposed\",\n\t\t\t);\n\t\t\treturn this.#hydrationState.innerNode; // Unhydrated case\n\t\t}\n\n\t\tif (this.disposed) {\n\t\t\tthrow new UsageError(\"Cannot access a deleted node.\");\n\t\t}\n\n\t\tif (this.#hydrationState.innerNode === undefined) {\n\t\t\t// Marinated case -> cooked\n\t\t\tconst anchorNode = this.#hydrationState.anchorNode;\n\t\t\t// This TreeNode is bound to an anchor node, but it may or may not have an actual flex node yet\n\t\t\tconst flexNode = anchorNode.slots.get(flexTreeSlot);\n\t\t\tif (flexNode !== undefined) {\n\t\t\t\t// If the flex node already exists, use it...\n\t\t\t\tthis.#hydrationState.innerNode = flexNode;\n\t\t\t} else {\n\t\t\t\t// ...otherwise, the flex node must be created\n\t\t\t\tconst context =\n\t\t\t\t\tanchorNode.anchorSet.slots.get(ContextSlot) ?? fail(0xb41 /* missing context */);\n\t\t\t\tconst cursor = context.checkout.forest.allocateCursor(\"getFlexNode\");\n\t\t\t\tcontext.checkout.forest.moveCursorToPath(anchorNode, cursor);\n\t\t\t\tthis.#hydrationState.innerNode = getOrCreateHydratedFlexTreeNode(context, cursor);\n\t\t\t\tcursor.free();\n\t\t\t\tassertFlexTreeEntityNotFreed(this.#hydrationState.innerNode);\n\t\t\t}\n\t\t}\n\n\t\treturn this.#hydrationState.innerNode;\n\t}\n\n\t/**\n\t * Retrieves the {@link UnhydratedFlexTreeNode} if unhydrated. otherwise undefined.\n\t */\n\tpublic getInnerNodeIfUnhydrated(): UnhydratedFlexTreeNode | undefined {\n\t\tif (isHydrated(this.#hydrationState)) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn this.#hydrationState.innerNode;\n\t}\n}\n\nconst kernelEvents = [\"childrenChangedAfterBatch\", \"subtreeChangedAfterBatch\"] as const;\n\ntype KernelEvents = Pick<AnchorEvents, (typeof kernelEvents)[number]>;\n\n// #region TreeNodeEventBuffer\n\n/**\n * Whether or not events from {@link TreeNodeKernel} should be buffered instead of emitted immediately.\n */\nlet bufferTreeEvents: boolean = false;\n\n/**\n * Call the provided callback with {@link TreeNode}s' events paused until after the callback's completion.\n *\n * Events that would otherwise have been emitted immediately are merged and buffered until after the\n * provided callback has been completed.\n *\n * @remarks\n * Note: this should be used with caution. User application behaviors are implicitly coupled to event timing.\n * Disrupting this timing can lead to unexpected behavior.\n */\nexport function withBufferedTreeEvents(callback: () => void): void {\n\tif (bufferTreeEvents) {\n\t\t// Already buffering - just run the callback\n\t\tcallback();\n\t} else {\n\t\tbufferTreeEvents = true;\n\t\ttry {\n\t\t\tcallback();\n\t\t} finally {\n\t\t\tbufferTreeEvents = false;\n\t\t\tflushEventsEmitter.emit(\"flush\");\n\t\t}\n\t}\n}\n\n/**\n * Event emitter to notify subscribers when tree events buffered due to {@link withBufferedTreeEvents} should be flushed.\n */\nconst flushEventsEmitter = createEmitter<{\n\tflush: () => void;\n}>();\n\n/**\n * Event emitter for {@link TreeNodeKernel}, which optionally buffers events based on {@link bufferTreeEvents}.\n * @remarks Listens to {@link flushEventsEmitter} to know when to flush any buffered events.\n */\nclass KernelEventBuffer implements Listenable<KernelEvents> {\n\t#disposed: boolean = false;\n\n\t/**\n\t * Listen to {@link flushEventsEmitter} to know when to flush buffered events.\n\t */\n\treadonly #disposeOnFlushListener = flushEventsEmitter.on(\"flush\", () => {\n\t\tthis.flush();\n\t});\n\n\treadonly #events = createEmitter<KernelEvents>();\n\n\t#eventSource: Listenable<KernelEvents> & HasListeners<KernelEvents>;\n\t#disposeSourceListeners: Map<keyof KernelEvents, Off> = new Map();\n\n\t/**\n\t * Buffer of fields that have changed since events were paused.\n\t * When events are flushed, a single {@link AnchorEvents.childrenChangedAfterBatch} event will be emitted\n\t * containing the accumulated set of changed fields.\n\t */\n\treadonly #childrenChangedBuffer: Set<FieldKey> = new Set();\n\n\t/**\n\t * Whether or not the subtree has changed since events were paused.\n\t * When events are flushed, a single {@link AnchorEvents.subTreeChanged} event will be emitted if and only\n\t * if the subtree has changed.\n\t */\n\t#subTreeChangedBuffer: boolean = false;\n\n\tpublic constructor(\n\t\t/**\n\t\t * Source of the kernel events.\n\t\t * Subscriptions will be created on-demand when listeners are added to this.events,\n\t\t * and those subscriptions will be cleaned up when all corresponding listeners have been removed.\n\t\t */\n\t\teventSource: Listenable<KernelEvents> & HasListeners<KernelEvents>,\n\t) {\n\t\tthis.#eventSource = eventSource;\n\t}\n\n\t/**\n\t * Migrate this event buffer to a new event source.\n\t *\n\t * @remarks\n\t * Cleans up any existing event subscriptions from the old source.\n\t * Binds events to the new source for each event with active listeners.\n\t */\n\tpublic migrateEventSource(\n\t\tnewSource: Listenable<KernelEvents> & HasListeners<KernelEvents>,\n\t): void {\n\t\t// Unsubscribe from the old source\n\t\tthis.#disposeSourceListeners.forEach((off) => off());\n\t\tthis.#disposeSourceListeners.clear();\n\n\t\tthis.#eventSource = newSource;\n\n\t\tif (this.#events.hasListeners(\"childrenChangedAfterBatch\")) {\n\t\t\tconst off = this.#eventSource.on(\"childrenChangedAfterBatch\", ({ changedFields }) =>\n\t\t\t\tthis.#emit(\"childrenChangedAfterBatch\", { changedFields }),\n\t\t\t);\n\t\t\tthis.#disposeSourceListeners.set(\"childrenChangedAfterBatch\", off);\n\t\t}\n\t\tif (this.#events.hasListeners(\"subtreeChangedAfterBatch\")) {\n\t\t\tconst off = this.#eventSource.on(\"subtreeChangedAfterBatch\", () =>\n\t\t\t\tthis.#emit(\"subtreeChangedAfterBatch\"),\n\t\t\t);\n\t\t\tthis.#disposeSourceListeners.set(\"subtreeChangedAfterBatch\", off);\n\t\t}\n\t}\n\n\tpublic on(eventName: keyof KernelEvents, listener: KernelEvents[typeof eventName]): Off {\n\t\t// Lazily bind event listeners to the source.\n\t\t// If we do not have any existing listeners for this event, then we need to bind to the source.\n\t\tif (!this.#events.hasListeners(eventName)) {\n\t\t\tassert(\n\t\t\t\t!this.#disposeSourceListeners.has(eventName),\n\t\t\t\t\"Should not have a dispose function without listeners\",\n\t\t\t);\n\n\t\t\tconst off = this.#eventSource.on(eventName, (args) => this.#emit(eventName, args));\n\t\t\tthis.#disposeSourceListeners.set(eventName, off);\n\t\t}\n\n\t\tthis.#events.on(eventName, listener);\n\t\treturn () => this.off(eventName, listener);\n\t}\n\n\tpublic off(eventName: keyof KernelEvents, listener: KernelEvents[typeof eventName]): void {\n\t\tthis.#events.off(eventName, listener);\n\n\t\t// If there are no remaining listeners for the event, unbind from the source\n\t\tif (!this.#events.hasListeners(eventName)) {\n\t\t\tconst off = this.#disposeSourceListeners.get(eventName);\n\t\t\toff?.();\n\t\t\tthis.#disposeSourceListeners.delete(eventName);\n\t\t}\n\t}\n\n\t#emit(\n\t\teventName: keyof KernelEvents,\n\t\targ?: {\n\t\t\tchangedFields: ReadonlySet<FieldKey>;\n\t\t},\n\t): void {\n\t\tthis.#assertNotDisposed();\n\t\tswitch (eventName) {\n\t\t\tcase \"childrenChangedAfterBatch\":\n\t\t\t\tassert(arg !== undefined, \"childrenChangedAfterBatch should have arg\");\n\t\t\t\treturn this.#handleChildrenChangedAfterBatch(arg.changedFields);\n\t\t\tcase \"subtreeChangedAfterBatch\":\n\t\t\t\treturn this.#handleSubtreeChangedAfterBatch();\n\t\t\tdefault:\n\t\t\t\tunreachableCase(eventName);\n\t\t}\n\t}\n\n\t#handleChildrenChangedAfterBatch(changedFields: ReadonlySet<FieldKey>): void {\n\t\tif (bufferTreeEvents) {\n\t\t\tfor (const fieldKey of changedFields) {\n\t\t\t\tthis.#childrenChangedBuffer.add(fieldKey);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.#events.emit(\"childrenChangedAfterBatch\", { changedFields });\n\t\t}\n\t}\n\n\t#handleSubtreeChangedAfterBatch(): void {\n\t\tif (bufferTreeEvents) {\n\t\t\tthis.#subTreeChangedBuffer = true;\n\t\t} else {\n\t\t\tthis.#events.emit(\"subtreeChangedAfterBatch\");\n\t\t}\n\t}\n\n\t/**\n\t * Flushes any events buffered due to {@link withBufferedTreeEvents}.\n\t */\n\tpublic flush(): void {\n\t\tthis.#assertNotDisposed();\n\n\t\tif (this.#childrenChangedBuffer.size > 0) {\n\t\t\tthis.#events.emit(\"childrenChangedAfterBatch\", {\n\t\t\t\tchangedFields: this.#childrenChangedBuffer,\n\t\t\t});\n\t\t\tthis.#childrenChangedBuffer.clear();\n\t\t}\n\n\t\tif (this.#subTreeChangedBuffer) {\n\t\t\tthis.#events.emit(\"subtreeChangedAfterBatch\");\n\t\t\tthis.#subTreeChangedBuffer = false;\n\t\t}\n\t}\n\n\t#assertNotDisposed(): void {\n\t\tassert(!this.#disposed, \"Event handler disposed.\");\n\t}\n\n\tpublic dispose(): void {\n\t\tif (this.#disposed) {\n\t\t\treturn;\n\t\t}\n\n\t\tassert(\n\t\t\tthis.#childrenChangedBuffer.size === 0 && !this.#subTreeChangedBuffer,\n\t\t\t\"Buffered kernel events should have been flushed before disposing.\",\n\t\t);\n\n\t\tthis.#disposeOnFlushListener();\n\t\tthis.#disposeSourceListeners.forEach((off) => off());\n\t\tthis.#disposeSourceListeners.clear();\n\n\t\tthis.#childrenChangedBuffer.clear();\n\t\tthis.#subTreeChangedBuffer = false;\n\n\t\tthis.#disposed = true;\n\t}\n}\n\n// #endregion\n\n/**\n * For \"cooked\" nodes this is a HydratedFlexTreeNode thats a projection of forest content.\n * For {@link Unhydrated} nodes this is a UnhydratedFlexTreeNode.\n *\n * For \"marinated\" nodes, some code (ex: getOrCreateInnerNode) returns the FlexTreeNode thats a projection of forest content, and some code (ex: tryGetInnerNode) returns undefined.\n */\nexport type InnerNode = FlexTreeNode;\n\n/**\n * Narrows innerNode to either {@link UnhydratedFlexTreeNode} or {@link HydratedFlexTreeNode}.\n */\nexport function splitInnerNodeType(\n\tinnerNode: InnerNode,\n): asserts innerNode is UnhydratedFlexTreeNode | HydratedFlexTreeNode {\n\tassert(\n\t\tinnerNode instanceof UnhydratedFlexTreeNode || innerNode.isHydrated(),\n\t\t0xbc8 /* Invalid inner node type */,\n\t);\n}\n\n/**\n * An anchor slot which associates an anchor with its corresponding {@link TreeNode}, if there is one.\n * @remarks\n * For this to work, we have to require that there is at most a single view using a given AnchorSet.\n * FlexTree already has this assumption, and we also assume there is a single simple-tree per FlexTree, so this is valid.\n */\nexport const simpleTreeNodeSlot = anchorSlot<TreeNode>();\n\n/**\n * Dispose a TreeNode (if any) for an existing anchor without disposing the anchor.\n */\nexport function tryDisposeTreeNode(anchorNode: AnchorNode): void {\n\tconst treeNode = anchorNode.slots.get(simpleTreeNodeSlot);\n\tif (treeNode !== undefined) {\n\t\tconst kernel = getKernel(treeNode);\n\t\tkernel.dispose();\n\t\tanchorNode.slots.delete(simpleTreeNodeSlot);\n\t}\n}\n\n/**\n * Gets the {@link TreeNodeSchema} for the {@link InnerNode}.\n */\nexport function getSimpleNodeSchemaFromInnerNode(innerNode: InnerNode): TreeNodeSchema {\n\tconst context: Context = getSimpleContextFromInnerNode(innerNode);\n\treturn context.schema.get(innerNode.type) ?? fail(0xb3f /* missing schema from context */);\n}\n\n/**\n * Gets the {@link Context} for the {@link InnerNode}.\n */\nexport function getSimpleContextFromInnerNode(innerNode: InnerNode): Context {\n\tsplitInnerNodeType(innerNode);\n\tif (innerNode instanceof UnhydratedFlexTreeNode) {\n\t\treturn innerNode.simpleContext;\n\t}\n\n\tconst context = innerNode.anchorNode.anchorSet.slots.get(SimpleContextSlot);\n\tassert(context !== undefined, 0xa55 /* missing simple tree context */);\n\n\treturn context;\n}\n\n/**\n * Retrieves the flex node associated with the given target.\n * @remarks\n * For {@link Unhydrated} nodes, this returns the MapTreeNode.\n *\n * For hydrated nodes it returns a FlexTreeNode backed by the forest.\n * Note that for \"marinated\" nodes, this FlexTreeNode exists and returns it: it does not return the MapTreeNode which is the current InnerNode.\n *\n * @throws A {@link @fluidframework/telemetry-utils#UsageError} if the node has been deleted.\n */\nexport function getOrCreateInnerNode(treeNode: TreeNode): InnerNode {\n\tconst kernel = getKernel(treeNode);\n\treturn kernel.getOrCreateInnerNode();\n}\n\n/**\n * Gets a flex node from an anchor node\n */\nfunction flexNodeFromAnchor(anchorNode: AnchorNode): HydratedFlexTreeNode {\n\tconst flexNode = anchorNode.slots.get(flexTreeSlot);\n\tif (flexNode !== undefined) {\n\t\treturn flexNode; // If it does have a flex node, return it...\n\t} // ...otherwise, the flex node must be created\n\tconst context =\n\t\tanchorNode.anchorSet.slots.get(ContextSlot) ?? fail(0xb45 /* missing context */);\n\tconst cursor = context.checkout.forest.allocateCursor(\"getFlexNode\");\n\tcontext.checkout.forest.moveCursorToPath(anchorNode, cursor);\n\tconst newFlexNode = getOrCreateHydratedFlexTreeNode(context, cursor);\n\tcursor.free();\n\treturn newFlexNode;\n}\n\n/**\n * Gets a tree node from an anchor node\n */\nexport function treeNodeFromAnchor(anchorNode: AnchorNode): TreeNode | TreeValue {\n\tconst cached = anchorNode.slots.get(simpleTreeNodeSlot);\n\tif (cached !== undefined) {\n\t\treturn cached;\n\t}\n\n\tconst flexNode = flexNodeFromAnchor(anchorNode);\n\treturn createTreeNodeFromInner(flexNode);\n}\n\n/**\n * Constructs a TreeNode from an InnerNode.\n * @remarks\n * This does not do caching or validation: caller must ensure duplicate nodes for a given inner node are not created, and that the inner node is valid.\n */\nexport function createTreeNodeFromInner(innerNode: InnerNode): TreeNode | TreeValue {\n\tconst classSchema = getSimpleNodeSchemaFromInnerNode(innerNode);\n\tconst internal = innerNode as unknown as InternalTreeNode;\n\treturn typeof classSchema === \"function\"\n\t\t? new classSchema(internal)\n\t\t: (classSchema as { create(data: InternalTreeNode): TreeNode | TreeValue }).create(\n\t\t\t\tinternal,\n\t\t\t);\n}\n\n/**\n * Creating multiple simple tree contexts for the same branch, and thus with the same underlying AnchorSet does not work due to how TreeNode caching works.\n * This slot is used to detect if one already exists and error if creating a second.\n * @remarks\n * See also {@link ContextSlot} in which the flex-tree context is stored.\n */\nexport const SimpleContextSlot = anchorSlot<HydratedContext>();\n"]}
@@ -2,19 +2,20 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import type { Listenable } from "@fluidframework/core-interfaces";
5
+ import type { HasListeners, Listenable } from "@fluidframework/core-interfaces/internal";
6
6
  import { type AnchorEvents, type FieldKey, type FieldKindIdentifier, type ITreeCursorSynchronous, type NodeData, type NormalizedFieldUpPath, type SchemaPolicy, type TreeNodeSchemaIdentifier, type TreeNodeStoredSchema, type TreeStoredSchema, type TreeValue, type Value } from "../../core/index.js";
7
7
  import { type FlexTreeContext, FlexTreeEntityKind, type FlexTreeField, type FlexTreeNode, type FlexTreeOptionalField, type FlexTreeSequenceField, type FlexTreeTypedField, type FlexTreeUnknownUnboxed, flexTreeMarker, type FlexTreeHydratedContext, type FlexFieldKind, type FlexibleNodeContent, type FlexTreeHydratedContextMinimal, type FlexibleFieldContent, type MapTreeFieldViewGeneric, type MapTreeNodeViewGeneric, type HydratedFlexTreeNode, type MinimalFieldMap } from "../../feature-libraries/index.js";
8
8
  import type { Context } from "./context.js";
9
9
  import type { ContextualFieldProvider } from "../fieldSchema.js";
10
10
  import type { TreeNode } from "./treeNode.js";
11
- type UnhydratedFlexTreeNodeEvents = Pick<AnchorEvents, "childrenChangedAfterBatch">;
11
+ type UnhydratedFlexTreeNodeEvents = Pick<AnchorEvents, "childrenChangedAfterBatch" | "subtreeChangedAfterBatch">;
12
12
  /** A node's parent field and its index in that field */
13
13
  type LocationInField = FlexTreeNode["parentField"];
14
14
  /**
15
15
  * The {@link Unhydrated} implementation of {@link FlexTreeNode}.
16
16
  */
17
17
  export declare class UnhydratedFlexTreeNode implements FlexTreeNode, MapTreeNodeViewGeneric<UnhydratedFlexTreeNode> {
18
+ #private;
18
19
  /**
19
20
  * The {@link NodeData} for this node.
20
21
  */
@@ -46,7 +47,7 @@ export declare class UnhydratedFlexTreeNode implements FlexTreeNode, MapTreeNode
46
47
  treeNode: TreeNode | undefined;
47
48
  readonly [flexTreeMarker]: FlexTreeEntityKind.Node;
48
49
  private readonly _events;
49
- get events(): Listenable<UnhydratedFlexTreeNodeEvents>;
50
+ get events(): Listenable<UnhydratedFlexTreeNodeEvents> & HasListeners<UnhydratedFlexTreeNodeEvents>;
50
51
  get context(): FlexTreeContext;
51
52
  /**
52
53
  * Create a new UnhydratedFlexTreeNode.
@@ -1 +1 @@
1
- {"version":3,"file":"unhydratedFlexTree.d.ts","sourceRoot":"","sources":["../../../src/simple-tree/core/unhydratedFlexTree.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"unhydratedFlexTree.d.ts","sourceRoot":"","sources":["../../../src/simple-tree/core/unhydratedFlexTree.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,12 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- var _a, _b;
5
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
6
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
7
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
8
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
9
+ };
10
+ var _UnhydratedFlexTreeNode_instances, _a, _UnhydratedFlexTreeNode_emitSubtreeChangedEvents, _b, _c;
6
11
  import { createEmitter } from "@fluid-internal/client-utils";
7
12
  import { assert, oob, fail } from "@fluidframework/core-utils/internal";
8
13
  import { UsageError } from "@fluidframework/telemetry-utils/internal";
@@ -46,11 +51,12 @@ export class UnhydratedFlexTreeNode {
46
51
  * See {@link getUnhydratedContext}.
47
52
  */
48
53
  simpleContext) {
54
+ _UnhydratedFlexTreeNode_instances.add(this);
49
55
  this.data = data;
50
56
  this.fieldsAll = fieldsAll;
51
57
  this.simpleContext = simpleContext;
52
58
  this.location = unparentedLocation;
53
- this[_a] = FlexTreeEntityKind.Node;
59
+ this[_b] = FlexTreeEntityKind.Node;
54
60
  this._events = createEmitter();
55
61
  /**
56
62
  * The non-empty fields on this node.
@@ -67,7 +73,7 @@ export class UnhydratedFlexTreeNode {
67
73
  field.parent = this;
68
74
  }
69
75
  }
70
- [(_a = flexTreeMarker, Symbol.iterator)]() {
76
+ [(_UnhydratedFlexTreeNode_instances = new WeakSet(), _b = flexTreeMarker, Symbol.iterator)]() {
71
77
  return mapIterable(this.fields, ([, field]) => field)[Symbol.iterator]();
72
78
  }
73
79
  /**
@@ -101,7 +107,7 @@ export class UnhydratedFlexTreeNode {
101
107
  throw new UsageError("A node may not be inserted into a location that is under itself");
102
108
  }
103
109
  const parentNode = unhydratedNode.parentField.parent.parent;
104
- assert(parentNode === undefined || parentNode instanceof UnhydratedFlexTreeNode, 0xb77 /* Unhydrated node's parent should be an unhydrated node */);
110
+ assert(parentNode === undefined || parentNode instanceof _a, 0xb77 /* Unhydrated node's parent should be an unhydrated node */);
105
111
  unhydratedNode = parentNode;
106
112
  }
107
113
  this.location = { parent, index };
@@ -140,8 +146,18 @@ export class UnhydratedFlexTreeNode {
140
146
  }
141
147
  emitChangedEvent(key) {
142
148
  this._events.emit("childrenChangedAfterBatch", { changedFields: new Set([key]) });
149
+ // Also emit subtree changed event for this node and all ancestors.
150
+ __classPrivateFieldGet(this, _UnhydratedFlexTreeNode_instances, "m", _UnhydratedFlexTreeNode_emitSubtreeChangedEvents).call(this);
143
151
  }
144
152
  }
153
+ _a = UnhydratedFlexTreeNode, _UnhydratedFlexTreeNode_emitSubtreeChangedEvents = function _UnhydratedFlexTreeNode_emitSubtreeChangedEvents() {
154
+ this._events.emit("subtreeChangedAfterBatch");
155
+ const parent = this.parentField.parent.parent;
156
+ assert(parent === undefined || parent instanceof _a, 0xb76 /* Unhydrated node's parent should be an unhydrated node */);
157
+ if (parent !== undefined) {
158
+ __classPrivateFieldGet(parent, _UnhydratedFlexTreeNode_instances, "m", _UnhydratedFlexTreeNode_emitSubtreeChangedEvents).call(parent);
159
+ }
160
+ };
145
161
  /**
146
162
  * Implementation of `FlexTreeContext`.
147
163
  *
@@ -198,7 +214,7 @@ export class UnhydratedFlexTreeField {
198
214
  this.schema = schema;
199
215
  this.key = key;
200
216
  this.lazyChildren = lazyChildren;
201
- this[_b] = FlexTreeEntityKind.Field;
217
+ this[_c] = FlexTreeEntityKind.Field;
202
218
  this.parent = undefined;
203
219
  // When this field is created (which only happens one time, because it is cached), all the children become parented for the first time.
204
220
  // "Adopt" each child by updating its parent information to point to this field.
@@ -255,7 +271,7 @@ export class UnhydratedFlexTreeField {
255
271
  const m = this.children[i];
256
272
  return m;
257
273
  }
258
- [(_b = flexTreeMarker, Symbol.iterator)]() {
274
+ [(_c = flexTreeMarker, Symbol.iterator)]() {
259
275
  return this.children[Symbol.iterator]();
260
276
  }
261
277
  /**