@fluidframework/tree 2.22.1 → 2.23.0

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 (427) hide show
  1. package/.vscode/extensions.json +1 -0
  2. package/CHANGELOG.md +47 -0
  3. package/api-report/tree.alpha.api.md +31 -0
  4. package/dist/alpha.d.ts +1 -0
  5. package/dist/codec/codec.js +3 -3
  6. package/dist/codec/codec.js.map +1 -1
  7. package/dist/codec/discriminatedUnions.d.ts.map +1 -1
  8. package/dist/codec/discriminatedUnions.js +1 -1
  9. package/dist/codec/discriminatedUnions.js.map +1 -1
  10. package/dist/core/schema-stored/schema.d.ts.map +1 -1
  11. package/dist/core/schema-stored/schema.js +3 -3
  12. package/dist/core/schema-stored/schema.js.map +1 -1
  13. package/dist/core/tree/anchorSet.d.ts.map +1 -1
  14. package/dist/core/tree/anchorSet.js +18 -13
  15. package/dist/core/tree/anchorSet.js.map +1 -1
  16. package/dist/core/tree/treeTextFormat.js +1 -1
  17. package/dist/core/tree/treeTextFormat.js.map +1 -1
  18. package/dist/feature-libraries/chunked-forest/basicChunk.d.ts.map +1 -1
  19. package/dist/feature-libraries/chunked-forest/basicChunk.js +11 -8
  20. package/dist/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
  21. package/dist/feature-libraries/chunked-forest/chunkTree.js +2 -2
  22. package/dist/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
  23. package/dist/feature-libraries/chunked-forest/chunkedForest.js +3 -3
  24. package/dist/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
  25. package/dist/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.js +2 -2
  26. package/dist/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.js.map +1 -1
  27. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.d.ts.map +1 -1
  28. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js +4 -3
  29. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
  30. package/dist/feature-libraries/chunked-forest/codec/nodeShape.js +2 -2
  31. package/dist/feature-libraries/chunked-forest/codec/nodeShape.js.map +1 -1
  32. package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncoding.d.ts.map +1 -1
  33. package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncoding.js +3 -3
  34. package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncoding.js.map +1 -1
  35. package/dist/feature-libraries/chunked-forest/emptyChunk.js +14 -14
  36. package/dist/feature-libraries/chunked-forest/emptyChunk.js.map +1 -1
  37. package/dist/feature-libraries/chunked-forest/uniformChunk.d.ts.map +1 -1
  38. package/dist/feature-libraries/chunked-forest/uniformChunk.js +6 -4
  39. package/dist/feature-libraries/chunked-forest/uniformChunk.js.map +1 -1
  40. package/dist/feature-libraries/default-schema/defaultFieldKinds.js +1 -1
  41. package/dist/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
  42. package/dist/feature-libraries/default-schema/schemaChecker.js +1 -1
  43. package/dist/feature-libraries/default-schema/schemaChecker.js.map +1 -1
  44. package/dist/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
  45. package/dist/feature-libraries/flex-tree/lazyField.js +4 -3
  46. package/dist/feature-libraries/flex-tree/lazyField.js.map +1 -1
  47. package/dist/feature-libraries/flex-tree/lazyNode.d.ts.map +1 -1
  48. package/dist/feature-libraries/flex-tree/lazyNode.js +5 -4
  49. package/dist/feature-libraries/flex-tree/lazyNode.js.map +1 -1
  50. package/dist/feature-libraries/indexing/anchorTreeIndex.d.ts.map +1 -1
  51. package/dist/feature-libraries/indexing/anchorTreeIndex.js +1 -1
  52. package/dist/feature-libraries/indexing/anchorTreeIndex.js.map +1 -1
  53. package/dist/feature-libraries/modular-schema/comparison.d.ts.map +1 -1
  54. package/dist/feature-libraries/modular-schema/comparison.js +6 -4
  55. package/dist/feature-libraries/modular-schema/comparison.js.map +1 -1
  56. package/dist/feature-libraries/modular-schema/isNeverTree.d.ts.map +1 -1
  57. package/dist/feature-libraries/modular-schema/isNeverTree.js +4 -4
  58. package/dist/feature-libraries/modular-schema/isNeverTree.js.map +1 -1
  59. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js +4 -4
  60. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  61. package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
  62. package/dist/feature-libraries/modular-schema/modularChangeFamily.js +10 -11
  63. package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  64. package/dist/feature-libraries/node-key/mockNodeKeyManager.js +1 -1
  65. package/dist/feature-libraries/node-key/mockNodeKeyManager.js.map +1 -1
  66. package/dist/feature-libraries/object-forest/objectForest.js +1 -1
  67. package/dist/feature-libraries/object-forest/objectForest.js.map +1 -1
  68. package/dist/feature-libraries/schema-index/codec.js +1 -1
  69. package/dist/feature-libraries/schema-index/codec.js.map +1 -1
  70. package/dist/feature-libraries/sequence-field/compose.js +1 -1
  71. package/dist/feature-libraries/sequence-field/compose.js.map +1 -1
  72. package/dist/feature-libraries/sequence-field/invert.js +1 -1
  73. package/dist/feature-libraries/sequence-field/invert.js.map +1 -1
  74. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV1.js +1 -1
  75. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV1.js.map +1 -1
  76. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV2.js +1 -1
  77. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV2.js.map +1 -1
  78. package/dist/feature-libraries/sequence-field/utils.js +1 -1
  79. package/dist/feature-libraries/sequence-field/utils.js.map +1 -1
  80. package/dist/feature-libraries/treeCursorUtils.d.ts.map +1 -1
  81. package/dist/feature-libraries/treeCursorUtils.js +6 -4
  82. package/dist/feature-libraries/treeCursorUtils.js.map +1 -1
  83. package/dist/index.d.ts +3 -1
  84. package/dist/index.d.ts.map +1 -1
  85. package/dist/index.js +5 -1
  86. package/dist/index.js.map +1 -1
  87. package/dist/jsonDomainSchema.d.ts +113 -0
  88. package/dist/jsonDomainSchema.d.ts.map +1 -0
  89. package/dist/jsonDomainSchema.js +101 -0
  90. package/dist/jsonDomainSchema.js.map +1 -0
  91. package/dist/packageVersion.d.ts +1 -1
  92. package/dist/packageVersion.js +1 -1
  93. package/dist/packageVersion.js.map +1 -1
  94. package/dist/serializableDomainSchema.d.ts +108 -0
  95. package/dist/serializableDomainSchema.d.ts.map +1 -0
  96. package/dist/serializableDomainSchema.js +90 -0
  97. package/dist/serializableDomainSchema.js.map +1 -0
  98. package/dist/shared-tree/index.d.ts +1 -1
  99. package/dist/shared-tree/index.d.ts.map +1 -1
  100. package/dist/shared-tree/index.js.map +1 -1
  101. package/dist/shared-tree/schematizeTree.js +1 -1
  102. package/dist/shared-tree/schematizeTree.js.map +1 -1
  103. package/dist/shared-tree/sharedTree.d.ts +37 -20
  104. package/dist/shared-tree/sharedTree.d.ts.map +1 -1
  105. package/dist/shared-tree/sharedTree.js +17 -17
  106. package/dist/shared-tree/sharedTree.js.map +1 -1
  107. package/dist/shared-tree/sharedTreeChangeFamily.js +1 -1
  108. package/dist/shared-tree/sharedTreeChangeFamily.js.map +1 -1
  109. package/dist/shared-tree/treeApiAlpha.d.ts.map +1 -1
  110. package/dist/shared-tree/treeApiAlpha.js +4 -4
  111. package/dist/shared-tree/treeApiAlpha.js.map +1 -1
  112. package/dist/shared-tree/treeCheckout.js +1 -1
  113. package/dist/shared-tree/treeCheckout.js.map +1 -1
  114. package/dist/shared-tree-core/editManager.d.ts +11 -2
  115. package/dist/shared-tree-core/editManager.d.ts.map +1 -1
  116. package/dist/shared-tree-core/editManager.js +70 -34
  117. package/dist/shared-tree-core/editManager.js.map +1 -1
  118. package/dist/shared-tree-core/resubmitMachine.d.ts +2 -0
  119. package/dist/shared-tree-core/resubmitMachine.d.ts.map +1 -1
  120. package/dist/shared-tree-core/resubmitMachine.js.map +1 -1
  121. package/dist/shared-tree-core/sharedTreeCore.d.ts +10 -3
  122. package/dist/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  123. package/dist/shared-tree-core/sharedTreeCore.js +42 -7
  124. package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
  125. package/dist/simple-tree/api/customTree.js +3 -3
  126. package/dist/simple-tree/api/customTree.js.map +1 -1
  127. package/dist/simple-tree/api/schemaCreationUtilities.js +1 -1
  128. package/dist/simple-tree/api/schemaCreationUtilities.js.map +1 -1
  129. package/dist/simple-tree/api/schemaFactoryRecursive.d.ts +1 -1
  130. package/dist/simple-tree/api/schemaFactoryRecursive.js.map +1 -1
  131. package/dist/simple-tree/api/simpleTreeIndex.js +3 -3
  132. package/dist/simple-tree/api/simpleTreeIndex.js.map +1 -1
  133. package/dist/simple-tree/api/tree.js +1 -1
  134. package/dist/simple-tree/api/tree.js.map +1 -1
  135. package/dist/simple-tree/api/treeNodeApi.d.ts.map +1 -1
  136. package/dist/simple-tree/api/treeNodeApi.js +9 -5
  137. package/dist/simple-tree/api/treeNodeApi.js.map +1 -1
  138. package/dist/simple-tree/api/verboseTree.d.ts.map +1 -1
  139. package/dist/simple-tree/api/verboseTree.js +5 -4
  140. package/dist/simple-tree/api/verboseTree.js.map +1 -1
  141. package/dist/simple-tree/api/view.js +1 -1
  142. package/dist/simple-tree/api/view.js.map +1 -1
  143. package/dist/simple-tree/arrayNode.js +2 -2
  144. package/dist/simple-tree/arrayNode.js.map +1 -1
  145. package/dist/simple-tree/core/getOrCreateNode.d.ts.map +1 -1
  146. package/dist/simple-tree/core/getOrCreateNode.js +1 -1
  147. package/dist/simple-tree/core/getOrCreateNode.js.map +1 -1
  148. package/dist/simple-tree/core/schemaCaching.js +1 -1
  149. package/dist/simple-tree/core/schemaCaching.js.map +1 -1
  150. package/dist/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
  151. package/dist/simple-tree/core/treeNodeKernel.js +6 -6
  152. package/dist/simple-tree/core/treeNodeKernel.js.map +1 -1
  153. package/dist/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
  154. package/dist/simple-tree/core/unhydratedFlexTree.js +5 -5
  155. package/dist/simple-tree/core/unhydratedFlexTree.js.map +1 -1
  156. package/dist/simple-tree/objectNode.js +2 -2
  157. package/dist/simple-tree/objectNode.js.map +1 -1
  158. package/dist/simple-tree/proxies.js +1 -1
  159. package/dist/simple-tree/proxies.js.map +1 -1
  160. package/dist/simple-tree/toMapTree.js +3 -3
  161. package/dist/simple-tree/toMapTree.js.map +1 -1
  162. package/dist/simple-tree/toStoredSchema.d.ts.map +1 -1
  163. package/dist/simple-tree/toStoredSchema.js +2 -1
  164. package/dist/simple-tree/toStoredSchema.js.map +1 -1
  165. package/dist/simple-tree/treeNodeValid.d.ts.map +1 -1
  166. package/dist/simple-tree/treeNodeValid.js +5 -2
  167. package/dist/simple-tree/treeNodeValid.js.map +1 -1
  168. package/dist/util/idAllocator.js +1 -1
  169. package/dist/util/idAllocator.js.map +1 -1
  170. package/dist/util/index.d.ts +2 -2
  171. package/dist/util/index.d.ts.map +1 -1
  172. package/dist/util/index.js +5 -4
  173. package/dist/util/index.js.map +1 -1
  174. package/dist/util/nestedMap.d.ts +2 -10
  175. package/dist/util/nestedMap.d.ts.map +1 -1
  176. package/dist/util/nestedMap.js +9 -28
  177. package/dist/util/nestedMap.js.map +1 -1
  178. package/dist/util/utils.d.ts +23 -6
  179. package/dist/util/utils.d.ts.map +1 -1
  180. package/dist/util/utils.js +46 -13
  181. package/dist/util/utils.js.map +1 -1
  182. package/lib/alpha.d.ts +1 -0
  183. package/lib/codec/codec.js +3 -3
  184. package/lib/codec/codec.js.map +1 -1
  185. package/lib/codec/discriminatedUnions.d.ts.map +1 -1
  186. package/lib/codec/discriminatedUnions.js +1 -1
  187. package/lib/codec/discriminatedUnions.js.map +1 -1
  188. package/lib/core/schema-stored/schema.d.ts.map +1 -1
  189. package/lib/core/schema-stored/schema.js +3 -3
  190. package/lib/core/schema-stored/schema.js.map +1 -1
  191. package/lib/core/tree/anchorSet.d.ts.map +1 -1
  192. package/lib/core/tree/anchorSet.js +19 -14
  193. package/lib/core/tree/anchorSet.js.map +1 -1
  194. package/lib/core/tree/treeTextFormat.js +1 -1
  195. package/lib/core/tree/treeTextFormat.js.map +1 -1
  196. package/lib/feature-libraries/chunked-forest/basicChunk.d.ts.map +1 -1
  197. package/lib/feature-libraries/chunked-forest/basicChunk.js +11 -8
  198. package/lib/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
  199. package/lib/feature-libraries/chunked-forest/chunkTree.js +2 -2
  200. package/lib/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
  201. package/lib/feature-libraries/chunked-forest/chunkedForest.js +3 -3
  202. package/lib/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
  203. package/lib/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.js +2 -2
  204. package/lib/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.js.map +1 -1
  205. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.d.ts.map +1 -1
  206. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js +4 -3
  207. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
  208. package/lib/feature-libraries/chunked-forest/codec/nodeShape.js +2 -2
  209. package/lib/feature-libraries/chunked-forest/codec/nodeShape.js.map +1 -1
  210. package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncoding.d.ts.map +1 -1
  211. package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncoding.js +3 -3
  212. package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncoding.js.map +1 -1
  213. package/lib/feature-libraries/chunked-forest/emptyChunk.js +14 -14
  214. package/lib/feature-libraries/chunked-forest/emptyChunk.js.map +1 -1
  215. package/lib/feature-libraries/chunked-forest/uniformChunk.d.ts.map +1 -1
  216. package/lib/feature-libraries/chunked-forest/uniformChunk.js +6 -4
  217. package/lib/feature-libraries/chunked-forest/uniformChunk.js.map +1 -1
  218. package/lib/feature-libraries/default-schema/defaultFieldKinds.js +1 -1
  219. package/lib/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
  220. package/lib/feature-libraries/default-schema/schemaChecker.js +1 -1
  221. package/lib/feature-libraries/default-schema/schemaChecker.js.map +1 -1
  222. package/lib/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
  223. package/lib/feature-libraries/flex-tree/lazyField.js +4 -3
  224. package/lib/feature-libraries/flex-tree/lazyField.js.map +1 -1
  225. package/lib/feature-libraries/flex-tree/lazyNode.d.ts.map +1 -1
  226. package/lib/feature-libraries/flex-tree/lazyNode.js +5 -4
  227. package/lib/feature-libraries/flex-tree/lazyNode.js.map +1 -1
  228. package/lib/feature-libraries/indexing/anchorTreeIndex.d.ts.map +1 -1
  229. package/lib/feature-libraries/indexing/anchorTreeIndex.js +1 -1
  230. package/lib/feature-libraries/indexing/anchorTreeIndex.js.map +1 -1
  231. package/lib/feature-libraries/modular-schema/comparison.d.ts.map +1 -1
  232. package/lib/feature-libraries/modular-schema/comparison.js +6 -4
  233. package/lib/feature-libraries/modular-schema/comparison.js.map +1 -1
  234. package/lib/feature-libraries/modular-schema/isNeverTree.d.ts.map +1 -1
  235. package/lib/feature-libraries/modular-schema/isNeverTree.js +4 -4
  236. package/lib/feature-libraries/modular-schema/isNeverTree.js.map +1 -1
  237. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js +4 -4
  238. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  239. package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
  240. package/lib/feature-libraries/modular-schema/modularChangeFamily.js +11 -12
  241. package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  242. package/lib/feature-libraries/node-key/mockNodeKeyManager.js +1 -1
  243. package/lib/feature-libraries/node-key/mockNodeKeyManager.js.map +1 -1
  244. package/lib/feature-libraries/object-forest/objectForest.js +1 -1
  245. package/lib/feature-libraries/object-forest/objectForest.js.map +1 -1
  246. package/lib/feature-libraries/schema-index/codec.js +1 -1
  247. package/lib/feature-libraries/schema-index/codec.js.map +1 -1
  248. package/lib/feature-libraries/sequence-field/compose.js +1 -1
  249. package/lib/feature-libraries/sequence-field/compose.js.map +1 -1
  250. package/lib/feature-libraries/sequence-field/invert.js +1 -1
  251. package/lib/feature-libraries/sequence-field/invert.js.map +1 -1
  252. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV1.js +1 -1
  253. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV1.js.map +1 -1
  254. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV2.js +1 -1
  255. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV2.js.map +1 -1
  256. package/lib/feature-libraries/sequence-field/utils.js +1 -1
  257. package/lib/feature-libraries/sequence-field/utils.js.map +1 -1
  258. package/lib/feature-libraries/treeCursorUtils.d.ts.map +1 -1
  259. package/lib/feature-libraries/treeCursorUtils.js +6 -4
  260. package/lib/feature-libraries/treeCursorUtils.js.map +1 -1
  261. package/lib/index.d.ts +3 -1
  262. package/lib/index.d.ts.map +1 -1
  263. package/lib/index.js +2 -0
  264. package/lib/index.js.map +1 -1
  265. package/lib/jsonDomainSchema.d.ts +113 -0
  266. package/lib/jsonDomainSchema.d.ts.map +1 -0
  267. package/lib/jsonDomainSchema.js +98 -0
  268. package/lib/jsonDomainSchema.js.map +1 -0
  269. package/lib/packageVersion.d.ts +1 -1
  270. package/lib/packageVersion.js +1 -1
  271. package/lib/packageVersion.js.map +1 -1
  272. package/lib/serializableDomainSchema.d.ts +108 -0
  273. package/lib/serializableDomainSchema.d.ts.map +1 -0
  274. package/lib/serializableDomainSchema.js +87 -0
  275. package/lib/serializableDomainSchema.js.map +1 -0
  276. package/lib/shared-tree/index.d.ts +1 -1
  277. package/lib/shared-tree/index.d.ts.map +1 -1
  278. package/lib/shared-tree/index.js.map +1 -1
  279. package/lib/shared-tree/schematizeTree.js +1 -1
  280. package/lib/shared-tree/schematizeTree.js.map +1 -1
  281. package/lib/shared-tree/sharedTree.d.ts +37 -20
  282. package/lib/shared-tree/sharedTree.d.ts.map +1 -1
  283. package/lib/shared-tree/sharedTree.js +18 -18
  284. package/lib/shared-tree/sharedTree.js.map +1 -1
  285. package/lib/shared-tree/sharedTreeChangeFamily.js +1 -1
  286. package/lib/shared-tree/sharedTreeChangeFamily.js.map +1 -1
  287. package/lib/shared-tree/treeApiAlpha.d.ts.map +1 -1
  288. package/lib/shared-tree/treeApiAlpha.js +4 -4
  289. package/lib/shared-tree/treeApiAlpha.js.map +1 -1
  290. package/lib/shared-tree/treeCheckout.js +1 -1
  291. package/lib/shared-tree/treeCheckout.js.map +1 -1
  292. package/lib/shared-tree-core/editManager.d.ts +11 -2
  293. package/lib/shared-tree-core/editManager.d.ts.map +1 -1
  294. package/lib/shared-tree-core/editManager.js +70 -34
  295. package/lib/shared-tree-core/editManager.js.map +1 -1
  296. package/lib/shared-tree-core/resubmitMachine.d.ts +2 -0
  297. package/lib/shared-tree-core/resubmitMachine.d.ts.map +1 -1
  298. package/lib/shared-tree-core/resubmitMachine.js.map +1 -1
  299. package/lib/shared-tree-core/sharedTreeCore.d.ts +10 -3
  300. package/lib/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  301. package/lib/shared-tree-core/sharedTreeCore.js +42 -7
  302. package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
  303. package/lib/simple-tree/api/customTree.js +3 -3
  304. package/lib/simple-tree/api/customTree.js.map +1 -1
  305. package/lib/simple-tree/api/schemaCreationUtilities.js +1 -1
  306. package/lib/simple-tree/api/schemaCreationUtilities.js.map +1 -1
  307. package/lib/simple-tree/api/schemaFactoryRecursive.d.ts +1 -1
  308. package/lib/simple-tree/api/schemaFactoryRecursive.js.map +1 -1
  309. package/lib/simple-tree/api/simpleTreeIndex.js +3 -3
  310. package/lib/simple-tree/api/simpleTreeIndex.js.map +1 -1
  311. package/lib/simple-tree/api/tree.js +1 -1
  312. package/lib/simple-tree/api/tree.js.map +1 -1
  313. package/lib/simple-tree/api/treeNodeApi.d.ts.map +1 -1
  314. package/lib/simple-tree/api/treeNodeApi.js +9 -5
  315. package/lib/simple-tree/api/treeNodeApi.js.map +1 -1
  316. package/lib/simple-tree/api/verboseTree.d.ts.map +1 -1
  317. package/lib/simple-tree/api/verboseTree.js +5 -4
  318. package/lib/simple-tree/api/verboseTree.js.map +1 -1
  319. package/lib/simple-tree/api/view.js +1 -1
  320. package/lib/simple-tree/api/view.js.map +1 -1
  321. package/lib/simple-tree/arrayNode.js +2 -2
  322. package/lib/simple-tree/arrayNode.js.map +1 -1
  323. package/lib/simple-tree/core/getOrCreateNode.d.ts.map +1 -1
  324. package/lib/simple-tree/core/getOrCreateNode.js +1 -1
  325. package/lib/simple-tree/core/getOrCreateNode.js.map +1 -1
  326. package/lib/simple-tree/core/schemaCaching.js +1 -1
  327. package/lib/simple-tree/core/schemaCaching.js.map +1 -1
  328. package/lib/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
  329. package/lib/simple-tree/core/treeNodeKernel.js +6 -6
  330. package/lib/simple-tree/core/treeNodeKernel.js.map +1 -1
  331. package/lib/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
  332. package/lib/simple-tree/core/unhydratedFlexTree.js +5 -5
  333. package/lib/simple-tree/core/unhydratedFlexTree.js.map +1 -1
  334. package/lib/simple-tree/objectNode.js +2 -2
  335. package/lib/simple-tree/objectNode.js.map +1 -1
  336. package/lib/simple-tree/proxies.js +1 -1
  337. package/lib/simple-tree/proxies.js.map +1 -1
  338. package/lib/simple-tree/toMapTree.js +3 -3
  339. package/lib/simple-tree/toMapTree.js.map +1 -1
  340. package/lib/simple-tree/toStoredSchema.d.ts.map +1 -1
  341. package/lib/simple-tree/toStoredSchema.js +2 -1
  342. package/lib/simple-tree/toStoredSchema.js.map +1 -1
  343. package/lib/simple-tree/treeNodeValid.d.ts.map +1 -1
  344. package/lib/simple-tree/treeNodeValid.js +5 -2
  345. package/lib/simple-tree/treeNodeValid.js.map +1 -1
  346. package/lib/util/idAllocator.js +1 -1
  347. package/lib/util/idAllocator.js.map +1 -1
  348. package/lib/util/index.d.ts +2 -2
  349. package/lib/util/index.d.ts.map +1 -1
  350. package/lib/util/index.js +2 -2
  351. package/lib/util/index.js.map +1 -1
  352. package/lib/util/nestedMap.d.ts +2 -10
  353. package/lib/util/nestedMap.d.ts.map +1 -1
  354. package/lib/util/nestedMap.js +5 -23
  355. package/lib/util/nestedMap.js.map +1 -1
  356. package/lib/util/utils.d.ts +23 -6
  357. package/lib/util/utils.d.ts.map +1 -1
  358. package/lib/util/utils.js +42 -11
  359. package/lib/util/utils.js.map +1 -1
  360. package/package.json +22 -22
  361. package/src/codec/codec.ts +3 -3
  362. package/src/codec/discriminatedUnions.ts +2 -1
  363. package/src/core/schema-stored/schema.ts +5 -3
  364. package/src/core/tree/anchorSet.ts +37 -26
  365. package/src/core/tree/treeTextFormat.ts +1 -1
  366. package/src/feature-libraries/chunked-forest/basicChunk.ts +11 -8
  367. package/src/feature-libraries/chunked-forest/chunkTree.ts +2 -2
  368. package/src/feature-libraries/chunked-forest/chunkedForest.ts +3 -3
  369. package/src/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.ts +2 -2
  370. package/src/feature-libraries/chunked-forest/codec/compressedEncode.ts +4 -3
  371. package/src/feature-libraries/chunked-forest/codec/nodeShape.ts +2 -2
  372. package/src/feature-libraries/chunked-forest/codec/schemaBasedEncoding.ts +4 -3
  373. package/src/feature-libraries/chunked-forest/emptyChunk.ts +14 -14
  374. package/src/feature-libraries/chunked-forest/uniformChunk.ts +6 -4
  375. package/src/feature-libraries/default-schema/defaultFieldKinds.ts +1 -1
  376. package/src/feature-libraries/default-schema/schemaChecker.ts +1 -1
  377. package/src/feature-libraries/flex-tree/lazyField.ts +6 -8
  378. package/src/feature-libraries/flex-tree/lazyNode.ts +6 -4
  379. package/src/feature-libraries/indexing/anchorTreeIndex.ts +2 -1
  380. package/src/feature-libraries/modular-schema/comparison.ts +7 -5
  381. package/src/feature-libraries/modular-schema/isNeverTree.ts +6 -4
  382. package/src/feature-libraries/modular-schema/modularChangeCodecs.ts +4 -4
  383. package/src/feature-libraries/modular-schema/modularChangeFamily.ts +16 -12
  384. package/src/feature-libraries/node-key/mockNodeKeyManager.ts +1 -1
  385. package/src/feature-libraries/object-forest/objectForest.ts +1 -1
  386. package/src/feature-libraries/schema-index/codec.ts +1 -1
  387. package/src/feature-libraries/sequence-field/compose.ts +1 -1
  388. package/src/feature-libraries/sequence-field/invert.ts +1 -1
  389. package/src/feature-libraries/sequence-field/sequenceFieldCodecV1.ts +1 -1
  390. package/src/feature-libraries/sequence-field/sequenceFieldCodecV2.ts +1 -1
  391. package/src/feature-libraries/sequence-field/utils.ts +1 -1
  392. package/src/feature-libraries/treeCursorUtils.ts +6 -4
  393. package/src/index.ts +3 -1
  394. package/src/jsonDomainSchema.ts +129 -0
  395. package/src/packageVersion.ts +1 -1
  396. package/src/serializableDomainSchema.ts +121 -0
  397. package/src/shared-tree/index.ts +0 -1
  398. package/src/shared-tree/schematizeTree.ts +1 -1
  399. package/src/shared-tree/sharedTree.ts +31 -41
  400. package/src/shared-tree/sharedTreeChangeFamily.ts +1 -1
  401. package/src/shared-tree/treeApiAlpha.ts +12 -4
  402. package/src/shared-tree/treeCheckout.ts +1 -1
  403. package/src/shared-tree-core/editManager.ts +85 -47
  404. package/src/shared-tree-core/resubmitMachine.ts +2 -0
  405. package/src/shared-tree-core/sharedTreeCore.ts +62 -14
  406. package/src/simple-tree/api/customTree.ts +3 -3
  407. package/src/simple-tree/api/schemaCreationUtilities.ts +1 -1
  408. package/src/simple-tree/api/schemaFactoryRecursive.ts +1 -1
  409. package/src/simple-tree/api/simpleTreeIndex.ts +3 -3
  410. package/src/simple-tree/api/tree.ts +1 -1
  411. package/src/simple-tree/api/treeNodeApi.ts +11 -6
  412. package/src/simple-tree/api/verboseTree.ts +8 -4
  413. package/src/simple-tree/api/view.ts +1 -1
  414. package/src/simple-tree/arrayNode.ts +2 -2
  415. package/src/simple-tree/core/getOrCreateNode.ts +2 -1
  416. package/src/simple-tree/core/schemaCaching.ts +1 -1
  417. package/src/simple-tree/core/treeNodeKernel.ts +9 -6
  418. package/src/simple-tree/core/unhydratedFlexTree.ts +7 -5
  419. package/src/simple-tree/objectNode.ts +2 -2
  420. package/src/simple-tree/proxies.ts +1 -1
  421. package/src/simple-tree/toMapTree.ts +3 -3
  422. package/src/simple-tree/toStoredSchema.ts +2 -1
  423. package/src/simple-tree/treeNodeValid.ts +5 -2
  424. package/src/util/idAllocator.ts +1 -1
  425. package/src/util/index.ts +3 -2
  426. package/src/util/nestedMap.ts +9 -33
  427. package/src/util/utils.ts +52 -12
