@fluidframework/tree 2.22.1 → 2.23.0-325054

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 (515) hide show
  1. package/.vscode/extensions.json +1 -0
  2. package/.vscode/settings.json +1 -0
  3. package/CHANGELOG.md +47 -0
  4. package/api-report/tree.alpha.api.md +169 -10
  5. package/api-report/tree.beta.api.md +101 -9
  6. package/api-report/tree.legacy.alpha.api.md +101 -9
  7. package/api-report/tree.legacy.public.api.md +101 -9
  8. package/api-report/tree.public.api.md +101 -9
  9. package/dist/alpha.d.ts +20 -0
  10. package/dist/beta.d.ts +15 -0
  11. package/dist/codec/codec.js +3 -3
  12. package/dist/codec/codec.js.map +1 -1
  13. package/dist/codec/discriminatedUnions.d.ts.map +1 -1
  14. package/dist/codec/discriminatedUnions.js +1 -1
  15. package/dist/codec/discriminatedUnions.js.map +1 -1
  16. package/dist/core/schema-stored/schema.d.ts.map +1 -1
  17. package/dist/core/schema-stored/schema.js +3 -3
  18. package/dist/core/schema-stored/schema.js.map +1 -1
  19. package/dist/core/tree/anchorSet.d.ts.map +1 -1
  20. package/dist/core/tree/anchorSet.js +18 -13
  21. package/dist/core/tree/anchorSet.js.map +1 -1
  22. package/dist/core/tree/treeTextFormat.js +1 -1
  23. package/dist/core/tree/treeTextFormat.js.map +1 -1
  24. package/dist/feature-libraries/chunked-forest/basicChunk.d.ts.map +1 -1
  25. package/dist/feature-libraries/chunked-forest/basicChunk.js +11 -8
  26. package/dist/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
  27. package/dist/feature-libraries/chunked-forest/chunkTree.js +2 -2
  28. package/dist/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
  29. package/dist/feature-libraries/chunked-forest/chunkedForest.js +3 -3
  30. package/dist/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
  31. package/dist/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.js +2 -2
  32. package/dist/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.js.map +1 -1
  33. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.d.ts.map +1 -1
  34. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js +4 -3
  35. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
  36. package/dist/feature-libraries/chunked-forest/codec/nodeShape.js +2 -2
  37. package/dist/feature-libraries/chunked-forest/codec/nodeShape.js.map +1 -1
  38. package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncoding.d.ts.map +1 -1
  39. package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncoding.js +3 -3
  40. package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncoding.js.map +1 -1
  41. package/dist/feature-libraries/chunked-forest/emptyChunk.js +14 -14
  42. package/dist/feature-libraries/chunked-forest/emptyChunk.js.map +1 -1
  43. package/dist/feature-libraries/chunked-forest/uniformChunk.d.ts.map +1 -1
  44. package/dist/feature-libraries/chunked-forest/uniformChunk.js +6 -4
  45. package/dist/feature-libraries/chunked-forest/uniformChunk.js.map +1 -1
  46. package/dist/feature-libraries/default-schema/defaultFieldKinds.js +1 -1
  47. package/dist/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
  48. package/dist/feature-libraries/default-schema/schemaChecker.js +1 -1
  49. package/dist/feature-libraries/default-schema/schemaChecker.js.map +1 -1
  50. package/dist/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
  51. package/dist/feature-libraries/flex-tree/lazyField.js +4 -3
  52. package/dist/feature-libraries/flex-tree/lazyField.js.map +1 -1
  53. package/dist/feature-libraries/flex-tree/lazyNode.d.ts.map +1 -1
  54. package/dist/feature-libraries/flex-tree/lazyNode.js +5 -4
  55. package/dist/feature-libraries/flex-tree/lazyNode.js.map +1 -1
  56. package/dist/feature-libraries/indexing/anchorTreeIndex.d.ts.map +1 -1
  57. package/dist/feature-libraries/indexing/anchorTreeIndex.js +1 -1
  58. package/dist/feature-libraries/indexing/anchorTreeIndex.js.map +1 -1
  59. package/dist/feature-libraries/modular-schema/comparison.d.ts.map +1 -1
  60. package/dist/feature-libraries/modular-schema/comparison.js +6 -4
  61. package/dist/feature-libraries/modular-schema/comparison.js.map +1 -1
  62. package/dist/feature-libraries/modular-schema/isNeverTree.d.ts.map +1 -1
  63. package/dist/feature-libraries/modular-schema/isNeverTree.js +4 -4
  64. package/dist/feature-libraries/modular-schema/isNeverTree.js.map +1 -1
  65. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js +4 -4
  66. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  67. package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
  68. package/dist/feature-libraries/modular-schema/modularChangeFamily.js +10 -11
  69. package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  70. package/dist/feature-libraries/node-key/mockNodeKeyManager.js +1 -1
  71. package/dist/feature-libraries/node-key/mockNodeKeyManager.js.map +1 -1
  72. package/dist/feature-libraries/object-forest/objectForest.js +1 -1
  73. package/dist/feature-libraries/object-forest/objectForest.js.map +1 -1
  74. package/dist/feature-libraries/schema-index/codec.js +1 -1
  75. package/dist/feature-libraries/schema-index/codec.js.map +1 -1
  76. package/dist/feature-libraries/sequence-field/compose.js +1 -1
  77. package/dist/feature-libraries/sequence-field/compose.js.map +1 -1
  78. package/dist/feature-libraries/sequence-field/invert.js +1 -1
  79. package/dist/feature-libraries/sequence-field/invert.js.map +1 -1
  80. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV1.js +1 -1
  81. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV1.js.map +1 -1
  82. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV2.js +1 -1
  83. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV2.js.map +1 -1
  84. package/dist/feature-libraries/sequence-field/utils.js +1 -1
  85. package/dist/feature-libraries/sequence-field/utils.js.map +1 -1
  86. package/dist/feature-libraries/treeCursorUtils.d.ts.map +1 -1
  87. package/dist/feature-libraries/treeCursorUtils.js +6 -4
  88. package/dist/feature-libraries/treeCursorUtils.js.map +1 -1
  89. package/dist/index.d.ts +4 -2
  90. package/dist/index.d.ts.map +1 -1
  91. package/dist/index.js +10 -1
  92. package/dist/index.js.map +1 -1
  93. package/dist/jsonDomainSchema.d.ts +113 -0
  94. package/dist/jsonDomainSchema.d.ts.map +1 -0
  95. package/dist/jsonDomainSchema.js +101 -0
  96. package/dist/jsonDomainSchema.js.map +1 -0
  97. package/dist/legacy.d.ts +15 -0
  98. package/dist/packageVersion.d.ts +1 -1
  99. package/dist/packageVersion.d.ts.map +1 -1
  100. package/dist/packageVersion.js +1 -1
  101. package/dist/packageVersion.js.map +1 -1
  102. package/dist/public.d.ts +15 -0
  103. package/dist/serializableDomainSchema.d.ts +108 -0
  104. package/dist/serializableDomainSchema.d.ts.map +1 -0
  105. package/dist/serializableDomainSchema.js +90 -0
  106. package/dist/serializableDomainSchema.js.map +1 -0
  107. package/dist/shared-tree/index.d.ts +1 -1
  108. package/dist/shared-tree/index.d.ts.map +1 -1
  109. package/dist/shared-tree/index.js.map +1 -1
  110. package/dist/shared-tree/schematizeTree.js +1 -1
  111. package/dist/shared-tree/schematizeTree.js.map +1 -1
  112. package/dist/shared-tree/sharedTree.d.ts +37 -20
  113. package/dist/shared-tree/sharedTree.d.ts.map +1 -1
  114. package/dist/shared-tree/sharedTree.js +17 -17
  115. package/dist/shared-tree/sharedTree.js.map +1 -1
  116. package/dist/shared-tree/sharedTreeChangeFamily.js +1 -1
  117. package/dist/shared-tree/sharedTreeChangeFamily.js.map +1 -1
  118. package/dist/shared-tree/treeApiAlpha.d.ts.map +1 -1
  119. package/dist/shared-tree/treeApiAlpha.js +4 -4
  120. package/dist/shared-tree/treeApiAlpha.js.map +1 -1
  121. package/dist/shared-tree/treeCheckout.js +1 -1
  122. package/dist/shared-tree/treeCheckout.js.map +1 -1
  123. package/dist/shared-tree-core/editManager.d.ts +11 -2
  124. package/dist/shared-tree-core/editManager.d.ts.map +1 -1
  125. package/dist/shared-tree-core/editManager.js +70 -34
  126. package/dist/shared-tree-core/editManager.js.map +1 -1
  127. package/dist/shared-tree-core/resubmitMachine.d.ts +2 -0
  128. package/dist/shared-tree-core/resubmitMachine.d.ts.map +1 -1
  129. package/dist/shared-tree-core/resubmitMachine.js.map +1 -1
  130. package/dist/shared-tree-core/sharedTreeCore.d.ts +10 -3
  131. package/dist/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  132. package/dist/shared-tree-core/sharedTreeCore.js +42 -7
  133. package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
  134. package/dist/simple-tree/api/component.d.ts +30 -0
  135. package/dist/simple-tree/api/component.d.ts.map +1 -0
  136. package/dist/simple-tree/api/component.js +26 -0
  137. package/dist/simple-tree/api/component.js.map +1 -0
  138. package/dist/simple-tree/api/customTree.js +3 -3
  139. package/dist/simple-tree/api/customTree.js.map +1 -1
  140. package/dist/simple-tree/api/index.d.ts +2 -1
  141. package/dist/simple-tree/api/index.d.ts.map +1 -1
  142. package/dist/simple-tree/api/index.js +3 -1
  143. package/dist/simple-tree/api/index.js.map +1 -1
  144. package/dist/simple-tree/api/schemaCreationUtilities.js +1 -1
  145. package/dist/simple-tree/api/schemaCreationUtilities.js.map +1 -1
  146. package/dist/simple-tree/api/schemaFactory.d.ts +0 -8
  147. package/dist/simple-tree/api/schemaFactory.d.ts.map +1 -1
  148. package/dist/simple-tree/api/schemaFactory.js +4 -25
  149. package/dist/simple-tree/api/schemaFactory.js.map +1 -1
  150. package/dist/simple-tree/api/schemaFactoryRecursive.d.ts +1 -1
  151. package/dist/simple-tree/api/schemaFactoryRecursive.js.map +1 -1
  152. package/dist/simple-tree/api/simpleTreeIndex.js +3 -3
  153. package/dist/simple-tree/api/simpleTreeIndex.js.map +1 -1
  154. package/dist/simple-tree/api/tree.d.ts.map +1 -1
  155. package/dist/simple-tree/api/tree.js +2 -3
  156. package/dist/simple-tree/api/tree.js.map +1 -1
  157. package/dist/simple-tree/api/treeNodeApi.d.ts.map +1 -1
  158. package/dist/simple-tree/api/treeNodeApi.js +7 -18
  159. package/dist/simple-tree/api/treeNodeApi.js.map +1 -1
  160. package/dist/simple-tree/api/typesUnsafe.d.ts +127 -19
  161. package/dist/simple-tree/api/typesUnsafe.d.ts.map +1 -1
  162. package/dist/simple-tree/api/typesUnsafe.js +17 -0
  163. package/dist/simple-tree/api/typesUnsafe.js.map +1 -1
  164. package/dist/simple-tree/api/verboseTree.d.ts.map +1 -1
  165. package/dist/simple-tree/api/verboseTree.js +5 -4
  166. package/dist/simple-tree/api/verboseTree.js.map +1 -1
  167. package/dist/simple-tree/api/view.js +1 -1
  168. package/dist/simple-tree/api/view.js.map +1 -1
  169. package/dist/simple-tree/arrayNode.d.ts +1 -1
  170. package/dist/simple-tree/arrayNode.d.ts.map +1 -1
  171. package/dist/simple-tree/arrayNode.js +2 -2
  172. package/dist/simple-tree/arrayNode.js.map +1 -1
  173. package/dist/simple-tree/core/getOrCreateNode.d.ts.map +1 -1
  174. package/dist/simple-tree/core/getOrCreateNode.js +1 -1
  175. package/dist/simple-tree/core/getOrCreateNode.js.map +1 -1
  176. package/dist/simple-tree/core/schemaCaching.js +1 -1
  177. package/dist/simple-tree/core/schemaCaching.js.map +1 -1
  178. package/dist/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
  179. package/dist/simple-tree/core/treeNodeKernel.js +6 -6
  180. package/dist/simple-tree/core/treeNodeKernel.js.map +1 -1
  181. package/dist/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
  182. package/dist/simple-tree/core/unhydratedFlexTree.js +5 -5
  183. package/dist/simple-tree/core/unhydratedFlexTree.js.map +1 -1
  184. package/dist/simple-tree/flexList.d.ts +4 -5
  185. package/dist/simple-tree/flexList.d.ts.map +1 -1
  186. package/dist/simple-tree/flexList.js +1 -14
  187. package/dist/simple-tree/flexList.js.map +1 -1
  188. package/dist/simple-tree/index.d.ts +4 -4
  189. package/dist/simple-tree/index.d.ts.map +1 -1
  190. package/dist/simple-tree/index.js +6 -2
  191. package/dist/simple-tree/index.js.map +1 -1
  192. package/dist/simple-tree/objectNode.d.ts +25 -2
  193. package/dist/simple-tree/objectNode.d.ts.map +1 -1
  194. package/dist/simple-tree/objectNode.js +4 -2
  195. package/dist/simple-tree/objectNode.js.map +1 -1
  196. package/dist/simple-tree/proxies.js +1 -1
  197. package/dist/simple-tree/proxies.js.map +1 -1
  198. package/dist/simple-tree/schemaTypes.d.ts +211 -9
  199. package/dist/simple-tree/schemaTypes.d.ts.map +1 -1
  200. package/dist/simple-tree/schemaTypes.js +83 -2
  201. package/dist/simple-tree/schemaTypes.js.map +1 -1
  202. package/dist/simple-tree/toMapTree.js +3 -3
  203. package/dist/simple-tree/toMapTree.js.map +1 -1
  204. package/dist/simple-tree/toStoredSchema.d.ts.map +1 -1
  205. package/dist/simple-tree/toStoredSchema.js +3 -6
  206. package/dist/simple-tree/toStoredSchema.js.map +1 -1
  207. package/dist/simple-tree/treeNodeValid.d.ts +7 -1
  208. package/dist/simple-tree/treeNodeValid.d.ts.map +1 -1
  209. package/dist/simple-tree/treeNodeValid.js +18 -7
  210. package/dist/simple-tree/treeNodeValid.js.map +1 -1
  211. package/dist/util/idAllocator.js +1 -1
  212. package/dist/util/idAllocator.js.map +1 -1
  213. package/dist/util/index.d.ts +2 -2
  214. package/dist/util/index.d.ts.map +1 -1
  215. package/dist/util/index.js +5 -4
  216. package/dist/util/index.js.map +1 -1
  217. package/dist/util/nestedMap.d.ts +2 -10
  218. package/dist/util/nestedMap.d.ts.map +1 -1
  219. package/dist/util/nestedMap.js +9 -28
  220. package/dist/util/nestedMap.js.map +1 -1
  221. package/dist/util/utils.d.ts +23 -6
  222. package/dist/util/utils.d.ts.map +1 -1
  223. package/dist/util/utils.js +46 -13
  224. package/dist/util/utils.js.map +1 -1
  225. package/lib/alpha.d.ts +20 -0
  226. package/lib/beta.d.ts +15 -0
  227. package/lib/codec/codec.js +3 -3
  228. package/lib/codec/codec.js.map +1 -1
  229. package/lib/codec/discriminatedUnions.d.ts.map +1 -1
  230. package/lib/codec/discriminatedUnions.js +1 -1
  231. package/lib/codec/discriminatedUnions.js.map +1 -1
  232. package/lib/core/schema-stored/schema.d.ts.map +1 -1
  233. package/lib/core/schema-stored/schema.js +3 -3
  234. package/lib/core/schema-stored/schema.js.map +1 -1
  235. package/lib/core/tree/anchorSet.d.ts.map +1 -1
  236. package/lib/core/tree/anchorSet.js +19 -14
  237. package/lib/core/tree/anchorSet.js.map +1 -1
  238. package/lib/core/tree/treeTextFormat.js +1 -1
  239. package/lib/core/tree/treeTextFormat.js.map +1 -1
  240. package/lib/feature-libraries/chunked-forest/basicChunk.d.ts.map +1 -1
  241. package/lib/feature-libraries/chunked-forest/basicChunk.js +11 -8
  242. package/lib/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
  243. package/lib/feature-libraries/chunked-forest/chunkTree.js +2 -2
  244. package/lib/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
  245. package/lib/feature-libraries/chunked-forest/chunkedForest.js +3 -3
  246. package/lib/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
  247. package/lib/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.js +2 -2
  248. package/lib/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.js.map +1 -1
  249. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.d.ts.map +1 -1
  250. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js +4 -3
  251. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
  252. package/lib/feature-libraries/chunked-forest/codec/nodeShape.js +2 -2
  253. package/lib/feature-libraries/chunked-forest/codec/nodeShape.js.map +1 -1
  254. package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncoding.d.ts.map +1 -1
  255. package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncoding.js +3 -3
  256. package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncoding.js.map +1 -1
  257. package/lib/feature-libraries/chunked-forest/emptyChunk.js +14 -14
  258. package/lib/feature-libraries/chunked-forest/emptyChunk.js.map +1 -1
  259. package/lib/feature-libraries/chunked-forest/uniformChunk.d.ts.map +1 -1
  260. package/lib/feature-libraries/chunked-forest/uniformChunk.js +6 -4
  261. package/lib/feature-libraries/chunked-forest/uniformChunk.js.map +1 -1
  262. package/lib/feature-libraries/default-schema/defaultFieldKinds.js +1 -1
  263. package/lib/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
  264. package/lib/feature-libraries/default-schema/schemaChecker.js +1 -1
  265. package/lib/feature-libraries/default-schema/schemaChecker.js.map +1 -1
  266. package/lib/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
  267. package/lib/feature-libraries/flex-tree/lazyField.js +4 -3
  268. package/lib/feature-libraries/flex-tree/lazyField.js.map +1 -1
  269. package/lib/feature-libraries/flex-tree/lazyNode.d.ts.map +1 -1
  270. package/lib/feature-libraries/flex-tree/lazyNode.js +5 -4
  271. package/lib/feature-libraries/flex-tree/lazyNode.js.map +1 -1
  272. package/lib/feature-libraries/indexing/anchorTreeIndex.d.ts.map +1 -1
  273. package/lib/feature-libraries/indexing/anchorTreeIndex.js +1 -1
  274. package/lib/feature-libraries/indexing/anchorTreeIndex.js.map +1 -1
  275. package/lib/feature-libraries/modular-schema/comparison.d.ts.map +1 -1
  276. package/lib/feature-libraries/modular-schema/comparison.js +6 -4
  277. package/lib/feature-libraries/modular-schema/comparison.js.map +1 -1
  278. package/lib/feature-libraries/modular-schema/isNeverTree.d.ts.map +1 -1
  279. package/lib/feature-libraries/modular-schema/isNeverTree.js +4 -4
  280. package/lib/feature-libraries/modular-schema/isNeverTree.js.map +1 -1
  281. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js +4 -4
  282. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  283. package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
  284. package/lib/feature-libraries/modular-schema/modularChangeFamily.js +11 -12
  285. package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  286. package/lib/feature-libraries/node-key/mockNodeKeyManager.js +1 -1
  287. package/lib/feature-libraries/node-key/mockNodeKeyManager.js.map +1 -1
  288. package/lib/feature-libraries/object-forest/objectForest.js +1 -1
  289. package/lib/feature-libraries/object-forest/objectForest.js.map +1 -1
  290. package/lib/feature-libraries/schema-index/codec.js +1 -1
  291. package/lib/feature-libraries/schema-index/codec.js.map +1 -1
  292. package/lib/feature-libraries/sequence-field/compose.js +1 -1
  293. package/lib/feature-libraries/sequence-field/compose.js.map +1 -1
  294. package/lib/feature-libraries/sequence-field/invert.js +1 -1
  295. package/lib/feature-libraries/sequence-field/invert.js.map +1 -1
  296. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV1.js +1 -1
  297. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV1.js.map +1 -1
  298. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV2.js +1 -1
  299. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV2.js.map +1 -1
  300. package/lib/feature-libraries/sequence-field/utils.js +1 -1
  301. package/lib/feature-libraries/sequence-field/utils.js.map +1 -1
  302. package/lib/feature-libraries/treeCursorUtils.d.ts.map +1 -1
  303. package/lib/feature-libraries/treeCursorUtils.js +6 -4
  304. package/lib/feature-libraries/treeCursorUtils.js.map +1 -1
  305. package/lib/index.d.ts +4 -2
  306. package/lib/index.d.ts.map +1 -1
  307. package/lib/index.js +3 -1
  308. package/lib/index.js.map +1 -1
  309. package/lib/jsonDomainSchema.d.ts +113 -0
  310. package/lib/jsonDomainSchema.d.ts.map +1 -0
  311. package/lib/jsonDomainSchema.js +98 -0
  312. package/lib/jsonDomainSchema.js.map +1 -0
  313. package/lib/legacy.d.ts +15 -0
  314. package/lib/packageVersion.d.ts +1 -1
  315. package/lib/packageVersion.d.ts.map +1 -1
  316. package/lib/packageVersion.js +1 -1
  317. package/lib/packageVersion.js.map +1 -1
  318. package/lib/public.d.ts +15 -0
  319. package/lib/serializableDomainSchema.d.ts +108 -0
  320. package/lib/serializableDomainSchema.d.ts.map +1 -0
  321. package/lib/serializableDomainSchema.js +87 -0
  322. package/lib/serializableDomainSchema.js.map +1 -0
  323. package/lib/shared-tree/index.d.ts +1 -1
  324. package/lib/shared-tree/index.d.ts.map +1 -1
  325. package/lib/shared-tree/index.js.map +1 -1
  326. package/lib/shared-tree/schematizeTree.js +1 -1
  327. package/lib/shared-tree/schematizeTree.js.map +1 -1
  328. package/lib/shared-tree/sharedTree.d.ts +37 -20
  329. package/lib/shared-tree/sharedTree.d.ts.map +1 -1
  330. package/lib/shared-tree/sharedTree.js +18 -18
  331. package/lib/shared-tree/sharedTree.js.map +1 -1
  332. package/lib/shared-tree/sharedTreeChangeFamily.js +1 -1
  333. package/lib/shared-tree/sharedTreeChangeFamily.js.map +1 -1
  334. package/lib/shared-tree/treeApiAlpha.d.ts.map +1 -1
  335. package/lib/shared-tree/treeApiAlpha.js +4 -4
  336. package/lib/shared-tree/treeApiAlpha.js.map +1 -1
  337. package/lib/shared-tree/treeCheckout.js +1 -1
  338. package/lib/shared-tree/treeCheckout.js.map +1 -1
  339. package/lib/shared-tree-core/editManager.d.ts +11 -2
  340. package/lib/shared-tree-core/editManager.d.ts.map +1 -1
  341. package/lib/shared-tree-core/editManager.js +70 -34
  342. package/lib/shared-tree-core/editManager.js.map +1 -1
  343. package/lib/shared-tree-core/resubmitMachine.d.ts +2 -0
  344. package/lib/shared-tree-core/resubmitMachine.d.ts.map +1 -1
  345. package/lib/shared-tree-core/resubmitMachine.js.map +1 -1
  346. package/lib/shared-tree-core/sharedTreeCore.d.ts +10 -3
  347. package/lib/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  348. package/lib/shared-tree-core/sharedTreeCore.js +42 -7
  349. package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
  350. package/lib/simple-tree/api/component.d.ts +30 -0
  351. package/lib/simple-tree/api/component.d.ts.map +1 -0
  352. package/lib/simple-tree/api/component.js +23 -0
  353. package/lib/simple-tree/api/component.js.map +1 -0
  354. package/lib/simple-tree/api/customTree.js +3 -3
  355. package/lib/simple-tree/api/customTree.js.map +1 -1
  356. package/lib/simple-tree/api/index.d.ts +2 -1
  357. package/lib/simple-tree/api/index.d.ts.map +1 -1
  358. package/lib/simple-tree/api/index.js +1 -0
  359. package/lib/simple-tree/api/index.js.map +1 -1
  360. package/lib/simple-tree/api/schemaCreationUtilities.js +1 -1
  361. package/lib/simple-tree/api/schemaCreationUtilities.js.map +1 -1
  362. package/lib/simple-tree/api/schemaFactory.d.ts +0 -8
  363. package/lib/simple-tree/api/schemaFactory.d.ts.map +1 -1
  364. package/lib/simple-tree/api/schemaFactory.js +2 -22
  365. package/lib/simple-tree/api/schemaFactory.js.map +1 -1
  366. package/lib/simple-tree/api/schemaFactoryRecursive.d.ts +1 -1
  367. package/lib/simple-tree/api/schemaFactoryRecursive.js.map +1 -1
  368. package/lib/simple-tree/api/simpleTreeIndex.js +3 -3
  369. package/lib/simple-tree/api/simpleTreeIndex.js.map +1 -1
  370. package/lib/simple-tree/api/tree.d.ts.map +1 -1
  371. package/lib/simple-tree/api/tree.js +3 -4
  372. package/lib/simple-tree/api/tree.js.map +1 -1
  373. package/lib/simple-tree/api/treeNodeApi.d.ts.map +1 -1
  374. package/lib/simple-tree/api/treeNodeApi.js +9 -20
  375. package/lib/simple-tree/api/treeNodeApi.js.map +1 -1
  376. package/lib/simple-tree/api/typesUnsafe.d.ts +127 -19
  377. package/lib/simple-tree/api/typesUnsafe.d.ts.map +1 -1
  378. package/lib/simple-tree/api/typesUnsafe.js +15 -1
  379. package/lib/simple-tree/api/typesUnsafe.js.map +1 -1
  380. package/lib/simple-tree/api/verboseTree.d.ts.map +1 -1
  381. package/lib/simple-tree/api/verboseTree.js +5 -4
  382. package/lib/simple-tree/api/verboseTree.js.map +1 -1
  383. package/lib/simple-tree/api/view.js +1 -1
  384. package/lib/simple-tree/api/view.js.map +1 -1
  385. package/lib/simple-tree/arrayNode.d.ts +1 -1
  386. package/lib/simple-tree/arrayNode.d.ts.map +1 -1
  387. package/lib/simple-tree/arrayNode.js +2 -2
  388. package/lib/simple-tree/arrayNode.js.map +1 -1
  389. package/lib/simple-tree/core/getOrCreateNode.d.ts.map +1 -1
  390. package/lib/simple-tree/core/getOrCreateNode.js +1 -1
  391. package/lib/simple-tree/core/getOrCreateNode.js.map +1 -1
  392. package/lib/simple-tree/core/schemaCaching.js +1 -1
  393. package/lib/simple-tree/core/schemaCaching.js.map +1 -1
  394. package/lib/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
  395. package/lib/simple-tree/core/treeNodeKernel.js +6 -6
  396. package/lib/simple-tree/core/treeNodeKernel.js.map +1 -1
  397. package/lib/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
  398. package/lib/simple-tree/core/unhydratedFlexTree.js +5 -5
  399. package/lib/simple-tree/core/unhydratedFlexTree.js.map +1 -1
  400. package/lib/simple-tree/flexList.d.ts +4 -5
  401. package/lib/simple-tree/flexList.d.ts.map +1 -1
  402. package/lib/simple-tree/flexList.js +0 -12
  403. package/lib/simple-tree/flexList.js.map +1 -1
  404. package/lib/simple-tree/index.d.ts +4 -4
  405. package/lib/simple-tree/index.d.ts.map +1 -1
  406. package/lib/simple-tree/index.js +2 -2
  407. package/lib/simple-tree/index.js.map +1 -1
  408. package/lib/simple-tree/objectNode.d.ts +25 -2
  409. package/lib/simple-tree/objectNode.d.ts.map +1 -1
  410. package/lib/simple-tree/objectNode.js +4 -2
  411. package/lib/simple-tree/objectNode.js.map +1 -1
  412. package/lib/simple-tree/proxies.js +1 -1
  413. package/lib/simple-tree/proxies.js.map +1 -1
  414. package/lib/simple-tree/schemaTypes.d.ts +211 -9
  415. package/lib/simple-tree/schemaTypes.d.ts.map +1 -1
  416. package/lib/simple-tree/schemaTypes.js +81 -3
  417. package/lib/simple-tree/schemaTypes.js.map +1 -1
  418. package/lib/simple-tree/toMapTree.js +3 -3
  419. package/lib/simple-tree/toMapTree.js.map +1 -1
  420. package/lib/simple-tree/toStoredSchema.d.ts.map +1 -1
  421. package/lib/simple-tree/toStoredSchema.js +5 -8
  422. package/lib/simple-tree/toStoredSchema.js.map +1 -1
  423. package/lib/simple-tree/treeNodeValid.d.ts +7 -1
  424. package/lib/simple-tree/treeNodeValid.d.ts.map +1 -1
  425. package/lib/simple-tree/treeNodeValid.js +18 -7
  426. package/lib/simple-tree/treeNodeValid.js.map +1 -1
  427. package/lib/util/idAllocator.js +1 -1
  428. package/lib/util/idAllocator.js.map +1 -1
  429. package/lib/util/index.d.ts +2 -2
  430. package/lib/util/index.d.ts.map +1 -1
  431. package/lib/util/index.js +2 -2
  432. package/lib/util/index.js.map +1 -1
  433. package/lib/util/nestedMap.d.ts +2 -10
  434. package/lib/util/nestedMap.d.ts.map +1 -1
  435. package/lib/util/nestedMap.js +5 -23
  436. package/lib/util/nestedMap.js.map +1 -1
  437. package/lib/util/utils.d.ts +23 -6
  438. package/lib/util/utils.d.ts.map +1 -1
  439. package/lib/util/utils.js +42 -11
  440. package/lib/util/utils.js.map +1 -1
  441. package/package.json +27 -23
  442. package/src/codec/codec.ts +3 -3
  443. package/src/codec/discriminatedUnions.ts +2 -1
  444. package/src/core/schema-stored/schema.ts +5 -3
  445. package/src/core/tree/anchorSet.ts +37 -26
  446. package/src/core/tree/treeTextFormat.ts +1 -1
  447. package/src/feature-libraries/chunked-forest/basicChunk.ts +11 -8
  448. package/src/feature-libraries/chunked-forest/chunkTree.ts +2 -2
  449. package/src/feature-libraries/chunked-forest/chunkedForest.ts +3 -3
  450. package/src/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.ts +2 -2
  451. package/src/feature-libraries/chunked-forest/codec/compressedEncode.ts +4 -3
  452. package/src/feature-libraries/chunked-forest/codec/nodeShape.ts +2 -2
  453. package/src/feature-libraries/chunked-forest/codec/schemaBasedEncoding.ts +4 -3
  454. package/src/feature-libraries/chunked-forest/emptyChunk.ts +14 -14
  455. package/src/feature-libraries/chunked-forest/uniformChunk.ts +6 -4
  456. package/src/feature-libraries/default-schema/defaultFieldKinds.ts +1 -1
  457. package/src/feature-libraries/default-schema/schemaChecker.ts +1 -1
  458. package/src/feature-libraries/flex-tree/lazyField.ts +6 -8
  459. package/src/feature-libraries/flex-tree/lazyNode.ts +6 -4
  460. package/src/feature-libraries/indexing/anchorTreeIndex.ts +2 -1
  461. package/src/feature-libraries/modular-schema/comparison.ts +7 -5
  462. package/src/feature-libraries/modular-schema/isNeverTree.ts +6 -4
  463. package/src/feature-libraries/modular-schema/modularChangeCodecs.ts +4 -4
  464. package/src/feature-libraries/modular-schema/modularChangeFamily.ts +16 -12
  465. package/src/feature-libraries/node-key/mockNodeKeyManager.ts +1 -1
  466. package/src/feature-libraries/object-forest/objectForest.ts +1 -1
  467. package/src/feature-libraries/schema-index/codec.ts +1 -1
  468. package/src/feature-libraries/sequence-field/compose.ts +1 -1
  469. package/src/feature-libraries/sequence-field/invert.ts +1 -1
  470. package/src/feature-libraries/sequence-field/sequenceFieldCodecV1.ts +1 -1
  471. package/src/feature-libraries/sequence-field/sequenceFieldCodecV2.ts +1 -1
  472. package/src/feature-libraries/sequence-field/utils.ts +1 -1
  473. package/src/feature-libraries/treeCursorUtils.ts +6 -4
  474. package/src/index.ts +22 -1
  475. package/src/jsonDomainSchema.ts +129 -0
  476. package/src/packageVersion.ts +1 -1
  477. package/src/serializableDomainSchema.ts +121 -0
  478. package/src/shared-tree/index.ts +0 -1
  479. package/src/shared-tree/schematizeTree.ts +1 -1
  480. package/src/shared-tree/sharedTree.ts +31 -41
  481. package/src/shared-tree/sharedTreeChangeFamily.ts +1 -1
  482. package/src/shared-tree/treeApiAlpha.ts +12 -4
  483. package/src/shared-tree/treeCheckout.ts +1 -1
  484. package/src/shared-tree-core/editManager.ts +85 -47
  485. package/src/shared-tree-core/resubmitMachine.ts +2 -0
  486. package/src/shared-tree-core/sharedTreeCore.ts +62 -14
  487. package/src/simple-tree/api/component.ts +42 -0
  488. package/src/simple-tree/api/customTree.ts +3 -3
  489. package/src/simple-tree/api/index.ts +7 -0
  490. package/src/simple-tree/api/schemaCreationUtilities.ts +1 -1
  491. package/src/simple-tree/api/schemaFactory.ts +1 -28
  492. package/src/simple-tree/api/schemaFactoryRecursive.ts +1 -1
  493. package/src/simple-tree/api/simpleTreeIndex.ts +3 -3
  494. package/src/simple-tree/api/tree.ts +3 -3
  495. package/src/simple-tree/api/treeNodeApi.ts +10 -18
  496. package/src/simple-tree/api/typesUnsafe.ts +193 -18
  497. package/src/simple-tree/api/verboseTree.ts +8 -4
  498. package/src/simple-tree/api/view.ts +1 -1
  499. package/src/simple-tree/arrayNode.ts +2 -2
  500. package/src/simple-tree/core/getOrCreateNode.ts +2 -1
  501. package/src/simple-tree/core/schemaCaching.ts +1 -1
  502. package/src/simple-tree/core/treeNodeKernel.ts +9 -6
  503. package/src/simple-tree/core/unhydratedFlexTree.ts +7 -5
  504. package/src/simple-tree/flexList.ts +4 -14
  505. package/src/simple-tree/index.ts +25 -1
  506. package/src/simple-tree/objectNode.ts +50 -5
  507. package/src/simple-tree/proxies.ts +1 -1
  508. package/src/simple-tree/schemaTypes.ts +322 -23
  509. package/src/simple-tree/toMapTree.ts +3 -3
  510. package/src/simple-tree/toStoredSchema.ts +5 -7
  511. package/src/simple-tree/treeNodeValid.ts +21 -7
  512. package/src/util/idAllocator.ts +1 -1
  513. package/src/util/index.ts +3 -2
  514. package/src/util/nestedMap.ts +9 -33
  515. package/src/util/utils.ts +52 -12
