@fluidframework/tree 2.41.0-337492 → 2.41.0-338186

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/api-report/tree.alpha.api.md +1 -1
  2. package/dist/feature-libraries/flex-tree/context.d.ts +16 -14
  3. package/dist/feature-libraries/flex-tree/context.d.ts.map +1 -1
  4. package/dist/feature-libraries/flex-tree/context.js +12 -18
  5. package/dist/feature-libraries/flex-tree/context.js.map +1 -1
  6. package/dist/feature-libraries/flex-tree/index.d.ts +1 -1
  7. package/dist/feature-libraries/flex-tree/index.d.ts.map +1 -1
  8. package/dist/feature-libraries/flex-tree/index.js +1 -2
  9. package/dist/feature-libraries/flex-tree/index.js.map +1 -1
  10. package/dist/feature-libraries/flex-tree/lazyField.d.ts +1 -5
  11. package/dist/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
  12. package/dist/feature-libraries/flex-tree/lazyField.js +2 -16
  13. package/dist/feature-libraries/flex-tree/lazyField.js.map +1 -1
  14. package/dist/feature-libraries/flex-tree/utilities.d.ts +6 -6
  15. package/dist/feature-libraries/flex-tree/utilities.d.ts.map +1 -1
  16. package/dist/feature-libraries/flex-tree/utilities.js +6 -7
  17. package/dist/feature-libraries/flex-tree/utilities.js.map +1 -1
  18. package/dist/feature-libraries/index.d.ts +1 -1
  19. package/dist/feature-libraries/index.d.ts.map +1 -1
  20. package/dist/feature-libraries/index.js +1 -2
  21. package/dist/feature-libraries/index.js.map +1 -1
  22. package/dist/packageVersion.d.ts +1 -1
  23. package/dist/packageVersion.js +1 -1
  24. package/dist/packageVersion.js.map +1 -1
  25. package/dist/shared-tree/checkoutFlexTreeView.d.ts +7 -3
  26. package/dist/shared-tree/checkoutFlexTreeView.d.ts.map +1 -1
  27. package/dist/shared-tree/checkoutFlexTreeView.js +11 -2
  28. package/dist/shared-tree/checkoutFlexTreeView.js.map +1 -1
  29. package/dist/shared-tree/schematizingTreeView.d.ts +3 -0
  30. package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
  31. package/dist/shared-tree/schematizingTreeView.js +10 -5
  32. package/dist/shared-tree/schematizingTreeView.js.map +1 -1
  33. package/dist/shared-tree/treeAlpha.d.ts +1 -4
  34. package/dist/shared-tree/treeAlpha.d.ts.map +1 -1
  35. package/dist/shared-tree/treeAlpha.js +6 -1
  36. package/dist/shared-tree/treeAlpha.js.map +1 -1
  37. package/dist/simple-tree/api/create.d.ts +5 -1
  38. package/dist/simple-tree/api/create.d.ts.map +1 -1
  39. package/dist/simple-tree/api/create.js +10 -11
  40. package/dist/simple-tree/api/create.js.map +1 -1
  41. package/dist/simple-tree/api/index.d.ts +2 -2
  42. package/dist/simple-tree/api/index.d.ts.map +1 -1
  43. package/dist/simple-tree/api/index.js +2 -2
  44. package/dist/simple-tree/api/index.js.map +1 -1
  45. package/dist/simple-tree/api/storedSchema.d.ts +1 -8
  46. package/dist/simple-tree/api/storedSchema.d.ts.map +1 -1
  47. package/dist/simple-tree/api/storedSchema.js +3 -14
  48. package/dist/simple-tree/api/storedSchema.js.map +1 -1
  49. package/dist/simple-tree/arrayNode.d.ts.map +1 -1
  50. package/dist/simple-tree/arrayNode.js +3 -9
  51. package/dist/simple-tree/arrayNode.js.map +1 -1
  52. package/dist/simple-tree/core/unhydratedFlexTree.d.ts +4 -4
  53. package/dist/simple-tree/core/unhydratedFlexTree.js +4 -4
  54. package/dist/simple-tree/core/unhydratedFlexTree.js.map +1 -1
  55. package/dist/simple-tree/index.d.ts +3 -2
  56. package/dist/simple-tree/index.d.ts.map +1 -1
  57. package/dist/simple-tree/index.js +6 -4
  58. package/dist/simple-tree/index.js.map +1 -1
  59. package/dist/simple-tree/mapNode.d.ts.map +1 -1
  60. package/dist/simple-tree/mapNode.js +17 -20
  61. package/dist/simple-tree/mapNode.js.map +1 -1
  62. package/dist/simple-tree/objectNode.d.ts.map +1 -1
  63. package/dist/simple-tree/objectNode.js +2 -4
  64. package/dist/simple-tree/objectNode.js.map +1 -1
  65. package/dist/simple-tree/prepareForInsertion.d.ts +30 -0
  66. package/dist/simple-tree/prepareForInsertion.d.ts.map +1 -0
  67. package/dist/simple-tree/prepareForInsertion.js +137 -0
  68. package/dist/simple-tree/prepareForInsertion.js.map +1 -0
  69. package/dist/simple-tree/proxies.d.ts +1 -12
  70. package/dist/simple-tree/proxies.d.ts.map +1 -1
  71. package/dist/simple-tree/proxies.js +10 -106
  72. package/dist/simple-tree/proxies.js.map +1 -1
  73. package/dist/simple-tree/toMapTree.d.ts +1 -1
  74. package/dist/simple-tree/toMapTree.js +1 -1
  75. package/dist/simple-tree/toMapTree.js.map +1 -1
  76. package/dist/tableSchema.d.ts +93 -43
  77. package/dist/tableSchema.d.ts.map +1 -1
  78. package/dist/tableSchema.js +72 -22
  79. package/dist/tableSchema.js.map +1 -1
  80. package/lib/feature-libraries/flex-tree/context.d.ts +16 -14
  81. package/lib/feature-libraries/flex-tree/context.d.ts.map +1 -1
  82. package/lib/feature-libraries/flex-tree/context.js +11 -16
  83. package/lib/feature-libraries/flex-tree/context.js.map +1 -1
  84. package/lib/feature-libraries/flex-tree/index.d.ts +1 -1
  85. package/lib/feature-libraries/flex-tree/index.d.ts.map +1 -1
  86. package/lib/feature-libraries/flex-tree/index.js +1 -1
  87. package/lib/feature-libraries/flex-tree/index.js.map +1 -1
  88. package/lib/feature-libraries/flex-tree/lazyField.d.ts +1 -5
  89. package/lib/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
  90. package/lib/feature-libraries/flex-tree/lazyField.js +1 -14
  91. package/lib/feature-libraries/flex-tree/lazyField.js.map +1 -1
  92. package/lib/feature-libraries/flex-tree/utilities.d.ts +6 -6
  93. package/lib/feature-libraries/flex-tree/utilities.d.ts.map +1 -1
  94. package/lib/feature-libraries/flex-tree/utilities.js +6 -7
  95. package/lib/feature-libraries/flex-tree/utilities.js.map +1 -1
  96. package/lib/feature-libraries/index.d.ts +1 -1
  97. package/lib/feature-libraries/index.d.ts.map +1 -1
  98. package/lib/feature-libraries/index.js +1 -1
  99. package/lib/feature-libraries/index.js.map +1 -1
  100. package/lib/packageVersion.d.ts +1 -1
  101. package/lib/packageVersion.js +1 -1
  102. package/lib/packageVersion.js.map +1 -1
  103. package/lib/shared-tree/checkoutFlexTreeView.d.ts +7 -3
  104. package/lib/shared-tree/checkoutFlexTreeView.d.ts.map +1 -1
  105. package/lib/shared-tree/checkoutFlexTreeView.js +12 -3
  106. package/lib/shared-tree/checkoutFlexTreeView.js.map +1 -1
  107. package/lib/shared-tree/schematizingTreeView.d.ts +3 -0
  108. package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
  109. package/lib/shared-tree/schematizingTreeView.js +11 -6
  110. package/lib/shared-tree/schematizingTreeView.js.map +1 -1
  111. package/lib/shared-tree/treeAlpha.d.ts +1 -4
  112. package/lib/shared-tree/treeAlpha.d.ts.map +1 -1
  113. package/lib/shared-tree/treeAlpha.js +7 -2
  114. package/lib/shared-tree/treeAlpha.js.map +1 -1
  115. package/lib/simple-tree/api/create.d.ts +5 -1
  116. package/lib/simple-tree/api/create.d.ts.map +1 -1
  117. package/lib/simple-tree/api/create.js +8 -10
  118. package/lib/simple-tree/api/create.js.map +1 -1
  119. package/lib/simple-tree/api/index.d.ts +2 -2
  120. package/lib/simple-tree/api/index.d.ts.map +1 -1
  121. package/lib/simple-tree/api/index.js +2 -2
  122. package/lib/simple-tree/api/index.js.map +1 -1
  123. package/lib/simple-tree/api/storedSchema.d.ts +1 -8
  124. package/lib/simple-tree/api/storedSchema.d.ts.map +1 -1
  125. package/lib/simple-tree/api/storedSchema.js +2 -12
  126. package/lib/simple-tree/api/storedSchema.js.map +1 -1
  127. package/lib/simple-tree/arrayNode.d.ts.map +1 -1
  128. package/lib/simple-tree/arrayNode.js +4 -10
  129. package/lib/simple-tree/arrayNode.js.map +1 -1
  130. package/lib/simple-tree/core/unhydratedFlexTree.d.ts +4 -4
  131. package/lib/simple-tree/core/unhydratedFlexTree.js +4 -4
  132. package/lib/simple-tree/core/unhydratedFlexTree.js.map +1 -1
  133. package/lib/simple-tree/index.d.ts +3 -2
  134. package/lib/simple-tree/index.d.ts.map +1 -1
  135. package/lib/simple-tree/index.js +3 -2
  136. package/lib/simple-tree/index.js.map +1 -1
  137. package/lib/simple-tree/mapNode.d.ts.map +1 -1
  138. package/lib/simple-tree/mapNode.js +3 -6
  139. package/lib/simple-tree/mapNode.js.map +1 -1
  140. package/lib/simple-tree/objectNode.d.ts.map +1 -1
  141. package/lib/simple-tree/objectNode.js +4 -6
  142. package/lib/simple-tree/objectNode.js.map +1 -1
  143. package/lib/simple-tree/prepareForInsertion.d.ts +30 -0
  144. package/lib/simple-tree/prepareForInsertion.d.ts.map +1 -0
  145. package/lib/simple-tree/prepareForInsertion.js +131 -0
  146. package/lib/simple-tree/prepareForInsertion.js.map +1 -0
  147. package/lib/simple-tree/proxies.d.ts +1 -12
  148. package/lib/simple-tree/proxies.d.ts.map +1 -1
  149. package/lib/simple-tree/proxies.js +1 -96
  150. package/lib/simple-tree/proxies.js.map +1 -1
  151. package/lib/simple-tree/toMapTree.d.ts +1 -1
  152. package/lib/simple-tree/toMapTree.js +1 -1
  153. package/lib/simple-tree/toMapTree.js.map +1 -1
  154. package/lib/tableSchema.d.ts +93 -43
  155. package/lib/tableSchema.d.ts.map +1 -1
  156. package/lib/tableSchema.js +73 -23
  157. package/lib/tableSchema.js.map +1 -1
  158. package/lib/tsdoc-metadata.json +1 -1
  159. package/package.json +25 -25
  160. package/src/feature-libraries/flex-tree/context.ts +18 -20
  161. package/src/feature-libraries/flex-tree/index.ts +0 -1
  162. package/src/feature-libraries/flex-tree/lazyField.ts +2 -14
  163. package/src/feature-libraries/flex-tree/utilities.ts +8 -8
  164. package/src/feature-libraries/index.ts +0 -1
  165. package/src/packageVersion.ts +1 -1
  166. package/src/shared-tree/checkoutFlexTreeView.ts +10 -6
  167. package/src/shared-tree/schematizingTreeView.ts +11 -12
  168. package/src/shared-tree/treeAlpha.ts +21 -5
  169. package/src/simple-tree/api/create.ts +15 -15
  170. package/src/simple-tree/api/index.ts +6 -2
  171. package/src/simple-tree/api/storedSchema.ts +2 -19
  172. package/src/simple-tree/arrayNode.ts +9 -20
  173. package/src/simple-tree/core/unhydratedFlexTree.ts +4 -4
  174. package/src/simple-tree/index.ts +6 -5
  175. package/src/simple-tree/mapNode.ts +8 -12
  176. package/src/simple-tree/objectNode.ts +3 -12
  177. package/src/simple-tree/prepareForInsertion.ts +236 -0
  178. package/src/simple-tree/proxies.ts +2 -147
  179. package/src/simple-tree/toMapTree.ts +1 -1
  180. package/src/tableSchema.ts +243 -77
