@fluidframework/tree 2.41.0-337492 → 2.41.0-338186

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 (180) hide show
  1. package/api-report/tree.alpha.api.md +1 -1
  2. package/dist/feature-libraries/flex-tree/context.d.ts +16 -14
  3. package/dist/feature-libraries/flex-tree/context.d.ts.map +1 -1
  4. package/dist/feature-libraries/flex-tree/context.js +12 -18
  5. package/dist/feature-libraries/flex-tree/context.js.map +1 -1
  6. package/dist/feature-libraries/flex-tree/index.d.ts +1 -1
  7. package/dist/feature-libraries/flex-tree/index.d.ts.map +1 -1
  8. package/dist/feature-libraries/flex-tree/index.js +1 -2
  9. package/dist/feature-libraries/flex-tree/index.js.map +1 -1
  10. package/dist/feature-libraries/flex-tree/lazyField.d.ts +1 -5
  11. package/dist/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
  12. package/dist/feature-libraries/flex-tree/lazyField.js +2 -16
  13. package/dist/feature-libraries/flex-tree/lazyField.js.map +1 -1
  14. package/dist/feature-libraries/flex-tree/utilities.d.ts +6 -6
  15. package/dist/feature-libraries/flex-tree/utilities.d.ts.map +1 -1
  16. package/dist/feature-libraries/flex-tree/utilities.js +6 -7
  17. package/dist/feature-libraries/flex-tree/utilities.js.map +1 -1
  18. package/dist/feature-libraries/index.d.ts +1 -1
  19. package/dist/feature-libraries/index.d.ts.map +1 -1
  20. package/dist/feature-libraries/index.js +1 -2
  21. package/dist/feature-libraries/index.js.map +1 -1
  22. package/dist/packageVersion.d.ts +1 -1
  23. package/dist/packageVersion.js +1 -1
  24. package/dist/packageVersion.js.map +1 -1
  25. package/dist/shared-tree/checkoutFlexTreeView.d.ts +7 -3
  26. package/dist/shared-tree/checkoutFlexTreeView.d.ts.map +1 -1
  27. package/dist/shared-tree/checkoutFlexTreeView.js +11 -2
  28. package/dist/shared-tree/checkoutFlexTreeView.js.map +1 -1
  29. package/dist/shared-tree/schematizingTreeView.d.ts +3 -0
  30. package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
  31. package/dist/shared-tree/schematizingTreeView.js +10 -5
  32. package/dist/shared-tree/schematizingTreeView.js.map +1 -1
  33. package/dist/shared-tree/treeAlpha.d.ts +1 -4
  34. package/dist/shared-tree/treeAlpha.d.ts.map +1 -1
  35. package/dist/shared-tree/treeAlpha.js +6 -1
  36. package/dist/shared-tree/treeAlpha.js.map +1 -1
  37. package/dist/simple-tree/api/create.d.ts +5 -1
  38. package/dist/simple-tree/api/create.d.ts.map +1 -1
  39. package/dist/simple-tree/api/create.js +10 -11
  40. package/dist/simple-tree/api/create.js.map +1 -1
  41. package/dist/simple-tree/api/index.d.ts +2 -2
  42. package/dist/simple-tree/api/index.d.ts.map +1 -1
  43. package/dist/simple-tree/api/index.js +2 -2
  44. package/dist/simple-tree/api/index.js.map +1 -1
  45. package/dist/simple-tree/api/storedSchema.d.ts +1 -8
  46. package/dist/simple-tree/api/storedSchema.d.ts.map +1 -1
  47. package/dist/simple-tree/api/storedSchema.js +3 -14
  48. package/dist/simple-tree/api/storedSchema.js.map +1 -1
  49. package/dist/simple-tree/arrayNode.d.ts.map +1 -1
  50. package/dist/simple-tree/arrayNode.js +3 -9
  51. package/dist/simple-tree/arrayNode.js.map +1 -1
  52. package/dist/simple-tree/core/unhydratedFlexTree.d.ts +4 -4
  53. package/dist/simple-tree/core/unhydratedFlexTree.js +4 -4
  54. package/dist/simple-tree/core/unhydratedFlexTree.js.map +1 -1
  55. package/dist/simple-tree/index.d.ts +3 -2
  56. package/dist/simple-tree/index.d.ts.map +1 -1
  57. package/dist/simple-tree/index.js +6 -4
  58. package/dist/simple-tree/index.js.map +1 -1
  59. package/dist/simple-tree/mapNode.d.ts.map +1 -1
  60. package/dist/simple-tree/mapNode.js +17 -20
  61. package/dist/simple-tree/mapNode.js.map +1 -1
  62. package/dist/simple-tree/objectNode.d.ts.map +1 -1
  63. package/dist/simple-tree/objectNode.js +2 -4
  64. package/dist/simple-tree/objectNode.js.map +1 -1
  65. package/dist/simple-tree/prepareForInsertion.d.ts +30 -0
  66. package/dist/simple-tree/prepareForInsertion.d.ts.map +1 -0
  67. package/dist/simple-tree/prepareForInsertion.js +137 -0
  68. package/dist/simple-tree/prepareForInsertion.js.map +1 -0
  69. package/dist/simple-tree/proxies.d.ts +1 -12
  70. package/dist/simple-tree/proxies.d.ts.map +1 -1
  71. package/dist/simple-tree/proxies.js +10 -106
  72. package/dist/simple-tree/proxies.js.map +1 -1
  73. package/dist/simple-tree/toMapTree.d.ts +1 -1
  74. package/dist/simple-tree/toMapTree.js +1 -1
  75. package/dist/simple-tree/toMapTree.js.map +1 -1
  76. package/dist/tableSchema.d.ts +93 -43
  77. package/dist/tableSchema.d.ts.map +1 -1
  78. package/dist/tableSchema.js +72 -22
  79. package/dist/tableSchema.js.map +1 -1
  80. package/lib/feature-libraries/flex-tree/context.d.ts +16 -14
  81. package/lib/feature-libraries/flex-tree/context.d.ts.map +1 -1
  82. package/lib/feature-libraries/flex-tree/context.js +11 -16
  83. package/lib/feature-libraries/flex-tree/context.js.map +1 -1
  84. package/lib/feature-libraries/flex-tree/index.d.ts +1 -1
  85. package/lib/feature-libraries/flex-tree/index.d.ts.map +1 -1
  86. package/lib/feature-libraries/flex-tree/index.js +1 -1
  87. package/lib/feature-libraries/flex-tree/index.js.map +1 -1
  88. package/lib/feature-libraries/flex-tree/lazyField.d.ts +1 -5
  89. package/lib/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
  90. package/lib/feature-libraries/flex-tree/lazyField.js +1 -14
  91. package/lib/feature-libraries/flex-tree/lazyField.js.map +1 -1
  92. package/lib/feature-libraries/flex-tree/utilities.d.ts +6 -6
  93. package/lib/feature-libraries/flex-tree/utilities.d.ts.map +1 -1
  94. package/lib/feature-libraries/flex-tree/utilities.js +6 -7
  95. package/lib/feature-libraries/flex-tree/utilities.js.map +1 -1
  96. package/lib/feature-libraries/index.d.ts +1 -1
  97. package/lib/feature-libraries/index.d.ts.map +1 -1
  98. package/lib/feature-libraries/index.js +1 -1
  99. package/lib/feature-libraries/index.js.map +1 -1
  100. package/lib/packageVersion.d.ts +1 -1
  101. package/lib/packageVersion.js +1 -1
  102. package/lib/packageVersion.js.map +1 -1
  103. package/lib/shared-tree/checkoutFlexTreeView.d.ts +7 -3
  104. package/lib/shared-tree/checkoutFlexTreeView.d.ts.map +1 -1
  105. package/lib/shared-tree/checkoutFlexTreeView.js +12 -3
  106. package/lib/shared-tree/checkoutFlexTreeView.js.map +1 -1
  107. package/lib/shared-tree/schematizingTreeView.d.ts +3 -0
  108. package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
  109. package/lib/shared-tree/schematizingTreeView.js +11 -6
  110. package/lib/shared-tree/schematizingTreeView.js.map +1 -1
  111. package/lib/shared-tree/treeAlpha.d.ts +1 -4
  112. package/lib/shared-tree/treeAlpha.d.ts.map +1 -1
  113. package/lib/shared-tree/treeAlpha.js +7 -2
  114. package/lib/shared-tree/treeAlpha.js.map +1 -1
  115. package/lib/simple-tree/api/create.d.ts +5 -1
  116. package/lib/simple-tree/api/create.d.ts.map +1 -1
  117. package/lib/simple-tree/api/create.js +8 -10
  118. package/lib/simple-tree/api/create.js.map +1 -1
  119. package/lib/simple-tree/api/index.d.ts +2 -2
  120. package/lib/simple-tree/api/index.d.ts.map +1 -1
  121. package/lib/simple-tree/api/index.js +2 -2
  122. package/lib/simple-tree/api/index.js.map +1 -1
  123. package/lib/simple-tree/api/storedSchema.d.ts +1 -8
  124. package/lib/simple-tree/api/storedSchema.d.ts.map +1 -1
  125. package/lib/simple-tree/api/storedSchema.js +2 -12
  126. package/lib/simple-tree/api/storedSchema.js.map +1 -1
  127. package/lib/simple-tree/arrayNode.d.ts.map +1 -1
  128. package/lib/simple-tree/arrayNode.js +4 -10
  129. package/lib/simple-tree/arrayNode.js.map +1 -1
  130. package/lib/simple-tree/core/unhydratedFlexTree.d.ts +4 -4
  131. package/lib/simple-tree/core/unhydratedFlexTree.js +4 -4
  132. package/lib/simple-tree/core/unhydratedFlexTree.js.map +1 -1
  133. package/lib/simple-tree/index.d.ts +3 -2
  134. package/lib/simple-tree/index.d.ts.map +1 -1
  135. package/lib/simple-tree/index.js +3 -2
  136. package/lib/simple-tree/index.js.map +1 -1
  137. package/lib/simple-tree/mapNode.d.ts.map +1 -1
  138. package/lib/simple-tree/mapNode.js +3 -6
  139. package/lib/simple-tree/mapNode.js.map +1 -1
  140. package/lib/simple-tree/objectNode.d.ts.map +1 -1
  141. package/lib/simple-tree/objectNode.js +4 -6
  142. package/lib/simple-tree/objectNode.js.map +1 -1
  143. package/lib/simple-tree/prepareForInsertion.d.ts +30 -0
  144. package/lib/simple-tree/prepareForInsertion.d.ts.map +1 -0
  145. package/lib/simple-tree/prepareForInsertion.js +131 -0
  146. package/lib/simple-tree/prepareForInsertion.js.map +1 -0
  147. package/lib/simple-tree/proxies.d.ts +1 -12
  148. package/lib/simple-tree/proxies.d.ts.map +1 -1
  149. package/lib/simple-tree/proxies.js +1 -96
  150. package/lib/simple-tree/proxies.js.map +1 -1
  151. package/lib/simple-tree/toMapTree.d.ts +1 -1
  152. package/lib/simple-tree/toMapTree.js +1 -1
  153. package/lib/simple-tree/toMapTree.js.map +1 -1
  154. package/lib/tableSchema.d.ts +93 -43
  155. package/lib/tableSchema.d.ts.map +1 -1
  156. package/lib/tableSchema.js +73 -23
  157. package/lib/tableSchema.js.map +1 -1
  158. package/lib/tsdoc-metadata.json +1 -1
  159. package/package.json +25 -25
  160. package/src/feature-libraries/flex-tree/context.ts +18 -20
  161. package/src/feature-libraries/flex-tree/index.ts +0 -1
  162. package/src/feature-libraries/flex-tree/lazyField.ts +2 -14
  163. package/src/feature-libraries/flex-tree/utilities.ts +8 -8
  164. package/src/feature-libraries/index.ts +0 -1
  165. package/src/packageVersion.ts +1 -1
  166. package/src/shared-tree/checkoutFlexTreeView.ts +10 -6
  167. package/src/shared-tree/schematizingTreeView.ts +11 -12
  168. package/src/shared-tree/treeAlpha.ts +21 -5
  169. package/src/simple-tree/api/create.ts +15 -15
  170. package/src/simple-tree/api/index.ts +6 -2
  171. package/src/simple-tree/api/storedSchema.ts +2 -19
  172. package/src/simple-tree/arrayNode.ts +9 -20
  173. package/src/simple-tree/core/unhydratedFlexTree.ts +4 -4
  174. package/src/simple-tree/index.ts +6 -5
  175. package/src/simple-tree/mapNode.ts +8 -12
  176. package/src/simple-tree/objectNode.ts +3 -12
  177. package/src/simple-tree/prepareForInsertion.ts +236 -0
  178. package/src/simple-tree/proxies.ts +2 -147
  179. package/src/simple-tree/toMapTree.ts +1 -1
  180. package/src/tableSchema.ts +243 -77
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/tree",
3
- "version": "2.41.0-337492",
3
+ "version": "2.41.0-338186",
4
4
  "description": "Distributed tree",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -89,17 +89,17 @@