@@ -27,6 +27,8 @@ import {
27
27
  type ImplicitAllowedTypes,
28
28
  FieldKind,
29
29
  type NodeSchemaMetadata,
30
+ type GetTypes,
31
+ type SchemaUnionToIntersection,
30
32
  } from "./schemaTypes.js";
31
33
  import {
32
34
  type TreeNodeSchema,
@@ -56,11 +58,51 @@ import { getUnhydratedContext } from "./createContext.js";
56
58
  * @system @public
57
59
  */
58
60
  export type ObjectFromSchemaRecord<T extends RestrictiveStringRecord<ImplicitFieldSchema>> = {
59
- -readonly [Property in keyof T]: Property extends string
60
- ? TreeFieldFromImplicitField<T[Property]>
61
- : unknown;
61
+ // Due to https://github.com/microsoft/TypeScript/issues/43826 we can not set the desired setter type,
62
+ // but we can at least remove the setter (by setting the key to never) when there should be no setter.
63
+ -readonly [Property in keyof T as [
64
+ AssignableTreeFieldFromImplicitField<T[Property & string]>,
65
+ // If the types we want to allow setting to are just never or undefined, remove the setter
66
+ ] extends [never | undefined]
67
+ ? never
68
+ : Property]: AssignableTreeFieldFromImplicitField<T[Property & string]>;
69
+ } & {
70
+ readonly [Property in keyof T]: TreeFieldFromImplicitField<T[Property & string]>;
62
71
  };
63
72
 
73
+ /**
74
+ * Type of content that can be assigned to a field of the given schema.
75
+ *
76
+ * @see {@link Input}
77
+ *
78
+ * @typeparam TSchemaInput - Schema to process.
79
+ * @typeparam TSchema - Do not specify: default value used as an implementation detail.
80
+ * @system @public
81
+ */
82
+ export type AssignableTreeFieldFromImplicitField<
83
+ TSchemaInput extends ImplicitFieldSchema,
84
+ TSchema = SchemaUnionToIntersection<TSchemaInput>,
85
+ > = [TSchema] extends [FieldSchema<infer Kind, infer Types>]
86
+ ? ApplyKindAssignment<GetTypes<Types>["readWrite"], Kind>
87
+ : [TSchema] extends [ImplicitAllowedTypes]
88
+ ? GetTypes<TSchema>["readWrite"]
89
+ : never;
90
+
91
+ /**
92
+ * Suitable for assignment.
93
+ *
94
+ * @see {@link Input}
95
+ * @system @public
96
+ */
97
+ export type ApplyKindAssignment<T, Kind extends FieldKind> = [Kind] extends [
98
+ FieldKind.Required,
99
+ ]
100
+ ? T
101
+ : [Kind] extends [FieldKind.Optional]
102
+ ? T | undefined
103
+ : // Unknown, non-exact and identifier fields are not assignable.
104
+ never;
105
+
64
106
  /**
65
107
  * A {@link TreeNode} which modules a JavaScript object.
66
108
  * @remarks
@@ -262,7 +304,7 @@ function createProxyHandler(
262
304
  // For some reason, the getOwnPropertyDescriptor is not passed in the receiver, so use a weak map.
263
305
  // If a refactoring is done to associated flex tree data with the target not the proxy, this extra map could be removed,
264
306
  // and the design would be more compatible with proxyless nodes.
265
- const proxy = targetToProxy.get(target) ?? fail("missing proxy");
307
+ const proxy = targetToProxy.get(target) ?? fail(0xadd /* missing proxy */);
266
308
  const field = getOrCreateInnerNode(proxy).tryGetField(fieldInfo.storedKey);
