@fluidframework/tree 2.70.0-361248 → 2.70.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 +52 -0
- package/api-report/tree.alpha.api.md +36 -17
- package/api-report/tree.beta.api.md +70 -2
- package/api-report/tree.legacy.beta.api.md +70 -2
- package/dist/alpha.d.ts +15 -11
- package/dist/api.d.ts +6 -1
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +9 -1
- package/dist/api.js.map +1 -1
- package/dist/beta.d.ts +13 -0
- package/dist/core/forest/forest.d.ts +3 -4
- package/dist/core/forest/forest.d.ts.map +1 -1
- package/dist/core/forest/forest.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/chunkTree.d.ts +6 -0
- package/dist/feature-libraries/chunked-forest/chunkTree.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/chunkTree.js +11 -2
- package/dist/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/chunkedForest.d.ts +1 -1
- package/dist/feature-libraries/chunked-forest/chunkedForest.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/chunkedForest.js +1 -1
- package/dist/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/compressedEncode.d.ts +21 -20
- package/dist/feature-libraries/chunked-forest/codec/compressedEncode.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js +17 -43
- package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/index.d.ts +1 -1
- package/dist/feature-libraries/chunked-forest/index.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/index.js +2 -1
- package/dist/feature-libraries/chunked-forest/index.js.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyField.js +2 -1
- package/dist/feature-libraries/flex-tree/lazyField.js.map +1 -1
- package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts +1 -1
- package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.js +43 -48
- package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.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 +2 -1
- package/dist/feature-libraries/index.js.map +1 -1
- package/dist/feature-libraries/object-forest/objectForest.d.ts +1 -1
- package/dist/feature-libraries/object-forest/objectForest.d.ts.map +1 -1
- package/dist/feature-libraries/object-forest/objectForest.js +1 -1
- package/dist/feature-libraries/object-forest/objectForest.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/legacy.d.ts +13 -0
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/shared-tree/independentView.d.ts.map +1 -1
- package/dist/shared-tree/independentView.js +2 -1
- package/dist/shared-tree/independentView.js.map +1 -1
- package/dist/shared-tree/schematizingTreeView.d.ts +4 -3
- package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
- package/dist/shared-tree/schematizingTreeView.js +1 -1
- package/dist/shared-tree/schematizingTreeView.js.map +1 -1
- package/dist/shared-tree/treeAlpha.d.ts +28 -2
- package/dist/shared-tree/treeAlpha.d.ts.map +1 -1
- package/dist/shared-tree/treeAlpha.js +12 -0
- package/dist/shared-tree/treeAlpha.js.map +1 -1
- package/dist/shared-tree-core/sharedTreeCore.js +1 -1
- package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/dist/simple-tree/api/incrementalAllowedTypes.d.ts +47 -0
- package/dist/simple-tree/api/incrementalAllowedTypes.d.ts.map +1 -0
- package/dist/simple-tree/api/incrementalAllowedTypes.js +90 -0
- package/dist/simple-tree/api/incrementalAllowedTypes.js.map +1 -0
- package/dist/simple-tree/api/index.d.ts +2 -1
- package/dist/simple-tree/api/index.d.ts.map +1 -1
- package/dist/simple-tree/api/index.js +4 -1
- package/dist/simple-tree/api/index.js.map +1 -1
- package/dist/simple-tree/api/schemaFactoryBeta.d.ts +2 -2
- package/dist/simple-tree/api/schemaFactoryBeta.d.ts.map +1 -1
- package/dist/simple-tree/api/schemaFactoryBeta.js.map +1 -1
- package/dist/simple-tree/api/tree.d.ts +51 -37
- 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/allowedTypes.d.ts +10 -11
- package/dist/simple-tree/core/allowedTypes.d.ts.map +1 -1
- package/dist/simple-tree/core/allowedTypes.js +1 -1
- package/dist/simple-tree/core/allowedTypes.js.map +1 -1
- package/dist/simple-tree/core/index.d.ts +1 -1
- package/dist/simple-tree/core/index.d.ts.map +1 -1
- package/dist/simple-tree/core/index.js +2 -1
- package/dist/simple-tree/core/index.js.map +1 -1
- package/dist/simple-tree/core/withType.d.ts +20 -0
- package/dist/simple-tree/core/withType.d.ts.map +1 -1
- package/dist/simple-tree/core/withType.js +21 -1
- package/dist/simple-tree/core/withType.js.map +1 -1
- package/dist/simple-tree/index.d.ts +2 -2
- package/dist/simple-tree/index.d.ts.map +1 -1
- package/dist/simple-tree/index.js +5 -2
- package/dist/simple-tree/index.js.map +1 -1
- package/dist/simple-tree/unhydratedFlexTreeFromInsertable.d.ts +1 -0
- package/dist/simple-tree/unhydratedFlexTreeFromInsertable.d.ts.map +1 -1
- package/dist/simple-tree/unhydratedFlexTreeFromInsertable.js +12 -0
- package/dist/simple-tree/unhydratedFlexTreeFromInsertable.js.map +1 -1
- package/lib/alpha.d.ts +15 -11
- package/lib/api.d.ts +6 -1
- package/lib/api.d.ts.map +1 -1
- package/lib/api.js +7 -0
- package/lib/api.js.map +1 -1
- package/lib/beta.d.ts +13 -0
- package/lib/core/forest/forest.d.ts +3 -4
- package/lib/core/forest/forest.d.ts.map +1 -1
- package/lib/core/forest/forest.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/chunkTree.d.ts +6 -0
- package/lib/feature-libraries/chunked-forest/chunkTree.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/chunkTree.js +8 -0
- package/lib/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/chunkedForest.d.ts +1 -1
- package/lib/feature-libraries/chunked-forest/chunkedForest.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/chunkedForest.js +2 -2
- package/lib/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/compressedEncode.d.ts +21 -20
- package/lib/feature-libraries/chunked-forest/codec/compressedEncode.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js +17 -43
- package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/index.d.ts +1 -1
- package/lib/feature-libraries/chunked-forest/index.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/index.js +1 -1
- package/lib/feature-libraries/chunked-forest/index.js.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyField.js +2 -1
- package/lib/feature-libraries/flex-tree/lazyField.js.map +1 -1
- package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts +1 -1
- package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.js +43 -48
- package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.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/feature-libraries/object-forest/objectForest.d.ts +1 -1
- package/lib/feature-libraries/object-forest/objectForest.d.ts.map +1 -1
- package/lib/feature-libraries/object-forest/objectForest.js +2 -2
- package/lib/feature-libraries/object-forest/objectForest.js.map +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -2
- package/lib/index.js.map +1 -1
- package/lib/legacy.d.ts +13 -0
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/shared-tree/independentView.d.ts.map +1 -1
- package/lib/shared-tree/independentView.js +2 -1
- package/lib/shared-tree/independentView.js.map +1 -1
- package/lib/shared-tree/schematizingTreeView.d.ts +4 -3
- package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
- package/lib/shared-tree/schematizingTreeView.js +2 -2
- package/lib/shared-tree/schematizingTreeView.js.map +1 -1
- package/lib/shared-tree/treeAlpha.d.ts +28 -2
- package/lib/shared-tree/treeAlpha.d.ts.map +1 -1
- package/lib/shared-tree/treeAlpha.js +13 -1
- package/lib/shared-tree/treeAlpha.js.map +1 -1
- package/lib/shared-tree-core/sharedTreeCore.js +1 -1
- package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/lib/simple-tree/api/incrementalAllowedTypes.d.ts +47 -0
- package/lib/simple-tree/api/incrementalAllowedTypes.d.ts.map +1 -0
- package/lib/simple-tree/api/incrementalAllowedTypes.js +86 -0
- package/lib/simple-tree/api/incrementalAllowedTypes.js.map +1 -0
- package/lib/simple-tree/api/index.d.ts +2 -1
- package/lib/simple-tree/api/index.d.ts.map +1 -1
- package/lib/simple-tree/api/index.js +1 -0
- package/lib/simple-tree/api/index.js.map +1 -1
- package/lib/simple-tree/api/schemaFactoryBeta.d.ts +2 -2
- package/lib/simple-tree/api/schemaFactoryBeta.d.ts.map +1 -1
- package/lib/simple-tree/api/schemaFactoryBeta.js.map +1 -1
- package/lib/simple-tree/api/tree.d.ts +51 -37
- 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/allowedTypes.d.ts +10 -11
- package/lib/simple-tree/core/allowedTypes.d.ts.map +1 -1
- package/lib/simple-tree/core/allowedTypes.js +1 -1
- package/lib/simple-tree/core/allowedTypes.js.map +1 -1
- package/lib/simple-tree/core/index.d.ts +1 -1
- package/lib/simple-tree/core/index.d.ts.map +1 -1
- package/lib/simple-tree/core/index.js +1 -1
- package/lib/simple-tree/core/index.js.map +1 -1
- package/lib/simple-tree/core/withType.d.ts +20 -0
- package/lib/simple-tree/core/withType.d.ts.map +1 -1
- package/lib/simple-tree/core/withType.js +20 -0
- package/lib/simple-tree/core/withType.js.map +1 -1
- package/lib/simple-tree/index.d.ts +2 -2
- package/lib/simple-tree/index.d.ts.map +1 -1
- package/lib/simple-tree/index.js +2 -2
- package/lib/simple-tree/index.js.map +1 -1
- package/lib/simple-tree/unhydratedFlexTreeFromInsertable.d.ts +1 -0
- package/lib/simple-tree/unhydratedFlexTreeFromInsertable.d.ts.map +1 -1
- package/lib/simple-tree/unhydratedFlexTreeFromInsertable.js +13 -1
- package/lib/simple-tree/unhydratedFlexTreeFromInsertable.js.map +1 -1
- package/package.json +21 -21
- package/src/api.ts +11 -0
- package/src/core/forest/forest.ts +3 -4
- package/src/feature-libraries/chunked-forest/chunkTree.ts +9 -0
- package/src/feature-libraries/chunked-forest/chunkedForest.ts +3 -3
- package/src/feature-libraries/chunked-forest/codec/compressedEncode.ts +20 -58
- package/src/feature-libraries/chunked-forest/index.ts +1 -0
- package/src/feature-libraries/flex-tree/lazyField.ts +3 -1
- package/src/feature-libraries/forest-summary/incrementalSummaryBuilder.ts +65 -71
- package/src/feature-libraries/index.ts +1 -0
- package/src/feature-libraries/object-forest/objectForest.ts +3 -3
- package/src/index.ts +4 -1
- package/src/packageVersion.ts +1 -1
- package/src/shared-tree/independentView.ts +4 -1
- package/src/shared-tree/schematizingTreeView.ts +10 -5
- package/src/shared-tree/treeAlpha.ts +50 -2
- package/src/shared-tree-core/sharedTreeCore.ts +1 -1
- package/src/simple-tree/api/incrementalAllowedTypes.ts +107 -0
- package/src/simple-tree/api/index.ts +6 -0
- package/src/simple-tree/api/schemaFactoryBeta.ts +6 -2
- package/src/simple-tree/api/tree.ts +64 -44
- package/src/simple-tree/core/allowedTypes.ts +10 -11
- package/src/simple-tree/core/index.ts +6 -1
- package/src/simple-tree/core/withType.ts +24 -0
- package/src/simple-tree/index.ts +5 -0
- package/src/simple-tree/unhydratedFlexTreeFromInsertable.ts +13 -0
|
@@ -44,6 +44,7 @@ import {
|
|
|
44
44
|
import { createTreeCheckout } from "./treeCheckout.js";
|
|
45
45
|
import { SchematizingSimpleTreeView } from "./schematizingTreeView.js";
|
|
46
46
|
import { initialize, initializerFromChunk } from "./schematizeTree.js";
|
|
47
|
+
import { combineChunks } from "../feature-libraries/index.js";
|
|
47
48
|
|
|
48
49
|
/**
|
|
49
50
|
* Create an uninitialized {@link TreeView} that is not tied to any {@link ITree} instance.
|
|
@@ -158,7 +159,9 @@ export function independentInitializedViewInternal<const TSchema extends Implici
|
|
|
158
159
|
initialize(
|
|
159
160
|
checkout,
|
|
160
161
|
schema,
|
|
161
|
-
initializerFromChunk(checkout, () =>
|
|
162
|
+
initializerFromChunk(checkout, () =>
|
|
163
|
+
combineChunks(checkout.forest.chunkField(rootFieldCursor)),
|
|
164
|
+
),
|
|
162
165
|
);
|
|
163
166
|
return new SchematizingSimpleTreeView<TSchema>(
|
|
164
167
|
checkout,
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
cursorForMapTreeField,
|
|
20
20
|
TreeStatus,
|
|
21
21
|
Context,
|
|
22
|
+
combineChunks,
|
|
22
23
|
type FlexTreeOptionalField,
|
|
23
24
|
type FlexTreeUnknownUnboxed,
|
|
24
25
|
FieldKinds,
|
|
@@ -70,6 +71,7 @@ import {
|
|
|
70
71
|
|
|
71
72
|
import { canInitialize, initialize, initializerFromChunk } from "./schematizeTree.js";
|
|
72
73
|
import type { ITreeCheckout, TreeCheckout } from "./treeCheckout.js";
|
|
74
|
+
import type { TreeBranchAlpha } from "../simple-tree/index.js";
|
|
73
75
|
|
|
74
76
|
/**
|
|
75
77
|
* Creating multiple tree views from the same checkout is not supported. This slot is used to detect if one already
|
|
@@ -227,8 +229,10 @@ export class SchematizingSimpleTreeView<
|
|
|
227
229
|
schema,
|
|
228
230
|
initializerFromChunk(this.checkout, () => {
|
|
229
231
|
// This must be done after initial schema is set!
|
|
230
|
-
return
|
|
231
|
-
|
|
232
|
+
return combineChunks(
|
|
233
|
+
this.checkout.forest.chunkField(
|
|
234
|
+
cursorForMapTreeField(mapTree === undefined ? [] : [mapTree]),
|
|
235
|
+
),
|
|
232
236
|
);
|
|
233
237
|
}),
|
|
234
238
|
);
|
|
@@ -510,15 +514,16 @@ export class SchematizingSimpleTreeView<
|
|
|
510
514
|
|
|
511
515
|
// #region Branching
|
|
512
516
|
|
|
513
|
-
public fork(): ReturnType<
|
|
517
|
+
public fork(): ReturnType<TreeBranchAlpha["fork"]> &
|
|
518
|
+
SchematizingSimpleTreeView<TRootSchema> {
|
|
514
519
|
return this.checkout.branch().viewWith(this.config);
|
|
515
520
|
}
|
|
516
521
|
|
|
517
|
-
public merge(context:
|
|
522
|
+
public merge(context: TreeBranchAlpha, disposeMerged = true): void {
|
|
518
523
|
this.checkout.merge(getCheckout(context), disposeMerged);
|
|
519
524
|
}
|
|
520
525
|
|
|
521
|
-
public rebaseOnto(context:
|
|
526
|
+
public rebaseOnto(context: TreeBranchAlpha): void {
|
|
522
527
|
getCheckout(context).rebase(this.checkout);
|
|
523
528
|
}
|
|
524
529
|
|
|
@@ -58,6 +58,8 @@ import {
|
|
|
58
58
|
importConcise,
|
|
59
59
|
exportConcise,
|
|
60
60
|
borrowCursorFromTreeNodeOrValue,
|
|
61
|
+
contentSchemaSymbol,
|
|
62
|
+
type TreeNodeSchema,
|
|
61
63
|
} from "../simple-tree/index.js";
|
|
62
64
|
import { brand, extractFromOpaque, type JsonCompatible } from "../util/index.js";
|
|
63
65
|
import {
|
|
@@ -83,8 +85,10 @@ import {
|
|
|
83
85
|
type Observer,
|
|
84
86
|
withObservation,
|
|
85
87
|
} from "../feature-libraries/index.js";
|
|
88
|
+
import type { TreeBranchAlpha } from "../simple-tree/index.js";
|
|
86
89
|
import { independentInitializedView, type ViewContent } from "./independentView.js";
|
|
87
90
|
import { SchematizingSimpleTreeView, ViewSlot } from "./schematizingTreeView.js";
|
|
91
|
+
import { isFluidHandle } from "@fluidframework/runtime-utils";
|
|
88
92
|
|
|
89
93
|
const identifier: TreeIdentifierUtils = (node: TreeNode): string | undefined => {
|
|
90
94
|
const nodeIdentifier = getIdentifierFromNode(node, "uncompressed");
|
|
@@ -227,7 +231,7 @@ export interface TreeAlpha {
|
|
|
227
231
|
* This does not fork a new branch, but rather retrieves the _existing_ branch for the node.
|
|
228
232
|
* To create a new branch, use e.g. {@link TreeBranch.fork | `myBranch.fork()`}.
|
|
229
233
|
*/
|
|
230
|
-
branch(node: TreeNode):
|
|
234
|
+
branch(node: TreeNode): TreeBranchAlpha | undefined;
|
|
231
235
|
|
|
232
236
|
/**
|
|
233
237
|
* Construct tree content that is compatible with the field defined by the provided `schema`.
|
|
@@ -519,6 +523,35 @@ export interface TreeAlpha {
|
|
|
519
523
|
onInvalidation: () => void,
|
|
520
524
|
trackDuring: () => TResult,
|
|
521
525
|
): ObservationResults<TResult>;
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* Ensures that the provided content will be interpreted as the given schema when inserting into the tree.
|
|
529
|
+
* @returns `content`, for convenience.
|
|
530
|
+
* @remarks
|
|
531
|
+
* If applicable, this will tag the given content with a {@link contentSchemaSymbol | special property} that indicates its intended schema.
|
|
532
|
+
* The `content` will be interpreted as the given `schema` when later inserted into the tree.
|
|
533
|
+
*
|
|
534
|
+
* This does not validate that the content actually conforms to the given schema (such validation will be done at insert time).
|
|
535
|
+
* If the content is not compatible with the tagged schema, an error will be thrown when the content is inserted.
|
|
536
|
+
*
|
|
537
|
+
* This is particularly useful when the content's schema cannot be inferred from its structure alone because it is compatible with multiple schemas.
|
|
538
|
+
* @example
|
|
539
|
+
* ```typescript
|
|
540
|
+
* const sf = new SchemaFactory("example");
|
|
541
|
+
* class Dog extends sf.object("Dog", { name: sf.string() }) {}
|
|
542
|
+
* class Cat extends sf.object("Cat", { name: sf.string() }) {}
|
|
543
|
+
* class Root extends sf.object("Root", { pet: [Dog, Cat] }) {}
|
|
544
|
+
* // ...
|
|
545
|
+
* const pet = { name: "Max" };
|
|
546
|
+
* view.root.pet = pet; // Error: ambiguous schema - is it a Dog or a Cat?
|
|
547
|
+
* TreeAlpha.ensureSchema(Dog, pet); // Tags `pet` as a Dog.
|
|
548
|
+
* view.root.pet = pet; // No error - it's a Dog.
|
|
549
|
+
* ```
|
|
550
|
+
*/
|
|
551
|
+
tagContentSchema<TSchema extends TreeNodeSchema, TContent extends InsertableField<TSchema>>(
|
|
552
|
+
schema: TSchema,
|
|
553
|
+
content: TContent,
|
|
554
|
+
): TContent;
|
|
522
555
|
}
|
|
523
556
|
|
|
524
557
|
/**
|
|
@@ -723,7 +756,7 @@ export const TreeAlpha: TreeAlpha = {
|
|
|
723
756
|
return result;
|
|
724
757
|
},
|
|
725
758
|
|
|
726
|
-
branch(node: TreeNode):
|
|
759
|
+
branch(node: TreeNode): TreeBranchAlpha | undefined {
|
|
727
760
|
const kernel = getKernel(node);
|
|
728
761
|
if (!kernel.isHydrated()) {
|
|
729
762
|
return undefined;
|
|
@@ -1003,6 +1036,21 @@ export const TreeAlpha: TreeAlpha = {
|
|
|
1003
1036
|
}
|
|
1004
1037
|
return result;
|
|
1005
1038
|
},
|
|
1039
|
+
|
|
1040
|
+
tagContentSchema<TSchema extends TreeNodeSchema, TNode extends InsertableField<TSchema>>(
|
|
1041
|
+
schema: TSchema,
|
|
1042
|
+
node: TNode,
|
|
1043
|
+
): TNode {
|
|
1044
|
+
if (typeof node === "object" && node !== null && !isFluidHandle(node)) {
|
|
1045
|
+
Reflect.defineProperty(node, contentSchemaSymbol, {
|
|
1046
|
+
configurable: false,
|
|
1047
|
+
enumerable: false,
|
|
1048
|
+
writable: true,
|
|
1049
|
+
value: schema.identifier,
|
|
1050
|
+
});
|
|
1051
|
+
}
|
|
1052
|
+
return node;
|
|
1053
|
+
},
|
|
1006
1054
|
};
|
|
1007
1055
|
|
|
1008
1056
|
/**
|
|
@@ -719,7 +719,7 @@ function scopeStorageService(
|
|
|
719
719
|
return service.list(`${scope}${path}`);
|
|
720
720
|
},
|
|
721
721
|
getSnapshotTree(): ISnapshotTree | undefined {
|
|
722
|
-
const snapshotTree = service.getSnapshotTree
|
|
722
|
+
const snapshotTree = service.getSnapshotTree();
|
|
723
723
|
if (snapshotTree === undefined) {
|
|
724
724
|
return undefined;
|
|
725
725
|
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { FieldKey, TreeNodeSchemaIdentifier } from "../../core/index.js";
|
|
7
|
+
import { getTreeNodeSchemaPrivateData, type AllowedTypesFull } from "../core/index.js";
|
|
8
|
+
import { isObjectNodeSchema } from "../node-kinds/index.js";
|
|
9
|
+
import type { TreeSchema } from "./configuration.js";
|
|
10
|
+
import type { IncrementalEncodingPolicy } from "../../feature-libraries/index.js";
|
|
11
|
+
import { oneFromIterable } from "../../util/index.js";
|
|
12
|
+
import { assert } from "@fluidframework/core-utils/internal";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* A symbol when present in the {@link AnnotatedAllowedTypes.metadata.custom} property as true, opts in the allowed
|
|
16
|
+
* types to incremental summary optimization.
|
|
17
|
+
* These allowed types will be optimized during summary such that if they don't change across summaries,
|
|
18
|
+
* they will not be encoded and their content will not be included in the summary that is uploaded to the service.
|
|
19
|
+
* @remarks
|
|
20
|
+
* See {@link getShouldIncrementallySummarizeAllowedTypes} for more details.
|
|
21
|
+
*
|
|
22
|
+
* Use {@link SchemaStaticsAlpha.types} to add this metadata to allowed types in a schema.
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* const sf = new SchemaFactoryAlpha("IncrementalSummarization");
|
|
26
|
+
* class Foo extends sf.objectAlpha("foo", {
|
|
27
|
+
* bar: sf.types([{ type: sf.string, metadata: {} }], {
|
|
28
|
+
* custom: { [incrementalSummaryHint]: true },
|
|
29
|
+
* }),
|
|
30
|
+
* }) {}
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export const incrementalSummaryHint: unique symbol = Symbol("IncrementalSummaryHint");
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Returns true if the provided allowed types's custom metadata has {@link incrementalSummaryHint} as true.
|
|
37
|
+
*/
|
|
38
|
+
function isIncrementalSummaryHintInAllowedTypes(allowedTypes: AllowedTypesFull): boolean {
|
|
39
|
+
const customMetadata = allowedTypes.metadata.custom;
|
|
40
|
+
return (
|
|
41
|
+
customMetadata !== undefined &&
|
|
42
|
+
(customMetadata as Record<symbol, unknown>)[incrementalSummaryHint] === true
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* This helper function {@link getShouldIncrementallySummarizeAllowedTypes} can be used to generate a callback function
|
|
48
|
+
* of type {@link IncrementalEncodingPolicy}.
|
|
49
|
+
* This callback can be passed as the value for {@link SharedTreeOptionsInternal.shouldEncodeFieldIncrementally} parameter
|
|
50
|
+
* when creating the tree.
|
|
51
|
+
* It will be called for each {@link AllowedTypes} in the schema to determine if it should be incrementally summarized.
|
|
52
|
+
*
|
|
53
|
+
* @param rootSchema - The schema for the root of the tree.
|
|
54
|
+
* @returns A callback function of type {@link IncrementalEncodingPolicy} which can be used to determine if a field
|
|
55
|
+
* should be incrementally summarized based on whether it is an allowed types with the
|
|
56
|
+
* {@link incrementalAllowedTypesMetadata} metadata.
|
|
57
|
+
*
|
|
58
|
+
* @remarks
|
|
59
|
+
* This only works for forest type {@link ForestTypeOptimized} and compression strategy
|
|
60
|
+
* {@link TreeCompressionStrategyExtended.CompressedIncremental}.
|
|
61
|
+
*
|
|
62
|
+
* The {@link incrementalAllowedTypesMetadata} will be replaced with a specialized metadata property once the
|
|
63
|
+
* incremental summary feature and APIs are stabilized.
|
|
64
|
+
*/
|
|
65
|
+
export function getShouldIncrementallySummarizeAllowedTypes(
|
|
66
|
+
rootSchema: TreeSchema,
|
|
67
|
+
): IncrementalEncodingPolicy {
|
|
68
|
+
return (
|
|
69
|
+
targetNodeIdentifier: TreeNodeSchemaIdentifier | undefined,
|
|
70
|
+
targetFieldKey: FieldKey,
|
|
71
|
+
) => {
|
|
72
|
+
if (targetNodeIdentifier === undefined) {
|
|
73
|
+
// Root fields cannot be allowed types, so we don't incrementally summarize them.
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const targetNode = rootSchema.definitions.get(targetNodeIdentifier);
|
|
78
|
+
if (targetNode === undefined) {
|
|
79
|
+
// The requested type is unknown to this schema.
|
|
80
|
+
// In this case we have no hints available from the view schema, and fall back to the default behavior of non-incremental encoding.
|
|
81
|
+
// There are two ways this can happen:
|
|
82
|
+
// 1. The view schema being used does not match the stored schema.
|
|
83
|
+
// 2. The view schema is compatible, but there are unknown optional fields which contain new types not described by the view schema.
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (isObjectNodeSchema(targetNode)) {
|
|
88
|
+
const targetPropertyKey = targetNode.storedKeyToPropertyKey.get(targetFieldKey);
|
|
89
|
+
if (targetPropertyKey !== undefined) {
|
|
90
|
+
const fieldSchema = targetNode.fields.get(targetPropertyKey);
|
|
91
|
+
if (fieldSchema !== undefined) {
|
|
92
|
+
return isIncrementalSummaryHintInAllowedTypes(fieldSchema.allowedTypesFull);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const allowedTypes = oneFromIterable(
|
|
99
|
+
getTreeNodeSchemaPrivateData(targetNode).childAllowedTypes,
|
|
100
|
+
);
|
|
101
|
+
assert(
|
|
102
|
+
allowedTypes !== undefined,
|
|
103
|
+
0xc87 /* Non object nodes with fields should only have one allowedTypes entry */,
|
|
104
|
+
);
|
|
105
|
+
return isIncrementalSummaryHintInAllowedTypes(allowedTypes);
|
|
106
|
+
};
|
|
107
|
+
}
|
|
@@ -19,7 +19,9 @@ export type {
|
|
|
19
19
|
TreeViewEvents,
|
|
20
20
|
SchemaCompatibilityStatus,
|
|
21
21
|
TreeViewAlpha,
|
|
22
|
+
TreeViewBeta,
|
|
22
23
|
TreeBranch,
|
|
24
|
+
TreeBranchAlpha,
|
|
23
25
|
TreeBranchEvents,
|
|
24
26
|
ITreeAlpha,
|
|
25
27
|
} from "./tree.js";
|
|
@@ -161,3 +163,7 @@ export {
|
|
|
161
163
|
export { generateSchemaFromSimpleSchema } from "./schemaFromSimple.js";
|
|
162
164
|
export { toSimpleTreeSchema } from "./viewSchemaToSimpleSchema.js";
|
|
163
165
|
export type { TreeChangeEvents } from "./treeChangeEvents.js";
|
|
166
|
+
export {
|
|
167
|
+
getShouldIncrementallySummarizeAllowedTypes,
|
|
168
|
+
incrementalSummaryHint,
|
|
169
|
+
} from "./incrementalAllowedTypes.js";
|
|
@@ -88,7 +88,9 @@ export class SchemaFactoryBeta<
|
|
|
88
88
|
TreeObjectNode<T, ScopedSchemaName<TScope, Name>>,
|
|
89
89
|
object & InsertableObjectFromSchemaRecord<T>,
|
|
90
90
|
true,
|
|
91
|
-
T
|
|
91
|
+
T,
|
|
92
|
+
never,
|
|
93
|
+
TCustomMetadata
|
|
92
94
|
> {
|
|
93
95
|
return objectSchema(scoped<TScope, TName, Name>(this, name), fields, true, {
|
|
94
96
|
...defaultSchemaFactoryObjectOptions,
|
|
@@ -110,7 +112,9 @@ export class SchemaFactoryBeta<
|
|
|
110
112
|
System_Unsafe.TreeObjectNodeUnsafe<T, ScopedSchemaName<TScope, Name>>,
|
|
111
113
|
object & System_Unsafe.InsertableObjectFromSchemaRecordUnsafe<T>,
|
|
112
114
|
false,
|
|
113
|
-
T
|
|
115
|
+
T,
|
|
116
|
+
never,
|
|
117
|
+
TCustomMetadata
|
|
114
118
|
> {
|
|
115
119
|
type TScopedName = ScopedSchemaName<TScope, Name>;
|
|
116
120
|
return this.object(
|
|
@@ -126,37 +126,10 @@ export interface ITreeAlpha extends ITree {
|
|
|
126
126
|
* A collection of functionality associated with a (version-control-style) branch of a SharedTree.
|
|
127
127
|
* @remarks A `TreeBranch` allows for the {@link TreeBranch.fork | creation of branches} and for those branches to later be {@link TreeBranch.merge | merged}.
|
|
128
128
|
*
|
|
129
|
-
* The `TreeBranch` for a specific {@link TreeNode} may be acquired by calling `TreeAlpha.branch`.
|
|
130
|
-
*
|
|
131
|
-
* A branch does not necessarily know the schema of its SharedTree - to convert a branch to a {@link TreeViewAlpha | view with a schema}, use {@link TreeBranch.hasRootSchema | hasRootSchema()}.
|
|
132
|
-
*
|
|
133
129
|
* The branch associated directly with the {@link ITree | SharedTree} is the "main" branch, and all other branches fork (directly or transitively) from that main branch.
|
|
134
|
-
* @sealed @
|
|
130
|
+
* @sealed @beta
|
|
135
131
|
*/
|
|
136
132
|
export interface TreeBranch extends IDisposable {
|
|
137
|
-
/**
|
|
138
|
-
* Events for the branch
|
|
139
|
-
*/
|
|
140
|
-
readonly events: Listenable<TreeBranchEvents>;
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Returns true if this branch has the given schema as its root schema.
|
|
144
|
-
* @remarks This is a type guard which allows this branch to become strongly typed as a {@link TreeViewAlpha | view} of the given schema.
|
|
145
|
-
*
|
|
146
|
-
* To succeed, the given schema must be invariant to the schema of the view - it must include exactly the same allowed types.
|
|
147
|
-
* For example, a schema of `Foo | Bar` will not match a view schema of `Foo`, and likewise a schema of `Foo` will not match a view schema of `Foo | Bar`.
|
|
148
|
-
* @example
|
|
149
|
-
* ```typescript
|
|
150
|
-
* if (branch.hasRootSchema(MySchema)) {
|
|
151
|
-
* const { root } = branch; // `branch` is now a TreeViewAlpha<MySchema>
|
|
152
|
-
* // ...
|
|
153
|
-
* }
|
|
154
|
-
* ```
|
|
155
|
-
*/
|
|
156
|
-
hasRootSchema<TSchema extends ImplicitFieldSchema>(
|
|
157
|
-
schema: TSchema,
|
|
158
|
-
): this is TreeViewAlpha<TSchema>;
|
|
159
|
-
|
|
160
133
|
/**
|
|
161
134
|
* Fork a new branch off of this branch which is based off of this branch's current state.
|
|
162
135
|
* @remarks Any changes to the tree on the new branch will not apply to this branch until the new branch is e.g. {@link TreeBranch.merge | merged} back into this branch.
|
|
@@ -187,6 +160,54 @@ export interface TreeBranch extends IDisposable {
|
|
|
187
160
|
*/
|
|
188
161
|
rebaseOnto(branch: TreeBranch): void;
|
|
189
162
|
|
|
163
|
+
/**
|
|
164
|
+
* Dispose of this branch, cleaning up any resources associated with it.
|
|
165
|
+
* @param error - Optional error indicating the reason for the disposal, if the object was disposed as the result of an error.
|
|
166
|
+
* @remarks Branches can also be automatically disposed when {@link TreeBranch.merge | they are merged} into another branch.
|
|
167
|
+
*
|
|
168
|
+
* Disposing branches is important to avoid consuming memory unnecessarily.
|
|
169
|
+
* In particular, the SharedTree retains all sequenced changes made to the tree since the "most-behind" branch was created or last {@link TreeBranch.rebaseOnto | rebased}.
|
|
170
|
+
*
|
|
171
|
+
* The {@link TreeBranch | main branch} cannot be disposed - attempting to do so will have no effect.
|
|
172
|
+
*/
|
|
173
|
+
dispose(error?: Error): void;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* {@link TreeBranch} with alpha-level APIs.
|
|
178
|
+
* @remarks
|
|
179
|
+
* The `TreeBranch` for a specific {@link TreeNode} may be acquired by calling `TreeAlpha.branch`.
|
|
180
|
+
*
|
|
181
|
+
* A branch does not necessarily know the schema of its SharedTree - to convert a branch to a {@link TreeViewAlpha | view with a schema}, use {@link TreeBranchAlpha.hasRootSchema | hasRootSchema()}.
|
|
182
|
+
* @sealed @alpha
|
|
183
|
+
*/
|
|
184
|
+
export interface TreeBranchAlpha extends TreeBranch {
|
|
185
|
+
/**
|
|
186
|
+
* Events for the branch
|
|
187
|
+
*/
|
|
188
|
+
readonly events: Listenable<TreeBranchEvents>;
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Returns true if this branch has the given schema as its root schema.
|
|
192
|
+
* @remarks This is a type guard which allows this branch to become strongly typed as a {@link TreeViewAlpha | view} of the given schema.
|
|
193
|
+
*
|
|
194
|
+
* To succeed, the given schema must be invariant to the schema of the view - it must include exactly the same allowed types.
|
|
195
|
+
* For example, a schema of `Foo | Bar` will not match a view schema of `Foo`, and likewise a schema of `Foo` will not match a view schema of `Foo | Bar`.
|
|
196
|
+
* @example
|
|
197
|
+
* ```typescript
|
|
198
|
+
* if (branch.hasRootSchema(MySchema)) {
|
|
199
|
+
* const { root } = branch; // `branch` is now a TreeViewAlpha<MySchema>
|
|
200
|
+
* // ...
|
|
201
|
+
* }
|
|
202
|
+
* ```
|
|
203
|
+
*/
|
|
204
|
+
hasRootSchema<TSchema extends ImplicitFieldSchema>(
|
|
205
|
+
schema: TSchema,
|
|
206
|
+
): this is TreeViewAlpha<TSchema>;
|
|
207
|
+
|
|
208
|
+
// Override the base fork method to return the alpha variant.
|
|
209
|
+
fork(): TreeBranchAlpha;
|
|
210
|
+
|
|
190
211
|
/**
|
|
191
212
|
* Run a transaction which applies one or more edits to the tree as a single atomic unit.
|
|
192
213
|
* @param transaction - The function to run as the body of the transaction.
|
|
@@ -261,18 +282,6 @@ export interface TreeBranch extends IDisposable {
|
|
|
261
282
|
transaction: () => VoidTransactionCallbackStatus | void,
|
|
262
283
|
params?: RunTransactionParams,
|
|
263
284
|
): TransactionResult;
|
|
264
|
-
|
|
265
|
-
/**
|
|
266
|
-
* Dispose of this branch, cleaning up any resources associated with it.
|
|
267
|
-
* @param error - Optional error indicating the reason for the disposal, if the object was disposed as the result of an error.
|
|
268
|
-
* @remarks Branches can also be automatically disposed when {@link TreeBranch.merge | they are merged} into another branch.
|
|
269
|
-
*
|
|
270
|
-
* Disposing branches is important to avoid consuming memory unnecessarily.
|
|
271
|
-
* In particular, the SharedTree retains all sequenced changes made to the tree since the "most-behind" branch was created or last {@link TreeBranch.rebaseOnto | rebased}.
|
|
272
|
-
*
|
|
273
|
-
* The {@link TreeBranch | main branch} cannot be disposed - attempting to do so will have no effect.
|
|
274
|
-
*/
|
|
275
|
-
dispose(error?: Error): void;
|
|
276
285
|
}
|
|
277
286
|
|
|
278
287
|
/**
|
|
@@ -371,18 +380,29 @@ export interface TreeView<in out TSchema extends ImplicitFieldSchema> extends ID
|
|
|
371
380
|
*/
|
|
372
381
|
export interface TreeViewAlpha<
|
|
373
382
|
in out TSchema extends ImplicitFieldSchema | UnsafeUnknownSchema,
|
|
374
|
-
> extends Omit<
|
|
375
|
-
|
|
383
|
+
> extends Omit<TreeViewBeta<ReadSchema<TSchema>>, "root" | "initialize" | "fork">,
|
|
384
|
+
TreeBranchAlpha {
|
|
376
385
|
get root(): ReadableField<TSchema>;
|
|
377
386
|
|
|
378
387
|
set root(newRoot: InsertableField<TSchema>);
|
|
379
388
|
|
|
389
|
+
initialize(content: InsertableField<TSchema>): void;
|
|
390
|
+
|
|
380
391
|
readonly events: Listenable<TreeViewEvents & TreeBranchEvents>;
|
|
381
392
|
|
|
382
|
-
|
|
393
|
+
// Override the base fork method to return a TreeViewAlpha.
|
|
394
|
+
fork(): ReturnType<TreeBranch["fork"]> & TreeViewAlpha<TSchema>;
|
|
395
|
+
}
|
|
383
396
|
|
|
397
|
+
/**
|
|
398
|
+
* {@link TreeView} with additional beta APIs.
|
|
399
|
+
* @sealed @beta
|
|
400
|
+
*/
|
|
401
|
+
export interface TreeViewBeta<in out TSchema extends ImplicitFieldSchema>
|
|
402
|
+
extends TreeView<TSchema>,
|
|
403
|
+
TreeBranch {
|
|
384
404
|
// Override the base branch method to return a typed view rather than merely a branch.
|
|
385
|
-
fork(): ReturnType<TreeBranch["fork"]> &
|
|
405
|
+
fork(): ReturnType<TreeBranch["fork"]> & TreeViewBeta<TSchema>;
|
|
386
406
|
}
|
|
387
407
|
|
|
388
408
|
/**
|
|
@@ -60,7 +60,7 @@ export type AllowedTypes = readonly LazyItem<TreeNodeSchema>[];
|
|
|
60
60
|
* @privateRemarks
|
|
61
61
|
* Since this is sealed, users are not supposed to create instances of it directly.
|
|
62
62
|
* Making it extend ErasedType could enforce that.
|
|
63
|
-
* @
|
|
63
|
+
* @beta
|
|
64
64
|
* @sealed
|
|
65
65
|
*/
|
|
66
66
|
export interface AnnotatedAllowedType<T = LazyItem<TreeNodeSchema>> {
|
|
@@ -77,7 +77,7 @@ export interface AnnotatedAllowedType<T = LazyItem<TreeNodeSchema>> {
|
|
|
77
77
|
/**
|
|
78
78
|
* {@link AllowedTypesFull} but with the lazy schema references eagerly evaluated.
|
|
79
79
|
* @sealed
|
|
80
|
-
* @
|
|
80
|
+
* @beta
|
|
81
81
|
*/
|
|
82
82
|
export type AllowedTypesFullEvaluated = AllowedTypesFull<
|
|
83
83
|
readonly AnnotatedAllowedType<TreeNodeSchema>[]
|
|
@@ -95,7 +95,7 @@ export function isAnnotatedAllowedTypes(
|
|
|
95
95
|
|
|
96
96
|
/**
|
|
97
97
|
* Stores annotations for a set of allowed types.
|
|
98
|
-
* @
|
|
98
|
+
* @beta
|
|
99
99
|
* @sealed
|
|
100
100
|
*/
|
|
101
101
|
export interface AnnotatedAllowedTypes<T = readonly AnnotatedAllowedType[]>
|
|
@@ -139,7 +139,7 @@ export interface AnnotatedAllowedTypes<T = readonly AnnotatedAllowedType[]>
|
|
|
139
139
|
* Stores annotations for a set of allowed types.
|
|
140
140
|
* @remarks
|
|
141
141
|
* Most expressive form of AllowedTypes which any of the implicit types can be normalized to.
|
|
142
|
-
* @
|
|
142
|
+
* @beta
|
|
143
143
|
* @sealed
|
|
144
144
|
*/
|
|
145
145
|
export type AllowedTypesFull<
|
|
@@ -148,8 +148,7 @@ export type AllowedTypesFull<
|
|
|
148
148
|
|
|
149
149
|
/**
|
|
150
150
|
* Creates an {@link AllowedTypesFull} type from a mixed array of annotated and unannotated allowed types.
|
|
151
|
-
* @
|
|
152
|
-
* @sealed
|
|
151
|
+
* @system @sealed @beta
|
|
153
152
|
*/
|
|
154
153
|
export type AllowedTypesFullFromMixed<
|
|
155
154
|
T extends readonly (AnnotatedAllowedType | LazyItem<TreeNodeSchema>)[],
|
|
@@ -360,7 +359,7 @@ export class AnnotatedAllowedTypesInternal<
|
|
|
360
359
|
* Annotations that apply to a set of allowed types.
|
|
361
360
|
* @remarks
|
|
362
361
|
* Additional optionals may be added to this as non-breaking changes, so implementations of it should be simple object literals with no unlisted members.
|
|
363
|
-
* @
|
|
362
|
+
* @beta
|
|
364
363
|
* @input
|
|
365
364
|
*/
|
|
366
365
|
export interface AllowedTypesMetadata {
|
|
@@ -385,7 +384,7 @@ export function isAnnotatedAllowedType(
|
|
|
385
384
|
* Annotations that apply to an individual allowed type.
|
|
386
385
|
* @remarks
|
|
387
386
|
* Additional optionals may be added to this as non-breaking changes, so implementations of it should be simple object literals with no unlisted members.
|
|
388
|
-
* @
|
|
387
|
+
* @beta
|
|
389
388
|
* @input
|
|
390
389
|
*/
|
|
391
390
|
export interface AllowedTypeMetadata {
|
|
@@ -413,7 +412,7 @@ export let createSchemaUpgrade: () => SchemaUpgrade;
|
|
|
413
412
|
* TODO:#38722 implement runtime schema upgrades.
|
|
414
413
|
* Until then, the class purely behaves mostly as a placeholder.
|
|
415
414
|
* TODO: Consider allowing users to store a name for the upgrade to use in error messages.
|
|
416
|
-
* @sealed @
|
|
415
|
+
* @sealed @beta
|
|
417
416
|
*/
|
|
418
417
|
export class SchemaUpgrade {
|
|
419
418
|
protected _typeCheck!: MakeNominal;
|
|
@@ -461,7 +460,7 @@ export type ImplicitAllowedTypes = AllowedTypes | TreeNodeSchema;
|
|
|
461
460
|
|
|
462
461
|
/**
|
|
463
462
|
* Removes annotations from a list of allowed types that may contain annotations.
|
|
464
|
-
* @system @
|
|
463
|
+
* @system @beta
|
|
465
464
|
*/
|
|
466
465
|
export type UnannotateAllowedTypesList<
|
|
467
466
|
T extends readonly (AnnotatedAllowedType | LazyItem<TreeNodeSchema>)[],
|
|
@@ -471,7 +470,7 @@ export type UnannotateAllowedTypesList<
|
|
|
471
470
|
|
|
472
471
|
/**
|
|
473
472
|
* Add annotations to a list of allowed types that may or may not contain annotations.
|
|
474
|
-
* @system @
|
|
473
|
+
* @system @beta
|
|
475
474
|
*/
|
|
476
475
|
export type AnnotateAllowedTypesList<
|
|
477
476
|
T extends readonly (AnnotatedAllowedType | LazyItem<TreeNodeSchema>)[],
|
|
@@ -16,7 +16,12 @@ export {
|
|
|
16
16
|
SimpleContextSlot,
|
|
17
17
|
withBufferedTreeEvents,
|
|
18
18
|
} from "./treeNodeKernel.js";
|
|
19
|
-
export {
|
|
19
|
+
export {
|
|
20
|
+
type WithType,
|
|
21
|
+
typeNameSymbol,
|
|
22
|
+
typeSchemaSymbol,
|
|
23
|
+
contentSchemaSymbol,
|
|
24
|
+
} from "./withType.js";
|
|
20
25
|
export {
|
|
21
26
|
type Unhydrated,
|
|
22
27
|
type InternalTreeNode,
|
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
|
|
6
6
|
import type { TreeNode } from "./treeNode.js";
|
|
7
7
|
import type { NodeKind, TreeNodeSchemaClass } from "./treeNodeSchema.js";
|
|
8
|
+
// Used by doc links:
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-imports
|
|
10
|
+
import type { TreeAlpha } from "../../shared-tree/index.js";
|
|
8
11
|
|
|
9
12
|
/**
|
|
10
13
|
* The type of a {@link TreeNode}.
|
|
@@ -39,6 +42,27 @@ export const typeNameSymbol: unique symbol = Symbol("TreeNode Type");
|
|
|
39
42
|
*/
|
|
40
43
|
export const typeSchemaSymbol: unique symbol = Symbol("TreeNode Schema");
|
|
41
44
|
|
|
45
|
+
/**
|
|
46
|
+
* The intended type of insertable content that is to become a {@link TreeNode}.
|
|
47
|
+
* @remarks Use the type-safe {@link (TreeAlpha:interface).tagContentSchema} function to tag insertable content with this symbol.
|
|
48
|
+
*
|
|
49
|
+
* If a property with this symbol key is present on an object that is inserted into the tree,
|
|
50
|
+
* the tree will use the schema identifier specified by the value of this property when creating the node.
|
|
51
|
+
* This is particularly useful for specifying the intended schema of untyped content when it would otherwise be ambiguous.
|
|
52
|
+
* @example
|
|
53
|
+
* ```typescript
|
|
54
|
+
* const sf = new SchemaFactory("example");
|
|
55
|
+
* class Dog extends sf.object("Dog", { name: sf.string() }) {}
|
|
56
|
+
* class Cat extends sf.object("Cat", { name: sf.string() }) {}
|
|
57
|
+
* class Root extends sf.object("Root", { pet: [Dog, Cat] }) {}
|
|
58
|
+
* // ...
|
|
59
|
+
* view.root.pet = { name: "Max" }; // Error: ambiguous schema - is it a Dog or a Cat?
|
|
60
|
+
* view.root.pet = { name: "Max", [contentSchemaSymbol]: "example.Dog" }; // No error - it's a Dog.
|
|
61
|
+
* ```
|
|
62
|
+
* @alpha
|
|
63
|
+
*/
|
|
64
|
+
export const contentSchemaSymbol: unique symbol = Symbol("SharedTree Schema");
|
|
65
|
+
|
|
42
66
|
/**
|
|
43
67
|
* Adds a type symbol to a type for stronger typing.
|
|
44
68
|
*
|
package/src/simple-tree/index.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
export {
|
|
7
7
|
typeNameSymbol,
|
|
8
8
|
typeSchemaSymbol,
|
|
9
|
+
contentSchemaSymbol,
|
|
9
10
|
type WithType,
|
|
10
11
|
type TreeNodeSchema,
|
|
11
12
|
type AnnotatedAllowedType,
|
|
@@ -135,7 +136,9 @@ export {
|
|
|
135
136
|
type UnannotateAllowedTypesListUnsafe,
|
|
136
137
|
type AnnotateAllowedTypesListUnsafe,
|
|
137
138
|
type TreeViewAlpha,
|
|
139
|
+
type TreeViewBeta,
|
|
138
140
|
type TreeBranch,
|
|
141
|
+
type TreeBranchAlpha,
|
|
139
142
|
type TreeBranchEvents,
|
|
140
143
|
getPropertyKeyFromStoredKey,
|
|
141
144
|
getStoredKey,
|
|
@@ -180,6 +183,8 @@ export {
|
|
|
180
183
|
type SchemaStaticsAlpha,
|
|
181
184
|
KeyEncodingOptions,
|
|
182
185
|
type TreeParsingOptions,
|
|
186
|
+
incrementalSummaryHint,
|
|
187
|
+
getShouldIncrementallySummarizeAllowedTypes,
|
|
183
188
|
type SchemaFactory_base,
|
|
184
189
|
} from "./api/index.js";
|
|
185
190
|
export type {
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
isTreeNode,
|
|
18
18
|
type TreeNode,
|
|
19
19
|
type TreeNodeSchema,
|
|
20
|
+
contentSchemaSymbol,
|
|
20
21
|
type Unhydrated,
|
|
21
22
|
UnhydratedFlexTreeNode,
|
|
22
23
|
} from "./core/index.js";
|
|
@@ -125,16 +126,28 @@ For class-based schema, this can be done by replacing an expression like "{foo:
|
|
|
125
126
|
|
|
126
127
|
/**
|
|
127
128
|
* Returns all types for which the data is schema-compatible.
|
|
129
|
+
* @remarks This will respect the {@link contentSchemaSymbol} property on data to disambiguate types - if present, only that type will be returned.
|
|
128
130
|
*/
|
|
129
131
|
export function getPossibleTypes(
|
|
130
132
|
allowedTypes: ReadonlySet<TreeNodeSchema>,
|
|
131
133
|
data: FactoryContent,
|
|
132
134
|
): TreeNodeSchema[] {
|
|
133
135
|
assert(data !== undefined, 0x889 /* undefined cannot be used as FactoryContent. */);
|
|
136
|
+
const type =
|
|
137
|
+
typeof data === "object" && data !== null
|
|
138
|
+
? (data as Partial<{ [contentSchemaSymbol]: string }>)[contentSchemaSymbol]
|
|
139
|
+
: undefined;
|
|
134
140
|
|
|
135
141
|
let best = CompatibilityLevel.None;
|
|
136
142
|
const possibleTypes: TreeNodeSchema[] = [];
|
|
137
143
|
for (const schema of allowedTypes) {
|
|
144
|
+
if (type !== undefined) {
|
|
145
|
+
if (schema.identifier === type) {
|
|
146
|
+
return [schema];
|
|
147
|
+
} else {
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
138
151
|
const handler = getTreeNodeSchemaPrivateData(schema).idempotentInitialize();
|
|
139
152
|
const level = handler.shallowCompatibilityTest(data);
|
|
140
153
|
if (level > best) {
|