89
89
  "temp-directory": "nyc/.nyc_output"
90
90
  },
91
91
  "dependencies": {
92
- "@fluid-internal/client-utils": "2.41.0-337492",
93
- "@fluidframework/container-runtime": "2.41.0-337492",
94
- "@fluidframework/core-interfaces": "2.41.0-337492",
95
- "@fluidframework/core-utils": "2.41.0-337492",
96
- "@fluidframework/datastore-definitions": "2.41.0-337492",
97
- "@fluidframework/driver-definitions": "2.41.0-337492",
98
- "@fluidframework/id-compressor": "2.41.0-337492",
99
- "@fluidframework/runtime-definitions": "2.41.0-337492",
100
- "@fluidframework/runtime-utils": "2.41.0-337492",
101
- "@fluidframework/shared-object-base": "2.41.0-337492",
102
- "@fluidframework/telemetry-utils": "2.41.0-337492",
92
+ "@fluid-internal/client-utils": "2.41.0-338186",
93
+ "@fluidframework/container-runtime": "2.41.0-338186",
94
+ "@fluidframework/core-interfaces": "2.41.0-338186",
95
+ "@fluidframework/core-utils": "2.41.0-338186",
96
+ "@fluidframework/datastore-definitions": "2.41.0-338186",
97
+ "@fluidframework/driver-definitions": "2.41.0-338186",
98
+ "@fluidframework/id-compressor": "2.41.0-338186",
99
+ "@fluidframework/runtime-definitions": "2.41.0-338186",
100
+ "@fluidframework/runtime-utils": "2.41.0-338186",
101
+ "@fluidframework/shared-object-base": "2.41.0-338186",
102
+ "@fluidframework/telemetry-utils": "2.41.0-338186",
103
103
  "@sinclair/typebox": "^0.34.13",
104
104
  "@tylerbu/sorted-btree-es6": "^1.8.0",
105
105
  "@types/ungap__structured-clone": "^1.2.0",
@@ -109,21 +109,21 @@
109
109
  "devDependencies": {
110
110
  "@arethetypeswrong/cli": "^0.17.1",
111
111
  "@biomejs/biome": "~1.9.3",
112
- "@fluid-internal/mocha-test-setup": "2.41.0-337492",
113
- "@fluid-private/stochastic-test-utils": "2.41.0-337492",
114
- "@fluid-private/test-dds-utils": "2.41.0-337492",
115
- "@fluid-private/test-drivers": "2.41.0-337492",
112
+ "@fluid-internal/mocha-test-setup": "2.41.0-338186",
113
+ "@fluid-private/stochastic-test-utils": "2.41.0-338186",
114
+ "@fluid-private/test-dds-utils": "2.41.0-338186",
115
+ "@fluid-private/test-drivers": "2.41.0-338186",
116
116
  "@fluid-tools/benchmark": "^0.51.0",
117
117
  "@fluid-tools/build-cli": "^0.55.0",
118
118
  "@fluidframework/build-common": "^2.0.3",
119
119
  "@fluidframework/build-tools": "^0.55.0",
120
- "@fluidframework/container-definitions": "2.41.0-337492",
121
- "@fluidframework/container-loader": "2.41.0-337492",
120
+ "@fluidframework/container-definitions": "2.41.0-338186",
121
+ "@fluidframework/container-loader": "2.41.0-338186",
122
122
  "@fluidframework/eslint-config-fluid": "^5.7.3",
123
- "@fluidframework/test-runtime-utils": "2.41.0-337492",
124
- "@fluidframework/test-utils": "2.41.0-337492",
125
- "@fluidframework/tree-previous": "npm:@fluidframework/tree@2.33.0",
126
- "@microsoft/api-extractor": "7.52.5",
123
+ "@fluidframework/test-runtime-utils": "2.41.0-338186",
124
+ "@fluidframework/test-utils": "2.41.0-338186",
125
+ "@fluidframework/tree-previous": "npm:@fluidframework/tree@2.40.0",
126
+ "@microsoft/api-extractor": "7.52.8",
127
127
  "@types/diff": "^3.5.1",
128
128
  "@types/easy-table": "^0.0.32",
129
129
  "@types/mocha": "^10.0.10",
@@ -168,8 +168,8 @@
168
168
  "api": "fluid-build . --task api",
169
169
  "api-extractor:commonjs": "flub generate entrypoints --outDir ./dist",
170
170
  "api-extractor:esnext": "flub generate entrypoints --outDir ./lib --node10TypeCompat",
171
- "bench": "mocha --timeout 999999 --perfMode --parentProcess --fgrep @Benchmark --reporter @fluid-tools/benchmark/dist/MochaReporter.js",
172
- "bench:profile": "mocha --v8-prof --v8-logfile=profile.log --v8-no-logfile-per-isolate --timeout 999999 --perfMode --fgrep @Benchmark --reporter @fluid-tools/benchmark/dist/MochaReporter.js && node --prof-process profile.log > profile.txt && rimraf profile.log && echo See results in profile.txt",
171
+ "bench": "mocha --timeout 999999 --perfMode --parentProcess --fgrep @Benchmark --fgrep @ExecutionTime --reporter @fluid-tools/benchmark/dist/MochaReporter.js",
172
+ "bench:profile": "mocha --v8-prof --v8-logfile=profile.log --v8-no-logfile-per-isolate --timeout 999999 --perfMode --fgrep @Benchmark --fgrep @ExecutionTime --reporter @fluid-tools/benchmark/dist/MochaReporter.js && node --prof-process profile.log > profile.txt && rimraf profile.log && echo See results in profile.txt",
173
173
  "build": "fluid-build . --task build",
174
174
  "build:api-reports": "concurrently \"npm:build:api-reports:*\"",
175
175
  "build:api-reports:current": "api-extractor run --local --config api-extractor/api-extractor.current.json",
@@ -210,7 +210,7 @@
210
210
  "lint:fix": "fluid-build . --task eslint:fix --task format",
211
211
  "pack:tests": "tar -cf ./tree.test-files.tar ./src/test ./dist/test ./lib/test",
212
212
  "test": "npm run test:mocha",
213
- "test:benchmark:report": "mocha --exit --perfMode --parentProcess --fgrep @Benchmark --reporter @fluid-tools/benchmark/dist/MochaReporter.js --timeout 60000",
213
+ "test:benchmark:report": "mocha --exit --perfMode --parentProcess --fgrep @Benchmark --fgrep @ExecutionTime --reporter @fluid-tools/benchmark/dist/MochaReporter.js --timeout 60000",
214
214
  "test:coverage": "c8 npm test",
215
215
  "test:customBenchmarks": "mocha --config ./.mocharc.customBenchmarks.cjs",
216
216
  "test:customBenchmarks:verbose": "cross-env FLUID_TEST_VERBOSE=1 npm run test:customBenchmarks",
@@ -79,6 +79,9 @@ export const ContextSlot = anchorSlot<Context>();
79
79
  * Implementation of `FlexTreeContext`.
80
80
  *
81
81
  * @remarks An editor is required to edit the FlexTree.
82
+ *
83
+ * A {@link FlexTreeContext} which is used to manage the cursors and anchors within the FlexTrees:
84
+ * This is necessary for supporting using this tree across edits to the forest, and not leaking memory.
82
85
  */
83
86
  export class Context implements FlexTreeHydratedContext, IDisposable {
84
87
  public readonly withCursors: Set<LazyEntity> = new Set();
@@ -88,13 +91,19 @@ export class Context implements FlexTreeHydratedContext, IDisposable {
88
91
  private disposed = false;
89
92
 
90
93
  /**
91
- * @param flexSchema - Schema to use when working with the tree.
92
- * @param checkout - The checkout.
93
- * @param nodeKeyManager - An object which handles node key generation and conversion
94
+ * Stores the last accessed version of the root.
95
+ * @remarks
96
+ * Anything which can delete this field must clear it.
97
+ * Currently "clear" is the only case.
94
98
  */
99
+ private lazyRootCache: FlexTreeField | undefined;
100
+
95
101
  public constructor(
96
102
  public readonly schemaPolicy: SchemaPolicy,
97
103
  public readonly checkout: ITreeCheckout,
104
+ /**
105
+ * An object which handles node key generation and conversion
106
+ */
98
107
  public readonly nodeKeyManager: NodeIdentifierManager,
99
108
  ) {
100
109
  this.eventUnregister = [
@@ -158,16 +167,22 @@ export class Context implements FlexTreeHydratedContext, IDisposable {
158
167
  for (const target of this.withAnchors) {
159
168
  target[disposeSymbol]();
160
169
  }
170
+ this.lazyRootCache = undefined;
161
171
  assert(this.withCursors.size === 0, 0x774 /* free should remove all cursors */);
162
172
  assert(this.withAnchors.size === 0, 0x775 /* free should remove all anchors */);
163
173
  }
164
174
 
165
175
  public get root(): FlexTreeField {
166
176
  assert(this.disposed === false, 0x804 /* use after dispose */);
177
+ if (this.lazyRootCache !== undefined) {
178
+ return this.lazyRootCache;
179
+ }
180
+
167
181
  const cursor = this.checkout.forest.allocateCursor("root");
168
182
  moveToDetachedField(this.checkout.forest, cursor);
169
183
  const field = makeField(this, this.schema.rootFieldSchema.kind, cursor);
170
184
  cursor.free();
185
+ this.lazyRootCache = field;
171
186
  return field;
172
187
  }
173
188
 
@@ -175,20 +190,3 @@ export class Context implements FlexTreeHydratedContext, IDisposable {
175
190
  return this.checkout.forest.events;
176
191
  }
177
192
  }
178
-
179
- /**
180
- * A simple API for a Forest to interact with the tree.
181
- *
182
- * @param forest - the Forest
183
- * @param editor - an editor that makes changes to the forest.
184
- * @param nodeKeyManager - an object which handles node key generation and conversion.
185
- * @returns {@link FlexTreeContext} which is used to manage the cursors and anchors within the FlexTrees:
186
- * This is necessary for supporting using this tree across edits to the forest, and not leaking memory.
187
- */
188
- export function getTreeContext(
189
- schema: SchemaPolicy,
190
- checkout: ITreeCheckout,
191
- nodeKeyManager: NodeIdentifierManager,
192
- ): Context {
193
- return new Context(schema, checkout, nodeKeyManager);
194
- }
@@ -28,7 +28,6 @@ export {
28
28
  } from "./navigation.js";
29
29
 
30
30
  export {
31
- getTreeContext,
32
31
  type FlexTreeContext,
33
32
  type FlexTreeHydratedContext,
34
33
  Context,
@@ -278,20 +278,8 @@ export class LazySequence extends LazyField implements FlexTreeSequenceField {
278
278
  }
279
279
  }
280
280
 
281
- export class ReadonlyLazyValueField extends LazyField implements FlexTreeRequiredField {
281
+ export class LazyValueField extends LazyField implements FlexTreeRequiredField {
282
282
  public editor: ValueFieldEditBuilder<ExclusiveMapTree> = {
283
- set: (newContent) => {
284
- assert(false, 0xa0c /* Unexpected set of readonly field */);
285
- },
286
- };
287
-
288
- public get content(): FlexTreeUnknownUnboxed {
289
- return this.atIndex(0);
290
- }
291
- }
292
-
293
- export class LazyValueField extends ReadonlyLazyValueField implements FlexTreeRequiredField {
294
- public override editor: ValueFieldEditBuilder<ExclusiveMapTree> = {
295
283
  set: (newContent) => {
296
284
  this.valueFieldEditor().set(cursorForMapTreeField([newContent]));
297
285
  },
@@ -303,7 +291,7 @@ export class LazyValueField extends ReadonlyLazyValueField implements FlexTreeRe
303
291
  return fieldEditor;
304
292
  }
305
293
 
306
- public override get content(): FlexTreeUnknownUnboxed {
294
+ public get content(): FlexTreeUnknownUnboxed {
307
295
  return this.atIndex(0);
308
296
  }
309
297
  }
@@ -11,8 +11,9 @@ import {
11
11
  rootField,
12
12
  type SchemaAndPolicy,
13
13
  } from "../../core/index.js";
14
+ import type { FlexTreeContext } from "./context.js";
14
15
 
15
- import { TreeStatus, type FlexTreeEntity } from "./flexTreeTypes.js";
16
+ import { TreeStatus } from "./flexTreeTypes.js";
16
17
  /**
17
18
  * Checks the detached field and returns the TreeStatus based on whether or not the detached field is a root field.
18
19
  * @param detachedField - the detached field you want to check.
@@ -75,15 +76,14 @@ export interface DetachedFieldCache {
75
76
  }
76
77
 
77
78
  /**
78
- * Utility function to get a {@link SchemaAndPolicy} object from a {@link FlexTreeNode} or {@link FlexTreeField}.
79
- * @param nodeOrField - {@link FlexTreeNode} or {@link FlexTreeField} to get the schema and policy from.
80
- * @returns A {@link SchemaAndPolicy} object with the stored schema and policy from the node or field provided.
81
- * For {@link Unhydrated} nodes this schema may only describe the types allowed subtree for this particular entity.
79
+ * Utility function to get a {@link SchemaAndPolicy} object from a {@link FlexTreeContext}.
80
+ * @returns A {@link SchemaAndPolicy} object with the stored schema and policy from the context provided.
81
+ * For {@link Unhydrated} contexts this schema may only describe the types allowed subtree for this particular entity.
82
82
  */
83
- export function getSchemaAndPolicy(nodeOrField: FlexTreeEntity): SchemaAndPolicy {
83
+ export function getSchemaAndPolicy(context: FlexTreeContext): SchemaAndPolicy {
84
84
  return {
85
- schema: nodeOrField.context.schema,
86
- policy: nodeOrField.context.schemaPolicy,
85
+ schema: context.schema,
86
+ policy: context.schemaPolicy,
87
87
  };
88
88
  }
89
89
 
@@ -158,7 +158,6 @@ export {
158
158
  type FlexTreeEntity,
159
159
  type FlexTreeField,
160
160
  type FlexTreeNode,
161
- getTreeContext,
162
161
  TreeStatus,
163
162
  Context,
164
163
  type FlexTreeNodeEvents,
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/tree";
9
- export const pkgVersion = "2.41.0-337492";
9
+ export const pkgVersion = "2.41.0-338186";
@@ -5,10 +5,9 @@
5
5
 
6
6
  import { assert } from "@fluidframework/core-utils/internal";
7
7
  import {
8
- type Context,
8
+ Context,
9
9
  type FlexTreeField,
10
10
  type NodeIdentifierManager,
11
- getTreeContext,
12
11
  type FlexTreeHydratedContext,
13
12
  type FullSchemaPolicy,
14
13
  } from "../feature-libraries/index.js";
@@ -19,6 +18,10 @@ import type { ITreeCheckout, ITreeCheckoutFork } from "./treeCheckout.js";
19
18
 
20
19
  /**
21
20
  * An editable view of a (version control style) branch of a shared tree.
21
+ * @remarks
22
+ * Does not depend on stored schema, and thus can live across schema changes.
23
+ * @privateRemarks
24
+ * This has no state beyond the context, so it likely should be replaced with just the context.
22
25
  */
23
26
  export class CheckoutFlexTreeView<out TCheckout extends ITreeCheckout = ITreeCheckout> {
24
27
  /**
@@ -30,9 +33,11 @@ export class CheckoutFlexTreeView<out TCheckout extends ITreeCheckout = ITreeChe
30
33
  public readonly context: Context;
31
34
 
32
35
  /**
33
- * Get a typed view of the tree content using the flex-tree API.
36
+ * Get a view of the tree content using the flex-tree API.
34
37
  */
35
- public readonly flexTree: FlexTreeField;
38
+ public get flexTree(): FlexTreeField {
39
+ return this.context.root;
40
+ }
36
41
 
37
42
  private disposed = false;
38
43
 
@@ -48,9 +53,8 @@ export class CheckoutFlexTreeView<out TCheckout extends ITreeCheckout = ITreeChe
48
53
  public readonly nodeKeyManager: NodeIdentifierManager,
49
54
  private readonly onDispose?: () => void,
50
55
  ) {
51
- this.context = getTreeContext(schema, this.checkout, nodeKeyManager);
56
+ this.context = new Context(schema, this.checkout, nodeKeyManager);
52
57
  contextToTreeViewMap.set(this.context, this);
53
- this.flexTree = this.context.root;
54
58
  }
55
59
 
56
60
  public [disposeSymbol](): void {
@@ -33,9 +33,6 @@ import {
33
33
  SchemaCompatibilityTester,
34
34
  type InsertableContent,
35
35
  type TreeViewConfiguration,
36
- mapTreeFromNodeData,
37
- prepareContentForHydration,
38
- comparePersistedSchemaInternal,
39
36
  type TreeViewAlpha,
40
37
  type InsertableField,
41
38
  type ReadableField,
@@ -55,6 +52,7 @@ import {
55
52
  SimpleContextSlot,
56
53
  areImplicitFieldSchemaEqual,
57
54
  createUnknownOptionalFieldPolicy,
55
+ prepareForInsertionContextless,
58
56
  } from "../simple-tree/index.js";
59
57
  import {
60
58
  type Breakable,
@@ -99,6 +97,9 @@ export class SchematizingSimpleTreeView<
99
97
 
100
98
  private readonly viewSchema: SchemaCompatibilityTester;
101
99
 
100
+ /**
101
+ * Events to unregister upon disposal.
102
+ */
102
103
  private readonly unregisterCallbacks = new Set<() => void>();
103
104
 
104
105
  public disposed = false;
@@ -174,17 +175,16 @@ export class SchematizingSimpleTreeView<
174
175
 
175
176
  this.runSchemaEdit(() => {
176
177
  const schema = this.viewSchema.viewSchemaAsStored;
177
- const mapTree = mapTreeFromNodeData(
178
+ const mapTree = prepareForInsertionContextless(
178
179
  content as InsertableContent | undefined,
179
180
  this.rootFieldSchema,
180
- this.nodeKeyManager,
181
181
  {
182
182
  schema,
183
183
  policy: this.schemaPolicy,
184
184
  },
185
+ this,
185
186
  );
186
187
 
187
- prepareContentForHydration(mapTree, this.checkout.forest);
188
188
  initialize(this.checkout, {
189
189
  schema,
190
190
  initialTree: mapTree === undefined ? undefined : cursorForMapTreeNode(mapTree),
@@ -324,15 +324,14 @@ export class SchematizingSimpleTreeView<
324
324
  private update(): void {
325
325
  this.disposeView();
326
326
 
327
- const compatibility = comparePersistedSchemaInternal(
328
- this.checkout.storedSchema,
329
- this.viewSchema,
330
- canInitialize(this.checkout),
331
- );
327
+ const compatibility = this.viewSchema.checkCompatibility(this.checkout.storedSchema);
332
328
 
333
329
  let lastRoot =
334
330
  this.compatibility.canView && this.view !== undefined ? this.root : undefined;
335
- this.currentCompatibility = compatibility;
331
+ this.currentCompatibility = {
332
+ ...compatibility,
333
+ canInitialize: canInitialize(this.checkout),
334
+ };
336
335
 
337
336
  if (compatibility.canView) {
338
337
  // Trigger "rootChanged" if the root changes in the future.
@@ -36,6 +36,7 @@ import {
36
36
  extractPersistedSchema,
37
37
  type TreeBranch,
38
38
  TreeViewConfigurationAlpha,
39
+ mapTreeFromNodeData,
39
40
  } from "../simple-tree/index.js";
40
41
  import type { JsonCompatible } from "../util/index.js";
41
42
  import { noopValidator, type FluidClientVersion, type ICodecOptions } from "../codec/index.js";
@@ -53,6 +54,7 @@ import {
53
54
  import { independentInitializedView, type ViewContent } from "./independentView.js";
54
55
  import { SchematizingSimpleTreeView, ViewSlot } from "./schematizingTreeView.js";
55
56
  import { currentVersion } from "../codec/index.js";
57
+ import { createFromMapTree } from "../simple-tree/index.js";
56
58
 
57
59
  /**
58
60
  * Extensions to {@link (Tree:interface)} and {@link (TreeBeta:interface)} which are not yet stable.
@@ -80,11 +82,8 @@ export interface TreeAlpha {
80
82
  * When providing a {@link TreeNodeSchemaClass}, this is the same as invoking its constructor except that an unhydrated node can also be provided.
81
83
  * This function exists as a generalization that can be used in other cases as well,
82
84
  * such as when `undefined` might be allowed (for an optional field), or when the type should be inferred from the data when more than one type is possible.
83
- *
84
- * Like with {@link TreeNodeSchemaClass}'s constructor, it's an error to provide an existing node to this API.
85
- * For that case, use {@link (TreeBeta:interface).clone}.
86
85
  * @privateRemarks
87
- * There should be a way to provide a source for defaulted identifiers, wither via this API or some way to add them to its output later.
86
+ * There should be a way to provide a source for defaulted identifiers, either via this API or some way to add them to its output later.
88
87
  */
89
88
  create<const TSchema extends ImplicitFieldSchema | UnsafeUnknownSchema>(
90
89
  schema: UnsafeUnknownSchema extends TSchema
@@ -229,7 +228,24 @@ export const TreeAlpha: TreeAlpha = {
229
228
  return view;
230
229
  },
231
230
 
232
- create: createFromInsertable,
231
+ create<const TSchema extends ImplicitFieldSchema | UnsafeUnknownSchema>(
232
+ schema: UnsafeUnknownSchema extends TSchema
233
+ ? ImplicitFieldSchema
234
+ : TSchema & ImplicitFieldSchema,
235
+ data: InsertableField<TSchema>,
236
+ ): Unhydrated<
237
+ TSchema extends ImplicitFieldSchema
238
+ ? TreeFieldFromImplicitField<TSchema>
239
+ : TreeNode | TreeLeafValue | undefined
240
+ > {
241
+ const mapTree = mapTreeFromNodeData(data as InsertableField<UnsafeUnknownSchema>, schema);
242
+ const result = mapTree === undefined ? undefined : createFromMapTree(schema, mapTree);
243
+ return result as Unhydrated<
244
+ TSchema extends ImplicitFieldSchema
245
+ ? TreeFieldFromImplicitField<TSchema>
246
+ : TreeNode | TreeLeafValue | undefined
247
+ >;
248
+ },
233
249
 
234
250
  importConcise<TSchema extends ImplicitFieldSchema | UnsafeUnknownSchema>(
235
251
  schema: UnsafeUnknownSchema extends TSchema
@@ -5,7 +5,11 @@
5
5
 
6
6
  import { assert } from "@fluidframework/core-utils/internal";
7
7
 
8
- import type { ITreeCursorSynchronous, SchemaAndPolicy } from "../../core/index.js";
8
+ import type {
9
+ ExclusiveMapTree,
10
+ ITreeCursorSynchronous,
11
+ SchemaAndPolicy,
12
+ } from "../../core/index.js";
9
13
  import type {
10
14
  ImplicitFieldSchema,
11
15
  TreeFieldFromImplicitField,
@@ -24,12 +28,10 @@ import {
24
28
  import {
25
29
  cursorForMapTreeNode,
26
30
  defaultSchemaPolicy,
27
- FieldKinds,
28
31
  mapTreeFromCursor,
29
32
  type NodeIdentifierManager,
30
33
  } from "../../feature-libraries/index.js";
31
34
  import { isFieldInSchema } from "../../feature-libraries/index.js";
32
- import { toStoredSchema } from "../toStoredSchema.js";
33
35
  import { inSchemaOrThrow, mapTreeFromNodeData } from "../toMapTree.js";
34
36
  import { getUnhydratedContext } from "../createContext.js";
35
37
  import { createUnknownOptionalFieldPolicy } from "../objectNode.js";
@@ -88,24 +90,12 @@ export function cursorFromInsertable<
88
90
  ):
89
91
  | ITreeCursorSynchronous
90
92
  | (TSchema extends FieldSchema<FieldKind.Optional> ? undefined : never) {
91
- const storedSchema = toStoredSchema(schema);
92
- const schemaValidationPolicy: SchemaAndPolicy = {
93
- policy: defaultSchemaPolicy,
94
- // TODO: optimize: This isn't the most efficient operation since its not cached, and has to convert all the schema.
95
- schema: storedSchema,
96
- };
97
-
98
93
  const mapTree = mapTreeFromNodeData(
99
94
  data as InsertableField<UnsafeUnknownSchema>,
100
95
  schema,
101
96
  context,
102
- schemaValidationPolicy,
103
97
  );
104
98
  if (mapTree === undefined) {
105
- assert(
106
- storedSchema.rootFieldSchema.kind === FieldKinds.optional.identifier,
107
- 0xa10 /* missing non-optional field */,
108
- );
109
99
  return undefined as TSchema extends FieldSchema<FieldKind.Optional> ? undefined : never;
110
100
  }
111
101
  return cursorForMapTreeNode(mapTree);
@@ -144,6 +134,16 @@ export function createFromCursor<const TSchema extends ImplicitFieldSchema>(
144
134
  // Length asserted above, so this is safe. This assert is done instead of checking for undefined after indexing to ensure a length greater than 1 also errors.
145
135
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
146
136
  const mapTree = mapTrees[0]!;
137
+ return createFromMapTree(schema, mapTree);
138
+ }
139
+
140
+ /**
141
+ * Creates an unhydrated simple-tree field from an ExclusiveMapTree.
142
+ */
143
+ export function createFromMapTree<const TSchema extends ImplicitFieldSchema>(
144
+ schema: TSchema,
145
+ mapTree: ExclusiveMapTree,
146
+ ): Unhydrated<TreeFieldFromImplicitField<TSchema>> {
147
147
  const mapTreeNode = UnhydratedFlexTreeNode.getOrCreate(
148
148
  getUnhydratedContext(schema),
149
149
  mapTree,
@@ -45,7 +45,12 @@ export {
45
45
  singletonSchema,
46
46
  } from "./schemaCreationUtilities.js";
47
47
  export { treeNodeApi, type TreeNodeApi, tryGetSchema } from "./treeNodeApi.js";
48
- export { createFromInsertable, cursorFromInsertable, createFromCursor } from "./create.js";
48
+ export {
49
+ createFromInsertable,
50
+ cursorFromInsertable,
51
+ createFromCursor,
52
+ createFromMapTree,
53
+ } from "./create.js";
49
54
  export {
50
55
  type JsonSchemaId,
51
56
  type JsonSchemaType,
@@ -107,7 +112,6 @@ export {
107
112
 
108
113
  export {
109
114
  extractPersistedSchema,
110
- comparePersistedSchemaInternal,
111
115
  comparePersistedSchema,
112
116
  } from "./storedSchema.js";
113
117
 
@@ -4,7 +4,6 @@
4
4
  */
5
5
 
6
6
  import type { FluidClientVersion, ICodecOptions } from "../../codec/index.js";
7
- import type { TreeStoredSchema } from "../../core/index.js";
8
7
  import {
9
8
  defaultSchemaPolicy,
10
9
  encodeTreeSchema,
@@ -96,8 +95,7 @@ export function comparePersistedSchema(
96
95
  persisted: JsonCompatible,
97
96
  view: ImplicitFieldSchema,
98
97
  options: ICodecOptions,
99
- canInitialize: boolean,
100
- ): SchemaCompatibilityStatus {
98
+ ): Omit<SchemaCompatibilityStatus, "canInitialize"> {
101
99
  // Any version can be passed down to makeSchemaCodec here.
102
100
  // We only use the decode part, which always dispatches to the correct codec based on the version in the data, not the version passed to `makeSchemaCodec`.
103
101
  const schemaCodec = makeSchemaCodec(options, SchemaCodecVersion.v1);
@@ -107,20 +105,5 @@ export function comparePersistedSchema(
107
105
  {},
108
106
  normalizeFieldSchema(view),
109
107
  );
110
- return comparePersistedSchemaInternal(stored, viewSchema, canInitialize);
111
- }
112
-
113
- /**
114
- * Compute compatibility for viewing a document with `stored` schema using `viewSchema`.
115
- * `canInitialize` is passed through to the return value unchanged and otherwise unused.
116
- */
117
- export function comparePersistedSchemaInternal(
118
- stored: TreeStoredSchema,
119
- viewSchema: SchemaCompatibilityTester,
120
- canInitialize: boolean,
121
- ): SchemaCompatibilityStatus {
122
- return {
123
- ...viewSchema.checkCompatibility(stored),
124
- canInitialize,
125
- };
108
+ return viewSchema.checkCompatibility(stored);
126
109
  }
@@ -10,10 +10,8 @@ import { EmptyKey, type ExclusiveMapTree } from "../core/index.js";
10
10
  import {
11
11
  type FlexTreeNode,
12
12
  type FlexTreeSequenceField,
13
- getSchemaAndPolicy,
14
13
  isFlexTreeNode,
15
14
  } from "../feature-libraries/index.js";
16
- import { prepareContentForHydration } from "./proxies.js";
17
15
  import {
18
16
  normalizeAllowedTypes,
19
17
  unannotateImplicitAllowedTypes,
@@ -41,6 +39,7 @@ import {
41
39
  type TreeNodeSchemaClass,
42
40
  } from "./core/index.js";
43
41
  import { type InsertableContent, mapTreeFromNodeData } from "./toMapTree.js";
42
+ import { prepareArrayForInsertion } from "./prepareForInsertion.js";
44
43
  import {
45
44
  getKernel,
46
45
  UnhydratedFlexTreeNode,
@@ -860,24 +859,14 @@ abstract class CustomArrayNodeBase<const T extends ImplicitAllowedTypes>
860
859
  | IterableTreeArrayContent<InsertableContent>
861
860
  )[];
862
861
 
863
- const mapTrees = content
864
- .flatMap((c): InsertableContent[] =>
865
- c instanceof IterableTreeArrayContent ? Array.from(c) : [c],
866
- )
867
- .map((c) =>
868
- mapTreeFromNodeData(
869
- c,
870
- this.simpleSchema,
871
- sequenceField.context.isHydrated()
872
- ? sequenceField.context.nodeKeyManager
873
- : undefined,
874
- getSchemaAndPolicy(sequenceField),
875
- ),
876
- );
877
-
878
- if (sequenceField.context.isHydrated()) {
879
- prepareContentForHydration(mapTrees, sequenceField.context.checkout.forest);
880
- }
862
+ const contentArray = content.flatMap((c): InsertableContent[] =>
863
+ c instanceof IterableTreeArrayContent ? Array.from(c) : [c],
864
+ );
865
+ const mapTrees = prepareArrayForInsertion(
866
+ contentArray,
867
+ this.simpleSchema,
868
+ sequenceField.context,
869
+ );
881
870
 
882
871
  return mapTrees;
883
872
  }
@@ -69,7 +69,7 @@ interface LocationInField {
69
69
  * An unhydrated implementation of {@link FlexTreeNode} which wraps a {@link MapTree}.
70
70
  * @remarks
71
71
  * MapTreeNodes are unconditionally cached -
72
- * when retrieved via {@link getOrCreateNode}, the same {@link MapTree} object will always produce the same `UnhydratedFlexTreeNode` object.
72
+ * when retrieved via {@link getOrCreateNodeFromInnerNode}, the same {@link MapTree} object will always produce the same `UnhydratedFlexTreeNode` object.
73
73
  *
74
74
  * Create a `UnhydratedFlexTreeNode` by calling {@link getOrCreate}.
75
75
  */
@@ -112,9 +112,9 @@ export class UnhydratedFlexTreeNode implements FlexTreeNode {
112
112
  * Create a new UnhydratedFlexTreeNode.
113
113
  * @param location - the parentage of this node, if it is being created underneath an existing node and field, or undefined if not
114
114
  * @remarks This class (and its subclasses) should not be directly constructed outside of this module.
115
- * Instead, use {@link getOrCreateNode} to create a UnhydratedFlexTreeNode from a {@link MapTree}.
115
+ * Instead, use {@link getOrCreateNodeFromInnerNode} to create a UnhydratedFlexTreeNode from a {@link MapTree}.
116
116
  * A `UnhydratedFlexTreeNode` may never be constructed more than once for the same {@link MapTree} object.
117
- * Instead, it should always be acquired via {@link getOrCreateNode}.
117
+ * Instead, it should always be acquired via {@link getOrCreateNodeFromInnerNode}.
118
118
  */
119
119
  public constructor(
120
120
  public readonly simpleContext: Context,
@@ -548,7 +548,7 @@ function getFieldKeyCache(
548
548
 
549
549
  /**
550
550
  * If there exists a {@link UnhydratedFlexTreeNode} for the given {@link MapTree}, returns it, otherwise returns `undefined`.
551
- * @remarks {@link UnhydratedFlexTreeNode | UnhydratedFlexTreeNodes} are created via {@link getOrCreateNode}.
551
+ * @remarks {@link UnhydratedFlexTreeNode | UnhydratedFlexTreeNodes} are created via {@link getOrCreateNodeFromInnerNode}.
552
552
  */
553
553
  export function tryUnhydratedFlexTreeNode(
554
554
  mapTree: MapTree,