@@ -184,7 +184,7 @@ export class TreeNodeKernel {
184
184
  // This can't be cached on this.#hydrated during hydration since initial tree is hydrated before the context is cached on the anchorSet.
185
185
  return (
186
186
  this.#hydrationState?.anchorNode.anchorSet.slots.get(SimpleContextSlot) ??
187
- fail("missing simple-tree context")
187
+ fail(0xb40 /* missing simple-tree context */)
188
188
  );
189
189
  }
190
190
  return this.initialContext;
@@ -303,7 +303,8 @@ export class TreeNodeKernel {
303
303
  this.#hydrationState.innerNode = flexNode;
304
304
  } else {
305
305
  // ...otherwise, the flex node must be created
306
- const context = anchorNode.anchorSet.slots.get(ContextSlot) ?? fail("missing context");
306
+ const context =
307
+ anchorNode.anchorSet.slots.get(ContextSlot) ?? fail(0xb41 /* missing context */);
307
308
  const cursor = context.checkout.forest.allocateCursor("getFlexNode");
308
309
  context.checkout.forest.moveCursorToPath(anchorNode, cursor);
309
310
  this.#hydrationState.innerNode = makeTree(context, cursor);
@@ -332,7 +333,8 @@ export class TreeNodeKernel {
332
333
  public anchorProxy(anchors: AnchorSet, path: UpPath): AnchorNode {
333
334
  assert(!anchorForgetters.has(this.node), 0x91c /* Proxy anchor should not be set twice */);
334
335
  const anchor = anchors.track(path);
335
- const anchorNode = anchors.locate(anchor) ?? fail("Expected anchor node to be present");
336
+ const anchorNode =
337
+ anchors.locate(anchor) ?? fail(0xb42 /* Expected anchor node to be present */);
336
338
  this.hydrate(anchorNode);
337
339
  const forget = (): void => {
338
340
  if (anchors.locate(anchor)) {
@@ -434,9 +436,9 @@ export function getTreeNodeSchemaFromHydratedFlexNode(flexNode: FlexTreeNode): T
434
436
 
435
437
  const context =
436
438
  flexNode.anchorNode.anchorSet.slots.get(SimpleContextSlot) ??
437
- fail("Missing SimpleContextSlot");
439
+ fail(0xb43 /* Missing SimpleContextSlot */);
438
440
 
439
- return context.schema.get(flexNode.schema) ?? fail("Missing schema");
441
+ return context.schema.get(flexNode.schema) ?? fail(0xb44 /* Missing schema */);
440
442
  }
441
443
 
442
444
  /**
@@ -461,7 +463,8 @@ function flexNodeFromAnchor(anchorNode: AnchorNode): FlexTreeNode {
461
463
  if (flexNode !== undefined) {
462
464
  return flexNode; // If it does have a flex node, return it...
463
465
  } // ...otherwise, the flex node must be created
464
- const context = anchorNode.anchorSet.slots.get(ContextSlot) ?? fail("missing context");
466
+ const context =
467
+ anchorNode.anchorSet.slots.get(ContextSlot) ?? fail(0xb45 /* missing context */);
465
468
  const cursor = context.checkout.forest.allocateCursor("getFlexNode");
466
469
  context.checkout.forest.moveCursorToPath(anchorNode, cursor);
467
470
  const newFlexNode = makeTree(context, cursor);
@@ -79,7 +79,9 @@ export class UnhydratedFlexTreeNode implements UnhydratedFlexTreeNode {
79
79
  }
80
80
 
81
81
  public get storedSchema(): TreeNodeStoredSchema {
82
- return this.context.schema.nodeSchema.get(this.mapTree.type) ?? fail("missing schema");
82
+ return (
83
+ this.context.schema.nodeSchema.get(this.mapTree.type) ?? fail(0xb46 /* missing schema */)
84
+ );
83
85
  }
84
86
 
85
87
  public readonly [flexTreeMarker] = FlexTreeEntityKind.Node as const;
@@ -215,7 +217,7 @@ export class UnhydratedFlexTreeNode implements UnhydratedFlexTreeNode {
215
217
  public get anchorNode(): AnchorNode {
216
218
  // This API is relevant to `LazyTreeNode`s, but not `UnhydratedFlexTreeNode`s.
217
219
  // TODO: Refactor the FlexTreeNode interface so that stubbing this out isn't necessary.
218
- return fail("UnhydratedFlexTreeNode does not implement anchorNode");
220
+ return fail(0xb47 /* UnhydratedFlexTreeNode does not implement anchorNode */);
219
221
  }
220
222
 
221
223
  private walkTree(): void {
@@ -294,10 +296,10 @@ const unparentedLocation: LocationInField = {
294
296
  },
295
297
  schema: brand(forbiddenFieldKindIdentifier),
296
298
  get context(): never {
297
- return fail("unsupported");
299
+ return fail(0xb48 /* unsupported */);
298
300
  },
299
301
  getFieldPath() {
300
- fail("unsupported");
302
+ fail(0xb49 /* unsupported */);
301
303
  },
302
304
  },
303
305
  index: -1,
@@ -489,7 +491,7 @@ export class UnhydratedTreeSequenceField
489
491
  this.edit((mapTrees) => {
490
492
  removed = mapTrees.splice(index, count);
491
493
  });
492
- return removed ?? fail("Expected removed to be set by edit");
494
+ return removed ?? fail(0xb4a /* Expected removed to be set by edit */);
493
495
  },
494
496
  };
495
497
 
@@ -262,7 +262,7 @@ function createProxyHandler(
262
262
  // For some reason, the getOwnPropertyDescriptor is not passed in the receiver, so use a weak map.
263
263
  // If a refactoring is done to associated flex tree data with the target not the proxy, this extra map could be removed,
264
264
  // and the design would be more compatible with proxyless nodes.
265
- const proxy = targetToProxy.get(target) ?? fail("missing proxy");
265
+ const proxy = targetToProxy.get(target) ?? fail(0xadd /* missing proxy */);
266
266
  const field = getOrCreateInnerNode(proxy).tryGetField(fieldInfo.storedKey);
267
267
 
268
268
  const p: PropertyDescriptor = {
@@ -311,7 +311,7 @@ export function setField(
311
311
  }
312
312
 
313
313
  default:
314
- fail("invalid FieldKind");
314
+ fail(0xade /* invalid FieldKind */);
315
315
  }
316
316
  }
317
317
 
@@ -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
 
@@ -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
  }
@@ -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;
@@ -58,7 +58,7 @@ 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
  /**
@@ -66,7 +66,7 @@ export abstract class TreeNodeValid<TInput> extends TreeNode {
66
66
  * This is a good place to perform extra validation and cache schema derived data needed for the implementation of the node.
67
67
  */
68
68
  protected static oneTimeSetup<T>(this: typeof TreeNodeValid<T>): Context {
69
- fail("Missing oneTimeSetup");
69
+ fail(0xae5 /* Missing oneTimeSetup */);
70
70
  }
71
71
 
72
72
  /**
@@ -119,6 +119,9 @@ export abstract class TreeNodeValid<TInput> extends TreeNode {
119
119
  return this.constructorCached;
120
120
  }
121
121
 
122
+ // If users trying to diagnose the cause of this error becomes a common issue, more information could be captured.
123
+ // The call stack to when a schema is first marked most derived could be captured in debug builds and stored in the `MostDerivedData` object:
124
+ // This could then be included in the error to aid in debugging this error.
122
125
  throw new UsageError(
123
126
  `Two schema classes were used (${this.name} and ${
124
127
  this.constructorCached.constructor.name
@@ -44,6 +44,6 @@ export function idAllocatorFromState(state: IdAllocationState): IdAllocator {
44
44
  }
45
45
 
46
46
  export const fakeIdAllocator: IdAllocator = {
47
- allocate: () => fail("Should not allocate IDs"),
47
+ allocate: () => fail(0xae6 /* Should not allocate IDs */),
48
48
  getMaxId: () => 0,
