@fluidframework/tree 2.103.0 → 2.110.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/CHANGELOG.md +61 -0
- package/api-report/tree.alpha.api.md +12 -3
- package/api-report/tree.beta.api.md +11 -3
- package/api-report/tree.legacy.beta.api.md +11 -3
- package/dist/codec/versioned/format.js +2 -24
- package/dist/codec/versioned/format.js.map +1 -1
- package/dist/core/rebase/types.js +2 -24
- package/dist/core/rebase/types.js.map +1 -1
- package/dist/core/schema-stored/formatV1.js +2 -24
- package/dist/core/schema-stored/formatV1.js.map +1 -1
- package/dist/core/schema-stored/formatV2.js +2 -24
- package/dist/core/schema-stored/formatV2.js.map +1 -1
- package/dist/core/schema-stored/index.js +3 -25
- package/dist/core/schema-stored/index.js.map +1 -1
- package/dist/core/tree/anchorSet.js +4 -8
- package/dist/core/tree/anchorSet.js.map +1 -1
- package/dist/core/tree/detachedFieldIndexFormatCommon.js +2 -24
- package/dist/core/tree/detachedFieldIndexFormatCommon.js.map +1 -1
- package/dist/core/tree/detachedFieldIndexFormatV2.js +2 -24
- package/dist/core/tree/detachedFieldIndexFormatV2.js.map +1 -1
- package/dist/core/tree/persistedTreeTextFormat.js +2 -24
- package/dist/core/tree/persistedTreeTextFormat.js.map +1 -1
- package/dist/entrypoints/internal.js +2 -15
- package/dist/entrypoints/internal.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/chunkedForest.js +7 -11
- package/dist/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/format/formatGeneric.js +2 -24
- package/dist/feature-libraries/chunked-forest/codec/format/formatGeneric.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/format/formatV1.js +2 -24
- package/dist/feature-libraries/chunked-forest/codec/format/formatV1.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/format/formatV2.js +2 -24
- package/dist/feature-libraries/chunked-forest/codec/format/formatV2.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/format/formatVText.js +2 -24
- package/dist/feature-libraries/chunked-forest/codec/format/formatVText.js.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyEntity.js +9 -19
- package/dist/feature-libraries/flex-tree/lazyEntity.js.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyNode.js +3 -13
- package/dist/feature-libraries/flex-tree/lazyNode.js.map +1 -1
- package/dist/feature-libraries/forest-summary/formatCommon.js +2 -24
- package/dist/feature-libraries/forest-summary/formatCommon.js.map +1 -1
- package/dist/feature-libraries/index.js +2 -24
- package/dist/feature-libraries/index.js.map +1 -1
- package/dist/feature-libraries/modular-schema/genericFieldKindFormat.js +2 -24
- package/dist/feature-libraries/modular-schema/genericFieldKindFormat.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js +10 -30
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFormatV1.js +2 -24
- package/dist/feature-libraries/modular-schema/modularChangeFormatV1.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFormatV2.js +2 -24
- package/dist/feature-libraries/modular-schema/modularChangeFormatV2.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeTypes.d.ts +0 -5
- package/dist/feature-libraries/modular-schema/modularChangeTypes.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeTypes.js.map +1 -1
- package/dist/feature-libraries/object-forest/objectForest.js +11 -55
- package/dist/feature-libraries/object-forest/objectForest.js.map +1 -1
- package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV1.js +2 -24
- package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV1.js.map +1 -1
- package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV2.js +2 -24
- package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV2.js.map +1 -1
- package/dist/feature-libraries/schema-edits/schemaChangeFormat.js +2 -24
- package/dist/feature-libraries/schema-edits/schemaChangeFormat.js.map +1 -1
- package/dist/feature-libraries/schema-index/formatV1.js +2 -24
- package/dist/feature-libraries/schema-index/formatV1.js.map +1 -1
- package/dist/feature-libraries/schema-index/formatV2.js +2 -24
- package/dist/feature-libraries/schema-index/formatV2.js.map +1 -1
- package/dist/feature-libraries/sequence-field/formatV1.js +2 -24
- package/dist/feature-libraries/sequence-field/formatV1.js.map +1 -1
- package/dist/feature-libraries/sequence-field/formatV2.js +2 -24
- package/dist/feature-libraries/sequence-field/formatV2.js.map +1 -1
- package/dist/feature-libraries/sequence-field/formatV3.js +2 -24
- package/dist/feature-libraries/sequence-field/formatV3.js.map +1 -1
- package/dist/index.js +2 -24
- 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/schematizingTreeView.d.ts +1 -0
- package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
- package/dist/shared-tree/schematizingTreeView.js +7 -41
- package/dist/shared-tree/schematizingTreeView.js.map +1 -1
- package/dist/shared-tree/sharedTree.d.ts +0 -1
- package/dist/shared-tree/sharedTree.d.ts.map +1 -1
- package/dist/shared-tree/sharedTree.js +6 -45
- package/dist/shared-tree/sharedTree.js.map +1 -1
- package/dist/shared-tree/sharedTreeChangeFormat.js +2 -24
- package/dist/shared-tree/sharedTreeChangeFormat.js.map +1 -1
- package/dist/shared-tree/treeCheckout.d.ts +12 -3
- package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
- package/dist/shared-tree/treeCheckout.js +106 -136
- package/dist/shared-tree/treeCheckout.js.map +1 -1
- package/dist/shared-tree-core/branch.js +13 -17
- package/dist/shared-tree-core/branch.js.map +1 -1
- package/dist/shared-tree-core/editManagerFormatCommons.js +2 -24
- package/dist/shared-tree-core/editManagerFormatCommons.js.map +1 -1
- package/dist/shared-tree-core/editManagerFormatV1toV4.js +2 -24
- package/dist/shared-tree-core/editManagerFormatV1toV4.js.map +1 -1
- package/dist/shared-tree-core/editManagerFormatVSharedBranches.js +2 -24
- package/dist/shared-tree-core/editManagerFormatVSharedBranches.js.map +1 -1
- package/dist/shared-tree-core/messageCodecVSharedBranches.js +2 -24
- package/dist/shared-tree-core/messageCodecVSharedBranches.js.map +1 -1
- package/dist/shared-tree-core/messageFormatV1ToV4.js +2 -24
- package/dist/shared-tree-core/messageFormatV1ToV4.js.map +1 -1
- package/dist/shared-tree-core/messageFormatVSharedBranches.js +2 -24
- package/dist/shared-tree-core/messageFormatVSharedBranches.js.map +1 -1
- package/dist/shared-tree-core/sharedTreeCore.js +6 -43
- package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/dist/shared-tree-core/transaction.js +20 -30
- package/dist/shared-tree-core/transaction.js.map +1 -1
- package/dist/simple-tree/api/simpleSchemaCodec.js +2 -24
- package/dist/simple-tree/api/simpleSchemaCodec.js.map +1 -1
- package/dist/simple-tree/api/snapshotCompatibilityChecker.js +2 -24
- package/dist/simple-tree/api/snapshotCompatibilityChecker.js.map +1 -1
- package/dist/simple-tree/api/tree.d.ts +10 -0
- package/dist/simple-tree/api/tree.d.ts.map +1 -1
- package/dist/simple-tree/api/tree.js.map +1 -1
- package/dist/simple-tree/core/treeNodeKernel.js +83 -93
- package/dist/simple-tree/core/treeNodeKernel.js.map +1 -1
- package/dist/simple-tree/core/unhydratedFlexTree.js +6 -10
- package/dist/simple-tree/core/unhydratedFlexTree.js.map +1 -1
- package/dist/simple-tree/leafNodeSchema.js +2 -12
- package/dist/simple-tree/leafNodeSchema.js.map +1 -1
- package/dist/simple-tree/node-kinds/array/arrayNode.js +2 -6
- package/dist/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
- package/dist/simple-tree/simpleSchemaFormatV1.js +2 -24
- package/dist/simple-tree/simpleSchemaFormatV1.js.map +1 -1
- package/dist/tableSchema.d.ts +50 -4
- package/dist/tableSchema.d.ts.map +1 -1
- package/dist/tableSchema.js +202 -106
- package/dist/tableSchema.js.map +1 -1
- package/dist/util/arrayUtilities.d.ts +20 -0
- package/dist/util/arrayUtilities.d.ts.map +1 -1
- package/dist/util/arrayUtilities.js +24 -1
- package/dist/util/arrayUtilities.js.map +1 -1
- package/dist/util/index.d.ts +1 -1
- package/dist/util/index.d.ts.map +1 -1
- package/dist/util/index.js +3 -2
- package/dist/util/index.js.map +1 -1
- package/dist/util/rangeMap.d.ts +13 -0
- package/dist/util/rangeMap.d.ts.map +1 -1
- package/dist/util/rangeMap.js +69 -8
- package/dist/util/rangeMap.js.map +1 -1
- package/dist/util/typeboxBrand.js +2 -24
- package/dist/util/typeboxBrand.js.map +1 -1
- package/dist/util/utils.js +2 -24
- package/dist/util/utils.js.map +1 -1
- package/eslint.config.mts +0 -30
- package/lib/core/tree/anchorSet.js +1 -5
- package/lib/core/tree/anchorSet.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/chunkedForest.js +1 -5
- package/lib/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyEntity.js +1 -11
- package/lib/feature-libraries/flex-tree/lazyEntity.js.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyNode.js +1 -11
- package/lib/feature-libraries/flex-tree/lazyNode.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js +10 -30
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeTypes.d.ts +0 -5
- package/lib/feature-libraries/modular-schema/modularChangeTypes.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeTypes.js.map +1 -1
- package/lib/feature-libraries/object-forest/objectForest.js +1 -45
- package/lib/feature-libraries/object-forest/objectForest.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/schematizingTreeView.d.ts +1 -0
- package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
- package/lib/shared-tree/schematizingTreeView.js +4 -38
- package/lib/shared-tree/schematizingTreeView.js.map +1 -1
- package/lib/shared-tree/sharedTree.d.ts +0 -1
- package/lib/shared-tree/sharedTree.d.ts.map +1 -1
- package/lib/shared-tree/sharedTree.js +1 -40
- package/lib/shared-tree/sharedTree.js.map +1 -1
- package/lib/shared-tree/treeCheckout.d.ts +12 -3
- package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
- package/lib/shared-tree/treeCheckout.js +62 -92
- package/lib/shared-tree/treeCheckout.js.map +1 -1
- package/lib/shared-tree-core/branch.js +1 -5
- package/lib/shared-tree-core/branch.js.map +1 -1
- package/lib/shared-tree-core/sharedTreeCore.js +1 -38
- package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/lib/shared-tree-core/transaction.js +1 -11
- package/lib/shared-tree-core/transaction.js.map +1 -1
- package/lib/simple-tree/api/tree.d.ts +10 -0
- package/lib/simple-tree/api/tree.d.ts.map +1 -1
- package/lib/simple-tree/api/tree.js.map +1 -1
- package/lib/simple-tree/core/treeNodeKernel.js +1 -11
- package/lib/simple-tree/core/treeNodeKernel.js.map +1 -1
- package/lib/simple-tree/core/unhydratedFlexTree.js +1 -5
- package/lib/simple-tree/core/unhydratedFlexTree.js.map +1 -1
- package/lib/simple-tree/leafNodeSchema.js +1 -11
- package/lib/simple-tree/leafNodeSchema.js.map +1 -1
- package/lib/simple-tree/node-kinds/array/arrayNode.js +1 -5
- package/lib/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
- package/lib/tableSchema.d.ts +50 -4
- package/lib/tableSchema.d.ts.map +1 -1
- package/lib/tableSchema.js +171 -75
- package/lib/tableSchema.js.map +1 -1
- package/lib/util/arrayUtilities.d.ts +20 -0
- package/lib/util/arrayUtilities.d.ts.map +1 -1
- package/lib/util/arrayUtilities.js +22 -0
- package/lib/util/arrayUtilities.js.map +1 -1
- package/lib/util/index.d.ts +1 -1
- package/lib/util/index.d.ts.map +1 -1
- package/lib/util/index.js +1 -1
- package/lib/util/index.js.map +1 -1
- package/lib/util/rangeMap.d.ts +13 -0
- package/lib/util/rangeMap.d.ts.map +1 -1
- package/lib/util/rangeMap.js +69 -8
- package/lib/util/rangeMap.js.map +1 -1
- package/package.json +24 -23
- package/src/feature-libraries/modular-schema/modularChangeFamily.ts +14 -47
- package/src/feature-libraries/modular-schema/modularChangeTypes.ts +0 -5
- package/src/packageVersion.ts +1 -1
- package/src/shared-tree/schematizingTreeView.ts +4 -0
- package/src/shared-tree/sharedTree.ts +2 -6
- package/src/shared-tree/treeCheckout.ts +59 -51
- package/src/simple-tree/api/tree.ts +11 -0
- package/src/tableSchema.ts +306 -80
- package/src/util/arrayUtilities.ts +35 -0
- package/src/util/index.ts +2 -0
- package/src/util/rangeMap.ts +108 -9
- package/tsconfig.json +5 -0
package/lib/tableSchema.js
CHANGED
|
@@ -2,23 +2,13 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
8
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
9
|
-
};
|
|
10
|
-
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
11
|
-
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
12
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
13
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
14
|
-
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
15
|
-
};
|
|
16
|
-
import { fail } from "@fluidframework/core-utils/internal";
|
|
5
|
+
import { __classPrivateFieldGet, __classPrivateFieldSet } from "tslib";
|
|
6
|
+
import { assert, fail, oob } from "@fluidframework/core-utils/internal";
|
|
17
7
|
import { UsageError } from "@fluidframework/telemetry-utils/internal";
|
|
18
8
|
import { EmptyKey } from "./core/index.js";
|
|
19
9
|
import { Tree, TreeAlpha } from "./shared-tree/index.js";
|
|
20
10
|
import { TreeArrayNode, SchemaFactory, scoped, withBufferedTreeEvents, objectSchema, eraseSchemaDetailsSubclassable, createCustomizedFluidFrameworkScopedFactory, } from "./simple-tree/index.js";
|
|
21
|
-
import { validateIndex, validateIndexRange } from "./util/index.js";
|
|
11
|
+
import { collectContiguousRanges, validateIndex, validateIndexRange } from "./util/index.js";
|
|
22
12
|
/**
|
|
23
13
|
* Not intended for use outside of this package.
|
|
24
14
|
*
|
|
@@ -147,7 +137,7 @@ export var System_TableSchema;
|
|
|
147
137
|
*/
|
|
148
138
|
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type -- Return type is too complex to be reasonable to specify
|
|
149
139
|
function createTableSchema(inputSchemaFactory, _cellSchema, columnSchema, rowSchema) {
|
|
150
|
-
var _Table_instances, _a, _Table_rowCache, _Table_rowCacheUnsubscribe, _Table_columnCache, _Table_columnCacheUnsubscribe, _Table_applyEditsInBatch, _Table_getColumnCache, _Table_tryGetColumn, _Table_getColumn, _Table_getRowCache, _Table_tryGetRow, _Table_getRow, _Table_validateNewColumns, _Table_validateNewRows;
|
|
140
|
+
var _Table_instances, _a, _Table_rowCache, _Table_rowCacheUnsubscribe, _Table_columnCache, _Table_columnCacheUnsubscribe, _Table_applyEditsInBatch, _Table_buildColumnInDocumentConstraintsForRows, _Table_getColumnCache, _Table_tryGetColumnId, _Table_tryGetColumn, _Table_getColumn, _Table_getRowCache, _Table_tryGetRow, _Table_getRow, _Table_validateNewColumns, _Table_validateNewRows;
|
|
151
141
|
const schemaFactory = createTableScopedFactory(inputSchemaFactory);
|
|
152
142
|
/**
|
|
153
143
|
* {@link Table} inner fields.
|
|
@@ -277,13 +267,27 @@ export var System_TableSchema;
|
|
|
277
267
|
if (row === undefined) {
|
|
278
268
|
return undefined;
|
|
279
269
|
}
|
|
280
|
-
const
|
|
281
|
-
if (
|
|
270
|
+
const columnId = __classPrivateFieldGet(this, _Table_instances, "m", _Table_tryGetColumnId).call(this, columnOrIdOrIndex);
|
|
271
|
+
if (columnId === undefined) {
|
|
282
272
|
return undefined;
|
|
283
273
|
}
|
|
284
|
-
return row.cells[
|
|
274
|
+
return row.cells[columnId];
|
|
285
275
|
}
|
|
286
|
-
insertColumns(
|
|
276
|
+
insertColumns(columnsOrParams, maybeIndex) {
|
|
277
|
+
// Dispatch on the runtime type of the first argument to disambiguate the two overloads:
|
|
278
|
+
// * Array → positional `(columns, index?)` overload
|
|
279
|
+
// * object → deprecated `(params)` property-bag overload
|
|
280
|
+
let index;
|
|
281
|
+
let columns;
|
|
282
|
+
if (Array.isArray(columnsOrParams)) {
|
|
283
|
+
index = maybeIndex;
|
|
284
|
+
columns = columnsOrParams;
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
const params = columnsOrParams;
|
|
288
|
+
index = params.index;
|
|
289
|
+
columns = params.columns;
|
|
290
|
+
}
|
|
287
291
|
// #region Input validation
|
|
288
292
|
// Ensure specified index is valid
|
|
289
293
|
if (index !== undefined) {
|
|
@@ -323,7 +327,21 @@ export var System_TableSchema;
|
|
|
323
327
|
// Inserting the input nodes into the tree hydrates them, making them usable as nodes.
|
|
324
328
|
return columns;
|
|
325
329
|
}
|
|
326
|
-
insertRows(
|
|
330
|
+
insertRows(rowsOrParams, maybeIndex) {
|
|
331
|
+
// Dispatch on the runtime type of the first argument to disambiguate the two overloads:
|
|
332
|
+
// * Array → positional `(rows, index?)` overload
|
|
333
|
+
// * object → deprecated `(params)` property-bag overload
|
|
334
|
+
let index;
|
|
335
|
+
let rows;
|
|
336
|
+
if (Array.isArray(rowsOrParams)) {
|
|
337
|
+
index = maybeIndex;
|
|
338
|
+
rows = rowsOrParams;
|
|
339
|
+
}
|
|
340
|
+
else {
|
|
341
|
+
const params = rowsOrParams;
|
|
342
|
+
index = params.index;
|
|
343
|
+
rows = params.rows;
|
|
344
|
+
}
|
|
327
345
|
// #region Input validation
|
|
328
346
|
// Ensure specified index is valid
|
|
329
347
|
if (index !== undefined) {
|
|
@@ -332,16 +350,14 @@ export var System_TableSchema;
|
|
|
332
350
|
// Ensure the new rows being inserted are valid
|
|
333
351
|
__classPrivateFieldGet(this, _Table_instances, "m", _Table_validateNewRows).call(this, rows);
|
|
334
352
|
// #endregion
|
|
335
|
-
// Relevant invariant: each cell corresponds to an existing row and column
|
|
353
|
+
// Relevant invariant: each cell corresponds to an existing row and column.
|
|
336
354
|
// Prevents cell leaks from concurrently removed columns.
|
|
337
355
|
// Example scenario: Client A removes a column while concurrently Client B adds a row with cells for those columns (including the one A removed).
|
|
338
356
|
// If client B is sequenced after A, then B's row could have cells that do not correspond to existing columns.
|
|
339
|
-
//
|
|
357
|
+
// We only need to constrain columns that the new rows actually reference — a removed column with no
|
|
358
|
+
// corresponding cell in the inserted rows cannot orphan anything from this insertion.
|
|
340
359
|
// TODO: Replace with "no detach" constraint on the column array when available.
|
|
341
|
-
const columnConstraints = this.
|
|
342
|
-
type: "nodeInDocument",
|
|
343
|
-
node: column,
|
|
344
|
-
}));
|
|
360
|
+
const columnConstraints = __classPrivateFieldGet(this, _Table_instances, "m", _Table_buildColumnInDocumentConstraintsForRows).call(this, rows);
|
|
345
361
|
__classPrivateFieldGet(this, _Table_instances, "m", _Table_applyEditsInBatch).call(this, {
|
|
346
362
|
applyEdits: () => {
|
|
347
363
|
// TypeScript is unable to narrow the row type correctly here, hence the casts below.
|
|
@@ -355,13 +371,29 @@ export var System_TableSchema;
|
|
|
355
371
|
this.table.rows.insertAt(index, TreeArrayNode.spread(rows));
|
|
356
372
|
}
|
|
357
373
|
},
|
|
358
|
-
preconditions: columnConstraints
|
|
374
|
+
preconditions: columnConstraints,
|
|
359
375
|
});
|
|
360
376
|
// Inserting the input nodes into the tree hydrates them, making them usable as nodes.
|
|
361
377
|
return rows;
|
|
362
378
|
}
|
|
363
|
-
setCell(
|
|
364
|
-
|
|
379
|
+
setCell(rowOrParams, maybeColumn, maybeCell) {
|
|
380
|
+
// Dispatch on the presence of the second argument to disambiguate the two overloads:
|
|
381
|
+
// * `maybeColumn === undefined` → deprecated `(params)` property-bag overload; unpack from `params.key`/`params.cell`
|
|
382
|
+
// * otherwise → positional `(row, column, cell)` overload
|
|
383
|
+
let rowOrId;
|
|
384
|
+
let columnOrId;
|
|
385
|
+
let cell;
|
|
386
|
+
if (maybeColumn === undefined) {
|
|
387
|
+
const params = rowOrParams;
|
|
388
|
+
rowOrId = params.key.row;
|
|
389
|
+
columnOrId = params.key.column;
|
|
390
|
+
cell = params.cell;
|
|
391
|
+
}
|
|
392
|
+
else {
|
|
393
|
+
rowOrId = rowOrParams;
|
|
394
|
+
columnOrId = maybeColumn;
|
|
395
|
+
cell = maybeCell;
|
|
396
|
+
}
|
|
365
397
|
const row = __classPrivateFieldGet(this, _Table_instances, "m", _Table_getRow).call(this, rowOrId);
|
|
366
398
|
const column = __classPrivateFieldGet(this, _Table_instances, "m", _Table_getColumn).call(this, columnOrId);
|
|
367
399
|
__classPrivateFieldGet(this, _Table_instances, "m", _Table_applyEditsInBatch).call(this, {
|
|
@@ -412,13 +444,15 @@ export var System_TableSchema;
|
|
|
412
444
|
__classPrivateFieldGet(this, _Table_instances, "m", _Table_applyEditsInBatch).call(this, {
|
|
413
445
|
applyEdits: () => {
|
|
414
446
|
const columnsToRemove = this.table.columns.slice(startIndex, endIndex);
|
|
415
|
-
// First, remove all cells that correspond to each column from each row
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
447
|
+
// First, remove all cells that correspond to each column from each row.
|
|
448
|
+
// Rows are the outer loop so each row's `cells` record is touched contiguously,
|
|
449
|
+
// and the per-column `id` values are read once up front instead of per (column, row) pair.
|
|
450
|
+
const idsToDelete = columnsToRemove.map((column) => column.id);
|
|
451
|
+
for (const row of this.table.rows) {
|
|
452
|
+
const cells = row.cells;
|
|
453
|
+
for (const id of idsToDelete) {
|
|
420
454
|
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete -- This is currently how Record node entries are deleted.
|
|
421
|
-
delete
|
|
455
|
+
delete cells[id];
|
|
422
456
|
}
|
|
423
457
|
}
|
|
424
458
|
// Second, remove the column nodes:
|
|
@@ -435,44 +469,45 @@ export var System_TableSchema;
|
|
|
435
469
|
return [];
|
|
436
470
|
}
|
|
437
471
|
// Resolve any IDs to actual nodes.
|
|
438
|
-
// This validates that all of the
|
|
472
|
+
// This validates that all of the columns exist before starting transaction.
|
|
439
473
|
// This improves user-facing error experience.
|
|
440
|
-
|
|
474
|
+
// Set insertion order is preserved on iteration, which matches the caller-supplied order
|
|
475
|
+
// expected by both the cell-deletion loop and the returned array.
|
|
476
|
+
const columnsToRemove = new Set();
|
|
441
477
|
for (const columnOrIdToRemove of indexOrColumns) {
|
|
442
|
-
columnsToRemove.
|
|
478
|
+
columnsToRemove.add(__classPrivateFieldGet(this, _Table_instances, "m", _Table_getColumn).call(this, columnOrIdToRemove));
|
|
443
479
|
}
|
|
480
|
+
// Collect contiguous runs of columns-to-remove as [start, end) ranges so they can be
|
|
481
|
+
// removed via a small number of `removeRange` calls below.
|
|
482
|
+
const ranges = collectContiguousRanges(this.table.columns, (column) => columnsToRemove.has(column));
|
|
483
|
+
// Note, throwing an error within a transaction will abort the entire transaction.
|
|
484
|
+
// So if we throw an error here for any column, no columns will be removed.
|
|
444
485
|
__classPrivateFieldGet(this, _Table_instances, "m", _Table_applyEditsInBatch).call(this, {
|
|
445
486
|
applyEdits: () => {
|
|
446
|
-
//
|
|
447
|
-
//
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
487
|
+
// Remove the corresponding cell from every row.
|
|
488
|
+
// The per-column `id` values are hoisted out of the row loop so each row's `cells`
|
|
489
|
+
// record is indexed by a plain string rather than re-reading a tree-node property.
|
|
490
|
+
const idsToDelete = Array.from(columnsToRemove, (column) => column.id);
|
|
491
|
+
for (const row of this.table.rows) {
|
|
492
|
+
const cells = row.cells;
|
|
493
|
+
for (const id of idsToDelete) {
|
|
453
494
|
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete -- This is currently how Record node entries are deleted.
|
|
454
|
-
delete
|
|
495
|
+
delete cells[id];
|
|
455
496
|
}
|
|
456
|
-
|
|
457
|
-
|
|
497
|
+
}
|
|
498
|
+
// Remove column nodes. Ranges are iterated in reverse so each `removeRange`
|
|
499
|
+
// call doesn't shift the indices of yet-to-remove ranges at lower positions.
|
|
500
|
+
for (let r = ranges.length - 1; r >= 0; r--) {
|
|
501
|
+
const { start, end } = ranges[r] ?? oob();
|
|
502
|
+
this.table.columns.removeRange(start, end);
|
|
458
503
|
}
|
|
459
504
|
},
|
|
460
505
|
preconditions,
|
|
461
506
|
});
|
|
462
|
-
return columnsToRemove;
|
|
507
|
+
return [...columnsToRemove];
|
|
463
508
|
}
|
|
464
509
|
}
|
|
465
510
|
removeRows(indexOrRows, count) {
|
|
466
|
-
// Relevant invariant: each cell corresponds to an existing row and column
|
|
467
|
-
// Adding a constraint on columns here to prevent cells being orphaned. The relevant scenario is:
|
|
468
|
-
// Client A removes rows
|
|
469
|
-
// Client B (either concurrently or not, so long as B's edit is sequenced after A's edit) removes a column,
|
|
470
|
-
// Client A reverts the removal of the rows
|
|
471
|
-
// TODO: Replace with "no detach on revert" constraint on the column array when available.
|
|
472
|
-
const columnConstraints = this.table.columns.map((column) => ({
|
|
473
|
-
type: "nodeInDocument",
|
|
474
|
-
node: column,
|
|
475
|
-
}));
|
|
476
511
|
if (typeof indexOrRows === "number" || indexOrRows === undefined) {
|
|
477
512
|
let removedRows;
|
|
478
513
|
const startIndex = indexOrRows ?? 0;
|
|
@@ -482,11 +517,18 @@ export var System_TableSchema;
|
|
|
482
517
|
return [];
|
|
483
518
|
}
|
|
484
519
|
validateIndexRange(startIndex, endIndex, this.table.rows, "Table.removeRows");
|
|
520
|
+
// Compute revert constraints from the rows being removed.
|
|
521
|
+
const rowsBeingRemoved = this.table.rows.slice(startIndex, endIndex);
|
|
485
522
|
__classPrivateFieldGet(this, _Table_instances, "m", _Table_applyEditsInBatch).call(this, {
|
|
486
523
|
applyEdits: () => {
|
|
487
524
|
removedRows = removeRangeFromArray(startIndex, endIndex, this.table.rows, "Table.removeRows");
|
|
488
525
|
},
|
|
489
|
-
|
|
526
|
+
// Relevant invariant: each cell corresponds to an existing row and column.
|
|
527
|
+
// On revert, the removed rows come back with their original cells, so we need
|
|
528
|
+
// each column referenced by those cells to still exist. Columns the removed rows
|
|
529
|
+
// don't reference cannot be orphaned by the revert and need not be constrained.
|
|
530
|
+
// TODO: Replace with "no detach on revert" constraint on the column array when available.
|
|
531
|
+
preconditionsOnRevert: __classPrivateFieldGet(this, _Table_instances, "m", _Table_buildColumnInDocumentConstraintsForRows).call(this, rowsBeingRemoved),
|
|
490
532
|
});
|
|
491
533
|
return removedRows ?? fail(0xccd /* Transaction did not complete */);
|
|
492
534
|
}
|
|
@@ -497,26 +539,50 @@ export var System_TableSchema;
|
|
|
497
539
|
// Resolve any IDs to actual nodes.
|
|
498
540
|
// This validates that all of the rows exist before starting transaction.
|
|
499
541
|
// This improves user-facing error experience.
|
|
500
|
-
|
|
542
|
+
// Set insertion order is preserved on iteration, which matches the caller-supplied order
|
|
543
|
+
// expected by the returned array.
|
|
544
|
+
const rowsToRemove = new Set();
|
|
501
545
|
for (const rowToRemove of indexOrRows) {
|
|
502
|
-
rowsToRemove.
|
|
546
|
+
rowsToRemove.add(__classPrivateFieldGet(this, _Table_instances, "m", _Table_getRow).call(this, rowToRemove));
|
|
503
547
|
}
|
|
548
|
+
// Collect contiguous runs of rows-to-remove as [start, end) ranges so they can be
|
|
549
|
+
// removed via a small number of `removeRange` calls below.
|
|
550
|
+
const ranges = collectContiguousRanges(this.table.rows, (row) => rowsToRemove.has(row));
|
|
551
|
+
// Note, throwing an error within a transaction will abort the entire transaction.
|
|
552
|
+
// So if we throw an error here for any row, no rows will be removed.
|
|
504
553
|
__classPrivateFieldGet(this, _Table_instances, "m", _Table_applyEditsInBatch).call(this, {
|
|
505
554
|
applyEdits: () => {
|
|
506
|
-
//
|
|
507
|
-
//
|
|
508
|
-
for (
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
this.table.rows.removeAt(index);
|
|
555
|
+
// Ranges are iterated in reverse so each `removeRange` call doesn't shift
|
|
556
|
+
// the indices of yet-to-remove ranges at lower positions.
|
|
557
|
+
for (let r = ranges.length - 1; r >= 0; r--) {
|
|
558
|
+
const { start, end } = ranges[r] ?? oob();
|
|
559
|
+
this.table.rows.removeRange(start, end);
|
|
512
560
|
}
|
|
513
561
|
},
|
|
514
|
-
|
|
562
|
+
// Relevant invariant: each cell corresponds to an existing row and column.
|
|
563
|
+
// On revert, the removed rows come back with their original cells, so we need
|
|
564
|
+
// each column referenced by those cells to still exist. Columns the removed rows
|
|
565
|
+
// don't reference cannot be orphaned by the revert and need not be constrained.
|
|
566
|
+
// TODO: Replace with "no detach on revert" constraint on the column array when available.
|
|
567
|
+
preconditionsOnRevert: __classPrivateFieldGet(this, _Table_instances, "m", _Table_buildColumnInDocumentConstraintsForRows).call(this, rowsToRemove),
|
|
515
568
|
});
|
|
516
|
-
return rowsToRemove;
|
|
569
|
+
return [...rowsToRemove];
|
|
517
570
|
}
|
|
518
|
-
removeCell(
|
|
519
|
-
|
|
571
|
+
removeCell(rowOrKey, maybeColumn) {
|
|
572
|
+
// Dispatch on the presence of the second argument to disambiguate the two overloads:
|
|
573
|
+
// * `maybeColumn === undefined` → deprecated `(key)` overload; unpack from `key.row`/`key.column`
|
|
574
|
+
// * otherwise → positional `(row, column)` overload
|
|
575
|
+
let rowOrIdOrIndex;
|
|
576
|
+
let columnOrIdOrIndex;
|
|
577
|
+
if (maybeColumn === undefined) {
|
|
578
|
+
const key = rowOrKey;
|
|
579
|
+
rowOrIdOrIndex = key.row;
|
|
580
|
+
columnOrIdOrIndex = key.column;
|
|
581
|
+
}
|
|
582
|
+
else {
|
|
583
|
+
rowOrIdOrIndex = rowOrKey;
|
|
584
|
+
columnOrIdOrIndex = maybeColumn;
|
|
585
|
+
}
|
|
520
586
|
const row = __classPrivateFieldGet(this, _Table_instances, "m", _Table_getRow).call(this, rowOrIdOrIndex);
|
|
521
587
|
const column = __classPrivateFieldGet(this, _Table_instances, "m", _Table_getColumn).call(this, columnOrIdOrIndex);
|
|
522
588
|
const cell = row.cells[column.id];
|
|
@@ -590,10 +656,9 @@ export var System_TableSchema;
|
|
|
590
656
|
// #region If the row contains cells, verify that the table contains the columns for those cells
|
|
591
657
|
// Note: we intentionally hide `cells` on `IRow` to avoid leaking the internal data representation as much as possible, so we have to cast here.
|
|
592
658
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
const
|
|
596
|
-
for (const key of keys) {
|
|
659
|
+
const cells = newRow.cells;
|
|
660
|
+
if (cells !== undefined) {
|
|
661
|
+
for (const key of Object.keys(cells)) {
|
|
597
662
|
if (!columnIds.has(key)) {
|
|
598
663
|
throw new UsageError(`Attempted to insert a row containing a cell under column ID "${key}", but the table does not contain a column with that ID.`);
|
|
599
664
|
}
|
|
@@ -637,6 +702,32 @@ export var System_TableSchema;
|
|
|
637
702
|
}, preconditions === undefined ? undefined : { preconditions });
|
|
638
703
|
}
|
|
639
704
|
});
|
|
705
|
+
}, _Table_buildColumnInDocumentConstraintsForRows = function _Table_buildColumnInDocumentConstraintsForRows(rows) {
|
|
706
|
+
if (!TreeAlpha.context(this).isBranch()) {
|
|
707
|
+
return undefined;
|
|
708
|
+
}
|
|
709
|
+
const referencedColumnIds = new Set();
|
|
710
|
+
for (const row of rows) {
|
|
711
|
+
// `cells` is intentionally hidden on the public row type, so cast to read it.
|
|
712
|
+
const cells = row.cells;
|
|
713
|
+
if (cells === undefined) {
|
|
714
|
+
continue;
|
|
715
|
+
}
|
|
716
|
+
for (const id of Object.keys(cells)) {
|
|
717
|
+
referencedColumnIds.add(id);
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
if (referencedColumnIds.size === 0) {
|
|
721
|
+
return undefined;
|
|
722
|
+
}
|
|
723
|
+
const columnCache = __classPrivateFieldGet(this, _Table_instances, "m", _Table_getColumnCache).call(this);
|
|
724
|
+
const constraints = [];
|
|
725
|
+
for (const id of referencedColumnIds) {
|
|
726
|
+
const column = columnCache.get(id) ?? fail(0xd05 /* Column ID not found in cache */);
|
|
727
|
+
constraints.push({ type: "nodeInDocument", node: column });
|
|
728
|
+
}
|
|
729
|
+
assert(constraints.length > 0, 0xd06 /* No constraints generated for column references. */);
|
|
730
|
+
return constraints;
|
|
640
731
|
}, _Table_getColumnCache = function _Table_getColumnCache() {
|
|
641
732
|
let cache = __classPrivateFieldGet(this, _Table_columnCache, "f");
|
|
642
733
|
if (cache === undefined) {
|
|
@@ -657,6 +748,11 @@ export var System_TableSchema;
|
|
|
657
748
|
}
|
|
658
749
|
}
|
|
659
750
|
return cache;
|
|
751
|
+
}, _Table_tryGetColumnId = function _Table_tryGetColumnId(columnOrIdOrIndex) {
|
|
752
|
+
if (typeof columnOrIdOrIndex === "string") {
|
|
753
|
+
return columnOrIdOrIndex;
|
|
754
|
+
}
|
|
755
|
+
return __classPrivateFieldGet(this, _Table_instances, "m", _Table_tryGetColumn).call(this, columnOrIdOrIndex)?.id;
|
|
660
756
|
}, _Table_tryGetColumn = function _Table_tryGetColumn(columnOrIdOrIndex) {
|
|
661
757
|
if (typeof columnOrIdOrIndex === "number") {
|
|
662
758
|
if (columnOrIdOrIndex < 0 || columnOrIdOrIndex >= this.table.columns.length) {
|