@fluidframework/tree 2.4.0-299707 → 2.4.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 +192 -0
- package/api-report/tree.alpha.api.md +2 -1
- package/api-report/tree.beta.api.md +2 -1
- package/dist/feature-libraries/flex-tree/lazyField.js +1 -1
- package/dist/feature-libraries/flex-tree/lazyField.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js +3 -3
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- 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/schematizingTreeView.js +1 -1
- package/dist/shared-tree/schematizingTreeView.js.map +1 -1
- package/dist/shared-tree/sharedTree.js +1 -1
- package/dist/shared-tree/sharedTree.js.map +1 -1
- package/dist/shared-tree-core/branch.js +1 -1
- package/dist/shared-tree-core/branch.js.map +1 -1
- package/dist/simple-tree/api/customTree.js +5 -5
- package/dist/simple-tree/api/customTree.js.map +1 -1
- package/dist/simple-tree/api/treeApiBeta.d.ts +14 -2
- package/dist/simple-tree/api/treeApiBeta.d.ts.map +1 -1
- package/dist/simple-tree/api/treeApiBeta.js +23 -8
- package/dist/simple-tree/api/treeApiBeta.js.map +1 -1
- package/dist/simple-tree/core/schemaCaching.js +1 -1
- package/dist/simple-tree/core/schemaCaching.js.map +1 -1
- package/dist/simple-tree/core/treeNodeKernel.d.ts +6 -1
- package/dist/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
- package/dist/simple-tree/core/treeNodeKernel.js +7 -1
- package/dist/simple-tree/core/treeNodeKernel.js.map +1 -1
- package/dist/simple-tree/core/unhydratedFlexTree.js +1 -1
- package/dist/simple-tree/core/unhydratedFlexTree.js.map +1 -1
- package/dist/simple-tree/toFlexSchema.js +2 -2
- package/dist/simple-tree/toFlexSchema.js.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyField.js +1 -1
- package/lib/feature-libraries/flex-tree/lazyField.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js +3 -3
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- 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/schematizingTreeView.js +1 -1
- package/lib/shared-tree/schematizingTreeView.js.map +1 -1
- package/lib/shared-tree/sharedTree.js +1 -1
- package/lib/shared-tree/sharedTree.js.map +1 -1
- package/lib/shared-tree-core/branch.js +1 -1
- package/lib/shared-tree-core/branch.js.map +1 -1
- package/lib/simple-tree/api/customTree.js +5 -5
- package/lib/simple-tree/api/customTree.js.map +1 -1
- package/lib/simple-tree/api/treeApiBeta.d.ts +14 -2
- package/lib/simple-tree/api/treeApiBeta.d.ts.map +1 -1
- package/lib/simple-tree/api/treeApiBeta.js +23 -8
- package/lib/simple-tree/api/treeApiBeta.js.map +1 -1
- package/lib/simple-tree/core/schemaCaching.js +1 -1
- package/lib/simple-tree/core/schemaCaching.js.map +1 -1
- package/lib/simple-tree/core/treeNodeKernel.d.ts +6 -1
- package/lib/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
- package/lib/simple-tree/core/treeNodeKernel.js +7 -1
- package/lib/simple-tree/core/treeNodeKernel.js.map +1 -1
- package/lib/simple-tree/core/unhydratedFlexTree.js +1 -1
- package/lib/simple-tree/core/unhydratedFlexTree.js.map +1 -1
- package/lib/simple-tree/toFlexSchema.js +2 -2
- package/lib/simple-tree/toFlexSchema.js.map +1 -1
- package/package.json +20 -20
- package/src/feature-libraries/flex-tree/lazyField.ts +1 -1
- package/src/feature-libraries/modular-schema/modularChangeFamily.ts +9 -3
- package/src/packageVersion.ts +1 -1
- package/src/shared-tree/schematizingTreeView.ts +1 -1
- package/src/shared-tree/sharedTree.ts +1 -1
- package/src/shared-tree-core/branch.ts +1 -1
- package/src/simple-tree/api/customTree.ts +5 -5
- package/src/simple-tree/api/treeApiBeta.ts +65 -3
- package/src/simple-tree/core/schemaCaching.ts +1 -1
- package/src/simple-tree/core/treeNodeKernel.ts +10 -2
- package/src/simple-tree/core/unhydratedFlexTree.ts +1 -1
- package/src/simple-tree/toFlexSchema.ts +2 -2
package/src/packageVersion.ts
CHANGED
|
@@ -273,7 +273,7 @@ export class SchematizingSimpleTreeView<in out TRootSchema extends ImplicitField
|
|
|
273
273
|
this.view = view;
|
|
274
274
|
assert(
|
|
275
275
|
!this.checkout.forest.anchors.slots.has(SimpleContextSlot),
|
|
276
|
-
|
|
276
|
+
0xa47 /* extra simple tree context */,
|
|
277
277
|
);
|
|
278
278
|
this.checkout.forest.anchors.slots.set(
|
|
279
279
|
SimpleContextSlot,
|
|
@@ -357,7 +357,7 @@ export function getBranch(view: TreeView<ImplicitFieldSchema>): TreeBranch;
|
|
|
357
357
|
export function getBranch(treeOrView: ITree | TreeView<ImplicitFieldSchema>): TreeBranch {
|
|
358
358
|
assert(
|
|
359
359
|
treeOrView instanceof SharedTree || treeOrView instanceof SchematizingSimpleTreeView,
|
|
360
|
-
|
|
360
|
+
0xa48 /* Unsupported implementation */,
|
|
361
361
|
);
|
|
362
362
|
const checkout: TreeCheckout = treeOrView.checkout;
|
|
363
363
|
// This cast is safe so long as TreeCheckout supports all the operations on the branch interface.
|
|
@@ -253,7 +253,7 @@ export class SharedTreeBranch<
|
|
|
253
253
|
this.assertNotDisposed();
|
|
254
254
|
|
|
255
255
|
const revisionTag = taggedChange.revision;
|
|
256
|
-
assert(revisionTag !== undefined,
|
|
256
|
+
assert(revisionTag !== undefined, 0xa49 /* Revision tag must be provided */);
|
|
257
257
|
|
|
258
258
|
const newHead = mintCommit(this.head, {
|
|
259
259
|
revision: revisionTag,
|
|
@@ -80,15 +80,15 @@ export function customFromCursorInner<TChild, THandle>(
|
|
|
80
80
|
case booleanSchema.identifier:
|
|
81
81
|
case nullSchema.identifier:
|
|
82
82
|
case stringSchema.identifier:
|
|
83
|
-
assert(reader.value !== undefined,
|
|
84
|
-
assert(!isFluidHandle(reader.value),
|
|
83
|
+
assert(reader.value !== undefined, 0xa50 /* out of schema: missing value */);
|
|
84
|
+
assert(!isFluidHandle(reader.value), 0xa51 /* out of schema: unexpected FluidHandle */);
|
|
85
85
|
return reader.value;
|
|
86
86
|
case handleSchema.identifier:
|
|
87
|
-
assert(reader.value !== undefined,
|
|
88
|
-
assert(isFluidHandle(reader.value),
|
|
87
|
+
assert(reader.value !== undefined, 0xa52 /* out of schema: missing value */);
|
|
88
|
+
assert(isFluidHandle(reader.value), 0xa53 /* out of schema: expected FluidHandle */);
|
|
89
89
|
return options.valueConverter(reader.value);
|
|
90
90
|
default: {
|
|
91
|
-
assert(reader.value === undefined,
|
|
91
|
+
assert(reader.value === undefined, 0xa54 /* out of schema: unexpected value */);
|
|
92
92
|
if (nodeSchema.kind === NodeKind.Array) {
|
|
93
93
|
const fields = inCursorField(reader, EmptyKey, () =>
|
|
94
94
|
mapCursorField(reader, () => childHandler(reader, options, schema)),
|
|
@@ -3,8 +3,19 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import
|
|
6
|
+
import {
|
|
7
|
+
getKernel,
|
|
8
|
+
isTreeNode,
|
|
9
|
+
type NodeKind,
|
|
10
|
+
type TreeChangeEvents,
|
|
11
|
+
type TreeNode,
|
|
12
|
+
type Unhydrated,
|
|
13
|
+
type WithType,
|
|
14
|
+
} from "../core/index.js";
|
|
15
|
+
import type { ImplicitFieldSchema, TreeFieldFromImplicitField } from "../schemaTypes.js";
|
|
7
16
|
import { treeNodeApi } from "./treeNodeApi.js";
|
|
17
|
+
import { createFromCursor, cursorFromInsertable } from "./create.js";
|
|
18
|
+
import type { ITreeCursorSynchronous } from "../../core/index.js";
|
|
8
19
|
|
|
9
20
|
/**
|
|
10
21
|
* Data included for {@link TreeChangeEventsBeta.nodeChanged}.
|
|
@@ -82,7 +93,7 @@ export interface TreeChangeEventsBeta<TNode extends TreeNode = TreeNode>
|
|
|
82
93
|
* Extensions to {@link Tree} which are not yet stable.
|
|
83
94
|
* @sealed @beta
|
|
84
95
|
*/
|
|
85
|
-
export const TreeBeta
|
|
96
|
+
export const TreeBeta: {
|
|
86
97
|
/**
|
|
87
98
|
* Register an event listener on the given node.
|
|
88
99
|
* @param node - The node whose events should be subscribed to.
|
|
@@ -91,6 +102,26 @@ export const TreeBeta = {
|
|
|
91
102
|
* @returns A callback function which will deregister the event.
|
|
92
103
|
* This callback should be called only once.
|
|
93
104
|
*/
|
|
105
|
+
on<K extends keyof TreeChangeEventsBeta<TNode>, TNode extends TreeNode>(
|
|
106
|
+
node: TNode,
|
|
107
|
+
eventName: K,
|
|
108
|
+
listener: NoInfer<TreeChangeEventsBeta<TNode>[K]>,
|
|
109
|
+
): () => void;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Clones the persisted data associated with a node. Some key things to note:
|
|
113
|
+
* - Local state, such as properties added to customized schema classes, will not be cloned. However, they will be
|
|
114
|
+
* initialized to their default state just as if the node had been created via its constructor.
|
|
115
|
+
* - Value node types (i.e., numbers, strings, booleans, nulls and Fluid handles) will be returned as is.
|
|
116
|
+
* - The identifiers in the node's subtree will be preserved, i.e., they are not replaced with new values.
|
|
117
|
+
*
|
|
118
|
+
* @param node - The node to clone.
|
|
119
|
+
* @returns A new unhydrated node with the same persisted data as the original node.
|
|
120
|
+
*/
|
|
121
|
+
clone<TSchema extends ImplicitFieldSchema>(
|
|
122
|
+
node: TreeFieldFromImplicitField<TSchema>,
|
|
123
|
+
): TreeFieldFromImplicitField<TSchema>;
|
|
124
|
+
} = {
|
|
94
125
|
on<K extends keyof TreeChangeEventsBeta<TNode>, TNode extends TreeNode>(
|
|
95
126
|
node: TNode,
|
|
96
127
|
eventName: K,
|
|
@@ -98,4 +129,35 @@ export const TreeBeta = {
|
|
|
98
129
|
): () => void {
|
|
99
130
|
return treeNodeApi.on(node, eventName, listener);
|
|
100
131
|
},
|
|
101
|
-
|
|
132
|
+
clone<TSchema extends ImplicitFieldSchema>(
|
|
133
|
+
node: TreeFieldFromImplicitField<TSchema>,
|
|
134
|
+
): Unhydrated<TreeFieldFromImplicitField<TSchema>> {
|
|
135
|
+
/* The only non-TreeNode cases are {@link Value} (for an empty optional field) which can be returned as is. */
|
|
136
|
+
if (!isTreeNode(node)) {
|
|
137
|
+
return node;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const kernel = getKernel(node);
|
|
141
|
+
/*
|
|
142
|
+
* For unhydrated nodes, we can create a cursor by calling `cursorFromInsertable` because the node
|
|
143
|
+
* hasn't been inserted yet. We can then create a new node from the cursor.
|
|
144
|
+
*/
|
|
145
|
+
if (!kernel.isHydrated()) {
|
|
146
|
+
return createFromCursor(
|
|
147
|
+
kernel.schema,
|
|
148
|
+
cursorFromInsertable(kernel.schema, node),
|
|
149
|
+
) as Unhydrated<TreeFieldFromImplicitField<TSchema>>;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// For hydrated nodes, create a new cursor in the forest and then create a new node from the cursor.
|
|
153
|
+
const forest = kernel.context.flexContext.checkout.forest;
|
|
154
|
+
const cursor = forest.allocateCursor("tree.clone");
|
|
155
|
+
forest.moveCursorToPath(kernel.anchorNode, cursor);
|
|
156
|
+
const clonedNode = createFromCursor(
|
|
157
|
+
kernel.schema,
|
|
158
|
+
cursor as ITreeCursorSynchronous,
|
|
159
|
+
) as Unhydrated<TreeFieldFromImplicitField<TSchema>>;
|
|
160
|
+
cursor.free();
|
|
161
|
+
return clonedNode;
|
|
162
|
+
},
|
|
163
|
+
};
|
|
@@ -29,7 +29,7 @@ export function getSimpleContextFromInnerNode(innerNode: InnerNode): Context {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
const context = innerNode.anchorNode.anchorSet.slots.get(SimpleContextSlot);
|
|
32
|
-
assert(context !== undefined,
|
|
32
|
+
assert(context !== undefined, 0xa55 /* missing simple tree context */);
|
|
33
33
|
|
|
34
34
|
return context;
|
|
35
35
|
}
|
|
@@ -29,7 +29,7 @@ import { fail } from "../../util/index.js";
|
|
|
29
29
|
// TODO: decide how to deal with dependencies on flex-tree implementation.
|
|
30
30
|
// eslint-disable-next-line import/no-internal-modules
|
|
31
31
|
import { makeTree } from "../../feature-libraries/flex-tree/lazyNode.js";
|
|
32
|
-
import { SimpleContextSlot, type Context } from "./context.js";
|
|
32
|
+
import { SimpleContextSlot, type Context, type HydratedContext } from "./context.js";
|
|
33
33
|
import { UnhydratedFlexTreeNode } from "./unhydratedFlexTree.js";
|
|
34
34
|
|
|
35
35
|
const treeNodeToKernel = new WeakMap<TreeNode, TreeNodeKernel>();
|
|
@@ -267,6 +267,14 @@ export class TreeNodeKernel implements Listenable<KernelEvents> {
|
|
|
267
267
|
// TODO: go to the context and remove myself from withAnchors
|
|
268
268
|
}
|
|
269
269
|
|
|
270
|
+
public isHydrated(): this is { anchorNode: AnchorNode; context: HydratedContext } {
|
|
271
|
+
return isHydrated(this.#hydrationState);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
public get anchorNode(): AnchorNode | undefined {
|
|
275
|
+
return isHydrated(this.#hydrationState) ? this.#hydrationState.anchorNode : undefined;
|
|
276
|
+
}
|
|
277
|
+
|
|
270
278
|
/**
|
|
271
279
|
* Retrieves the flex node associated with the given target via {@link setInnerNode}.
|
|
272
280
|
* @remarks
|
|
@@ -421,7 +429,7 @@ export function tryDisposeTreeNode(anchorNode: AnchorNode): void {
|
|
|
421
429
|
export function getTreeNodeSchemaFromHydratedFlexNode(flexNode: FlexTreeNode): TreeNodeSchema {
|
|
422
430
|
assert(
|
|
423
431
|
flexNode.context.isHydrated(),
|
|
424
|
-
|
|
432
|
+
0xa56 /* getTreeNodeSchemaFromHydratedFlexNode only allows hydrated flex tree nodes */,
|
|
425
433
|
);
|
|
426
434
|
|
|
427
435
|
const context =
|
|
@@ -445,7 +445,7 @@ class EagerMapTreeRequiredField
|
|
|
445
445
|
// This cannot use ?? since null is a legal value here.
|
|
446
446
|
assert(
|
|
447
447
|
super.content !== undefined,
|
|
448
|
-
|
|
448
|
+
0xa57 /* Expected EagerMapTree required field to have a value */,
|
|
449
449
|
);
|
|
450
450
|
return super.content;
|
|
451
451
|
}
|
|
@@ -98,7 +98,7 @@ export function getStoredSchema(schema: TreeNodeSchema): TreeNodeStoredSchema {
|
|
|
98
98
|
const kind = schema.kind;
|
|
99
99
|
switch (kind) {
|
|
100
100
|
case NodeKind.Leaf: {
|
|
101
|
-
assert(schema instanceof LeafNodeSchema,
|
|
101
|
+
assert(schema instanceof LeafNodeSchema, 0xa4a /* invalid kind */);
|
|
102
102
|
return new LeafNodeStoredSchema(schema.info);
|
|
103
103
|
}
|
|
104
104
|
case NodeKind.Map: {
|
|
@@ -116,7 +116,7 @@ export function getStoredSchema(schema: TreeNodeSchema): TreeNodeStoredSchema {
|
|
|
116
116
|
return new ObjectNodeStoredSchema(fields);
|
|
117
117
|
}
|
|
118
118
|
case NodeKind.Object: {
|
|
119
|
-
assert(isObjectNodeSchema(schema),
|
|
119
|
+
assert(isObjectNodeSchema(schema), 0xa4b /* invalid kind */);
|
|
120
120
|
const fields: Map<FieldKey, TreeFieldStoredSchema> = new Map();
|
|
121
121
|
for (const field of schema.flexKeyMap.values()) {
|
|
122
122
|
fields.set(field.storedKey, convertField(field.schema));
|