@fluidframework/tree 2.10.0-305357 → 2.10.0-307060

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 (292) hide show
  1. package/.eslintrc.cjs +56 -25
  2. package/api-report/tree.alpha.api.md +14 -11
  3. package/api-report/tree.beta.api.md +5 -2
  4. package/api-report/tree.legacy.alpha.api.md +5 -2
  5. package/api-report/tree.legacy.public.api.md +5 -2
  6. package/api-report/tree.public.api.md +5 -2
  7. package/dist/core/forest/forest.d.ts +5 -1
  8. package/dist/core/forest/forest.d.ts.map +1 -1
  9. package/dist/core/forest/forest.js.map +1 -1
  10. package/dist/core/index.d.ts +1 -1
  11. package/dist/core/index.d.ts.map +1 -1
  12. package/dist/core/index.js.map +1 -1
  13. package/dist/core/schema-stored/storedSchemaRepository.d.ts +7 -3
  14. package/dist/core/schema-stored/storedSchemaRepository.d.ts.map +1 -1
  15. package/dist/core/schema-stored/storedSchemaRepository.js +4 -6
  16. package/dist/core/schema-stored/storedSchemaRepository.js.map +1 -1
  17. package/dist/core/tree/anchorSet.d.ts +8 -5
  18. package/dist/core/tree/anchorSet.d.ts.map +1 -1
  19. package/dist/core/tree/anchorSet.js +12 -11
  20. package/dist/core/tree/anchorSet.js.map +1 -1
  21. package/dist/events/emitter.d.ts +21 -9
  22. package/dist/events/emitter.d.ts.map +1 -1
  23. package/dist/events/emitter.js +36 -21
  24. package/dist/events/emitter.js.map +1 -1
  25. package/dist/events/listeners.d.ts +16 -5
  26. package/dist/events/listeners.d.ts.map +1 -1
  27. package/dist/events/listeners.js.map +1 -1
  28. package/dist/feature-libraries/chunked-forest/basicChunk.d.ts +26 -5
  29. package/dist/feature-libraries/chunked-forest/basicChunk.d.ts.map +1 -1
  30. package/dist/feature-libraries/chunked-forest/basicChunk.js +15 -5
  31. package/dist/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
  32. package/dist/feature-libraries/chunked-forest/chunkTree.js +1 -1
  33. package/dist/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
  34. package/dist/feature-libraries/chunked-forest/chunkedForest.d.ts +3 -2
  35. package/dist/feature-libraries/chunked-forest/chunkedForest.d.ts.map +1 -1
  36. package/dist/feature-libraries/chunked-forest/chunkedForest.js +19 -9
  37. package/dist/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
  38. package/dist/feature-libraries/flex-tree/context.d.ts +3 -2
  39. package/dist/feature-libraries/flex-tree/context.d.ts.map +1 -1
  40. package/dist/feature-libraries/flex-tree/context.js +3 -3
  41. package/dist/feature-libraries/flex-tree/context.js.map +1 -1
  42. package/dist/feature-libraries/flex-tree/lazyField.js +1 -1
  43. package/dist/feature-libraries/flex-tree/lazyField.js.map +1 -1
  44. package/dist/feature-libraries/flex-tree/lazyNode.js +1 -1
  45. package/dist/feature-libraries/flex-tree/lazyNode.js.map +1 -1
  46. package/dist/feature-libraries/flex-tree/utilities.js +1 -1
  47. package/dist/feature-libraries/flex-tree/utilities.js.map +1 -1
  48. package/dist/feature-libraries/index.d.ts +1 -1
  49. package/dist/feature-libraries/index.d.ts.map +1 -1
  50. package/dist/feature-libraries/index.js +2 -2
  51. package/dist/feature-libraries/index.js.map +1 -1
  52. package/dist/feature-libraries/modular-schema/comparison.d.ts.map +1 -1
  53. package/dist/feature-libraries/modular-schema/comparison.js +3 -0
  54. package/dist/feature-libraries/modular-schema/comparison.js.map +1 -1
  55. package/dist/feature-libraries/modular-schema/discrepancies.d.ts +29 -29
  56. package/dist/feature-libraries/modular-schema/discrepancies.d.ts.map +1 -1
  57. package/dist/feature-libraries/modular-schema/discrepancies.js +121 -75
  58. package/dist/feature-libraries/modular-schema/discrepancies.js.map +1 -1
  59. package/dist/feature-libraries/modular-schema/genericFieldKind.js +2 -2
  60. package/dist/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
  61. package/dist/feature-libraries/modular-schema/index.d.ts +1 -1
  62. package/dist/feature-libraries/modular-schema/index.d.ts.map +1 -1
  63. package/dist/feature-libraries/modular-schema/index.js +2 -2
  64. package/dist/feature-libraries/modular-schema/index.js.map +1 -1
  65. package/dist/feature-libraries/modular-schema/modularChangeFamily.js +1 -1
  66. package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  67. package/dist/feature-libraries/object-forest/objectForest.d.ts +2 -2
  68. package/dist/feature-libraries/object-forest/objectForest.d.ts.map +1 -1
  69. package/dist/feature-libraries/object-forest/objectForest.js +6 -8
  70. package/dist/feature-libraries/object-forest/objectForest.js.map +1 -1
  71. package/dist/feature-libraries/schema-index/schemaSummarizer.js +1 -1
  72. package/dist/feature-libraries/schema-index/schemaSummarizer.js.map +1 -1
  73. package/dist/feature-libraries/sequence-field/compose.js +2 -2
  74. package/dist/feature-libraries/sequence-field/compose.js.map +1 -1
  75. package/dist/feature-libraries/sequence-field/markListFactory.js +1 -1
  76. package/dist/feature-libraries/sequence-field/markListFactory.js.map +1 -1
  77. package/dist/packageVersion.d.ts +1 -1
  78. package/dist/packageVersion.js +1 -1
  79. package/dist/packageVersion.js.map +1 -1
  80. package/dist/shared-tree/schematizingTreeView.js +2 -2
  81. package/dist/shared-tree/schematizingTreeView.js.map +1 -1
  82. package/dist/shared-tree/treeApi.js +6 -3
  83. package/dist/shared-tree/treeApi.js.map +1 -1
  84. package/dist/shared-tree/treeCheckout.js +7 -7
  85. package/dist/shared-tree/treeCheckout.js.map +1 -1
  86. package/dist/shared-tree-core/branch.d.ts +7 -7
  87. package/dist/shared-tree-core/branch.d.ts.map +1 -1
  88. package/dist/shared-tree-core/branch.js +35 -25
  89. package/dist/shared-tree-core/branch.js.map +1 -1
  90. package/dist/shared-tree-core/editManager.js +4 -4
  91. package/dist/shared-tree-core/editManager.js.map +1 -1
  92. package/dist/shared-tree-core/sharedTreeCore.js +5 -5
  93. package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
  94. package/dist/simple-tree/api/schemaCreationUtilities.d.ts +12 -14
  95. package/dist/simple-tree/api/schemaCreationUtilities.d.ts.map +1 -1
  96. package/dist/simple-tree/api/schemaCreationUtilities.js +9 -7
  97. package/dist/simple-tree/api/schemaCreationUtilities.js.map +1 -1
  98. package/dist/simple-tree/api/schemaFactory.d.ts +68 -10
  99. package/dist/simple-tree/api/schemaFactory.d.ts.map +1 -1
  100. package/dist/simple-tree/api/schemaFactory.js +38 -10
  101. package/dist/simple-tree/api/schemaFactory.js.map +1 -1
  102. package/dist/simple-tree/api/schemaFactoryRecursive.js.map +1 -1
  103. package/dist/simple-tree/api/treeNodeApi.js +4 -4
  104. package/dist/simple-tree/api/treeNodeApi.js.map +1 -1
  105. package/dist/simple-tree/arrayNode.js +1 -1
  106. package/dist/simple-tree/arrayNode.js.map +1 -1
  107. package/dist/simple-tree/core/treeNodeKernel.d.ts +7 -8
  108. package/dist/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
  109. package/dist/simple-tree/core/treeNodeKernel.js +68 -73
  110. package/dist/simple-tree/core/treeNodeKernel.js.map +1 -1
  111. package/dist/simple-tree/objectNode.d.ts +1 -1
  112. package/dist/simple-tree/objectNode.js.map +1 -1
  113. package/dist/simple-tree/objectNodeTypes.d.ts +3 -0
  114. package/dist/simple-tree/objectNodeTypes.d.ts.map +1 -1
  115. package/dist/simple-tree/objectNodeTypes.js +3 -1
  116. package/dist/simple-tree/objectNodeTypes.js.map +1 -1
  117. package/dist/simple-tree/proxies.js +1 -1
  118. package/dist/simple-tree/proxies.js.map +1 -1
  119. package/dist/simple-tree/schemaTypes.d.ts +26 -1
  120. package/dist/simple-tree/schemaTypes.d.ts.map +1 -1
  121. package/dist/simple-tree/schemaTypes.js.map +1 -1
  122. package/dist/simple-tree/treeNodeValid.js +2 -2
  123. package/dist/simple-tree/treeNodeValid.js.map +1 -1
  124. package/dist/util/nestedMap.d.ts.map +1 -1
  125. package/dist/util/nestedMap.js.map +1 -1
  126. package/docs/.attachments/object-merge-semantics.drawio +145 -0
  127. package/docs/user-facing/array-merge-semantics.md +344 -0
  128. package/docs/user-facing/map-merge-semantics.md +128 -0
  129. package/docs/user-facing/merge-semantics.md +7 -3
  130. package/docs/user-facing/object-merge-semantics.md +77 -0
  131. package/lib/core/forest/forest.d.ts +5 -1
  132. package/lib/core/forest/forest.d.ts.map +1 -1
  133. package/lib/core/forest/forest.js.map +1 -1
  134. package/lib/core/index.d.ts +1 -1
  135. package/lib/core/index.d.ts.map +1 -1
  136. package/lib/core/index.js.map +1 -1
  137. package/lib/core/schema-stored/storedSchemaRepository.d.ts +7 -3
  138. package/lib/core/schema-stored/storedSchemaRepository.d.ts.map +1 -1
  139. package/lib/core/schema-stored/storedSchemaRepository.js +4 -6
  140. package/lib/core/schema-stored/storedSchemaRepository.js.map +1 -1
  141. package/lib/core/tree/anchorSet.d.ts +8 -5
  142. package/lib/core/tree/anchorSet.d.ts.map +1 -1
  143. package/lib/core/tree/anchorSet.js +12 -11
  144. package/lib/core/tree/anchorSet.js.map +1 -1
  145. package/lib/events/emitter.d.ts +21 -9
  146. package/lib/events/emitter.d.ts.map +1 -1
  147. package/lib/events/emitter.js +37 -22
  148. package/lib/events/emitter.js.map +1 -1
  149. package/lib/events/listeners.d.ts +16 -5
  150. package/lib/events/listeners.d.ts.map +1 -1
  151. package/lib/events/listeners.js.map +1 -1
  152. package/lib/feature-libraries/chunked-forest/basicChunk.d.ts +26 -5
  153. package/lib/feature-libraries/chunked-forest/basicChunk.d.ts.map +1 -1
  154. package/lib/feature-libraries/chunked-forest/basicChunk.js +15 -5
  155. package/lib/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
  156. package/lib/feature-libraries/chunked-forest/chunkTree.js +1 -1
  157. package/lib/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
  158. package/lib/feature-libraries/chunked-forest/chunkedForest.d.ts +3 -2
  159. package/lib/feature-libraries/chunked-forest/chunkedForest.d.ts.map +1 -1
  160. package/lib/feature-libraries/chunked-forest/chunkedForest.js +19 -9
  161. package/lib/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
  162. package/lib/feature-libraries/flex-tree/context.d.ts +3 -2
  163. package/lib/feature-libraries/flex-tree/context.d.ts.map +1 -1
  164. package/lib/feature-libraries/flex-tree/context.js +3 -3
  165. package/lib/feature-libraries/flex-tree/context.js.map +1 -1
  166. package/lib/feature-libraries/flex-tree/lazyField.js +1 -1
  167. package/lib/feature-libraries/flex-tree/lazyField.js.map +1 -1
  168. package/lib/feature-libraries/flex-tree/lazyNode.js +1 -1
  169. package/lib/feature-libraries/flex-tree/lazyNode.js.map +1 -1
  170. package/lib/feature-libraries/flex-tree/utilities.js +1 -1
  171. package/lib/feature-libraries/flex-tree/utilities.js.map +1 -1
  172. package/lib/feature-libraries/index.d.ts +1 -1
  173. package/lib/feature-libraries/index.d.ts.map +1 -1
  174. package/lib/feature-libraries/index.js +1 -1
  175. package/lib/feature-libraries/index.js.map +1 -1
  176. package/lib/feature-libraries/modular-schema/comparison.d.ts.map +1 -1
  177. package/lib/feature-libraries/modular-schema/comparison.js +3 -0
  178. package/lib/feature-libraries/modular-schema/comparison.js.map +1 -1
  179. package/lib/feature-libraries/modular-schema/discrepancies.d.ts +29 -29
  180. package/lib/feature-libraries/modular-schema/discrepancies.d.ts.map +1 -1
  181. package/lib/feature-libraries/modular-schema/discrepancies.js +120 -74
  182. package/lib/feature-libraries/modular-schema/discrepancies.js.map +1 -1
  183. package/lib/feature-libraries/modular-schema/genericFieldKind.js +2 -2
  184. package/lib/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
  185. package/lib/feature-libraries/modular-schema/index.d.ts +1 -1
  186. package/lib/feature-libraries/modular-schema/index.d.ts.map +1 -1
  187. package/lib/feature-libraries/modular-schema/index.js +1 -1
  188. package/lib/feature-libraries/modular-schema/index.js.map +1 -1
  189. package/lib/feature-libraries/modular-schema/modularChangeFamily.js +1 -1
  190. package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  191. package/lib/feature-libraries/object-forest/objectForest.d.ts +2 -2
  192. package/lib/feature-libraries/object-forest/objectForest.d.ts.map +1 -1
  193. package/lib/feature-libraries/object-forest/objectForest.js +6 -8
  194. package/lib/feature-libraries/object-forest/objectForest.js.map +1 -1
  195. package/lib/feature-libraries/schema-index/schemaSummarizer.js +1 -1
  196. package/lib/feature-libraries/schema-index/schemaSummarizer.js.map +1 -1
  197. package/lib/feature-libraries/sequence-field/compose.js +2 -2
  198. package/lib/feature-libraries/sequence-field/compose.js.map +1 -1
  199. package/lib/feature-libraries/sequence-field/markListFactory.js +1 -1
  200. package/lib/feature-libraries/sequence-field/markListFactory.js.map +1 -1
  201. package/lib/packageVersion.d.ts +1 -1
  202. package/lib/packageVersion.js +1 -1
  203. package/lib/packageVersion.js.map +1 -1
  204. package/lib/shared-tree/schematizingTreeView.js +2 -2
  205. package/lib/shared-tree/schematizingTreeView.js.map +1 -1
  206. package/lib/shared-tree/treeApi.js +7 -4
  207. package/lib/shared-tree/treeApi.js.map +1 -1
  208. package/lib/shared-tree/treeCheckout.js +7 -7
  209. package/lib/shared-tree/treeCheckout.js.map +1 -1
  210. package/lib/shared-tree-core/branch.d.ts +7 -7
  211. package/lib/shared-tree-core/branch.d.ts.map +1 -1
  212. package/lib/shared-tree-core/branch.js +36 -26
  213. package/lib/shared-tree-core/branch.js.map +1 -1
  214. package/lib/shared-tree-core/editManager.js +4 -4
  215. package/lib/shared-tree-core/editManager.js.map +1 -1
  216. package/lib/shared-tree-core/sharedTreeCore.js +5 -5
  217. package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
  218. package/lib/simple-tree/api/schemaCreationUtilities.d.ts +12 -14
  219. package/lib/simple-tree/api/schemaCreationUtilities.d.ts.map +1 -1
  220. package/lib/simple-tree/api/schemaCreationUtilities.js +9 -7
  221. package/lib/simple-tree/api/schemaCreationUtilities.js.map +1 -1
  222. package/lib/simple-tree/api/schemaFactory.d.ts +68 -10
  223. package/lib/simple-tree/api/schemaFactory.d.ts.map +1 -1
  224. package/lib/simple-tree/api/schemaFactory.js +38 -10
  225. package/lib/simple-tree/api/schemaFactory.js.map +1 -1
  226. package/lib/simple-tree/api/schemaFactoryRecursive.js.map +1 -1
  227. package/lib/simple-tree/api/treeNodeApi.js +4 -4
  228. package/lib/simple-tree/api/treeNodeApi.js.map +1 -1
  229. package/lib/simple-tree/arrayNode.js +1 -1
  230. package/lib/simple-tree/arrayNode.js.map +1 -1
  231. package/lib/simple-tree/core/treeNodeKernel.d.ts +7 -8
  232. package/lib/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
  233. package/lib/simple-tree/core/treeNodeKernel.js +69 -74
  234. package/lib/simple-tree/core/treeNodeKernel.js.map +1 -1
  235. package/lib/simple-tree/objectNode.d.ts +1 -1
  236. package/lib/simple-tree/objectNode.js.map +1 -1
  237. package/lib/simple-tree/objectNodeTypes.d.ts +3 -0
  238. package/lib/simple-tree/objectNodeTypes.d.ts.map +1 -1
  239. package/lib/simple-tree/objectNodeTypes.js +3 -1
  240. package/lib/simple-tree/objectNodeTypes.js.map +1 -1
  241. package/lib/simple-tree/proxies.js +1 -1
  242. package/lib/simple-tree/proxies.js.map +1 -1
  243. package/lib/simple-tree/schemaTypes.d.ts +26 -1
  244. package/lib/simple-tree/schemaTypes.d.ts.map +1 -1
  245. package/lib/simple-tree/schemaTypes.js.map +1 -1
  246. package/lib/simple-tree/treeNodeValid.js +2 -2
  247. package/lib/simple-tree/treeNodeValid.js.map +1 -1
  248. package/lib/util/nestedMap.d.ts.map +1 -1
  249. package/lib/util/nestedMap.js.map +1 -1
  250. package/package.json +20 -20
  251. package/src/core/forest/forest.ts +6 -1
  252. package/src/core/index.ts +1 -1
  253. package/src/core/schema-stored/storedSchemaRepository.ts +10 -13
  254. package/src/core/tree/anchorSet.ts +13 -20
  255. package/src/events/emitter.ts +45 -24
  256. package/src/events/listeners.ts +17 -5
  257. package/src/feature-libraries/chunked-forest/basicChunk.ts +12 -4
  258. package/src/feature-libraries/chunked-forest/chunkTree.ts +1 -1
  259. package/src/feature-libraries/chunked-forest/chunkedForest.ts +13 -14
  260. package/src/feature-libraries/flex-tree/context.ts +5 -7
  261. package/src/feature-libraries/flex-tree/lazyField.ts +1 -1
  262. package/src/feature-libraries/flex-tree/lazyNode.ts +1 -1
  263. package/src/feature-libraries/flex-tree/utilities.ts +1 -1
  264. package/src/feature-libraries/index.ts +1 -1
  265. package/src/feature-libraries/modular-schema/comparison.ts +4 -0
  266. package/src/feature-libraries/modular-schema/discrepancies.ts +188 -124
  267. package/src/feature-libraries/modular-schema/genericFieldKind.ts +2 -2
  268. package/src/feature-libraries/modular-schema/index.ts +4 -1
  269. package/src/feature-libraries/modular-schema/modularChangeFamily.ts +1 -1
  270. package/src/feature-libraries/object-forest/objectForest.ts +5 -11
  271. package/src/feature-libraries/schema-index/schemaSummarizer.ts +1 -1
  272. package/src/feature-libraries/sequence-field/compose.ts +2 -2
  273. package/src/feature-libraries/sequence-field/markListFactory.ts +1 -1
  274. package/src/packageVersion.ts +1 -1
  275. package/src/shared-tree/schematizingTreeView.ts +2 -2
  276. package/src/shared-tree/treeApi.ts +9 -7
  277. package/src/shared-tree/treeCheckout.ts +7 -7
  278. package/src/shared-tree-core/branch.ts +30 -30
  279. package/src/shared-tree-core/editManager.ts +4 -4
  280. package/src/shared-tree-core/sharedTreeCore.ts +5 -5
  281. package/src/simple-tree/api/schemaCreationUtilities.ts +29 -17
  282. package/src/simple-tree/api/schemaFactory.ts +62 -29
  283. package/src/simple-tree/api/schemaFactoryRecursive.ts +1 -1
  284. package/src/simple-tree/api/treeNodeApi.ts +4 -4
  285. package/src/simple-tree/arrayNode.ts +1 -1
  286. package/src/simple-tree/core/treeNodeKernel.ts +68 -72
  287. package/src/simple-tree/objectNode.ts +1 -1
  288. package/src/simple-tree/objectNodeTypes.ts +3 -1
  289. package/src/simple-tree/proxies.ts +1 -1
  290. package/src/simple-tree/schemaTypes.ts +26 -1
  291. package/src/simple-tree/treeNodeValid.ts +2 -2
  292. package/src/util/nestedMap.ts +1 -0