@@ -27,6 +27,7 @@ import {
27
27
  SchemaFactory,
28
28
  type ImplicitAnnotatedFieldSchema,
29
29
  type UnannotateImplicitFieldSchema,
30
+ isArrayNodeSchema,
30
31
  } from "./simple-tree/index.js";
31
32
 
32
33
  // Future improvement TODOs:
@@ -42,6 +43,54 @@ import {
42
43
  */
43
44
  const tableSchemaFactorySubScope = "table";
44
45
 
46
+ /**
47
+ * Gets the table containing the provided row/column node, if the node is part of a table.
48
+ * @remarks Assumes that the table is the grandparent of the row/column node.
49
+ */
50
+ function getParentTable(
51
+ rowOrColumnNode: TreeNode,
52
+ ):
53
+ | (TreeNode &
54
+ TableSchema.Table<
55
+ string | undefined,
56
+ ImplicitAllowedTypes,
57
+ System_TableSchema.ColumnSchemaBase,
58
+ System_TableSchema.RowSchemaBase
59
+ >)
60
+ | undefined {
61
+ const rowListNode = Tree.parent(rowOrColumnNode);
62
+ if (rowListNode === undefined || !isArrayNodeSchema(Tree.schema(rowListNode))) {
63
+ return undefined;
64
+ }
65
+ const tableNode = Tree.parent(rowListNode);
66
+ if (tableNode === undefined || !isTableNode(tableNode)) {
67
+ return undefined;
68
+ }
69
+
70
+ return tableNode;
71
+ }
72
+
73
+ /**
74
+ * A private symbol put on table schema to help identify them.
75
+ */
76
+ const tableSchemaSymbol: unique symbol = Symbol("tableNode");
77
+
78
+ /**
79
+ * Type-guard to determine if a node is a table node.
80
+ * @remarks Uses {@link tableSchemaSymbol} to identify table nodes.
81
+ */
82
+ function isTableNode(
83
+ node: TreeNode,
84
+ ): node is TreeNode &
85
+ TableSchema.Table<
86
+ string | undefined,
87
+ ImplicitAllowedTypes,
88
+ System_TableSchema.ColumnSchemaBase,
89
+ System_TableSchema.RowSchemaBase
90
+ > {
91
+ return tableSchemaSymbol in Tree.schema(node);
92
+ }
93
+
45
94
  /**
46
95
  * Not intended for use outside of this package.
47
96
  *
@@ -99,7 +148,8 @@ export namespace System_TableSchema {
99
148
  */
100
149
  export type CreateColumnOptionsBase<
101
150
  TSchemaFactory extends SchemaFactoryAlpha = SchemaFactoryAlpha,
102
- > = OptionsWithSchemaFactory<TSchemaFactory>;
151
+ TCell extends ImplicitAllowedTypes = ImplicitAllowedTypes,
152
+ > = OptionsWithSchemaFactory<TSchemaFactory> & OptionsWithCellSchema<TCell>;
103
153
 
104
154
  /**
105
155
  * Factory for creating column schema.
@@ -108,11 +158,18 @@ export namespace System_TableSchema {
108
158
  // eslint-disable-next-line @typescript-eslint/explicit-function-return-type -- Return type is too complex to be reasonable to specify
109
159
  export function createColumnSchema<
110
160
  const TInputScope extends string | undefined,
161
+ const TCellSchema extends ImplicitAllowedTypes,
111
162
  const TPropsSchema extends ImplicitAnnotatedFieldSchema,
112
- >(inputSchemaFactory: SchemaFactoryAlpha<TInputScope>, propsSchema: TPropsSchema) {
163
+ >(
164
+ inputSchemaFactory: SchemaFactoryAlpha<TInputScope>,
165
+ cellSchema: TCellSchema,
166
+ propsSchema: TPropsSchema,
167
+ ) {
113
168
  const schemaFactory = inputSchemaFactory.scopedFactory(tableSchemaFactorySubScope);
114
169
  type Scope = ScopedSchemaName<TInputScope, typeof tableSchemaFactorySubScope>;
115
170
 
171
+ type CellValueType = TreeNodeFromImplicitAllowedTypes<TCellSchema>;
172
+
116
173
  // Note: `columnFields` is broken into two parts to work around a TypeScript bug
117
174
  // that results in broken `.d.ts` output.
118
175
  // See definition of `ColumnInsertableType` below.
@@ -147,10 +204,36 @@ export namespace System_TableSchema {
147
204
  // Will make it easier to evolve this schema in the future.
148
205
  allowUnknownOptionalFields: true,
149
206
  })
150
- implements TableSchema.Column<TPropsSchema> {}
207
+ implements TableSchema.Column<TCellSchema, TPropsSchema>
208
+ {
209
+ public getCells(): {
210
+ rowId: string;
211
+ cell: CellValueType;
212
+ }[] {
213
+ const tableNode = getParentTable(this);
214
+ if (tableNode === undefined) {
215
+ throw new UsageError(`Column with ID "${this.id}" is not contained in a table.`);
216
+ }
217
+
218
+ const result = [];
219
+ for (const row of tableNode.rows) {
220
+ const cell = row.getCell(this.id);
221
+ if (cell !== undefined) {
222
+ if (!Tree.is(cell, cellSchema)) {
223
+ throw new UsageError(
224
+ "Parent table contains a cell with incompatible with this column.",
225
+ );
226
+ }
227
+
228
+ result.push({ rowId: row.id, cell: cell as CellValueType });
229
+ }
230
+ }
231
+ return result;
232
+ }
233
+ }
151
234
 
152
235
  type ColumnValueType = TreeNode &
153
- TableSchema.Column<TPropsSchema> &
236
+ TableSchema.Column<TCellSchema, TPropsSchema> &
154
237
  WithType<ScopedSchemaName<Scope, "Column">>;
155
238
 
156
239
  // Note: ideally this type would just leverage `InsertableObjectFromSchemaRecord<typeof columnFields>`,
@@ -226,8 +309,9 @@ export namespace System_TableSchema {
226
309
  */
227
310
  export type ColumnSchemaBase<
228
311
  TScope extends string | undefined = string | undefined,
312
+ TCellSchema extends ImplicitAllowedTypes = ImplicitAllowedTypes,
229
313
  TPropsSchema extends ImplicitAnnotatedFieldSchema = ImplicitAnnotatedFieldSchema,
230
- > = ReturnType<typeof createColumnSchema<TScope, TPropsSchema>>;
314
+ > = ReturnType<typeof createColumnSchema<TScope, TCellSchema, TPropsSchema>>;
231
315
 
232
316
  // #endregion
233
317
 
@@ -301,13 +385,15 @@ export namespace System_TableSchema {
301
385
  })
