@fluidframework/tree 2.33.1 → 2.40.0-336023

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 (315) hide show
  1. package/.vscode/settings.json +2 -0
  2. package/api-report/tree.alpha.api.md +120 -50
  3. package/api-report/tree.beta.api.md +31 -27
  4. package/api-report/tree.legacy.alpha.api.md +24 -23
  5. package/api-report/tree.legacy.public.api.md +24 -23
  6. package/api-report/tree.public.api.md +24 -23
  7. package/dist/alpha.d.ts +16 -1
  8. package/dist/beta.d.ts +2 -0
  9. package/dist/index.d.ts +2 -2
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js.map +1 -1
  12. package/dist/internalTypes.d.ts +0 -1
  13. package/dist/internalTypes.d.ts.map +1 -1
  14. package/dist/internalTypes.js.map +1 -1
  15. package/dist/jsonDomainSchema.d.ts +2 -2
  16. package/dist/jsonDomainSchema.js +2 -2
  17. package/dist/jsonDomainSchema.js.map +1 -1
  18. package/dist/legacy.d.ts +2 -0
  19. package/dist/packageVersion.d.ts +1 -1
  20. package/dist/packageVersion.d.ts.map +1 -1
  21. package/dist/packageVersion.js +1 -1
  22. package/dist/packageVersion.js.map +1 -1
  23. package/dist/public.d.ts +2 -0
  24. package/dist/serializableDomainSchema.d.ts +3 -3
  25. package/dist/serializableDomainSchema.js +2 -2
  26. package/dist/serializableDomainSchema.js.map +1 -1
  27. package/dist/shared-tree/independentView.d.ts +1 -1
  28. package/dist/shared-tree/independentView.js.map +1 -1
  29. package/dist/shared-tree/index.d.ts +3 -2
  30. package/dist/shared-tree/index.d.ts.map +1 -1
  31. package/dist/shared-tree/index.js +4 -4
  32. package/dist/shared-tree/index.js.map +1 -1
  33. package/dist/shared-tree/schematizeTree.d.ts +4 -4
  34. package/dist/shared-tree/schematizeTree.d.ts.map +1 -1
  35. package/dist/shared-tree/schematizeTree.js +2 -3
  36. package/dist/shared-tree/schematizeTree.js.map +1 -1
  37. package/dist/shared-tree/schematizingTreeView.d.ts +3 -3
  38. package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
  39. package/dist/shared-tree/schematizingTreeView.js +4 -4
  40. package/dist/shared-tree/schematizingTreeView.js.map +1 -1
  41. package/dist/shared-tree/{treeApi.d.ts → tree.d.ts} +34 -34
  42. package/dist/shared-tree/tree.d.ts.map +1 -0
  43. package/dist/shared-tree/{treeApi.js → tree.js} +6 -6
  44. package/dist/shared-tree/tree.js.map +1 -0
  45. package/dist/shared-tree/{treeApiAlpha.d.ts → treeAlpha.d.ts} +22 -14
  46. package/dist/shared-tree/treeAlpha.d.ts.map +1 -0
  47. package/dist/shared-tree/{treeApiAlpha.js → treeAlpha.js} +4 -3
  48. package/dist/shared-tree/treeAlpha.js.map +1 -0
  49. package/dist/simple-tree/api/conciseTree.d.ts +1 -1
  50. package/dist/simple-tree/api/conciseTree.js.map +1 -1
  51. package/dist/simple-tree/api/configuration.d.ts +177 -0
  52. package/dist/simple-tree/api/configuration.d.ts.map +1 -0
  53. package/dist/simple-tree/api/configuration.js +163 -0
  54. package/dist/simple-tree/api/configuration.js.map +1 -0
  55. package/dist/simple-tree/api/getJsonSchema.js +2 -2
  56. package/dist/simple-tree/api/getJsonSchema.js.map +1 -1
  57. package/dist/simple-tree/api/index.d.ts +7 -4
  58. package/dist/simple-tree/api/index.d.ts.map +1 -1
  59. package/dist/simple-tree/api/index.js +8 -7
  60. package/dist/simple-tree/api/index.js.map +1 -1
  61. package/dist/simple-tree/api/{view.d.ts → schemaCompatibilityTester.d.ts} +8 -10
  62. package/dist/simple-tree/api/schemaCompatibilityTester.d.ts.map +1 -0
  63. package/dist/simple-tree/api/{view.js → schemaCompatibilityTester.js} +9 -9
  64. package/dist/simple-tree/api/schemaCompatibilityTester.js.map +1 -0
  65. package/dist/simple-tree/api/schemaFactory.d.ts +16 -10
  66. package/dist/simple-tree/api/schemaFactory.d.ts.map +1 -1
  67. package/dist/simple-tree/api/schemaFactory.js +20 -12
  68. package/dist/simple-tree/api/schemaFactory.js.map +1 -1
  69. package/dist/simple-tree/api/schemaFactoryAlpha.d.ts +12 -6
  70. package/dist/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -1
  71. package/dist/simple-tree/api/schemaFactoryAlpha.js +2 -2
  72. package/dist/simple-tree/api/schemaFactoryAlpha.js.map +1 -1
  73. package/dist/simple-tree/api/schemaFactoryRecursive.d.ts +67 -4
  74. package/dist/simple-tree/api/schemaFactoryRecursive.d.ts.map +1 -1
  75. package/dist/simple-tree/api/schemaFactoryRecursive.js.map +1 -1
  76. package/dist/simple-tree/api/schemaFromSimple.d.ts +1 -1
  77. package/dist/simple-tree/api/schemaFromSimple.d.ts.map +1 -1
  78. package/dist/simple-tree/api/schemaFromSimple.js +1 -1
  79. package/dist/simple-tree/api/schemaFromSimple.js.map +1 -1
  80. package/dist/simple-tree/api/simpleSchemaToJsonSchema.d.ts +1 -1
  81. package/dist/simple-tree/api/simpleSchemaToJsonSchema.d.ts.map +1 -1
  82. package/dist/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
  83. package/dist/simple-tree/api/storedSchema.d.ts +3 -3
  84. package/dist/simple-tree/api/storedSchema.d.ts.map +1 -1
  85. package/dist/simple-tree/api/storedSchema.js +3 -2
  86. package/dist/simple-tree/api/storedSchema.js.map +1 -1
  87. package/dist/simple-tree/api/tree.d.ts +5 -174
  88. package/dist/simple-tree/api/tree.d.ts.map +1 -1
  89. package/dist/simple-tree/api/tree.js +1 -156
  90. package/dist/simple-tree/api/tree.js.map +1 -1
  91. package/{lib/simple-tree/api/treeApiBeta.d.ts → dist/simple-tree/api/treeBeta.d.ts} +13 -5
  92. package/dist/simple-tree/api/treeBeta.d.ts.map +1 -0
  93. package/dist/simple-tree/api/{treeApiBeta.js → treeBeta.js} +5 -4
  94. package/dist/simple-tree/api/treeBeta.js.map +1 -0
  95. package/dist/simple-tree/api/typesUnsafe.d.ts +4 -9
  96. package/dist/simple-tree/api/typesUnsafe.d.ts.map +1 -1
  97. package/dist/simple-tree/api/typesUnsafe.js.map +1 -1
  98. package/dist/simple-tree/arrayNode.d.ts +2 -2
  99. package/dist/simple-tree/arrayNode.d.ts.map +1 -1
  100. package/dist/simple-tree/arrayNode.js +3 -2
  101. package/dist/simple-tree/arrayNode.js.map +1 -1
  102. package/dist/simple-tree/arrayNodeTypes.d.ts +3 -3
  103. package/dist/simple-tree/arrayNodeTypes.d.ts.map +1 -1
  104. package/dist/simple-tree/arrayNodeTypes.js.map +1 -1
  105. package/dist/simple-tree/index.d.ts +3 -3
  106. package/dist/simple-tree/index.d.ts.map +1 -1
  107. package/dist/simple-tree/index.js +2 -2
  108. package/dist/simple-tree/index.js.map +1 -1
  109. package/dist/simple-tree/mapNode.d.ts +2 -2
  110. package/dist/simple-tree/mapNode.d.ts.map +1 -1
  111. package/dist/simple-tree/mapNode.js +1 -1
  112. package/dist/simple-tree/mapNode.js.map +1 -1
  113. package/dist/simple-tree/mapNodeTypes.d.ts +3 -3
  114. package/dist/simple-tree/mapNodeTypes.d.ts.map +1 -1
  115. package/dist/simple-tree/mapNodeTypes.js.map +1 -1
  116. package/dist/simple-tree/objectNode.d.ts +18 -5
  117. package/dist/simple-tree/objectNode.d.ts.map +1 -1
  118. package/dist/simple-tree/objectNode.js +4 -3
  119. package/dist/simple-tree/objectNode.js.map +1 -1
  120. package/dist/simple-tree/objectNodeTypes.d.ts +4 -4
  121. package/dist/simple-tree/objectNodeTypes.d.ts.map +1 -1
  122. package/dist/simple-tree/objectNodeTypes.js.map +1 -1
  123. package/dist/simple-tree/schemaTypes.d.ts +163 -13
  124. package/dist/simple-tree/schemaTypes.d.ts.map +1 -1
  125. package/dist/simple-tree/schemaTypes.js +107 -8
  126. package/dist/simple-tree/schemaTypes.js.map +1 -1
  127. package/dist/simple-tree/treeNodeValid.js +2 -2
  128. package/dist/simple-tree/treeNodeValid.js.map +1 -1
  129. package/dist/tableSchema.d.ts +197 -86
  130. package/dist/tableSchema.d.ts.map +1 -1
  131. package/dist/tableSchema.js +100 -45
  132. package/dist/tableSchema.js.map +1 -1
  133. package/dist/util/typeUtils.d.ts +1 -1
  134. package/dist/util/typeUtils.js.map +1 -1
  135. package/lib/alpha.d.ts +16 -1
  136. package/lib/beta.d.ts +2 -0
  137. package/lib/index.d.ts +2 -2
  138. package/lib/index.d.ts.map +1 -1
  139. package/lib/index.js.map +1 -1
  140. package/lib/internalTypes.d.ts +0 -1
  141. package/lib/internalTypes.d.ts.map +1 -1
  142. package/lib/internalTypes.js.map +1 -1
  143. package/lib/jsonDomainSchema.d.ts +2 -2
  144. package/lib/jsonDomainSchema.js +2 -2
  145. package/lib/jsonDomainSchema.js.map +1 -1
  146. package/lib/legacy.d.ts +2 -0
  147. package/lib/packageVersion.d.ts +1 -1
  148. package/lib/packageVersion.d.ts.map +1 -1
  149. package/lib/packageVersion.js +1 -1
  150. package/lib/packageVersion.js.map +1 -1
  151. package/lib/public.d.ts +2 -0
  152. package/lib/serializableDomainSchema.d.ts +3 -3
  153. package/lib/serializableDomainSchema.js +2 -2
  154. package/lib/serializableDomainSchema.js.map +1 -1
  155. package/lib/shared-tree/independentView.d.ts +1 -1
  156. package/lib/shared-tree/independentView.js.map +1 -1
  157. package/lib/shared-tree/index.d.ts +3 -2
  158. package/lib/shared-tree/index.d.ts.map +1 -1
  159. package/lib/shared-tree/index.js +2 -2
  160. package/lib/shared-tree/index.js.map +1 -1
  161. package/lib/shared-tree/schematizeTree.d.ts +4 -4
  162. package/lib/shared-tree/schematizeTree.d.ts.map +1 -1
  163. package/lib/shared-tree/schematizeTree.js +2 -3
  164. package/lib/shared-tree/schematizeTree.js.map +1 -1
  165. package/lib/shared-tree/schematizingTreeView.d.ts +3 -3
  166. package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
  167. package/lib/shared-tree/schematizingTreeView.js +5 -5
  168. package/lib/shared-tree/schematizingTreeView.js.map +1 -1
  169. package/lib/shared-tree/{treeApi.d.ts → tree.d.ts} +34 -34
  170. package/lib/shared-tree/tree.d.ts.map +1 -0
  171. package/lib/shared-tree/{treeApi.js → tree.js} +5 -5
  172. package/lib/shared-tree/tree.js.map +1 -0
  173. package/lib/shared-tree/{treeApiAlpha.d.ts → treeAlpha.d.ts} +22 -14
  174. package/lib/shared-tree/treeAlpha.d.ts.map +1 -0
  175. package/lib/shared-tree/{treeApiAlpha.js → treeAlpha.js} +4 -3
  176. package/lib/shared-tree/treeAlpha.js.map +1 -0
  177. package/lib/simple-tree/api/conciseTree.d.ts +1 -1
  178. package/lib/simple-tree/api/conciseTree.js.map +1 -1
  179. package/lib/simple-tree/api/configuration.d.ts +177 -0
  180. package/lib/simple-tree/api/configuration.d.ts.map +1 -0
  181. package/lib/simple-tree/api/configuration.js +157 -0
  182. package/lib/simple-tree/api/configuration.js.map +1 -0
  183. package/lib/simple-tree/api/getJsonSchema.js +1 -1
  184. package/lib/simple-tree/api/getJsonSchema.js.map +1 -1
  185. package/lib/simple-tree/api/index.d.ts +7 -4
  186. package/lib/simple-tree/api/index.d.ts.map +1 -1
  187. package/lib/simple-tree/api/index.js +4 -3
  188. package/lib/simple-tree/api/index.js.map +1 -1
  189. package/lib/simple-tree/api/{view.d.ts → schemaCompatibilityTester.d.ts} +8 -10
  190. package/lib/simple-tree/api/schemaCompatibilityTester.d.ts.map +1 -0
  191. package/lib/simple-tree/api/{view.js → schemaCompatibilityTester.js} +7 -7
  192. package/lib/simple-tree/api/schemaCompatibilityTester.js.map +1 -0
  193. package/lib/simple-tree/api/schemaFactory.d.ts +16 -10
  194. package/lib/simple-tree/api/schemaFactory.d.ts.map +1 -1
  195. package/lib/simple-tree/api/schemaFactory.js +20 -12
  196. package/lib/simple-tree/api/schemaFactory.js.map +1 -1
  197. package/lib/simple-tree/api/schemaFactoryAlpha.d.ts +12 -6
  198. package/lib/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -1
  199. package/lib/simple-tree/api/schemaFactoryAlpha.js +2 -2
  200. package/lib/simple-tree/api/schemaFactoryAlpha.js.map +1 -1
  201. package/lib/simple-tree/api/schemaFactoryRecursive.d.ts +67 -4
  202. package/lib/simple-tree/api/schemaFactoryRecursive.d.ts.map +1 -1
  203. package/lib/simple-tree/api/schemaFactoryRecursive.js.map +1 -1
  204. package/lib/simple-tree/api/schemaFromSimple.d.ts +1 -1
  205. package/lib/simple-tree/api/schemaFromSimple.d.ts.map +1 -1
  206. package/lib/simple-tree/api/schemaFromSimple.js +1 -1
  207. package/lib/simple-tree/api/schemaFromSimple.js.map +1 -1
  208. package/lib/simple-tree/api/simpleSchemaToJsonSchema.d.ts +1 -1
  209. package/lib/simple-tree/api/simpleSchemaToJsonSchema.d.ts.map +1 -1
  210. package/lib/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
  211. package/lib/simple-tree/api/storedSchema.d.ts +3 -3
  212. package/lib/simple-tree/api/storedSchema.d.ts.map +1 -1
  213. package/lib/simple-tree/api/storedSchema.js +3 -2
  214. package/lib/simple-tree/api/storedSchema.js.map +1 -1
  215. package/lib/simple-tree/api/tree.d.ts +5 -174
  216. package/lib/simple-tree/api/tree.d.ts.map +1 -1
  217. package/lib/simple-tree/api/tree.js +0 -152
  218. package/lib/simple-tree/api/tree.js.map +1 -1
  219. package/{dist/simple-tree/api/treeApiBeta.d.ts → lib/simple-tree/api/treeBeta.d.ts} +13 -5
  220. package/lib/simple-tree/api/treeBeta.d.ts.map +1 -0
  221. package/lib/simple-tree/api/{treeApiBeta.js → treeBeta.js} +5 -4
  222. package/lib/simple-tree/api/treeBeta.js.map +1 -0
  223. package/lib/simple-tree/api/typesUnsafe.d.ts +4 -9
  224. package/lib/simple-tree/api/typesUnsafe.d.ts.map +1 -1
  225. package/lib/simple-tree/api/typesUnsafe.js.map +1 -1
  226. package/lib/simple-tree/arrayNode.d.ts +2 -2
  227. package/lib/simple-tree/arrayNode.d.ts.map +1 -1
  228. package/lib/simple-tree/arrayNode.js +4 -3
  229. package/lib/simple-tree/arrayNode.js.map +1 -1
  230. package/lib/simple-tree/arrayNodeTypes.d.ts +3 -3
  231. package/lib/simple-tree/arrayNodeTypes.d.ts.map +1 -1
  232. package/lib/simple-tree/arrayNodeTypes.js.map +1 -1
  233. package/lib/simple-tree/index.d.ts +3 -3
  234. package/lib/simple-tree/index.d.ts.map +1 -1
  235. package/lib/simple-tree/index.js +1 -1
  236. package/lib/simple-tree/index.js.map +1 -1
  237. package/lib/simple-tree/mapNode.d.ts +2 -2
  238. package/lib/simple-tree/mapNode.d.ts.map +1 -1
  239. package/lib/simple-tree/mapNode.js +2 -2
  240. package/lib/simple-tree/mapNode.js.map +1 -1
  241. package/lib/simple-tree/mapNodeTypes.d.ts +3 -3
  242. package/lib/simple-tree/mapNodeTypes.d.ts.map +1 -1
  243. package/lib/simple-tree/mapNodeTypes.js.map +1 -1
  244. package/lib/simple-tree/objectNode.d.ts +18 -5
  245. package/lib/simple-tree/objectNode.d.ts.map +1 -1
  246. package/lib/simple-tree/objectNode.js +5 -4
  247. package/lib/simple-tree/objectNode.js.map +1 -1
  248. package/lib/simple-tree/objectNodeTypes.d.ts +4 -4
  249. package/lib/simple-tree/objectNodeTypes.d.ts.map +1 -1
  250. package/lib/simple-tree/objectNodeTypes.js.map +1 -1
  251. package/lib/simple-tree/schemaTypes.d.ts +163 -13
  252. package/lib/simple-tree/schemaTypes.d.ts.map +1 -1
  253. package/lib/simple-tree/schemaTypes.js +96 -8
  254. package/lib/simple-tree/schemaTypes.js.map +1 -1
  255. package/lib/simple-tree/treeNodeValid.js +2 -2
  256. package/lib/simple-tree/treeNodeValid.js.map +1 -1
  257. package/lib/tableSchema.d.ts +197 -86
  258. package/lib/tableSchema.d.ts.map +1 -1
  259. package/lib/tableSchema.js +100 -45
  260. package/lib/tableSchema.js.map +1 -1
  261. package/lib/util/typeUtils.d.ts +1 -1
  262. package/lib/util/typeUtils.js.map +1 -1
  263. package/package.json +20 -20
  264. package/src/index.ts +17 -1
  265. package/src/internalTypes.ts +0 -2
  266. package/src/jsonDomainSchema.ts +2 -2
  267. package/src/packageVersion.ts +1 -1
  268. package/src/serializableDomainSchema.ts +3 -3
  269. package/src/shared-tree/independentView.ts +1 -1
  270. package/src/shared-tree/index.ts +3 -6
  271. package/src/shared-tree/schematizeTree.ts +5 -5
  272. package/src/shared-tree/schematizingTreeView.ts +11 -8
  273. package/src/shared-tree/{treeApi.ts → tree.ts} +51 -51
  274. package/src/shared-tree/{treeApiAlpha.ts → treeAlpha.ts} +22 -13
  275. package/src/simple-tree/api/conciseTree.ts +1 -1
  276. package/src/simple-tree/api/configuration.ts +353 -0
  277. package/src/simple-tree/api/getJsonSchema.ts +1 -1
  278. package/src/simple-tree/api/index.ts +21 -15
  279. package/src/simple-tree/api/{view.ts → schemaCompatibilityTester.ts} +8 -15
  280. package/src/simple-tree/api/schemaFactory.ts +130 -19
  281. package/src/simple-tree/api/schemaFactoryAlpha.ts +7 -5
  282. package/src/simple-tree/api/schemaFactoryRecursive.ts +102 -38
  283. package/src/simple-tree/api/schemaFromSimple.ts +2 -2
  284. package/src/simple-tree/api/simpleSchemaToJsonSchema.ts +1 -1
  285. package/src/simple-tree/api/storedSchema.ts +8 -4
  286. package/src/simple-tree/api/tree.ts +13 -354
  287. package/src/simple-tree/api/{treeApiBeta.ts → treeBeta.ts} +17 -5
  288. package/src/simple-tree/api/typesUnsafe.ts +15 -11
  289. package/src/simple-tree/arrayNode.ts +10 -5
  290. package/src/simple-tree/arrayNodeTypes.ts +8 -7
  291. package/src/simple-tree/index.ts +17 -1
  292. package/src/simple-tree/mapNode.ts +11 -3
  293. package/src/simple-tree/mapNodeTypes.ts +10 -7
  294. package/src/simple-tree/objectNode.ts +39 -15
  295. package/src/simple-tree/objectNodeTypes.ts +9 -5
  296. package/src/simple-tree/schemaTypes.ts +353 -25
  297. package/src/simple-tree/treeNodeValid.ts +2 -2
  298. package/src/tableSchema.ts +749 -445
  299. package/src/util/typeUtils.ts +1 -1
  300. package/dist/shared-tree/treeApi.d.ts.map +0 -1
  301. package/dist/shared-tree/treeApi.js.map +0 -1
  302. package/dist/shared-tree/treeApiAlpha.d.ts.map +0 -1
  303. package/dist/shared-tree/treeApiAlpha.js.map +0 -1
  304. package/dist/simple-tree/api/treeApiBeta.d.ts.map +0 -1
  305. package/dist/simple-tree/api/treeApiBeta.js.map +0 -1
  306. package/dist/simple-tree/api/view.d.ts.map +0 -1
  307. package/dist/simple-tree/api/view.js.map +0 -1
  308. package/lib/shared-tree/treeApi.d.ts.map +0 -1
  309. package/lib/shared-tree/treeApi.js.map +0 -1
  310. package/lib/shared-tree/treeApiAlpha.d.ts.map +0 -1
  311. package/lib/shared-tree/treeApiAlpha.js.map +0 -1
  312. package/lib/simple-tree/api/treeApiBeta.d.ts.map +0 -1
  313. package/lib/simple-tree/api/treeApiBeta.js.map +0 -1
  314. package/lib/simple-tree/api/view.d.ts.map +0 -1
  315. package/lib/simple-tree/api/view.js.map +0 -1
