@fluidframework/tree 2.10.0-305357 → 2.10.0-307060
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/.eslintrc.cjs +56 -25
- package/api-report/tree.alpha.api.md +14 -11
- package/api-report/tree.beta.api.md +5 -2
- package/api-report/tree.legacy.alpha.api.md +5 -2
- package/api-report/tree.legacy.public.api.md +5 -2
- package/api-report/tree.public.api.md +5 -2
- package/dist/core/forest/forest.d.ts +5 -1
- package/dist/core/forest/forest.d.ts.map +1 -1
- package/dist/core/forest/forest.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/schema-stored/storedSchemaRepository.d.ts +7 -3
- package/dist/core/schema-stored/storedSchemaRepository.d.ts.map +1 -1
- package/dist/core/schema-stored/storedSchemaRepository.js +4 -6
- package/dist/core/schema-stored/storedSchemaRepository.js.map +1 -1
- package/dist/core/tree/anchorSet.d.ts +8 -5
- package/dist/core/tree/anchorSet.d.ts.map +1 -1
- package/dist/core/tree/anchorSet.js +12 -11
- package/dist/core/tree/anchorSet.js.map +1 -1
- package/dist/events/emitter.d.ts +21 -9
- package/dist/events/emitter.d.ts.map +1 -1
- package/dist/events/emitter.js +36 -21
- package/dist/events/emitter.js.map +1 -1
- package/dist/events/listeners.d.ts +16 -5
- package/dist/events/listeners.d.ts.map +1 -1
- package/dist/events/listeners.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/basicChunk.d.ts +26 -5
- package/dist/feature-libraries/chunked-forest/basicChunk.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/basicChunk.js +15 -5
- package/dist/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/chunkTree.js +1 -1
- package/dist/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/chunkedForest.d.ts +3 -2
- package/dist/feature-libraries/chunked-forest/chunkedForest.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/chunkedForest.js +19 -9
- package/dist/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
- package/dist/feature-libraries/flex-tree/context.d.ts +3 -2
- package/dist/feature-libraries/flex-tree/context.d.ts.map +1 -1
- package/dist/feature-libraries/flex-tree/context.js +3 -3
- package/dist/feature-libraries/flex-tree/context.js.map +1 -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/flex-tree/lazyNode.js +1 -1
- package/dist/feature-libraries/flex-tree/lazyNode.js.map +1 -1
- package/dist/feature-libraries/flex-tree/utilities.js +1 -1
- package/dist/feature-libraries/flex-tree/utilities.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 -2
- package/dist/feature-libraries/index.js.map +1 -1
- package/dist/feature-libraries/modular-schema/comparison.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/comparison.js +3 -0
- package/dist/feature-libraries/modular-schema/comparison.js.map +1 -1
- package/dist/feature-libraries/modular-schema/discrepancies.d.ts +29 -29
- package/dist/feature-libraries/modular-schema/discrepancies.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/discrepancies.js +121 -75
- package/dist/feature-libraries/modular-schema/discrepancies.js.map +1 -1
- package/dist/feature-libraries/modular-schema/genericFieldKind.js +2 -2
- package/dist/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
- package/dist/feature-libraries/modular-schema/index.d.ts +1 -1
- package/dist/feature-libraries/modular-schema/index.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/index.js +2 -2
- package/dist/feature-libraries/modular-schema/index.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/dist/feature-libraries/object-forest/objectForest.d.ts +2 -2
- package/dist/feature-libraries/object-forest/objectForest.d.ts.map +1 -1
- package/dist/feature-libraries/object-forest/objectForest.js +6 -8
- package/dist/feature-libraries/object-forest/objectForest.js.map +1 -1
- package/dist/feature-libraries/schema-index/schemaSummarizer.js +1 -1
- package/dist/feature-libraries/schema-index/schemaSummarizer.js.map +1 -1
- package/dist/feature-libraries/sequence-field/compose.js +2 -2
- package/dist/feature-libraries/sequence-field/compose.js.map +1 -1
- package/dist/feature-libraries/sequence-field/markListFactory.js +1 -1
- package/dist/feature-libraries/sequence-field/markListFactory.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.js +2 -2
- package/dist/shared-tree/schematizingTreeView.js.map +1 -1
- package/dist/shared-tree/treeApi.js +6 -3
- package/dist/shared-tree/treeApi.js.map +1 -1
- package/dist/shared-tree/treeCheckout.js +7 -7
- package/dist/shared-tree/treeCheckout.js.map +1 -1
- package/dist/shared-tree-core/branch.d.ts +7 -7
- package/dist/shared-tree-core/branch.d.ts.map +1 -1
- package/dist/shared-tree-core/branch.js +35 -25
- package/dist/shared-tree-core/branch.js.map +1 -1
- package/dist/shared-tree-core/editManager.js +4 -4
- package/dist/shared-tree-core/editManager.js.map +1 -1
- package/dist/shared-tree-core/sharedTreeCore.js +5 -5
- package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/dist/simple-tree/api/schemaCreationUtilities.d.ts +12 -14
- package/dist/simple-tree/api/schemaCreationUtilities.d.ts.map +1 -1
- package/dist/simple-tree/api/schemaCreationUtilities.js +9 -7
- package/dist/simple-tree/api/schemaCreationUtilities.js.map +1 -1
- package/dist/simple-tree/api/schemaFactory.d.ts +68 -10
- package/dist/simple-tree/api/schemaFactory.d.ts.map +1 -1
- package/dist/simple-tree/api/schemaFactory.js +38 -10
- package/dist/simple-tree/api/schemaFactory.js.map +1 -1
- package/dist/simple-tree/api/schemaFactoryRecursive.js.map +1 -1
- package/dist/simple-tree/api/treeNodeApi.js +4 -4
- package/dist/simple-tree/api/treeNodeApi.js.map +1 -1
- package/dist/simple-tree/arrayNode.js +1 -1
- package/dist/simple-tree/arrayNode.js.map +1 -1
- package/dist/simple-tree/core/treeNodeKernel.d.ts +7 -8
- package/dist/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
- package/dist/simple-tree/core/treeNodeKernel.js +68 -73
- package/dist/simple-tree/core/treeNodeKernel.js.map +1 -1
- package/dist/simple-tree/objectNode.d.ts +1 -1
- package/dist/simple-tree/objectNode.js.map +1 -1
- package/dist/simple-tree/objectNodeTypes.d.ts +3 -0
- package/dist/simple-tree/objectNodeTypes.d.ts.map +1 -1
- package/dist/simple-tree/objectNodeTypes.js +3 -1
- package/dist/simple-tree/objectNodeTypes.js.map +1 -1
- package/dist/simple-tree/proxies.js +1 -1
- package/dist/simple-tree/proxies.js.map +1 -1
- package/dist/simple-tree/schemaTypes.d.ts +26 -1
- package/dist/simple-tree/schemaTypes.d.ts.map +1 -1
- package/dist/simple-tree/schemaTypes.js.map +1 -1
- package/dist/simple-tree/treeNodeValid.js +2 -2
- package/dist/simple-tree/treeNodeValid.js.map +1 -1
- package/dist/util/nestedMap.d.ts.map +1 -1
- package/dist/util/nestedMap.js.map +1 -1
- package/docs/.attachments/object-merge-semantics.drawio +145 -0
- package/docs/user-facing/array-merge-semantics.md +344 -0
- package/docs/user-facing/map-merge-semantics.md +128 -0
- package/docs/user-facing/merge-semantics.md +7 -3
- package/docs/user-facing/object-merge-semantics.md +77 -0
- package/lib/core/forest/forest.d.ts +5 -1
- package/lib/core/forest/forest.d.ts.map +1 -1
- package/lib/core/forest/forest.js.map +1 -1
- package/lib/core/index.d.ts +1 -1
- package/lib/core/index.d.ts.map +1 -1
- package/lib/core/index.js.map +1 -1
- package/lib/core/schema-stored/storedSchemaRepository.d.ts +7 -3
- package/lib/core/schema-stored/storedSchemaRepository.d.ts.map +1 -1
- package/lib/core/schema-stored/storedSchemaRepository.js +4 -6
- package/lib/core/schema-stored/storedSchemaRepository.js.map +1 -1
- package/lib/core/tree/anchorSet.d.ts +8 -5
- package/lib/core/tree/anchorSet.d.ts.map +1 -1
- package/lib/core/tree/anchorSet.js +12 -11
- package/lib/core/tree/anchorSet.js.map +1 -1
- package/lib/events/emitter.d.ts +21 -9
- package/lib/events/emitter.d.ts.map +1 -1
- package/lib/events/emitter.js +37 -22
- package/lib/events/emitter.js.map +1 -1
- package/lib/events/listeners.d.ts +16 -5
- package/lib/events/listeners.d.ts.map +1 -1
- package/lib/events/listeners.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/basicChunk.d.ts +26 -5
- package/lib/feature-libraries/chunked-forest/basicChunk.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/basicChunk.js +15 -5
- package/lib/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/chunkTree.js +1 -1
- package/lib/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/chunkedForest.d.ts +3 -2
- package/lib/feature-libraries/chunked-forest/chunkedForest.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/chunkedForest.js +19 -9
- package/lib/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
- package/lib/feature-libraries/flex-tree/context.d.ts +3 -2
- package/lib/feature-libraries/flex-tree/context.d.ts.map +1 -1
- package/lib/feature-libraries/flex-tree/context.js +3 -3
- package/lib/feature-libraries/flex-tree/context.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/flex-tree/lazyNode.js +1 -1
- package/lib/feature-libraries/flex-tree/lazyNode.js.map +1 -1
- package/lib/feature-libraries/flex-tree/utilities.js +1 -1
- package/lib/feature-libraries/flex-tree/utilities.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/modular-schema/comparison.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/comparison.js +3 -0
- package/lib/feature-libraries/modular-schema/comparison.js.map +1 -1
- package/lib/feature-libraries/modular-schema/discrepancies.d.ts +29 -29
- package/lib/feature-libraries/modular-schema/discrepancies.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/discrepancies.js +120 -74
- package/lib/feature-libraries/modular-schema/discrepancies.js.map +1 -1
- package/lib/feature-libraries/modular-schema/genericFieldKind.js +2 -2
- package/lib/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
- package/lib/feature-libraries/modular-schema/index.d.ts +1 -1
- package/lib/feature-libraries/modular-schema/index.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/index.js +1 -1
- package/lib/feature-libraries/modular-schema/index.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/lib/feature-libraries/object-forest/objectForest.d.ts +2 -2
- package/lib/feature-libraries/object-forest/objectForest.d.ts.map +1 -1
- package/lib/feature-libraries/object-forest/objectForest.js +6 -8
- package/lib/feature-libraries/object-forest/objectForest.js.map +1 -1
- package/lib/feature-libraries/schema-index/schemaSummarizer.js +1 -1
- package/lib/feature-libraries/schema-index/schemaSummarizer.js.map +1 -1
- package/lib/feature-libraries/sequence-field/compose.js +2 -2
- package/lib/feature-libraries/sequence-field/compose.js.map +1 -1
- package/lib/feature-libraries/sequence-field/markListFactory.js +1 -1
- package/lib/feature-libraries/sequence-field/markListFactory.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.js +2 -2
- package/lib/shared-tree/schematizingTreeView.js.map +1 -1
- package/lib/shared-tree/treeApi.js +7 -4
- package/lib/shared-tree/treeApi.js.map +1 -1
- package/lib/shared-tree/treeCheckout.js +7 -7
- package/lib/shared-tree/treeCheckout.js.map +1 -1
- package/lib/shared-tree-core/branch.d.ts +7 -7
- package/lib/shared-tree-core/branch.d.ts.map +1 -1
- package/lib/shared-tree-core/branch.js +36 -26
- package/lib/shared-tree-core/branch.js.map +1 -1
- package/lib/shared-tree-core/editManager.js +4 -4
- package/lib/shared-tree-core/editManager.js.map +1 -1
- package/lib/shared-tree-core/sharedTreeCore.js +5 -5
- package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/lib/simple-tree/api/schemaCreationUtilities.d.ts +12 -14
- package/lib/simple-tree/api/schemaCreationUtilities.d.ts.map +1 -1
- package/lib/simple-tree/api/schemaCreationUtilities.js +9 -7
- package/lib/simple-tree/api/schemaCreationUtilities.js.map +1 -1
- package/lib/simple-tree/api/schemaFactory.d.ts +68 -10
- package/lib/simple-tree/api/schemaFactory.d.ts.map +1 -1
- package/lib/simple-tree/api/schemaFactory.js +38 -10
- package/lib/simple-tree/api/schemaFactory.js.map +1 -1
- package/lib/simple-tree/api/schemaFactoryRecursive.js.map +1 -1
- package/lib/simple-tree/api/treeNodeApi.js +4 -4
- package/lib/simple-tree/api/treeNodeApi.js.map +1 -1
- package/lib/simple-tree/arrayNode.js +1 -1
- package/lib/simple-tree/arrayNode.js.map +1 -1
- package/lib/simple-tree/core/treeNodeKernel.d.ts +7 -8
- package/lib/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
- package/lib/simple-tree/core/treeNodeKernel.js +69 -74
- package/lib/simple-tree/core/treeNodeKernel.js.map +1 -1
- package/lib/simple-tree/objectNode.d.ts +1 -1
- package/lib/simple-tree/objectNode.js.map +1 -1
- package/lib/simple-tree/objectNodeTypes.d.ts +3 -0
- package/lib/simple-tree/objectNodeTypes.d.ts.map +1 -1
- package/lib/simple-tree/objectNodeTypes.js +3 -1
- package/lib/simple-tree/objectNodeTypes.js.map +1 -1
- package/lib/simple-tree/proxies.js +1 -1
- package/lib/simple-tree/proxies.js.map +1 -1
- package/lib/simple-tree/schemaTypes.d.ts +26 -1
- package/lib/simple-tree/schemaTypes.d.ts.map +1 -1
- package/lib/simple-tree/schemaTypes.js.map +1 -1
- package/lib/simple-tree/treeNodeValid.js +2 -2
- package/lib/simple-tree/treeNodeValid.js.map +1 -1
- package/lib/util/nestedMap.d.ts.map +1 -1
- package/lib/util/nestedMap.js.map +1 -1
- package/package.json +20 -20
- package/src/core/forest/forest.ts +6 -1
- package/src/core/index.ts +1 -1
- package/src/core/schema-stored/storedSchemaRepository.ts +10 -13
- package/src/core/tree/anchorSet.ts +13 -20
- package/src/events/emitter.ts +45 -24
- package/src/events/listeners.ts +17 -5
- package/src/feature-libraries/chunked-forest/basicChunk.ts +12 -4
- package/src/feature-libraries/chunked-forest/chunkTree.ts +1 -1
- package/src/feature-libraries/chunked-forest/chunkedForest.ts +13 -14
- package/src/feature-libraries/flex-tree/context.ts +5 -7
- package/src/feature-libraries/flex-tree/lazyField.ts +1 -1
- package/src/feature-libraries/flex-tree/lazyNode.ts +1 -1
- package/src/feature-libraries/flex-tree/utilities.ts +1 -1
- package/src/feature-libraries/index.ts +1 -1
- package/src/feature-libraries/modular-schema/comparison.ts +4 -0
- package/src/feature-libraries/modular-schema/discrepancies.ts +188 -124
- package/src/feature-libraries/modular-schema/genericFieldKind.ts +2 -2
- package/src/feature-libraries/modular-schema/index.ts +4 -1
- package/src/feature-libraries/modular-schema/modularChangeFamily.ts +1 -1
- package/src/feature-libraries/object-forest/objectForest.ts +5 -11
- package/src/feature-libraries/schema-index/schemaSummarizer.ts +1 -1
- package/src/feature-libraries/sequence-field/compose.ts +2 -2
- package/src/feature-libraries/sequence-field/markListFactory.ts +1 -1
- package/src/packageVersion.ts +1 -1
- package/src/shared-tree/schematizingTreeView.ts +2 -2
- package/src/shared-tree/treeApi.ts +9 -7
- package/src/shared-tree/treeCheckout.ts +7 -7
- package/src/shared-tree-core/branch.ts +30 -30
- package/src/shared-tree-core/editManager.ts +4 -4
- package/src/shared-tree-core/sharedTreeCore.ts +5 -5
- package/src/simple-tree/api/schemaCreationUtilities.ts +29 -17
- package/src/simple-tree/api/schemaFactory.ts +62 -29
- package/src/simple-tree/api/schemaFactoryRecursive.ts +1 -1
- package/src/simple-tree/api/treeNodeApi.ts +4 -4
- package/src/simple-tree/arrayNode.ts +1 -1
- package/src/simple-tree/core/treeNodeKernel.ts +68 -72
- package/src/simple-tree/objectNode.ts +1 -1
- package/src/simple-tree/objectNodeTypes.ts +3 -1
- package/src/simple-tree/proxies.ts +1 -1
- package/src/simple-tree/schemaTypes.ts +26 -1
- package/src/simple-tree/treeNodeValid.ts +2 -2
- package/src/util/nestedMap.ts +1 -0
|
@@ -1096,7 +1096,7 @@ export function arraySchema<
|
|
|
1096
1096
|
// Since proxy reports this as a "non-configurable" property, it must exist on the underlying object used as the proxy target, not as an inherited property.
|
|
1097
1097
|
// This should not get used as the proxy should intercept all use.
|
|
1098
1098
|
Object.defineProperty(instance, "length", {
|
|
1099
|
-
value: NaN,
|
|
1099
|
+
value: Number.NaN,
|
|
1100
1100
|
writable: true,
|
|
1101
1101
|
enumerable: false,
|
|
1102
1102
|
configurable: false,
|
|
@@ -17,7 +17,6 @@ import {
|
|
|
17
17
|
assertFlexTreeEntityNotFreed,
|
|
18
18
|
ContextSlot,
|
|
19
19
|
flexTreeSlot,
|
|
20
|
-
isFlexTreeNode,
|
|
21
20
|
isFreedSymbol,
|
|
22
21
|
LazyEntity,
|
|
23
22
|
TreeStatus,
|
|
@@ -71,10 +70,15 @@ export function tryGetTreeNodeSchema(value: unknown): undefined | TreeNodeSchema
|
|
|
71
70
|
}
|
|
72
71
|
|
|
73
72
|
/** The {@link HydrationState} of a {@link TreeNodeKernel} before the kernel is hydrated */
|
|
74
|
-
|
|
73
|
+
interface UnhydratedState {
|
|
74
|
+
off: Off;
|
|
75
|
+
innerNode: UnhydratedFlexTreeNode;
|
|
76
|
+
}
|
|
75
77
|
|
|
76
78
|
/** The {@link HydrationState} of a {@link TreeNodeKernel} after the kernel is hydrated */
|
|
77
79
|
interface HydratedState {
|
|
80
|
+
/** The flex node for this kernel (lazy - undefined if it has not yet been demanded) */
|
|
81
|
+
innerNode?: FlexTreeNode;
|
|
78
82
|
/** The {@link AnchorNode} that this node is associated with. */
|
|
79
83
|
anchorNode: AnchorNode;
|
|
80
84
|
/** All {@link Off | event deregistration functions} that should be run when the kernel is disposed. */
|
|
@@ -86,16 +90,15 @@ type HydrationState = UnhydratedState | HydratedState;
|
|
|
86
90
|
|
|
87
91
|
/** True if and only if the given {@link HydrationState} is post-hydration */
|
|
88
92
|
function isHydrated(state: HydrationState): state is HydratedState {
|
|
89
|
-
return
|
|
93
|
+
return (state as Partial<HydratedState>).anchorNode !== undefined;
|
|
90
94
|
}
|
|
91
95
|
|
|
92
96
|
/**
|
|
93
97
|
* Contains state and an internal API for managing {@link TreeNode}s.
|
|
94
98
|
* @remarks All {@link TreeNode}s have an associated kernel object.
|
|
95
99
|
* The kernel has the same lifetime as the node and spans both its unhydrated and hydrated states.
|
|
96
|
-
* When hydration occurs, the kernel is notified via the {@link TreeNodeKernel.hydrate | hydrate} method.
|
|
97
100
|
*/
|
|
98
|
-
export class TreeNodeKernel
|
|
101
|
+
export class TreeNodeKernel {
|
|
99
102
|
private disposed = false;
|
|
100
103
|
|
|
101
104
|
/**
|
|
@@ -110,7 +113,7 @@ export class TreeNodeKernel implements Listenable<KernelEvents> {
|
|
|
110
113
|
*/
|
|
111
114
|
public generationNumber: number = 0;
|
|
112
115
|
|
|
113
|
-
#hydrationState: HydrationState
|
|
116
|
+
#hydrationState: HydrationState;
|
|
114
117
|
|
|
115
118
|
/**
|
|
116
119
|
* Events registered before hydration.
|
|
@@ -133,7 +136,7 @@ export class TreeNodeKernel implements Listenable<KernelEvents> {
|
|
|
133
136
|
public constructor(
|
|
134
137
|
public readonly node: TreeNode,
|
|
135
138
|
public readonly schema: TreeNodeSchema,
|
|
136
|
-
|
|
139
|
+
innerNode: InnerNode,
|
|
137
140
|
private readonly initialContext: Context,
|
|
138
141
|
) {
|
|
139
142
|
assert(!treeNodeToKernel.has(node), 0xa1a /* only one kernel per node can be made */);
|
|
@@ -144,9 +147,9 @@ export class TreeNodeKernel implements Listenable<KernelEvents> {
|
|
|
144
147
|
mapTreeNodeToProxy.set(innerNode, node);
|
|
145
148
|
// Register for change events from the unhydrated flex node.
|
|
146
149
|
// These will be fired if the unhydrated node is edited, and will also be forwarded later to the hydrated node.
|
|
147
|
-
this.#hydrationState =
|
|
148
|
-
|
|
149
|
-
({ changedFields }) => {
|
|
150
|
+
this.#hydrationState = {
|
|
151
|
+
innerNode,
|
|
152
|
+
off: innerNode.events.on("childrenChangedAfterBatch", ({ changedFields }) => {
|
|
150
153
|
this.#unhydratedEvents.value.emit("childrenChangedAfterBatch", {
|
|
151
154
|
changedFields,
|
|
152
155
|
});
|
|
@@ -161,15 +164,16 @@ export class TreeNodeKernel implements Listenable<KernelEvents> {
|
|
|
161
164
|
// This cast is safe because the parent (if it exists) of an unhydrated flex node is always another unhydrated flex node.
|
|
162
165
|
n = n.parentField.parent.parent as UnhydratedFlexTreeNode | undefined;
|
|
163
166
|
}
|
|
164
|
-
},
|
|
165
|
-
|
|
167
|
+
}),
|
|
168
|
+
};
|
|
166
169
|
} else {
|
|
167
170
|
// Hydrated case
|
|
171
|
+
const { anchorNode } = innerNode;
|
|
168
172
|
assert(
|
|
169
|
-
!
|
|
173
|
+
!anchorNode.slots.has(proxySlot),
|
|
170
174
|
0x7f5 /* Cannot associate an flex node with multiple simple-tree nodes */,
|
|
171
175
|
);
|
|
172
|
-
this.
|
|
176
|
+
this.#hydrationState = this.createHydratedState(anchorNode);
|
|
173
177
|
}
|
|
174
178
|
}
|
|
175
179
|
|
|
@@ -191,27 +195,11 @@ export class TreeNodeKernel implements Listenable<KernelEvents> {
|
|
|
191
195
|
* Happens at most once for any given node.
|
|
192
196
|
* Cleans up mappings to {@link UnhydratedFlexTreeNode} - it is assumed that they are no longer needed once the proxy has an anchor node.
|
|
193
197
|
*/
|
|
194
|
-
|
|
198
|
+
private hydrate(anchorNode: AnchorNode): void {
|
|
195
199
|
assert(!this.disposed, 0xa2a /* cannot hydrate a disposed node */);
|
|
196
200
|
assert(!isHydrated(this.#hydrationState), 0xa2b /* hydration should only happen once */);
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
if (this.innerNode instanceof UnhydratedFlexTreeNode) {
|
|
200
|
-
mapTreeNodeToProxy.delete(this.innerNode);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
// However, it's fine for an anchor node to rotate through different proxies when the content at that place in the tree is replaced.
|
|
204
|
-
anchorNode.slots.set(proxySlot, this.node);
|
|
205
|
-
this.#hydrationState = {
|
|
206
|
-
anchorNode,
|
|
207
|
-
offAnchorNode: new Set([
|
|
208
|
-
anchorNode.on("afterDestroy", () => this.dispose()),
|
|
209
|
-
// TODO: this should be triggered on change even for unhydrated nodes.
|
|
210
|
-
anchorNode.on("childrenChanging", () => {
|
|
211
|
-
this.generationNumber += 1;
|
|
212
|
-
}),
|
|
213
|
-
]),
|
|
214
|
-
};
|
|
201
|
+
mapTreeNodeToProxy.delete(this.#hydrationState.innerNode);
|
|
202
|
+
this.#hydrationState = this.createHydratedState(anchorNode);
|
|
215
203
|
|
|
216
204
|
// If needed, register forwarding emitters for events from before hydration
|
|
217
205
|
if (this.#unhydratedEvents.evaluated) {
|
|
@@ -221,13 +209,27 @@ export class TreeNodeKernel implements Listenable<KernelEvents> {
|
|
|
221
209
|
this.#hydrationState.offAnchorNode.add(
|
|
222
210
|
// Argument is forwarded between matching events, so the type should be correct.
|
|
223
211
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
224
|
-
anchorNode.on(eventName, (arg: any) => events.emit(eventName, arg)),
|
|
212
|
+
anchorNode.events.on(eventName, (arg: any) => events.emit(eventName, arg)),
|
|
225
213
|
);
|
|
226
214
|
}
|
|
227
215
|
}
|
|
228
216
|
}
|
|
229
217
|
}
|
|
230
218
|
|
|
219
|
+
private createHydratedState(anchorNode: AnchorNode): HydratedState {
|
|
220
|
+
anchorNode.slots.set(proxySlot, this.node);
|
|
221
|
+
return {
|
|
222
|
+
anchorNode,
|
|
223
|
+
offAnchorNode: new Set([
|
|
224
|
+
anchorNode.events.on("afterDestroy", () => this.dispose()),
|
|
225
|
+
// TODO: this should be triggered on change even for unhydrated nodes.
|
|
226
|
+
anchorNode.events.on("childrenChanging", () => {
|
|
227
|
+
this.generationNumber += 1;
|
|
228
|
+
}),
|
|
229
|
+
]),
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
|
|
231
233
|
public getStatus(): TreeStatus {
|
|
232
234
|
if (this.disposed) {
|
|
233
235
|
return TreeStatus.Deleted;
|
|
@@ -248,13 +250,11 @@ export class TreeNodeKernel implements Listenable<KernelEvents> {
|
|
|
248
250
|
return treeStatusFromAnchorCache(this.#hydrationState.anchorNode);
|
|
249
251
|
}
|
|
250
252
|
|
|
251
|
-
public
|
|
253
|
+
public get events(): Listenable<KernelEvents> {
|
|
252
254
|
// Retrieve the correct events object based on whether this node is pre or post hydration.
|
|
253
|
-
|
|
254
|
-
? this.#hydrationState.anchorNode
|
|
255
|
+
return isHydrated(this.#hydrationState)
|
|
256
|
+
? this.#hydrationState.anchorNode.events
|
|
255
257
|
: this.#unhydratedEvents.value;
|
|
256
|
-
|
|
257
|
-
return events.on(eventName, listener);
|
|
258
258
|
}
|
|
259
259
|
|
|
260
260
|
public dispose(): void {
|
|
@@ -284,13 +284,12 @@ export class TreeNodeKernel implements Listenable<KernelEvents> {
|
|
|
284
284
|
* Note that for "marinated" nodes, this FlexTreeNode exists and returns it: it does not return the MapTreeNode which is the current InnerNode.
|
|
285
285
|
*/
|
|
286
286
|
public getOrCreateInnerNode(allowFreed = false): InnerNode {
|
|
287
|
-
if (!(this
|
|
288
|
-
//
|
|
289
|
-
return this.innerNode;
|
|
287
|
+
if (!isHydrated(this.#hydrationState)) {
|
|
288
|
+
return this.#hydrationState.innerNode; // Unhydrated case
|
|
290
289
|
}
|
|
291
290
|
|
|
292
|
-
if (
|
|
293
|
-
return this.innerNode;
|
|
291
|
+
if (this.#hydrationState.innerNode !== undefined) {
|
|
292
|
+
return this.#hydrationState.innerNode; // Cooked case
|
|
294
293
|
}
|
|
295
294
|
|
|
296
295
|
// Marinated case -> cooked
|
|
@@ -298,21 +297,23 @@ export class TreeNodeKernel implements Listenable<KernelEvents> {
|
|
|
298
297
|
// The proxy is bound to an anchor node, but it may or may not have an actual flex node yet
|
|
299
298
|
const flexNode = anchorNode.slots.get(flexTreeSlot);
|
|
300
299
|
if (flexNode !== undefined) {
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
300
|
+
// If the flex node already exists, use it...
|
|
301
|
+
this.#hydrationState.innerNode = flexNode;
|
|
302
|
+
} else {
|
|
303
|
+
// ...otherwise, the flex node must be created
|
|
304
|
+
const context = anchorNode.anchorSet.slots.get(ContextSlot) ?? fail("missing context");
|
|
305
|
+
const cursor = context.checkout.forest.allocateCursor("getFlexNode");
|
|
306
|
+
context.checkout.forest.moveCursorToPath(anchorNode, cursor);
|
|
307
|
+
this.#hydrationState.innerNode = makeTree(context, cursor);
|
|
308
|
+
cursor.free();
|
|
309
|
+
// Calling this is a performance improvement, however, do this only after demand to avoid momentarily having no anchors to anchorNode
|
|
310
|
+
anchorForgetters?.get(this.node)?.();
|
|
311
|
+
if (!allowFreed) {
|
|
312
|
+
assertFlexTreeEntityNotFreed(this.#hydrationState.innerNode);
|
|
313
|
+
}
|
|
314
314
|
}
|
|
315
|
-
|
|
315
|
+
|
|
316
|
+
return this.#hydrationState.innerNode;
|
|
316
317
|
}
|
|
317
318
|
|
|
318
319
|
/**
|
|
@@ -339,31 +340,26 @@ export class TreeNodeKernel implements Listenable<KernelEvents> {
|
|
|
339
340
|
off();
|
|
340
341
|
};
|
|
341
342
|
anchorForgetters.set(this.node, forget);
|
|
342
|
-
const off = anchorNode.on("afterDestroy", forget);
|
|
343
|
+
const off = anchorNode.events.on("afterDestroy", forget);
|
|
343
344
|
return anchorNode;
|
|
344
345
|
}
|
|
345
346
|
|
|
346
347
|
/**
|
|
347
348
|
* Retrieves the InnerNode associated with the given target via {@link setInnerNode}, if any.
|
|
348
349
|
* @remarks
|
|
349
|
-
* If `target` is
|
|
350
|
+
* If `target` is an unhydrated node, returns its UnhydratedFlexTreeNode.
|
|
350
351
|
* If `target` is a cooked node (or marinated but a FlexTreeNode exists) returns the FlexTreeNode.
|
|
351
|
-
* If the target is
|
|
352
|
+
* If the target is a marinated node with no FlexTreeNode for its anchor, returns undefined.
|
|
352
353
|
*/
|
|
353
354
|
public tryGetInnerNode(): InnerNode | undefined {
|
|
354
|
-
if (
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
if (!isHydrated(this.#hydrationState)) {
|
|
360
|
-
return this.innerNode;
|
|
355
|
+
if (isHydrated(this.#hydrationState)) {
|
|
356
|
+
return (
|
|
357
|
+
this.#hydrationState.innerNode ??
|
|
358
|
+
this.#hydrationState.anchorNode.slots.get(flexTreeSlot)
|
|
359
|
+
);
|
|
361
360
|
}
|
|
362
361
|
|
|
363
|
-
|
|
364
|
-
const anchorNode = this.#hydrationState.anchorNode;
|
|
365
|
-
// The proxy is bound to an anchor node, but it may or may not have an actual flex node yet
|
|
366
|
-
return anchorNode.slots.get(flexTreeSlot);
|
|
362
|
+
return this.#hydrationState.innerNode;
|
|
367
363
|
}
|
|
368
364
|
}
|
|
369
365
|
|
|
@@ -47,7 +47,7 @@ import { TreeNodeValid, type MostDerivedData } from "./treeNodeValid.js";
|
|
|
47
47
|
import { getUnhydratedContext } from "./createContext.js";
|
|
48
48
|
|
|
49
49
|
/**
|
|
50
|
-
*
|
|
50
|
+
* Generates the properties for an ObjectNode from its field schema object.
|
|
51
51
|
* @system @public
|
|
52
52
|
*/
|
|
53
53
|
export type ObjectFromSchemaRecord<T extends RestrictiveStringRecord<ImplicitFieldSchema>> = {
|
|
@@ -58,7 +58,9 @@ export interface ObjectNodeSchemaInternalData {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
export const ObjectNodeSchema = {
|
|
61
|
-
|
|
61
|
+
/**
|
|
62
|
+
* instanceof-based narrowing support for ObjectNodeSchema in Javascript and TypeScript 5.3 or newer.
|
|
63
|
+
*/
|
|
62
64
|
[Symbol.hasInstance](value: TreeNodeSchema): value is ObjectNodeSchema {
|
|
63
65
|
return isObjectNodeSchema(value);
|
|
64
66
|
},
|
|
@@ -172,7 +172,7 @@ function bindProxies(proxies: RootedProxyPaths[], forest: IForestSubscription):
|
|
|
172
172
|
if (proxies.length > 0) {
|
|
173
173
|
// Creating a new array emits one event per element in the array, so listen to the event once for each element
|
|
174
174
|
let i = 0;
|
|
175
|
-
const off = forest.on("afterRootFieldCreated", (fieldKey) => {
|
|
175
|
+
const off = forest.events.on("afterRootFieldCreated", (fieldKey) => {
|
|
176
176
|
// Non null asserting here because of the length check above
|
|
177
177
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
178
178
|
(proxies[i]!.rootPath as Mutable<UpPath>).parentField = fieldKey;
|
|
@@ -476,9 +476,34 @@ function evaluateLazySchema(value: LazyItem<TreeNodeSchema>): TreeNodeSchema {
|
|
|
476
476
|
}
|
|
477
477
|
|
|
478
478
|
/**
|
|
479
|
-
* Types allowed in a
|
|
479
|
+
* Types of {@link TreeNode|TreeNodes} or {@link TreeLeafValue|TreeLeafValues} allowed at a location in a tree.
|
|
480
480
|
* @remarks
|
|
481
|
+
* Used by {@link TreeViewConfiguration} for the root and various kinds of {@link TreeNodeSchema} to specify their allowed child types.
|
|
482
|
+
*
|
|
483
|
+
* Use {@link SchemaFactory} to access leaf schema or declare new composite schema.
|
|
484
|
+
*
|
|
481
485
|
* Implicitly treats a single type as an array of one type.
|
|
486
|
+
*
|
|
487
|
+
* Arrays of schema can be used to specify multiple types are allowed, which result in unions of those types in the Tree APIs.
|
|
488
|
+
*
|
|
489
|
+
* When saved into variables, avoid type-erasing the details, as doing so loses the compile time schema awareness of APIs derived from the types.
|
|
490
|
+
*
|
|
491
|
+
* When referring to types that are declared after the definition of the `ImplicitAllowedTypes`, the schema can be wrapped in a lambda to allow the forward reference.
|
|
492
|
+
* See {@link ValidateRecursiveSchema} for details on how to structure the `ImplicitAllowedTypes` instances when constructing recursive schema.
|
|
493
|
+
*
|
|
494
|
+
* @example Explicit use with strong typing
|
|
495
|
+
* ```typescript
|
|
496
|
+
* const sf = new SchemaFactory("myScope");
|
|
497
|
+
* const childTypes = [sf.number, sf.string] as const satisfies ImplicitAllowedTypes;
|
|
498
|
+
* const config = new TreeViewConfiguration({ schema: childTypes });
|
|
499
|
+
* ```
|
|
500
|
+
*
|
|
501
|
+
* @example Forward reference
|
|
502
|
+
* ```typescript
|
|
503
|
+
* const sf = new SchemaFactory("myScope");
|
|
504
|
+
* class A extends sf.array("example", [() => B]) {}
|
|
505
|
+
* class B extends sf.array("Inner", sf.number) {}
|
|
506
|
+
* ```
|
|
482
507
|
* @public
|
|
483
508
|
*/
|
|
484
509
|
export type ImplicitAllowedTypes = AllowedTypes | TreeNodeSchema;
|
|
@@ -103,7 +103,7 @@ export abstract class TreeNodeValid<TInput> extends TreeNode {
|
|
|
103
103
|
// would not see the stored `constructorCached`, and the validation above against multiple derived classes would not work.
|
|
104
104
|
|
|
105
105
|
// This is not just an alias of `this`, but a reference to the item in the prototype chain being walked, which happens to start at `this`.
|
|
106
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
106
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias, unicorn/no-this-assignment
|
|
107
107
|
let schemaBase: typeof TreeNodeValid = this;
|
|
108
108
|
while (!Object.prototype.hasOwnProperty.call(schemaBase, "constructorCached")) {
|
|
109
109
|
schemaBase = Reflect.getPrototypeOf(schemaBase) as typeof TreeNodeValid;
|
|
@@ -300,7 +300,7 @@ function formattedReference(
|
|
|
300
300
|
object: unknown,
|
|
301
301
|
config?: DevtoolsFormatter.ObjectConfig,
|
|
302
302
|
): DevtoolsFormatter.Item {
|
|
303
|
-
if (
|
|
303
|
+
if (object === undefined) {
|
|
304
304
|
return ["span", "undefined"];
|
|
305
305
|
} else if (object === "null") {
|
|
306
306
|
return ["span", "null"];
|