49
49
  };
package/src/util/index.ts CHANGED
@@ -19,8 +19,6 @@ export {
19
19
  } from "./opaque.js";
20
20
  export {
21
21
  deleteFromNestedMap,
22
- getOrAddInMap,
23
- getOrAddInMapLazy,
24
22
  getOrAddInNestedMap,
25
23
  getOrDefaultInNestedMap,
26
24
  forEachInNestedMap,
@@ -34,6 +32,7 @@ export {
34
32
  mapNestedMap,
35
33
  nestedMapToFlatList,
36
34
  nestedMapFromFlatList,
35
+ getOrCreateInNestedMap,
37
36
  } from "./nestedMap.js";
38
37
  export { addToNestedSet, type NestedSet, nestedSetContains } from "./nestedSet.js";
39
38
  export { type OffsetList, OffsetListFactory } from "./offsetList.js";
@@ -56,6 +55,7 @@ export type {
56
55
  export { StackyIterator } from "./stackyIterator.js";
57
56
  export {
58
57
  asMutable,
58
+ balancedReduce,
59
59
  clone,
60
60
  compareSets,
61
61
  fail,
@@ -95,6 +95,7 @@ export {
95
95
  hasSingle,
96
96
  defineLazyCachedProperty,
97
97
  copyPropertyIfDefined as copyProperty,
98
+ getOrAddInMap,
98
99
  } from "./utils.js";
99
100
  export { ReferenceCountedBase, type ReferenceCounted } from "./referenceCounting.js";
100
101
 
@@ -5,7 +5,7 @@
5
5
 
6
6
  import { oob } from "@fluidframework/core-utils/internal";
7
7
 
8
- import type { MapGetSet } from "./utils.js";
8
+ import { getOrAddInMap, getOrCreate } from "./utils.js";
9
9
 
10
10
  /**
11
11
  * A dictionary whose values are keyed off of two objects (key1, key2).
@@ -87,40 +87,16 @@ export function setInNestedMap<Key1, Key2, Value>(
87
87
  }
88
88
 
89
89
  /**
90
- * Sets the value at `key` in map to value if not already present.
91
- * Returns the value at `key` after setting it.
92
- * This is equivalent to a get or default that adds the default to the map.
90
+ * {@link getOrCreate} for {@link NestedMap}.
93
91
  */
94
- export function getOrAddInMap<Key, Value>(
95
- map: MapGetSet<Key, Value>,
96
- key: Key,
97
- value: Value,
98
- ): Value {
99
- const currentValue = map.get(key);
100
- if (currentValue !== undefined) {
101
- return currentValue;
102
- }
103
- map.set(key, value);
104
- return value;
105
- }
106
-
107
- /**
108
- * Sets the value at `key` in `map` to `generateValue()` if not already present.
109
- * Returns the value at `key` after setting it.
110
- */
111
- export function getOrAddInMapLazy<Key, Value>(
112
- map: MapGetSet<Key, Value>,
113
- key: Key,
114
- generateValue: () => Value,
92
+ export function getOrCreateInNestedMap<Key1, Key2, Value>(
93
+ map: NestedMap<Key1, Key2, Value>,
94
+ key1: Key1,
95
+ key2: Key2,
96
+ defaultValue: (key1: Key1, key2: Key2) => Value,
115
97
  ): Value {
116
- const currentValue = map.get(key);
117
- if (currentValue !== undefined) {
118
- return currentValue;
119
- }
120
-
121
- const value = generateValue();
122
- map.set(key, value);
123
- return value;
98
+ const innerMap = getOrAddInMap(map, key1, new Map<Key2, Value>());
99
+ return getOrCreate(innerMap, key2, (): Value => defaultValue(key1, key2));
124
100
  }
125
101
 
126
102
  /**
package/src/util/utils.ts CHANGED
@@ -47,18 +47,8 @@ export function asMutable<T>(readonly: T): Mutable<T> {
47
47
 
48
48
  export const clone = structuredClone;
49
49
 
50
- /**
51
- * Throw an error with a constant message.
52
- * @remarks
53
- * Works like {@link @fluidframework/core-utils/internal#assert}.
54
- */
55
- export function fail(message: string | number): never {
56
- // Declaring this here aliased to a different name avoids the assert tagging objecting to the usages of `assert` below.
57
- // Since users of `fail` do the assert message tagging instead, suppressing tagging errors here makes sense.
58
- const assertNoTag: (condition: boolean, message: string | number) => asserts condition =
59
- assert;
60
- assertNoTag(false, message);
61
- }
50
+ // TODO: update usages of this to use @fluidframework/core-utils/internal directly.
51
+ export { fail } from "@fluidframework/core-utils/internal";
62
52
 
63
53
  /**
64
54
  * Checks whether or not the given object is a `readonly` array.
@@ -177,6 +167,24 @@ export function compareSets<T>({
177
167
  return true;
178
168
  }
179
169
 
170
+ /**
171
+ * Sets the value at `key` in map to value if not already present.
172
+ * Returns the value at `key` after setting it.
173
+ * This is equivalent to a get or default that adds the default to the map.
174
+ */
175
+ export function getOrAddInMap<Key, Value>(
176
+ map: MapGetSet<Key, Value>,
177
+ key: Key,
178
+ value: Value,
179
+ ): Value {
180
+ const currentValue = map.get(key);
181
+ if (currentValue !== undefined) {
182
+ return currentValue;
183
+ }
184
+ map.set(key, value);
185
+ return value;
186
+ }
187
+
180
188
  /**
181
189
  * Retrieve a value from a map with the given key, or create a new entry if the key is not in the map.
182
190
  * @param map - The map to query/update
@@ -616,3 +624,35 @@ export function copyPropertyIfDefined<
616
624
  }
617
625
  }
618
626
  }
627
+
628
+ /**
629
+ * Reduces an array of values into a single value.
630
+ * This is similar to `Array.prototype.reduce`,
631
+ * except that it recursively reduces the left and right halves of the input before reducing their respective reductions.
632
+ *
633
+ * When compared with an approach like reducing all the values left-to-right,
634
+ * this balanced approach is beneficial when the cost of invoking `callbackFn` is proportional to the number reduced values that its parameters collectively represent.
635
+ * For example, if `T` is an array, and `callbackFn` concatenates its inputs,
636
+ * then `balancedReduce` will have O(N*log(N)) time complexity instead of `Array.prototype.reduce`'s O(N²).
637
+ * However, if `callbackFn` is O(1) then both `balancedReduce` and `Array.prototype.reduce` will have O(N) complexity.
638
+ *
639
+ * @param array - The array to reduce.
640
+ * @param callbackFn - The function to execute for each pairwise reduction.
641
+ * @param emptyCase - A factory function that provides the value to return if the input array is empty.
642
+ */
643
+ export function balancedReduce<T>(
644
+ array: readonly T[],
645
+ callbackFn: (left: T, right: T) => T,
646
+ emptyCase: () => T,
647
+ ): T {
648
+ if (hasSingle(array)) {
649
+ return array[0];
650
+ }
651
+ if (!hasSome(array)) {
652
+ return emptyCase();
653
+ }
654
+ const mid = Math.floor(array.length / 2);
655
+ const left = balancedReduce(array.slice(0, mid), callbackFn, emptyCase);
656
+ const right = balancedReduce(array.slice(mid), callbackFn, emptyCase);
657
+ return callbackFn(left, right);
658
+ }