267
309
 
268
310
  const p: PropertyDescriptor = {
@@ -311,7 +353,7 @@ export function setField(
311
353
  }
312
354
 
313
355
  default:
314
- fail("invalid FieldKind");
356
+ fail(0xade /* invalid FieldKind */);
315
357
  }
316
358
  }
317
359
 
@@ -340,6 +382,9 @@ export function objectSchema<
340
382
  metadata?: NodeSchemaMetadata<TCustomMetadata>,
341
383
  ): ObjectNodeSchema<TName, T, ImplicitlyConstructable, TCustomMetadata> &
342
384
  ObjectNodeSchemaInternalData {
385
+ // Field set can't be modified after since derived data is stored in maps.
386
+ Object.freeze(info);
387
+
343
388
  // Ensure no collisions between final set of property keys, and final set of stored keys (including those
344
389
  // implicitly derived from property keys)
345
390
  assertUniqueKeys(identifier, info);
@@ -56,7 +56,7 @@ export function getTreeNodeForField(field: FlexTreeField): TreeNode | TreeValue
56
56
  }
57
57
 
58
58
  default:
59
- fail("invalid field kind");
59
+ fail(0xadf /* invalid field kind */);
60
60
  }
61
61
  }
62
62
 
@@ -16,19 +16,23 @@ import {
16
16
  compareSets,
17
17
  type requireTrue,
18
18
  type areOnlyKeys,
19
+ getOrCreate,
19
20
  } from "../util/index.js";
