@fluidframework/tree 2.31.0 → 2.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/settings.json +1 -1
- package/CHANGELOG.md +44 -0
- package/api-extractor/api-extractor.current.json +5 -1
- package/api-report/tree.alpha.api.md +44 -20
- package/dist/alpha.d.ts +6 -2
- package/dist/feature-libraries/flex-tree/context.d.ts +1 -1
- package/dist/feature-libraries/flex-tree/context.d.ts.map +1 -1
- package/dist/feature-libraries/flex-tree/context.js +1 -2
- package/dist/feature-libraries/flex-tree/context.js.map +1 -1
- package/dist/feature-libraries/flex-tree/index.d.ts +1 -1
- package/dist/feature-libraries/flex-tree/index.d.ts.map +1 -1
- package/dist/feature-libraries/flex-tree/index.js +1 -2
- package/dist/feature-libraries/flex-tree/index.js.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyEntity.d.ts +6 -15
- package/dist/feature-libraries/flex-tree/lazyEntity.d.ts.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyEntity.js +9 -18
- package/dist/feature-libraries/flex-tree/lazyEntity.js.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyField.d.ts +3 -3
- package/dist/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyField.js +14 -14
- package/dist/feature-libraries/flex-tree/lazyField.js.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyNode.d.ts +4 -4
- package/dist/feature-libraries/flex-tree/lazyNode.d.ts.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyNode.js +12 -12
- package/dist/feature-libraries/flex-tree/lazyNode.js.map +1 -1
- package/dist/feature-libraries/index.d.ts +1 -1
- package/dist/feature-libraries/index.d.ts.map +1 -1
- package/dist/feature-libraries/index.js +1 -2
- package/dist/feature-libraries/index.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/shared-tree/sharedTree.js +2 -2
- package/dist/shared-tree/sharedTree.js.map +1 -1
- package/dist/shared-tree/treeApiAlpha.d.ts +6 -6
- package/dist/shared-tree/treeApiAlpha.d.ts.map +1 -1
- package/dist/shared-tree/treeApiAlpha.js.map +1 -1
- package/dist/shared-tree-core/sharedTreeCore.d.ts +0 -6
- package/dist/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
- package/dist/shared-tree-core/sharedTreeCore.js +0 -17
- package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/dist/simple-tree/api/conciseTree.d.ts +2 -2
- package/dist/simple-tree/api/conciseTree.d.ts.map +1 -1
- package/dist/simple-tree/api/conciseTree.js.map +1 -1
- package/dist/simple-tree/api/customTree.d.ts +14 -12
- package/dist/simple-tree/api/customTree.d.ts.map +1 -1
- package/dist/simple-tree/api/customTree.js.map +1 -1
- package/dist/simple-tree/api/getJsonSchema.d.ts +21 -7
- package/dist/simple-tree/api/getJsonSchema.d.ts.map +1 -1
- package/dist/simple-tree/api/getJsonSchema.js +8 -16
- package/dist/simple-tree/api/getJsonSchema.js.map +1 -1
- package/dist/simple-tree/api/getSimpleSchema.d.ts +3 -10
- package/dist/simple-tree/api/getSimpleSchema.d.ts.map +1 -1
- package/dist/simple-tree/api/getSimpleSchema.js +4 -16
- package/dist/simple-tree/api/getSimpleSchema.js.map +1 -1
- package/dist/simple-tree/api/index.d.ts +4 -3
- package/dist/simple-tree/api/index.d.ts.map +1 -1
- package/dist/simple-tree/api/index.js +2 -1
- package/dist/simple-tree/api/index.js.map +1 -1
- package/dist/simple-tree/api/schemaFactoryAlpha.d.ts +17 -1
- package/dist/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -1
- package/dist/simple-tree/api/schemaFactoryAlpha.js +4 -0
- package/dist/simple-tree/api/schemaFactoryAlpha.js.map +1 -1
- package/dist/simple-tree/api/schemaFromSimple.d.ts +5 -2
- package/dist/simple-tree/api/schemaFromSimple.d.ts.map +1 -1
- package/dist/simple-tree/api/schemaFromSimple.js +24 -8
- package/dist/simple-tree/api/schemaFromSimple.js.map +1 -1
- package/dist/simple-tree/api/simpleSchemaToJsonSchema.d.ts +11 -3
- package/dist/simple-tree/api/simpleSchemaToJsonSchema.d.ts.map +1 -1
- package/dist/simple-tree/api/simpleSchemaToJsonSchema.js +40 -28
- package/dist/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
- package/dist/simple-tree/api/tree.d.ts +32 -5
- package/dist/simple-tree/api/tree.d.ts.map +1 -1
- package/dist/simple-tree/api/tree.js +17 -1
- package/dist/simple-tree/api/tree.js.map +1 -1
- package/dist/simple-tree/api/verboseTree.d.ts +4 -28
- package/dist/simple-tree/api/verboseTree.d.ts.map +1 -1
- package/dist/simple-tree/api/verboseTree.js.map +1 -1
- package/dist/simple-tree/api/viewSchemaToSimpleSchema.d.ts.map +1 -1
- package/dist/simple-tree/api/viewSchemaToSimpleSchema.js +7 -3
- package/dist/simple-tree/api/viewSchemaToSimpleSchema.js.map +1 -1
- package/dist/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
- package/dist/simple-tree/core/treeNodeKernel.js +7 -6
- package/dist/simple-tree/core/treeNodeKernel.js.map +1 -1
- package/dist/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
- package/dist/simple-tree/core/unhydratedFlexTree.js +12 -1
- package/dist/simple-tree/core/unhydratedFlexTree.js.map +1 -1
- package/dist/simple-tree/index.d.ts +1 -1
- package/dist/simple-tree/index.d.ts.map +1 -1
- package/dist/simple-tree/index.js +3 -2
- package/dist/simple-tree/index.js.map +1 -1
- package/dist/simple-tree/simpleSchema.d.ts +4 -11
- package/dist/simple-tree/simpleSchema.d.ts.map +1 -1
- package/dist/simple-tree/simpleSchema.js.map +1 -1
- package/dist/tableSchema.d.ts +227 -0
- package/dist/tableSchema.d.ts.map +1 -0
- package/dist/tableSchema.js +234 -0
- package/dist/tableSchema.js.map +1 -0
- package/dist/treeFactory.d.ts +4 -4
- package/dist/treeFactory.d.ts.map +1 -1
- package/dist/treeFactory.js.map +1 -1
- package/dist/util/breakable.d.ts.map +1 -1
- package/dist/util/breakable.js +9 -7
- package/dist/util/breakable.js.map +1 -1
- package/lib/alpha.d.ts +6 -2
- package/lib/feature-libraries/flex-tree/context.d.ts +1 -1
- package/lib/feature-libraries/flex-tree/context.d.ts.map +1 -1
- package/lib/feature-libraries/flex-tree/context.js +1 -2
- package/lib/feature-libraries/flex-tree/context.js.map +1 -1
- package/lib/feature-libraries/flex-tree/index.d.ts +1 -1
- package/lib/feature-libraries/flex-tree/index.d.ts.map +1 -1
- package/lib/feature-libraries/flex-tree/index.js +1 -1
- package/lib/feature-libraries/flex-tree/index.js.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyEntity.d.ts +6 -15
- package/lib/feature-libraries/flex-tree/lazyEntity.d.ts.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyEntity.js +8 -17
- package/lib/feature-libraries/flex-tree/lazyEntity.js.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyField.d.ts +3 -3
- package/lib/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyField.js +15 -15
- package/lib/feature-libraries/flex-tree/lazyField.js.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyNode.d.ts +4 -4
- package/lib/feature-libraries/flex-tree/lazyNode.d.ts.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyNode.js +13 -13
- package/lib/feature-libraries/flex-tree/lazyNode.js.map +1 -1
- package/lib/feature-libraries/index.d.ts +1 -1
- package/lib/feature-libraries/index.d.ts.map +1 -1
- package/lib/feature-libraries/index.js +1 -1
- package/lib/feature-libraries/index.js.map +1 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -1
- package/lib/index.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/shared-tree/sharedTree.js +2 -2
- package/lib/shared-tree/sharedTree.js.map +1 -1
- package/lib/shared-tree/treeApiAlpha.d.ts +6 -6
- package/lib/shared-tree/treeApiAlpha.d.ts.map +1 -1
- package/lib/shared-tree/treeApiAlpha.js.map +1 -1
- package/lib/shared-tree-core/sharedTreeCore.d.ts +0 -6
- package/lib/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
- package/lib/shared-tree-core/sharedTreeCore.js +0 -17
- package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/lib/simple-tree/api/conciseTree.d.ts +2 -2
- package/lib/simple-tree/api/conciseTree.d.ts.map +1 -1
- package/lib/simple-tree/api/conciseTree.js.map +1 -1
- package/lib/simple-tree/api/customTree.d.ts +14 -12
- package/lib/simple-tree/api/customTree.d.ts.map +1 -1
- package/lib/simple-tree/api/customTree.js.map +1 -1
- package/lib/simple-tree/api/getJsonSchema.d.ts +21 -7
- package/lib/simple-tree/api/getJsonSchema.d.ts.map +1 -1
- package/lib/simple-tree/api/getJsonSchema.js +8 -16
- package/lib/simple-tree/api/getJsonSchema.js.map +1 -1
- package/lib/simple-tree/api/getSimpleSchema.d.ts +3 -10
- package/lib/simple-tree/api/getSimpleSchema.d.ts.map +1 -1
- package/lib/simple-tree/api/getSimpleSchema.js +4 -16
- package/lib/simple-tree/api/getSimpleSchema.js.map +1 -1
- package/lib/simple-tree/api/index.d.ts +4 -3
- package/lib/simple-tree/api/index.d.ts.map +1 -1
- package/lib/simple-tree/api/index.js +1 -1
- package/lib/simple-tree/api/index.js.map +1 -1
- package/lib/simple-tree/api/schemaFactoryAlpha.d.ts +17 -1
- package/lib/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -1
- package/lib/simple-tree/api/schemaFactoryAlpha.js +4 -0
- package/lib/simple-tree/api/schemaFactoryAlpha.js.map +1 -1
- package/lib/simple-tree/api/schemaFromSimple.d.ts +5 -2
- package/lib/simple-tree/api/schemaFromSimple.d.ts.map +1 -1
- package/lib/simple-tree/api/schemaFromSimple.js +24 -8
- package/lib/simple-tree/api/schemaFromSimple.js.map +1 -1
- package/lib/simple-tree/api/simpleSchemaToJsonSchema.d.ts +11 -3
- package/lib/simple-tree/api/simpleSchemaToJsonSchema.d.ts.map +1 -1
- package/lib/simple-tree/api/simpleSchemaToJsonSchema.js +41 -29
- package/lib/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
- package/lib/simple-tree/api/tree.d.ts +32 -5
- package/lib/simple-tree/api/tree.d.ts.map +1 -1
- package/lib/simple-tree/api/tree.js +16 -1
- package/lib/simple-tree/api/tree.js.map +1 -1
- package/lib/simple-tree/api/verboseTree.d.ts +4 -28
- package/lib/simple-tree/api/verboseTree.d.ts.map +1 -1
- package/lib/simple-tree/api/verboseTree.js.map +1 -1
- package/lib/simple-tree/api/viewSchemaToSimpleSchema.d.ts.map +1 -1
- package/lib/simple-tree/api/viewSchemaToSimpleSchema.js +7 -3
- package/lib/simple-tree/api/viewSchemaToSimpleSchema.js.map +1 -1
- package/lib/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
- package/lib/simple-tree/core/treeNodeKernel.js +8 -7
- package/lib/simple-tree/core/treeNodeKernel.js.map +1 -1
- package/lib/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
- package/lib/simple-tree/core/unhydratedFlexTree.js +12 -1
- package/lib/simple-tree/core/unhydratedFlexTree.js.map +1 -1
- package/lib/simple-tree/index.d.ts +1 -1
- package/lib/simple-tree/index.d.ts.map +1 -1
- package/lib/simple-tree/index.js +1 -1
- package/lib/simple-tree/index.js.map +1 -1
- package/lib/simple-tree/simpleSchema.d.ts +4 -11
- package/lib/simple-tree/simpleSchema.d.ts.map +1 -1
- package/lib/simple-tree/simpleSchema.js.map +1 -1
- package/lib/tableSchema.d.ts +227 -0
- package/lib/tableSchema.d.ts.map +1 -0
- package/lib/tableSchema.js +231 -0
- package/lib/tableSchema.js.map +1 -0
- package/lib/treeFactory.d.ts +4 -4
- package/lib/treeFactory.d.ts.map +1 -1
- package/lib/treeFactory.js.map +1 -1
- package/lib/util/breakable.d.ts.map +1 -1
- package/lib/util/breakable.js +9 -7
- package/lib/util/breakable.js.map +1 -1
- package/package.json +25 -37
- package/src/feature-libraries/flex-tree/context.ts +2 -2
- package/src/feature-libraries/flex-tree/index.ts +0 -1
- package/src/feature-libraries/flex-tree/lazyEntity.ts +11 -21
- package/src/feature-libraries/flex-tree/lazyField.ts +17 -26
- package/src/feature-libraries/flex-tree/lazyNode.ts +13 -19
- package/src/feature-libraries/index.ts +0 -1
- package/src/index.ts +6 -2
- package/src/packageVersion.ts +1 -1
- package/src/shared-tree/sharedTree.ts +2 -2
- package/src/shared-tree/treeApiAlpha.ts +17 -15
- package/src/shared-tree-core/sharedTreeCore.ts +0 -23
- package/src/simple-tree/api/conciseTree.ts +4 -4
- package/src/simple-tree/api/customTree.ts +16 -14
- package/src/simple-tree/api/getJsonSchema.ts +25 -16
- package/src/simple-tree/api/getSimpleSchema.ts +4 -18
- package/src/simple-tree/api/index.ts +4 -2
- package/src/simple-tree/api/schemaFactoryAlpha.ts +18 -1
- package/src/simple-tree/api/schemaFromSimple.ts +45 -16
- package/src/simple-tree/api/simpleSchemaToJsonSchema.ts +53 -34
- package/src/simple-tree/api/tree.ts +51 -4
- package/src/simple-tree/api/verboseTree.ts +7 -32
- package/src/simple-tree/api/viewSchemaToSimpleSchema.ts +8 -3
- package/src/simple-tree/core/treeNodeKernel.ts +11 -7
- package/src/simple-tree/core/unhydratedFlexTree.ts +17 -4
- package/src/simple-tree/index.ts +4 -2
- package/src/simple-tree/simpleSchema.ts +4 -12
- package/src/tableSchema.ts +609 -0
- package/src/treeFactory.ts +4 -3
- package/src/util/breakable.ts +9 -6
|
@@ -0,0 +1,609 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { oob } from "@fluidframework/core-utils/internal";
|
|
7
|
+
|
|
8
|
+
import { Tree } from "./shared-tree/index.js";
|
|
9
|
+
import {
|
|
10
|
+
type ImplicitAllowedTypes,
|
|
11
|
+
type ImplicitFieldSchema,
|
|
12
|
+
type InsertableObjectFromSchemaRecord,
|
|
13
|
+
type InsertableTreeNodeFromImplicitAllowedTypes,
|
|
14
|
+
type NodeKind,
|
|
15
|
+
type SchemaFactoryAlpha,
|
|
16
|
+
type ScopedSchemaName,
|
|
17
|
+
TreeArrayNode,
|
|
18
|
+
type TreeNode,
|
|
19
|
+
type TreeNodeFromImplicitAllowedTypes,
|
|
20
|
+
type TreeNodeSchemaClass,
|
|
21
|
+
type WithType,
|
|
22
|
+
} from "./simple-tree/index.js";
|
|
23
|
+
|
|
24
|
+
// Future improvement TODOs (ideally to be done before promoting these APIs to `@alpha`):
|
|
25
|
+
// - Custom fields on Table/Row/Column (props pattern from Nick's demo)
|
|
26
|
+
// - Overloads to make Column/Row schema optional when constructing Tables
|
|
27
|
+
// - Record-like type parameters / input parameters?
|
|
28
|
+
// - Move `@system` types into separate / sub scope?
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Contains types and factories for creating schema to represent dynamic tabular data.
|
|
32
|
+
* @privateRemarks TODO: document in more detail and add `@example`s.
|
|
33
|
+
* @internal
|
|
34
|
+
*/
|
|
35
|
+
export namespace TableSchema {
|
|
36
|
+
const tableSchemaFactorySubScope = "table";
|
|
37
|
+
|
|
38
|
+
// #region Column
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* A column in a table.
|
|
42
|
+
* @remarks Implemented by the schema class returned from {@link TableSchema.createColumn}.
|
|
43
|
+
* @sealed @internal
|
|
44
|
+
*/
|
|
45
|
+
export interface IColumn {
|
|
46
|
+
/**
|
|
47
|
+
* The unique identifier of the column.
|
|
48
|
+
* @remarks Uniquely identifies the node within the entire tree, not just the table.
|
|
49
|
+
*/
|
|
50
|
+
readonly id: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Factory for creating new table column schema.
|
|
55
|
+
* @internal
|
|
56
|
+
*/
|
|
57
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type -- Return type is too complex to be reasonable to specify
|
|
58
|
+
export function createColumn<const TInputScope extends string | undefined>(
|
|
59
|
+
inputSchemaFactory: SchemaFactoryAlpha<TInputScope>,
|
|
60
|
+
) {
|
|
61
|
+
const schemaFactory = inputSchemaFactory.scopedFactory(tableSchemaFactorySubScope);
|
|
62
|
+
type Scope = ScopedSchemaName<TInputScope, typeof tableSchemaFactorySubScope>;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* {@link Column} fields.
|
|
66
|
+
* @remarks Extracted for re-use in returned type signature defined later in this function.
|
|
67
|
+
* The implicit typing is intentional.
|
|
68
|
+
*/
|
|
69
|
+
const columnFields = {
|
|
70
|
+
id: schemaFactory.identifier,
|
|
71
|
+
} as const satisfies Record<string, ImplicitFieldSchema>;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* A column in a table.
|
|
75
|
+
*/
|
|
76
|
+
class Column extends schemaFactory.object("Column", columnFields) implements IColumn {}
|
|
77
|
+
|
|
78
|
+
type ColumnValueType = TreeNode & IColumn & WithType<ScopedSchemaName<Scope, "Column">>;
|
|
79
|
+
type ColumnInsertableType = InsertableObjectFromSchemaRecord<typeof columnFields>;
|
|
80
|
+
|
|
81
|
+
// Returning SingletonSchema without a type conversion results in TypeScript generating something like `readonly "__#124291@#brand": unknown;`
|
|
82
|
+
// for the private brand field of TreeNode.
|
|
83
|
+
// This numeric id doesn't seem to be stable over incremental builds, and thus causes diffs in the API extractor reports.
|
|
84
|
+
// This is avoided by doing this type conversion.
|
|
85
|
+
// The conversion is done via assignment instead of `as` to get stronger type safety.
|
|
86
|
+
const ColumnSchemaType: TreeNodeSchemaClass<
|
|
87
|
+
/* Name */ ScopedSchemaName<Scope, "Column">,
|
|
88
|
+
/* Kind */ NodeKind.Object,
|
|
89
|
+
/* TNode */ ColumnValueType,
|
|
90
|
+
/* TInsertable */ object & ColumnInsertableType,
|
|
91
|
+
/* ImplicitlyConstructable */ true,
|
|
92
|
+
/* Info */ typeof columnFields
|
|
93
|
+
> = Column;
|
|
94
|
+
|
|
95
|
+
return ColumnSchemaType;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Base column schema type.
|
|
100
|
+
* @sealed @system @internal
|
|
101
|
+
*/
|
|
102
|
+
export type ColumnSchemaBase<TScope extends string | undefined> = ReturnType<
|
|
103
|
+
typeof createColumn<TScope>
|
|
104
|
+
>;
|
|
105
|
+
|
|
106
|
+
// #endregion
|
|
107
|
+
|
|
108
|
+
// #region Row
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* A row in a table.
|
|
112
|
+
* @remarks Implemented by the schema class returned from {@link TableSchema.createRow}.
|
|
113
|
+
* @sealed @internal
|
|
114
|
+
*/
|
|
115
|
+
export interface IRow<
|
|
116
|
+
TCellSchema extends ImplicitAllowedTypes,
|
|
117
|
+
TColumnSchema extends ImplicitAllowedTypes,
|
|
118
|
+
> {
|
|
119
|
+
/**
|
|
120
|
+
* The unique identifier of the row.
|
|
121
|
+
* @remarks Uniquely identifies the node within the entire tree, not just the table.
|
|
122
|
+
*/
|
|
123
|
+
readonly id: string;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Gets the cell in the specified column
|
|
127
|
+
* @returns The cell if it exists, otherwise undefined.
|
|
128
|
+
* @privateRemarks TODO: add overload that takes column ID.
|
|
129
|
+
*/
|
|
130
|
+
getCell(
|
|
131
|
+
column: TreeNodeFromImplicitAllowedTypes<TColumnSchema>,
|
|
132
|
+
): TreeNodeFromImplicitAllowedTypes<TCellSchema> | undefined;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Sets the cell in the specified column.
|
|
136
|
+
* @remarks To delete a cell, call {@link TableSchema.IRow.deleteCell} instead.
|
|
137
|
+
* @privateRemarks TODO: add overload that takes column ID.
|
|
138
|
+
*/
|
|
139
|
+
setCell(
|
|
140
|
+
column: TreeNodeFromImplicitAllowedTypes<TColumnSchema>,
|
|
141
|
+
value: InsertableTreeNodeFromImplicitAllowedTypes<TCellSchema>,
|
|
142
|
+
): void;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Deletes the cell in the specified column.
|
|
146
|
+
* @privateRemarks TODO: add overload that takes column ID.
|
|
147
|
+
*/
|
|
148
|
+
deleteCell(column: TreeNodeFromImplicitAllowedTypes<TColumnSchema>): void;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Factory for creating new table row schema.
|
|
153
|
+
* @privateRemarks TODO: add overloads to make column schema optional.
|
|
154
|
+
* @sealed @internal
|
|
155
|
+
*/
|
|
156
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type -- Return type is too complex to be reasonable to specify
|
|
157
|
+
export function createRow<
|
|
158
|
+
const TInputScope extends string | undefined,
|
|
159
|
+
const TCellSchema extends ImplicitAllowedTypes,
|
|
160
|
+
const TColumnSchema extends ColumnSchemaBase<TInputScope> = ColumnSchemaBase<TInputScope>,
|
|
161
|
+
>(
|
|
162
|
+
inputSchemaFactory: SchemaFactoryAlpha<TInputScope>,
|
|
163
|
+
cellSchema: TCellSchema,
|
|
164
|
+
_columnSchema: TColumnSchema,
|
|
165
|
+
) {
|
|
166
|
+
const schemaFactory = inputSchemaFactory.scopedFactory(tableSchemaFactorySubScope);
|
|
167
|
+
type Scope = ScopedSchemaName<TInputScope, typeof tableSchemaFactorySubScope>;
|
|
168
|
+
|
|
169
|
+
type CellValueType = TreeNodeFromImplicitAllowedTypes<TCellSchema>;
|
|
170
|
+
type CellInsertableType = InsertableTreeNodeFromImplicitAllowedTypes<TCellSchema>;
|
|
171
|
+
|
|
172
|
+
type ColumnValueType = TreeNodeFromImplicitAllowedTypes<TColumnSchema>;
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* {@link Row} fields.
|
|
176
|
+
* @remarks Extracted for re-use in returned type signature defined later in this function.
|
|
177
|
+
* The implicit typing is intentional.
|
|
178
|
+
*/
|
|
179
|
+
const rowFields = {
|
|
180
|
+
id: schemaFactory.identifier,
|
|
181
|
+
cells: schemaFactory.map("Row.cells", cellSchema),
|
|
182
|
+
} as const satisfies Record<string, ImplicitFieldSchema>;
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* The Row schema - this is a map of Cells where the key is the column id
|
|
186
|
+
*/
|
|
187
|
+
class Row
|
|
188
|
+
extends schemaFactory.object("Row", rowFields)
|
|
189
|
+
implements IRow<TCellSchema, TColumnSchema>
|
|
190
|
+
{
|
|
191
|
+
public getCell(column: ColumnValueType): CellValueType | undefined {
|
|
192
|
+
return this.cells.get(column.id) as CellValueType | undefined;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
public setCell(column: ColumnValueType, value: CellInsertableType | undefined): void {
|
|
196
|
+
this.cells.set(column.id, value);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
public deleteCell(column: ColumnValueType): void {
|
|
200
|
+
if (!this.cells.has(column.id)) return;
|
|
201
|
+
this.cells.delete(column.id);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
type RowValueType = TreeNode &
|
|
206
|
+
IRow<TCellSchema, TColumnSchema> &
|
|
207
|
+
WithType<ScopedSchemaName<Scope, "Row">>;
|
|
208
|
+
type RowInsertableType = InsertableObjectFromSchemaRecord<typeof rowFields>;
|
|
209
|
+
|
|
210
|
+
// Returning SingletonSchema without a type conversion results in TypeScript generating something like `readonly "__#124291@#brand": unknown;`
|
|
211
|
+
// for the private brand field of TreeNode.
|
|
212
|
+
// This numeric id doesn't seem to be stable over incremental builds, and thus causes diffs in the API extractor reports.
|
|
213
|
+
// This is avoided by doing this type conversion.
|
|
214
|
+
// The conversion is done via assignment instead of `as` to get stronger type safety.
|
|
215
|
+
const RowSchemaType: TreeNodeSchemaClass<
|
|
216
|
+
/* Name */ ScopedSchemaName<Scope, "Row">,
|
|
217
|
+
/* Kind */ NodeKind.Object,
|
|
218
|
+
/* TNode */ RowValueType,
|
|
219
|
+
/* TInsertable */ object & RowInsertableType,
|
|
220
|
+
/* ImplicitlyConstructable */ true,
|
|
221
|
+
/* Info */ typeof rowFields
|
|
222
|
+
> = Row;
|
|
223
|
+
|
|
224
|
+
return RowSchemaType;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Base row schema type.
|
|
229
|
+
* @sealed @system @internal
|
|
230
|
+
*/
|
|
231
|
+
export type RowSchemaBase<
|
|
232
|
+
TScope extends string | undefined,
|
|
233
|
+
TCellSchema extends ImplicitAllowedTypes,
|
|
234
|
+
TColumnSchema extends ColumnSchemaBase<TScope> = ColumnSchemaBase<TScope>,
|
|
235
|
+
> = ReturnType<typeof createRow<TScope, TCellSchema, TColumnSchema>>;
|
|
236
|
+
|
|
237
|
+
// #endregion
|
|
238
|
+
|
|
239
|
+
// #region Table
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* A key to uniquely identify a cell in a table.
|
|
243
|
+
* @sealed @internal
|
|
244
|
+
*/
|
|
245
|
+
export interface CellKey {
|
|
246
|
+
/**
|
|
247
|
+
* {@link TableSchema.IColumn.id} of the containing {@link TableSchema.IColumn}.
|
|
248
|
+
*/
|
|
249
|
+
readonly columnId: string;
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* {@link TableSchema.IRow.id} of the containing {@link TableSchema.IRow}.
|
|
253
|
+
*/
|
|
254
|
+
readonly rowId: string;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* {@link TableSchema.ITable.insertColumn} parameters.
|
|
259
|
+
* @sealed @internal
|
|
260
|
+
*/
|
|
261
|
+
export interface InsertColumnParameters<TInsertableColumn> {
|
|
262
|
+
/**
|
|
263
|
+
* The index at which to insert the new column.
|
|
264
|
+
* @remarks If not provided, the column will be appended to the end of the table.
|
|
265
|
+
*/
|
|
266
|
+
readonly index?: number | undefined;
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* The column to insert.
|
|
270
|
+
*/
|
|
271
|
+
readonly column: TInsertableColumn;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* {@link TableSchema.ITable.insertRows} parameters.
|
|
276
|
+
* @sealed @internal
|
|
277
|
+
*/
|
|
278
|
+
export interface InsertRowsParameters<TInsertableRow> {
|
|
279
|
+
/**
|
|
280
|
+
* The index at which to insert the new rows.
|
|
281
|
+
* @remarks If not provided, the rows will be appended to the end of the table.
|
|
282
|
+
*/
|
|
283
|
+
readonly index?: number | undefined;
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* The rows to insert.
|
|
287
|
+
*/
|
|
288
|
+
readonly rows: TInsertableRow[];
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* {@link TableSchema.ITable.setCell} parameters.
|
|
293
|
+
* @sealed @internal
|
|
294
|
+
*/
|
|
295
|
+
export interface SetCellParameters<TInsertableCell> {
|
|
296
|
+
/**
|
|
297
|
+
* The key to uniquely identify a cell in a table.
|
|
298
|
+
*/
|
|
299
|
+
readonly key: CellKey;
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* The cell to set.
|
|
303
|
+
*/
|
|
304
|
+
readonly cell: TInsertableCell;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* A table.
|
|
309
|
+
* @sealed @internal
|
|
310
|
+
*/
|
|
311
|
+
export interface ITable<
|
|
312
|
+
TCellSchema extends ImplicitAllowedTypes,
|
|
313
|
+
TColumnSchema extends ImplicitAllowedTypes,
|
|
314
|
+
TRowSchema extends ImplicitAllowedTypes,
|
|
315
|
+
> {
|
|
316
|
+
/**
|
|
317
|
+
* The table's columns.
|
|
318
|
+
*/
|
|
319
|
+
readonly columns: TreeArrayNode<TColumnSchema>;
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* The table's rows.
|
|
323
|
+
*/
|
|
324
|
+
readonly rows: TreeArrayNode<TRowSchema>;
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Gets a table column by its {@link TableSchema.IRow.id}.
|
|
328
|
+
*/
|
|
329
|
+
getColumn(id: string): TreeNodeFromImplicitAllowedTypes<TColumnSchema> | undefined;
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Gets a table row by its {@link TableSchema.IRow.id}.
|
|
333
|
+
*/
|
|
334
|
+
getRow(id: string): TreeNodeFromImplicitAllowedTypes<TRowSchema> | undefined;
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Gets a cell in the table by column and row IDs.
|
|
338
|
+
* @param key - A key that uniquely distinguishes a cell in the table, represented as a combination of the column ID and row ID.
|
|
339
|
+
* @privateRemarks TODO: add overload that takes row and column nodes.
|
|
340
|
+
*/
|
|
341
|
+
getCell(key: CellKey): TreeNodeFromImplicitAllowedTypes<TCellSchema> | undefined;
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Inserts a column into the table.
|
|
345
|
+
* @throws Throws an error if the column is already in the tree, or if the specified index is out of range.
|
|
346
|
+
*/
|
|
347
|
+
insertColumn(
|
|
348
|
+
params: InsertColumnParameters<
|
|
349
|
+
InsertableTreeNodeFromImplicitAllowedTypes<TColumnSchema>
|
|
350
|
+
>,
|
|
351
|
+
): TreeNodeFromImplicitAllowedTypes<TColumnSchema>;
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Inserts 0 or more rows into the table.
|
|
355
|
+
* @throws Throws an error if any of the rows are already in the tree, or if the specified index is out of range.
|
|
356
|
+
*/
|
|
357
|
+
insertRows(
|
|
358
|
+
params: InsertRowsParameters<InsertableTreeNodeFromImplicitAllowedTypes<TRowSchema>>,
|
|
359
|
+
): TreeNodeFromImplicitAllowedTypes<TRowSchema>[];
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Sets the cell at the specified location in the table.
|
|
363
|
+
* @remarks To delete a cell, call {@link TableSchema.ITable.deleteCell} instead.
|
|
364
|
+
* @privateRemarks TODO: add overload that takes column/row nodes?
|
|
365
|
+
*/
|
|
366
|
+
setCell(
|
|
367
|
+
params: SetCellParameters<InsertableTreeNodeFromImplicitAllowedTypes<TCellSchema>>,
|
|
368
|
+
): void;
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Removes the specified column from the table.
|
|
372
|
+
* @remarks Note: this does not remove any cells from the table's rows.
|
|
373
|
+
* @privateRemarks
|
|
374
|
+
* TODO:
|
|
375
|
+
* - Policy for when the column is not in the table.
|
|
376
|
+
* - Actually remove corresponding cells from table rows.
|
|
377
|
+
*/
|
|
378
|
+
removeColumn: (column: TreeNodeFromImplicitAllowedTypes<TColumnSchema>) => void;
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Deletes 0 or more rows from the table.
|
|
382
|
+
* @privateRemarks TODO: policy for when 1 or more rows are not in the table.
|
|
383
|
+
*/
|
|
384
|
+
deleteRows: (rows: readonly TreeNodeFromImplicitAllowedTypes<TRowSchema>[]) => void;
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Deletes all rows from the table.
|
|
388
|
+
*/
|
|
389
|
+
deleteAllRows: () => void;
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Deletes the cell at the specified location in the table.
|
|
393
|
+
* @privateRemarks TODO: add overload that takes column/row nodes?
|
|
394
|
+
*/
|
|
395
|
+
deleteCell: (key: CellKey) => void;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Factory for creating new table schema.
|
|
400
|
+
* @privateRemarks TODO: add overloads to make column/row schema optional.
|
|
401
|
+
* @internal
|
|
402
|
+
*/
|
|
403
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type -- Return type is too complex to be reasonable to specify
|
|
404
|
+
export function createTable<
|
|
405
|
+
const TInputScope extends string | undefined,
|
|
406
|
+
const TCell extends ImplicitAllowedTypes,
|
|
407
|
+
const TColumn extends ColumnSchemaBase<TInputScope> = ColumnSchemaBase<TInputScope>,
|
|
408
|
+
const TRow extends RowSchemaBase<TInputScope, TCell, TColumn> = RowSchemaBase<
|
|
409
|
+
TInputScope,
|
|
410
|
+
TCell,
|
|
411
|
+
TColumn
|
|
412
|
+
>,
|
|
413
|
+
>(
|
|
414
|
+
inputSchemaFactory: SchemaFactoryAlpha<TInputScope>,
|
|
415
|
+
_cellSchema: TCell,
|
|
416
|
+
columnSchema: TColumn,
|
|
417
|
+
rowSchema: TRow,
|
|
418
|
+
) {
|
|
419
|
+
const schemaFactory = inputSchemaFactory.scopedFactory(tableSchemaFactorySubScope);
|
|
420
|
+
type Scope = ScopedSchemaName<TInputScope, typeof tableSchemaFactorySubScope>;
|
|
421
|
+
|
|
422
|
+
type CellValueType = TreeNodeFromImplicitAllowedTypes<TCell>;
|
|
423
|
+
type CellInsertableType = InsertableTreeNodeFromImplicitAllowedTypes<TCell>;
|
|
424
|
+
|
|
425
|
+
type ColumnValueType = TreeNodeFromImplicitAllowedTypes<TColumn>;
|
|
426
|
+
type ColumnInsertableType = InsertableTreeNodeFromImplicitAllowedTypes<TColumn>;
|
|
427
|
+
|
|
428
|
+
type RowValueType = TreeNodeFromImplicitAllowedTypes<TRow>;
|
|
429
|
+
type RowInsertableType = InsertableTreeNodeFromImplicitAllowedTypes<TRow>;
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* {@link Table} fields.
|
|
433
|
+
* @remarks Extracted for re-use in returned type signature defined later in this function.
|
|
434
|
+
* The implicit typing is intentional.
|
|
435
|
+
*/
|
|
436
|
+
const tableFields = {
|
|
437
|
+
rows: schemaFactory.array("Table.rows", rowSchema),
|
|
438
|
+
columns: schemaFactory.array("Table.columns", columnSchema),
|
|
439
|
+
} as const satisfies Record<string, ImplicitFieldSchema>;
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* The Table schema
|
|
443
|
+
*/
|
|
444
|
+
class Table
|
|
445
|
+
extends schemaFactory.object("Table", tableFields)
|
|
446
|
+
implements ITable<TCell, TColumn, TRow>
|
|
447
|
+
{
|
|
448
|
+
public getColumn(id: string): ColumnValueType | undefined {
|
|
449
|
+
// TypeScript is unable to narrow the types correctly here, hence the casts.
|
|
450
|
+
// See: https://github.com/microsoft/TypeScript/issues/52144
|
|
451
|
+
return this.columns.find((column) => (column as ColumnValueType).id === id) as
|
|
452
|
+
| ColumnValueType
|
|
453
|
+
| undefined;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
public getRow(id: string): RowValueType | undefined {
|
|
457
|
+
// TypeScript is unable to narrow the types correctly here, hence the casts.
|
|
458
|
+
// See: https://github.com/microsoft/TypeScript/issues/52144
|
|
459
|
+
return this.rows.find((_row) => (_row as RowValueType).id === id) as
|
|
460
|
+
| RowValueType
|
|
461
|
+
| undefined;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
public getCell(key: CellKey): CellValueType | undefined {
|
|
465
|
+
const { columnId, rowId } = key;
|
|
466
|
+
const row = this.getRow(rowId);
|
|
467
|
+
if (row !== undefined) {
|
|
468
|
+
const column = this.getColumn(columnId);
|
|
469
|
+
if (column !== undefined) {
|
|
470
|
+
return row.getCell(column);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
// If the cell does not exist return undefined
|
|
474
|
+
return undefined;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
public insertColumn({
|
|
478
|
+
column,
|
|
479
|
+
index,
|
|
480
|
+
}: InsertColumnParameters<ColumnInsertableType>): ColumnValueType {
|
|
481
|
+
if (index === undefined) {
|
|
482
|
+
// TypeScript is unable to narrow the types correctly here, hence the cast.
|
|
483
|
+
// See: https://github.com/microsoft/TypeScript/issues/52144
|
|
484
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
485
|
+
this.columns.insertAtEnd(column as any);
|
|
486
|
+
} else {
|
|
487
|
+
// TypeScript is unable to narrow the types correctly here, hence the cast.
|
|
488
|
+
// See: https://github.com/microsoft/TypeScript/issues/52144
|
|
489
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
490
|
+
this.columns.insertAt(index, column as any);
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
// Inserting the input node into the tree hydrates it, making it usable as a node.
|
|
494
|
+
return column as ColumnValueType;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
public insertRows({
|
|
498
|
+
index,
|
|
499
|
+
rows,
|
|
500
|
+
}: InsertRowsParameters<RowInsertableType>): RowValueType[] {
|
|
501
|
+
if (index === undefined) {
|
|
502
|
+
// TypeScript is unable to narrow the types correctly here, hence the cast.
|
|
503
|
+
// See: https://github.com/microsoft/TypeScript/issues/52144
|
|
504
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
505
|
+
this.rows.insertAtEnd(TreeArrayNode.spread(rows) as any);
|
|
506
|
+
} else {
|
|
507
|
+
// TypeScript is unable to narrow the types correctly here, hence the cast.
|
|
508
|
+
// See: https://github.com/microsoft/TypeScript/issues/52144
|
|
509
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
510
|
+
this.rows.insertAt(index, TreeArrayNode.spread(rows) as any);
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
// Inserting the input nodes into the tree hydrates them, making them usable as nodes.
|
|
514
|
+
return rows as unknown as RowValueType[];
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
public setCell({ key, cell }: SetCellParameters<CellInsertableType>): void {
|
|
518
|
+
const { columnId, rowId } = key;
|
|
519
|
+
const row = this.getRow(rowId);
|
|
520
|
+
if (row !== undefined) {
|
|
521
|
+
const column = this.getColumn(columnId);
|
|
522
|
+
if (column !== undefined) {
|
|
523
|
+
row.setCell(column, cell);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
public removeColumn(column: ColumnValueType): void {
|
|
529
|
+
const index = this.columns.indexOf(column);
|
|
530
|
+
// If the column is not in the table, do nothing
|
|
531
|
+
if (index === -1) return;
|
|
532
|
+
this.columns.removeAt(index);
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
public deleteRows(rows: readonly RowValueType[]): void {
|
|
536
|
+
// If there are no rows to delete, do nothing
|
|
537
|
+
if (rows.length === 0) {
|
|
538
|
+
return;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// If there is only one row to delete, delete it
|
|
542
|
+
if (rows.length === 1) {
|
|
543
|
+
const index = this.rows.indexOf(rows[0] ?? oob());
|
|
544
|
+
this.rows.removeAt(index);
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
547
|
+
// If there are multiple rows to delete, delete them in a transaction
|
|
548
|
+
// This is to avoid the performance issues of deleting multiple rows at once
|
|
549
|
+
Tree.runTransaction(this, () => {
|
|
550
|
+
// Iterate over the rows and delete them
|
|
551
|
+
for (const row of rows) {
|
|
552
|
+
const index = this.rows.indexOf(row);
|
|
553
|
+
this.rows.removeAt(index);
|
|
554
|
+
}
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
public deleteAllRows(): void {
|
|
559
|
+
this.rows.removeRange();
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
public deleteCell(key: CellKey): void {
|
|
563
|
+
const { columnId, rowId } = key;
|
|
564
|
+
const row = this.getRow(rowId);
|
|
565
|
+
if (row !== undefined) {
|
|
566
|
+
const column = this.getColumn(columnId);
|
|
567
|
+
if (column !== undefined) {
|
|
568
|
+
row.deleteCell(column);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
type TableValueType = TreeNode &
|
|
575
|
+
ITable<TCell, TColumn, TRow> &
|
|
576
|
+
WithType<ScopedSchemaName<Scope, "Table">>;
|
|
577
|
+
type TableInsertableType = InsertableObjectFromSchemaRecord<typeof tableFields>;
|
|
578
|
+
|
|
579
|
+
// Returning SingletonSchema without a type conversion results in TypeScript generating something like `readonly "__#124291@#brand": unknown;`
|
|
580
|
+
// for the private brand field of TreeNode.
|
|
581
|
+
// This numeric id doesn't seem to be stable over incremental builds, and thus causes diffs in the API extractor reports.
|
|
582
|
+
// This is avoided by doing this type conversion.
|
|
583
|
+
// The conversion is done via assignment instead of `as` to get stronger type safety.
|
|
584
|
+
const TableSchemaType: TreeNodeSchemaClass<
|
|
585
|
+
/* Name */ ScopedSchemaName<Scope, "Table">,
|
|
586
|
+
/* Kind */ NodeKind.Object,
|
|
587
|
+
/* TNode */ TableValueType,
|
|
588
|
+
/* TInsertable */ object & TableInsertableType,
|
|
589
|
+
/* ImplicitlyConstructable */ true,
|
|
590
|
+
/* Info */ typeof tableFields
|
|
591
|
+
> = Table;
|
|
592
|
+
|
|
593
|
+
// Return the table schema
|
|
594
|
+
return TableSchemaType;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
/**
|
|
598
|
+
* Base row schema type.
|
|
599
|
+
* @sealed @system @internal
|
|
600
|
+
*/
|
|
601
|
+
export type TableSchemaBase<
|
|
602
|
+
TScope extends string | undefined,
|
|
603
|
+
TCell extends ImplicitAllowedTypes,
|
|
604
|
+
TColumn extends ColumnSchemaBase<TScope> = ColumnSchemaBase<TScope>,
|
|
605
|
+
TRow extends RowSchemaBase<TScope, TCell, TColumn> = RowSchemaBase<TScope, TCell, TColumn>,
|
|
606
|
+
> = ReturnType<typeof createTable<TScope, TCell, TColumn, TRow>>;
|
|
607
|
+
|
|
608
|
+
// #endregion
|
|
609
|
+
}
|
package/src/treeFactory.ts
CHANGED
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
|
|
18
18
|
import {
|
|
19
19
|
SharedTree as SharedTreeImpl,
|
|
20
|
+
type ISharedTree,
|
|
20
21
|
type SharedTreeOptions,
|
|
21
22
|
type SharedTreeOptionsInternal,
|
|
22
23
|
} from "./shared-tree/index.js";
|
|
@@ -27,7 +28,7 @@ import { SharedTreeFactoryType, SharedTreeAttributes } from "./sharedTreeAttribu
|
|
|
27
28
|
/**
|
|
28
29
|
* A channel factory that creates an {@link ITree}.
|
|
29
30
|
*/
|
|
30
|
-
export class TreeFactory implements IChannelFactory<
|
|
31
|
+
export class TreeFactory implements IChannelFactory<ISharedTree> {
|
|
31
32
|
public static Type: string = SharedTreeFactoryType;
|
|
32
33
|
public readonly type: string = SharedTreeFactoryType;
|
|
33
34
|
|
|
@@ -40,13 +41,13 @@ export class TreeFactory implements IChannelFactory<ITree> {
|
|
|
40
41
|
id: string,
|
|
41
42
|
services: IChannelServices,
|
|
42
43
|
channelAttributes: Readonly<IChannelAttributes>,
|
|
43
|
-
): Promise<
|
|
44
|
+
): Promise<ISharedTree> {
|
|
44
45
|
const tree = new SharedTreeImpl(id, runtime, channelAttributes, this.options);
|
|
45
46
|
await tree.load(services);
|
|
46
47
|
return tree;
|
|
47
48
|
}
|
|
48
49
|
|
|
49
|
-
public create(runtime: IFluidDataStoreRuntime, id: string):
|
|
50
|
+
public create(runtime: IFluidDataStoreRuntime, id: string): ISharedTree {
|
|
50
51
|
const tree = new SharedTreeImpl(id, runtime, this.attributes, this.options);
|
|
51
52
|
tree.initializeLocal();
|
|
52
53
|
return tree;
|
package/src/util/breakable.ts
CHANGED
|
@@ -183,17 +183,20 @@ export function breakingClass<Target extends abstract new (...args: any[]) => Wi
|
|
|
183
183
|
target: Target,
|
|
184
184
|
context: ClassDecoratorContext<Target>,
|
|
185
185
|
): Target {
|
|
186
|
-
|
|
186
|
+
// This could extend target, but doing so adds an extra step in the prototype chain and makes the instances just show up as "DecoratedBreakable" in the debugger.
|
|
187
|
+
const DecoratedBreakable = target;
|
|
187
188
|
|
|
188
|
-
// Keep track of what keys we have seen
|
|
189
|
-
//
|
|
190
|
-
|
|
189
|
+
// Keep track of what keys we have seen (and already wrapped if needed).
|
|
190
|
+
// Used to avoid rewrapping already wrapped properties.
|
|
191
|
+
// Preloaded with "constructor" to avoid wrapping the constructor as there is no need to set the broken flag when the constructor throws and does not return an object.
|
|
192
|
+
// Avoiding wrapping the constructor also avoids messing up the displayed name in the debugger.
|
|
193
|
+
const doNotWrap: Set<string | symbol> = new Set(["constructor"]);
|
|
191
194
|
|
|
192
195
|
let prototype: object | null = target.prototype;
|
|
193
196
|
while (prototype !== null) {
|
|
194
197
|
for (const key of Reflect.ownKeys(prototype)) {
|
|
195
|
-
if (!
|
|
196
|
-
|
|
198
|
+
if (!doNotWrap.has(key)) {
|
|
199
|
+
doNotWrap.add(key);
|
|
197
200
|
const descriptor = Reflect.getOwnPropertyDescriptor(prototype, key);
|
|
198
201
|
if (descriptor !== undefined) {
|
|
199
202
|
// Method
|