@@ -1 +1 @@
1
- {"version":3,"file":"chunkTree.js","sourceRoot":"","sources":["../../../src/feature-libraries/chunked-forest/chunkTree.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 { assert, oob } from \"@fluidframework/core-utils/internal\";\n\nimport {\n\tCursorLocationType,\n\ttype FieldKey,\n\ttype ITreeCursorSynchronous,\n\tLeafNodeStoredSchema,\n\tObjectNodeStoredSchema,\n\ttype StoredSchemaCollection,\n\ttype TreeFieldStoredSchema,\n\ttype TreeNodeSchemaIdentifier,\n\ttype TreeStoredSchema,\n\ttype TreeStoredSchemaSubscription,\n\ttype TreeValue,\n\ttype Value,\n\tmapCursorFields,\n\tMultiplicity,\n\tValueSchema,\n} from \"../../core/index.js\";\nimport { fail, getOrCreate } from \"../../util/index.js\";\nimport type { FullSchemaPolicy } from \"../modular-schema/index.js\";\n\nimport { BasicChunk } from \"./basicChunk.js\";\nimport { type TreeChunk, tryGetChunk } from \"./chunk.js\";\nimport { SequenceChunk } from \"./sequenceChunk.js\";\nimport { type FieldShape, TreeShape, UniformChunk } from \"./uniformChunk.js\";\nimport { isStableNodeKey } from \"../node-key/index.js\";\nimport type { IIdCompressor } from \"@fluidframework/id-compressor\";\n\nexport interface Disposable {\n\t/**\n\t * Cleans up resources used by this, such as inbound event registrations.\n\t */\n\tdispose(): void;\n}\n\n/**\n * Creates a ChunkPolicy which responds to schema changes.\n */\nexport function makeTreeChunker(\n\tschema: TreeStoredSchemaSubscription,\n\tpolicy: FullSchemaPolicy,\n): IChunker {\n\treturn new Chunker(\n\t\tschema,\n\t\tpolicy,\n\t\tdefaultChunkPolicy.sequenceChunkInlineThreshold,\n\t\tdefaultChunkPolicy.sequenceChunkInlineThreshold,\n\t\tdefaultChunkPolicy.uniformChunkNodeCount,\n\t\ttryShapeFromSchema,\n\t);\n}\n\n/**\n * Extends ChunkPolicy to include stateful details required by ChunkedForest.\n *\n * This extra complexity is mostly due to the fact that schema can change over time,\n * and that chunk policy uses caching which thus needs invalidation.\n */\nexport interface IChunker extends ChunkPolicy, Disposable {\n\treadonly schema: TreeStoredSchemaSubscription;\n\tclone(schema: TreeStoredSchemaSubscription): IChunker;\n}\n\n/**\n * Indicates that there are multiple possible `TreeShape` trees with a given type can have.\n *\n * @remarks\n * For example, a schema transitively containing a sequence field, optional field, or allowing multiple child types will be Polymorphic.\n * See `tryShapeFromSchema` for how to tell if a type is Polymorphic.\n *\n * TODO: cache some of the possible shapes here.\n */\n// eslint-disable-next-line @typescript-eslint/no-extraneous-class\nexport class Polymorphic {}\n\n/**\n * See `Polymorphic`.\n * For now Polymorphic is stateless, so just use a singleton.\n */\nexport const polymorphic = new Polymorphic();\n\n/**\n * Information about the possible shapes a tree could take based on its type.\n * Note that this information is for a specific version of the schema.\n */\nexport type ShapeInfo = TreeShape | Polymorphic;\n\nexport class Chunker implements IChunker {\n\t/**\n\t * Cache for information about possible shapes for types.\n\t * Corresponds to the version of the schema in `schema`.\n\t * Cleared when `schema` changes.\n\t */\n\tprivate readonly typeShapes: Map<TreeNodeSchemaIdentifier, ShapeInfo> = new Map();\n\n\tprivate unregisterSchemaCallback: (() => void) | undefined;\n\n\tpublic constructor(\n\t\tpublic readonly schema: TreeStoredSchemaSubscription,\n\t\tpublic readonly policy: FullSchemaPolicy,\n\t\tpublic readonly sequenceChunkSplitThreshold: number,\n\t\tpublic readonly sequenceChunkInlineThreshold: number,\n\t\tpublic readonly uniformChunkNodeCount: number,\n\t\t// eslint-disable-next-line @typescript-eslint/no-shadow\n\t\tprivate readonly tryShapeFromSchema: (\n\t\t\tschema: TreeStoredSchema,\n\t\t\tpolicy: FullSchemaPolicy,\n\t\t\ttype: TreeNodeSchemaIdentifier,\n\t\t\tshapes: Map<TreeNodeSchemaIdentifier, ShapeInfo>,\n\t\t) => ShapeInfo,\n\t) {}\n\n\tpublic clone(schema: TreeStoredSchemaSubscription): IChunker {\n\t\t// This does not preserve the cache.\n\t\t// This is probably fine, but is a potential way it could be optimized in the future (with care to ensure invalidation work properly).\n\t\treturn new Chunker(\n\t\t\tschema,\n\t\t\tthis.policy,\n\t\t\tthis.sequenceChunkSplitThreshold,\n\t\t\tthis.sequenceChunkInlineThreshold,\n\t\t\tthis.uniformChunkNodeCount,\n\t\t\tthis.tryShapeFromSchema,\n\t\t);\n\t}\n\n\tpublic shapeFromSchema(schema: TreeNodeSchemaIdentifier): ShapeInfo {\n\t\tconst cached = this.typeShapes.get(schema);\n\t\tif (cached !== undefined) {\n\t\t\treturn cached;\n\t\t}\n\t\tthis.unregisterSchemaCallback = this.schema.on(\"afterSchemaChange\", () =>\n\t\t\tthis.schemaChanged(),\n\t\t);\n\t\treturn this.tryShapeFromSchema(this.schema, this.policy, schema, this.typeShapes);\n\t}\n\n\tpublic dispose(): void {\n\t\t// Remove subscription for changes via dependent.\n\t\tthis.schemaChanged();\n\t}\n\n\tprivate schemaChanged(): void {\n\t\tthis.typeShapes.clear();\n\t\tif (this.unregisterSchemaCallback) {\n\t\t\tthis.unregisterSchemaCallback();\n\t\t\tthis.unregisterSchemaCallback = undefined;\n\t\t}\n\t}\n}\n\n/**\n * Get a TreeChunk for the current node (and its children) of cursor.\n * This will copy if needed, but add refs to existing chunks which hold the data.\n *\n * @param cursor - cursor in nodes mode\n */\nexport function chunkTree(cursor: ITreeCursorSynchronous, policy: ChunkCompressor): TreeChunk {\n\treturn chunkRange(cursor, policy, 1, true)[0] ?? oob();\n}\n\n/**\n * Get a TreeChunk[] for the current field (and its children) of cursor.\n * This will copy if needed, but add refs to existing chunks which hold the data.\n */\nexport function chunkField(\n\tcursor: ITreeCursorSynchronous,\n\tpolicy: ChunkCompressor,\n): TreeChunk[] {\n\tconst length = cursor.getFieldLength();\n\tconst started = cursor.firstNode();\n\tassert(started, 0x57c /* field to chunk should have at least one node */);\n\treturn chunkRange(cursor, policy, length, false);\n}\n\n/**\n * Get a TreeChunk for the current field (and its children) of cursor.\n * Like {@link chunkField}, but forces the results into a single TreeChunk.\n */\nexport function chunkFieldSingle(\n\tcursor: ITreeCursorSynchronous,\n\tpolicy: ChunkCompressor,\n): TreeChunk {\n\tconst chunks = chunkField(cursor, policy);\n\tif (chunks.length === 1) {\n\t\treturn chunks[0] ?? oob();\n\t}\n\treturn new SequenceChunk(chunks);\n}\n\n/**\n * Get a BasicChunk for the current node (and its children) of cursor.\n * This will copy if needed, and add refs to existing chunks which hold the data.\n */\nexport function basicChunkTree(\n\tcursor: ITreeCursorSynchronous,\n\tpolicy: ChunkCompressor,\n): BasicChunk {\n\t// symbol based fast path to check for BasicChunk:\n\t// return existing chunk with a increased ref count if possible.\n\tconst chunk = tryGetChunk(cursor);\n\tif (chunk instanceof BasicChunk) {\n\t\tchunk.referenceAdded();\n\t\treturn chunk;\n\t}\n\n\treturn newBasicChunkTree(cursor, policy);\n}\n\nexport function makePolicy(policy?: Partial<ChunkPolicy>): ChunkPolicy {\n\tconst withDefaults = { ...defaultChunkPolicy, ...policy };\n\t// TODO: move this to a top level policy validation\n\tassert(\n\t\twithDefaults.sequenceChunkSplitThreshold >= 2,\n\t\t0x57d /* sequenceChunkThreshold must be at least 2 */,\n\t);\n\n\treturn withDefaults;\n}\n\nexport function shapesFromSchema(\n\tschema: StoredSchemaCollection,\n\tpolicy: FullSchemaPolicy,\n): Map<TreeNodeSchemaIdentifier, ShapeInfo> {\n\tconst shapes: Map<TreeNodeSchemaIdentifier, ShapeInfo> = new Map();\n\tfor (const identifier of schema.nodeSchema.keys()) {\n\t\ttryShapeFromSchema(schema, policy, identifier, shapes);\n\t}\n\treturn shapes;\n}\n\n/**\n * If `schema` has only one shape, return it.\n *\n * Note that this does not tolerate optional or sequence fields, nor does it optimize for patterns of specific values.\n */\nexport function tryShapeFromSchema(\n\tschema: StoredSchemaCollection,\n\tpolicy: FullSchemaPolicy,\n\ttype: TreeNodeSchemaIdentifier,\n\tshapes: Map<TreeNodeSchemaIdentifier, ShapeInfo>,\n): ShapeInfo {\n\treturn getOrCreate(shapes, type, () => {\n\t\tconst treeSchema = schema.nodeSchema.get(type) ?? fail(\"missing schema\");\n\t\tif (treeSchema instanceof LeafNodeStoredSchema) {\n\t\t\t// Allow all string values (but only string values) to be compressed by the id compressor.\n\t\t\t// This allows compressing all compressible identifiers without requiring additional context to know which values could be identifiers.\n\t\t\t// Attempting to compress other string shouldn't have significant overhead,\n\t\t\t// and if any of them do end up compressing, that's a benefit not a bug.\n\t\t\treturn treeSchema.leafValue === ValueSchema.String\n\t\t\t\t? new TreeShape(type, true, [], true)\n\t\t\t\t: new TreeShape(type, true, [], false);\n\t\t}\n\t\tif (treeSchema instanceof ObjectNodeStoredSchema) {\n\t\t\tconst fieldsArray: FieldShape[] = [];\n\t\t\tfor (const [key, field] of treeSchema.objectNodeFields) {\n\t\t\t\tconst fieldShape = tryShapeFromFieldSchema(schema, policy, field, key, shapes);\n\t\t\t\tif (fieldShape === undefined) {\n\t\t\t\t\treturn polymorphic;\n\t\t\t\t}\n\t\t\t\tfieldsArray.push(fieldShape);\n\t\t\t}\n\t\t\treturn new TreeShape(type, false, fieldsArray);\n\t\t}\n\t\treturn polymorphic;\n\t});\n}\n\n/**\n * If `schema` has only one shape, return it.\n *\n * Note that this does not tolerate optional or sequence fields, nor does it optimize for patterns of specific values.\n */\nexport function tryShapeFromFieldSchema(\n\tschema: StoredSchemaCollection,\n\tpolicy: FullSchemaPolicy,\n\ttype: TreeFieldStoredSchema,\n\tkey: FieldKey,\n\tshapes: Map<TreeNodeSchemaIdentifier, ShapeInfo>,\n): FieldShape | undefined {\n\tconst kind = policy.fieldKinds.get(type.kind) ?? fail(\"missing FieldKind\");\n\tif (kind.multiplicity !== Multiplicity.Single) {\n\t\treturn undefined;\n\t}\n\tif (type.types?.size !== 1) {\n\t\treturn undefined;\n\t}\n\tconst childType = [...type.types][0] ?? oob();\n\tconst childShape = tryShapeFromSchema(schema, policy, childType, shapes);\n\tif (childShape instanceof Polymorphic) {\n\t\treturn undefined;\n\t}\n\treturn [key, childShape, 1];\n}\n\n/**\n * Default settings for use for {@link ChunkPolicy}.\n * Use `makeTreeChunker` to create a policy with the defaults, but leverages to schema.\n */\nexport const defaultChunkPolicy: ChunkPolicy = {\n\t// Currently ChunkedForest and BasicTreeCursor don't handle SequenceChunks very efficiently:\n\t// they likely add more overhead than they save for now, so don't create them.\n\tsequenceChunkSplitThreshold: Number.POSITIVE_INFINITY,\n\tsequenceChunkInlineThreshold: Number.POSITIVE_INFINITY,\n\t// Current UniformChunk handling doesn't scale well to large chunks, so set a modest size limit:\n\tuniformChunkNodeCount: 400,\n\t// Without knowing what the schema is, all shapes are possible.\n\t// Use `makeTreeChunker` to do better.\n\tshapeFromSchema: () => polymorphic,\n};\n\nexport const basicOnlyChunkPolicy: ChunkPolicy = {\n\tsequenceChunkSplitThreshold: Number.POSITIVE_INFINITY,\n\tsequenceChunkInlineThreshold: Number.POSITIVE_INFINITY,\n\tuniformChunkNodeCount: 0,\n\tshapeFromSchema: () => polymorphic,\n};\n\n/**\n * Policy for how to chunk a tree.\n */\nexport interface ChunkPolicy {\n\t/**\n\t * Group sequences longer than this into into sequence chunks of this length or less.\n\t *\n\t * Must be at least 2.\n\t * Can be set to `Number.POSITIVE_INFINITY` to never introduce extra sequence chunks.\n\t */\n\treadonly sequenceChunkSplitThreshold: number;\n\n\t/**\n\t * SequenceChunks this long or shorter may get inlined into their parent chunk.\n\t */\n\treadonly sequenceChunkInlineThreshold: number;\n\n\t/**\n\t * Maximum total nodes to put in a UniformChunk.\n\t */\n\treadonly uniformChunkNodeCount: number;\n\n\t/**\n\t * Returns information about the shapes trees of type `schema` can take.\n\t */\n\tshapeFromSchema(schema: TreeNodeSchemaIdentifier): ShapeInfo;\n}\n\nexport interface ChunkCompressor {\n\treadonly policy: ChunkPolicy;\n\t/**\n\t * If the idCompressor is provided, {@link UniformChunk}s with identifiers will be encoded for its in-memory representation.\n\t * @remarks\n\t * This compression applies to {@link UniformChunk}s when {@link TreeShape.maybeDecompressedStringAsNumber} is set.\n\t * If the `policy` does not use UniformChunks or does not set `maybeDecompressedStringAsNumber`, then no compression will be applied even when providing `idCompressor`.\n\t */\n\treadonly idCompressor: IIdCompressor | undefined;\n}\n\nfunction newBasicChunkTree(\n\tcursor: ITreeCursorSynchronous,\n\tpolicy: ChunkCompressor,\n): BasicChunk {\n\treturn new BasicChunk(\n\t\tcursor.type,\n\t\tnew Map(mapCursorFields(cursor, () => [cursor.getFieldKey(), chunkField(cursor, policy)])),\n\t\tcursor.value,\n\t);\n}\n\n/**\n * @param cursor - cursor in nodes mode\n * @param policy - heuristics to impact chunking\n * @param length - how many nodes to process (at the top level)\n * @param skipLastNavigation - if true, leaves the cursor at the last node instead of moving off of it.\n */\nexport function chunkRange(\n\tcursor: ITreeCursorSynchronous,\n\tchunkCompressor: ChunkCompressor,\n\tlength: number,\n\tskipLastNavigation: boolean,\n): TreeChunk[] {\n\tassert(cursor.mode === CursorLocationType.Nodes, 0x57e /* should be in nodes */);\n\tlet output: TreeChunk[] = [];\n\tlet remaining = length;\n\twhile (remaining > 0) {\n\t\tassert(cursor.mode === CursorLocationType.Nodes, 0x57f /* should be in nodes */);\n\t\tconst start = cursor.chunkStart;\n\t\tlet reusedChunk = false;\n\t\t// symbol based fast path to check for chunk:\n\t\t// return existing chunk with a increased ref count if possible.\n\t\tif (start === cursor.fieldIndex) {\n\t\t\tconst chunkLength = cursor.chunkLength;\n\t\t\tif (chunkLength <= remaining) {\n\t\t\t\tconst chunk = tryGetChunk(cursor);\n\t\t\t\tif (chunk !== undefined) {\n\t\t\t\t\tif (\n\t\t\t\t\t\tchunk instanceof SequenceChunk &&\n\t\t\t\t\t\tchunk.subChunks.length <= chunkCompressor.policy.sequenceChunkInlineThreshold\n\t\t\t\t\t) {\n\t\t\t\t\t\t// If sequence chunk, and its very short, inline it.\n\t\t\t\t\t\t// Note that this is not recursive: there may be short sequences nested below this which are not inlined.\n\t\t\t\t\t\tfor (const subChunk of chunk.subChunks) {\n\t\t\t\t\t\t\tsubChunk.referenceAdded();\n\t\t\t\t\t\t\toutput.push(subChunk);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tchunk.referenceAdded();\n\t\t\t\t\toutput.push(chunk);\n\t\t\t\t\tremaining -= chunkLength;\n\t\t\t\t\treusedChunk = true;\n\t\t\t\t\tlet seek = chunkLength;\n\t\t\t\t\tif (skipLastNavigation && remaining === 0) {\n\t\t\t\t\t\tseek -= 1;\n\t\t\t\t\t}\n\t\t\t\t\tcursor.seekNodes(seek);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!reusedChunk) {\n\t\t\tassert(cursor.mode === CursorLocationType.Nodes, 0x580 /* should be in nodes */);\n\t\t\t// TODO: if provided, use schema to consider using UniformChunks\n\t\t\tconst type = cursor.type;\n\t\t\tconst shape = chunkCompressor.policy.shapeFromSchema(type);\n\t\t\tif (shape instanceof TreeShape) {\n\t\t\t\tconst nodesPerTopLevelNode = shape.positions.length;\n\t\t\t\tconst maxTopLevelLength = Math.ceil(\n\t\t\t\t\tnodesPerTopLevelNode / chunkCompressor.policy.uniformChunkNodeCount,\n\t\t\t\t);\n\t\t\t\tconst maxLength = Math.min(maxTopLevelLength, remaining);\n\t\t\t\tconst newChunk = uniformChunkFromCursor(\n\t\t\t\t\tcursor,\n\t\t\t\t\tshape,\n\t\t\t\t\tmaxLength,\n\t\t\t\t\tmaxLength === remaining && skipLastNavigation,\n\t\t\t\t\tchunkCompressor.idCompressor,\n\t\t\t\t);\n\t\t\t\tremaining -= newChunk.topLevelLength;\n\t\t\t\toutput.push(newChunk);\n\t\t\t} else {\n\t\t\t\t// Slow path: copy tree into new basic chunk\n\t\t\t\toutput.push(newBasicChunkTree(cursor, chunkCompressor));\n\t\t\t\tremaining -= 1;\n\t\t\t\tif (!skipLastNavigation || remaining !== 0) {\n\t\t\t\t\tcursor.nextNode();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// TODO: maybe make a pass over output to coalesce UniformChunks and/or convert other formats to UniformChunks where possible.\n\n\t// If output is large, group it into a tree of sequence chunks.\n\twhile (output.length > chunkCompressor.policy.sequenceChunkSplitThreshold) {\n\t\tconst chunkCount = Math.ceil(\n\t\t\toutput.length / chunkCompressor.policy.sequenceChunkSplitThreshold,\n\t\t);\n\t\tconst newOutput: TreeChunk[] = [];\n\t\t// Rounding down, and add an extra item to some of the chunks.\n\t\tconst chunkSize = Math.floor(output.length / chunkCount);\n\t\t// number of chunks to add an extra item to to make total line up.\n\t\tconst extra = output.length % chunkCount;\n\t\tlet previousEnd = 0;\n\t\tfor (let index = 0; index < chunkCount; index++) {\n\t\t\t// If we are in the first `extra` items, add an extra to this chunk.\n\t\t\tconst end = previousEnd + chunkSize + (index < extra ? 1 : 0);\n\t\t\tnewOutput.push(new SequenceChunk(output.slice(previousEnd, end)));\n\t\t\tpreviousEnd = end;\n\t\t}\n\t\tassert(previousEnd === output.length, 0x581 /* chunks should add up to total */);\n\t\toutput = newOutput;\n\t}\n\n\treturn output;\n}\n/**\n * @param idCompressor - compressor used to encoded string values that are compressible by the idCompressor for in-memory representation.\n * If the idCompressor is not provided, the values will be the original uncompressed values.\n */\nexport function insertValues(\n\tcursor: ITreeCursorSynchronous,\n\tshape: TreeShape,\n\tvalues: Value[],\n\tidCompressor?: IIdCompressor,\n): void {\n\tassert(shape.type === cursor.type, 0x582 /* shape and type must match */);\n\n\t// TODO:Perf:\n\t// Fast path for already part of a uniform chunk with matching shape\n\n\t// Slow path: walk shape and cursor together, inserting values.\n\tif (shape.hasValue) {\n\t\tif (\n\t\t\ttypeof cursor.value === \"string\" &&\n\t\t\tidCompressor !== undefined &&\n\t\t\tisStableNodeKey(cursor.value)\n\t\t) {\n\t\t\tvalues.push(idCompressor.tryRecompress(cursor.value) ?? cursor.value);\n\t\t} else {\n\t\t\tvalues.push(cursor.value);\n\t\t}\n\t}\n\tfor (const [key, childShape, length] of shape.fieldsArray) {\n\t\tcursor.enterField(key);\n\t\tlet count = 0;\n\t\tfor (let inNodes = cursor.firstNode(); inNodes; inNodes = cursor.nextNode()) {\n\t\t\tinsertValues(cursor, childShape, values, idCompressor);\n\t\t\tcount++;\n\t\t}\n\t\tcursor.exitField();\n\t\tassert(length === count, 0x583 /* unexpected field length */);\n\t}\n}\n\n/**\n * Read up to `maxTopLevelLength` nodes from `cursor`, stopping when limit is hit or type of node changes.\n *\n * This requires that the all trees with matching type match the provided shape.\n * This cannot be used if other shapes are possible for this type.\n *\n * If this stops early due to the type changing, `skipLastNavigation` is not involved:\n * `skipLastNavigation` only determines if the cursor will be left on the node after the last one (possibly exiting the field)\n * if the full length is used.\n *\n * @param idCompressor - compressor used to encoded string values that are compressible by the idCompressor for in-memory representation.\n * If the idCompressor is not provided, the values will be the original uncompressed values.\n */\nexport function uniformChunkFromCursor(\n\tcursor: ITreeCursorSynchronous,\n\tshape: TreeShape,\n\tmaxTopLevelLength: number,\n\tskipLastNavigation: boolean,\n\tidCompressor?: IIdCompressor,\n): UniformChunk {\n\t// TODO:\n\t// This could have a fast path for consuming already uniformly chunked data with matching shape.\n\n\tconst values: TreeValue[] = [];\n\tlet topLevelLength = 1;\n\twhile (topLevelLength <= maxTopLevelLength) {\n\t\tinsertValues(cursor, shape, values, idCompressor);\n\t\tif (topLevelLength === maxTopLevelLength) {\n\t\t\tif (!skipLastNavigation) {\n\t\t\t\tcursor.nextNode();\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcursor.nextNode();\n\t\tif (cursor.type !== shape.type) {\n\t\t\tbreak;\n\t\t}\n\t\ttopLevelLength += 1;\n\t}\n\treturn new UniformChunk(shape.withTopLevelLength(topLevelLength), values, idCompressor);\n}\n"]}
1
+ {"version":3,"file":"chunkTree.js","sourceRoot":"","sources":["../../../src/feature-libraries/chunked-forest/chunkTree.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 { assert, oob } from \"@fluidframework/core-utils/internal\";\n\nimport {\n\tCursorLocationType,\n\ttype FieldKey,\n\ttype ITreeCursorSynchronous,\n\tLeafNodeStoredSchema,\n\tObjectNodeStoredSchema,\n\ttype StoredSchemaCollection,\n\ttype TreeFieldStoredSchema,\n\ttype TreeNodeSchemaIdentifier,\n\ttype TreeStoredSchema,\n\ttype TreeStoredSchemaSubscription,\n\ttype TreeValue,\n\ttype Value,\n\tmapCursorFields,\n\tMultiplicity,\n\tValueSchema,\n} from \"../../core/index.js\";\nimport { fail, getOrCreate } from \"../../util/index.js\";\nimport type { FullSchemaPolicy } from \"../modular-schema/index.js\";\n\nimport { BasicChunk } from \"./basicChunk.js\";\nimport { type TreeChunk, tryGetChunk } from \"./chunk.js\";\nimport { SequenceChunk } from \"./sequenceChunk.js\";\nimport { type FieldShape, TreeShape, UniformChunk } from \"./uniformChunk.js\";\nimport { isStableNodeKey } from \"../node-key/index.js\";\nimport type { IIdCompressor } from \"@fluidframework/id-compressor\";\n\nexport interface Disposable {\n\t/**\n\t * Cleans up resources used by this, such as inbound event registrations.\n\t */\n\tdispose(): void;\n}\n\n/**\n * Creates a ChunkPolicy which responds to schema changes.\n */\nexport function makeTreeChunker(\n\tschema: TreeStoredSchemaSubscription,\n\tpolicy: FullSchemaPolicy,\n): IChunker {\n\treturn new Chunker(\n\t\tschema,\n\t\tpolicy,\n\t\tdefaultChunkPolicy.sequenceChunkInlineThreshold,\n\t\tdefaultChunkPolicy.sequenceChunkInlineThreshold,\n\t\tdefaultChunkPolicy.uniformChunkNodeCount,\n\t\ttryShapeFromSchema,\n\t);\n}\n\n/**\n * Extends ChunkPolicy to include stateful details required by ChunkedForest.\n *\n * This extra complexity is mostly due to the fact that schema can change over time,\n * and that chunk policy uses caching which thus needs invalidation.\n */\nexport interface IChunker extends ChunkPolicy, Disposable {\n\treadonly schema: TreeStoredSchemaSubscription;\n\tclone(schema: TreeStoredSchemaSubscription): IChunker;\n}\n\n/**\n * Indicates that there are multiple possible `TreeShape` trees with a given type can have.\n *\n * @remarks\n * For example, a schema transitively containing a sequence field, optional field, or allowing multiple child types will be Polymorphic.\n * See `tryShapeFromSchema` for how to tell if a type is Polymorphic.\n *\n * TODO: cache some of the possible shapes here.\n */\n// eslint-disable-next-line @typescript-eslint/no-extraneous-class\nexport class Polymorphic {}\n\n/**\n * See `Polymorphic`.\n * For now Polymorphic is stateless, so just use a singleton.\n */\nexport const polymorphic = new Polymorphic();\n\n/**\n * Information about the possible shapes a tree could take based on its type.\n * Note that this information is for a specific version of the schema.\n */\nexport type ShapeInfo = TreeShape | Polymorphic;\n\nexport class Chunker implements IChunker {\n\t/**\n\t * Cache for information about possible shapes for types.\n\t * Corresponds to the version of the schema in `schema`.\n\t * Cleared when `schema` changes.\n\t */\n\tprivate readonly typeShapes: Map<TreeNodeSchemaIdentifier, ShapeInfo> = new Map();\n\n\tprivate unregisterSchemaCallback: (() => void) | undefined;\n\n\tpublic constructor(\n\t\tpublic readonly schema: TreeStoredSchemaSubscription,\n\t\tpublic readonly policy: FullSchemaPolicy,\n\t\tpublic readonly sequenceChunkSplitThreshold: number,\n\t\tpublic readonly sequenceChunkInlineThreshold: number,\n\t\tpublic readonly uniformChunkNodeCount: number,\n\t\t// eslint-disable-next-line @typescript-eslint/no-shadow\n\t\tprivate readonly tryShapeFromSchema: (\n\t\t\tschema: TreeStoredSchema,\n\t\t\tpolicy: FullSchemaPolicy,\n\t\t\ttype: TreeNodeSchemaIdentifier,\n\t\t\tshapes: Map<TreeNodeSchemaIdentifier, ShapeInfo>,\n\t\t) => ShapeInfo,\n\t) {}\n\n\tpublic clone(schema: TreeStoredSchemaSubscription): IChunker {\n\t\t// This does not preserve the cache.\n\t\t// This is probably fine, but is a potential way it could be optimized in the future (with care to ensure invalidation work properly).\n\t\treturn new Chunker(\n\t\t\tschema,\n\t\t\tthis.policy,\n\t\t\tthis.sequenceChunkSplitThreshold,\n\t\t\tthis.sequenceChunkInlineThreshold,\n\t\t\tthis.uniformChunkNodeCount,\n\t\t\tthis.tryShapeFromSchema,\n\t\t);\n\t}\n\n\tpublic shapeFromSchema(schema: TreeNodeSchemaIdentifier): ShapeInfo {\n\t\tconst cached = this.typeShapes.get(schema);\n\t\tif (cached !== undefined) {\n\t\t\treturn cached;\n\t\t}\n\t\tthis.unregisterSchemaCallback = this.schema.events.on(\"afterSchemaChange\", () =>\n\t\t\tthis.schemaChanged(),\n\t\t);\n\t\treturn this.tryShapeFromSchema(this.schema, this.policy, schema, this.typeShapes);\n\t}\n\n\tpublic dispose(): void {\n\t\t// Remove subscription for changes via dependent.\n\t\tthis.schemaChanged();\n\t}\n\n\tprivate schemaChanged(): void {\n\t\tthis.typeShapes.clear();\n\t\tif (this.unregisterSchemaCallback) {\n\t\t\tthis.unregisterSchemaCallback();\n\t\t\tthis.unregisterSchemaCallback = undefined;\n\t\t}\n\t}\n}\n\n/**\n * Get a TreeChunk for the current node (and its children) of cursor.\n * This will copy if needed, but add refs to existing chunks which hold the data.\n *\n * @param cursor - cursor in nodes mode\n */\nexport function chunkTree(cursor: ITreeCursorSynchronous, policy: ChunkCompressor): TreeChunk {\n\treturn chunkRange(cursor, policy, 1, true)[0] ?? oob();\n}\n\n/**\n * Get a TreeChunk[] for the current field (and its children) of cursor.\n * This will copy if needed, but add refs to existing chunks which hold the data.\n */\nexport function chunkField(\n\tcursor: ITreeCursorSynchronous,\n\tpolicy: ChunkCompressor,\n): TreeChunk[] {\n\tconst length = cursor.getFieldLength();\n\tconst started = cursor.firstNode();\n\tassert(started, 0x57c /* field to chunk should have at least one node */);\n\treturn chunkRange(cursor, policy, length, false);\n}\n\n/**\n * Get a TreeChunk for the current field (and its children) of cursor.\n * Like {@link chunkField}, but forces the results into a single TreeChunk.\n */\nexport function chunkFieldSingle(\n\tcursor: ITreeCursorSynchronous,\n\tpolicy: ChunkCompressor,\n): TreeChunk {\n\tconst chunks = chunkField(cursor, policy);\n\tif (chunks.length === 1) {\n\t\treturn chunks[0] ?? oob();\n\t}\n\treturn new SequenceChunk(chunks);\n}\n\n/**\n * Get a BasicChunk for the current node (and its children) of cursor.\n * This will copy if needed, and add refs to existing chunks which hold the data.\n */\nexport function basicChunkTree(\n\tcursor: ITreeCursorSynchronous,\n\tpolicy: ChunkCompressor,\n): BasicChunk {\n\t// symbol based fast path to check for BasicChunk:\n\t// return existing chunk with a increased ref count if possible.\n\tconst chunk = tryGetChunk(cursor);\n\tif (chunk instanceof BasicChunk) {\n\t\tchunk.referenceAdded();\n\t\treturn chunk;\n\t}\n\n\treturn newBasicChunkTree(cursor, policy);\n}\n\nexport function makePolicy(policy?: Partial<ChunkPolicy>): ChunkPolicy {\n\tconst withDefaults = { ...defaultChunkPolicy, ...policy };\n\t// TODO: move this to a top level policy validation\n\tassert(\n\t\twithDefaults.sequenceChunkSplitThreshold >= 2,\n\t\t0x57d /* sequenceChunkThreshold must be at least 2 */,\n\t);\n\n\treturn withDefaults;\n}\n\nexport function shapesFromSchema(\n\tschema: StoredSchemaCollection,\n\tpolicy: FullSchemaPolicy,\n): Map<TreeNodeSchemaIdentifier, ShapeInfo> {\n\tconst shapes: Map<TreeNodeSchemaIdentifier, ShapeInfo> = new Map();\n\tfor (const identifier of schema.nodeSchema.keys()) {\n\t\ttryShapeFromSchema(schema, policy, identifier, shapes);\n\t}\n\treturn shapes;\n}\n\n/**\n * If `schema` has only one shape, return it.\n *\n * Note that this does not tolerate optional or sequence fields, nor does it optimize for patterns of specific values.\n */\nexport function tryShapeFromSchema(\n\tschema: StoredSchemaCollection,\n\tpolicy: FullSchemaPolicy,\n\ttype: TreeNodeSchemaIdentifier,\n\tshapes: Map<TreeNodeSchemaIdentifier, ShapeInfo>,\n): ShapeInfo {\n\treturn getOrCreate(shapes, type, () => {\n\t\tconst treeSchema = schema.nodeSchema.get(type) ?? fail(\"missing schema\");\n\t\tif (treeSchema instanceof LeafNodeStoredSchema) {\n\t\t\t// Allow all string values (but only string values) to be compressed by the id compressor.\n\t\t\t// This allows compressing all compressible identifiers without requiring additional context to know which values could be identifiers.\n\t\t\t// Attempting to compress other string shouldn't have significant overhead,\n\t\t\t// and if any of them do end up compressing, that's a benefit not a bug.\n\t\t\treturn treeSchema.leafValue === ValueSchema.String\n\t\t\t\t? new TreeShape(type, true, [], true)\n\t\t\t\t: new TreeShape(type, true, [], false);\n\t\t}\n\t\tif (treeSchema instanceof ObjectNodeStoredSchema) {\n\t\t\tconst fieldsArray: FieldShape[] = [];\n\t\t\tfor (const [key, field] of treeSchema.objectNodeFields) {\n\t\t\t\tconst fieldShape = tryShapeFromFieldSchema(schema, policy, field, key, shapes);\n\t\t\t\tif (fieldShape === undefined) {\n\t\t\t\t\treturn polymorphic;\n\t\t\t\t}\n\t\t\t\tfieldsArray.push(fieldShape);\n\t\t\t}\n\t\t\treturn new TreeShape(type, false, fieldsArray);\n\t\t}\n\t\treturn polymorphic;\n\t});\n}\n\n/**\n * If `schema` has only one shape, return it.\n *\n * Note that this does not tolerate optional or sequence fields, nor does it optimize for patterns of specific values.\n */\nexport function tryShapeFromFieldSchema(\n\tschema: StoredSchemaCollection,\n\tpolicy: FullSchemaPolicy,\n\ttype: TreeFieldStoredSchema,\n\tkey: FieldKey,\n\tshapes: Map<TreeNodeSchemaIdentifier, ShapeInfo>,\n): FieldShape | undefined {\n\tconst kind = policy.fieldKinds.get(type.kind) ?? fail(\"missing FieldKind\");\n\tif (kind.multiplicity !== Multiplicity.Single) {\n\t\treturn undefined;\n\t}\n\tif (type.types?.size !== 1) {\n\t\treturn undefined;\n\t}\n\tconst childType = [...type.types][0] ?? oob();\n\tconst childShape = tryShapeFromSchema(schema, policy, childType, shapes);\n\tif (childShape instanceof Polymorphic) {\n\t\treturn undefined;\n\t}\n\treturn [key, childShape, 1];\n}\n\n/**\n * Default settings for use for {@link ChunkPolicy}.\n * Use `makeTreeChunker` to create a policy with the defaults, but leverages to schema.\n */\nexport const defaultChunkPolicy: ChunkPolicy = {\n\t// Currently ChunkedForest and BasicTreeCursor don't handle SequenceChunks very efficiently:\n\t// they likely add more overhead than they save for now, so don't create them.\n\tsequenceChunkSplitThreshold: Number.POSITIVE_INFINITY,\n\tsequenceChunkInlineThreshold: Number.POSITIVE_INFINITY,\n\t// Current UniformChunk handling doesn't scale well to large chunks, so set a modest size limit:\n\tuniformChunkNodeCount: 400,\n\t// Without knowing what the schema is, all shapes are possible.\n\t// Use `makeTreeChunker` to do better.\n\tshapeFromSchema: () => polymorphic,\n};\n\nexport const basicOnlyChunkPolicy: ChunkPolicy = {\n\tsequenceChunkSplitThreshold: Number.POSITIVE_INFINITY,\n\tsequenceChunkInlineThreshold: Number.POSITIVE_INFINITY,\n\tuniformChunkNodeCount: 0,\n\tshapeFromSchema: () => polymorphic,\n};\n\n/**\n * Policy for how to chunk a tree.\n */\nexport interface ChunkPolicy {\n\t/**\n\t * Group sequences longer than this into into sequence chunks of this length or less.\n\t *\n\t * Must be at least 2.\n\t * Can be set to `Number.POSITIVE_INFINITY` to never introduce extra sequence chunks.\n\t */\n\treadonly sequenceChunkSplitThreshold: number;\n\n\t/**\n\t * SequenceChunks this long or shorter may get inlined into their parent chunk.\n\t */\n\treadonly sequenceChunkInlineThreshold: number;\n\n\t/**\n\t * Maximum total nodes to put in a UniformChunk.\n\t */\n\treadonly uniformChunkNodeCount: number;\n\n\t/**\n\t * Returns information about the shapes trees of type `schema` can take.\n\t */\n\tshapeFromSchema(schema: TreeNodeSchemaIdentifier): ShapeInfo;\n}\n\nexport interface ChunkCompressor {\n\treadonly policy: ChunkPolicy;\n\t/**\n\t * If the idCompressor is provided, {@link UniformChunk}s with identifiers will be encoded for its in-memory representation.\n\t * @remarks\n\t * This compression applies to {@link UniformChunk}s when {@link TreeShape.maybeDecompressedStringAsNumber} is set.\n\t * If the `policy` does not use UniformChunks or does not set `maybeDecompressedStringAsNumber`, then no compression will be applied even when providing `idCompressor`.\n\t */\n\treadonly idCompressor: IIdCompressor | undefined;\n}\n\nfunction newBasicChunkTree(\n\tcursor: ITreeCursorSynchronous,\n\tpolicy: ChunkCompressor,\n): BasicChunk {\n\treturn new BasicChunk(\n\t\tcursor.type,\n\t\tnew Map(mapCursorFields(cursor, () => [cursor.getFieldKey(), chunkField(cursor, policy)])),\n\t\tcursor.value,\n\t);\n}\n\n/**\n * @param cursor - cursor in nodes mode\n * @param policy - heuristics to impact chunking\n * @param length - how many nodes to process (at the top level)\n * @param skipLastNavigation - if true, leaves the cursor at the last node instead of moving off of it.\n */\nexport function chunkRange(\n\tcursor: ITreeCursorSynchronous,\n\tchunkCompressor: ChunkCompressor,\n\tlength: number,\n\tskipLastNavigation: boolean,\n): TreeChunk[] {\n\tassert(cursor.mode === CursorLocationType.Nodes, 0x57e /* should be in nodes */);\n\tlet output: TreeChunk[] = [];\n\tlet remaining = length;\n\twhile (remaining > 0) {\n\t\tassert(cursor.mode === CursorLocationType.Nodes, 0x57f /* should be in nodes */);\n\t\tconst start = cursor.chunkStart;\n\t\tlet reusedChunk = false;\n\t\t// symbol based fast path to check for chunk:\n\t\t// return existing chunk with a increased ref count if possible.\n\t\tif (start === cursor.fieldIndex) {\n\t\t\tconst chunkLength = cursor.chunkLength;\n\t\t\tif (chunkLength <= remaining) {\n\t\t\t\tconst chunk = tryGetChunk(cursor);\n\t\t\t\tif (chunk !== undefined) {\n\t\t\t\t\tif (\n\t\t\t\t\t\tchunk instanceof SequenceChunk &&\n\t\t\t\t\t\tchunk.subChunks.length <= chunkCompressor.policy.sequenceChunkInlineThreshold\n\t\t\t\t\t) {\n\t\t\t\t\t\t// If sequence chunk, and its very short, inline it.\n\t\t\t\t\t\t// Note that this is not recursive: there may be short sequences nested below this which are not inlined.\n\t\t\t\t\t\tfor (const subChunk of chunk.subChunks) {\n\t\t\t\t\t\t\tsubChunk.referenceAdded();\n\t\t\t\t\t\t\toutput.push(subChunk);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tchunk.referenceAdded();\n\t\t\t\t\toutput.push(chunk);\n\t\t\t\t\tremaining -= chunkLength;\n\t\t\t\t\treusedChunk = true;\n\t\t\t\t\tlet seek = chunkLength;\n\t\t\t\t\tif (skipLastNavigation && remaining === 0) {\n\t\t\t\t\t\tseek -= 1;\n\t\t\t\t\t}\n\t\t\t\t\tcursor.seekNodes(seek);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!reusedChunk) {\n\t\t\tassert(cursor.mode === CursorLocationType.Nodes, 0x580 /* should be in nodes */);\n\t\t\t// TODO: if provided, use schema to consider using UniformChunks\n\t\t\tconst type = cursor.type;\n\t\t\tconst shape = chunkCompressor.policy.shapeFromSchema(type);\n\t\t\tif (shape instanceof TreeShape) {\n\t\t\t\tconst nodesPerTopLevelNode = shape.positions.length;\n\t\t\t\tconst maxTopLevelLength = Math.ceil(\n\t\t\t\t\tnodesPerTopLevelNode / chunkCompressor.policy.uniformChunkNodeCount,\n\t\t\t\t);\n\t\t\t\tconst maxLength = Math.min(maxTopLevelLength, remaining);\n\t\t\t\tconst newChunk = uniformChunkFromCursor(\n\t\t\t\t\tcursor,\n\t\t\t\t\tshape,\n\t\t\t\t\tmaxLength,\n\t\t\t\t\tmaxLength === remaining && skipLastNavigation,\n\t\t\t\t\tchunkCompressor.idCompressor,\n\t\t\t\t);\n\t\t\t\tremaining -= newChunk.topLevelLength;\n\t\t\t\toutput.push(newChunk);\n\t\t\t} else {\n\t\t\t\t// Slow path: copy tree into new basic chunk\n\t\t\t\toutput.push(newBasicChunkTree(cursor, chunkCompressor));\n\t\t\t\tremaining -= 1;\n\t\t\t\tif (!skipLastNavigation || remaining !== 0) {\n\t\t\t\t\tcursor.nextNode();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// TODO: maybe make a pass over output to coalesce UniformChunks and/or convert other formats to UniformChunks where possible.\n\n\t// If output is large, group it into a tree of sequence chunks.\n\twhile (output.length > chunkCompressor.policy.sequenceChunkSplitThreshold) {\n\t\tconst chunkCount = Math.ceil(\n\t\t\toutput.length / chunkCompressor.policy.sequenceChunkSplitThreshold,\n\t\t);\n\t\tconst newOutput: TreeChunk[] = [];\n\t\t// Rounding down, and add an extra item to some of the chunks.\n\t\tconst chunkSize = Math.floor(output.length / chunkCount);\n\t\t// number of chunks to add an extra item to to make total line up.\n\t\tconst extra = output.length % chunkCount;\n\t\tlet previousEnd = 0;\n\t\tfor (let index = 0; index < chunkCount; index++) {\n\t\t\t// If we are in the first `extra` items, add an extra to this chunk.\n\t\t\tconst end = previousEnd + chunkSize + (index < extra ? 1 : 0);\n\t\t\tnewOutput.push(new SequenceChunk(output.slice(previousEnd, end)));\n\t\t\tpreviousEnd = end;\n\t\t}\n\t\tassert(previousEnd === output.length, 0x581 /* chunks should add up to total */);\n\t\toutput = newOutput;\n\t}\n\n\treturn output;\n}\n/**\n * @param idCompressor - compressor used to encoded string values that are compressible by the idCompressor for in-memory representation.\n * If the idCompressor is not provided, the values will be the original uncompressed values.\n */\nexport function insertValues(\n\tcursor: ITreeCursorSynchronous,\n\tshape: TreeShape,\n\tvalues: Value[],\n\tidCompressor?: IIdCompressor,\n): void {\n\tassert(shape.type === cursor.type, 0x582 /* shape and type must match */);\n\n\t// TODO:Perf:\n\t// Fast path for already part of a uniform chunk with matching shape\n\n\t// Slow path: walk shape and cursor together, inserting values.\n\tif (shape.hasValue) {\n\t\tif (\n\t\t\ttypeof cursor.value === \"string\" &&\n\t\t\tidCompressor !== undefined &&\n\t\t\tisStableNodeKey(cursor.value)\n\t\t) {\n\t\t\tvalues.push(idCompressor.tryRecompress(cursor.value) ?? cursor.value);\n\t\t} else {\n\t\t\tvalues.push(cursor.value);\n\t\t}\n\t}\n\tfor (const [key, childShape, length] of shape.fieldsArray) {\n\t\tcursor.enterField(key);\n\t\tlet count = 0;\n\t\tfor (let inNodes = cursor.firstNode(); inNodes; inNodes = cursor.nextNode()) {\n\t\t\tinsertValues(cursor, childShape, values, idCompressor);\n\t\t\tcount++;\n\t\t}\n\t\tcursor.exitField();\n\t\tassert(length === count, 0x583 /* unexpected field length */);\n\t}\n}\n\n/**\n * Read up to `maxTopLevelLength` nodes from `cursor`, stopping when limit is hit or type of node changes.\n *\n * This requires that the all trees with matching type match the provided shape.\n * This cannot be used if other shapes are possible for this type.\n *\n * If this stops early due to the type changing, `skipLastNavigation` is not involved:\n * `skipLastNavigation` only determines if the cursor will be left on the node after the last one (possibly exiting the field)\n * if the full length is used.\n *\n * @param idCompressor - compressor used to encoded string values that are compressible by the idCompressor for in-memory representation.\n * If the idCompressor is not provided, the values will be the original uncompressed values.\n */\nexport function uniformChunkFromCursor(\n\tcursor: ITreeCursorSynchronous,\n\tshape: TreeShape,\n\tmaxTopLevelLength: number,\n\tskipLastNavigation: boolean,\n\tidCompressor?: IIdCompressor,\n): UniformChunk {\n\t// TODO:\n\t// This could have a fast path for consuming already uniformly chunked data with matching shape.\n\n\tconst values: TreeValue[] = [];\n\tlet topLevelLength = 1;\n\twhile (topLevelLength <= maxTopLevelLength) {\n\t\tinsertValues(cursor, shape, values, idCompressor);\n\t\tif (topLevelLength === maxTopLevelLength) {\n\t\t\tif (!skipLastNavigation) {\n\t\t\t\tcursor.nextNode();\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcursor.nextNode();\n\t\tif (cursor.type !== shape.type) {\n\t\t\tbreak;\n\t\t}\n\t\ttopLevelLength += 1;\n\t}\n\treturn new UniformChunk(shape.withTopLevelLength(topLevelLength), values, idCompressor);\n}\n"]}
@@ -3,6 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  import { type Anchor, AnchorSet, type DeltaVisitor, type DetachedField, type FieldAnchor, type FieldKey, type ForestEvents, type IEditableForest, type ITreeCursorSynchronous, type ITreeSubscriptionCursor, ITreeSubscriptionCursorState, TreeNavigationResult, type TreeStoredSchemaSubscription, type UpPath } from "../../core/index.js";
6
+ import { type Listenable } from "../../events/index.js";
6
7
  import { BasicChunk, BasicChunkCursor, type SiblingsOrKey } from "./basicChunk.js";