20
- import type {
21
- Unhydrated,
22
- NodeKind,
23
- TreeNodeSchema,
24
- TreeNodeSchemaClass,
25
- TreeNode,
26
- TreeNodeSchemaCore,
27
- TreeNodeSchemaNonClass,
21
+ import {
22
+ type Unhydrated,
23
+ type NodeKind,
24
+ type TreeNodeSchema,
25
+ type TreeNodeSchemaClass,
26
+ type TreeNode,
27
+ type TreeNodeSchemaCore,
28
+ type TreeNodeSchemaNonClass,
29
+ inPrototypeChain,
28
30
  } from "./core/index.js";
29
31
  import type { FieldKey } from "../core/index.js";
30
32
  import type { InsertableContent } from "./toMapTree.js";
31
33
  import { isLazy, type FlexListToUnion, type LazyItem } from "./flexList.js";
34
+ import { LeafNodeSchema } from "./leafNodeSchema.js";
35
+ import { TreeNodeValid } from "./treeNodeValid.js";
32
36
 
33
37
  /**
34
38
  * Returns true if the given schema is a {@link TreeNodeSchemaClass}, or otherwise false if it is a {@link TreeNodeSchemaNonClass}.
@@ -69,6 +73,8 @@ export function isTreeNodeSchemaClass<
69
73
  * way to declare and manipulate unordered sets of types in TypeScript.
70
74
  *
71
75
  * Not intended for direct use outside of package.
76
+ * @privateRemarks
77
+ * Code reading data from this should use `normalizeAllowedTypes` to ensure consistent handling, caching, nice errors etc.
72
78
  * @system @public
73
79
  */
74
80
  export type AllowedTypes = readonly LazyItem<TreeNodeSchema>[];
@@ -379,6 +385,8 @@ export function normalizeAllowedTypes(
379
385
  ): ReadonlySet<TreeNodeSchema> {
380
386
  const normalized = new Set<TreeNodeSchema>();
381
387
  if (isReadonlyArray(types)) {
388
+ // Types array must not be modified after it is normalized since that would result if the user of the normalized data having wrong (out of date) content.
389
+ Object.freeze(types);
382
390
  for (const lazyType of types) {
383
391
  normalized.add(evaluateLazySchema(lazyType));
384
392
  }
@@ -469,16 +477,59 @@ function areMetadataEqual(
469
477
  return a?.custom === b?.custom && a?.description === b?.description;
470
478
  }
471
479
 
472
- function evaluateLazySchema(value: LazyItem<TreeNodeSchema>): TreeNodeSchema {
473
- const evaluatedSchema = isLazy(value) ? value() : value;
480
+ const cachedLazyItem = new WeakMap<() => unknown, unknown>();
481
+
482
+ /**
483
+ * Returns the schema referenced by the {@link LazyItem}.
484
+ * @remarks
485
+ * Caches results to handle {@link LazyItem} which compute their resulting schema.
486
+ * @alpha
487
+ */
488
+ export function evaluateLazySchema<T extends TreeNodeSchema>(value: LazyItem<T>): T {
489
+ const evaluatedSchema = isLazy(value)
490
+ ? (getOrCreate(cachedLazyItem, value, value) as T)
491
+ : value;
474
492
  if (evaluatedSchema === undefined) {
475
493
  throw new UsageError(
476
494
  `Encountered an undefined schema. This could indicate that some referenced schema has not yet been instantiated.`,
477
495
  );
478
496
  }
497
+ markSchemaMostDerived(evaluatedSchema);
479
498
  return evaluatedSchema;
480
499
  }
481
500
 
501
+ /**
502
+ * Indicates that a schema is the "most derived" version which is allowed to be used, see {@link MostDerivedData}.
503
+ * Calling helps with error messages about invalid schema usage (using more than one type from single schema factor produced type,
504
+ * and thus calling this for one than one subclass).
505
+ * @remarks
506
+ * Helper for invoking {@link TreeNodeValid.markMostDerived} for any {@link TreeNodeSchema} if it needed.
507
+ */
508
+ export function markSchemaMostDerived(
509
+ schema: TreeNodeSchema,
510
+ oneTimeInitialize = false,
511
+ ): void {
512
+ if (schema instanceof LeafNodeSchema) {
513
+ return;
514
+ }
515
+
516
+ if (!inPrototypeChain(schema, TreeNodeValid)) {
517
+ // Use JSON.stringify to quote and escape identifier string.
518
+ throw new UsageError(
519
+ `Schema for ${JSON.stringify(
520
+ schema.identifier,
521
+ )} does not extend a SchemaFactory generated class. This is invalid.`,
522
+ );
523
+ }
524
+
525
+ const schemaValid = schema as typeof TreeNodeValid & TreeNodeSchema;
526
+ if (oneTimeInitialize) {
527
+ schemaValid.oneTimeInitialize();
528
+ } else {
529
+ schemaValid.markMostDerived();
530
+ }
531
+ }
532
+
482
533
  /**
483
534
  * Types of {@link TreeNode|TreeNodes} or {@link TreeLeafValue|TreeLeafValues} allowed at a location in a tree.
484
535
  * @remarks
@@ -508,6 +559,8 @@ function evaluateLazySchema(value: LazyItem<TreeNodeSchema>): TreeNodeSchema {
508
559
  * class A extends sf.array("example", [() => B]) {}
509
560
  * class B extends sf.array("Inner", sf.number) {}
510
561
  * ```
562
+ * @privateRemarks
563
+ * Code reading data from this should use `normalizeAllowedTypes` to ensure consistent handling, caching, nice errors etc.
511
564
  * @public
512
565
  */
513
566
  export type ImplicitAllowedTypes = AllowedTypes | TreeNodeSchema;
@@ -546,13 +599,27 @@ export type TreeFieldFromImplicitField<TSchema extends ImplicitFieldSchema = Fie
546
599
  */
547
600
  export type InsertableTreeFieldFromImplicitField<
548
601
  TSchemaInput extends ImplicitFieldSchema,
549
- TSchema = UnionToIntersection<TSchemaInput>,
602
+ TSchema = [TSchemaInput] extends [CustomizedSchemaTyping<unknown, CustomTypes>]
603
+ ? TSchemaInput
604
+ : SchemaUnionToIntersection<TSchemaInput>,
550
605
  > = [TSchema] extends [FieldSchema<infer Kind, infer Types>]
551
606
  ? ApplyKindInput<InsertableTreeNodeFromImplicitAllowedTypes<Types>, Kind, true>
552
607
  : [TSchema] extends [ImplicitAllowedTypes]
553
608
  ? InsertableTreeNodeFromImplicitAllowedTypes<TSchema>
554
609
  : never;
555
610
 
611
+ /**
612
+ * {@link UnionToIntersection} except it does not distribute over {@link CustomizedSchemaTyping}s when the original type is a union.
613
+ * @privateRemarks
614
+ * This is a workaround for TypeScript distributing over intersections over unions when distributing extends over unions.
615
+ * @system @public
616
+ */
617
+ export type SchemaUnionToIntersection<T> = [T] extends [
618
+ CustomizedSchemaTyping<unknown, CustomTypes>,
619
+ ]
620
+ ? T
621
+ : UnionToIntersection<T>;
622
+
556
623
  /**
557
624
  * {@inheritdoc (UnsafeUnknownSchema:type)}
558
625
  * @alpha
@@ -575,22 +642,228 @@ export const UnsafeUnknownSchema: unique symbol = Symbol("UnsafeUnknownSchema");
575
642
  * Any APIs which use this must produce UsageErrors when out of schema data is encountered, and never produce unrecoverable errors,
576
643
  * or silently accept invalid data.
577
644
  * This is currently only type exported from the package: the symbol is just used as a way to get a named type.
645
+ *
646
+ * TODO: This takes a very different approach than `customizeSchemaTyping` which applies to allowed types.
647
+ * Maybe generalize that to apply to field schema as well and replace this with it?
578
648
  * @alpha
579
649
  */
580
650
  export type UnsafeUnknownSchema = typeof UnsafeUnknownSchema;
581
651
 
652
+ /**
653
+ * {@inheritdoc (CustomizedTyping:type)}
654
+ * @system @public
655
+ */
656
+ export const CustomizedTyping: unique symbol = Symbol("CustomizedTyping");
657
+
658
+ /**
659
+ * A type brand used by {@link customizeSchemaTyping}.
660
+ * @system @public
661
+ */
662
+ export type CustomizedTyping = typeof CustomizedTyping;
663
+
664
+ /**
665
+ * Collection of schema aware types.
666
+ * @remarks
667
+ * This type is only used as a type constraint.
668
+ * It's fields are similar to an unordered set of generic type parameters.
669
+ * {@link customizeSchemaTyping} applies this to {@link ImplicitAllowedTypes} via {@link CustomizedSchemaTyping}.
670
+ * @sealed @public
671
+ */
672
+ export interface CustomTypes {
673
+ /**
674
+ * Type used for inserting values.
675
+ */
676
+ readonly input: unknown;
677
+ /**
678
+ * Type used for the read+write property on object nodes.
679
+ *
680
+ * Set to never to disable setter.
681
+ * @remarks
682
+ * Due to https://github.com/microsoft/TypeScript/issues/43826 we cannot set the desired setter type.
683
+ * Instead we can only control the types of the read+write property and the type of a readonly property.
684
+ *
685
+ * For recursive types using {@link SchemaFactory.objectRecursive}, support for using `never` to remove setters is limited:
686
+ * When the customized schema is wrapped in an {@link FieldSchema}, the setter will not be fully removed.
687
+ */
688
+ readonly readWrite: TreeLeafValue | TreeNode;
689
+ /**
690
+ * Type for reading data.
691
+ * @remarks
692
+ * See limitation for read+write properties on ObjectNodes in {@link CustomTypes.readWrite}.
693
+ */
694
+ readonly output: TreeLeafValue | TreeNode;
695
+ }
696
+
697
+ /**
698
+ * Type annotation which overrides the default schema derived types with customized ones.
699
+ * @remarks
700
+ * See {@link customizeSchemaTyping} for more information.
701
+ * @system @public
702
+ */
703
+ export type CustomizedSchemaTyping<TSchema, TCustom extends CustomTypes> = TSchema & {
704
+ [CustomizedTyping]: TCustom;
705
+ };
706
+
707
+ /**
708
+ * Default strict policy.
709
+ *
710
+ * @typeparam TSchema - The schema to process
711
+ * @typeparam TInput - Internal: do not specify.
712
+ * @typeparam TOutput - Internal: do not specify.
713
+ * @remarks
714
+ * Handles input types contravariantly so any input which might be invalid is rejected.
715
+ * @sealed @public
716
+ */
717
+ export interface StrictTypes<
718
+ TSchema extends ImplicitAllowedTypes,
719
+ TInput = DefaultInsertableTreeNodeFromImplicitAllowedTypes<TSchema>,
720
+ TOutput extends TreeNode | TreeLeafValue = DefaultTreeNodeFromImplicitAllowedTypes<TSchema>,
721
+ > {
722
+ input: TInput;
723
+ readWrite: TInput extends never ? never : TOutput;
724
+ output: TOutput;
725
+ }
726
+
727
+ /**
728
+ * Customizes the types associated with `TSchema`
729
+ * @remarks
730
+ * By default, the types used when constructing, reading and writing tree nodes are derived from the schema.
731
+ * In some cases, it may be desirable to override these types with carefully selected alternatives.
732
+ * This utility allows for that customization.
733
+ * Note that this customization is only used for typing, and does not affect the runtime behavior at all.
734
+ *
735
+ * This can be used for a wide variety of purposes, including (but not limited to):
736
+ *
737
+ * 1. Implementing better typing for a runtime extensible set of types (e.g. a polymorphic collection).
738
+ * This is commonly needed when implementing containers which don't directly reference their child types, and can be done using {@link Customizer.simplified}.
739
+ * 2. Adding type brands to specific values to increase type safety.
740
+ * This can be done using {@link Customizer.simplified}.
741
+ * 3. Adding some (compile time only) constraints to values, like enum style unions.
742
+ * This can be done using {@link Customizer.simplified}.
743
+ * 4. Making fields readonly (for the current client).
744
+ * This can be done using {@link Customizer.custom} with `{ readWrite: never; }`.
745
+ * 5. Opting into more [compleat and less sound](https://en.wikipedia.org/wiki/Soundness#Relation_to_completeness) typing.
746
+ * {@link Customizer.relaxed} is an example of this.
747
+ *
748
+ * For this customization to be used, the resulting schema must be used as `ImplicitAllowedTypes`.
749
+ * For example applying this to a single type, then using that type in an array of allowed types will have no effect:
750
+ * in such a case the customization must instead be applied to the array of allowed types.
751
+ * @privateRemarks
752
+ * Once this API is more stable/final, the examples in tests such as openPolymorphism.spec.ts and schemaFactory.examples.spec.ts
753
+ * should be copied into examples here, or somehow linked.
754
+ * @alpha
755
+ */
756
+ export function customizeSchemaTyping<const TSchema extends ImplicitAllowedTypes>(
757
+ schema: TSchema,
758
+ ): Customizer<TSchema> {
759
+ // This function just does type branding, and duplicating the typing here to avoid any would just make it harder to maintain not easier:
760
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
761
+ const f = (): any => schema;
762
+ return { strict: f, relaxed: f, simplified: f, simplifiedUnrestricted: f, custom: f };
763
+ }
764
+
765
+ /**
766
+ * Utility for customizing the types used for data matching a given schema.
767
+ * @sealed @alpha
768
+ */
769
+ export interface Customizer<TSchema extends ImplicitAllowedTypes> {
770
+ /**
771
+ * The default {@link StrictTypes}, explicitly applied.
772
+ */
773
+ strict(): CustomizedSchemaTyping<TSchema, StrictTypes<TSchema>>;
774
+ /**
775
+ * Relaxed policy: allows possible invalid edits (which will err at runtime) when schema is not exact.
776
+ * @remarks
777
+ * Handles input types covariantly so any input which might be valid with the schema is allowed
778
+ * instead of the default strict policy of only inputs with all possible schema are allowed.
779
+ *
780
+ * This only modifies the typing shallowly: the typing of children are not effected.
781
+ */
782
+ relaxed(): CustomizedSchemaTyping<
783
+ TSchema,
784
+ {
785
+ input: TreeNodeSchema extends TSchema
786
+ ? InsertableContent
787
+ : // This intentionally distributes unions over the conditional to get covariant type handling.
788
+ TSchema extends TreeNodeSchema
789
+ ? InsertableTypedNode<TSchema>
790
+ : // This intentionally distributes unions over the conditional to get covariant type handling.
791
+ TSchema extends AllowedTypes
792
+ ? TSchema[number] extends LazyItem<infer TSchemaInner extends TreeNodeSchema>
793
+ ? InsertableTypedNode<TSchemaInner, TSchemaInner>
794
+ : never
795
+ : never;
796
+ readWrite: TreeNodeFromImplicitAllowedTypes<TSchema>;
797
+ output: TreeNodeFromImplicitAllowedTypes<TSchema>;
798
+ }
799
+ >;
800
+ /**
801
+ * Replace typing with a single substitute which allowed types must implement.
802
+ * @remarks
803
+ * This is generally type safe for reading the tree, but allows instances of `T` other than those listed in the schema to be assigned,
804
+ * which can be out of schema and err at runtime in the same way {@link Customizer.relaxed} does.
805
+ * Until with {@link Customizer.relaxed}, implicit construction is disabled, meaning all nodes must be explicitly constructed (and thus implement `T`) before being inserted.
806
+ */
807
+ simplified<T extends TreeNodeFromImplicitAllowedTypes<TSchema>>(): CustomizedSchemaTyping<
808
+ TSchema,
809
+ {
810
+ input: T;
811
+ readWrite: T;
812
+ output: T;
813
+ }
814
+ >;
815
+
816
+ /**
817
+ * The same as {@link Customizer} except that more T values are allowed, even ones not known to be implemented by `TSchema`.
818
+ */
819
+ simplifiedUnrestricted<T extends TreeNode | TreeLeafValue>(): CustomizedSchemaTyping<
820
+ TSchema,
821
+ {
822
+ input: T;
823
+ readWrite: T;
824
+ output: T;
825
+ }
826
+ >;
827
+
828
+ /**
829
+ * Fully arbitrary customization.
830
+ * Provided types override existing types.
831
+ */
832
+ custom<T extends Partial<CustomTypes>>(): CustomizedSchemaTyping<
833
+ TSchema,
834
+ {
835
+ // Check if property is provided. This check is needed to early out missing values so if undefined is allowed,
836
+ // not providing the field doesn't overwrite the corresponding type with undefined.
837
+ // TODO: test this case
838
+ [Property in keyof CustomTypes]: Property extends keyof T
839
+ ? T[Property] extends CustomTypes[Property]
840
+ ? T[Property]
841
+ : GetTypes<TSchema>[Property]
842
+ : GetTypes<TSchema>[Property];
843
+ }
844
+ >;
845
+ }
846
+
847
+ /**
848
+ * Fetch types associated with a schema, or use the default if not customized.
849
+ * @system @public
850
+ */
851
+ export type GetTypes<TSchema extends ImplicitAllowedTypes> = [TSchema] extends [
852
+ CustomizedSchemaTyping<unknown, infer TCustom>,
853
+ ]
854
+ ? TCustom
855
+ : StrictTypes<TSchema>;
856
+
582
857
  /**
583
858
  * Content which could be inserted into a tree.
584
859
  *
585
860
  * @see {@link Input}
586
861
  * @remarks
587
- * Extended version of {@link InsertableTreeNodeFromImplicitAllowedTypes} that also allows {@link (UnsafeUnknownSchema:type)}.
862
+ * Alias of {@link InsertableTreeNodeFromImplicitAllowedTypes} with a shorter name.
588
863
  * @alpha
589
864
  */
590
- export type Insertable<TSchema extends ImplicitAllowedTypes | UnsafeUnknownSchema> =
591
- TSchema extends ImplicitAllowedTypes
592
- ? InsertableTreeNodeFromImplicitAllowedTypes<TSchema>
593
- : InsertableContent;
865
+ export type Insertable<TSchema extends ImplicitAllowedTypes> =
866
+ InsertableTreeNodeFromImplicitAllowedTypes<TSchema>;
594
867
 
595
868
  /**
596
869
  * Content which could be inserted into a field within a tree.
@@ -664,10 +937,22 @@ export type ApplyKindInput<T, Kind extends FieldKind, DefaultsAreOptional extend
664
937
 
665
938
  /**
666
939
  * Type of tree node for a field of the given schema.
940
+ *
941
+ * @typeparam TSchema - Schema to process.
942
+ * @remarks
943
+ * Defaults to {@link DefaultTreeNodeFromImplicitAllowedTypes}.
667
944
  * @public
668
945
  */
669
946
  export type TreeNodeFromImplicitAllowedTypes<
670
947
  TSchema extends ImplicitAllowedTypes = TreeNodeSchema,
948
+ > = GetTypes<TSchema>["output"];
949
+
950
+ /**
951
+ * Default type of tree node for a field of the given schema.
952
+ * @system @public
953
+ */
954
+ export type DefaultTreeNodeFromImplicitAllowedTypes<
955
+ TSchema extends ImplicitAllowedTypes = TreeNodeSchema,
671
956
  > = TSchema extends TreeNodeSchema
672
957
  ? NodeFromSchema<TSchema>
673
958
  : TSchema extends AllowedTypes
@@ -727,6 +1012,17 @@ export type TreeNodeFromImplicitAllowedTypes<
727
1012
  */
728
1013
  export type Input<T extends never> = T;
729
1014
 
1015
+ /**
1016
+ * Type of content that can be inserted into the tree for a node of the given schema.
1017
+ *
1018
+ * @typeparam TSchema - Schema to process.
1019
+ * @remarks
1020
+ * Defaults to {@link DefaultInsertableTreeNodeFromImplicitAllowedTypes}.
1021
+ * @public
1022
+ */
1023
+ export type InsertableTreeNodeFromImplicitAllowedTypes<TSchema extends ImplicitAllowedTypes> =
1024
+ GetTypes<TSchema>["input"];
1025
+
730
1026
  /**
731
1027
  * Type of content that can be inserted into the tree for a node of the given schema.
732
1028
  *
@@ -736,14 +1032,15 @@ export type Input<T extends never> = T;
736
1032
  *
737
1033
  * @privateRemarks
738
1034
  * This is a bit overly conservative, since cases like `A | [A]` give never and could give `A`.
739
- * @public
1035
+ * @system @public
740
1036
  */
741
- export type InsertableTreeNodeFromImplicitAllowedTypes<TSchema extends ImplicitAllowedTypes> =
742
- [TSchema] extends [TreeNodeSchema]
743
- ? InsertableTypedNode<TSchema>
744
- : [TSchema] extends [AllowedTypes]
745
- ? InsertableTreeNodeFromAllowedTypes<TSchema>
746
- : never;
1037
+ export type DefaultInsertableTreeNodeFromImplicitAllowedTypes<
1038
+ TSchema extends ImplicitAllowedTypes,
1039
+ > = [TSchema] extends [TreeNodeSchema]
1040
+ ? InsertableTypedNode<TSchema>
1041
+ : [TSchema] extends [AllowedTypes]
1042
+ ? InsertableTreeNodeFromAllowedTypes<TSchema>
1043
+ : never;
747
1044
 
748
1045
  /**
749
1046
  * Type of content that can be inserted into the tree for a node of the given schema.
@@ -793,6 +1090,8 @@ export type NodeFromSchema<T extends TreeNodeSchema> = T extends TreeNodeSchemaC
793
1090
  * One special case this makes is if the result of NodeFromSchema contains TreeNode, this must be an under constrained schema, so the result is set to never.
794
1091
  * Note that applying UnionToIntersection on the result of NodeFromSchema<T> does not work since it breaks booleans.
795
1092
  *
1093
+ * Some internal code may use second parameter to opt out of contravariant behavior, but this is not a stable API.
1094
+ *
796
1095
  * @public
797
1096
  */
798
1097
  export type InsertableTypedNode<
@@ -196,7 +196,7 @@ function nodeDataToMapTree(
196
196
  result = objectToMapTree(data, schema);
197
197
  break;
198
198
  default:
199
- fail("Unrecognized schema kind");
199
+ fail(0xae0 /* Unrecognized schema kind */);
200
200
  }
201
201
 
202
202
  return result;
@@ -642,7 +642,7 @@ export function addDefaultsToMapTree(
642
642
  ): void {
643
643
  const schema =
644
644
  find(normalizeAllowedTypes(allowedTypes), (s) => s.identifier === mapTree.type) ??
645
- fail("MapTree is incompatible with schema");
645
+ fail(0xae1 /* MapTree is incompatible with schema */);
646
646
 
647
647
  if (isObjectNodeSchema(schema)) {
648
648
  for (const [_key, fieldInfo] of schema.flexKeyMap) {
@@ -660,7 +660,7 @@ export function addDefaultsToMapTree(
660
660
  setFieldValue(mapTree.fields, data, fieldInfo.schema, fieldInfo.storedKey);
661
661
  // call addDefaultsToMapTree on newly inserted default values
662
662
  for (const child of mapTree.fields.get(fieldInfo.storedKey) ??
663
- fail("Expected field to be populated")) {
663
+ fail(0xae2 /* Expected field to be populated */)) {
664
664
  addDefaultsToMapTree(child, fieldInfo.schema.allowedTypes, context);
665
665
  }
666
666
  }
@@ -20,18 +20,18 @@ import {
20
20
  type TreeTypeSet,
21
21
  } from "../core/index.js";
22
22
  import { FieldKinds, type FlexFieldKind } from "../feature-libraries/index.js";
23
- import { brand, fail, getOrCreate, isReadonlyArray } from "../util/index.js";
23
+ import { brand, fail, getOrCreate } from "../util/index.js";
24
24
  import { NodeKind, type TreeNodeSchema } from "./core/index.js";
25
25
  import {
26
26
  FieldKind,
27
27
  FieldSchema,
28
+ normalizeAllowedTypes,
28
29
  type ImplicitAllowedTypes,
29
30
  type ImplicitFieldSchema,
30
31
  } from "./schemaTypes.js";
31
32
  import { walkFieldSchema } from "./walkFieldSchema.js";
32
33
  import { LeafNodeSchema } from "./leafNodeSchema.js";
33
34
  import { isObjectNodeSchema } from "./objectNodeTypes.js";
34
- import { normalizeFlexListEager } from "./flexList.js";
35
35
 
36
36
  const viewToStoredCache = new WeakMap<ImplicitFieldSchema, TreeStoredSchema>();
37
37
 
@@ -71,7 +71,8 @@ export function convertField(schema: ImplicitFieldSchema): TreeFieldStoredSchema
71
71
  let kind: FieldKindIdentifier;
72
72
  let allowedTypes: ImplicitAllowedTypes;
73
73
  if (schema instanceof FieldSchema) {
74
- kind = convertFieldKind.get(schema.kind)?.identifier ?? fail("Invalid field kind");
74
+ kind =
75
+ convertFieldKind.get(schema.kind)?.identifier ?? fail(0xae3 /* Invalid field kind */);
75
76
  allowedTypes = schema.allowedTypes;
76
77
  } else {
77
78
  kind = FieldKinds.required.identifier;
@@ -91,10 +92,7 @@ const convertFieldKind = new Map<FieldKind, FlexFieldKind>([
91
92
  * Normalizes an {@link ImplicitAllowedTypes} into an {@link TreeTypeSet}.
92
93
  */
93
94
  export function convertAllowedTypes(schema: ImplicitAllowedTypes): TreeTypeSet {
94
- if (isReadonlyArray(schema)) {
95
- return new Set(normalizeFlexListEager(schema).map((item) => brand(item.identifier)));
96
- }
97
- return new Set([brand(schema.identifier)]);
95
+ return new Set([...normalizeAllowedTypes(schema)].map((item) => brand(item.identifier)));
98
96
  }
99
97
 
100
98
  /**
@@ -58,15 +58,17 @@ export abstract class TreeNodeValid<TInput> extends TreeNode {
58
58
  instance: TreeNodeValid<T>,
59
59
  input: T,
60
60
  ): UnhydratedFlexTreeNode {
61
- return fail("Schema must override buildRawNode");
61
+ return fail(0xae4 /* Schema must override buildRawNode */);
62
62
  }
63
63
 
64
64
  /**
65
65
  * Schema classes can override to provide a callback that is called once when the first node is constructed.
66
66
  * This is a good place to perform extra validation and cache schema derived data needed for the implementation of the node.
67
+ * @remarks
68
+ * It is valid to dereference LazyItem schema references in this function (or anything that runs after it).
67
69
  */
68
70
  protected static oneTimeSetup<T>(this: typeof TreeNodeValid<T>): Context {
69
- fail("Missing oneTimeSetup");
71
+ fail(0xae5 /* Missing oneTimeSetup */);
70
72
  }
71
73
 
72
74
  /**
@@ -119,6 +121,9 @@ export abstract class TreeNodeValid<TInput> extends TreeNode {
119
121
  return this.constructorCached;
120
122
  }
121
123
 
124
+ // If users trying to diagnose the cause of this error becomes a common issue, more information could be captured.
125
+ // The call stack to when a schema is first marked most derived could be captured in debug builds and stored in the `MostDerivedData` object:
126
+ // This could then be included in the error to aid in debugging this error.
122
127
  throw new UsageError(
123
128
  `Two schema classes were used (${this.name} and ${
124
129
  this.constructorCached.constructor.name
@@ -143,7 +148,7 @@ export abstract class TreeNodeValid<TInput> extends TreeNode {
143
148
  }
144
149
 
145
150
  /**
146
- * @see {@link TreeNodeSchemaCore.createFromInsertable}.
151
+ * See {@link TreeNodeSchemaCore.createFromInsertable}.
147
152
  */
148
153
  public static createFromInsertable<TInput, TOut, TThis extends new (args: TInput) => TOut>(
149
154
  this: TThis,
@@ -152,13 +157,22 @@ export abstract class TreeNodeValid<TInput> extends TreeNode {
152
157
  return new this(input);
153
158
  }
154
159
 
160
+ /**
161
+ * Idempotent initialization function that pre-caches data and can dereference lazy schema references.
162
+ */
163
+ public static oneTimeInitialize(
164
+ this: typeof TreeNodeValid & TreeNodeSchema,
165
+ ): Required<MostDerivedData> {
166
+ const cache = this.markMostDerived();
167
+ cache.oneTimeInitialized ??= this.oneTimeSetup();
168
+ // Typescript fails to narrow the type of `oneTimeInitialized` to `Context` here, so use a cast:
169
+ return cache as MostDerivedData & { oneTimeInitialized: Context };
170
+ }
171
+
155
172
  public constructor(input: TInput | InternalTreeNode) {
156
173
  super(privateToken);
157
174
  const schema = this.constructor as typeof TreeNodeValid & TreeNodeSchema;
158
- const cache = schema.markMostDerived();
159
- if (cache.oneTimeInitialized === undefined) {
160
- cache.oneTimeInitialized = schema.oneTimeSetup();
161
- }
175
+ const cache = schema.oneTimeInitialize();
162
176
 
163
177
  if (isTreeNode(input)) {
164
178
  // TODO: update this once we have better support for deep-copying and move operations.