302
386
  implements TableSchema.Row<TCellSchema, TPropsSchema>
303
387
  {
304
- public getCell(columnOrId: TableSchema.Column | string): CellValueType | undefined {
388
+ public getCell(
389
+ columnOrId: TableSchema.Column<TCellSchema> | string,
390
+ ): CellValueType | undefined {
305
391
  const columnId = typeof columnOrId === "string" ? columnOrId : columnOrId.id;
306
392
  return this.cells.get(columnId) as CellValueType | undefined;
307
393
  }
308
394
 
309
395
  public setCell(
310
- columnOrId: TableSchema.Column | string,
396
+ columnOrId: TableSchema.Column<TCellSchema> | string,
311
397
  value: CellInsertableType | undefined,
312
398
  ): void {
313
399
  // TODO: throw if column does not exist in the owning table.
@@ -316,7 +402,9 @@ export namespace System_TableSchema {
316
402
  this.cells.set(columnId, value);
317
403
  }
318
404
 
319
- public removeCell(columnOrId: TableSchema.Column | string): CellValueType | undefined {
405
+ public removeCell(
406
+ columnOrId: TableSchema.Column<TCellSchema> | string,
407
+ ): CellValueType | undefined {
320
408
  // TODO: throw if column does not exist in the owning table.
321
409
 
322
410
  const columnId = typeof columnOrId === "string" ? columnOrId : columnOrId.id;
@@ -329,6 +417,22 @@ export namespace System_TableSchema {
329
417
  this.cells.delete(columnId);
330
418
  return cell;
331
419
  }
420
+
421
+ public getCells(): {
422
+ columnId: string;
423
+ cell: CellValueType;
424
+ }[] {
425
+ const result = [];
426
+ for (const [columnId, cell] of this.cells.entries()) {
427
+ if (cell !== undefined) {
428
+ result.push({
429
+ columnId,
430
+ cell,
431
+ });
432
+ }
433
+ }
434
+ return result;
435
+ }
332
436
  }
333
437
 
334
438
  type RowValueType = TreeNode &
@@ -435,7 +539,7 @@ export namespace System_TableSchema {
435
539
  export function createTableSchema<
436
540
  const TInputScope extends string | undefined,
437
541
  const TCellSchema extends ImplicitAllowedTypes,
438
- const TColumnSchema extends ColumnSchemaBase<TInputScope>,
542
+ const TColumnSchema extends ColumnSchemaBase<TInputScope, TCellSchema>,
439
543
  const TRowSchema extends RowSchemaBase<TInputScope, TCellSchema>,
440
544
  >(
441
545
  inputSchemaFactory: SchemaFactoryAlpha<TInputScope>,
@@ -468,8 +572,14 @@ export namespace System_TableSchema {
468
572
  // Will make it easier to evolve this schema in the future.
469
573
  allowUnknownOptionalFields: true,
470
574
  })
471
- implements TableSchema.Table<TCellSchema, TColumnSchema, TRowSchema>
575
+ implements TableSchema.Table<TInputScope, TCellSchema, TColumnSchema, TRowSchema>
472
576
  {
577
+ public static empty<TThis extends TableConstructorType>(
578
+ this: TThis,
579
+ ): InstanceType<TThis> {
580
+ return new this({ columns: [], rows: [] }) as InstanceType<TThis>;
581
+ }
582
+
473
583
  public getColumn(id: string): ColumnValueType | undefined {
474
584
  // TypeScript is unable to narrow the types correctly here, hence the casts.
475
585
  // See: https://github.com/microsoft/TypeScript/issues/52144
@@ -518,27 +628,11 @@ export namespace System_TableSchema {
518
628
  columns,
519
629
  index,
520
630
  }: TableSchema.InsertColumnsParameters<TColumnSchema>): ColumnValueType[] {
521
- // #region Input validation
522
-
523
631
  // Ensure index is valid
524
632
  if (index !== undefined) {
525
633
  Table.validateInsertionIndex(index, this.columns);
526
634
  }
527
635
 
528
- // Check all of the columns being inserted an ensure the table does not already contain any with the same ID.
529
- for (const column of columns) {
530
- // TypeScript is unable to narrow the type of the column type correctly here, hence the casts below.
531
- // See: https://github.com/microsoft/TypeScript/issues/52144
532
- const maybeId = (column as ColumnValueType).id;
533
- if (maybeId !== undefined && this.containsColumnWithId(maybeId)) {
534
- throw new UsageError(
535
- `A column with ID "${(column as ColumnValueType).id}" already exists in the table.`,
536
- );
537
- }
538
- }
539
-
540
- // #endregion
541
-
542
636
  // TypeScript is unable to narrow the column type correctly here, hence the casts below.
543
637
  // See: https://github.com/microsoft/TypeScript/issues/52144
544
638
  if (index === undefined) {
@@ -578,14 +672,6 @@ export namespace System_TableSchema {
578
672
  // Note: TypeScript is unable to narrow the type of the row type correctly here, hence the casts below.
579
673
  // See: https://github.com/microsoft/TypeScript/issues/52144
580
674
  for (const newRow of rows) {
581
- // Check all of the rows being inserted an ensure the table does not already contain any with the same ID.
582
- const maybeId = (newRow as RowValueType).id;
583
- if (maybeId !== undefined && this.containsRowWithId(maybeId)) {
584
- throw new UsageError(
585
- `A row with ID "${(newRow as RowValueType).id}" already exists in the table.`,
586
- );
587
- }
588
-
589
675
  // If the row contains cells, verify that the table contains the columns for those cells.
590
676
  // Note: we intentionally hide `cells` on `IRow` to avoid leaking the internal data representation as much as possible, so we have to cast here.
591
677
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -781,15 +867,19 @@ export namespace System_TableSchema {
781
867
  // TypeScript is unable to narrow the types correctly here, hence the cast.
782
868
  // See: https://github.com/microsoft/TypeScript/issues/52144
783
869
  return (
784
- this.columns.find((column) => (column as TableSchema.Column).id === columnId) !==
785
- undefined
870
+ this.columns.find(
871
+ (column) => (column as TableSchema.Column<TCellSchema>).id === columnId,
872
+ ) !== undefined
786
873
  );
787
874
  }
788
875
 
789
876
  private containsRowWithId(rowId: string): boolean {
790
877
  // TypeScript is unable to narrow the types correctly here, hence the cast.
791
878
  // See: https://github.com/microsoft/TypeScript/issues/52144
792
- return this.rows.find((row) => (row as TableSchema.Row).id === rowId) !== undefined;
879
+ return (
880
+ this.rows.find((row) => (row as TableSchema.Row<TCellSchema>).id === rowId) !==
881
+ undefined
882
+ );
793
883
  }
794
884
 
795
885
  /**
@@ -814,10 +904,18 @@ export namespace System_TableSchema {
814
904
  }
815
905
  }
816
906
 
907
+ // Set a private symbol on the schema class that marks it as having been generated by this factory.
908
+ // Column / Row functionality use this to validate that they are being used in a table.
909
+ // This is effectively a work-around that allows columns and rows to invoke table methods
910
+ // without having to pass the table as a parameter to their construction, which isn't possible.
911
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
912
+ (Table as any)[tableSchemaSymbol] = true;
913
+
817
914
  type TableValueType = TreeNode &
818
- TableSchema.Table<TCellSchema, TColumnSchema, TRowSchema> &
915
+ TableSchema.Table<TInputScope, TCellSchema, TColumnSchema, TRowSchema> &
819
916
  WithType<ScopedSchemaName<Scope, "Table">>;
820
917
  type TableInsertableType = InsertableObjectFromSchemaRecord<typeof tableFields>;
918
+ type TableConstructorType = new (data: TableInsertableType) => TableValueType;
821
919
 
822
920
  // Returning SingletonSchema without a type conversion results in TypeScript generating something like `readonly "__#124291@#brand": unknown;`
823
921
  // for the private brand field of TreeNode.
@@ -831,7 +929,12 @@ export namespace System_TableSchema {
831
929
  /* TInsertable */ object & TableInsertableType,
832
930
  /* ImplicitlyConstructable */ true,
833
931
  /* Info */ typeof tableFields
834
- > = Table;
932
+ > & {
933
+ /**
934
+ * Create an empty table.
935
+ */
936
+ empty<TThis extends TableConstructorType>(this: TThis): InstanceType<TThis>;
937
+ } = Table;
835
938
 
836
939
  // Return the table schema
837
940
  return TableSchemaType;
@@ -844,7 +947,7 @@ export namespace System_TableSchema {
844
947
  export type TableSchemaBase<
845
948
  TScope extends string | undefined,
846
949
  TCell extends ImplicitAllowedTypes,
847
- TColumn extends ColumnSchemaBase<TScope>,
950
+ TColumn extends ColumnSchemaBase<TScope, TCell>,
848
951
  TRow extends RowSchemaBase<TScope, TCell>,
849
952
  > = ReturnType<typeof createTableSchema<TScope, TCell, TColumn, TRow>>;
850
953
 
@@ -909,6 +1012,7 @@ export namespace System_TableSchema {
909
1012
  *
910
1013
  * class Column extends TableSchema.column({
911
1014
  * schemaFactory,
1015
+ * cell: Cell,
912
1016
  * props: ColumnProps,
913
1017
  * }) {}
914
1018
  *
@@ -946,9 +1050,12 @@ export namespace TableSchema {
946
1050
  /**
947
1051
  * A column in a table.
948
1052
  * @remarks Implemented by the schema class returned from {@link TableSchema.(column:2)}.
1053
+ * @typeParam TCell - The type of the cells in the {@link TableSchema.Table}.
1054
+ * @typeParam TProps - Additional properties to associate with the column.
949
1055
  * @sealed @internal
950
1056
  */
951
1057
  export interface Column<
1058
+ TCell extends ImplicitAllowedTypes,
952
1059
  TProps extends ImplicitAnnotatedFieldSchema = ImplicitAnnotatedFieldSchema,
953
1060
  > {
954
1061
  /**
@@ -968,40 +1075,59 @@ export namespace TableSchema {
968
1075
  set props(value: InsertableTreeFieldFromImplicitField<
969
1076
  UnannotateImplicitFieldSchema<TProps>
970
1077
  >);
1078
+
1079
+ /**
1080
+ * Gets all of the populated cells in the column, keyed by their associated row IDs.
1081
+ * @throws Throws an error if the column is not in a table.
1082
+ */
1083
+ getCells(): readonly {
1084
+ rowId: string;
1085
+ cell: TreeNodeFromImplicitAllowedTypes<TCell>;
1086
+ }[];
971
1087
  }
972
1088
 
973
1089
  /**
974
1090
  * Factory for creating new table column schema.
1091
+ * @typeParam TScope - The {@link SchemaFactory.scope | schema factory scope}.
1092
+ * @typeParam TCell - The type of the cells in the {@link TableSchema.Table}.
975
1093
  * @internal
976
1094
  */
977
- export function column<const TScope extends string | undefined>(
978
- params: System_TableSchema.CreateColumnOptionsBase<SchemaFactoryAlpha<TScope>>,
979
- ): System_TableSchema.ColumnSchemaBase<TScope, System_TableSchema.DefaultPropsType>;
1095
+ export function column<
1096
+ const TScope extends string | undefined,
1097
+ const TCell extends ImplicitAllowedTypes,
1098
+ >(
1099
+ params: System_TableSchema.CreateColumnOptionsBase<SchemaFactoryAlpha<TScope>, TCell>,
1100
+ ): System_TableSchema.ColumnSchemaBase<TScope, TCell, System_TableSchema.DefaultPropsType>;
980
1101
  /**
981
1102
  * Factory for creating new table column schema.
1103
+ * @typeParam TScope - The {@link SchemaFactory.scope | schema factory scope}.
1104
+ * @typeParam TCell - The type of the cells in the {@link TableSchema.Table}.
1105
+ * @typeParam TProps - Additional properties to associate with the column.
982
1106
  * @internal
983
1107
  */
984
1108
  export function column<
985
1109
  const TScope extends string | undefined,
1110
+ const TCell extends ImplicitAllowedTypes,
986
1111
  const TProps extends ImplicitAnnotatedFieldSchema,
987
1112
  >(
988
- params: System_TableSchema.CreateColumnOptionsBase<SchemaFactoryAlpha<TScope>> & {
1113
+ params: System_TableSchema.CreateColumnOptionsBase<SchemaFactoryAlpha<TScope>, TCell> & {
989
1114
  /**
990
1115
  * Optional column properties.
991
1116
  */
992
1117
  readonly props: TProps;
993
1118
  },
994
- ): System_TableSchema.ColumnSchemaBase<TScope, TProps>;
1119
+ ): System_TableSchema.ColumnSchemaBase<TScope, TCell, TProps>;
995
1120
  /**
996
1121
  * Overload implementation
997
1122
  */
998
1123
  export function column({
999
1124
  schemaFactory,
1125
+ cell,
1000
1126
  props = SchemaFactory.optional(SchemaFactory.null),
1001
1127
  }: System_TableSchema.CreateColumnOptionsBase & {
1002
1128
  readonly props?: ImplicitAnnotatedFieldSchema;
1003
1129
  }): TreeNodeSchema {
1004
- return System_TableSchema.createColumnSchema(schemaFactory, props);
1130
+ return System_TableSchema.createColumnSchema(schemaFactory, cell, props);
1005
1131
  }
1006
1132
 
1007
1133
  // #endregion
@@ -1010,11 +1136,13 @@ export namespace TableSchema {
1010
1136
 
1011
1137
  /**
1012
1138
  * A row in a table.
1013
- * @remarks Implemented by the schema class returned from {@link TableSchema.(createRow:2)}.
1139
+ * @remarks Implemented by the schema class returned from {@link TableSchema.(row:2)}.
1140
+ * @typeParam TCell - The type of the cells in the {@link TableSchema.Table}.
1141
+ * @typeParam TProps - Additional properties to associate with the row.
1014
1142
  * @sealed @internal
1015
1143
  */
1016
1144
  export interface Row<
1017
- TCell extends ImplicitAllowedTypes = ImplicitAllowedTypes,
1145
+ TCell extends ImplicitAllowedTypes,
1018
1146
  TProps extends ImplicitAnnotatedFieldSchema = ImplicitAnnotatedFieldSchema,
1019
1147
  > {
1020
1148
  /**
@@ -1028,19 +1156,30 @@ export namespace TableSchema {
1028
1156
  * @returns The cell if it exists, otherwise undefined.
1029
1157
  * @privateRemarks TODO: throw if the column does not belong to the same table as the row.
1030
1158
  */
1031
- getCell(column: Column): TreeNodeFromImplicitAllowedTypes<TCell> | undefined;
1159
+ getCell(column: Column<TCell>): TreeNodeFromImplicitAllowedTypes<TCell> | undefined;
1032
1160
  /**
1033
1161
  * Gets the cell in the specified column, denoted by column ID.
1034
1162
  * @returns The cell if it exists, otherwise undefined.
1035
1163
  */
1036
1164
  getCell(columnId: string): TreeNodeFromImplicitAllowedTypes<TCell> | undefined;
1037
1165
 
1166
+ /**
1167
+ * Gets all of the populated cells in the row, keyed by their associated column IDs.
1168
+ */
1169
+ getCells(): readonly {
1170
+ columnId: string;
1171
+ cell: TreeNodeFromImplicitAllowedTypes<TCell>;
1172
+ }[];
1173
+
1038
1174
  /**
1039
1175
  * Sets the cell in the specified column.
1040
1176
  * @remarks To remove a cell, call {@link TableSchema.Row.(removeCell:1)} instead.
1041
1177
  * @privateRemarks TODO: Throw an error if the column does not exist in the table.
1042
1178
  */
1043
- setCell(column: Column, value: InsertableTreeNodeFromImplicitAllowedTypes<TCell>): void;
1179
+ setCell(
1180
+ column: Column<TCell>,
1181
+ value: InsertableTreeNodeFromImplicitAllowedTypes<TCell>,
1182
+ ): void;
1044
1183
  /**
1045
1184
  * Sets the cell in the specified column, denoted by column ID.
1046
1185
  * @remarks To remove a cell, call {@link TableSchema.Row.(removeCell:2)} instead.
@@ -1052,7 +1191,7 @@ export namespace TableSchema {
1052
1191
  * @returns The cell if it exists, otherwise undefined.
1053
1192
  * @privateRemarks TODO: Throw if the column does not belong to the same table as the row.
1054
1193
  */
1055
- removeCell(column: Column): TreeNodeFromImplicitAllowedTypes<TCell> | undefined;
1194
+ removeCell(column: Column<TCell>): TreeNodeFromImplicitAllowedTypes<TCell> | undefined;
1056
1195
  /**
1057
1196
  * Removes the cell in the specified column, denoted by column ID.
1058
1197
  * @returns The cell if it exists, otherwise undefined.
@@ -1074,6 +1213,8 @@ export namespace TableSchema {
1074
1213
 
1075
1214
  /**
1076
1215
  * Factory for creating new table column schema.
1216
+ * @typeParam TScope - The {@link SchemaFactory.scope | schema factory scope}.
1217
+ * @typeParam TCell - The type of the cells in the {@link TableSchema.Table}.
1077
1218
  * @internal
1078
1219
  */
1079
1220
  export function row<
@@ -1084,6 +1225,9 @@ export namespace TableSchema {
1084
1225
  ): System_TableSchema.RowSchemaBase<TScope, TCell, System_TableSchema.DefaultPropsType>;
1085
1226
  /**
1086
1227
  * Factory for creating new table row schema.
1228
+ * @typeParam TScope - The {@link SchemaFactory.scope | schema factory scope}.
1229
+ * @typeParam TCell - The type of the cells in the {@link TableSchema.Table}.
1230
+ * @typeParam TProps - Additional properties to associate with the row.
1087
1231
  * @internal
1088
1232
  */
1089
1233
  export function row<
@@ -1224,12 +1368,17 @@ export namespace TableSchema {
1224
1368
 
1225
1369
  /**
1226
1370
  * A table.
1371
+ * @typeParam TScope - The {@link SchemaFactory.scope | schema factory scope}.
1372
+ * @typeParam TCell - The type of the cells in the table.
1373
+ * @typeParam TColumn - The type of the columns in the table.
1374
+ * @typeParam TRow - The type of the rows in the table.
1227
1375
  * @sealed @internal
1228
1376
  */
1229
1377
  export interface Table<
1378
+ TScope extends string | undefined,
1230
1379
  TCell extends ImplicitAllowedTypes,
1231
- TColumn extends ImplicitAllowedTypes,
1232
- TRow extends ImplicitAllowedTypes,
1380
+ TColumn extends System_TableSchema.ColumnSchemaBase<TScope, TCell>,
1381
+ TRow extends System_TableSchema.RowSchemaBase<TScope, TCell>,
1233
1382
  > {
1234
1383
  /**
1235
1384
  * The table's columns.
@@ -1260,14 +1409,9 @@ export namespace TableSchema {
1260
1409
  /**
1261
1410
  * Inserts a column into the table.
1262
1411
  *
1263
- * @throws
1264
- * Throws an error in the following cases:
1265
- *
1266
- * - The column, or a column with the same ID is already in the tree.
1412
+ * @throws Throws an error if the specified index is out of range.
1267
1413
  *
1268
- * - The specified index is out of range.
1269
- *
1270
- * No column is inserted in these cases.
1414
+ * No column is inserted in this case.
1271
1415
  */
1272
1416
  insertColumn(
1273
1417
  params: InsertColumnParameters<TColumn>,
@@ -1276,14 +1420,9 @@ export namespace TableSchema {
1276
1420
  /**
1277
1421
  * Inserts 0 or more columns into the table.
1278
1422
  *
1279
- * @throws
1280
- * Throws an error in the following cases:
1281
- *
1282
- * - At least one column, or a column with the same ID is already in the tree.
1283
- *
1284
- * - The specified index is out of range.
1423
+ * @throws Throws an error if the specified index is out of range.
1285
1424
  *
1286
- * No columns are inserted in these cases.
1425
+ * No columns are inserted in this case.
1287
1426
  */
1288
1427
  insertColumns(
1289
1428
  params: InsertColumnsParameters<TColumn>,
@@ -1295,8 +1434,6 @@ export namespace TableSchema {
1295
1434
  * @throws
1296
1435
  * Throws an error in the following cases:
1297
1436
  *
1298
- * - The row, or a row with the same ID is already in the tree.
1299
- *
1300
1437
  * - The row contains cells, but the table does not contain matching columns for one or more of those cells.
1301
1438
  *
1302
1439
  * - The specified index is out of range.
@@ -1311,8 +1448,6 @@ export namespace TableSchema {
1311
1448
  * @throws
1312
1449
  * Throws an error in the following cases:
1313
1450
  *
1314
- * - At least one row, or a row with the same ID is already in the tree.
1315
- *
1316
1451
  * - The row contains cells, but the table does not contain matching columns for one or more of those cells.
1317
1452
  *
1318
1453
  * - The specified index is out of range.
@@ -1418,7 +1553,9 @@ export namespace TableSchema {
1418
1553
  }
1419
1554
 
1420
1555
  /**
1421
- * Factory for creating new table schema without specifying row or column schema.
1556
+ * Factory for creating new table schema.
1557
+ * @typeParam TScope - The {@link SchemaFactory.scope | schema factory scope}.
1558
+ * @typeParam TCell - The type of the cells in the table.
1422
1559
  * @internal
1423
1560
  */
1424
1561
  export function table<
@@ -1429,17 +1566,20 @@ export namespace TableSchema {
1429
1566
  ): System_TableSchema.TableSchemaBase<
1430
1567
  TScope,
1431
1568
  TCell,
1432
- System_TableSchema.ColumnSchemaBase<TScope, System_TableSchema.DefaultPropsType>,
1569
+ System_TableSchema.ColumnSchemaBase<TScope, TCell, System_TableSchema.DefaultPropsType>,
1433
1570
  System_TableSchema.RowSchemaBase<TScope, TCell, System_TableSchema.DefaultPropsType>
1434
1571
  >;
1435
1572
  /**
1436
- * Factory for creating new table schema without specifying row schema.
1573
+ * Factory for creating new table schema with custom column schema.
1574
+ * @typeParam TScope - The {@link SchemaFactory.scope | schema factory scope}.
1575
+ * @typeParam TCell - The type of the cells in the table.
1576
+ * @typeParam TColumn - The type of the columns in the table.
1437
1577
  * @internal
1438
1578
  */
1439
1579
  export function table<
1440
1580
  const TScope extends string | undefined,
1441
1581
  const TCell extends ImplicitAllowedTypes,
1442
- const TColumn extends System_TableSchema.ColumnSchemaBase<TScope>,
1582
+ const TColumn extends System_TableSchema.ColumnSchemaBase<TScope, TCell>,
1443
1583
  >(
1444
1584
  params: System_TableSchema.TableFactoryOptionsBase<SchemaFactoryAlpha<TScope>, TCell> & {
1445
1585
  readonly column: TColumn;
@@ -1451,13 +1591,38 @@ export namespace TableSchema {
1451
1591
  System_TableSchema.RowSchemaBase<TScope, TCell, System_TableSchema.DefaultPropsType>
1452
1592
  >;
1453
1593
  /**
1454
- * Factory for creating new table schema.
1594
+ * Factory for creating new table schema with custom row schema.
1595
+ * @typeParam TScope - The {@link SchemaFactory.scope | schema factory scope}.
1596
+ * @typeParam TCell - The type of the cells in the table.
1597
+ * @typeParam TRow - The type of the rows in the table.
1455
1598
  * @internal
1456
1599
  */
1457
1600
  export function table<
1458
1601
  const TScope extends string | undefined,
1459
1602
  const TCell extends ImplicitAllowedTypes,
1460
- const TColumn extends System_TableSchema.ColumnSchemaBase<TScope>,
1603
+ const TRow extends System_TableSchema.RowSchemaBase<TScope, TCell>,
1604
+ >(
1605
+ params: System_TableSchema.TableFactoryOptionsBase<SchemaFactoryAlpha<TScope>, TCell> & {
1606
+ readonly row: TRow;
1607
+ },
1608
+ ): System_TableSchema.TableSchemaBase<
1609
+ TScope,
1610
+ TCell,
1611
+ System_TableSchema.ColumnSchemaBase<TScope, TCell, System_TableSchema.DefaultPropsType>,
1612
+ TRow
1613
+ >;
1614
+ /**
1615
+ * Factory for creating new table schema with custom column and row schema.
1616
+ * @typeParam TScope - The {@link SchemaFactory.scope | schema factory scope}.
1617
+ * @typeParam TCell - The type of the cells in the table.
1618
+ * @typeParam TColumn - The type of the columns in the table.
1619
+ * @typeParam TRow - The type of the rows in the table.
1620
+ * @internal
1621
+ */
1622
+ export function table<
1623
+ const TScope extends string | undefined,
1624
+ const TCell extends ImplicitAllowedTypes,
1625
+ const TColumn extends System_TableSchema.ColumnSchemaBase<TScope, TCell>,
1461
1626
  const TRow extends System_TableSchema.RowSchemaBase<TScope, TCell>,
1462
1627
  >(
1463
1628
  params: System_TableSchema.TableFactoryOptionsBase<SchemaFactoryAlpha<TScope>, TCell> & {
@@ -1473,6 +1638,7 @@ export namespace TableSchema {
1473
1638
  cell: cellSchema,
1474
1639
  column: columnSchema = column({
1475
1640
  schemaFactory,
1641
+ cell: cellSchema,
1476
1642
  }),
1477
1643
  row: rowSchema = row({
1478
1644
  schemaFactory,