7
8
  import type { ChunkedCursor, TreeChunk } from "./chunk.js";
8
9
  import { type IChunker } from "./chunkTree.js";
@@ -13,13 +14,14 @@ import type { IIdCompressor } from "@fluidframework/id-compressor";
13
14
  * This implementation focuses on performance.
14
15
  */
15
16
  export declare class ChunkedForest implements IEditableForest {
17
+ #private;
16
18
  roots: BasicChunk;
17
19
  readonly schema: TreeStoredSchemaSubscription;
18
20
  readonly chunker: IChunker;
19
21
  readonly anchors: AnchorSet;
20
22
  readonly idCompressor?: IIdCompressor | undefined;
21
23
  private activeVisitor?;
22
- private readonly events;
24
+ readonly events: Listenable<ForestEvents>;
23
25
  /**
24
26
  * @param roots - dummy node above the root under which detached fields are stored. All content of the forest is reachable from this.
25
27
  * @param schema - schema which all content in this forest is assumed to comply with.
@@ -28,7 +30,6 @@ export declare class ChunkedForest implements IEditableForest {
28
30
  */
29
31
  constructor(roots: BasicChunk, schema: TreeStoredSchemaSubscription, chunker: IChunker, anchors?: AnchorSet, idCompressor?: IIdCompressor | undefined);
30
32
  get isEmpty(): boolean;
31
- on<K extends keyof ForestEvents>(eventName: K, listener: ForestEvents[K]): () => void;
32
33
  clone(schema: TreeStoredSchemaSubscription, anchors: AnchorSet): ChunkedForest;
33
34
  forgetAnchor(anchor: Anchor): void;
34
35
  acquireVisitor(): DeltaVisitor;
@@ -1 +1 @@
1
- {"version":3,"file":"chunkedForest.d.ts","sourceRoot":"","sources":["../../../src/feature-libraries/chunked-forest/chunkedForest.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chunkedForest.d.ts","sourceRoot":"","sources":["../../../src/feature-libraries/chunked-forest/chunkedForest.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,12 @@
3
3
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
4
4
  * Licensed under the MIT License.
5
5
  */
6
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
7
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
8
+ 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");
9
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
10
+ };
11
+ var _ChunkedForest_events;
6
12
  Object.defineProperty(exports, "__esModule", { value: true });
7
13
  exports.buildChunkedForest = exports.ChunkedForest = void 0;
8
14
  const internal_1 = require("@fluidframework/core-utils/internal");
@@ -32,15 +38,13 @@ class ChunkedForest {
32
38
  this.chunker = chunker;
33
39
  this.anchors = anchors;
34
40
  this.idCompressor = idCompressor;
35
- this.events = (0, index_js_2.createEmitter)();
41
+ _ChunkedForest_events.set(this, (0, index_js_2.createEmitter)());
42
+ this.events = __classPrivateFieldGet(this, _ChunkedForest_events, "f");
36
43
  this.nextDetachedFieldIdentifier = 0;
37
44
  }
38
45
  get isEmpty() {
39
46
  return this.roots.fields.size === 0;
40
47
  }
41
- on(eventName, listener) {
42
- return this.events.on(eventName, listener);
43
- }
44
48
  clone(schema, anchors) {
45
49
  this.roots.referenceAdded();
46
50
  return new ChunkedForest(this.roots, schema, this.chunker.clone(schema), anchors);
@@ -70,17 +74,17 @@ class ChunkedForest {
70
74
  this.forest.activeVisitor = undefined;
71
75
  },
72
76
  destroy(detachedField, count) {
73
- this.forest.events.emit("beforeChange");
77
+ __classPrivateFieldGet(this.forest, _ChunkedForest_events, "f").emit("beforeChange");
74
78
  this.forest.roots.fields.delete(detachedField);
75
79
  },
76
80
  create(content, destination) {
77
- this.forest.events.emit("beforeChange");
81
+ __classPrivateFieldGet(this.forest, _ChunkedForest_events, "f").emit("beforeChange");
78
82
  const chunks = content.map((c) => (0, chunkTree_js_1.chunkTree)(c, {
79
83
  policy: this.forest.chunker,
80
84
  idCompressor: this.forest.idCompressor,
81
85
  }));
82
86
  this.forest.roots.fields.set(destination, chunks);
83
- this.forest.events.emit("afterRootFieldCreated", destination);
87
+ __classPrivateFieldGet(this.forest, _ChunkedForest_events, "f").emit("afterRootFieldCreated", destination);
84
88
  },
85
89
  attach(source, count, destination) {
86
90
  this.attachEdit(source, count, destination);
@@ -95,7 +99,7 @@ class ChunkedForest {
95
99
  * @param destination - The index in the current field at which to attach the content.
96
100
  */
97
101
  attachEdit(source, count, destination) {
98
- this.forest.events.emit("beforeChange");
102
+ __classPrivateFieldGet(this.forest, _ChunkedForest_events, "f").emit("beforeChange");
99
103
  const sourceField = this.forest.roots.fields.get(source) ?? [];
100
104
  this.forest.roots.fields.delete(source);
101
105
  if (sourceField.length === 0) {
@@ -114,7 +118,7 @@ class ChunkedForest {
114
118
  * If not specified, the detached range is destroyed.
115
119
  */
116
120
  detachEdit(source, destination) {
117
- this.forest.events.emit("beforeChange");
121
+ __classPrivateFieldGet(this.forest, _ChunkedForest_events, "f").emit("beforeChange");
118
122
  const parent = this.getParent();
119
123
  const sourceField = parent.mutableChunk.fields.get(parent.key) ?? [];
120
124
  (0, index_js_3.assertValidRange)(source, sourceField);
@@ -138,6 +142,11 @@ class ChunkedForest {
138
142
  },
139
143
  replace(newContentSource, range, oldContentDestination) {
140
144
  (0, internal_1.assert)(newContentSource !== oldContentDestination, 0x7b0 /* Replace detached source field and detached destination field must be different */);
145
+ // TODO: optimize this to: perform in-place replace in uniform chunks when possible.
146
+ // This should result in 3 cases:
147
+ // 1. In-place update of uniform chunk. No allocations, no ref count changes, no new TreeChunks.
148
+ // 2. Uniform chunk is shared: copy it (and parent path as needed), and update the copy.
149
+ // 3. Fallback to detach then attach (Which will copy parents and convert to basic chunks as needed).
141
150
  this.detachEdit(range, oldContentDestination);
142
151
  this.attachEdit(newContentSource, range.end - range.start, range.start);
143
152
  },
@@ -263,6 +272,7 @@ class ChunkedForest {
263
272
  }
264
273
  }
265
274
  exports.ChunkedForest = ChunkedForest;
275
+ _ChunkedForest_events = new WeakMap();
266
276
  class Cursor extends basicChunk_js_1.BasicChunkCursor {
267
277
  constructor(forest, state, root, siblingStack, indexStack, indexOfChunkStack, indexWithinChunkStack, siblings, index, indexOfChunk, indexWithinChunk, nestedCursor) {
268
278
  super(root, siblingStack, indexStack, indexOfChunkStack, indexWithinChunkStack, siblings, index, indexOfChunk, indexWithinChunk, nestedCursor);
@@ -1 +1 @@
1
- {"version":3,"file":"chunkedForest.js","sourceRoot":"","sources":["../../../src/feature-libraries/chunked-forest/chunkedForest.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 { assert, oob } from \"@fluidframework/core-utils/internal\";\n\nimport {\n\ttype Anchor,\n\tAnchorSet,\n\ttype DeltaVisitor,\n\ttype DetachedField,\n\ttype FieldAnchor,\n\ttype FieldKey,\n\ttype ForestEvents,\n\ttype IEditableForest,\n\ttype ITreeCursorSynchronous,\n\ttype ITreeSubscriptionCursor,\n\tITreeSubscriptionCursorState,\n\ttype PlaceIndex,\n\ttype ProtoNodes,\n\ttype Range,\n\tTreeNavigationResult,\n\ttype TreeStoredSchemaSubscription,\n\ttype UpPath,\n\taboveRootPlaceholder,\n\tdetachedFieldAsKey,\n\tmapCursorField,\n\trootFieldKey,\n} from \"../../core/index.js\";\nimport { createEmitter } from \"../../events/index.js\";\nimport { assertValidRange, brand, fail, getOrAddEmptyToMap } from \"../../util/index.js\";\n\nimport { BasicChunk, BasicChunkCursor, type SiblingsOrKey } from \"./basicChunk.js\";\nimport type { ChunkedCursor, TreeChunk } from \"./chunk.js\";\nimport { type IChunker, basicChunkTree, chunkTree } from \"./chunkTree.js\";\nimport type { IIdCompressor } from \"@fluidframework/id-compressor\";\n\nfunction makeRoot(): BasicChunk {\n\treturn new BasicChunk(aboveRootPlaceholder, new Map());\n}\n\ninterface StackNode {\n\tmutableChunk: BasicChunk;\n\tkey: FieldKey;\n}\n\n/**\n * Implementation of IEditableForest based on copy on write chunks.\n *\n * This implementation focuses on performance.\n */\nexport class ChunkedForest implements IEditableForest {\n\tprivate activeVisitor?: DeltaVisitor;\n\n\tprivate readonly events = createEmitter<ForestEvents>();\n\n\t/**\n\t * @param roots - dummy node above the root under which detached fields are stored. All content of the forest is reachable from this.\n\t * @param schema - schema which all content in this forest is assumed to comply with.\n\t * @param chunker - Chunking policy. TODO: dispose of this when forest is disposed.\n\t * @param anchors - anchorSet used to track location in this forest across changes. Callers of applyDelta must ensure this is updated accordingly.\n\t */\n\tpublic constructor(\n\t\tpublic roots: BasicChunk,\n\t\tpublic readonly schema: TreeStoredSchemaSubscription,\n\t\tpublic readonly chunker: IChunker,\n\t\tpublic readonly anchors: AnchorSet = new AnchorSet(),\n\t\tpublic readonly idCompressor?: IIdCompressor,\n\t) {}\n\n\tpublic get isEmpty(): boolean {\n\t\treturn this.roots.fields.size === 0;\n\t}\n\n\tpublic on<K extends keyof ForestEvents>(\n\t\teventName: K,\n\t\tlistener: ForestEvents[K],\n\t): () => void {\n\t\treturn this.events.on(eventName, listener);\n\t}\n\n\tpublic clone(schema: TreeStoredSchemaSubscription, anchors: AnchorSet): ChunkedForest {\n\t\tthis.roots.referenceAdded();\n\t\treturn new ChunkedForest(this.roots, schema, this.chunker.clone(schema), anchors);\n\t}\n\n\tpublic forgetAnchor(anchor: Anchor): void {\n\t\tthis.anchors.forget(anchor);\n\t}\n\n\tpublic acquireVisitor(): DeltaVisitor {\n\t\tassert(\n\t\t\tthis.activeVisitor === undefined,\n\t\t\t0x76a /* Must release existing visitor before acquiring another */,\n\t\t);\n\n\t\tif (this.roots.isShared()) {\n\t\t\tthis.roots = this.roots.clone();\n\t\t}\n\n\t\tconst visitor = {\n\t\t\tforest: this,\n\t\t\t// Current location in the tree, as a non-shared BasicChunk (TODO: support in-place modification of other chunk formats when possible).\n\t\t\t// Start above root detached sequences.\n\t\t\tmutableChunkStack: [] as StackNode[],\n\t\t\tmutableChunk: this.roots as BasicChunk | undefined,\n\t\t\tgetParent(): StackNode {\n\t\t\t\tassert(this.mutableChunkStack.length > 0, 0x532 /* invalid access to root's parent */);\n\t\t\t\treturn this.mutableChunkStack[this.mutableChunkStack.length - 1] ?? oob();\n\t\t\t},\n\t\t\tfree(): void {\n\t\t\t\tthis.mutableChunk = undefined;\n\t\t\t\tthis.mutableChunkStack.length = 0;\n\t\t\t\tassert(\n\t\t\t\t\tthis.forest.activeVisitor !== undefined,\n\t\t\t\t\t0x76b /* Multiple free calls for same visitor */,\n\t\t\t\t);\n\t\t\t\tthis.forest.activeVisitor = undefined;\n\t\t\t},\n\t\t\tdestroy(detachedField: FieldKey, count: number): void {\n\t\t\t\tthis.forest.events.emit(\"beforeChange\");\n\t\t\t\tthis.forest.roots.fields.delete(detachedField);\n\t\t\t},\n\t\t\tcreate(content: ProtoNodes, destination: FieldKey): void {\n\t\t\t\tthis.forest.events.emit(\"beforeChange\");\n\t\t\t\tconst chunks: TreeChunk[] = content.map((c) =>\n\t\t\t\t\tchunkTree(c, {\n\t\t\t\t\t\tpolicy: this.forest.chunker,\n\t\t\t\t\t\tidCompressor: this.forest.idCompressor,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tthis.forest.roots.fields.set(destination, chunks);\n\t\t\t\tthis.forest.events.emit(\"afterRootFieldCreated\", destination);\n\t\t\t},\n\t\t\tattach(source: FieldKey, count: number, destination: PlaceIndex): void {\n\t\t\t\tthis.attachEdit(source, count, destination);\n\t\t\t},\n\t\t\tdetach(source: Range, destination: FieldKey): void {\n\t\t\t\tthis.detachEdit(source, destination);\n\t\t\t},\n\t\t\t/**\n\t\t\t * Attaches the range into the current field by transferring it from the given source path.\n\t\t\t * Does not invalidate dependents.\n\t\t\t * @param source - The the range to be attached.\n\t\t\t * @param destination - The index in the current field at which to attach the content.\n\t\t\t */\n\t\t\tattachEdit(source: FieldKey, count: number, destination: PlaceIndex): void {\n\t\t\t\tthis.forest.events.emit(\"beforeChange\");\n\t\t\t\tconst sourceField = this.forest.roots.fields.get(source) ?? [];\n\t\t\t\tthis.forest.roots.fields.delete(source);\n\t\t\t\tif (sourceField.length === 0) {\n\t\t\t\t\treturn; // Prevent creating 0 sized fields when inserting empty into empty.\n\t\t\t\t}\n\n\t\t\t\tconst parent = this.getParent();\n\t\t\t\tconst destinationField = getOrAddEmptyToMap(parent.mutableChunk.fields, parent.key);\n\t\t\t\t// TODO: this will fail for very large moves due to argument limits.\n\t\t\t\tdestinationField.splice(destination, 0, ...sourceField);\n\t\t\t},\n\t\t\t/**\n\t\t\t * Detaches the range from the current field and transfers it to the given destination if any.\n\t\t\t * Does not invalidate dependents.\n\t\t\t * @param source - The bounds of the range to be detached from the current field.\n\t\t\t * @param destination - If specified, the destination to transfer the detached range to.\n\t\t\t * If not specified, the detached range is destroyed.\n\t\t\t */\n\t\t\tdetachEdit(source: Range, destination: FieldKey | undefined): void {\n\t\t\t\tthis.forest.events.emit(\"beforeChange\");\n\t\t\t\tconst parent = this.getParent();\n\t\t\t\tconst sourceField = parent.mutableChunk.fields.get(parent.key) ?? [];\n\n\t\t\t\tassertValidRange(source, sourceField);\n\t\t\t\tconst newField = sourceField.splice(source.start, source.end - source.start);\n\n\t\t\t\tif (destination !== undefined) {\n\t\t\t\t\tassert(\n\t\t\t\t\t\t!this.forest.roots.fields.has(destination),\n\t\t\t\t\t\t0x7af /* Destination must be a new empty detached field */,\n\t\t\t\t\t);\n\t\t\t\t\tif (newField.length > 0) {\n\t\t\t\t\t\tthis.forest.roots.fields.set(destination, newField);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tfor (const child of newField) {\n\t\t\t\t\t\tchild.referenceRemoved();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// This check is performed after the transfer to ensure that the field is not removed in scenarios\n\t\t\t\t// where the source and destination are the same.\n\t\t\t\tif (sourceField.length === 0) {\n\t\t\t\t\tparent.mutableChunk.fields.delete(parent.key);\n\t\t\t\t}\n\t\t\t},\n\t\t\treplace(\n\t\t\t\tnewContentSource: FieldKey,\n\t\t\t\trange: Range,\n\t\t\t\toldContentDestination: FieldKey,\n\t\t\t): void {\n\t\t\t\tassert(\n\t\t\t\t\tnewContentSource !== oldContentDestination,\n\t\t\t\t\t0x7b0 /* Replace detached source field and detached destination field must be different */,\n\t\t\t\t);\n\t\t\t\tthis.detachEdit(range, oldContentDestination);\n\t\t\t\tthis.attachEdit(newContentSource, range.end - range.start, range.start);\n\t\t\t},\n\t\t\tenterNode(index: number): void {\n\t\t\t\tassert(this.mutableChunk === undefined, 0x535 /* should be in field */);\n\t\t\t\tconst parent = this.getParent();\n\t\t\t\tconst chunks =\n\t\t\t\t\tparent.mutableChunk.fields.get(parent.key) ?? fail(\"missing edited field\");\n\t\t\t\tlet indexWithinChunk = index;\n\t\t\t\tlet indexOfChunk = 0;\n\t\t\t\tlet chunk = chunks[indexOfChunk] ?? oob();\n\t\t\t\twhile (indexWithinChunk >= chunk.topLevelLength) {\n\t\t\t\t\tchunk = chunks[indexOfChunk] ?? oob();\n\t\t\t\t\tindexWithinChunk -= chunk.topLevelLength;\n\t\t\t\t\tindexOfChunk++;\n\t\t\t\t\tif (indexOfChunk === chunks.length) {\n\t\t\t\t\t\tfail(\"missing edited node\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlet found = chunks[indexOfChunk] ?? oob();\n\t\t\t\tif (!(found instanceof BasicChunk)) {\n\t\t\t\t\t// TODO:Perf: support in place editing of other chunk formats when possible:\n\t\t\t\t\t// 1. Support updating values in uniform chunks.\n\t\t\t\t\t// 2. Support traversing sequence chunks.\n\t\t\t\t\t//\n\t\t\t\t\t// Maybe build path when visitor navigates then lazily sync to chunk tree when editing?\n\t\t\t\t\tconst newChunks = mapCursorField(found.cursor(), (cursor) =>\n\t\t\t\t\t\tbasicChunkTree(cursor, {\n\t\t\t\t\t\t\tpolicy: this.forest.chunker,\n\t\t\t\t\t\t\tidCompressor: this.forest.idCompressor,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t\t// TODO: this could fail for really long chunks being split (due to argument count limits).\n\t\t\t\t\t// Current implementations of chunks shouldn't ever be that long, but it could be an issue if they get bigger.\n\t\t\t\t\tchunks.splice(indexOfChunk, 1, ...newChunks);\n\t\t\t\t\tfound.referenceRemoved();\n\n\t\t\t\t\tfound = newChunks[indexWithinChunk] ?? oob();\n\t\t\t\t}\n\t\t\t\tassert(found instanceof BasicChunk, 0x536 /* chunk should have been normalized */);\n\t\t\t\tif (found.isShared()) {\n\t\t\t\t\tthis.mutableChunk = chunks[indexOfChunk] = found.clone();\n\t\t\t\t\tfound.referenceRemoved();\n\t\t\t\t} else {\n\t\t\t\t\tthis.mutableChunk = found;\n\t\t\t\t}\n\t\t\t},\n\t\t\texitNode(index: number): void {\n\t\t\t\tassert(this.mutableChunk !== undefined, 0x537 /* should be in node */);\n\t\t\t\tthis.mutableChunk = undefined;\n\t\t\t},\n\t\t\tenterField(key: FieldKey): void {\n\t\t\t\tassert(this.mutableChunk !== undefined, 0x538 /* should be in node */);\n\t\t\t\tthis.mutableChunkStack.push({ key, mutableChunk: this.mutableChunk });\n\t\t\t\tthis.mutableChunk = undefined;\n\t\t\t},\n\t\t\texitField(key: FieldKey): void {\n\t\t\t\tconst top = this.mutableChunkStack.pop() ?? fail(\"should not be at root\");\n\t\t\t\tassert(this.mutableChunk === undefined, 0x539 /* should be in field */);\n\t\t\t\tthis.mutableChunk = top.mutableChunk;\n\t\t\t},\n\t\t};\n\t\tthis.activeVisitor = visitor;\n\t\treturn visitor;\n\t}\n\n\tprivate nextDetachedFieldIdentifier = 0;\n\tpublic newDetachedField(): DetachedField {\n\t\tconst field: DetachedField = brand(String(this.nextDetachedFieldIdentifier));\n\t\tassert(\n\t\t\t!this.roots.fields.has(detachedFieldAsKey(field)),\n\t\t\t0x53a /* new field must not already exist */,\n\t\t);\n\t\tthis.nextDetachedFieldIdentifier += 1;\n\t\treturn field;\n\t}\n\n\tpublic allocateCursor(): Cursor {\n\t\treturn new Cursor(\n\t\t\tthis,\n\t\t\tITreeSubscriptionCursorState.Cleared,\n\t\t\t[],\n\t\t\t[],\n\t\t\t[],\n\t\t\t[],\n\t\t\t[],\n\t\t\t[],\n\t\t\t0,\n\t\t\t0,\n\t\t\t0,\n\t\t\tundefined,\n\t\t);\n\t}\n\n\tpublic tryMoveCursorToNode(\n\t\tdestination: Anchor,\n\t\tcursorToMove: ITreeSubscriptionCursor,\n\t): TreeNavigationResult {\n\t\tconst path = this.anchors.locate(destination);\n\t\tif (path === undefined) {\n\t\t\treturn TreeNavigationResult.NotFound;\n\t\t}\n\t\tthis.moveCursorToPath(path, cursorToMove);\n\t\treturn TreeNavigationResult.Ok;\n\t}\n\n\tpublic tryMoveCursorToField(\n\t\tdestination: FieldAnchor,\n\t\tcursorToMove: ITreeSubscriptionCursor,\n\t): TreeNavigationResult {\n\t\tassert(\n\t\t\tcursorToMove instanceof Cursor,\n\t\t\t0x53b /* ChunkedForest must only be given its own Cursor type */,\n\t\t);\n\t\tif (destination.parent === undefined) {\n\t\t\tcursorToMove.setToDetachedSequence(destination.fieldKey);\n\t\t\treturn TreeNavigationResult.Ok;\n\t\t}\n\t\tconst result = this.tryMoveCursorToNode(destination.parent, cursorToMove);\n\t\tif (result !== TreeNavigationResult.Ok) {\n\t\t\treturn result;\n\t\t}\n\n\t\tcursorToMove.enterField(destination.fieldKey);\n\t\treturn TreeNavigationResult.Ok;\n\t}\n\n\tpublic moveCursorToPath(destination: UpPath, cursorToMove: ITreeSubscriptionCursor): void {\n\t\tassert(\n\t\t\tcursorToMove instanceof Cursor,\n\t\t\t0x53c /* ChunkedForest must only be given its own Cursor type */,\n\t\t);\n\t\tassert(\n\t\t\tcursorToMove.forest === this,\n\t\t\t0x53d /* ChunkedForest must only be given its own Cursor */,\n\t\t);\n\n\t\tconst indexStack: number[] = [];\n\t\tconst keyStack: FieldKey[] = [];\n\n\t\tlet path: UpPath | undefined = destination;\n\t\twhile (path !== undefined) {\n\t\t\tindexStack.push(path.parentIndex);\n\t\t\tkeyStack.push(path.parentField);\n\t\t\tpath = path.parent;\n\t\t}\n\t\tcursorToMove.clear();\n\t\twhile (keyStack.length > 0) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tconst key = keyStack.pop()!;\n\t\t\tif (cursorToMove.state === ITreeSubscriptionCursorState.Cleared) {\n\t\t\t\tcursorToMove.setToDetachedSequence(key);\n\t\t\t\tcursorToMove.state = ITreeSubscriptionCursorState.Current;\n\t\t\t} else {\n\t\t\t\tcursorToMove.enterField(key);\n\t\t\t}\n\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tcursorToMove.enterNode(indexStack.pop()!);\n\t\t}\n\t}\n\n\tpublic getCursorAboveDetachedFields(): ITreeCursorSynchronous {\n\t\tconst rootCursor = this.roots.cursor();\n\t\trootCursor.enterNode(0);\n\t\treturn rootCursor;\n\t}\n}\n\nclass Cursor extends BasicChunkCursor implements ITreeSubscriptionCursor {\n\tpublic constructor(\n\t\tpublic readonly forest: ChunkedForest,\n\t\tpublic state: ITreeSubscriptionCursorState,\n\t\troot: readonly TreeChunk[],\n\t\tsiblingStack: SiblingsOrKey[],\n\t\tindexStack: number[],\n\t\tindexOfChunkStack: number[],\n\t\tindexWithinChunkStack: number[],\n\t\tsiblings: SiblingsOrKey,\n\t\tindex: number,\n\t\tindexOfChunk: number,\n\t\tindexWithinChunk: number,\n\t\tnestedCursor: ChunkedCursor | undefined,\n\t) {\n\t\tsuper(\n\t\t\troot,\n\t\t\tsiblingStack,\n\t\t\tindexStack,\n\t\t\tindexOfChunkStack,\n\t\t\tindexWithinChunkStack,\n\t\t\tsiblings,\n\t\t\tindex,\n\t\t\tindexOfChunk,\n\t\t\tindexWithinChunk,\n\t\t\tnestedCursor,\n\t\t);\n\t}\n\n\tpublic setToDetachedSequence(key: FieldKey): void {\n\t\tthis.root = (this.forest.roots.fields.get(key) ?? []) as BasicChunk[];\n\t\tthis.siblingStack.length = 0;\n\t\tthis.indexStack.length = 0;\n\t\tthis.indexOfChunkStack.length = 0;\n\t\tthis.indexWithinChunkStack.length = 0;\n\t\tthis.siblings = [key];\n\t\tthis.index = 0;\n\t\tthis.indexOfChunk = 0;\n\t\tthis.indexWithinChunk = 0;\n\t\tthis.nestedCursor = undefined;\n\t}\n\n\tpublic override fork(): Cursor {\n\t\t// Siblings arrays are not modified during navigation and do not need be be copied.\n\t\t// This allows this copy to be shallow, and `this.siblings` below to not be copied as all.\n\t\treturn new Cursor(\n\t\t\tthis.forest,\n\t\t\tthis.state,\n\t\t\tthis.root,\n\t\t\t[...this.siblingStack],\n\t\t\t[...this.indexStack],\n\t\t\t[...this.indexOfChunkStack],\n\t\t\t[...this.indexWithinChunkStack],\n\t\t\tthis.siblings,\n\t\t\tthis.index,\n\t\t\tthis.indexOfChunk,\n\t\t\tthis.indexWithinChunk,\n\t\t\tthis.nestedCursor?.fork(),\n\t\t);\n\t}\n\n\tpublic buildFieldAnchor(): FieldAnchor {\n\t\tconst path = this.getFieldPath();\n\t\tconst anchor =\n\t\t\tpath.parent === undefined ? undefined : this.forest.anchors.track(path.parent);\n\t\treturn { parent: anchor, fieldKey: path.field };\n\t}\n\n\tpublic free(): void {\n\t\tthis.state = ITreeSubscriptionCursorState.Freed;\n\t}\n\n\tpublic buildAnchor(): Anchor {\n\t\treturn this.forest.anchors.track(this.getPath());\n\t}\n\n\tpublic clear(): void {\n\t\tthis.state = ITreeSubscriptionCursorState.Cleared;\n\t\tthis.setToDetachedSequence(rootFieldKey);\n\t}\n}\n\n/**\n * @returns an implementation of {@link IEditableForest} with no data or schema.\n */\nexport function buildChunkedForest(\n\tchunker: IChunker,\n\tanchors?: AnchorSet,\n\tidCompressor?: IIdCompressor,\n): ChunkedForest {\n\treturn new ChunkedForest(makeRoot(), chunker.schema, chunker, anchors, idCompressor);\n}\n"]}
1
+ {"version":3,"file":"chunkedForest.js","sourceRoot":"","sources":["../../../src/feature-libraries/chunked-forest/chunkedForest.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 { assert, oob } from \"@fluidframework/core-utils/internal\";\n\nimport {\n\ttype Anchor,\n\tAnchorSet,\n\ttype DeltaVisitor,\n\ttype DetachedField,\n\ttype FieldAnchor,\n\ttype FieldKey,\n\ttype ForestEvents,\n\ttype IEditableForest,\n\ttype ITreeCursorSynchronous,\n\ttype ITreeSubscriptionCursor,\n\tITreeSubscriptionCursorState,\n\ttype PlaceIndex,\n\ttype ProtoNodes,\n\ttype Range,\n\tTreeNavigationResult,\n\ttype TreeStoredSchemaSubscription,\n\ttype UpPath,\n\taboveRootPlaceholder,\n\tdetachedFieldAsKey,\n\tmapCursorField,\n\trootFieldKey,\n} from \"../../core/index.js\";\nimport { createEmitter, type Listenable } from \"../../events/index.js\";\nimport { assertValidRange, brand, fail, getOrAddEmptyToMap } from \"../../util/index.js\";\n\nimport { BasicChunk, BasicChunkCursor, type SiblingsOrKey } from \"./basicChunk.js\";\nimport type { ChunkedCursor, TreeChunk } from \"./chunk.js\";\nimport { type IChunker, basicChunkTree, chunkTree } from \"./chunkTree.js\";\nimport type { IIdCompressor } from \"@fluidframework/id-compressor\";\n\nfunction makeRoot(): BasicChunk {\n\treturn new BasicChunk(aboveRootPlaceholder, new Map());\n}\n\ninterface StackNode {\n\tmutableChunk: BasicChunk;\n\tkey: FieldKey;\n}\n\n/**\n * Implementation of IEditableForest based on copy on write chunks.\n *\n * This implementation focuses on performance.\n */\nexport class ChunkedForest implements IEditableForest {\n\tprivate activeVisitor?: DeltaVisitor;\n\n\treadonly #events = createEmitter<ForestEvents>();\n\tpublic readonly events: Listenable<ForestEvents> = this.#events;\n\n\t/**\n\t * @param roots - dummy node above the root under which detached fields are stored. All content of the forest is reachable from this.\n\t * @param schema - schema which all content in this forest is assumed to comply with.\n\t * @param chunker - Chunking policy. TODO: dispose of this when forest is disposed.\n\t * @param anchors - anchorSet used to track location in this forest across changes. Callers of applyDelta must ensure this is updated accordingly.\n\t */\n\tpublic constructor(\n\t\tpublic roots: BasicChunk,\n\t\tpublic readonly schema: TreeStoredSchemaSubscription,\n\t\tpublic readonly chunker: IChunker,\n\t\tpublic readonly anchors: AnchorSet = new AnchorSet(),\n\t\tpublic readonly idCompressor?: IIdCompressor,\n\t) {}\n\n\tpublic get isEmpty(): boolean {\n\t\treturn this.roots.fields.size === 0;\n\t}\n\n\tpublic clone(schema: TreeStoredSchemaSubscription, anchors: AnchorSet): ChunkedForest {\n\t\tthis.roots.referenceAdded();\n\t\treturn new ChunkedForest(this.roots, schema, this.chunker.clone(schema), anchors);\n\t}\n\n\tpublic forgetAnchor(anchor: Anchor): void {\n\t\tthis.anchors.forget(anchor);\n\t}\n\n\tpublic acquireVisitor(): DeltaVisitor {\n\t\tassert(\n\t\t\tthis.activeVisitor === undefined,\n\t\t\t0x76a /* Must release existing visitor before acquiring another */,\n\t\t);\n\n\t\tif (this.roots.isShared()) {\n\t\t\tthis.roots = this.roots.clone();\n\t\t}\n\n\t\tconst visitor = {\n\t\t\tforest: this,\n\t\t\t// Current location in the tree, as a non-shared BasicChunk (TODO: support in-place modification of other chunk formats when possible).\n\t\t\t// Start above root detached sequences.\n\t\t\tmutableChunkStack: [] as StackNode[],\n\t\t\tmutableChunk: this.roots as BasicChunk | undefined,\n\t\t\tgetParent(): StackNode {\n\t\t\t\tassert(this.mutableChunkStack.length > 0, 0x532 /* invalid access to root's parent */);\n\t\t\t\treturn this.mutableChunkStack[this.mutableChunkStack.length - 1] ?? oob();\n\t\t\t},\n\t\t\tfree(): void {\n\t\t\t\tthis.mutableChunk = undefined;\n\t\t\t\tthis.mutableChunkStack.length = 0;\n\t\t\t\tassert(\n\t\t\t\t\tthis.forest.activeVisitor !== undefined,\n\t\t\t\t\t0x76b /* Multiple free calls for same visitor */,\n\t\t\t\t);\n\t\t\t\tthis.forest.activeVisitor = undefined;\n\t\t\t},\n\t\t\tdestroy(detachedField: FieldKey, count: number): void {\n\t\t\t\tthis.forest.#events.emit(\"beforeChange\");\n\t\t\t\tthis.forest.roots.fields.delete(detachedField);\n\t\t\t},\n\t\t\tcreate(content: ProtoNodes, destination: FieldKey): void {\n\t\t\t\tthis.forest.#events.emit(\"beforeChange\");\n\t\t\t\tconst chunks: TreeChunk[] = content.map((c) =>\n\t\t\t\t\tchunkTree(c, {\n\t\t\t\t\t\tpolicy: this.forest.chunker,\n\t\t\t\t\t\tidCompressor: this.forest.idCompressor,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tthis.forest.roots.fields.set(destination, chunks);\n\t\t\t\tthis.forest.#events.emit(\"afterRootFieldCreated\", destination);\n\t\t\t},\n\t\t\tattach(source: FieldKey, count: number, destination: PlaceIndex): void {\n\t\t\t\tthis.attachEdit(source, count, destination);\n\t\t\t},\n\t\t\tdetach(source: Range, destination: FieldKey): void {\n\t\t\t\tthis.detachEdit(source, destination);\n\t\t\t},\n\t\t\t/**\n\t\t\t * Attaches the range into the current field by transferring it from the given source path.\n\t\t\t * Does not invalidate dependents.\n\t\t\t * @param source - The the range to be attached.\n\t\t\t * @param destination - The index in the current field at which to attach the content.\n\t\t\t */\n\t\t\tattachEdit(source: FieldKey, count: number, destination: PlaceIndex): void {\n\t\t\t\tthis.forest.#events.emit(\"beforeChange\");\n\t\t\t\tconst sourceField = this.forest.roots.fields.get(source) ?? [];\n\t\t\t\tthis.forest.roots.fields.delete(source);\n\t\t\t\tif (sourceField.length === 0) {\n\t\t\t\t\treturn; // Prevent creating 0 sized fields when inserting empty into empty.\n\t\t\t\t}\n\n\t\t\t\tconst parent = this.getParent();\n\t\t\t\tconst destinationField = getOrAddEmptyToMap(parent.mutableChunk.fields, parent.key);\n\t\t\t\t// TODO: this will fail for very large moves due to argument limits.\n\t\t\t\tdestinationField.splice(destination, 0, ...sourceField);\n\t\t\t},\n\t\t\t/**\n\t\t\t * Detaches the range from the current field and transfers it to the given destination if any.\n\t\t\t * Does not invalidate dependents.\n\t\t\t * @param source - The bounds of the range to be detached from the current field.\n\t\t\t * @param destination - If specified, the destination to transfer the detached range to.\n\t\t\t * If not specified, the detached range is destroyed.\n\t\t\t */\n\t\t\tdetachEdit(source: Range, destination: FieldKey | undefined): void {\n\t\t\t\tthis.forest.#events.emit(\"beforeChange\");\n\t\t\t\tconst parent = this.getParent();\n\t\t\t\tconst sourceField = parent.mutableChunk.fields.get(parent.key) ?? [];\n\n\t\t\t\tassertValidRange(source, sourceField);\n\t\t\t\tconst newField = sourceField.splice(source.start, source.end - source.start);\n\n\t\t\t\tif (destination !== undefined) {\n\t\t\t\t\tassert(\n\t\t\t\t\t\t!this.forest.roots.fields.has(destination),\n\t\t\t\t\t\t0x7af /* Destination must be a new empty detached field */,\n\t\t\t\t\t);\n\t\t\t\t\tif (newField.length > 0) {\n\t\t\t\t\t\tthis.forest.roots.fields.set(destination, newField);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tfor (const child of newField) {\n\t\t\t\t\t\tchild.referenceRemoved();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// This check is performed after the transfer to ensure that the field is not removed in scenarios\n\t\t\t\t// where the source and destination are the same.\n\t\t\t\tif (sourceField.length === 0) {\n\t\t\t\t\tparent.mutableChunk.fields.delete(parent.key);\n\t\t\t\t}\n\t\t\t},\n\t\t\treplace(\n\t\t\t\tnewContentSource: FieldKey,\n\t\t\t\trange: Range,\n\t\t\t\toldContentDestination: FieldKey,\n\t\t\t): void {\n\t\t\t\tassert(\n\t\t\t\t\tnewContentSource !== oldContentDestination,\n\t\t\t\t\t0x7b0 /* Replace detached source field and detached destination field must be different */,\n\t\t\t\t);\n\t\t\t\t// TODO: optimize this to: perform in-place replace in uniform chunks when possible.\n\t\t\t\t// This should result in 3 cases:\n\t\t\t\t// 1. In-place update of uniform chunk. No allocations, no ref count changes, no new TreeChunks.\n\t\t\t\t// 2. Uniform chunk is shared: copy it (and parent path as needed), and update the copy.\n\t\t\t\t// 3. Fallback to detach then attach (Which will copy parents and convert to basic chunks as needed).\n\t\t\t\tthis.detachEdit(range, oldContentDestination);\n\t\t\t\tthis.attachEdit(newContentSource, range.end - range.start, range.start);\n\t\t\t},\n\t\t\tenterNode(index: number): void {\n\t\t\t\tassert(this.mutableChunk === undefined, 0x535 /* should be in field */);\n\t\t\t\tconst parent = this.getParent();\n\t\t\t\tconst chunks =\n\t\t\t\t\tparent.mutableChunk.fields.get(parent.key) ?? fail(\"missing edited field\");\n\t\t\t\tlet indexWithinChunk = index;\n\t\t\t\tlet indexOfChunk = 0;\n\t\t\t\tlet chunk = chunks[indexOfChunk] ?? oob();\n\t\t\t\twhile (indexWithinChunk >= chunk.topLevelLength) {\n\t\t\t\t\tchunk = chunks[indexOfChunk] ?? oob();\n\t\t\t\t\tindexWithinChunk -= chunk.topLevelLength;\n\t\t\t\t\tindexOfChunk++;\n\t\t\t\t\tif (indexOfChunk === chunks.length) {\n\t\t\t\t\t\tfail(\"missing edited node\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlet found = chunks[indexOfChunk] ?? oob();\n\t\t\t\tif (!(found instanceof BasicChunk)) {\n\t\t\t\t\t// TODO:Perf: support in place editing of other chunk formats when possible:\n\t\t\t\t\t// 1. Support updating values in uniform chunks.\n\t\t\t\t\t// 2. Support traversing sequence chunks.\n\t\t\t\t\t//\n\t\t\t\t\t// Maybe build path when visitor navigates then lazily sync to chunk tree when editing?\n\t\t\t\t\tconst newChunks = mapCursorField(found.cursor(), (cursor) =>\n\t\t\t\t\t\tbasicChunkTree(cursor, {\n\t\t\t\t\t\t\tpolicy: this.forest.chunker,\n\t\t\t\t\t\t\tidCompressor: this.forest.idCompressor,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t\t// TODO: this could fail for really long chunks being split (due to argument count limits).\n\t\t\t\t\t// Current implementations of chunks shouldn't ever be that long, but it could be an issue if they get bigger.\n\t\t\t\t\tchunks.splice(indexOfChunk, 1, ...newChunks);\n\t\t\t\t\tfound.referenceRemoved();\n\n\t\t\t\t\tfound = newChunks[indexWithinChunk] ?? oob();\n\t\t\t\t}\n\t\t\t\tassert(found instanceof BasicChunk, 0x536 /* chunk should have been normalized */);\n\t\t\t\tif (found.isShared()) {\n\t\t\t\t\tthis.mutableChunk = chunks[indexOfChunk] = found.clone();\n\t\t\t\t\tfound.referenceRemoved();\n\t\t\t\t} else {\n\t\t\t\t\tthis.mutableChunk = found;\n\t\t\t\t}\n\t\t\t},\n\t\t\texitNode(index: number): void {\n\t\t\t\tassert(this.mutableChunk !== undefined, 0x537 /* should be in node */);\n\t\t\t\tthis.mutableChunk = undefined;\n\t\t\t},\n\t\t\tenterField(key: FieldKey): void {\n\t\t\t\tassert(this.mutableChunk !== undefined, 0x538 /* should be in node */);\n\t\t\t\tthis.mutableChunkStack.push({ key, mutableChunk: this.mutableChunk });\n\t\t\t\tthis.mutableChunk = undefined;\n\t\t\t},\n\t\t\texitField(key: FieldKey): void {\n\t\t\t\tconst top = this.mutableChunkStack.pop() ?? fail(\"should not be at root\");\n\t\t\t\tassert(this.mutableChunk === undefined, 0x539 /* should be in field */);\n\t\t\t\tthis.mutableChunk = top.mutableChunk;\n\t\t\t},\n\t\t};\n\t\tthis.activeVisitor = visitor;\n\t\treturn visitor;\n\t}\n\n\tprivate nextDetachedFieldIdentifier = 0;\n\tpublic newDetachedField(): DetachedField {\n\t\tconst field: DetachedField = brand(String(this.nextDetachedFieldIdentifier));\n\t\tassert(\n\t\t\t!this.roots.fields.has(detachedFieldAsKey(field)),\n\t\t\t0x53a /* new field must not already exist */,\n\t\t);\n\t\tthis.nextDetachedFieldIdentifier += 1;\n\t\treturn field;\n\t}\n\n\tpublic allocateCursor(): Cursor {\n\t\treturn new Cursor(\n\t\t\tthis,\n\t\t\tITreeSubscriptionCursorState.Cleared,\n\t\t\t[],\n\t\t\t[],\n\t\t\t[],\n\t\t\t[],\n\t\t\t[],\n\t\t\t[],\n\t\t\t0,\n\t\t\t0,\n\t\t\t0,\n\t\t\tundefined,\n\t\t);\n\t}\n\n\tpublic tryMoveCursorToNode(\n\t\tdestination: Anchor,\n\t\tcursorToMove: ITreeSubscriptionCursor,\n\t): TreeNavigationResult {\n\t\tconst path = this.anchors.locate(destination);\n\t\tif (path === undefined) {\n\t\t\treturn TreeNavigationResult.NotFound;\n\t\t}\n\t\tthis.moveCursorToPath(path, cursorToMove);\n\t\treturn TreeNavigationResult.Ok;\n\t}\n\n\tpublic tryMoveCursorToField(\n\t\tdestination: FieldAnchor,\n\t\tcursorToMove: ITreeSubscriptionCursor,\n\t): TreeNavigationResult {\n\t\tassert(\n\t\t\tcursorToMove instanceof Cursor,\n\t\t\t0x53b /* ChunkedForest must only be given its own Cursor type */,\n\t\t);\n\t\tif (destination.parent === undefined) {\n\t\t\tcursorToMove.setToDetachedSequence(destination.fieldKey);\n\t\t\treturn TreeNavigationResult.Ok;\n\t\t}\n\t\tconst result = this.tryMoveCursorToNode(destination.parent, cursorToMove);\n\t\tif (result !== TreeNavigationResult.Ok) {\n\t\t\treturn result;\n\t\t}\n\n\t\tcursorToMove.enterField(destination.fieldKey);\n\t\treturn TreeNavigationResult.Ok;\n\t}\n\n\tpublic moveCursorToPath(destination: UpPath, cursorToMove: ITreeSubscriptionCursor): void {\n\t\tassert(\n\t\t\tcursorToMove instanceof Cursor,\n\t\t\t0x53c /* ChunkedForest must only be given its own Cursor type */,\n\t\t);\n\t\tassert(\n\t\t\tcursorToMove.forest === this,\n\t\t\t0x53d /* ChunkedForest must only be given its own Cursor */,\n\t\t);\n\n\t\tconst indexStack: number[] = [];\n\t\tconst keyStack: FieldKey[] = [];\n\n\t\tlet path: UpPath | undefined = destination;\n\t\twhile (path !== undefined) {\n\t\t\tindexStack.push(path.parentIndex);\n\t\t\tkeyStack.push(path.parentField);\n\t\t\tpath = path.parent;\n\t\t}\n\t\tcursorToMove.clear();\n\t\twhile (keyStack.length > 0) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tconst key = keyStack.pop()!;\n\t\t\tif (cursorToMove.state === ITreeSubscriptionCursorState.Cleared) {\n\t\t\t\tcursorToMove.setToDetachedSequence(key);\n\t\t\t\tcursorToMove.state = ITreeSubscriptionCursorState.Current;\n\t\t\t} else {\n\t\t\t\tcursorToMove.enterField(key);\n\t\t\t}\n\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tcursorToMove.enterNode(indexStack.pop()!);\n\t\t}\n\t}\n\n\tpublic getCursorAboveDetachedFields(): ITreeCursorSynchronous {\n\t\tconst rootCursor = this.roots.cursor();\n\t\trootCursor.enterNode(0);\n\t\treturn rootCursor;\n\t}\n}\n\nclass Cursor extends BasicChunkCursor implements ITreeSubscriptionCursor {\n\tpublic constructor(\n\t\tpublic readonly forest: ChunkedForest,\n\t\tpublic state: ITreeSubscriptionCursorState,\n\t\troot: readonly TreeChunk[],\n\t\tsiblingStack: SiblingsOrKey[],\n\t\tindexStack: number[],\n\t\tindexOfChunkStack: number[],\n\t\tindexWithinChunkStack: number[],\n\t\tsiblings: SiblingsOrKey,\n\t\tindex: number,\n\t\tindexOfChunk: number,\n\t\tindexWithinChunk: number,\n\t\tnestedCursor: ChunkedCursor | undefined,\n\t) {\n\t\tsuper(\n\t\t\troot,\n\t\t\tsiblingStack,\n\t\t\tindexStack,\n\t\t\tindexOfChunkStack,\n\t\t\tindexWithinChunkStack,\n\t\t\tsiblings,\n\t\t\tindex,\n\t\t\tindexOfChunk,\n\t\t\tindexWithinChunk,\n\t\t\tnestedCursor,\n\t\t);\n\t}\n\n\tpublic setToDetachedSequence(key: FieldKey): void {\n\t\tthis.root = (this.forest.roots.fields.get(key) ?? []) as BasicChunk[];\n\t\tthis.siblingStack.length = 0;\n\t\tthis.indexStack.length = 0;\n\t\tthis.indexOfChunkStack.length = 0;\n\t\tthis.indexWithinChunkStack.length = 0;\n\t\tthis.siblings = [key];\n\t\tthis.index = 0;\n\t\tthis.indexOfChunk = 0;\n\t\tthis.indexWithinChunk = 0;\n\t\tthis.nestedCursor = undefined;\n\t}\n\n\tpublic override fork(): Cursor {\n\t\t// Siblings arrays are not modified during navigation and do not need be be copied.\n\t\t// This allows this copy to be shallow, and `this.siblings` below to not be copied as all.\n\t\treturn new Cursor(\n\t\t\tthis.forest,\n\t\t\tthis.state,\n\t\t\tthis.root,\n\t\t\t[...this.siblingStack],\n\t\t\t[...this.indexStack],\n\t\t\t[...this.indexOfChunkStack],\n\t\t\t[...this.indexWithinChunkStack],\n\t\t\tthis.siblings,\n\t\t\tthis.index,\n\t\t\tthis.indexOfChunk,\n\t\t\tthis.indexWithinChunk,\n\t\t\tthis.nestedCursor?.fork(),\n\t\t);\n\t}\n\n\tpublic buildFieldAnchor(): FieldAnchor {\n\t\tconst path = this.getFieldPath();\n\t\tconst anchor =\n\t\t\tpath.parent === undefined ? undefined : this.forest.anchors.track(path.parent);\n\t\treturn { parent: anchor, fieldKey: path.field };\n\t}\n\n\tpublic free(): void {\n\t\tthis.state = ITreeSubscriptionCursorState.Freed;\n\t}\n\n\tpublic buildAnchor(): Anchor {\n\t\treturn this.forest.anchors.track(this.getPath());\n\t}\n\n\tpublic clear(): void {\n\t\tthis.state = ITreeSubscriptionCursorState.Cleared;\n\t\tthis.setToDetachedSequence(rootFieldKey);\n\t}\n}\n\n/**\n * @returns an implementation of {@link IEditableForest} with no data or schema.\n */\nexport function buildChunkedForest(\n\tchunker: IChunker,\n\tanchors?: AnchorSet,\n\tidCompressor?: IIdCompressor,\n): ChunkedForest {\n\treturn new ChunkedForest(makeRoot(), chunker.schema, chunker, anchors, idCompressor);\n}\n"]}
@@ -34,7 +34,8 @@ export interface FlexTreeContext {
34
34
  * A common context of a "forest" of FlexTrees.
35
35
  * It handles group operations like transforming cursors into anchors for edits.
36
36
  */
37
- export interface FlexTreeHydratedContext extends FlexTreeContext, Listenable<ForestEvents> {
37
+ export interface FlexTreeHydratedContext extends FlexTreeContext {
38
+ readonly events: Listenable<ForestEvents>;
38
39
  /**
39
40
  * Gets the root field of the tree.
40
41
  */
@@ -85,7 +86,7 @@ export declare class Context implements FlexTreeHydratedContext, IDisposable {
85
86
  */
86
87
  clear(): void;
87
88
  get root(): FlexTreeField;
88
- on<K extends keyof ForestEvents>(eventName: K, listener: ForestEvents[K]): () => void;
89
+ get events(): Listenable<ForestEvents>;
89
90
  }
90
91
  /**
91
92
  * A simple API for a Forest to interact with the tree.
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/feature-libraries/flex-tree/context.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EACN,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EAGrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,KAAK,WAAW,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,KAAK,UAAU,EAAwB,MAAM,iBAAiB,CAAC;AAExE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAElC;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IAEpC;;;;;OAKG;IACH,UAAU,IAAI,IAAI,IAAI,uBAAuB,CAAC;CAC9C;AAED;;;GAGG;AACH,MAAM,WAAW,uBAAwB,SAAQ,eAAe,EAAE,UAAU,CAAC,YAAY,CAAC;IACzF;;OAEG;IACH,IAAI,IAAI,IAAI,aAAa,CAAC;IAE1B,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IAExC;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;CACjC;AAED;;;GAGG;AACH,eAAO,MAAM,WAAW,mDAAwB,CAAC;AAEjD;;;;GAIG;AACH,qBAAa,OAAQ,YAAW,uBAAuB,EAAE,WAAW;aAalD,YAAY,EAAE,YAAY;aAC1B,QAAQ,EAAE,aAAa;aACvB,cAAc,EAAE,cAAc;IAd/C,SAAgB,WAAW,EAAE,GAAG,CAAC,UAAU,CAAC,CAAa;IACzD,SAAgB,WAAW,EAAE,GAAG,CAAC,UAAU,CAAC,CAAa;IAEzD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiB;IACjD,OAAO,CAAC,QAAQ,CAAS;IAEzB;;;;OAIG;gBAEc,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,aAAa,EACvB,cAAc,EAAE,cAAc;IAexC,UAAU,IAAI,IAAI,IAAI,uBAAuB;IAIpD,IAAW,MAAM,IAAI,gBAAgB,CAEpC;IAED;;;OAGG;IACH,OAAO,CAAC,cAAc;IAQf,CAAC,aAAa,CAAC,IAAI,IAAI;IAa9B;;;;;OAKG;IACI,KAAK,IAAI,IAAI;IAQpB,IAAW,IAAI,IAAI,aAAa,CAO/B;IAEM,EAAE,CAAC,CAAC,SAAS,MAAM,YAAY,EACrC,SAAS,EAAE,CAAC,EACZ,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,GACvB,MAAM,IAAI;CAGb;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC7B,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,aAAa,EACvB,cAAc,EAAE,cAAc,GAC5B,OAAO,CAET"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/feature-libraries/flex-tree/context.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EACN,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EAGrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,KAAK,WAAW,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,KAAK,UAAU,EAAwB,MAAM,iBAAiB,CAAC;AAExE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAElC;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IAEpC;;;;;OAKG;IACH,UAAU,IAAI,IAAI,IAAI,uBAAuB,CAAC;CAC9C;AAED;;;GAGG;AACH,MAAM,WAAW,uBAAwB,SAAQ,eAAe;IAC/D,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,YAAY,CAAC,CAAC;IAC1C;;OAEG;IACH,IAAI,IAAI,IAAI,aAAa,CAAC;IAE1B,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IAExC;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;CACjC;AAED;;;GAGG;AACH,eAAO,MAAM,WAAW,mDAAwB,CAAC;AAEjD;;;;GAIG;AACH,qBAAa,OAAQ,YAAW,uBAAuB,EAAE,WAAW;aAalD,YAAY,EAAE,YAAY;aAC1B,QAAQ,EAAE,aAAa;aACvB,cAAc,EAAE,cAAc;IAd/C,SAAgB,WAAW,EAAE,GAAG,CAAC,UAAU,CAAC,CAAa;IACzD,SAAgB,WAAW,EAAE,GAAG,CAAC,UAAU,CAAC,CAAa;IAEzD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiB;IACjD,OAAO,CAAC,QAAQ,CAAS;IAEzB;;;;OAIG;gBAEc,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,aAAa,EACvB,cAAc,EAAE,cAAc;IAexC,UAAU,IAAI,IAAI,IAAI,uBAAuB;IAIpD,IAAW,MAAM,IAAI,gBAAgB,CAEpC;IAED;;;OAGG;IACH,OAAO,CAAC,cAAc;IAQf,CAAC,aAAa,CAAC,IAAI,IAAI;IAa9B;;;;;OAKG;IACI,KAAK,IAAI,IAAI;IAQpB,IAAW,IAAI,IAAI,aAAa,CAO/B;IAED,IAAW,MAAM,IAAI,UAAU,CAAC,YAAY,CAAC,CAE5C;CACD;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC7B,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,aAAa,EACvB,cAAc,EAAE,cAAc,GAC5B,OAAO,CAET"}
@@ -34,7 +34,7 @@ class Context {
34
34
  this.withAnchors = new Set();
35
35
  this.disposed = false;
36
36
  this.eventUnregister = [
37
- this.checkout.forest.on("beforeChange", () => {
37
+ this.checkout.forest.events.on("beforeChange", () => {
38
38
  this.prepareForEdit();
39
39
  }),
40
40
  ];
@@ -90,8 +90,8 @@ class Context {
90
90
  cursor.free();
91
91
  return field;
92
92
  }
93
- on(eventName, listener) {
94
- return this.checkout.forest.on(eventName, listener);
93
+ get events() {
94
+ return this.checkout.forest.events;
95
95
  }
96
96
  }
97
97
  exports.Context = Context;
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/feature-libraries/flex-tree/context.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 { assert } from \"@fluidframework/core-utils/internal\";\n\nimport {\n\ttype ForestEvents,\n\ttype SchemaPolicy,\n\ttype TreeStoredSchema,\n\tanchorSlot,\n\tmoveToDetachedField,\n} from \"../../core/index.js\";\nimport type { Listenable } from \"../../events/index.js\";\nimport { type IDisposable, disposeSymbol } from \"../../util/index.js\";\nimport type { NodeKeyManager } from \"../node-key/index.js\";\n\nimport type { FlexTreeField } from \"./flexTreeTypes.js\";\nimport { type LazyEntity, prepareForEditSymbol } from \"./lazyEntity.js\";\nimport { makeField } from \"./lazyField.js\";\nimport type { ITreeCheckout } from \"../../shared-tree/index.js\";\n\n/**\n * Context for FlexTrees.\n */\nexport interface FlexTreeContext {\n\t/**\n\t * Schema used within this context.\n\t * All data must conform to these schema.\n\t */\n\treadonly schema: TreeStoredSchema;\n\n\t/**\n\t * SchemaPolicy used within this context.\n\t */\n\treadonly schemaPolicy: SchemaPolicy;\n\n\t/**\n\t * If true, this context is the canonical context instance for a given view,\n\t * and its schema include all schema from the document.\n\t *\n\t * If false, this context was created for use in a unhydrated tree, and the full document schema is unknown.\n\t */\n\tisHydrated(): this is FlexTreeHydratedContext;\n}\n\n/**\n * A common context of a \"forest\" of FlexTrees.\n * It handles group operations like transforming cursors into anchors for edits.\n */\nexport interface FlexTreeHydratedContext extends FlexTreeContext, Listenable<ForestEvents> {\n\t/**\n\t * Gets the root field of the tree.\n\t */\n\tget root(): FlexTreeField;\n\n\treadonly nodeKeyManager: NodeKeyManager;\n\n\t/**\n\t * The checkout object associated with this context.\n\t */\n\treadonly checkout: ITreeCheckout;\n}\n\n/**\n * Creating multiple flex 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 */\nexport const ContextSlot = anchorSlot<Context>();\n\n/**\n * Implementation of `FlexTreeContext`.\n *\n * @remarks An editor is required to edit the FlexTree.\n */\nexport class Context implements FlexTreeHydratedContext, IDisposable {\n\tpublic readonly withCursors: Set<LazyEntity> = new Set();\n\tpublic readonly withAnchors: Set<LazyEntity> = new Set();\n\n\tprivate readonly eventUnregister: (() => void)[];\n\tprivate disposed = false;\n\n\t/**\n\t * @param flexSchema - Schema to use when working with the tree.\n\t * @param checkout - The checkout.\n\t * @param nodeKeyManager - An object which handles node key generation and conversion\n\t */\n\tpublic constructor(\n\t\tpublic readonly schemaPolicy: SchemaPolicy,\n\t\tpublic readonly checkout: ITreeCheckout,\n\t\tpublic readonly nodeKeyManager: NodeKeyManager,\n\t) {\n\t\tthis.eventUnregister = [\n\t\t\tthis.checkout.forest.on(\"beforeChange\", () => {\n\t\t\t\tthis.prepareForEdit();\n\t\t\t}),\n\t\t];\n\n\t\tassert(\n\t\t\t!this.checkout.forest.anchors.slots.has(ContextSlot),\n\t\t\t0x92b /* Cannot create second flex-tree from checkout */,\n\t\t);\n\t\tthis.checkout.forest.anchors.slots.set(ContextSlot, this);\n\t}\n\n\tpublic isHydrated(): this is FlexTreeHydratedContext {\n\t\treturn true;\n\t}\n\n\tpublic get schema(): TreeStoredSchema {\n\t\treturn this.checkout.storedSchema;\n\t}\n\n\t/**\n\t * Called before editing.\n\t * Clears all cursors so editing can proceed.\n\t */\n\tprivate prepareForEdit(): void {\n\t\tassert(this.disposed === false, 0x802 /* use after dispose */);\n\t\tfor (const target of this.withCursors) {\n\t\t\ttarget[prepareForEditSymbol]();\n\t\t}\n\t\tassert(this.withCursors.size === 0, 0x773 /* prepareForEdit should remove all cursors */);\n\t}\n\n\tpublic [disposeSymbol](): void {\n\t\tassert(this.disposed === false, 0x803 /* double dispose */);\n\t\tthis.disposed = true;\n\t\tthis.clear();\n\t\tfor (const unregister of this.eventUnregister) {\n\t\t\tunregister();\n\t\t}\n\t\tthis.eventUnregister.length = 0;\n\n\t\tconst deleted = this.checkout.forest.anchors.slots.delete(ContextSlot);\n\t\tassert(deleted, 0x8c4 /* unexpected dispose */);\n\t}\n\n\t/**\n\t * Release any cursors and anchors held by tree entities created in this context.\n\t * Ensures the cashed references to those entities on the Anchors are also cleared.\n\t * The tree entities are invalid to use after this, but the context may still be used\n\t * to create new trees starting from the root.\n\t */\n\tpublic clear(): void {\n\t\tfor (const target of this.withAnchors) {\n\t\t\ttarget[disposeSymbol]();\n\t\t}\n\t\tassert(this.withCursors.size === 0, 0x774 /* free should remove all cursors */);\n\t\tassert(this.withAnchors.size === 0, 0x775 /* free should remove all anchors */);\n\t}\n\n\tpublic get root(): FlexTreeField {\n\t\tassert(this.disposed === false, 0x804 /* use after dispose */);\n\t\tconst cursor = this.checkout.forest.allocateCursor(\"root\");\n\t\tmoveToDetachedField(this.checkout.forest, cursor);\n\t\tconst field = makeField(this, this.schema.rootFieldSchema.kind, cursor);\n\t\tcursor.free();\n\t\treturn field;\n\t}\n\n\tpublic on<K extends keyof ForestEvents>(\n\t\teventName: K,\n\t\tlistener: ForestEvents[K],\n\t): () => void {\n\t\treturn this.checkout.forest.on(eventName, listener);\n\t}\n}\n\n/**\n * A simple API for a Forest to interact with the tree.\n *\n * @param forest - the Forest\n * @param editor - an editor that makes changes to the forest.\n * @param nodeKeyManager - an object which handles node key generation and conversion.\n * @returns {@link FlexTreeContext} which is used to manage the cursors and anchors within the FlexTrees:\n * This is necessary for supporting using this tree across edits to the forest, and not leaking memory.\n */\nexport function getTreeContext(\n\tschema: SchemaPolicy,\n\tcheckout: ITreeCheckout,\n\tnodeKeyManager: NodeKeyManager,\n): Context {\n\treturn new Context(schema, checkout, nodeKeyManager);\n}\n"]}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/feature-libraries/flex-tree/context.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,kEAA6D;AAE7D,kDAM6B;AAE7B,kDAAsE;AAItE,mDAAwE;AACxE,iDAA2C;AA8C3C;;;GAGG;AACU,QAAA,WAAW,GAAG,IAAA,qBAAU,GAAW,CAAC;AAEjD;;;;GAIG;AACH,MAAa,OAAO;IAOnB;;;;OAIG;IACH,YACiB,YAA0B,EAC1B,QAAuB,EACvB,cAA8B;QAF9B,iBAAY,GAAZ,YAAY,CAAc;QAC1B,aAAQ,GAAR,QAAQ,CAAe;QACvB,mBAAc,GAAd,cAAc,CAAgB;QAd/B,gBAAW,GAAoB,IAAI,GAAG,EAAE,CAAC;QACzC,gBAAW,GAAoB,IAAI,GAAG,EAAE,CAAC;QAGjD,aAAQ,GAAG,KAAK,CAAC;QAYxB,IAAI,CAAC,eAAe,GAAG;YACtB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,cAAc,EAAE,GAAG,EAAE;gBACnD,IAAI,CAAC,cAAc,EAAE,CAAC;YACvB,CAAC,CAAC;SACF,CAAC;QAEF,IAAA,iBAAM,EACL,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,mBAAW,CAAC,EACpD,KAAK,CAAC,kDAAkD,CACxD,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,mBAAW,EAAE,IAAI,CAAC,CAAC;IAC3D,CAAC;IAEM,UAAU;QAChB,OAAO,IAAI,CAAC;IACb,CAAC;IAED,IAAW,MAAM;QAChB,OAAO,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;IACnC,CAAC;IAED;;;OAGG;IACK,cAAc;QACrB,IAAA,iBAAM,EAAC,IAAI,CAAC,QAAQ,KAAK,KAAK,EAAE,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAC/D,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACvC,MAAM,CAAC,oCAAoB,CAAC,EAAE,CAAC;QAChC,CAAC;QACD,IAAA,iBAAM,EAAC,IAAI,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,EAAE,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAC3F,CAAC;IAEM,CAAC,wBAAa,CAAC;QACrB,IAAA,iBAAM,EAAC,IAAI,CAAC,QAAQ,KAAK,KAAK,EAAE,KAAK,CAAC,oBAAoB,CAAC,CAAC;QAC5D,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YAC/C,UAAU,EAAE,CAAC;QACd,CAAC;QACD,IAAI,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC;QAEhC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,mBAAW,CAAC,CAAC;QACvE,IAAA,iBAAM,EAAC,OAAO,EAAE,KAAK,CAAC,wBAAwB,CAAC,CAAC;IACjD,CAAC;IAED;;;;;OAKG;IACI,KAAK;QACX,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACvC,MAAM,CAAC,wBAAa,CAAC,EAAE,CAAC;QACzB,CAAC;QACD,IAAA,iBAAM,EAAC,IAAI,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,EAAE,KAAK,CAAC,oCAAoC,CAAC,CAAC;QAChF,IAAA,iBAAM,EAAC,IAAI,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,EAAE,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACjF,CAAC;IAED,IAAW,IAAI;QACd,IAAA,iBAAM,EAAC,IAAI,CAAC,QAAQ,KAAK,KAAK,EAAE,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAC/D,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QAC3D,IAAA,8BAAmB,EAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAClD,MAAM,KAAK,GAAG,IAAA,wBAAS,EAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACxE,MAAM,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,KAAK,CAAC;IACd,CAAC;IAED,IAAW,MAAM;QAChB,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC;IACpC,CAAC;CACD;AAzFD,0BAyFC;AAED;;;;;;;;GAQG;AACH,SAAgB,cAAc,CAC7B,MAAoB,EACpB,QAAuB,EACvB,cAA8B;IAE9B,OAAO,IAAI,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC;AACtD,CAAC;AAND,wCAMC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\n\nimport {\n\ttype ForestEvents,\n\ttype SchemaPolicy,\n\ttype TreeStoredSchema,\n\tanchorSlot,\n\tmoveToDetachedField,\n} from \"../../core/index.js\";\nimport type { Listenable } from \"../../events/index.js\";\nimport { type IDisposable, disposeSymbol } from \"../../util/index.js\";\nimport type { NodeKeyManager } from \"../node-key/index.js\";\n\nimport type { FlexTreeField } from \"./flexTreeTypes.js\";\nimport { type LazyEntity, prepareForEditSymbol } from \"./lazyEntity.js\";\nimport { makeField } from \"./lazyField.js\";\nimport type { ITreeCheckout } from \"../../shared-tree/index.js\";\n\n/**\n * Context for FlexTrees.\n */\nexport interface FlexTreeContext {\n\t/**\n\t * Schema used within this context.\n\t * All data must conform to these schema.\n\t */\n\treadonly schema: TreeStoredSchema;\n\n\t/**\n\t * SchemaPolicy used within this context.\n\t */\n\treadonly schemaPolicy: SchemaPolicy;\n\n\t/**\n\t * If true, this context is the canonical context instance for a given view,\n\t * and its schema include all schema from the document.\n\t *\n\t * If false, this context was created for use in a unhydrated tree, and the full document schema is unknown.\n\t */\n\tisHydrated(): this is FlexTreeHydratedContext;\n}\n\n/**\n * A common context of a \"forest\" of FlexTrees.\n * It handles group operations like transforming cursors into anchors for edits.\n */\nexport interface FlexTreeHydratedContext extends FlexTreeContext {\n\treadonly events: Listenable<ForestEvents>;\n\t/**\n\t * Gets the root field of the tree.\n\t */\n\tget root(): FlexTreeField;\n\n\treadonly nodeKeyManager: NodeKeyManager;\n\n\t/**\n\t * The checkout object associated with this context.\n\t */\n\treadonly checkout: ITreeCheckout;\n}\n\n/**\n * Creating multiple flex 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 */\nexport const ContextSlot = anchorSlot<Context>();\n\n/**\n * Implementation of `FlexTreeContext`.\n *\n * @remarks An editor is required to edit the FlexTree.\n */\nexport class Context implements FlexTreeHydratedContext, IDisposable {\n\tpublic readonly withCursors: Set<LazyEntity> = new Set();\n\tpublic readonly withAnchors: Set<LazyEntity> = new Set();\n\n\tprivate readonly eventUnregister: (() => void)[];\n\tprivate disposed = false;\n\n\t/**\n\t * @param flexSchema - Schema to use when working with the tree.\n\t * @param checkout - The checkout.\n\t * @param nodeKeyManager - An object which handles node key generation and conversion\n\t */\n\tpublic constructor(\n\t\tpublic readonly schemaPolicy: SchemaPolicy,\n\t\tpublic readonly checkout: ITreeCheckout,\n\t\tpublic readonly nodeKeyManager: NodeKeyManager,\n\t) {\n\t\tthis.eventUnregister = [\n\t\t\tthis.checkout.forest.events.on(\"beforeChange\", () => {\n\t\t\t\tthis.prepareForEdit();\n\t\t\t}),\n\t\t];\n\n\t\tassert(\n\t\t\t!this.checkout.forest.anchors.slots.has(ContextSlot),\n\t\t\t0x92b /* Cannot create second flex-tree from checkout */,\n\t\t);\n\t\tthis.checkout.forest.anchors.slots.set(ContextSlot, this);\n\t}\n\n\tpublic isHydrated(): this is FlexTreeHydratedContext {\n\t\treturn true;\n\t}\n\n\tpublic get schema(): TreeStoredSchema {\n\t\treturn this.checkout.storedSchema;\n\t}\n\n\t/**\n\t * Called before editing.\n\t * Clears all cursors so editing can proceed.\n\t */\n\tprivate prepareForEdit(): void {\n\t\tassert(this.disposed === false, 0x802 /* use after dispose */);\n\t\tfor (const target of this.withCursors) {\n\t\t\ttarget[prepareForEditSymbol]();\n\t\t}\n\t\tassert(this.withCursors.size === 0, 0x773 /* prepareForEdit should remove all cursors */);\n\t}\n\n\tpublic [disposeSymbol](): void {\n\t\tassert(this.disposed === false, 0x803 /* double dispose */);\n\t\tthis.disposed = true;\n\t\tthis.clear();\n\t\tfor (const unregister of this.eventUnregister) {\n\t\t\tunregister();\n\t\t}\n\t\tthis.eventUnregister.length = 0;\n\n\t\tconst deleted = this.checkout.forest.anchors.slots.delete(ContextSlot);\n\t\tassert(deleted, 0x8c4 /* unexpected dispose */);\n\t}\n\n\t/**\n\t * Release any cursors and anchors held by tree entities created in this context.\n\t * Ensures the cashed references to those entities on the Anchors are also cleared.\n\t * The tree entities are invalid to use after this, but the context may still be used\n\t * to create new trees starting from the root.\n\t */\n\tpublic clear(): void {\n\t\tfor (const target of this.withAnchors) {\n\t\t\ttarget[disposeSymbol]();\n\t\t}\n\t\tassert(this.withCursors.size === 0, 0x774 /* free should remove all cursors */);\n\t\tassert(this.withAnchors.size === 0, 0x775 /* free should remove all anchors */);\n\t}\n\n\tpublic get root(): FlexTreeField {\n\t\tassert(this.disposed === false, 0x804 /* use after dispose */);\n\t\tconst cursor = this.checkout.forest.allocateCursor(\"root\");\n\t\tmoveToDetachedField(this.checkout.forest, cursor);\n\t\tconst field = makeField(this, this.schema.rootFieldSchema.kind, cursor);\n\t\tcursor.free();\n\t\treturn field;\n\t}\n\n\tpublic get events(): Listenable<ForestEvents> {\n\t\treturn this.checkout.forest.events;\n\t}\n}\n\n/**\n * A simple API for a Forest to interact with the tree.\n *\n * @param forest - the Forest\n * @param editor - an editor that makes changes to the forest.\n * @param nodeKeyManager - an object which handles node key generation and conversion.\n * @returns {@link FlexTreeContext} which is used to manage the cursors and anchors within the FlexTrees:\n * This is necessary for supporting using this tree across edits to the forest, and not leaking memory.\n */\nexport function getTreeContext(\n\tschema: SchemaPolicy,\n\tcheckout: ITreeCheckout,\n\tnodeKeyManager: NodeKeyManager,\n): Context {\n\treturn new Context(schema, checkout, nodeKeyManager);\n}\n"]}
@@ -76,7 +76,7 @@ class LazyField extends lazyEntity_js_1.LazyEntity {
76
76
  if (fieldAnchor.parent !== undefined) {
77
77
  const anchorNode = context.checkout.forest.anchors.locate(fieldAnchor.parent) ??
78
78
  (0, index_js_2.fail)("parent anchor node should always exist since field is under a node");
79
- this.offAfterDestroy = anchorNode.on("afterDestroy", () => {
79
+ this.offAfterDestroy = anchorNode.events.on("afterDestroy", () => {
80
80
  this[index_js_2.disposeSymbol]();
81
81
  });
82
82
  }