@@ -7,6 +7,7 @@ import { oob } from "@fluidframework/core-utils/internal";
7
7
 
8
8
  import { Tree } from "./shared-tree/index.js";
9
9
  import {
10
+ type FieldHasDefault,
10
11
  type ImplicitAllowedTypes,
11
12
  type ImplicitFieldSchema,
12
13
  type InsertableObjectFromSchemaRecord,
@@ -20,83 +21,176 @@ import {
20
21
  type TreeNodeSchema,
21
22
  type TreeNodeSchemaClass,
22
23
  type WithType,
24
+ type TreeFieldFromImplicitField,
25
+ type InsertableTreeFieldFromImplicitField,
26
+ type InternalTreeNode,
27
+ type FieldSchema,
28
+ type FieldKind,
29
+ SchemaFactory,
30
+ type ImplicitAnnotatedFieldSchema,
31
+ type UnannotateImplicitFieldSchema,
23
32
  } from "./simple-tree/index.js";
24
33
 
25
34
  // Future improvement TODOs (ideally to be done before promoting these APIs to `@alpha`):
26
- // - Custom fields on Table/Row/Column (props pattern from Nick's demo)
27
- // - Overloads to make Column/Row schema optional when constructing Tables
28
35
  // - Record-like type parameters / input parameters?
29
- // - Move `@system` types into separate / sub scope?
36
+ // - Omit `props` properties from Row and Column schemas when not provided?
37
+
38
+ const tableSchemaFactorySubScope = "table";
30
39
 
31
40
  /**
32
- * Contains types and factories for creating schema to represent dynamic tabular data.
33
- * @privateRemarks TODO: document in more detail and add `@example`s.
34
- * @internal
41
+ * Not intended for use outside of this package.
42
+ *
43
+ * @privateRemarks
44
+ * This namespace is a collection of internal system types relate to {@link TableSchema}.
45
+ * This namespace should be strictly type-exported by the package.
46
+ * All members should be tagged with `@system`.
47
+ *
48
+ * @system @internal
35
49
  */
36
- export namespace TableSchema {
37
- const tableSchemaFactorySubScope = "table";
38
-
39
- // #region Column
40
-
50
+ export namespace System_TableSchema {
41
51
  /**
42
- * A column in a table.
43
- * @remarks Implemented by the schema class returned from {@link TableSchema.createColumn}.
44
- * @sealed @internal
52
+ * A base interface for factory input options which include an schema factory.
53
+ * @remarks This interface should not be referenced directly.
54
+ * @privateRemarks This interface primarily exists to provide a single home for property documentation.
55
+ * @system @internal
45
56
  */
46
- export interface IColumn<TPropsSchema extends ImplicitAllowedTypes = ImplicitAllowedTypes> {
57
+ export interface OptionsWithSchemaFactory<
58
+ TScope extends string | undefined = string | undefined,
59
+ > {
47
60
  /**
48
- * The unique identifier of the column.
49
- * @remarks Uniquely identifies the node within the entire tree, not just the table.
61
+ * Schema factory with which the Column schema will be associated.
62
+ * @remarks Can be used to associate the resulting schema with an existing {@link SchemaFactory.scope|scope}.
50
63
  */
51
- readonly id: string;
64
+ readonly schemaFactory: SchemaFactoryAlpha<TScope>;
65
+ }
52
66
 
67
+ /**
68
+ * A base interface for factory input options which include the table cell schema.
69
+ * @remarks This interface should not be referenced directly.
70
+ * @privateRemarks This interface primarily exists to provide a single home for property documentation.
71
+ * @system @internal
72
+ */
73
+ export interface OptionsWithCellSchema<
74
+ TCellSchema extends ImplicitAllowedTypes = ImplicitAllowedTypes,
75
+ > {
53
76
  /**
54
- * User-provided column properties.
77
+ * Schema for the table's cells.
55
78
  */
56
- get props(): TreeNodeFromImplicitAllowedTypes<TPropsSchema>;
57
- set props(value: InsertableTreeNodeFromImplicitAllowedTypes<TPropsSchema>);
79
+ readonly cell: TCellSchema;
58
80
  }
59
81
 
82
+ // #region Column
83
+
84
+ /**
85
+ * Base options for creating table cow schema.
86
+ * @remarks Includes parameters common to all column factory overloads.
87
+ * @system @internal
88
+ */
89
+ export type CreateColumnOptionsBase<
90
+ TInputScope extends string | undefined = string | undefined,
91
+ > = OptionsWithSchemaFactory<TInputScope>;
92
+
60
93
  /**
61
94
  * Factory for creating new table column schema.
62
- * @privateRemarks
63
- * TODO:
64
- * - Add overloads to make propsSchema optional.
65
- * - Take field schema rather than node schema for `propsSchema`, in particular to allow making
66
- * the additional properties optional.
67
- * @internal
95
+ * @system @internal
68
96
  */
69
97
  // eslint-disable-next-line @typescript-eslint/explicit-function-return-type -- Return type is too complex to be reasonable to specify
70
- export function createColumn<
98
+ export function createColumnInternal<
71
99
  const TInputScope extends string | undefined,
72
- const TPropsSchema extends ImplicitAllowedTypes,
100
+ const TPropsSchema extends ImplicitAnnotatedFieldSchema,
73
101
  >(inputSchemaFactory: SchemaFactoryAlpha<TInputScope>, propsSchema: TPropsSchema) {
74
102
  const schemaFactory = inputSchemaFactory.scopedFactory(tableSchemaFactorySubScope);
75
103
  type Scope = ScopedSchemaName<TInputScope, typeof tableSchemaFactorySubScope>;
76
104
 
105
+ // Note: `columnFields` is broken into two parts to work around a TypeScript bug
106
+ // that results in broken `.d.ts` output.
107
+ // See definition of `ColumnInsertableType` below.
108
+ const columnFieldsBuiltInParts = {
109
+ id: schemaFactory.identifier,
110
+ } as const;
111
+ const columnFieldsPropsPart = {
112
+ props: propsSchema,
113
+ } as const;
114
+
77
115
  /**
78
116
  * {@link Column} fields.
79
- * @remarks Extracted for re-use in returned type signature defined later in this function.
117
+ *
118
+ * @remarks
119
+ * Extracted for re-use in returned type signature defined later in this function.
80
120
  * The implicit typing is intentional.
121
+ *
81
122
  * Note: ideally we would add a satisfies clause here to ensure that this satisfies
82
123
  * `Record<string, ImplicitFieldSchema>`, but doing so causes TypeScript to prematurely and incorrectly evaluate the type of `propsSchema`.
83
124
  * Likely related to the following issue: https://github.com/microsoft/TypeScript/issues/52394
84
125
  */
85
126
  const columnFields = {
86
- id: schemaFactory.identifier,
87
- props: schemaFactory.required(propsSchema),
88
- } as const;
127
+ ...columnFieldsBuiltInParts,
128
+ ...columnFieldsPropsPart,
129
+ } as const; // satisfies Record<string, ImplicitFieldSchema>;
89
130
 
90
131
  /**
91
132
  * A column in a table.
92
133
  */
93
- class Column extends schemaFactory.object("Column", columnFields) {}
134
+ class Column
135
+ extends schemaFactory.objectAlpha("Column", columnFields, {
136
+ // Will make it easier to evolve this schema in the future.
137
+ allowUnknownOptionalFields: true,
138
+ })
139
+ implements TableSchema.IColumn<TPropsSchema> {}
94
140
 
95
141
  type ColumnValueType = TreeNode &
96
- IColumn<TPropsSchema> &
142
+ TableSchema.IColumn<TPropsSchema> &
97
143
  WithType<ScopedSchemaName<Scope, "Column">>;
98
144
 
99
- type ColumnInsertableType = InsertableObjectFromSchemaRecord<typeof columnFields>;
145
+ // Note: ideally this type would just leverage `InsertableObjectFromSchemaRecord<typeof columnFields>`,
146
+ // but that results in broken `.d.ts` output due to a TypeScript bug.
147
+ // See: https://github.com/microsoft/TypeScript/issues/58688.
148
+ // Instead we extract and inline the typing of the "props" field here, which seems to sufficiently work around the issue.
149
+ // type ColumnInsertableType = InsertableObjectFromSchemaRecord<typeof columnFields>;
150
+ type ColumnInsertableType = InsertableObjectFromSchemaRecord<
151
+ typeof columnFieldsBuiltInParts
152
+ > &
153
+ (FieldHasDefault<UnannotateImplicitFieldSchema<TPropsSchema>> extends true
154
+ ? // Note: The docs on the below properties are copied from `IRow.props`' docs to ensure that the
155
+ // documentation appears in the data insertion scenario.
156
+ // The contents are duplicated instead of using `@inheritdoc`, as intellisense does not correctly
157
+ // support `@inheritDoc`.
158
+ // See: https://github.com/microsoft/TypeScript/issues/31267
159
+ {
160
+ /**
161
+ * The column's properties.
162
+ * @remarks This is a user-defined schema that can be used to store additional information about the column.
163
+ */
164
+ props?: InsertableTreeFieldFromImplicitField<
165
+ UnannotateImplicitFieldSchema<TPropsSchema>
166
+ >;
167
+ }
168
+ : {
169
+ /**
170
+ * The column's properties.
171
+ * @remarks This is a user-defined schema that can be used to store additional information about the column.
172
+ */
173
+ props: InsertableTreeFieldFromImplicitField<
174
+ UnannotateImplicitFieldSchema<TPropsSchema>
175
+ >;
176
+ });
177
+
178
+ // Modified version of `Column` that ensures the constructor (and `createFromInsertable`) are
179
+ // typed correctly in terms of our insertable type.
180
+ // This lets us be selective in our type-cast for the value returned from this function,
181
+ // preserving as much type-safety as we reasonably can.
182
+ type ColumnSchemaModifiedType = Omit<
183
+ // Use mapped type to omit the constructor
184
+ {
185
+ [Property in keyof typeof Column]: (typeof Column)[Property];
186
+ },
187
+ "createFromInsertable"
188
+ > &
189
+ (new (
190
+ parameters: InternalTreeNode | ColumnInsertableType,
191
+ ) => Column) & {
192
+ createFromInsertable(parameters: ColumnInsertableType): Column;
193
+ };
100
194
 
101
195
  // Returning SingletonSchema without a type conversion results in TypeScript generating something like `readonly "__#124291@#brand": unknown;`
102
196
  // for the private brand field of TreeNode.
@@ -110,7 +204,7 @@ export namespace TableSchema {
110
204
  /* TInsertable */ object & ColumnInsertableType,
111
205
  /* ImplicitlyConstructable */ true,
112
206
  /* Info */ typeof columnFields
113
- > = Column;
207
+ > = Column as ColumnSchemaModifiedType;
114
208
 
115
209
  return ColumnSchemaType;
116
210
  }
@@ -120,91 +214,34 @@ export namespace TableSchema {
120
214
  * @sealed @system @internal
121
215
  */
122
216
  export type ColumnSchemaBase<
123
- TScope extends string | undefined,
124
- TPropsSchema extends ImplicitAllowedTypes,
125
- > = ReturnType<typeof createColumn<TScope, TPropsSchema>>;
217
+ TScope extends string | undefined = string | undefined,
218
+ TPropsSchema extends ImplicitFieldSchema = ImplicitFieldSchema,
219
+ > = ReturnType<typeof TableSchema.createColumn<TScope, TPropsSchema>>;
126
220
 
127
221
  // #endregion
128
222
 
129
223
  // #region Row
130
224
 
131
225
  /**
132
- * A row in a table.
133
- * @remarks Implemented by the schema class returned from {@link TableSchema.createRow}.
134
- * @sealed @internal
226
+ * Base options for creating table row schema.
227
+ * @remarks Includes parameters common to all row factory overloads.
228
+ * @system @internal
135
229
  */
136
- export interface IRow<
137
- TCellSchema extends ImplicitAllowedTypes,
138
- TPropsSchema extends ImplicitAllowedTypes = ImplicitAllowedTypes,
139
- > {
140
- /**
141
- * The unique identifier of the row.
142
- * @remarks Uniquely identifies the node within the entire tree, not just the table.
143
- */
144
- readonly id: string;
145
-
146
- /**
147
- * Gets the cell in the specified column.
148
- * @returns The cell if it exists, otherwise undefined.
149
- */
150
- getCell(column: IColumn): TreeNodeFromImplicitAllowedTypes<TCellSchema> | undefined;
151
- /**
152
- * Gets the cell in the specified column, denoted by column ID.
153
- * @returns The cell if it exists, otherwise undefined.
154
- */
155
- getCell(columnId: string): TreeNodeFromImplicitAllowedTypes<TCellSchema> | undefined;
156
-
157
- /**
158
- * Sets the cell in the specified column.
159
- * @remarks To remove a cell, call {@link TableSchema.IRow.(removeCell:1)} instead.
160
- */
161
- setCell(
162
- column: IColumn,
163
- value: InsertableTreeNodeFromImplicitAllowedTypes<TCellSchema>,
164
- ): void;
165
- /**
166
- * Sets the cell in the specified column, denoted by column ID.
167
- * @remarks To remove a cell, call {@link TableSchema.IRow.(removeCell:2)} instead.
168
- */
169
- setCell(
170
- columnId: string,
171
- value: InsertableTreeNodeFromImplicitAllowedTypes<TCellSchema>,
172
- ): void;
173
-
174
- /**
175
- * Removes the cell in the specified column.
176
- * @privateRemarks TODO: return removed cell
177
- */
178
- removeCell(column: IColumn): void;
179
- /**
180
- * Removes the cell in the specified column, denoted by column ID.
181
- * @privateRemarks TODO: return removed cell
182
- */
183
- removeCell(columnId: string): void;
184
-
185
- /**
186
- * User-provided row properties.
187
- */
188
- get props(): TreeNodeFromImplicitAllowedTypes<TPropsSchema>;
189
- set props(value: InsertableTreeNodeFromImplicitAllowedTypes<TPropsSchema>);
190
- }
230
+ export type CreateRowOptionsBase<
231
+ TScope extends string | undefined = string | undefined,
232
+ TCell extends ImplicitAllowedTypes = ImplicitAllowedTypes,
233
+ > = OptionsWithSchemaFactory<TScope> & OptionsWithCellSchema<TCell>;
191
234
 
192
235
  /**
193
236
  * Factory for creating new table row schema.
194
237
  *
195
- * @privateRemarks
196
- * TODO:
197
- * - Add overloads to make propsSchema optional.
198
- * - Take field schema rather than node schema for `propsSchema`, in particular to allow making
199
- * the additional properties optional.
200
- *
201
238
  * @sealed @internal
202
239
  */
203
240
  // eslint-disable-next-line @typescript-eslint/explicit-function-return-type -- Return type is too complex to be reasonable to specify
204
- export function createRow<
241
+ export function createRowInternal<
205
242
  const TInputScope extends string | undefined,
206
243
  const TCellSchema extends ImplicitAllowedTypes,
207
- const TPropsSchema extends ImplicitAllowedTypes,
244
+ const TPropsSchema extends ImplicitFieldSchema,
208
245
  >(
209
246
  inputSchemaFactory: SchemaFactoryAlpha<TInputScope>,
210
247
  cellSchema: TCellSchema,
@@ -216,6 +253,21 @@ export namespace TableSchema {
216
253
  type CellValueType = TreeNodeFromImplicitAllowedTypes<TCellSchema>;
217
254
  type CellInsertableType = InsertableTreeNodeFromImplicitAllowedTypes<TCellSchema>;
218
255
 
256
+ // Note: `rowFields` is broken into two parts to work around a TypeScript bug
257
+ // that results in broken `.d.ts` output.
258
+ // See definition of `RowInsertableType` below.
259
+ const rowFieldsBuiltInParts = {
260
+ id: schemaFactory.identifier,
261
+ cells: schemaFactory.required(schemaFactory.map("Row.cells", cellSchema), {
262
+ metadata: {
263
+ description: "The cells of the table row, keyed by column ID.",
264
+ },
265
+ }),
266
+ } as const;
267
+ const rowFieldsPropsPart = {
268
+ props: propsSchema,
269
+ } as const;
270
+
219
271
  /**
220
272
  * {@link Row} fields.
221
273
  * @remarks Extracted for re-use in returned type signature defined later in this function.
@@ -225,32 +277,34 @@ export namespace TableSchema {
225
277
  * Likely related to the following issue: https://github.com/microsoft/TypeScript/issues/52394
226
278
  */
227
279
  const rowFields = {
228
- id: schemaFactory.identifier,
229
- cells: schemaFactory.map("Row.cells", cellSchema),
230
- props: schemaFactory.required(propsSchema),
231
- } as const;
280
+ ...rowFieldsBuiltInParts,
281
+ ...rowFieldsPropsPart,
282
+ } as const; // satisfies Record<string, ImplicitFieldSchema>;
232
283
 
233
284
  /**
234
285
  * The Row schema - this is a map of Cells where the key is the column id
235
286
  */
236
287
  class Row
237
- extends schemaFactory.object("Row", rowFields)
238
- implements IRow<TCellSchema, TPropsSchema>
288
+ extends schemaFactory.objectAlpha("Row", rowFields, {
289
+ // Will make it easier to evolve this schema in the future.
290
+ allowUnknownOptionalFields: true,
291
+ })
292
+ implements TableSchema.IRow<TCellSchema, TPropsSchema>
239
293
  {
240
- public getCell(columnOrId: IColumn | string): CellValueType | undefined {
294
+ public getCell(columnOrId: TableSchema.IColumn | string): CellValueType | undefined {
241
295
  const columnId = typeof columnOrId === "string" ? columnOrId : columnOrId.id;
242
296
  return this.cells.get(columnId) as CellValueType | undefined;
243
297
  }
244
298
 
245
299
  public setCell(
246
- columnOrId: IColumn | string,
300
+ columnOrId: TableSchema.IColumn | string,
247
301
  value: CellInsertableType | undefined,
248
302
  ): void {
249
303
  const columnId = typeof columnOrId === "string" ? columnOrId : columnOrId.id;
250
304
  this.cells.set(columnId, value);
251
305
  }
252
306
 
253
- public removeCell(columnOrId: IColumn | string): void {
307
+ public removeCell(columnOrId: TableSchema.IColumn | string): void {
254
308
  const columnId = typeof columnOrId === "string" ? columnOrId : columnOrId.id;
255
309
  if (!this.cells.has(columnId)) {
256
310
  return;
@@ -260,9 +314,55 @@ export namespace TableSchema {
260
314
  }
261
315
 
262
316
  type RowValueType = TreeNode &
263
- IRow<TCellSchema, TPropsSchema> &
317
+ TableSchema.IRow<TCellSchema, TPropsSchema> &
264
318
  WithType<ScopedSchemaName<Scope, "Row">>;
265
- type RowInsertableType = InsertableObjectFromSchemaRecord<typeof rowFields>;
319
+
320
+ // Note: ideally this type would just leverage `InsertableObjectFromSchemaRecord<typeof rowFields>`,
321
+ // but that results in broken `.d.ts` output due to a TypeScript bug.
322
+ // See: https://github.com/microsoft/TypeScript/issues/58688.
323
+ // Instead we extract and inline the typing of the "props" field here, which seems to sufficiently work around
324
+ // the issue.
325
+ // type RowInsertableType = InsertableObjectFromSchemaRecord<typeof rowFields>;
326
+ type RowInsertableType = InsertableObjectFromSchemaRecord<typeof rowFieldsBuiltInParts> &
327
+ (FieldHasDefault<TPropsSchema> extends true
328
+ ? // Note: The docs on the below properties are copied from `IRow.props`' docs to ensure that the
329
+ // documentation appears in the data insertion scenario.
330
+ // The contents are duplicated instead of using `@inheritdoc`, as intellisense does not correctly
331
+ // support `@inheritDoc`.
332
+ // See: https://github.com/microsoft/TypeScript/issues/31267
333
+ {
334
+ /**
335
+ * The row's properties.
336
+ * @remarks This is a user-defined schema that can be used to store additional information
337
+ * about the row.
338
+ */
339
+ props?: InsertableTreeFieldFromImplicitField<TPropsSchema>;
340
+ }
341
+ : {
342
+ /**
343
+ * The row's properties.
344
+ * @remarks This is a user-defined schema that can be used to store additional information
345
+ * about the row.
346
+ */
347
+ props: InsertableTreeFieldFromImplicitField<TPropsSchema>;
348
+ });
349
+
350
+ // Modified version of `Column` that ensures the constructor (and `createFromInsertable`) are
351
+ // typed correctly in terms of our insertable type.
352
+ // This lets us be selective in our type-cast for the value returned from this function,
353
+ // preserving as much type-safety as we reasonably can.
354
+ type RowSchemaModifiedType = Omit<
355
+ // Use mapped type to omit the constructor
356
+ {
357
+ [Property in keyof typeof Row]: (typeof Row)[Property];
358
+ },
359
+ "createFromInsertable"
360
+ > &
361
+ (new (
362
+ parameters: InternalTreeNode | RowInsertableType,
363
+ ) => Row) & {
364
+ createFromInsertable(parameters: RowInsertableType): Row;
365
+ };
266
366
 
267
367
  // Returning SingletonSchema without a type conversion results in TypeScript generating something like `readonly "__#124291@#brand": unknown;`
268
368
  // for the private brand field of TreeNode.
@@ -276,7 +376,7 @@ export namespace TableSchema {
276
376
  /* TInsertable */ object & RowInsertableType,
277
377
  /* ImplicitlyConstructable */ true,
278
378
  /* Info */ typeof rowFields
279
- > = Row;
379
+ > = Row as RowSchemaModifiedType;
280
380
 
281
381
  return RowSchemaType;
282
382
  }
@@ -286,355 +386,146 @@ export namespace TableSchema {
286
386
  * @sealed @system @internal
287
387
  */
288
388
  export type RowSchemaBase<
289
- TScope extends string | undefined,
290
- TCellSchema extends ImplicitAllowedTypes,
291
- TPropsSchema extends ImplicitAllowedTypes,
292
- > = ReturnType<typeof createRow<TScope, TCellSchema, TPropsSchema>>;
389
+ TScope extends string | undefined = string | undefined,
390
+ TCellSchema extends ImplicitAllowedTypes = ImplicitAllowedTypes,
391
+ TPropsSchema extends ImplicitFieldSchema = ImplicitFieldSchema,
392
+ > = ReturnType<typeof TableSchema.createRow<TScope, TCellSchema, TPropsSchema>>;
293
393
 
294
394
  // #endregion
295
395
 
296
396
  // #region Table
297
397
 
298
398
  /**
299
- * A key to uniquely identify a cell in a table.
300
- * @sealed @internal
399
+ * Base options for creating table schema.
400
+ * @remarks Includes parameters common to all table factory overloads.
401
+ * @system @internal
301
402
  */
302
- export interface CellKey {
303
- /**
304
- * {@link TableSchema.IColumn.id} of the containing {@link TableSchema.IColumn}.
305
- */
306
- readonly columnId: string;
307
-
308
- /**
309
- * {@link TableSchema.IRow.id} of the containing {@link TableSchema.IRow}.
310
- */
311
- readonly rowId: string;
312
- }
403
+ export type TableFactoryOptionsBase<
404
+ TScope extends string | undefined = string | undefined,
405
+ TCell extends ImplicitAllowedTypes = ImplicitAllowedTypes,
406
+ > = OptionsWithSchemaFactory<TScope> & OptionsWithCellSchema<TCell>;
313
407
 
314
408
  /**
315
- * {@link TableSchema.ITable.insertColumn} parameters.
316
- * @sealed @internal
409
+ * Factory for creating new table schema.
410
+ * @system @internal
317
411
  */
318
- export interface InsertColumnParameters<TInsertableColumn> {
319
- /**
320
- * The index at which to insert the new column.
321
- * @remarks If not provided, the column will be appended to the end of the table.
322
- */
323
- readonly index?: number | undefined;
412
+ // eslint-disable-next-line @typescript-eslint/explicit-function-return-type -- Return type is too complex to be reasonable to specify
413
+ export function createTableInternal<
414
+ const TInputScope extends string | undefined,
415
+ const TCellSchema extends ImplicitAllowedTypes,
416
+ const TColumnSchema extends ColumnSchemaBase<TInputScope> = ColumnSchemaBase<TInputScope>,
417
+ const TRowSchema extends RowSchemaBase<TInputScope, TCellSchema> = RowSchemaBase<
418
+ TInputScope,
419
+ TCellSchema
420
+ >,
421
+ >(
422
+ inputSchemaFactory: SchemaFactoryAlpha<TInputScope>,
423
+ _cellSchema: TCellSchema,
424
+ columnSchema: TColumnSchema,
425
+ rowSchema: TRowSchema,
426
+ ) {
427
+ const schemaFactory = inputSchemaFactory.scopedFactory(tableSchemaFactorySubScope);
428
+ type Scope = ScopedSchemaName<TInputScope, typeof tableSchemaFactorySubScope>;
324
429
 
325
- /**
326
- * The column to insert.
327
- */
328
- readonly column: TInsertableColumn;
329
- }
430
+ type CellValueType = TreeNodeFromImplicitAllowedTypes<TCellSchema>;
431
+ type CellInsertableType = InsertableTreeNodeFromImplicitAllowedTypes<TCellSchema>;
330
432
 
331
- /**
332
- * {@link TableSchema.ITable.insertRows} parameters.
333
- * @sealed @internal
334
- */
335
- export interface InsertRowsParameters<TInsertableRow> {
336
- /**
337
- * The index at which to insert the new rows.
338
- * @remarks If not provided, the rows will be appended to the end of the table.
339
- */
340
- readonly index?: number | undefined;
433
+ type ColumnValueType = TreeNodeFromImplicitAllowedTypes<TColumnSchema>;
434
+ type ColumnInsertableType = InsertableTreeNodeFromImplicitAllowedTypes<TColumnSchema>;
341
435
 
342
- /**
343
- * The rows to insert.
344
- */
345
- readonly rows: TInsertableRow[];
346
- }
436
+ type RowValueType = TreeNodeFromImplicitAllowedTypes<TRowSchema>;
437
+ type RowInsertableType = InsertableTreeNodeFromImplicitAllowedTypes<TRowSchema>;
347
438
 
348
- /**
349
- * {@link TableSchema.ITable.setCell} parameters.
350
- * @sealed @internal
351
- */
352
- export interface SetCellParameters<TInsertableCell> {
353
439
  /**
354
- * The key to uniquely identify a cell in a table.
440
+ * {@link Table} fields.
441
+ * @remarks Extracted for re-use in returned type signature defined later in this function.
442
+ * The implicit typing is intentional.
355
443
  */
356
- readonly key: CellKey;
444
+ const tableFields = {
445
+ rows: schemaFactory.array("Table.rows", rowSchema),
446
+ columns: schemaFactory.array("Table.columns", columnSchema),
447
+ } as const satisfies Record<string, ImplicitFieldSchema>;
357
448
 
358
449
  /**
359
- * The cell to set.
450
+ * The Table schema
360
451
  */
361
- readonly cell: TInsertableCell;
362
- }
452
+ class Table
453
+ extends schemaFactory.objectAlpha("Table", tableFields, {
454
+ // Will make it easier to evolve this schema in the future.
455
+ allowUnknownOptionalFields: true,
456
+ })
457
+ implements TableSchema.ITable<TCellSchema, TColumnSchema, TRowSchema>
458
+ {
459
+ public getColumn(id: string): ColumnValueType | undefined {
460
+ // TypeScript is unable to narrow the types correctly here, hence the casts.
461
+ // See: https://github.com/microsoft/TypeScript/issues/52144
462
+ return this.columns.find((column) => (column as ColumnValueType).id === id) as
463
+ | ColumnValueType
464
+ | undefined;
465
+ }
363
466
 
364
- /**
365
- * A table.
366
- * @sealed @internal
367
- */
368
- export interface ITable<
369
- TCellSchema extends ImplicitAllowedTypes,
370
- TColumnSchema extends ImplicitAllowedTypes,
371
- TRowSchema extends ImplicitAllowedTypes,
372
- > {
373
- /**
374
- * The table's columns.
375
- */
376
- readonly columns: TreeArrayNode<TColumnSchema>;
467
+ public getRow(id: string): RowValueType | undefined {
468
+ // TypeScript is unable to narrow the types correctly here, hence the casts.
469
+ // See: https://github.com/microsoft/TypeScript/issues/52144
470
+ return this.rows.find((_row) => (_row as RowValueType).id === id) as
471
+ | RowValueType
472
+ | undefined;
473
+ }
377
474
 
378
- /**
379
- * The table's rows.
380
- */
381
- readonly rows: TreeArrayNode<TRowSchema>;
475
+ public getCell(key: TableSchema.CellKey): CellValueType | undefined {
476
+ const { columnId, rowId } = key;
477
+ const row = this.getRow(rowId);
478
+ if (row !== undefined) {
479
+ const column = this.getColumn(columnId);
480
+ if (column !== undefined) {
481
+ return row.getCell(column.id);
482
+ }
483
+ }
484
+ // If the cell does not exist return undefined
485
+ return undefined;
486
+ }
382
487
 
383
- /**
384
- * Gets a table column by its {@link TableSchema.IRow.id}.
385
- */
386
- getColumn(id: string): TreeNodeFromImplicitAllowedTypes<TColumnSchema> | undefined;
488
+ public insertColumn({
489
+ column,
490
+ index,
491
+ }: TableSchema.InsertColumnParameters<ColumnInsertableType>): ColumnValueType {
492
+ if (index === undefined) {
493
+ // TypeScript is unable to narrow the types correctly here, hence the cast.
494
+ // See: https://github.com/microsoft/TypeScript/issues/52144
495
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
496
+ this.columns.insertAtEnd(column as any);
497
+ } else {
498
+ // TypeScript is unable to narrow the types correctly here, hence the cast.
499
+ // See: https://github.com/microsoft/TypeScript/issues/52144
500
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
501
+ this.columns.insertAt(index, column as any);
502
+ }
387
503
 
388
- /**
389
- * Gets a table row by its {@link TableSchema.IRow.id}.
390
- */
391
- getRow(id: string): TreeNodeFromImplicitAllowedTypes<TRowSchema> | undefined;
504
+ // Inserting the input node into the tree hydrates it, making it usable as a node.
505
+ return column as ColumnValueType;
506
+ }
392
507
 
393
- /**
394
- * Gets a cell in the table by column and row IDs.
395
- * @param key - A key that uniquely distinguishes a cell in the table, represented as a combination of the column ID and row ID.
396
- * @privateRemarks TODO: add overload that takes row and column nodes.
397
- */
398
- getCell(key: CellKey): TreeNodeFromImplicitAllowedTypes<TCellSchema> | undefined;
399
-
400
- /**
401
- * Inserts a column into the table.
402
- * @throws Throws an error if the column is already in the tree, or if the specified index is out of range.
403
- */
404
- insertColumn(
405
- params: InsertColumnParameters<
406
- InsertableTreeNodeFromImplicitAllowedTypes<TColumnSchema>
407
- >,
408
- ): TreeNodeFromImplicitAllowedTypes<TColumnSchema>;
409
-
410
- /**
411
- * Inserts 0 or more rows into the table.
412
- * @throws Throws an error if any of the rows are already in the tree, or if the specified index is out of range.
413
- */
414
- insertRows(
415
- params: InsertRowsParameters<InsertableTreeNodeFromImplicitAllowedTypes<TRowSchema>>,
416
- ): TreeNodeFromImplicitAllowedTypes<TRowSchema>[];
417
-
418
- /**
419
- * Sets the cell at the specified location in the table.
420
- * @remarks To remove a cell, call {@link TableSchema.ITable.removeCell} instead.
421
- * @privateRemarks TODO: add overload that takes column/row nodes?
422
- */
423
- setCell(
424
- params: SetCellParameters<InsertableTreeNodeFromImplicitAllowedTypes<TCellSchema>>,
425
- ): void;
426
-
427
- /**
428
- * Removes the specified column from the table.
429
- * @remarks Note: this does not remove any cells from the table's rows.
430
- * @privateRemarks
431
- * TODO:
432
- * - Policy for when the column is not in the table.
433
- * - Actually remove corresponding cells from table rows.
434
- */
435
- removeColumn: (column: TreeNodeFromImplicitAllowedTypes<TColumnSchema>) => void;
436
-
437
- /**
438
- * Removes 0 or more rows from the table.
439
- * @privateRemarks TODO: policy for when 1 or more rows are not in the table.
440
- */
441
- removeRows: (rows: readonly TreeNodeFromImplicitAllowedTypes<TRowSchema>[]) => void;
442
-
443
- /**
444
- * Removes all rows from the table.
445
- */
446
- removeAllRows: () => void;
447
-
448
- /**
449
- * Removes the cell at the specified location in the table.
450
- * @privateRemarks TODO: add overload that takes column/row nodes?
451
- */
452
- removeCell: (key: CellKey) => void;
453
- }
454
-
455
- /**
456
- * Factory for creating new table schema without specifying row or column schema.
457
- * @internal
458
- */
459
- export function createTable<
460
- const TInputScope extends string | undefined,
461
- const TCell extends ImplicitAllowedTypes,
462
- >(
463
- inputSchemaFactory: SchemaFactoryAlpha<TInputScope>,
464
- _cellSchema: TCell,
465
- ): ReturnType<typeof createTableInternal<TInputScope, TCell>>;
466
- /**
467
- * Factory for creating new table schema without specifying row schema
468
- * @internal
469
- */
470
- export function createTable<
471
- const TInputScope extends string | undefined,
472
- const TCell extends ImplicitAllowedTypes,
473
- const TColumn extends ColumnSchemaBase<TInputScope, ImplicitAllowedTypes>,
474
- >(
475
- inputSchemaFactory: SchemaFactoryAlpha<TInputScope>,
476
- _cellSchema: TCell,
477
- columnSchema: TColumn,
478
- ): ReturnType<typeof createTableInternal<TInputScope, TCell, TColumn>>;
479
- /**
480
- * Factory for creating new table schema.
481
- * @internal
482
- */
483
- export function createTable<
484
- const TInputScope extends string | undefined,
485
- const TCell extends ImplicitAllowedTypes,
486
- const TColumn extends ColumnSchemaBase<TInputScope, ImplicitAllowedTypes>,
487
- const TRow extends RowSchemaBase<TInputScope, TCell, ImplicitAllowedTypes>,
488
- >(
489
- inputSchemaFactory: SchemaFactoryAlpha<TInputScope>,
490
- _cellSchema: TCell,
491
- columnSchema: TColumn,
492
- rowSchema: TRow,
493
- ): ReturnType<typeof createTableInternal<TInputScope, TCell, TColumn, TRow>>;
494
- /** `createTable` implementation */
495
- export function createTable<
496
- const TInputScope extends string | undefined,
497
- const TCell extends ImplicitAllowedTypes,
498
- const TColumn extends ColumnSchemaBase<TInputScope, ImplicitAllowedTypes>,
499
- const TRow extends RowSchemaBase<TInputScope, TCell, ImplicitAllowedTypes>,
500
- >(
501
- inputSchemaFactory: SchemaFactoryAlpha<TInputScope>,
502
- _cellSchema: TCell,
503
- columnSchema?: TColumn,
504
- rowSchema?: TRow,
505
- ): TreeNodeSchema {
506
- const column = columnSchema ?? createColumn(inputSchemaFactory, inputSchemaFactory.null);
507
- return createTableInternal(
508
- inputSchemaFactory,
509
- _cellSchema,
510
- column as TColumn,
511
- rowSchema ??
512
- (createRow(inputSchemaFactory, _cellSchema, inputSchemaFactory.null) as TRow),
513
- );
514
- }
515
-
516
- /**
517
- * Factory for creating new table schema.
518
- * @system @internal
519
- */
520
- // eslint-disable-next-line @typescript-eslint/explicit-function-return-type -- Return type is too complex to be reasonable to specify
521
- export function createTableInternal<
522
- const TInputScope extends string | undefined,
523
- const TCell extends ImplicitAllowedTypes,
524
- const TColumn extends ColumnSchemaBase<
525
- TInputScope,
526
- ImplicitAllowedTypes
527
- > = ColumnSchemaBase<TInputScope, ImplicitAllowedTypes>,
528
- const TRow extends RowSchemaBase<TInputScope, TCell, ImplicitAllowedTypes> = RowSchemaBase<
529
- TInputScope,
530
- TCell,
531
- ImplicitAllowedTypes
532
- >,
533
- >(
534
- inputSchemaFactory: SchemaFactoryAlpha<TInputScope>,
535
- _cellSchema: TCell,
536
- columnSchema: TColumn,
537
- rowSchema: TRow,
538
- ) {
539
- const schemaFactory = inputSchemaFactory.scopedFactory(tableSchemaFactorySubScope);
540
- type Scope = ScopedSchemaName<TInputScope, typeof tableSchemaFactorySubScope>;
541
-
542
- type CellValueType = TreeNodeFromImplicitAllowedTypes<TCell>;
543
- type CellInsertableType = InsertableTreeNodeFromImplicitAllowedTypes<TCell>;
544
-
545
- type ColumnValueType = TreeNodeFromImplicitAllowedTypes<TColumn>;
546
- type ColumnInsertableType = InsertableTreeNodeFromImplicitAllowedTypes<TColumn>;
547
-
548
- type RowValueType = TreeNodeFromImplicitAllowedTypes<TRow>;
549
- type RowInsertableType = InsertableTreeNodeFromImplicitAllowedTypes<TRow>;
550
-
551
- /**
552
- * {@link Table} fields.
553
- * @remarks Extracted for re-use in returned type signature defined later in this function.
554
- * The implicit typing is intentional.
555
- */
556
- const tableFields = {
557
- rows: schemaFactory.array("Table.rows", rowSchema),
558
- columns: schemaFactory.array("Table.columns", columnSchema),
559
- } as const satisfies Record<string, ImplicitFieldSchema>;
560
-
561
- /**
562
- * The Table schema
563
- */
564
- class Table
565
- extends schemaFactory.object("Table", tableFields)
566
- implements ITable<TCell, TColumn, TRow>
567
- {
568
- public getColumn(id: string): ColumnValueType | undefined {
569
- // TypeScript is unable to narrow the types correctly here, hence the casts.
570
- // See: https://github.com/microsoft/TypeScript/issues/52144
571
- return this.columns.find((column) => (column as ColumnValueType).id === id) as
572
- | ColumnValueType
573
- | undefined;
574
- }
575
-
576
- public getRow(id: string): RowValueType | undefined {
577
- // TypeScript is unable to narrow the types correctly here, hence the casts.
578
- // See: https://github.com/microsoft/TypeScript/issues/52144
579
- return this.rows.find((_row) => (_row as RowValueType).id === id) as
580
- | RowValueType
581
- | undefined;
582
- }
583
-
584
- public getCell(key: CellKey): CellValueType | undefined {
585
- const { columnId, rowId } = key;
586
- const row = this.getRow(rowId);
587
- if (row !== undefined) {
588
- const column = this.getColumn(columnId);
589
- if (column !== undefined) {
590
- return row.getCell(column.id);
591
- }
592
- }
593
- // If the cell does not exist return undefined
594
- return undefined;
595
- }
596
-
597
- public insertColumn({
598
- column,
599
- index,
600
- }: InsertColumnParameters<ColumnInsertableType>): ColumnValueType {
601
- if (index === undefined) {
602
- // TypeScript is unable to narrow the types correctly here, hence the cast.
603
- // See: https://github.com/microsoft/TypeScript/issues/52144
604
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
605
- this.columns.insertAtEnd(column as any);
606
- } else {
607
- // TypeScript is unable to narrow the types correctly here, hence the cast.
608
- // See: https://github.com/microsoft/TypeScript/issues/52144
609
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
610
- this.columns.insertAt(index, column as any);
611
- }
612
-
613
- // Inserting the input node into the tree hydrates it, making it usable as a node.
614
- return column as ColumnValueType;
615
- }
616
-
617
- public insertRows({
618
- index,
619
- rows,
620
- }: InsertRowsParameters<RowInsertableType>): RowValueType[] {
621
- if (index === undefined) {
622
- // TypeScript is unable to narrow the types correctly here, hence the cast.
623
- // See: https://github.com/microsoft/TypeScript/issues/52144
624
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
625
- this.rows.insertAtEnd(TreeArrayNode.spread(rows) as any);
626
- } else {
627
- // TypeScript is unable to narrow the types correctly here, hence the cast.
628
- // See: https://github.com/microsoft/TypeScript/issues/52144
629
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
630
- this.rows.insertAt(index, TreeArrayNode.spread(rows) as any);
631
- }
508
+ public insertRows({
509
+ index,
510
+ rows,
511
+ }: TableSchema.InsertRowsParameters<RowInsertableType>): RowValueType[] {
512
+ if (index === undefined) {
513
+ // TypeScript is unable to narrow the types correctly here, hence the cast.
514
+ // See: https://github.com/microsoft/TypeScript/issues/52144
515
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
516
+ this.rows.insertAtEnd(TreeArrayNode.spread(rows) as any);
517
+ } else {
518
+ // TypeScript is unable to narrow the types correctly here, hence the cast.
519
+ // See: https://github.com/microsoft/TypeScript/issues/52144
520
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
521
+ this.rows.insertAt(index, TreeArrayNode.spread(rows) as any);
522
+ }
632
523
 
633
524
  // Inserting the input nodes into the tree hydrates them, making them usable as nodes.
634
525
  return rows as unknown as RowValueType[];
635
526
  }
636
527
 
637
- public setCell({ key, cell }: SetCellParameters<CellInsertableType>): void {
528
+ public setCell({ key, cell }: TableSchema.SetCellParameters<CellInsertableType>): void {
638
529
  const { columnId, rowId } = key;
639
530
  const row = this.getRow(rowId);
640
531
  if (row !== undefined) {
@@ -679,7 +570,7 @@ export namespace TableSchema {
679
570
  this.rows.removeRange();
680
571
  }
681
572
 
682
- public removeCell(key: CellKey): void {
573
+ public removeCell(key: TableSchema.CellKey): void {
683
574
  const { columnId, rowId } = key;
684
575
  const row = this.getRow(rowId);
685
576
  if (row !== undefined) {
@@ -692,7 +583,7 @@ export namespace TableSchema {
692
583
  }
693
584
 
694
585
  type TableValueType = TreeNode &
695
- ITable<TCell, TColumn, TRow> &
586
+ TableSchema.ITable<TCellSchema, TColumnSchema, TRowSchema> &
696
587
  WithType<ScopedSchemaName<Scope, "Table">>;
697
588
  type TableInsertableType = InsertableObjectFromSchemaRecord<typeof tableFields>;
698
589
 
@@ -721,16 +612,429 @@ export namespace TableSchema {
721
612
  export type TableSchemaBase<
722
613
  TScope extends string | undefined,
723
614
  TCell extends ImplicitAllowedTypes,
724
- TColumn extends ColumnSchemaBase<TScope, ImplicitAllowedTypes> = ColumnSchemaBase<
725
- TScope,
726
- ImplicitAllowedTypes
727
- >,
615
+ TColumn extends ColumnSchemaBase<TScope> = ColumnSchemaBase<TScope>,
728
616
  TRow extends RowSchemaBase<TScope, TCell, ImplicitAllowedTypes> = RowSchemaBase<
729
617
  TScope,
730
618
  TCell,
731
619
  ImplicitAllowedTypes
732
620
  >,
733
- > = ReturnType<typeof createTable<TScope, TCell, TColumn, TRow>>;
621
+ > = ReturnType<typeof TableSchema.createTable<TScope, TCell, TColumn, TRow>>;
622
+
623
+ // #endregion
624
+ }
625
+
626
+ /**
627
+ * Contains types and factories for creating schema to represent dynamic tabular data.
628
+ * @privateRemarks TODO: document in more detail and add `@example`s.
629
+ * @internal
630
+ */
631
+ export namespace TableSchema {
632
+ // #region Column
633
+
634
+ /**
635
+ * A column in a table.
636
+ * @remarks Implemented by the schema class returned from {@link TableSchema.(createColumn:2)}.
637
+ * @sealed @internal
638
+ */
639
+ export interface IColumn<
640
+ TProps extends ImplicitAnnotatedFieldSchema = ImplicitAnnotatedFieldSchema,
641
+ > {
642
+ /**
643
+ * The unique identifier of the column.
644
+ * @remarks Uniquely identifies the node within the entire tree, not just the table.
645
+ */
646
+ readonly id: string;
647
+
648
+ /**
649
+ * The column's properties.
650
+ * @remarks This is a user-defined schema that can be used to store additional information about the column.
651
+ * @privateRemarks
652
+ * Note: these docs are duplicated on the inline type definitions in {@link createColumn}.
653
+ * If you update the docs here, please also update the inline type definitions.
654
+ */
655
+ get props(): TreeFieldFromImplicitField<UnannotateImplicitFieldSchema<TProps>> | undefined;
656
+ set props(value: InsertableTreeFieldFromImplicitField<
657
+ UnannotateImplicitFieldSchema<TProps>
658
+ >);
659
+ }
660
+
661
+ /**
662
+ * Factory for creating new table column schema.
663
+ * @internal
664
+ */
665
+ export function createColumn<const TScope extends string | undefined>({
666
+ schemaFactory,
667
+ }: System_TableSchema.CreateColumnOptionsBase<TScope>): ReturnType<
668
+ typeof System_TableSchema.createColumnInternal<
669
+ TScope,
670
+ FieldSchema<FieldKind.Optional, typeof SchemaFactoryAlpha.null>
671
+ >
672
+ >;
673
+ /**
674
+ * Factory for creating new table column schema.
675
+ * @internal
676
+ */
677
+ export function createColumn<
678
+ const TScope extends string | undefined,
679
+ const TProps extends ImplicitFieldSchema,
680
+ >({
681
+ schemaFactory,
682
+ props,
683
+ }: System_TableSchema.CreateColumnOptionsBase<TScope> & {
684
+ /**
685
+ * Optional column properties.
686
+ */
687
+ readonly props: TProps;
688
+ }): ReturnType<typeof System_TableSchema.createColumnInternal<TScope, TProps>>;
689
+ /**
690
+ * Overload implementation
691
+ */
692
+ export function createColumn({
693
+ schemaFactory,
694
+ props = SchemaFactory.optional(SchemaFactory.null),
695
+ }: System_TableSchema.CreateColumnOptionsBase & {
696
+ readonly props?: ImplicitFieldSchema;
697
+ }): TreeNodeSchema {
698
+ return System_TableSchema.createColumnInternal(schemaFactory, props);
699
+ }
700
+
701
+ // #endregion
702
+
703
+ // #region Row
704
+
705
+ /**
706
+ * A row in a table.
707
+ * @remarks Implemented by the schema class returned from {@link TableSchema.(createRow:2)}.
708
+ * @sealed @internal
709
+ */
710
+ export interface IRow<
711
+ TCell extends ImplicitAllowedTypes,
712
+ TProps extends ImplicitAnnotatedFieldSchema = ImplicitAnnotatedFieldSchema,
713
+ > {
714
+ /**
715
+ * The unique identifier of the row.
716
+ * @remarks Uniquely identifies the node within the entire tree, not just the table.
717
+ */
718
+ readonly id: string;
719
+
720
+ /**
721
+ * Gets the cell in the specified column.
722
+ * @returns The cell if it exists, otherwise undefined.
723
+ */
724
+ getCell(column: IColumn): TreeNodeFromImplicitAllowedTypes<TCell> | undefined;
725
+ /**
726
+ * Gets the cell in the specified column, denoted by column ID.
727
+ * @returns The cell if it exists, otherwise undefined.
728
+ */
729
+ getCell(columnId: string): TreeNodeFromImplicitAllowedTypes<TCell> | undefined;
730
+
731
+ /**
732
+ * Sets the cell in the specified column.
733
+ * @remarks To remove a cell, call {@link TableSchema.IRow.(removeCell:1)} instead.
734
+ */
735
+ setCell(column: IColumn, value: InsertableTreeNodeFromImplicitAllowedTypes<TCell>): void;
736
+ /**
737
+ * Sets the cell in the specified column, denoted by column ID.
738
+ * @remarks To remove a cell, call {@link TableSchema.IRow.(removeCell:2)} instead.
739
+ */
740
+ setCell(columnId: string, value: InsertableTreeNodeFromImplicitAllowedTypes<TCell>): void;
741
+
742
+ /**
743
+ * Removes the cell in the specified column.
744
+ * @privateRemarks TODO: return removed cell
745
+ */
746
+ removeCell(column: IColumn): void;
747
+ /**
748
+ * Removes the cell in the specified column, denoted by column ID.
749
+ * @privateRemarks TODO: return removed cell
750
+ */
751
+ removeCell(columnId: string): void;
752
+
753
+ /**
754
+ * The row's properties.
755
+ * @remarks This is a user-defined schema that can be used to store additional information about the row.
756
+ * @privateRemarks
757
+ * Note: these docs are duplicated on the inline type definitions in {@link createColumn}.
758
+ * If you update the docs here, please also update the inline type definitions.
759
+ */
760
+ get props(): TreeFieldFromImplicitField<UnannotateImplicitFieldSchema<TProps>>;
761
+ set props(value: InsertableTreeFieldFromImplicitField<
762
+ UnannotateImplicitFieldSchema<TProps>
763
+ >);
764
+ }
765
+
766
+ /**
767
+ * Factory for creating new table column schema.
768
+ * @internal
769
+ */
770
+ export function createRow<
771
+ const TScope extends string | undefined,
772
+ const TCell extends ImplicitAllowedTypes,
773
+ >({
774
+ schemaFactory,
775
+ cell,
776
+ }: System_TableSchema.CreateRowOptionsBase<TScope, TCell>): ReturnType<
777
+ typeof System_TableSchema.createRowInternal<
778
+ TScope,
779
+ TCell,
780
+ FieldSchema<FieldKind.Optional, typeof SchemaFactoryAlpha.null>
781
+ >
782
+ >;
783
+ /**
784
+ * Factory for creating new table column schema.
785
+ * @internal
786
+ */
787
+ export function createRow<
788
+ const TScope extends string | undefined,
789
+ const TCell extends ImplicitAllowedTypes,
790
+ const TProps extends ImplicitFieldSchema,
791
+ >({
792
+ schemaFactory,
793
+ cell,
794
+ props,
795
+ }: System_TableSchema.CreateRowOptionsBase<TScope, TCell> & {
796
+ /**
797
+ * Optional row properties.
798
+ */
799
+ readonly props: TProps;
800
+ }): ReturnType<typeof System_TableSchema.createRowInternal<TScope, TCell, TProps>>;
801
+ /**
802
+ * Overload implementation
803
+ */
804
+ export function createRow({
805
+ schemaFactory,
806
+ cell,
807
+ props = SchemaFactory.optional(SchemaFactory.null),
808
+ }: System_TableSchema.CreateRowOptionsBase & {
809
+ readonly props?: ImplicitFieldSchema;
810
+ }): TreeNodeSchema {
811
+ return System_TableSchema.createRowInternal(schemaFactory, cell, props);
812
+ }
813
+
814
+ // #endregion
815
+
816
+ // #region Table
817
+
818
+ /**
819
+ * A key to uniquely identify a cell in a table.
820
+ * @internal
821
+ */
822
+ export interface CellKey {
823
+ /**
824
+ * {@link TableSchema.IColumn.id} of the containing {@link TableSchema.IColumn}.
825
+ */
826
+ readonly columnId: string;
827
+
828
+ /**
829
+ * {@link TableSchema.IRow.id} of the containing {@link TableSchema.IRow}.
830
+ */
831
+ readonly rowId: string;
832
+ }
833
+
834
+ /**
835
+ * {@link TableSchema.ITable.insertColumn} parameters.
836
+ * @internal
837
+ */
838
+ export interface InsertColumnParameters<TInsertableColumn> {
839
+ /**
840
+ * The index at which to insert the new column.
841
+ * @remarks If not provided, the column will be appended to the end of the table.
842
+ */
843
+ readonly index?: number | undefined;
844
+
845
+ /**
846
+ * The column to insert.
847
+ */
848
+ readonly column: TInsertableColumn;
849
+ }
850
+
851
+ /**
852
+ * {@link TableSchema.ITable.insertRows} parameters.
853
+ * @internal
854
+ */
855
+ export interface InsertRowsParameters<TInsertableRow> {
856
+ /**
857
+ * The index at which to insert the new rows.
858
+ * @remarks If not provided, the rows will be appended to the end of the table.
859
+ */
860
+ readonly index?: number | undefined;
861
+
862
+ /**
863
+ * The rows to insert.
864
+ */
865
+ readonly rows: TInsertableRow[];
866
+ }
867
+
868
+ /**
869
+ * {@link TableSchema.ITable.setCell} parameters.
870
+ * @internal
871
+ */
872
+ export interface SetCellParameters<TInsertableCell> {
873
+ /**
874
+ * The key to uniquely identify a cell in a table.
875
+ */
876
+ readonly key: CellKey;
877
+
878
+ /**
879
+ * The cell to set.
880
+ */
881
+ readonly cell: TInsertableCell;
882
+ }
883
+
884
+ /**
885
+ * A table.
886
+ * @sealed @internal
887
+ */
888
+ export interface ITable<
889
+ TCell extends ImplicitAllowedTypes,
890
+ TColumn extends ImplicitAllowedTypes,
891
+ TRow extends ImplicitAllowedTypes,
892
+ > {
893
+ /**
894
+ * The table's columns.
895
+ */
896
+ readonly columns: TreeArrayNode<TColumn>;
897
+
898
+ /**
899
+ * The table's rows.
900
+ */
901
+ readonly rows: TreeArrayNode<TRow>;
902
+
903
+ /**
904
+ * Gets a table column by its {@link TableSchema.IRow.id}.
905
+ */
906
+ getColumn(id: string): TreeNodeFromImplicitAllowedTypes<TColumn> | undefined;
907
+
908
+ /**
909
+ * Gets a table row by its {@link TableSchema.IRow.id}.
910
+ */
911
+ getRow(id: string): TreeNodeFromImplicitAllowedTypes<TRow> | undefined;
912
+
913
+ /**
914
+ * Gets a cell in the table by column and row IDs.
915
+ * @param key - A key that uniquely distinguishes a cell in the table, represented as a combination of the column ID and row ID.
916
+ * @privateRemarks TODO: add overload that takes row and column nodes.
917
+ */
918
+ getCell(key: CellKey): TreeNodeFromImplicitAllowedTypes<TCell> | undefined;
919
+
920
+ /**
921
+ * Inserts a column into the table.
922
+ * @throws Throws an error if the column is already in the tree, or if the specified index is out of range.
923
+ */
924
+ insertColumn(
925
+ params: InsertColumnParameters<InsertableTreeNodeFromImplicitAllowedTypes<TColumn>>,
926
+ ): TreeNodeFromImplicitAllowedTypes<TColumn>;
927
+
928
+ /**
929
+ * Inserts 0 or more rows into the table.
930
+ * @throws Throws an error if any of the rows are already in the tree, or if the specified index is out of range.
931
+ */
932
+ insertRows(
933
+ params: InsertRowsParameters<InsertableTreeNodeFromImplicitAllowedTypes<TRow>>,
934
+ ): TreeNodeFromImplicitAllowedTypes<TRow>[];
935
+
936
+ /**
937
+ * Sets the cell at the specified location in the table.
938
+ * @remarks To remove a cell, call {@link TableSchema.ITable.removeCell} instead.
939
+ * @privateRemarks TODO: add overload that takes column/row nodes?
940
+ */
941
+ setCell(
942
+ params: SetCellParameters<InsertableTreeNodeFromImplicitAllowedTypes<TCell>>,
943
+ ): void;
944
+
945
+ /**
946
+ * Removes the specified column from the table.
947
+ * @remarks Note: this does not remove any cells from the table's rows.
948
+ * @privateRemarks
949
+ * TODO:
950
+ * - Policy for when the column is not in the table.
951
+ * - Actually remove corresponding cells from table rows.
952
+ */
953
+ removeColumn: (column: TreeNodeFromImplicitAllowedTypes<TColumn>) => void;
954
+
955
+ /**
956
+ * Removes 0 or more rows from the table.
957
+ * @privateRemarks TODO: policy for when 1 or more rows are not in the table.
958
+ */
959
+ removeRows: (rows: readonly TreeNodeFromImplicitAllowedTypes<TRow>[]) => void;
960
+
961
+ /**
962
+ * Removes all rows from the table.
963
+ */
964
+ removeAllRows: () => void;
965
+
966
+ /**
967
+ * Removes the cell at the specified location in the table.
968
+ * @privateRemarks TODO: add overload that takes column/row nodes?
969
+ */
970
+ removeCell: (key: CellKey) => void;
971
+ }
972
+
973
+ /**
974
+ * Factory for creating new table schema without specifying row or column schema.
975
+ * @internal
976
+ */
977
+ export function createTable<
978
+ const TScope extends string | undefined,
979
+ const TCell extends ImplicitAllowedTypes,
980
+ >({
981
+ schemaFactory,
982
+ cell,
983
+ }: System_TableSchema.TableFactoryOptionsBase<TScope, TCell>): ReturnType<
984
+ typeof System_TableSchema.createTableInternal<TScope, TCell>
985
+ >;
986
+ /**
987
+ * Factory for creating new table schema without specifying row schema.
988
+ * @internal
989
+ */
990
+ export function createTable<
991
+ const TScope extends string | undefined,
992
+ const TCell extends ImplicitAllowedTypes,
993
+ const TColumn extends System_TableSchema.ColumnSchemaBase<TScope>,
994
+ >({
995
+ schemaFactory,
996
+ cell,
997
+ column,
998
+ }: System_TableSchema.TableFactoryOptionsBase<TScope, TCell> & {
999
+ readonly column: TColumn;
1000
+ }): ReturnType<typeof System_TableSchema.createTableInternal<TScope, TCell, TColumn>>;
1001
+ /**
1002
+ * Factory for creating new table schema.
1003
+ * @internal
1004
+ */
1005
+ export function createTable<
1006
+ const TScope extends string | undefined,
1007
+ const TCell extends ImplicitAllowedTypes,
1008
+ const TColumn extends System_TableSchema.ColumnSchemaBase<TScope>,
1009
+ const TRow extends System_TableSchema.RowSchemaBase<TScope, TCell>,
1010
+ >({
1011
+ schemaFactory,
1012
+ cell,
1013
+ column,
1014
+ row,
1015
+ }: System_TableSchema.TableFactoryOptionsBase<TScope, TCell> & {
1016
+ readonly column: TColumn;
1017
+ readonly row: TRow;
1018
+ }): ReturnType<typeof System_TableSchema.createTableInternal<TScope, TCell, TColumn, TRow>>;
1019
+ /**
1020
+ * Overload implementation
1021
+ */
1022
+ export function createTable({
1023
+ schemaFactory,
1024
+ cell,
1025
+ column = createColumn({
1026
+ schemaFactory,
1027
+ }),
1028
+ row = createRow({
1029
+ schemaFactory,
1030
+ cell,
1031
+ }),
1032
+ }: System_TableSchema.TableFactoryOptionsBase & {
1033
+ readonly column?: System_TableSchema.ColumnSchemaBase;
1034
+ readonly row?: System_TableSchema.RowSchemaBase;
1035
+ }): TreeNodeSchema {
1036
+ return System_TableSchema.createTableInternal(schemaFactory, cell, column, row);
1037
+ }
734
1038
 
735
1039
  // #endregion
736
1040
  }