@fluidframework/tree 2.43.0-343119 → 2.43.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 +189 -0
- package/api-report/tree.alpha.api.md +13 -4
- package/api-report/tree.beta.api.md +1 -0
- package/api-report/tree.legacy.alpha.api.md +1 -0
- package/api-report/tree.legacy.public.api.md +1 -0
- package/api-report/tree.public.api.md +1 -0
- package/dist/alpha.d.ts +1 -0
- package/dist/feature-libraries/flex-tree/flexTreeTypes.d.ts +1 -1
- package/dist/feature-libraries/flex-tree/flexTreeTypes.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.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.d.ts.map +1 -1
- package/dist/shared-tree/schematizingTreeView.js +3 -3
- package/dist/shared-tree/schematizingTreeView.js.map +1 -1
- package/dist/shared-tree/treeAlpha.d.ts +38 -0
- package/dist/shared-tree/treeAlpha.d.ts.map +1 -1
- package/dist/shared-tree/treeAlpha.js +114 -9
- package/dist/shared-tree/treeAlpha.js.map +1 -1
- package/dist/simple-tree/api/configuration.d.ts +15 -3
- package/dist/simple-tree/api/configuration.d.ts.map +1 -1
- package/dist/simple-tree/api/configuration.js +40 -22
- package/dist/simple-tree/api/configuration.js.map +1 -1
- package/dist/simple-tree/api/index.d.ts +1 -1
- package/dist/simple-tree/api/index.d.ts.map +1 -1
- package/dist/simple-tree/api/index.js +4 -4
- package/dist/simple-tree/api/index.js.map +1 -1
- package/dist/simple-tree/api/treeNodeApi.d.ts +3 -0
- package/dist/simple-tree/api/treeNodeApi.d.ts.map +1 -1
- package/dist/simple-tree/api/treeNodeApi.js +1 -1
- package/dist/simple-tree/api/treeNodeApi.js.map +1 -1
- package/dist/simple-tree/core/context.d.ts +3 -3
- package/dist/simple-tree/core/context.d.ts.map +1 -1
- package/dist/simple-tree/core/context.js.map +1 -1
- package/dist/simple-tree/core/getOrCreateNode.d.ts +9 -0
- package/dist/simple-tree/core/getOrCreateNode.d.ts.map +1 -1
- package/dist/simple-tree/core/getOrCreateNode.js +12 -1
- package/dist/simple-tree/core/getOrCreateNode.js.map +1 -1
- package/dist/simple-tree/core/index.d.ts +2 -2
- package/dist/simple-tree/core/index.d.ts.map +1 -1
- package/dist/simple-tree/core/index.js +3 -1
- package/dist/simple-tree/core/index.js.map +1 -1
- package/dist/simple-tree/core/treeNodeKernel.js +1 -1
- package/dist/simple-tree/core/treeNodeKernel.js.map +1 -1
- package/dist/simple-tree/core/treeNodeSchema.d.ts +68 -1
- package/dist/simple-tree/core/treeNodeSchema.d.ts.map +1 -1
- package/dist/simple-tree/core/treeNodeSchema.js +24 -1
- package/dist/simple-tree/core/treeNodeSchema.js.map +1 -1
- package/dist/simple-tree/core/walkSchema.d.ts +3 -3
- package/dist/simple-tree/core/walkSchema.d.ts.map +1 -1
- package/dist/simple-tree/core/walkSchema.js +9 -5
- package/dist/simple-tree/core/walkSchema.js.map +1 -1
- package/dist/simple-tree/createContext.js +1 -1
- package/dist/simple-tree/createContext.js.map +1 -1
- package/dist/simple-tree/getTreeNodeForField.d.ts +1 -1
- package/dist/simple-tree/getTreeNodeForField.d.ts.map +1 -1
- package/dist/simple-tree/getTreeNodeForField.js +3 -3
- package/dist/simple-tree/getTreeNodeForField.js.map +1 -1
- package/dist/simple-tree/index.d.ts +5 -5
- package/dist/simple-tree/index.d.ts.map +1 -1
- package/dist/simple-tree/index.js +8 -5
- package/dist/simple-tree/index.js.map +1 -1
- package/dist/simple-tree/leafNodeSchema.d.ts +2 -1
- package/dist/simple-tree/leafNodeSchema.d.ts.map +1 -1
- package/dist/simple-tree/leafNodeSchema.js +1 -0
- package/dist/simple-tree/leafNodeSchema.js.map +1 -1
- package/dist/simple-tree/node-kinds/array/arrayNode.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/array/arrayNode.js +18 -15
- package/dist/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
- package/dist/simple-tree/node-kinds/map/mapNode.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/map/mapNode.js +7 -3
- package/dist/simple-tree/node-kinds/map/mapNode.js.map +1 -1
- package/dist/simple-tree/node-kinds/object/objectNode.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/object/objectNode.js +9 -6
- package/dist/simple-tree/node-kinds/object/objectNode.js.map +1 -1
- package/dist/simple-tree/schemaTypes.d.ts +13 -27
- package/dist/simple-tree/schemaTypes.d.ts.map +1 -1
- package/dist/simple-tree/schemaTypes.js +45 -39
- package/dist/simple-tree/schemaTypes.js.map +1 -1
- package/dist/simple-tree/toStoredSchema.d.ts +2 -0
- package/dist/simple-tree/toStoredSchema.d.ts.map +1 -1
- package/dist/simple-tree/toStoredSchema.js +2 -0
- package/dist/simple-tree/toStoredSchema.js.map +1 -1
- package/dist/simple-tree/treeNodeValid.d.ts.map +1 -1
- package/dist/simple-tree/treeNodeValid.js +1 -2
- package/dist/simple-tree/treeNodeValid.js.map +1 -1
- package/dist/simple-tree/walkFieldSchema.d.ts.map +1 -1
- package/dist/simple-tree/walkFieldSchema.js +1 -1
- package/dist/simple-tree/walkFieldSchema.js.map +1 -1
- package/lib/alpha.d.ts +1 -0
- package/lib/feature-libraries/flex-tree/flexTreeTypes.d.ts +1 -1
- package/lib/feature-libraries/flex-tree/flexTreeTypes.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.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.d.ts.map +1 -1
- package/lib/shared-tree/schematizingTreeView.js +4 -4
- package/lib/shared-tree/schematizingTreeView.js.map +1 -1
- package/lib/shared-tree/treeAlpha.d.ts +38 -0
- package/lib/shared-tree/treeAlpha.d.ts.map +1 -1
- package/lib/shared-tree/treeAlpha.js +108 -3
- package/lib/shared-tree/treeAlpha.js.map +1 -1
- package/lib/simple-tree/api/configuration.d.ts +15 -3
- package/lib/simple-tree/api/configuration.d.ts.map +1 -1
- package/lib/simple-tree/api/configuration.js +42 -24
- package/lib/simple-tree/api/configuration.js.map +1 -1
- package/lib/simple-tree/api/index.d.ts +1 -1
- package/lib/simple-tree/api/index.d.ts.map +1 -1
- package/lib/simple-tree/api/index.js +1 -1
- package/lib/simple-tree/api/index.js.map +1 -1
- package/lib/simple-tree/api/treeNodeApi.d.ts +3 -0
- package/lib/simple-tree/api/treeNodeApi.d.ts.map +1 -1
- package/lib/simple-tree/api/treeNodeApi.js +2 -2
- package/lib/simple-tree/api/treeNodeApi.js.map +1 -1
- package/lib/simple-tree/core/context.d.ts +3 -3
- package/lib/simple-tree/core/context.d.ts.map +1 -1
- package/lib/simple-tree/core/context.js.map +1 -1
- package/lib/simple-tree/core/getOrCreateNode.d.ts +9 -0
- package/lib/simple-tree/core/getOrCreateNode.d.ts.map +1 -1
- package/lib/simple-tree/core/getOrCreateNode.js +10 -0
- package/lib/simple-tree/core/getOrCreateNode.js.map +1 -1
- package/lib/simple-tree/core/index.d.ts +2 -2
- package/lib/simple-tree/core/index.d.ts.map +1 -1
- package/lib/simple-tree/core/index.js +2 -2
- package/lib/simple-tree/core/index.js.map +1 -1
- package/lib/simple-tree/core/treeNodeKernel.js +1 -1
- package/lib/simple-tree/core/treeNodeKernel.js.map +1 -1
- package/lib/simple-tree/core/treeNodeSchema.d.ts +68 -1
- package/lib/simple-tree/core/treeNodeSchema.d.ts.map +1 -1
- package/lib/simple-tree/core/treeNodeSchema.js +21 -0
- package/lib/simple-tree/core/treeNodeSchema.js.map +1 -1
- package/lib/simple-tree/core/walkSchema.d.ts +3 -3
- package/lib/simple-tree/core/walkSchema.d.ts.map +1 -1
- package/lib/simple-tree/core/walkSchema.js +9 -5
- package/lib/simple-tree/core/walkSchema.js.map +1 -1
- package/lib/simple-tree/createContext.js +1 -1
- package/lib/simple-tree/createContext.js.map +1 -1
- package/lib/simple-tree/getTreeNodeForField.d.ts +1 -1
- package/lib/simple-tree/getTreeNodeForField.d.ts.map +1 -1
- package/lib/simple-tree/getTreeNodeForField.js +1 -1
- package/lib/simple-tree/getTreeNodeForField.js.map +1 -1
- package/lib/simple-tree/index.d.ts +5 -5
- package/lib/simple-tree/index.d.ts.map +1 -1
- package/lib/simple-tree/index.js +4 -4
- package/lib/simple-tree/index.js.map +1 -1
- package/lib/simple-tree/leafNodeSchema.d.ts +2 -1
- package/lib/simple-tree/leafNodeSchema.d.ts.map +1 -1
- package/lib/simple-tree/leafNodeSchema.js +2 -1
- package/lib/simple-tree/leafNodeSchema.js.map +1 -1
- package/lib/simple-tree/node-kinds/array/arrayNode.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/array/arrayNode.js +10 -7
- package/lib/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
- package/lib/simple-tree/node-kinds/map/mapNode.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/map/mapNode.js +9 -5
- package/lib/simple-tree/node-kinds/map/mapNode.js.map +1 -1
- package/lib/simple-tree/node-kinds/object/objectNode.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/object/objectNode.js +11 -8
- package/lib/simple-tree/node-kinds/object/objectNode.js.map +1 -1
- package/lib/simple-tree/schemaTypes.d.ts +13 -27
- package/lib/simple-tree/schemaTypes.d.ts.map +1 -1
- package/lib/simple-tree/schemaTypes.js +42 -35
- package/lib/simple-tree/schemaTypes.js.map +1 -1
- package/lib/simple-tree/toStoredSchema.d.ts +2 -0
- package/lib/simple-tree/toStoredSchema.d.ts.map +1 -1
- package/lib/simple-tree/toStoredSchema.js +2 -0
- package/lib/simple-tree/toStoredSchema.js.map +1 -1
- package/lib/simple-tree/treeNodeValid.d.ts.map +1 -1
- package/lib/simple-tree/treeNodeValid.js +1 -2
- package/lib/simple-tree/treeNodeValid.js.map +1 -1
- package/lib/simple-tree/walkFieldSchema.d.ts.map +1 -1
- package/lib/simple-tree/walkFieldSchema.js +1 -1
- package/lib/simple-tree/walkFieldSchema.js.map +1 -1
- package/package.json +22 -22
- package/src/feature-libraries/flex-tree/flexTreeTypes.ts +1 -1
- package/src/index.ts +1 -0
- package/src/packageVersion.ts +1 -1
- package/src/shared-tree/schematizingTreeView.ts +8 -5
- package/src/shared-tree/treeAlpha.ts +188 -3
- package/src/simple-tree/api/configuration.ts +59 -27
- package/src/simple-tree/api/index.ts +3 -3
- package/src/simple-tree/api/treeNodeApi.ts +5 -2
- package/src/simple-tree/core/context.ts +3 -3
- package/src/simple-tree/core/getOrCreateNode.ts +14 -0
- package/src/simple-tree/core/index.ts +7 -1
- package/src/simple-tree/core/treeNodeKernel.ts +1 -1
- package/src/simple-tree/core/treeNodeSchema.ts +113 -1
- package/src/simple-tree/core/walkSchema.ts +16 -7
- package/src/simple-tree/createContext.ts +1 -1
- package/src/simple-tree/getTreeNodeForField.ts +3 -1
- package/src/simple-tree/index.ts +9 -5
- package/src/simple-tree/leafNodeSchema.ts +7 -1
- package/src/simple-tree/node-kinds/array/arrayNode.ts +15 -9
- package/src/simple-tree/node-kinds/map/mapNode.ts +10 -4
- package/src/simple-tree/node-kinds/object/objectNode.ts +20 -11
- package/src/simple-tree/schemaTypes.ts +55 -64
- package/src/simple-tree/toStoredSchema.ts +2 -0
- package/src/simple-tree/treeNodeValid.ts +1 -1
- package/src/simple-tree/walkFieldSchema.ts +5 -1
|
@@ -43,24 +43,29 @@ class TreeViewConfiguration {
|
|
|
43
43
|
this.preventAmbiguity = config.preventAmbiguity;
|
|
44
44
|
// Ambiguity errors are lower priority to report than invalid schema errors, so collect these in an array and report them all at once.
|
|
45
45
|
const ambiguityErrors = [];
|
|
46
|
+
// Eagerly perform this conversion to surface errors sooner.
|
|
47
|
+
// Includes detection of duplicate schema identifiers.
|
|
48
|
+
(0, toStoredSchema_js_1.toStoredSchema)(config.schema);
|
|
49
|
+
const definitions = new Map();
|
|
46
50
|
(0, walkFieldSchema_js_1.walkFieldSchema)(config.schema, {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
node: (schema) => {
|
|
52
|
+
// Ensure all reachable schema are marked as most derived.
|
|
53
|
+
// This ensures if multiple schema extending the same schema factory generated class are present (or have had instances of them constructed, or get instances of them constructed in the future),
|
|
54
|
+
// an error is reported.
|
|
55
|
+
(0, schemaTypes_js_1.markSchemaMostDerived)(schema, true);
|
|
56
|
+
(0, internal_1.debugAssert)(() => !definitions.has(schema.identifier));
|
|
57
|
+
definitions.set(schema.identifier, schema);
|
|
58
|
+
},
|
|
59
|
+
allowedTypes({ types }) {
|
|
60
|
+
checkUnion(types.map((t) => (0, schemaTypes_js_1.evaluateLazySchema)((0, schemaTypes_js_1.isAnnotatedAllowedType)(t) ? t.type : t)), config.preventAmbiguity, ambiguityErrors);
|
|
55
61
|
},
|
|
56
62
|
});
|
|
63
|
+
this.definitionsInternal = definitions;
|
|
57
64
|
if (ambiguityErrors.length !== 0) {
|
|
58
65
|
// Duplicate errors are common since when two types conflict, both orders error:
|
|
59
66
|
const deduplicated = new Set(ambiguityErrors);
|
|
60
67
|
throw new internal_2.UsageError(`Ambiguous schema found:\n${[...deduplicated].join("\n")}`);
|
|
61
68
|
}
|
|
62
|
-
// Eagerly perform this conversion to surface errors sooner.
|
|
63
|
-
(0, toStoredSchema_js_1.toStoredSchema)(config.schema);
|
|
64
69
|
}
|
|
65
70
|
}
|
|
66
71
|
exports.TreeViewConfiguration = TreeViewConfiguration;
|
|
@@ -69,14 +74,15 @@ exports.TreeViewConfiguration = TreeViewConfiguration;
|
|
|
69
74
|
* @sealed @alpha
|
|
70
75
|
*/
|
|
71
76
|
class TreeViewConfigurationAlpha extends TreeViewConfiguration {
|
|
77
|
+
/**
|
|
78
|
+
* {@inheritDoc TreeSchema.definitions}
|
|
79
|
+
*/
|
|
80
|
+
get definitions() {
|
|
81
|
+
return this.definitionsInternal;
|
|
82
|
+
}
|
|
72
83
|
constructor(props) {
|
|
73
84
|
super(props);
|
|
74
85
|
this.root = (0, schemaTypes_js_1.normalizeFieldSchema)(props.schema);
|
|
75
|
-
const definitions = new Map();
|
|
76
|
-
(0, walkFieldSchema_js_1.walkFieldSchema)(props.schema, {
|
|
77
|
-
node: (schema) => definitions.set(schema.identifier, schema),
|
|
78
|
-
});
|
|
79
|
-
this.definitions = definitions;
|
|
80
86
|
}
|
|
81
87
|
}
|
|
82
88
|
exports.TreeViewConfigurationAlpha = TreeViewConfigurationAlpha;
|
|
@@ -89,9 +95,17 @@ function formatTypes(allowed) {
|
|
|
89
95
|
return `[${Array.from(allowed, (s) => JSON.stringify(s.identifier)).join(", ")}]`;
|
|
90
96
|
}
|
|
91
97
|
/**
|
|
92
|
-
*
|
|
98
|
+
* Check if union contents are valid (shallowly).
|
|
99
|
+
*
|
|
100
|
+
* @param union - The union of {@link TreeNodeSchema} to check.
|
|
101
|
+
* @param preventAmbiguity - If true, detect cases documented in {@link ITreeConfigurationOptions.preventAmbiguity}, reporting them to `ambiguityErrors`.
|
|
102
|
+
* @param ambiguityErrors - An array into which this function inserts any ambiguity errors, see {@link ITreeConfigurationOptions.preventAmbiguity}.
|
|
103
|
+
*
|
|
104
|
+
* @remarks
|
|
105
|
+
* Includes checks for non-ambiguity errors as well: such as duplicate schemas in the union.
|
|
106
|
+
* Any non-ambiguity errors are thrown as exceptions: `UsageError`s if causable by incorrect API use, and asserts if violating internal invariants.
|
|
93
107
|
*/
|
|
94
|
-
function checkUnion(union,
|
|
108
|
+
function checkUnion(union, preventAmbiguity, ambiguityErrors) {
|
|
95
109
|
const checked = new Set();
|
|
96
110
|
const maps = [];
|
|
97
111
|
const arrays = [];
|
|
@@ -120,17 +134,21 @@ function checkUnion(union, errors) {
|
|
|
120
134
|
maps.push(schema);
|
|
121
135
|
}
|
|
122
136
|
}
|
|
137
|
+
if (!preventAmbiguity) {
|
|
138
|
+
// All remaining checks are for the preventAmbiguity case, so skip them if not enabled.
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
123
141
|
if (arrays.length > 1) {
|
|
124
|
-
|
|
142
|
+
ambiguityErrors.push(`More than one kind of array allowed within union (${formatTypes(arrays)}). This would require type disambiguation which is not supported by arrays during import or export.`);
|
|
125
143
|
}
|
|
126
144
|
if (maps.length > 1) {
|
|
127
|
-
|
|
145
|
+
ambiguityErrors.push(`More than one kind of map allowed within union (${formatTypes(maps)}). This would require type disambiguation which is not supported by maps during import or export.`);
|
|
128
146
|
}
|
|
129
147
|
if (maps.length > 0 && arrays.length > 0) {
|
|
130
|
-
|
|
148
|
+
ambiguityErrors.push(`Both a map and an array allowed within union (${formatTypes([...arrays, ...maps])}). Both can be implicitly constructed from iterables like arrays, which are ambiguous when the array is empty.`);
|
|
131
149
|
}
|
|
132
150
|
if (objects.length > 0 && maps.length > 0) {
|
|
133
|
-
|
|
151
|
+
ambiguityErrors.push(`Both a object and a map allowed within union (${formatTypes([...objects, ...maps])}). Both can be constructed from objects and can be ambiguous.`);
|
|
134
152
|
}
|
|
135
153
|
// Check for objects which fully overlap:
|
|
136
154
|
for (const schema of objects) {
|
|
@@ -155,7 +173,7 @@ function checkUnion(union, errors) {
|
|
|
155
173
|
// Add "constant" fields which can be used to disambiguate even more cases without adding persisted data: maybe make them optional in constructor?
|
|
156
174
|
// Consider separating unambiguous implicit construction format from constructor arguments at type level, allowing constructor to superset the implicit construction options (ex: optional constant fields).
|
|
157
175
|
// The policy here however must remain at least as conservative as shallowCompatibilityTest in src/simple-tree/unhydratedFlexTreeFromInsertable.ts.
|
|
158
|
-
|
|
176
|
+
ambiguityErrors.push(`The required fields of ${JSON.stringify(schema.identifier)} are insufficient to differentiate it from the following types: ${formatTypes(possiblyAmbiguous)}. For objects to be considered unambiguous, each must have required fields that do not all occur on any other object in the union.`);
|
|
159
177
|
}
|
|
160
178
|
}
|
|
161
179
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configuration.js","sourceRoot":"","sources":["../../../src/simple-tree/api/configuration.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, fail } from \"@fluidframework/core-utils/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport {\n\ttype FieldSchemaAlpha,\n\ttype ImplicitFieldSchema,\n\tFieldKind,\n\tmarkSchemaMostDerived,\n\tnormalizeFieldSchema,\n} from \"../schemaTypes.js\";\nimport { NodeKind, type TreeNodeSchema } from \"../core/index.js\";\nimport { toStoredSchema } from \"../toStoredSchema.js\";\nimport { LeafNodeSchema } from \"../leafNodeSchema.js\";\nimport { isObjectNodeSchema, type ObjectNodeSchema } from \"../node-kinds/index.js\";\nimport { getOrCreate } from \"../../util/index.js\";\nimport type { MakeNominal } from \"../../util/index.js\";\nimport { walkFieldSchema } from \"../walkFieldSchema.js\";\nimport type { SimpleNodeSchema, SimpleTreeSchema } from \"../simpleSchema.js\";\n\n/**\n * Options when constructing a tree view.\n * @public\n */\nexport interface ITreeConfigurationOptions {\n\t/**\n\t * If `true`, the tree will validate new content against its stored schema at insertion time\n\t * and throw an error if the new content doesn't match the expected schema.\n\t *\n\t * @defaultValue `false`.\n\t *\n\t * @remarks Enabling schema validation has a performance penalty when inserting new content into the tree because\n\t * additional checks are done. Enable this option only in scenarios where you are ok with that operation being a\n\t * bit slower.\n\t */\n\tenableSchemaValidation?: boolean;\n\n\t/**\n\t * A flag used to opt into strict rules ensuring that the schema avoids cases which can make the type of nodes ambiguous when importing or exporting data.\n\t * @defaultValue `false`.\n\t *\n\t * @remarks\n\t * When this is true, it ensures that the compile time type safety for data when constructing nodes is sufficient to ensure that the runtime behavior will not give node data ambiguity errors.\n\t *\n\t * This ensures that the canonical JSON-like representation of all unions in the tree are lossless and unambiguous.\n\t * This canonical JSON-like representation consists of arrays, plain old JavaScript objects with string keys, booleans, numbers (excluding NaN, -0 and infinities), strings, null and {@link @fluidframework/core-interfaces#IFluidHandle}s.\n\t * It is compatible with the node creation APIs (such as schema class constructors) and is also compatible with JSON assuming any IFluidHandles get special handling (since they are not JSON compatible).\n\t * Currently these cases can cause ambiguity in a union:\n\t *\n\t * - More than one ArrayNode type: it's impossible to tell which array type is intended in the case of empty arrays (`[]`).\n\t *\n\t * - More than one MapNode type: it's impossible to tell which map type is intended in the case of an empty map (`{}`).\n\t *\n\t * - Both a MapNode and an ArrayNode: this case is not a problem for the canonical JSON representation, but is an issue when constructing from an Iterable, which is supported for both MapNode and ArrayNode.\n\t *\n\t * - Both a MapNode and an ObjectNode: when the input is valid for the ObjectNode, the current parser always considers it ambiguous with being a MapNode.\n\t *\n\t * - ObjectNodes which have fields (required or optional) which include all required fields of another ObjectNode: currently each ObjectNode is differentiated by the presence of its required fields.\n\t *\n\t * This check is conservative: some complex cases may error if the current simple algorithm cannot show no ambiguity is possible.\n\t * This check may become more permissive over time.\n\t *\n\t * @example Ambiguous schema (with `preventAmbiguity: false`), and how to disambiguate it using {@link Unhydrated} nodes:\n\t * ```typescript\n\t * const schemaFactory = new SchemaFactory(\"com.example\");\n\t * class Feet extends schemaFactory.object(\"Feet\", { length: schemaFactory.number }) {}\n\t * class Meters extends schemaFactory.object(\"Meters\", { length: schemaFactory.number }) {}\n\t * const config = new TreeViewConfiguration({\n\t * \t// This combination of schema can lead to ambiguous cases and will error if `preventAmbiguity` is true.\n\t * \tschema: [Feet, Meters],\n\t * \tpreventAmbiguity: false,\n\t * });\n\t * const view = tree.viewWith(config);\n\t * // This is invalid since it is ambiguous which type of node is being constructed:\n\t * // view.initialize({ length: 5 });\n\t * // To work, an explicit type can be provided by using an {@link Unhydrated} Node:\n\t * view.initialize(new Meters({ length: 5 }));\n\t * ```\n\t *\n\t * @example Schema disambiguated by adjusting field names, validated with `preventAmbiguity: true:`\n\t * ```typescript\n\t * const schemaFactory = new SchemaFactory(\"com.example\");\n\t * class Feet extends schemaFactory.object(\"Feet\", { length: schemaFactory.number }) {}\n\t * class Meters extends schemaFactory.object(\"Meters\", {\n\t * \t// To avoid ambiguity when parsing unions of Feet and Meters, this renames the length field to \"meters\".\n\t * \t// To preserve compatibility with existing data from the ambiguous case,\n\t * \t// `{ key: \"length\" }` is set, so when persisted in the tree \"length\" is used as the field name.\n\t * \tmeters: schemaFactory.required(schemaFactory.number, { key: \"length\" }),\n\t * }) {}\n\t * const config = new TreeViewConfiguration({\n\t * \t// This combination of schema is not ambiguous because `Feet` and `Meters` have different required keys.\n\t * \tschema: [Feet, Meters],\n\t * \tpreventAmbiguity: true,\n\t * });\n\t * const view = tree.viewWith(config);\n\t * // This now works, since the field is sufficient to determine this is a `Meters` node.\n\t * view.initialize({ meters: 5 });\n\t * ```\n\t *\n\t * @privateRemarks\n\t * In the future, we can support lossless round tripping via the canonical JSON-like representation above when unambiguous.\n\t * This could be done via methods added to `Tree` to export and import such objects, which would give us a place to explicitly define the type of this representation.\n\t *\n\t * To make this more permissive in the future we can:\n\t *\n\t * - Make unhydratedFlexTreeFromInsertable more permissive (ex: allow disambiguation based on leaf type)\n\t * - Update this check to more tightly match unhydratedFlexTreeFromInsertable\n\t * - Add options to help schema authors disambiguate their types, such as \"constant fields\" which are not persisted, and always have a constant value.\n\t *\n\t * The above examples exist in executable form in this files tests, and should be updated there then copied back here.\n\t */\n\treadonly preventAmbiguity?: boolean;\n}\n\nconst defaultTreeConfigurationOptions: Required<ITreeConfigurationOptions> = {\n\tenableSchemaValidation: false,\n\tpreventAmbiguity: false,\n};\n\n/**\n * Property-bag configuration for {@link TreeViewConfiguration} construction.\n * @public\n */\nexport interface ITreeViewConfiguration<\n\tTSchema extends ImplicitFieldSchema = ImplicitFieldSchema,\n> extends ITreeConfigurationOptions {\n\t/**\n\t * The schema which the application wants to view the tree with.\n\t */\n\treadonly schema: TSchema;\n}\n\n/**\n * Configuration for {@link ViewableTree.viewWith}.\n * @sealed @public\n */\nexport class TreeViewConfiguration<\n\tconst TSchema extends ImplicitFieldSchema = ImplicitFieldSchema,\n> implements Required<ITreeViewConfiguration<TSchema>>\n{\n\tprotected _typeCheck!: MakeNominal;\n\n\t/**\n\t * {@inheritDoc ITreeViewConfiguration.schema}\n\t */\n\tpublic readonly schema: TSchema;\n\n\t/**\n\t * {@inheritDoc ITreeConfigurationOptions.enableSchemaValidation}\n\t */\n\tpublic readonly enableSchemaValidation: boolean;\n\n\t/**\n\t * {@inheritDoc ITreeConfigurationOptions.preventAmbiguity}\n\t */\n\tpublic readonly preventAmbiguity: boolean;\n\n\t/**\n\t * Construct a new {@link TreeViewConfiguration}.\n\t *\n\t * @param props - Property bag of configuration options.\n\t *\n\t * @remarks\n\t * Performing this construction deeply validates the provided schema.\n\t * This means that when this constructor is called, all {@link LazyItem} {@link TreeNodeSchema} references will be evaluated (using {@link evaluateLazySchema}).\n\t * This means that the declarations for all transitively reachable {@link TreeNodeSchema} must be available at this time.\n\t *\n\t * For example, a schema reachable from this configuration cannot reference this configuration during its declaration,\n\t * since this would be a cyclic dependency that will cause an error when constructing this configuration.\n\t */\n\tpublic constructor(props: ITreeViewConfiguration<TSchema>) {\n\t\tconst config = { ...defaultTreeConfigurationOptions, ...props };\n\t\tthis.schema = config.schema;\n\t\tthis.enableSchemaValidation = config.enableSchemaValidation;\n\t\tthis.preventAmbiguity = config.preventAmbiguity;\n\n\t\t// Ambiguity errors are lower priority to report than invalid schema errors, so collect these in an array and report them all at once.\n\t\tconst ambiguityErrors: string[] = [];\n\n\t\twalkFieldSchema(config.schema, {\n\t\t\t// Ensure all reachable schema are marked as most derived.\n\t\t\t// This ensures if multiple schema extending the same schema factory generated class are present (or have been constructed, or get constructed in the future),\n\t\t\t// an error is reported.\n\n\t\t\tnode: (schema) => markSchemaMostDerived(schema, true),\n\t\t\tallowedTypes(types): void {\n\t\t\t\tif (config.preventAmbiguity) {\n\t\t\t\t\tcheckUnion(types, ambiguityErrors);\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\n\t\tif (ambiguityErrors.length !== 0) {\n\t\t\t// Duplicate errors are common since when two types conflict, both orders error:\n\t\t\tconst deduplicated = new Set(ambiguityErrors);\n\t\t\tthrow new UsageError(`Ambiguous schema found:\\n${[...deduplicated].join(\"\\n\")}`);\n\t\t}\n\n\t\t// Eagerly perform this conversion to surface errors sooner.\n\t\ttoStoredSchema(config.schema);\n\t}\n}\n\n/**\n * {@link TreeViewConfiguration} extended with some alpha APIs.\n * @sealed @alpha\n */\nexport class TreeViewConfigurationAlpha<\n\t\tconst TSchema extends ImplicitFieldSchema = ImplicitFieldSchema,\n\t>\n\textends TreeViewConfiguration<TSchema>\n\timplements TreeSchema\n{\n\t/**\n\t * {@inheritDoc TreeSchema.root}\n\t */\n\tpublic readonly root: FieldSchemaAlpha;\n\t/**\n\t * {@inheritDoc TreeSchema.definitions}\n\t */\n\tpublic readonly definitions: ReadonlyMap<string, SimpleNodeSchema & TreeNodeSchema>;\n\n\tpublic constructor(props: ITreeViewConfiguration<TSchema>) {\n\t\tsuper(props);\n\t\tthis.root = normalizeFieldSchema(props.schema);\n\t\tconst definitions = new Map<string, SimpleNodeSchema & TreeNodeSchema>();\n\t\twalkFieldSchema(props.schema, {\n\t\t\tnode: (schema) =>\n\t\t\t\tdefinitions.set(schema.identifier, schema as SimpleNodeSchema & TreeNodeSchema),\n\t\t});\n\t\tthis.definitions = definitions;\n\t}\n}\n\n/**\n * {@link TreeViewConfigurationAlpha}\n * @sealed @alpha\n */\nexport interface TreeSchema extends SimpleTreeSchema {\n\t/**\n\t * {@inheritDoc SimpleTreeSchema.root}\n\t */\n\treadonly root: FieldSchemaAlpha;\n\n\t/**\n\t * {@inheritDoc SimpleTreeSchema.definitions}\n\t */\n\treadonly definitions: ReadonlyMap<string, SimpleNodeSchema & TreeNodeSchema>;\n}\n\n/**\n * Pretty print a set of types for use in error messages.\n */\nfunction formatTypes(allowed: Iterable<TreeNodeSchema>): string {\n\t// Use JSON.stringify to quote and escape identifiers.\n\t// Don't just use a single array JSON.stringify since that omits spaces between items\n\treturn `[${Array.from(allowed, (s) => JSON.stringify(s.identifier)).join(\", \")}]`;\n}\n\n/**\n * Detect cases documented in {@link ITreeConfigurationOptions.preventAmbiguity}.\n */\nexport function checkUnion(union: Iterable<TreeNodeSchema>, errors: string[]): void {\n\tconst checked: Set<TreeNodeSchema> = new Set();\n\tconst maps: TreeNodeSchema[] = [];\n\tconst arrays: TreeNodeSchema[] = [];\n\n\tconst objects: ObjectNodeSchema[] = [];\n\t// Map from key to schema using that key\n\tconst allObjectKeys: Map<string, Set<TreeNodeSchema>> = new Map();\n\n\tfor (const schema of union) {\n\t\tif (checked.has(schema)) {\n\t\t\tthrow new UsageError(`Duplicate schema in allowed types: ${schema.identifier}`);\n\t\t}\n\t\tchecked.add(schema);\n\n\t\tif (schema instanceof LeafNodeSchema) {\n\t\t\t// nothing to do\n\t\t} else if (isObjectNodeSchema(schema)) {\n\t\t\tobjects.push(schema);\n\t\t\tfor (const key of schema.fields.keys()) {\n\t\t\t\tgetOrCreate(allObjectKeys, key, () => new Set()).add(schema);\n\t\t\t}\n\t\t} else if (schema.kind === NodeKind.Array) {\n\t\t\tarrays.push(schema);\n\t\t} else {\n\t\t\tassert(schema.kind === NodeKind.Map, 0x9e7 /* invalid schema */);\n\t\t\tmaps.push(schema);\n\t\t}\n\t}\n\n\tif (arrays.length > 1) {\n\t\terrors.push(\n\t\t\t`More than one kind of array allowed within union (${formatTypes(arrays)}). This would require type disambiguation which is not supported by arrays during import or export.`,\n\t\t);\n\t}\n\n\tif (maps.length > 1) {\n\t\terrors.push(\n\t\t\t`More than one kind of map allowed within union (${formatTypes(maps)}). This would require type disambiguation which is not supported by maps during import or export.`,\n\t\t);\n\t}\n\n\tif (maps.length > 0 && arrays.length > 0) {\n\t\terrors.push(\n\t\t\t`Both a map and an array allowed within union (${formatTypes([...arrays, ...maps])}). Both can be implicitly constructed from iterables like arrays, which are ambiguous when the array is empty.`,\n\t\t);\n\t}\n\n\tif (objects.length > 0 && maps.length > 0) {\n\t\terrors.push(\n\t\t\t`Both a object and a map allowed within union (${formatTypes([...objects, ...maps])}). Both can be constructed from objects and can be ambiguous.`,\n\t\t);\n\t}\n\n\t// Check for objects which fully overlap:\n\tfor (const schema of objects) {\n\t\t// All objects which might be ambiguous relative to `schema`.\n\t\tconst possiblyAmbiguous = new Set(objects);\n\n\t\t// A schema can't be ambiguous with itself\n\t\tpossiblyAmbiguous.delete(schema);\n\n\t\t// For each field of schema, remove schema from possiblyAmbiguous that do not have that field\n\t\tfor (const [key, field] of schema.fields) {\n\t\t\tif (field.kind === FieldKind.Required) {\n\t\t\t\tconst withKey = allObjectKeys.get(key) ?? fail(0xb35 /* missing schema */);\n\t\t\t\tfor (const candidate of possiblyAmbiguous) {\n\t\t\t\t\tif (!withKey.has(candidate)) {\n\t\t\t\t\t\tpossiblyAmbiguous.delete(candidate);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (possiblyAmbiguous.size > 0) {\n\t\t\t// TODO: make this check more permissive.\n\t\t\t// Allow using the type of the field to disambiguate, at least for leaf types.\n\t\t\t// Add \"constant\" fields which can be used to disambiguate even more cases without adding persisted data: maybe make them optional in constructor?\n\t\t\t// Consider separating unambiguous implicit construction format from constructor arguments at type level, allowing constructor to superset the implicit construction options (ex: optional constant fields).\n\t\t\t// The policy here however must remain at least as conservative as shallowCompatibilityTest in src/simple-tree/unhydratedFlexTreeFromInsertable.ts.\n\n\t\t\terrors.push(\n\t\t\t\t`The required fields of ${JSON.stringify(schema.identifier)} are insufficient to differentiate it from the following types: ${formatTypes(possiblyAmbiguous)}. For objects to be considered unambiguous, each must have required fields that do not all occur on any other object in the union.`,\n\t\t\t);\n\t\t}\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"configuration.js","sourceRoot":"","sources":["../../../src/simple-tree/api/configuration.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, debugAssert, fail } from \"@fluidframework/core-utils/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport {\n\ttype FieldSchemaAlpha,\n\ttype ImplicitFieldSchema,\n\tevaluateLazySchema,\n\tFieldKind,\n\tisAnnotatedAllowedType,\n\tmarkSchemaMostDerived,\n\tnormalizeFieldSchema,\n} from \"../schemaTypes.js\";\nimport { NodeKind, type TreeNodeSchema } from \"../core/index.js\";\nimport { toStoredSchema } from \"../toStoredSchema.js\";\nimport { LeafNodeSchema } from \"../leafNodeSchema.js\";\nimport { isObjectNodeSchema, type ObjectNodeSchema } from \"../node-kinds/index.js\";\nimport { getOrCreate } from \"../../util/index.js\";\nimport type { MakeNominal } from \"../../util/index.js\";\nimport { walkFieldSchema } from \"../walkFieldSchema.js\";\nimport type { SimpleNodeSchema, SimpleTreeSchema } from \"../simpleSchema.js\";\n\n/**\n * Options when constructing a tree view.\n * @public\n */\nexport interface ITreeConfigurationOptions {\n\t/**\n\t * If `true`, the tree will validate new content against its stored schema at insertion time\n\t * and throw an error if the new content doesn't match the expected schema.\n\t *\n\t * @defaultValue `false`.\n\t *\n\t * @remarks Enabling schema validation has a performance penalty when inserting new content into the tree because\n\t * additional checks are done. Enable this option only in scenarios where you are ok with that operation being a\n\t * bit slower.\n\t */\n\tenableSchemaValidation?: boolean;\n\n\t/**\n\t * A flag used to opt into strict rules ensuring that the schema avoids cases which can make the type of nodes ambiguous when importing or exporting data.\n\t * @defaultValue `false`.\n\t *\n\t * @remarks\n\t * When this is true, it ensures that the compile time type safety for data when constructing nodes is sufficient to ensure that the runtime behavior will not give node data ambiguity errors.\n\t *\n\t * This ensures that the canonical JSON-like representation of all unions in the tree are lossless and unambiguous.\n\t * This canonical JSON-like representation consists of arrays, plain old JavaScript objects with string keys, booleans, numbers (excluding NaN, -0 and infinities), strings, null and {@link @fluidframework/core-interfaces#IFluidHandle}s.\n\t * It is compatible with the node creation APIs (such as schema class constructors) and is also compatible with JSON assuming any IFluidHandles get special handling (since they are not JSON compatible).\n\t * Currently these cases can cause ambiguity in a union:\n\t *\n\t * - More than one ArrayNode type: it's impossible to tell which array type is intended in the case of empty arrays (`[]`).\n\t *\n\t * - More than one MapNode type: it's impossible to tell which map type is intended in the case of an empty map (`{}`).\n\t *\n\t * - Both a MapNode and an ArrayNode: this case is not a problem for the canonical JSON representation, but is an issue when constructing from an Iterable, which is supported for both MapNode and ArrayNode.\n\t *\n\t * - Both a MapNode and an ObjectNode: when the input is valid for the ObjectNode, the current parser always considers it ambiguous with being a MapNode.\n\t *\n\t * - ObjectNodes which have fields (required or optional) which include all required fields of another ObjectNode: currently each ObjectNode is differentiated by the presence of its required fields.\n\t *\n\t * This check is conservative: some complex cases may error if the current simple algorithm cannot show no ambiguity is possible.\n\t * This check may become more permissive over time.\n\t *\n\t * @example Ambiguous schema (with `preventAmbiguity: false`), and how to disambiguate it using {@link Unhydrated} nodes:\n\t * ```typescript\n\t * const schemaFactory = new SchemaFactory(\"com.example\");\n\t * class Feet extends schemaFactory.object(\"Feet\", { length: schemaFactory.number }) {}\n\t * class Meters extends schemaFactory.object(\"Meters\", { length: schemaFactory.number }) {}\n\t * const config = new TreeViewConfiguration({\n\t * \t// This combination of schema can lead to ambiguous cases and will error if `preventAmbiguity` is true.\n\t * \tschema: [Feet, Meters],\n\t * \tpreventAmbiguity: false,\n\t * });\n\t * const view = tree.viewWith(config);\n\t * // This is invalid since it is ambiguous which type of node is being constructed:\n\t * // view.initialize({ length: 5 });\n\t * // To work, an explicit type can be provided by using an {@link Unhydrated} Node:\n\t * view.initialize(new Meters({ length: 5 }));\n\t * ```\n\t *\n\t * @example Schema disambiguated by adjusting field names, validated with `preventAmbiguity: true:`\n\t * ```typescript\n\t * const schemaFactory = new SchemaFactory(\"com.example\");\n\t * class Feet extends schemaFactory.object(\"Feet\", { length: schemaFactory.number }) {}\n\t * class Meters extends schemaFactory.object(\"Meters\", {\n\t * \t// To avoid ambiguity when parsing unions of Feet and Meters, this renames the length field to \"meters\".\n\t * \t// To preserve compatibility with existing data from the ambiguous case,\n\t * \t// `{ key: \"length\" }` is set, so when persisted in the tree \"length\" is used as the field name.\n\t * \tmeters: schemaFactory.required(schemaFactory.number, { key: \"length\" }),\n\t * }) {}\n\t * const config = new TreeViewConfiguration({\n\t * \t// This combination of schema is not ambiguous because `Feet` and `Meters` have different required keys.\n\t * \tschema: [Feet, Meters],\n\t * \tpreventAmbiguity: true,\n\t * });\n\t * const view = tree.viewWith(config);\n\t * // This now works, since the field is sufficient to determine this is a `Meters` node.\n\t * view.initialize({ meters: 5 });\n\t * ```\n\t *\n\t * @privateRemarks\n\t * In the future, we can support lossless round tripping via the canonical JSON-like representation above when unambiguous.\n\t * This could be done via methods added to `Tree` to export and import such objects, which would give us a place to explicitly define the type of this representation.\n\t *\n\t * To make this more permissive in the future we can:\n\t *\n\t * - Make unhydratedFlexTreeFromInsertable more permissive (ex: allow disambiguation based on leaf type)\n\t * - Update this check to more tightly match unhydratedFlexTreeFromInsertable\n\t * - Add options to help schema authors disambiguate their types, such as \"constant fields\" which are not persisted, and always have a constant value.\n\t *\n\t * The above examples exist in executable form in this files tests, and should be updated there then copied back here.\n\t */\n\treadonly preventAmbiguity?: boolean;\n}\n\nconst defaultTreeConfigurationOptions: Required<ITreeConfigurationOptions> = {\n\tenableSchemaValidation: false,\n\tpreventAmbiguity: false,\n};\n\n/**\n * Property-bag configuration for {@link TreeViewConfiguration} construction.\n * @public\n */\nexport interface ITreeViewConfiguration<\n\tTSchema extends ImplicitFieldSchema = ImplicitFieldSchema,\n> extends ITreeConfigurationOptions {\n\t/**\n\t * The schema which the application wants to view the tree with.\n\t */\n\treadonly schema: TSchema;\n}\n\n/**\n * Configuration for {@link ViewableTree.viewWith}.\n * @sealed @public\n */\nexport class TreeViewConfiguration<\n\tconst TSchema extends ImplicitFieldSchema = ImplicitFieldSchema,\n> implements Required<ITreeViewConfiguration<TSchema>>\n{\n\tprotected _typeCheck!: MakeNominal;\n\n\t/**\n\t * {@inheritDoc ITreeViewConfiguration.schema}\n\t */\n\tpublic readonly schema: TSchema;\n\n\t/**\n\t * {@inheritDoc ITreeConfigurationOptions.enableSchemaValidation}\n\t */\n\tpublic readonly enableSchemaValidation: boolean;\n\n\t/**\n\t * {@inheritDoc ITreeConfigurationOptions.preventAmbiguity}\n\t */\n\tpublic readonly preventAmbiguity: boolean;\n\n\t/**\n\t * {@link TreeSchema.definitions} but with public types.\n\t */\n\tprotected readonly definitionsInternal: ReadonlyMap<string, TreeNodeSchema>;\n\n\t/**\n\t * Construct a new {@link TreeViewConfiguration}.\n\t *\n\t * @param props - Property bag of configuration options.\n\t *\n\t * @remarks\n\t * Performing this construction deeply validates the provided schema.\n\t * This means that when this constructor is called, all {@link LazyItem} {@link TreeNodeSchema} references will be evaluated (using {@link evaluateLazySchema}).\n\t * This means that the declarations for all transitively reachable {@link TreeNodeSchema} must be available at this time.\n\t *\n\t * For example, a schema reachable from this configuration cannot reference this configuration during its declaration,\n\t * since this would be a cyclic dependency that will cause an error when constructing this configuration.\n\t */\n\tpublic constructor(props: ITreeViewConfiguration<TSchema>) {\n\t\tconst config = { ...defaultTreeConfigurationOptions, ...props };\n\t\tthis.schema = config.schema;\n\t\tthis.enableSchemaValidation = config.enableSchemaValidation;\n\t\tthis.preventAmbiguity = config.preventAmbiguity;\n\n\t\t// Ambiguity errors are lower priority to report than invalid schema errors, so collect these in an array and report them all at once.\n\t\tconst ambiguityErrors: string[] = [];\n\n\t\t// Eagerly perform this conversion to surface errors sooner.\n\t\t// Includes detection of duplicate schema identifiers.\n\t\ttoStoredSchema(config.schema);\n\n\t\tconst definitions = new Map<string, SimpleNodeSchema & TreeNodeSchema>();\n\n\t\twalkFieldSchema(config.schema, {\n\t\t\tnode: (schema) => {\n\t\t\t\t// Ensure all reachable schema are marked as most derived.\n\t\t\t\t// This ensures if multiple schema extending the same schema factory generated class are present (or have had instances of them constructed, or get instances of them constructed in the future),\n\t\t\t\t// an error is reported.\n\t\t\t\tmarkSchemaMostDerived(schema, true);\n\n\t\t\t\tdebugAssert(() => !definitions.has(schema.identifier));\n\t\t\t\tdefinitions.set(schema.identifier, schema as SimpleNodeSchema & TreeNodeSchema);\n\t\t\t},\n\t\t\tallowedTypes({ types }): void {\n\t\t\t\tcheckUnion(\n\t\t\t\t\ttypes.map((t) => evaluateLazySchema(isAnnotatedAllowedType(t) ? t.type : t)),\n\t\t\t\t\tconfig.preventAmbiguity,\n\t\t\t\t\tambiguityErrors,\n\t\t\t\t);\n\t\t\t},\n\t\t});\n\n\t\tthis.definitionsInternal = definitions;\n\n\t\tif (ambiguityErrors.length !== 0) {\n\t\t\t// Duplicate errors are common since when two types conflict, both orders error:\n\t\t\tconst deduplicated = new Set(ambiguityErrors);\n\t\t\tthrow new UsageError(`Ambiguous schema found:\\n${[...deduplicated].join(\"\\n\")}`);\n\t\t}\n\t}\n}\n\n/**\n * {@link TreeViewConfiguration} extended with some alpha APIs.\n * @sealed @alpha\n */\nexport class TreeViewConfigurationAlpha<\n\t\tconst TSchema extends ImplicitFieldSchema = ImplicitFieldSchema,\n\t>\n\textends TreeViewConfiguration<TSchema>\n\timplements TreeSchema\n{\n\t/**\n\t * {@inheritDoc TreeSchema.root}\n\t */\n\tpublic readonly root: FieldSchemaAlpha;\n\n\t/**\n\t * {@inheritDoc TreeSchema.definitions}\n\t */\n\tpublic get definitions(): ReadonlyMap<string, SimpleNodeSchema & TreeNodeSchema> {\n\t\treturn this.definitionsInternal as ReadonlyMap<string, SimpleNodeSchema & TreeNodeSchema>;\n\t}\n\n\tpublic constructor(props: ITreeViewConfiguration<TSchema>) {\n\t\tsuper(props);\n\t\tthis.root = normalizeFieldSchema(props.schema);\n\t}\n}\n\n/**\n * {@link TreeViewConfigurationAlpha}\n * @sealed @alpha\n */\nexport interface TreeSchema extends SimpleTreeSchema {\n\t/**\n\t * {@inheritDoc SimpleTreeSchema.root}\n\t */\n\treadonly root: FieldSchemaAlpha;\n\n\t/**\n\t * {@inheritDoc SimpleTreeSchema.definitions}\n\t */\n\treadonly definitions: ReadonlyMap<string, SimpleNodeSchema & TreeNodeSchema>;\n}\n\n/**\n * Pretty print a set of types for use in error messages.\n */\nfunction formatTypes(allowed: Iterable<TreeNodeSchema>): string {\n\t// Use JSON.stringify to quote and escape identifiers.\n\t// Don't just use a single array JSON.stringify since that omits spaces between items\n\treturn `[${Array.from(allowed, (s) => JSON.stringify(s.identifier)).join(\", \")}]`;\n}\n\n/**\n * Check if union contents are valid (shallowly).\n *\n * @param union - The union of {@link TreeNodeSchema} to check.\n * @param preventAmbiguity - If true, detect cases documented in {@link ITreeConfigurationOptions.preventAmbiguity}, reporting them to `ambiguityErrors`.\n * @param ambiguityErrors - An array into which this function inserts any ambiguity errors, see {@link ITreeConfigurationOptions.preventAmbiguity}.\n *\n * @remarks\n * Includes checks for non-ambiguity errors as well: such as duplicate schemas in the union.\n * Any non-ambiguity errors are thrown as exceptions: `UsageError`s if causable by incorrect API use, and asserts if violating internal invariants.\n */\nexport function checkUnion(\n\tunion: Iterable<TreeNodeSchema>,\n\tpreventAmbiguity: boolean,\n\tambiguityErrors: string[],\n): void {\n\tconst checked: Set<TreeNodeSchema> = new Set();\n\tconst maps: TreeNodeSchema[] = [];\n\tconst arrays: TreeNodeSchema[] = [];\n\n\tconst objects: ObjectNodeSchema[] = [];\n\t// Map from key to schema using that key\n\tconst allObjectKeys: Map<string, Set<TreeNodeSchema>> = new Map();\n\n\tfor (const schema of union) {\n\t\tif (checked.has(schema)) {\n\t\t\tthrow new UsageError(`Duplicate schema in allowed types: ${schema.identifier}`);\n\t\t}\n\t\tchecked.add(schema);\n\n\t\tif (schema instanceof LeafNodeSchema) {\n\t\t\t// nothing to do\n\t\t} else if (isObjectNodeSchema(schema)) {\n\t\t\tobjects.push(schema);\n\t\t\tfor (const key of schema.fields.keys()) {\n\t\t\t\tgetOrCreate(allObjectKeys, key, () => new Set()).add(schema);\n\t\t\t}\n\t\t} else if (schema.kind === NodeKind.Array) {\n\t\t\tarrays.push(schema);\n\t\t} else {\n\t\t\tassert(schema.kind === NodeKind.Map, 0x9e7 /* invalid schema */);\n\t\t\tmaps.push(schema);\n\t\t}\n\t}\n\n\tif (!preventAmbiguity) {\n\t\t// All remaining checks are for the preventAmbiguity case, so skip them if not enabled.\n\t\treturn;\n\t}\n\n\tif (arrays.length > 1) {\n\t\tambiguityErrors.push(\n\t\t\t`More than one kind of array allowed within union (${formatTypes(arrays)}). This would require type disambiguation which is not supported by arrays during import or export.`,\n\t\t);\n\t}\n\n\tif (maps.length > 1) {\n\t\tambiguityErrors.push(\n\t\t\t`More than one kind of map allowed within union (${formatTypes(maps)}). This would require type disambiguation which is not supported by maps during import or export.`,\n\t\t);\n\t}\n\n\tif (maps.length > 0 && arrays.length > 0) {\n\t\tambiguityErrors.push(\n\t\t\t`Both a map and an array allowed within union (${formatTypes([...arrays, ...maps])}). Both can be implicitly constructed from iterables like arrays, which are ambiguous when the array is empty.`,\n\t\t);\n\t}\n\n\tif (objects.length > 0 && maps.length > 0) {\n\t\tambiguityErrors.push(\n\t\t\t`Both a object and a map allowed within union (${formatTypes([...objects, ...maps])}). Both can be constructed from objects and can be ambiguous.`,\n\t\t);\n\t}\n\n\t// Check for objects which fully overlap:\n\tfor (const schema of objects) {\n\t\t// All objects which might be ambiguous relative to `schema`.\n\t\tconst possiblyAmbiguous = new Set(objects);\n\n\t\t// A schema can't be ambiguous with itself\n\t\tpossiblyAmbiguous.delete(schema);\n\n\t\t// For each field of schema, remove schema from possiblyAmbiguous that do not have that field\n\t\tfor (const [key, field] of schema.fields) {\n\t\t\tif (field.kind === FieldKind.Required) {\n\t\t\t\tconst withKey = allObjectKeys.get(key) ?? fail(0xb35 /* missing schema */);\n\t\t\t\tfor (const candidate of possiblyAmbiguous) {\n\t\t\t\t\tif (!withKey.has(candidate)) {\n\t\t\t\t\t\tpossiblyAmbiguous.delete(candidate);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (possiblyAmbiguous.size > 0) {\n\t\t\t// TODO: make this check more permissive.\n\t\t\t// Allow using the type of the field to disambiguate, at least for leaf types.\n\t\t\t// Add \"constant\" fields which can be used to disambiguate even more cases without adding persisted data: maybe make them optional in constructor?\n\t\t\t// Consider separating unambiguous implicit construction format from constructor arguments at type level, allowing constructor to superset the implicit construction options (ex: optional constant fields).\n\t\t\t// The policy here however must remain at least as conservative as shallowCompatibilityTest in src/simple-tree/unhydratedFlexTreeFromInsertable.ts.\n\n\t\t\tambiguityErrors.push(\n\t\t\t\t`The required fields of ${JSON.stringify(schema.identifier)} are insufficient to differentiate it from the following types: ${formatTypes(possiblyAmbiguous)}. For objects to be considered unambiguous, each must have required fields that do not all occur on any other object in the union.`,\n\t\t\t);\n\t\t}\n\t}\n}\n"]}
|
|
@@ -11,7 +11,7 @@ export { SchemaFactoryAlpha } from "./schemaFactoryAlpha.js";
|
|
|
11
11
|
export type { ValidateRecursiveSchema, FixRecursiveArraySchema, ValidateRecursiveSchemaTemplate, FixRecursiveRecursionLimit, } from "./schemaFactoryRecursive.js";
|
|
12
12
|
export { allowUnused } from "./schemaFactoryRecursive.js";
|
|
13
13
|
export { adaptEnum, enumFromStrings, singletonSchema, } from "./schemaCreationUtilities.js";
|
|
14
|
-
export {
|
|
14
|
+
export { getIdentifierFromNode, getPropertyKeyFromStoredKey, getStoredKey, treeNodeApi, type TreeNodeApi, tryGetSchema, } from "./treeNodeApi.js";
|
|
15
15
|
export { createFromCursor } from "./create.js";
|
|
16
16
|
export { type JsonSchemaId, type JsonSchemaType, type JsonObjectNodeSchema, type JsonArrayNodeSchema, type JsonMapNodeSchema, type JsonLeafNodeSchema, type JsonSchemaRef, type JsonRefPath, type JsonNodeSchema, type JsonNodeSchemaBase, type JsonTreeSchema, type JsonFieldSchema, type JsonLeafSchemaType, } from "./jsonSchema.js";
|
|
17
17
|
export type { TreeSchemaEncodingOptions } from "./getJsonSchema.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/simple-tree/api/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,YAAY,EACX,UAAU,EACV,sBAAsB,EACtB,yBAAyB,GACzB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACN,qBAAqB,EACrB,0BAA0B,GAC1B,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACX,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,yBAAyB,EACzB,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,UAAU,GACV,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EACN,aAAa,EACb,KAAK,gBAAgB,EACrB,KAAK,0BAA0B,EAC/B,KAAK,aAAa,EAClB,aAAa,GACb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,YAAY,EACX,uBAAuB,EACvB,uBAAuB,EACvB,+BAA+B,EAC/B,0BAA0B,GAC1B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EACN,SAAS,EACT,eAAe,EACf,eAAe,GACf,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACN,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/simple-tree/api/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.toSimpleTreeSchema = exports.generateSchemaFromSimpleSchema = exports.rollback = exports.comparePersistedSchema = exports.extractPersistedSchema = exports.createIdentifierIndex = exports.createSimpleTreeIndex = exports.TreeBeta = exports.replaceConciseTreeHandles = exports.conciseFromCursor = exports.replaceHandles = exports.tryStoredSchemaAsArray = exports.customFromCursorStored = exports.replaceVerboseTreeHandles = exports.verboseFromCursor = exports.cursorFromVerbose = exports.applySchemaToParserOptions = exports.SchemaCompatibilityTester = exports.getSimpleSchema = exports.getJsonSchema = exports.createFromCursor = exports.
|
|
7
|
+
exports.toSimpleTreeSchema = exports.generateSchemaFromSimpleSchema = exports.rollback = exports.comparePersistedSchema = exports.extractPersistedSchema = exports.createIdentifierIndex = exports.createSimpleTreeIndex = exports.TreeBeta = exports.replaceConciseTreeHandles = exports.conciseFromCursor = exports.replaceHandles = exports.tryStoredSchemaAsArray = exports.customFromCursorStored = exports.replaceVerboseTreeHandles = exports.verboseFromCursor = exports.cursorFromVerbose = exports.applySchemaToParserOptions = exports.SchemaCompatibilityTester = exports.getSimpleSchema = exports.getJsonSchema = exports.createFromCursor = exports.tryGetSchema = exports.treeNodeApi = exports.getStoredKey = exports.getPropertyKeyFromStoredKey = exports.getIdentifierFromNode = exports.singletonSchema = exports.enumFromStrings = exports.adaptEnum = exports.allowUnused = exports.SchemaFactoryAlpha = exports.schemaStatics = exports.SchemaFactory = exports.asTreeViewAlpha = exports.TreeViewConfigurationAlpha = exports.TreeViewConfiguration = void 0;
|
|
8
8
|
var configuration_js_1 = require("./configuration.js");
|
|
9
9
|
Object.defineProperty(exports, "TreeViewConfiguration", { enumerable: true, get: function () { return configuration_js_1.TreeViewConfiguration; } });
|
|
10
10
|
Object.defineProperty(exports, "TreeViewConfigurationAlpha", { enumerable: true, get: function () { return configuration_js_1.TreeViewConfigurationAlpha; } });
|
|
@@ -22,11 +22,11 @@ Object.defineProperty(exports, "adaptEnum", { enumerable: true, get: function ()
|
|
|
22
22
|
Object.defineProperty(exports, "enumFromStrings", { enumerable: true, get: function () { return schemaCreationUtilities_js_1.enumFromStrings; } });
|
|
23
23
|
Object.defineProperty(exports, "singletonSchema", { enumerable: true, get: function () { return schemaCreationUtilities_js_1.singletonSchema; } });
|
|
24
24
|
var treeNodeApi_js_1 = require("./treeNodeApi.js");
|
|
25
|
+
Object.defineProperty(exports, "getIdentifierFromNode", { enumerable: true, get: function () { return treeNodeApi_js_1.getIdentifierFromNode; } });
|
|
26
|
+
Object.defineProperty(exports, "getPropertyKeyFromStoredKey", { enumerable: true, get: function () { return treeNodeApi_js_1.getPropertyKeyFromStoredKey; } });
|
|
27
|
+
Object.defineProperty(exports, "getStoredKey", { enumerable: true, get: function () { return treeNodeApi_js_1.getStoredKey; } });
|
|
25
28
|
Object.defineProperty(exports, "treeNodeApi", { enumerable: true, get: function () { return treeNodeApi_js_1.treeNodeApi; } });
|
|
26
29
|
Object.defineProperty(exports, "tryGetSchema", { enumerable: true, get: function () { return treeNodeApi_js_1.tryGetSchema; } });
|
|
27
|
-
Object.defineProperty(exports, "getStoredKey", { enumerable: true, get: function () { return treeNodeApi_js_1.getStoredKey; } });
|
|
28
|
-
Object.defineProperty(exports, "getPropertyKeyFromStoredKey", { enumerable: true, get: function () { return treeNodeApi_js_1.getPropertyKeyFromStoredKey; } });
|
|
29
|
-
Object.defineProperty(exports, "getIdentifierFromNode", { enumerable: true, get: function () { return treeNodeApi_js_1.getIdentifierFromNode; } });
|
|
30
30
|
var create_js_1 = require("./create.js");
|
|
31
31
|
Object.defineProperty(exports, "createFromCursor", { enumerable: true, get: function () { return create_js_1.createFromCursor; } });
|
|
32
32
|
var getJsonSchema_js_1 = require("./getJsonSchema.js");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/simple-tree/api/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAOH,uDAG4B;AAF3B,yHAAA,qBAAqB,OAAA;AACrB,8HAAA,0BAA0B,OAAA;AAa3B,qCAA4C;AAAnC,0GAAA,eAAe,OAAA;AACxB,uDAM4B;AAL3B,iHAAA,aAAa,OAAA;AAIb,iHAAA,aAAa,OAAA;AAEd,iEAA6D;AAApD,2HAAA,kBAAkB,OAAA;AAO3B,yEAA0D;AAAjD,wHAAA,WAAW,OAAA;AACpB,2EAIsC;AAHrC,uHAAA,SAAS,OAAA;AACT,6HAAA,eAAe,OAAA;AACf,6HAAA,eAAe,OAAA;AAEhB,mDAO0B;AANzB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/simple-tree/api/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAOH,uDAG4B;AAF3B,yHAAA,qBAAqB,OAAA;AACrB,8HAAA,0BAA0B,OAAA;AAa3B,qCAA4C;AAAnC,0GAAA,eAAe,OAAA;AACxB,uDAM4B;AAL3B,iHAAA,aAAa,OAAA;AAIb,iHAAA,aAAa,OAAA;AAEd,iEAA6D;AAApD,2HAAA,kBAAkB,OAAA;AAO3B,yEAA0D;AAAjD,wHAAA,WAAW,OAAA;AACpB,2EAIsC;AAHrC,uHAAA,SAAS,OAAA;AACT,6HAAA,eAAe,OAAA;AACf,6HAAA,eAAe,OAAA;AAEhB,mDAO0B;AANzB,uHAAA,qBAAqB,OAAA;AACrB,6HAAA,2BAA2B,OAAA;AAC3B,8GAAA,YAAY,OAAA;AACZ,6GAAA,WAAW,OAAA;AAEX,8GAAA,YAAY,OAAA;AAEb,yCAA+C;AAAtC,6GAAA,gBAAgB,OAAA;AAiBzB,uDAAmD;AAA1C,iHAAA,aAAa,OAAA;AACtB,2DAAuD;AAA9C,qHAAA,eAAe,OAAA;AACxB,+EAA2E;AAAlE,yIAAA,yBAAyB,OAAA;AASlC,mDAO0B;AAJzB,4HAAA,0BAA0B,OAAA;AAC1B,mHAAA,iBAAiB,OAAA;AACjB,mHAAA,iBAAiB,OAAA;AACjB,2HAAA,yBAAyB,OAAA;AAG1B,iDAQyB;AANxB,uHAAA,sBAAsB,OAAA;AAGtB,uHAAA,sBAAsB,OAAA;AACtB,+GAAA,cAAc,OAAA;AAIf,mDAI0B;AAFzB,mHAAA,iBAAiB,OAAA;AACjB,2HAAA,yBAAyB,OAAA;AAG1B,6CAA0F;AAAjF,uGAAA,QAAQ,OAAA;AACjB,2DAAmF;AAA1E,2HAAA,qBAAqB,OAAA;AAC9B,2DAG8B;AAF7B,2HAAA,qBAAqB,OAAA;AAItB,qDAG2B;AAF1B,yHAAA,sBAAsB,OAAA;AACtB,yHAAA,sBAAsB,OAAA;AAGvB,6DAW+B;AAD9B,+GAAA,QAAQ,OAAA;AAGT,6DAAuE;AAA9D,qIAAA,8BAA8B,OAAA;AACvC,6EAAmE;AAA1D,iIAAA,kBAAkB,OAAA","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport type {\n\tTreeSchema,\n\tITreeViewConfiguration,\n\tITreeConfigurationOptions,\n} from \"./configuration.js\";\nexport {\n\tTreeViewConfiguration,\n\tTreeViewConfigurationAlpha,\n} from \"./configuration.js\";\nexport type {\n\tITree,\n\tTreeView,\n\tViewableTree,\n\tTreeViewEvents,\n\tSchemaCompatibilityStatus,\n\tTreeViewAlpha,\n\tTreeBranch,\n\tTreeBranchEvents,\n\tITreeAlpha,\n} from \"./tree.js\";\nexport { asTreeViewAlpha } from \"./tree.js\";\nexport {\n\tSchemaFactory,\n\ttype ScopedSchemaName,\n\ttype SchemaFactoryObjectOptions,\n\ttype SchemaStatics,\n\tschemaStatics,\n} from \"./schemaFactory.js\";\nexport { SchemaFactoryAlpha } from \"./schemaFactoryAlpha.js\";\nexport type {\n\tValidateRecursiveSchema,\n\tFixRecursiveArraySchema,\n\tValidateRecursiveSchemaTemplate,\n\tFixRecursiveRecursionLimit,\n} from \"./schemaFactoryRecursive.js\";\nexport { allowUnused } from \"./schemaFactoryRecursive.js\";\nexport {\n\tadaptEnum,\n\tenumFromStrings,\n\tsingletonSchema,\n} from \"./schemaCreationUtilities.js\";\nexport {\n\tgetIdentifierFromNode,\n\tgetPropertyKeyFromStoredKey,\n\tgetStoredKey,\n\ttreeNodeApi,\n\ttype TreeNodeApi,\n\ttryGetSchema,\n} from \"./treeNodeApi.js\";\nexport { createFromCursor } from \"./create.js\";\nexport {\n\ttype JsonSchemaId,\n\ttype JsonSchemaType,\n\ttype JsonObjectNodeSchema,\n\ttype JsonArrayNodeSchema,\n\ttype JsonMapNodeSchema,\n\ttype JsonLeafNodeSchema,\n\ttype JsonSchemaRef,\n\ttype JsonRefPath,\n\ttype JsonNodeSchema,\n\ttype JsonNodeSchemaBase,\n\ttype JsonTreeSchema,\n\ttype JsonFieldSchema,\n\ttype JsonLeafSchemaType,\n} from \"./jsonSchema.js\";\nexport type { TreeSchemaEncodingOptions } from \"./getJsonSchema.js\";\nexport { getJsonSchema } from \"./getJsonSchema.js\";\nexport { getSimpleSchema } from \"./getSimpleSchema.js\";\nexport { SchemaCompatibilityTester } from \"./schemaCompatibilityTester.js\";\nexport type {\n\tUnenforced,\n\tFieldSchemaAlphaUnsafe,\n\tArrayNodeCustomizableSchemaUnsafe,\n\tMapNodeCustomizableSchemaUnsafe,\n\tSystem_Unsafe,\n} from \"./typesUnsafe.js\";\n\nexport {\n\ttype VerboseTreeNode,\n\ttype VerboseTree,\n\tapplySchemaToParserOptions,\n\tcursorFromVerbose,\n\tverboseFromCursor,\n\treplaceVerboseTreeHandles,\n} from \"./verboseTree.js\";\n\nexport {\n\ttype TreeEncodingOptions,\n\tcustomFromCursorStored,\n\ttype CustomTreeNode,\n\ttype CustomTreeValue,\n\ttryStoredSchemaAsArray,\n\treplaceHandles,\n\ttype HandleConverter,\n} from \"./customTree.js\";\n\nexport {\n\ttype ConciseTree,\n\tconciseFromCursor,\n\treplaceConciseTreeHandles,\n} from \"./conciseTree.js\";\n\nexport { TreeBeta, type NodeChangedData, type TreeChangeEventsBeta } from \"./treeBeta.js\";\nexport { createSimpleTreeIndex, type SimpleTreeIndex } from \"./simpleTreeIndex.js\";\nexport {\n\tcreateIdentifierIndex,\n\ttype IdentifierIndex,\n} from \"./identifierIndex.js\";\n\nexport {\n\textractPersistedSchema,\n\tcomparePersistedSchema,\n} from \"./storedSchema.js\";\n\nexport {\n\ttype TransactionConstraint,\n\ttype NodeInDocumentConstraint,\n\ttype RunTransactionParams,\n\ttype VoidTransactionCallbackStatus,\n\ttype TransactionCallbackStatus,\n\ttype TransactionResult,\n\ttype TransactionResultExt,\n\ttype TransactionResultSuccess,\n\ttype TransactionResultFailed,\n\trollback,\n} from \"./transactionTypes.js\";\n\nexport { generateSchemaFromSimpleSchema } from \"./schemaFromSimple.js\";\nexport { toSimpleTreeSchema } from \"./viewSchemaToSimpleSchema.js\";\nexport type { TreeChangeEvents } from \"./treeChangeEvents.js\";\n"]}
|
|
@@ -43,6 +43,9 @@ export interface TreeNodeApi {
|
|
|
43
43
|
* Return the node under which this node resides in the tree (or undefined if this is a root node of the tree).
|
|
44
44
|
*
|
|
45
45
|
* @throws A {@link @fluidframework/telemetry-utils#UsageError} if the node has been {@link TreeStatus.Deleted | deleted}.
|
|
46
|
+
*
|
|
47
|
+
* @see {@link (TreeAlpha:interface).child}
|
|
48
|
+
* @see {@link (TreeAlpha:interface).children}
|
|
46
49
|
*/
|
|
47
50
|
parent(node: TreeNode): TreeNode | undefined;
|
|
48
51
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"treeNodeApi.d.ts","sourceRoot":"","sources":["../../../src/simple-tree/api/treeNodeApi.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,KAAK,UAAU,EAA2B,MAAM,kCAAkC,CAAC;AAE5F,OAAO,EACN,KAAK,aAAa,EAGlB,KAAK,oBAAoB,EACzB,KAAK,gCAAgC,EAErC,MAAM,mBAAmB,CAAC;AAW3B,OAAO,EAGN,KAAK,cAAc,EAEnB,KAAK,QAAQ,EAKb,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAI9D;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,WAAW;IAC3B;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,QAAQ,GAAG,aAAa,GAAG,cAAc,CAAC;IAEvD;;;;;;;;OAQG;IACH,EAAE,CAAC,OAAO,SAAS,oBAAoB,EACtC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,OAAO,GACb,KAAK,IAAI,gCAAgC,CAAC,OAAO,CAAC,CAAC;IAEtD
|
|
1
|
+
{"version":3,"file":"treeNodeApi.d.ts","sourceRoot":"","sources":["../../../src/simple-tree/api/treeNodeApi.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,KAAK,UAAU,EAA2B,MAAM,kCAAkC,CAAC;AAE5F,OAAO,EACN,KAAK,aAAa,EAGlB,KAAK,oBAAoB,EACzB,KAAK,gCAAgC,EAErC,MAAM,mBAAmB,CAAC;AAW3B,OAAO,EAGN,KAAK,cAAc,EAEnB,KAAK,QAAQ,EAKb,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAI9D;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,WAAW;IAC3B;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,QAAQ,GAAG,aAAa,GAAG,cAAc,CAAC;IAEvD;;;;;;;;OAQG;IACH,EAAE,CAAC,OAAO,SAAS,oBAAoB,EACtC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,OAAO,GACb,KAAK,IAAI,gCAAgC,CAAC,OAAO,CAAC,CAAC;IAEtD;;;;;;;OAOG;IACH,MAAM,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;IAE7C;;;;;;;;OAQG;IACH,GAAG,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;IAErC;;;;;;;OAOG;IACH,EAAE,CAAC,CAAC,SAAS,MAAM,gBAAgB,EAClC,IAAI,EAAE,QAAQ,EACd,SAAS,EAAE,CAAC,EACZ,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAC3B,MAAM,IAAI,CAAC;IAEd;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,QAAQ,GAAG,UAAU,CAAC;IAEnC;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACrD;AAED;;GAEG;AACH,eAAO,MAAM,WAAW,EAAE,WA2FzB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,GAAG,cAAc,CAuBvE;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,qBAAqB,CACpC,IAAI,EAAE,QAAQ,EACd,WAAW,EAAE,kBAAkB,GAC7B,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;AAC/B,wBAAgB,qBAAqB,CACpC,IAAI,EAAE,QAAQ,EACd,WAAW,EAAE,YAAY,GACvB,MAAM,GAAG,SAAS,CAAC;AACtB,wBAAgB,qBAAqB,CACpC,IAAI,EAAE,QAAQ,EACd,WAAW,EAAE,cAAc,GACzB,MAAM,GAAG,SAAS,CAAC;AA2DtB;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,CAgB5D;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAC1C,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE,MAAM,GAAG,MAAM,GACxB,MAAM,GAAG,MAAM,CAyBjB"}
|
|
@@ -137,7 +137,7 @@ function getIdentifierFromNode(node, compression) {
|
|
|
137
137
|
const key = identifierFieldKeys[0] ?? (0, internal_1.oob)();
|
|
138
138
|
const identifierField = flexNode.tryGetField(key);
|
|
139
139
|
(0, internal_1.assert)(identifierField !== undefined, 0xbb5 /* missing identifier field */);
|
|
140
|
-
const identifierValue = (0, getTreeNodeForField_js_1.
|
|
140
|
+
const identifierValue = (0, getTreeNodeForField_js_1.tryGetTreeNodeForField)(identifierField);
|
|
141
141
|
(0, internal_1.assert)(typeof identifierValue === "string", 0xbb6 /* identifier not a string */);
|
|
142
142
|
const context = flexNode.context;
|
|
143
143
|
switch (compression) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"treeNodeApi.js","sourceRoot":"","sources":["../../../src/simple-tree/api/treeNodeApi.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,kEAAyF;AAEzF,kDAA6D;AAC7D,+DAA4F;AAC5F,kDAAwD;AACxD,sDAO2B;AAC3B,4DAM8B;AAC9B,qEAAuE;AACvE,uEAAsE;AAEtE,+CAU0B;AAE1B,qDAA4D;AAC5D,sEAAgE;AAiGhE;;GAEG;AACU,QAAA,WAAW,GAAgB;IACvC,MAAM,CAAC,IAAc;QACpB,MAAM,QAAQ,GAAG,IAAA,+BAAoB,EAAC,IAAI,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;QACtE,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC5B,OAAO,SAAS,CAAC;QAClB,CAAC;QAED,MAAM,MAAM,GAAG,IAAA,uCAA4B,EAAC,QAAQ,CAAC,CAAC;QACtD,IAAA,iBAAM,EACL,CAAC,IAAA,sBAAW,EAAC,MAAM,CAAC,EACpB,KAAK,CAAC,gEAAgE,CACtE,CAAC;QACF,OAAO,MAAM,CAAC;IACf,CAAC;IACD,GAAG,CAAC,IAAc;QACjB,sEAAsE;QACtE,8CAA8C;QAC9C,MAAM,MAAM,GAAG,mBAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,uBAAY,CAAC;QACrB,CAAC;QAED,+DAA+D;QAC/D,uGAAuG;QACvG,4GAA4G;QAC5G,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QACrC,MAAM,YAAY,GAAG,mBAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAChD,MAAM,WAAW,GAAG,2BAA2B,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;QACzE,OAAO,WAAW,CAAC;IACpB,CAAC;IACD,EAAE,CACD,IAAc,EACd,SAAY,EACZ,QAA6B;QAE7B,MAAM,MAAM,GAAG,IAAA,oBAAS,EAAC,IAAI,CAAC,CAAC;QAC/B,QAAQ,SAAS,EAAE,CAAC;YACnB,KAAK,aAAa,CAAC,CAAC,CAAC;gBACpB,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;gBACjC,IAAI,IAAA,6BAAkB,EAAC,UAAU,CAAC,EAAE,CAAC;oBACpC,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,2BAA2B,EAAE,CAAC,EAAE,aAAa,EAAE,EAAE,EAAE;wBAC1E,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAChC,KAAK,CAAC,IAAI,CACT,aAAa,EACb,CAAC,KAAK,EAAE,EAAE,CACT,UAAU,CAAC,sBAAsB,CAAC,GAAG,CAAC,KAAK,CAAC;4BAC5C,IAAA,eAAI,EAAC,KAAK,CAAC,0CAA0C,CAAC,CACvD,CACD,CAAC;wBACF,QAAQ,CAAC,EAAE,iBAAiB,EAAE,CAAC,CAAC;oBACjC,CAAC,CAAC,CAAC;gBACJ,CAAC;qBAAM,IAAI,UAAU,CAAC,IAAI,KAAK,mBAAQ,CAAC,KAAK,EAAE,CAAC;oBAC/C,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;wBACzD,QAAQ,CAAC,EAAE,iBAAiB,EAAE,SAAS,EAAE,CAAC,CAAC;oBAC5C,CAAC,CAAC,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACP,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,2BAA2B,EAAE,CAAC,EAAE,aAAa,EAAE,EAAE,EAAE;wBAC1E,QAAQ,CAAC,EAAE,iBAAiB,EAAE,aAAa,EAAE,CAAC,CAAC;oBAChD,CAAC,CAAC,CAAC;gBACJ,CAAC;YACF,CAAC;YACD,KAAK,aAAa,CAAC,CAAC,CAAC;gBACpB,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;YACzE,CAAC;YACD;gBACC,MAAM,IAAI,qBAAU,CAAC,kBAAkB,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACvE,CAAC;IACF,CAAC;IACD,MAAM,CAAC,IAAc;QACpB,OAAO,IAAA,oBAAS,EAAC,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;IACpC,CAAC;IACD,EAAE,CACD,KAAc,EACd,MAAe;QAEf,mGAAmG;QACnG,uLAAuL;QACvL,kIAAkI;QAElI,MAAM,YAAY,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;QACzC,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;YAChC,OAAO,KAAK,CAAC;QACd,CAAC;QACD,OAAO,IAAA,sCAAqB,EAAC,MAAM,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACxD,CAAC;IACD,MAAM,CAAC,IAA8B;QACpC,OAAO,YAAY,CAAC,IAAI,CAAC,IAAI,IAAA,eAAI,EAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,CAAC,IAAc;QACrB,OAAO,qBAAqB,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;IACxD,CAAC;CACD,CAAC;AAEF;;;GAGG;AACH,SAAgB,YAAY,CAAC,KAAc;IAC1C,QAAQ,OAAO,KAAK,EAAE,CAAC;QACtB,KAAK,QAAQ;YACZ,OAAO,gCAAY,CAAC;QACrB,KAAK,QAAQ;YACZ,OAAO,gCAAY,CAAC;QACrB,KAAK,SAAS;YACb,OAAO,iCAAa,CAAC;QACtB,KAAK,QAAQ,CAAC,CAAC,CAAC;YACf,IAAI,IAAA,qBAAU,EAAC,KAAK,CAAC,EAAE,CAAC;gBACvB,0GAA0G;gBAC1G,OAAO,IAAA,+BAAoB,EAAC,KAAK,CAAC,CAAC;YACpC,CAAC;YACD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACpB,OAAO,8BAAU,CAAC;YACnB,CAAC;YACD,IAAI,IAAA,wBAAa,EAAC,KAAK,CAAC,EAAE,CAAC;gBAC1B,OAAO,gCAAY,CAAC;YACrB,CAAC;QACF,CAAC;QACD;YACC,OAAO,SAAS,CAAC;IACnB,CAAC;AACF,CAAC;AAvBD,oCAuBC;AAsCD,SAAgB,qBAAqB,CACpC,IAAc,EACd,WAA+D;IAE/D,MAAM,MAAM,GAAG,IAAI,CAAC,2BAAgB,CAAC,CAAC;IACtC,IAAI,CAAC,IAAA,6BAAkB,EAAC,MAAM,CAAC,EAAE,CAAC;QACjC,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,MAAM,QAAQ,GAAG,IAAA,+BAAoB,EAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,mBAAmB,GAAG,MAAM,CAAC,mBAAmB,CAAC;IAEvD,QAAQ,mBAAmB,CAAC,MAAM,EAAE,CAAC;QACpC,KAAK,CAAC;YACL,OAAO,SAAS,CAAC;QAClB,KAAK,CAAC,CAAC,CAAC,CAAC;YACR,MAAM,GAAG,GAAG,mBAAmB,CAAC,CAAC,CAAC,IAAI,IAAA,cAAG,GAAE,CAAC;YAC5C,MAAM,eAAe,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;YAClD,IAAA,iBAAM,EAAC,eAAe,KAAK,SAAS,EAAE,KAAK,CAAC,8BAA8B,CAAC,CAAC;YAC5E,MAAM,eAAe,GAAG,IAAA,4CAAmB,EAAC,eAAe,CAAC,CAAC;YAC7D,IAAA,iBAAM,EAAC,OAAO,eAAe,KAAK,QAAQ,EAAE,KAAK,CAAC,6BAA6B,CAAC,CAAC;YAEjF,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;YACjC,QAAQ,WAAW,EAAE,CAAC;gBACrB,KAAK,kBAAkB,CAAC,CAAC,CAAC;oBACzB,IAAI,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;wBAC1B,MAAM,YAAY,GACjB,OAAO,CAAC,cAAc,CAAC,yBAAyB,CAAC,eAAe,CAAC,CAAC;wBACnE,OAAO,YAAY,KAAK,SAAS;4BAChC,CAAC,CAAC,IAAA,4BAAiB,EAAC,YAAY,CAAC;4BACjC,CAAC,CAAC,eAAe,CAAC;oBACpB,CAAC;yBAAM,CAAC;wBACP,OAAO,eAAe,CAAC;oBACxB,CAAC;gBACF,CAAC;gBACD,KAAK,YAAY,CAAC,CAAC,CAAC;oBACnB,IAAI,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;wBAC1B,MAAM,YAAY,GACjB,OAAO,CAAC,cAAc,CAAC,yBAAyB,CAAC,eAAe,CAAC,CAAC;wBACnE,OAAO,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,IAAA,4BAAiB,EAAC,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;oBACjF,CAAC;yBAAM,CAAC;wBACP,OAAO,SAAS,CAAC;oBAClB,CAAC;gBACF,CAAC;gBACD,KAAK,cAAc,CAAC,CAAC,CAAC;oBACrB,OAAO,eAAe,CAAC;gBACxB,CAAC;gBACD;oBACC,IAAA,0BAAe,EAAC,WAAW,CAAC,CAAC;YAC/B,CAAC;QACF,CAAC;QACD;YACC,MAAM,IAAI,qBAAU,CACnB,yIAAyI,CACzI,CAAC;IACJ,CAAC;AACF,CAAC;AAxDD,sDAwDC;AAED;;GAEG;AACH,SAAgB,YAAY,CAAC,IAAc;IAC1C,wGAAwG;IACxG,mBAAmB;IACnB,MAAM,WAAW,GAAG,IAAA,+BAAoB,EAAC,IAAI,CAAC,CAAC,WAAW,CAAC;IAC3D,IAAI,WAAW,CAAC,MAAM,CAAC,MAAM,KAAK,qBAAU,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;QAClE,wCAAwC;QACxC,IAAA,iBAAM,EACL,WAAW,CAAC,MAAM,CAAC,GAAG,KAAK,mBAAQ,EACnC,KAAK,CAAC,wDAAwD,CAC9D,CAAC;QACF,OAAO,WAAW,CAAC,KAAK,CAAC;IAC1B,CAAC;IAED,6GAA6G;IAC7G,IAAA,iBAAM,EAAC,WAAW,CAAC,KAAK,KAAK,CAAC,EAAE,KAAK,CAAC,oDAAoD,CAAC,CAAC;IAC5F,OAAO,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC;AAC/B,CAAC;AAhBD,oCAgBC;AAED;;GAEG;AACH,SAAgB,2BAA2B,CAC1C,MAAsB,EACtB,SAA0B;IAE1B,iHAAiH;IACjH,gFAAgF;IAChF,IAAI,MAAM,CAAC,IAAI,KAAK,mBAAQ,CAAC,MAAM,EAAE,CAAC;QACrC,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,IAA2C,CAAC;IAElE,cAAc;IACd,iEAAiE;IACjE,uGAAuG;IACvG,6IAA6I;IAC7I,iEAAiE;IACjE,KAAK,MAAM,CAAC,WAAW,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACjE,IAAI,WAAW,YAAY,4BAAW,IAAI,WAAW,CAAC,KAAK,EAAE,GAAG,KAAK,SAAS,EAAE,CAAC;YAChF,OAAO,WAAW,CAAC;QACpB,CAAC;IACF,CAAC;IAED,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,SAAS,EAAE,CAAC;QACrC,IAAA,eAAI,EAAC,KAAK,CAAC,6DAA6D,CAAC,CAAC;IAC3E,CAAC;IAED,OAAO,SAAS,CAAC;AAClB,CAAC;AA5BD,kEA4BC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, oob, fail, unreachableCase } from \"@fluidframework/core-utils/internal\";\n\nimport { EmptyKey, rootFieldKey } from \"../../core/index.js\";\nimport { type TreeStatus, isTreeValue, FieldKinds } from \"../../feature-libraries/index.js\";\nimport { extractFromOpaque } from \"../../util/index.js\";\nimport {\n\ttype TreeLeafValue,\n\ttype ImplicitFieldSchema,\n\tFieldSchema,\n\ttype ImplicitAllowedTypes,\n\ttype TreeNodeFromImplicitAllowedTypes,\n\tnormalizeAllowedTypes,\n} from \"../schemaTypes.js\";\nimport {\n\tbooleanSchema,\n\thandleSchema,\n\tnullSchema,\n\tnumberSchema,\n\tstringSchema,\n} from \"../leafNodeSchema.js\";\nimport { isFluidHandle } from \"@fluidframework/runtime-utils/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\nimport type { Off } from \"@fluidframework/core-interfaces\";\nimport {\n\tgetKernel,\n\tisTreeNode,\n\ttype TreeNodeSchema,\n\tNodeKind,\n\ttype TreeNode,\n\ttryGetTreeNodeSchema,\n\tgetOrCreateNodeFromInnerNode,\n\ttypeSchemaSymbol,\n\tgetOrCreateInnerNode,\n} from \"../core/index.js\";\nimport type { TreeChangeEvents } from \"./treeChangeEvents.js\";\nimport { isObjectNodeSchema } from \"../node-kinds/index.js\";\nimport { getTreeNodeForField } from \"../getTreeNodeForField.js\";\n\n/**\n * Provides various functions for analyzing {@link TreeNode}s.\n *\n * @remarks\n * With the exception of {@link TreeNodeApi.status}, these functions should not be called with nodes that have\n * been {@link TreeStatus.Deleted | deleted}.\n * To verify whether or not a node already has been deleted, use the {@link TreeNodeApi.status} function.\n *\n * This type should only be used via the public {@link (Tree:variable)} export.\n *\n * @privateRemarks\n * Due to limitations of API-Extractor link resolution, this type can't be moved into internalTypes but should be considered just an implementation detail of the `Tree` export.\n *\n * Inlining the typing of this interface onto the `Tree` object provides slightly different .d.ts generation,\n * which avoids typescript expanding the type of TreeNodeSchema and thus encountering\n * https://github.com/microsoft/rushstack/issues/1958.\n * @sealed @public\n */\nexport interface TreeNodeApi {\n\t/**\n\t * The schema information for this node.\n\t */\n\tschema(node: TreeNode | TreeLeafValue): TreeNodeSchema;\n\n\t/**\n\t * Narrow the type of the given value if it satisfies the given schema.\n\t * @example\n\t * ```ts\n\t * if (node.is(myNode, Point)) {\n\t * const y = myNode.y; // `myNode` is now known to satisfy the `Point` schema and therefore has a `y` coordinate.\n\t * }\n\t * ```\n\t */\n\tis<TSchema extends ImplicitAllowedTypes>(\n\t\tvalue: unknown,\n\t\tschema: TSchema,\n\t): value is TreeNodeFromImplicitAllowedTypes<TSchema>;\n\n\t/**\n\t * Return the node under which this node resides in the tree (or undefined if this is a root node of the tree).\n\t *\n\t * @throws A {@link @fluidframework/telemetry-utils#UsageError} if the node has been {@link TreeStatus.Deleted | deleted}.\n\t */\n\tparent(node: TreeNode): TreeNode | undefined;\n\n\t/**\n\t * The key of the given node under its parent.\n\t *\n\t * @remarks\n\t * If `node` is an element in a {@link (TreeArrayNode:interface)}, this returns the index of `node` in the array node (a `number`).\n\t * Otherwise, this returns the key of the field that it is under (a `string`).\n\t *\n\t * @throws A {@link @fluidframework/telemetry-utils#UsageError} if the node has been {@link TreeStatus.Deleted | deleted}.\n\t */\n\tkey(node: TreeNode): string | number;\n\n\t/**\n\t * Register an event listener on the given node.\n\t * @param node - The node whose events should be subscribed to.\n\t * @param eventName - Which event to subscribe to.\n\t * @param listener - The callback to trigger for the event. The tree can be read during the callback, but it is invalid to modify the tree during this callback.\n\t * @returns A callback function which will deregister the event.\n\t * This callback should be called only once.\n\t */\n\ton<K extends keyof TreeChangeEvents>(\n\t\tnode: TreeNode,\n\t\teventName: K,\n\t\tlistener: TreeChangeEvents[K],\n\t): () => void;\n\n\t/**\n\t * Returns the {@link TreeStatus} of the given node.\n\t */\n\tstatus(node: TreeNode): TreeStatus;\n\n\t/**\n\t * Returns the {@link SchemaFactory.identifier | identifier} of the given node in the most compressed form possible.\n\t * @remarks\n\t * If the node is {@link Unhydrated | hydrated} and its identifier is a valid UUID that was automatically generated by the SharedTree it is part of (or something else using the same {@link @fluidframework/id-compressor#IIdCompressor}), then this will return a process-unique integer corresponding to that identifier.\n\t * This is useful for performance-sensitive scenarios involving many nodes with identifiers that need to be compactly retained in memory or used for efficient lookup.\n\t * Note that automatically generated identifiers that were accessed before the node was hydrated will return the generated UUID, not the process-unique integer.\n\t *\n\t * If the node's identifier is any other user-provided string, then this will return that string.\n\t *\n\t * If the node has no identifier (that is, it has no {@link SchemaFactory.identifier | identifier} field), then this returns `undefined`.\n\t *\n\t * If the node has more than one identifier, then this will throw an error.\n\t *\n\t * The returned integer should not be serialized or preserved outside of the current process.\n\t * Its lifetime is that of the current in-memory instance of the FF container for this client, and it is not guaranteed to be unique or stable outside of that context.\n\t * The same node's identifier may, for example, be different across multiple sessions for the same client and document, or different across two clients in the same session.\n\t */\n\tshortId(node: TreeNode): number | string | undefined;\n}\n\n/**\n * {@inheritDoc TreeNodeApi}\n */\nexport const treeNodeApi: TreeNodeApi = {\n\tparent(node: TreeNode): TreeNode | undefined {\n\t\tconst editNode = getOrCreateInnerNode(node).parentField.parent.parent;\n\t\tif (editNode === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst output = getOrCreateNodeFromInnerNode(editNode);\n\t\tassert(\n\t\t\t!isTreeValue(output),\n\t\t\t0x87f /* Parent can't be a leaf, so it should be a node not a value */,\n\t\t);\n\t\treturn output;\n\t},\n\tkey(node: TreeNode): string | number {\n\t\t// If the parent is undefined, then this node is under the root field,\n\t\t// so we know its key is the special root one.\n\t\tconst parent = treeNodeApi.parent(node);\n\t\tif (parent === undefined) {\n\t\t\treturn rootFieldKey;\n\t\t}\n\n\t\t// The flex-domain strictly operates in terms of \"stored keys\".\n\t\t// To find the associated developer-facing \"property key\", we need to look up the field associated with\n\t\t// the stored key from the flex-domain, and get property key its simple-domain counterpart was created with.\n\t\tconst storedKey = getStoredKey(node);\n\t\tconst parentSchema = treeNodeApi.schema(parent);\n\t\tconst propertyKey = getPropertyKeyFromStoredKey(parentSchema, storedKey);\n\t\treturn propertyKey;\n\t},\n\ton<K extends keyof TreeChangeEvents>(\n\t\tnode: TreeNode,\n\t\teventName: K,\n\t\tlistener: TreeChangeEvents[K],\n\t): Off {\n\t\tconst kernel = getKernel(node);\n\t\tswitch (eventName) {\n\t\t\tcase \"nodeChanged\": {\n\t\t\t\tconst nodeSchema = kernel.schema;\n\t\t\t\tif (isObjectNodeSchema(nodeSchema)) {\n\t\t\t\t\treturn kernel.events.on(\"childrenChangedAfterBatch\", ({ changedFields }) => {\n\t\t\t\t\t\tconst changedProperties = new Set(\n\t\t\t\t\t\t\tArray.from(\n\t\t\t\t\t\t\t\tchangedFields,\n\t\t\t\t\t\t\t\t(field) =>\n\t\t\t\t\t\t\t\t\tnodeSchema.storedKeyToPropertyKey.get(field) ??\n\t\t\t\t\t\t\t\t\tfail(0xb36 /* Could not find stored key in schema. */),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tlistener({ changedProperties });\n\t\t\t\t\t});\n\t\t\t\t} else if (nodeSchema.kind === NodeKind.Array) {\n\t\t\t\t\treturn kernel.events.on(\"childrenChangedAfterBatch\", () => {\n\t\t\t\t\t\tlistener({ changedProperties: undefined });\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\treturn kernel.events.on(\"childrenChangedAfterBatch\", ({ changedFields }) => {\n\t\t\t\t\t\tlistener({ changedProperties: changedFields });\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tcase \"treeChanged\": {\n\t\t\t\treturn kernel.events.on(\"subtreeChangedAfterBatch\", () => listener({}));\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tthrow new UsageError(`No event named ${JSON.stringify(eventName)}.`);\n\t\t}\n\t},\n\tstatus(node: TreeNode): TreeStatus {\n\t\treturn getKernel(node).getStatus();\n\t},\n\tis<TSchema extends ImplicitAllowedTypes>(\n\t\tvalue: unknown,\n\t\tschema: TSchema,\n\t): value is TreeNodeFromImplicitAllowedTypes<TSchema> {\n\t\t// This \"is\" utility would return false if the provided schema is a base type of the actual schema.\n\t\t// This could be confusing, and that case can only be hit when violating the rule that there is a single most derived schema that gets used (See documentation on TreeNodeSchemaClass).\n\t\t// Therefore this uses markSchemaMostDerived to ensure an informative usage error is thrown in the case where a base type is used.\n\n\t\tconst actualSchema = tryGetSchema(value);\n\t\tif (actualSchema === undefined) {\n\t\t\treturn false;\n\t\t}\n\t\treturn normalizeAllowedTypes(schema).has(actualSchema);\n\t},\n\tschema(node: TreeNode | TreeLeafValue): TreeNodeSchema {\n\t\treturn tryGetSchema(node) ?? fail(0xb37 /* Not a tree node */);\n\t},\n\tshortId(node: TreeNode): number | string | undefined {\n\t\treturn getIdentifierFromNode(node, \"preferCompressed\");\n\t},\n};\n\n/**\n * Returns a schema for a value if the value is a {@link TreeNode} or a {@link TreeLeafValue}.\n * Returns undefined for other values.\n */\nexport function tryGetSchema(value: unknown): undefined | TreeNodeSchema {\n\tswitch (typeof value) {\n\t\tcase \"string\":\n\t\t\treturn stringSchema;\n\t\tcase \"number\":\n\t\t\treturn numberSchema;\n\t\tcase \"boolean\":\n\t\t\treturn booleanSchema;\n\t\tcase \"object\": {\n\t\t\tif (isTreeNode(value)) {\n\t\t\t\t// TODO: This case could be optimized, for example by placing the simple schema in a symbol on tree nodes.\n\t\t\t\treturn tryGetTreeNodeSchema(value);\n\t\t\t}\n\t\t\tif (value === null) {\n\t\t\t\treturn nullSchema;\n\t\t\t}\n\t\t\tif (isFluidHandle(value)) {\n\t\t\t\treturn handleSchema;\n\t\t\t}\n\t\t}\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n}\n\n/**\n * Gets the identifier from a node.\n *\n * @param node - {@link TreeNode} where you want to extract the identifier from.\n * @param compression - string value to determine what type of identifier you want to retrieve.\n *\n * @remarks\n * If the node does not contain an identifier field, it returns undefined.\n *\n * If `compression` is set to `compressed`:\n *\n * - If the node contains a compressible identifier known by the id compressor, the compressed identifier is returned.\n *\n * - If the node contains an identifier, but is not compressible or unknown by the id compressor, `undefined` is returned.\n *\n * If `compression` is set to `preferCompressed`:\n *\n * - If the node contains a compressible identifier known by the id compressor, the compressed identifier is returned.\n *\n * - If the node contains an identifier, but is not compressible or unknown by the id compressor, the uncompressed identifier is returned.\n *\n * If `compression` is set to `uncompressed`:\n * - If the node contains an identifier field, the uncompressed identifier is returned.\n */\nexport function getIdentifierFromNode(\n\tnode: TreeNode,\n\tcompression: \"preferCompressed\",\n): number | string | undefined;\nexport function getIdentifierFromNode(\n\tnode: TreeNode,\n\tcompression: \"compressed\",\n): number | undefined;\nexport function getIdentifierFromNode(\n\tnode: TreeNode,\n\tcompression: \"uncompressed\",\n): string | undefined;\nexport function getIdentifierFromNode(\n\tnode: TreeNode,\n\tcompression: \"preferCompressed\" | \"compressed\" | \"uncompressed\",\n): number | string | undefined {\n\tconst schema = node[typeSchemaSymbol];\n\tif (!isObjectNodeSchema(schema)) {\n\t\treturn undefined;\n\t}\n\n\tconst flexNode = getOrCreateInnerNode(node);\n\tconst identifierFieldKeys = schema.identifierFieldKeys;\n\n\tswitch (identifierFieldKeys.length) {\n\t\tcase 0:\n\t\t\treturn undefined;\n\t\tcase 1: {\n\t\t\tconst key = identifierFieldKeys[0] ?? oob();\n\t\t\tconst identifierField = flexNode.tryGetField(key);\n\t\t\tassert(identifierField !== undefined, 0xbb5 /* missing identifier field */);\n\t\t\tconst identifierValue = getTreeNodeForField(identifierField);\n\t\t\tassert(typeof identifierValue === \"string\", 0xbb6 /* identifier not a string */);\n\n\t\t\tconst context = flexNode.context;\n\t\t\tswitch (compression) {\n\t\t\t\tcase \"preferCompressed\": {\n\t\t\t\t\tif (context.isHydrated()) {\n\t\t\t\t\t\tconst localNodeKey =\n\t\t\t\t\t\t\tcontext.nodeKeyManager.tryLocalizeNodeIdentifier(identifierValue);\n\t\t\t\t\t\treturn localNodeKey !== undefined\n\t\t\t\t\t\t\t? extractFromOpaque(localNodeKey)\n\t\t\t\t\t\t\t: identifierValue;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn identifierValue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcase \"compressed\": {\n\t\t\t\t\tif (context.isHydrated()) {\n\t\t\t\t\t\tconst localNodeKey =\n\t\t\t\t\t\t\tcontext.nodeKeyManager.tryLocalizeNodeIdentifier(identifierValue);\n\t\t\t\t\t\treturn localNodeKey !== undefined ? extractFromOpaque(localNodeKey) : undefined;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcase \"uncompressed\": {\n\t\t\t\t\treturn identifierValue;\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\tunreachableCase(compression);\n\t\t\t}\n\t\t}\n\t\tdefault:\n\t\t\tthrow new UsageError(\n\t\t\t\t\"shortId() may not be called on a node with more than one identifier. Consider converting extraneous identifier fields to string fields.\",\n\t\t\t);\n\t}\n}\n\n/**\n * Gets the stored key with which the provided node is associated in the parent.\n */\nexport function getStoredKey(node: TreeNode): string | number {\n\t// Note: the flex domain strictly works with \"stored keys\", and knows nothing about the developer-facing\n\t// \"property keys\".\n\tconst parentField = getOrCreateInnerNode(node).parentField;\n\tif (parentField.parent.schema === FieldKinds.sequence.identifier) {\n\t\t// The parent of `node` is an array node\n\t\tassert(\n\t\t\tparentField.parent.key === EmptyKey,\n\t\t\t0xa28 /* When using index as key, field should use EmptyKey */,\n\t\t);\n\t\treturn parentField.index;\n\t}\n\n\t// The parent of `node` is an object, a map, or undefined. If undefined, then `node` is a root/detached node.\n\tassert(parentField.index === 0, 0xa29 /* When using field key as key, index should be 0 */);\n\treturn parentField.parent.key;\n}\n\n/**\n * Given a node schema, gets the property key corresponding with the provided {@link FieldProps.key | stored key}.\n */\nexport function getPropertyKeyFromStoredKey(\n\tschema: TreeNodeSchema,\n\tstoredKey: string | number,\n): string | number {\n\t// Only object nodes have the concept of a \"stored key\", differentiated from the developer-facing \"property key\".\n\t// For any other kind of node, the stored key and the property key are the same.\n\tif (schema.kind !== NodeKind.Object) {\n\t\treturn storedKey;\n\t}\n\n\tconst fields = schema.info as Record<string, ImplicitFieldSchema>;\n\n\t// Invariants:\n\t// - The set of all property keys under an object must be unique.\n\t// - The set of all stored keys (including those implicitly created from property keys) must be unique.\n\t// To find the property key associated with the provided stored key, first check for any stored key matches (which are optionally populated).\n\t// If we don't find any, then search for a matching property key.\n\tfor (const [propertyKey, fieldSchema] of Object.entries(fields)) {\n\t\tif (fieldSchema instanceof FieldSchema && fieldSchema.props?.key === storedKey) {\n\t\t\treturn propertyKey;\n\t\t}\n\t}\n\n\tif (fields[storedKey] === undefined) {\n\t\tfail(0xb38 /* Existing stored key should always map to a property key */);\n\t}\n\n\treturn storedKey;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"treeNodeApi.js","sourceRoot":"","sources":["../../../src/simple-tree/api/treeNodeApi.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, oob, fail, unreachableCase } from \"@fluidframework/core-utils/internal\";\n\nimport { EmptyKey, rootFieldKey } from \"../../core/index.js\";\nimport { type TreeStatus, isTreeValue, FieldKinds } from \"../../feature-libraries/index.js\";\nimport { extractFromOpaque } from \"../../util/index.js\";\nimport {\n\ttype TreeLeafValue,\n\ttype ImplicitFieldSchema,\n\tFieldSchema,\n\ttype ImplicitAllowedTypes,\n\ttype TreeNodeFromImplicitAllowedTypes,\n\tnormalizeAllowedTypes,\n} from \"../schemaTypes.js\";\nimport {\n\tbooleanSchema,\n\thandleSchema,\n\tnullSchema,\n\tnumberSchema,\n\tstringSchema,\n} from \"../leafNodeSchema.js\";\nimport { isFluidHandle } from \"@fluidframework/runtime-utils/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\nimport type { Off } from \"@fluidframework/core-interfaces\";\nimport {\n\tgetKernel,\n\tisTreeNode,\n\ttype TreeNodeSchema,\n\tNodeKind,\n\ttype TreeNode,\n\ttryGetTreeNodeSchema,\n\tgetOrCreateNodeFromInnerNode,\n\ttypeSchemaSymbol,\n\tgetOrCreateInnerNode,\n} from \"../core/index.js\";\nimport type { TreeChangeEvents } from \"./treeChangeEvents.js\";\nimport { isObjectNodeSchema } from \"../node-kinds/index.js\";\nimport { tryGetTreeNodeForField } from \"../getTreeNodeForField.js\";\n\n/**\n * Provides various functions for analyzing {@link TreeNode}s.\n *\n * @remarks\n * With the exception of {@link TreeNodeApi.status}, these functions should not be called with nodes that have\n * been {@link TreeStatus.Deleted | deleted}.\n * To verify whether or not a node already has been deleted, use the {@link TreeNodeApi.status} function.\n *\n * This type should only be used via the public {@link (Tree:variable)} export.\n *\n * @privateRemarks\n * Due to limitations of API-Extractor link resolution, this type can't be moved into internalTypes but should be considered just an implementation detail of the `Tree` export.\n *\n * Inlining the typing of this interface onto the `Tree` object provides slightly different .d.ts generation,\n * which avoids typescript expanding the type of TreeNodeSchema and thus encountering\n * https://github.com/microsoft/rushstack/issues/1958.\n * @sealed @public\n */\nexport interface TreeNodeApi {\n\t/**\n\t * The schema information for this node.\n\t */\n\tschema(node: TreeNode | TreeLeafValue): TreeNodeSchema;\n\n\t/**\n\t * Narrow the type of the given value if it satisfies the given schema.\n\t * @example\n\t * ```ts\n\t * if (node.is(myNode, Point)) {\n\t * const y = myNode.y; // `myNode` is now known to satisfy the `Point` schema and therefore has a `y` coordinate.\n\t * }\n\t * ```\n\t */\n\tis<TSchema extends ImplicitAllowedTypes>(\n\t\tvalue: unknown,\n\t\tschema: TSchema,\n\t): value is TreeNodeFromImplicitAllowedTypes<TSchema>;\n\n\t/**\n\t * Return the node under which this node resides in the tree (or undefined if this is a root node of the tree).\n\t *\n\t * @throws A {@link @fluidframework/telemetry-utils#UsageError} if the node has been {@link TreeStatus.Deleted | deleted}.\n\t *\n\t * @see {@link (TreeAlpha:interface).child}\n\t * @see {@link (TreeAlpha:interface).children}\n\t */\n\tparent(node: TreeNode): TreeNode | undefined;\n\n\t/**\n\t * The key of the given node under its parent.\n\t *\n\t * @remarks\n\t * If `node` is an element in a {@link (TreeArrayNode:interface)}, this returns the index of `node` in the array node (a `number`).\n\t * Otherwise, this returns the key of the field that it is under (a `string`).\n\t *\n\t * @throws A {@link @fluidframework/telemetry-utils#UsageError} if the node has been {@link TreeStatus.Deleted | deleted}.\n\t */\n\tkey(node: TreeNode): string | number;\n\n\t/**\n\t * Register an event listener on the given node.\n\t * @param node - The node whose events should be subscribed to.\n\t * @param eventName - Which event to subscribe to.\n\t * @param listener - The callback to trigger for the event. The tree can be read during the callback, but it is invalid to modify the tree during this callback.\n\t * @returns A callback function which will deregister the event.\n\t * This callback should be called only once.\n\t */\n\ton<K extends keyof TreeChangeEvents>(\n\t\tnode: TreeNode,\n\t\teventName: K,\n\t\tlistener: TreeChangeEvents[K],\n\t): () => void;\n\n\t/**\n\t * Returns the {@link TreeStatus} of the given node.\n\t */\n\tstatus(node: TreeNode): TreeStatus;\n\n\t/**\n\t * Returns the {@link SchemaFactory.identifier | identifier} of the given node in the most compressed form possible.\n\t * @remarks\n\t * If the node is {@link Unhydrated | hydrated} and its identifier is a valid UUID that was automatically generated by the SharedTree it is part of (or something else using the same {@link @fluidframework/id-compressor#IIdCompressor}), then this will return a process-unique integer corresponding to that identifier.\n\t * This is useful for performance-sensitive scenarios involving many nodes with identifiers that need to be compactly retained in memory or used for efficient lookup.\n\t * Note that automatically generated identifiers that were accessed before the node was hydrated will return the generated UUID, not the process-unique integer.\n\t *\n\t * If the node's identifier is any other user-provided string, then this will return that string.\n\t *\n\t * If the node has no identifier (that is, it has no {@link SchemaFactory.identifier | identifier} field), then this returns `undefined`.\n\t *\n\t * If the node has more than one identifier, then this will throw an error.\n\t *\n\t * The returned integer should not be serialized or preserved outside of the current process.\n\t * Its lifetime is that of the current in-memory instance of the FF container for this client, and it is not guaranteed to be unique or stable outside of that context.\n\t * The same node's identifier may, for example, be different across multiple sessions for the same client and document, or different across two clients in the same session.\n\t */\n\tshortId(node: TreeNode): number | string | undefined;\n}\n\n/**\n * {@inheritDoc TreeNodeApi}\n */\nexport const treeNodeApi: TreeNodeApi = {\n\tparent(node: TreeNode): TreeNode | undefined {\n\t\tconst editNode = getOrCreateInnerNode(node).parentField.parent.parent;\n\t\tif (editNode === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst output = getOrCreateNodeFromInnerNode(editNode);\n\t\tassert(\n\t\t\t!isTreeValue(output),\n\t\t\t0x87f /* Parent can't be a leaf, so it should be a node not a value */,\n\t\t);\n\t\treturn output;\n\t},\n\tkey(node: TreeNode): string | number {\n\t\t// If the parent is undefined, then this node is under the root field,\n\t\t// so we know its key is the special root one.\n\t\tconst parent = treeNodeApi.parent(node);\n\t\tif (parent === undefined) {\n\t\t\treturn rootFieldKey;\n\t\t}\n\n\t\t// The flex-domain strictly operates in terms of \"stored keys\".\n\t\t// To find the associated developer-facing \"property key\", we need to look up the field associated with\n\t\t// the stored key from the flex-domain, and get property key its simple-domain counterpart was created with.\n\t\tconst storedKey = getStoredKey(node);\n\t\tconst parentSchema = treeNodeApi.schema(parent);\n\t\tconst propertyKey = getPropertyKeyFromStoredKey(parentSchema, storedKey);\n\t\treturn propertyKey;\n\t},\n\ton<K extends keyof TreeChangeEvents>(\n\t\tnode: TreeNode,\n\t\teventName: K,\n\t\tlistener: TreeChangeEvents[K],\n\t): Off {\n\t\tconst kernel = getKernel(node);\n\t\tswitch (eventName) {\n\t\t\tcase \"nodeChanged\": {\n\t\t\t\tconst nodeSchema = kernel.schema;\n\t\t\t\tif (isObjectNodeSchema(nodeSchema)) {\n\t\t\t\t\treturn kernel.events.on(\"childrenChangedAfterBatch\", ({ changedFields }) => {\n\t\t\t\t\t\tconst changedProperties = new Set(\n\t\t\t\t\t\t\tArray.from(\n\t\t\t\t\t\t\t\tchangedFields,\n\t\t\t\t\t\t\t\t(field) =>\n\t\t\t\t\t\t\t\t\tnodeSchema.storedKeyToPropertyKey.get(field) ??\n\t\t\t\t\t\t\t\t\tfail(0xb36 /* Could not find stored key in schema. */),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tlistener({ changedProperties });\n\t\t\t\t\t});\n\t\t\t\t} else if (nodeSchema.kind === NodeKind.Array) {\n\t\t\t\t\treturn kernel.events.on(\"childrenChangedAfterBatch\", () => {\n\t\t\t\t\t\tlistener({ changedProperties: undefined });\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\treturn kernel.events.on(\"childrenChangedAfterBatch\", ({ changedFields }) => {\n\t\t\t\t\t\tlistener({ changedProperties: changedFields });\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tcase \"treeChanged\": {\n\t\t\t\treturn kernel.events.on(\"subtreeChangedAfterBatch\", () => listener({}));\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tthrow new UsageError(`No event named ${JSON.stringify(eventName)}.`);\n\t\t}\n\t},\n\tstatus(node: TreeNode): TreeStatus {\n\t\treturn getKernel(node).getStatus();\n\t},\n\tis<TSchema extends ImplicitAllowedTypes>(\n\t\tvalue: unknown,\n\t\tschema: TSchema,\n\t): value is TreeNodeFromImplicitAllowedTypes<TSchema> {\n\t\t// This \"is\" utility would return false if the provided schema is a base type of the actual schema.\n\t\t// This could be confusing, and that case can only be hit when violating the rule that there is a single most derived schema that gets used (See documentation on TreeNodeSchemaClass).\n\t\t// Therefore this uses markSchemaMostDerived to ensure an informative usage error is thrown in the case where a base type is used.\n\n\t\tconst actualSchema = tryGetSchema(value);\n\t\tif (actualSchema === undefined) {\n\t\t\treturn false;\n\t\t}\n\t\treturn normalizeAllowedTypes(schema).has(actualSchema);\n\t},\n\tschema(node: TreeNode | TreeLeafValue): TreeNodeSchema {\n\t\treturn tryGetSchema(node) ?? fail(0xb37 /* Not a tree node */);\n\t},\n\tshortId(node: TreeNode): number | string | undefined {\n\t\treturn getIdentifierFromNode(node, \"preferCompressed\");\n\t},\n};\n\n/**\n * Returns a schema for a value if the value is a {@link TreeNode} or a {@link TreeLeafValue}.\n * Returns undefined for other values.\n */\nexport function tryGetSchema(value: unknown): undefined | TreeNodeSchema {\n\tswitch (typeof value) {\n\t\tcase \"string\":\n\t\t\treturn stringSchema;\n\t\tcase \"number\":\n\t\t\treturn numberSchema;\n\t\tcase \"boolean\":\n\t\t\treturn booleanSchema;\n\t\tcase \"object\": {\n\t\t\tif (isTreeNode(value)) {\n\t\t\t\t// TODO: This case could be optimized, for example by placing the simple schema in a symbol on tree nodes.\n\t\t\t\treturn tryGetTreeNodeSchema(value);\n\t\t\t}\n\t\t\tif (value === null) {\n\t\t\t\treturn nullSchema;\n\t\t\t}\n\t\t\tif (isFluidHandle(value)) {\n\t\t\t\treturn handleSchema;\n\t\t\t}\n\t\t}\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n}\n\n/**\n * Gets the identifier from a node.\n *\n * @param node - {@link TreeNode} where you want to extract the identifier from.\n * @param compression - string value to determine what type of identifier you want to retrieve.\n *\n * @remarks\n * If the node does not contain an identifier field, it returns undefined.\n *\n * If `compression` is set to `compressed`:\n *\n * - If the node contains a compressible identifier known by the id compressor, the compressed identifier is returned.\n *\n * - If the node contains an identifier, but is not compressible or unknown by the id compressor, `undefined` is returned.\n *\n * If `compression` is set to `preferCompressed`:\n *\n * - If the node contains a compressible identifier known by the id compressor, the compressed identifier is returned.\n *\n * - If the node contains an identifier, but is not compressible or unknown by the id compressor, the uncompressed identifier is returned.\n *\n * If `compression` is set to `uncompressed`:\n * - If the node contains an identifier field, the uncompressed identifier is returned.\n */\nexport function getIdentifierFromNode(\n\tnode: TreeNode,\n\tcompression: \"preferCompressed\",\n): number | string | undefined;\nexport function getIdentifierFromNode(\n\tnode: TreeNode,\n\tcompression: \"compressed\",\n): number | undefined;\nexport function getIdentifierFromNode(\n\tnode: TreeNode,\n\tcompression: \"uncompressed\",\n): string | undefined;\nexport function getIdentifierFromNode(\n\tnode: TreeNode,\n\tcompression: \"preferCompressed\" | \"compressed\" | \"uncompressed\",\n): number | string | undefined {\n\tconst schema = node[typeSchemaSymbol];\n\tif (!isObjectNodeSchema(schema)) {\n\t\treturn undefined;\n\t}\n\n\tconst flexNode = getOrCreateInnerNode(node);\n\tconst identifierFieldKeys = schema.identifierFieldKeys;\n\n\tswitch (identifierFieldKeys.length) {\n\t\tcase 0:\n\t\t\treturn undefined;\n\t\tcase 1: {\n\t\t\tconst key = identifierFieldKeys[0] ?? oob();\n\t\t\tconst identifierField = flexNode.tryGetField(key);\n\t\t\tassert(identifierField !== undefined, 0xbb5 /* missing identifier field */);\n\t\t\tconst identifierValue = tryGetTreeNodeForField(identifierField);\n\t\t\tassert(typeof identifierValue === \"string\", 0xbb6 /* identifier not a string */);\n\n\t\t\tconst context = flexNode.context;\n\t\t\tswitch (compression) {\n\t\t\t\tcase \"preferCompressed\": {\n\t\t\t\t\tif (context.isHydrated()) {\n\t\t\t\t\t\tconst localNodeKey =\n\t\t\t\t\t\t\tcontext.nodeKeyManager.tryLocalizeNodeIdentifier(identifierValue);\n\t\t\t\t\t\treturn localNodeKey !== undefined\n\t\t\t\t\t\t\t? extractFromOpaque(localNodeKey)\n\t\t\t\t\t\t\t: identifierValue;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn identifierValue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcase \"compressed\": {\n\t\t\t\t\tif (context.isHydrated()) {\n\t\t\t\t\t\tconst localNodeKey =\n\t\t\t\t\t\t\tcontext.nodeKeyManager.tryLocalizeNodeIdentifier(identifierValue);\n\t\t\t\t\t\treturn localNodeKey !== undefined ? extractFromOpaque(localNodeKey) : undefined;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcase \"uncompressed\": {\n\t\t\t\t\treturn identifierValue;\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\tunreachableCase(compression);\n\t\t\t}\n\t\t}\n\t\tdefault:\n\t\t\tthrow new UsageError(\n\t\t\t\t\"shortId() may not be called on a node with more than one identifier. Consider converting extraneous identifier fields to string fields.\",\n\t\t\t);\n\t}\n}\n\n/**\n * Gets the stored key with which the provided node is associated in the parent.\n */\nexport function getStoredKey(node: TreeNode): string | number {\n\t// Note: the flex domain strictly works with \"stored keys\", and knows nothing about the developer-facing\n\t// \"property keys\".\n\tconst parentField = getOrCreateInnerNode(node).parentField;\n\tif (parentField.parent.schema === FieldKinds.sequence.identifier) {\n\t\t// The parent of `node` is an array node\n\t\tassert(\n\t\t\tparentField.parent.key === EmptyKey,\n\t\t\t0xa28 /* When using index as key, field should use EmptyKey */,\n\t\t);\n\t\treturn parentField.index;\n\t}\n\n\t// The parent of `node` is an object, a map, or undefined. If undefined, then `node` is a root/detached node.\n\tassert(parentField.index === 0, 0xa29 /* When using field key as key, index should be 0 */);\n\treturn parentField.parent.key;\n}\n\n/**\n * Given a node schema, gets the property key corresponding with the provided {@link FieldProps.key | stored key}.\n */\nexport function getPropertyKeyFromStoredKey(\n\tschema: TreeNodeSchema,\n\tstoredKey: string | number,\n): string | number {\n\t// Only object nodes have the concept of a \"stored key\", differentiated from the developer-facing \"property key\".\n\t// For any other kind of node, the stored key and the property key are the same.\n\tif (schema.kind !== NodeKind.Object) {\n\t\treturn storedKey;\n\t}\n\n\tconst fields = schema.info as Record<string, ImplicitFieldSchema>;\n\n\t// Invariants:\n\t// - The set of all property keys under an object must be unique.\n\t// - The set of all stored keys (including those implicitly created from property keys) must be unique.\n\t// To find the property key associated with the provided stored key, first check for any stored key matches (which are optionally populated).\n\t// If we don't find any, then search for a matching property key.\n\tfor (const [propertyKey, fieldSchema] of Object.entries(fields)) {\n\t\tif (fieldSchema instanceof FieldSchema && fieldSchema.props?.key === storedKey) {\n\t\t\treturn propertyKey;\n\t\t}\n\t}\n\n\tif (fields[storedKey] === undefined) {\n\t\tfail(0xb38 /* Existing stored key should always map to a property key */);\n\t}\n\n\treturn storedKey;\n}\n"]}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { type TreeNodeSchemaIdentifier } from "../../core/index.js";
|
|
6
6
|
import type { FlexTreeContext, FlexTreeHydratedContext } from "../../feature-libraries/index.js";
|
|
7
|
-
import type { TreeNodeSchema } from "./treeNodeSchema.js";
|
|
7
|
+
import type { NormalizedAnnotatedAllowedTypes, TreeNodeSchema } from "./treeNodeSchema.js";
|
|
8
8
|
/**
|
|
9
9
|
* Creating multiple simple tree contexts for the same branch, and thus with the same underlying AnchorSet does not work due to how TreeNode caching works.
|
|
10
10
|
* This slot is used to detect if one already exists and error if creating a second.
|
|
@@ -42,7 +42,7 @@ export declare class Context {
|
|
|
42
42
|
* @remarks
|
|
43
43
|
* Since this walks the schema, it must not be invoked during schema declaration or schema forward references could fail to be resolved.
|
|
44
44
|
*/
|
|
45
|
-
constructor(rootSchema:
|
|
45
|
+
constructor(rootSchema: NormalizedAnnotatedAllowedTypes, flexContext: FlexTreeContext);
|
|
46
46
|
}
|
|
47
47
|
/**
|
|
48
48
|
* Extends {@link Context} with additional information from the view and/or tree which becomes known when a {@link TreeNode} is hydrated,
|
|
@@ -50,6 +50,6 @@ export declare class Context {
|
|
|
50
50
|
*/
|
|
51
51
|
export declare class HydratedContext extends Context {
|
|
52
52
|
readonly flexContext: FlexTreeHydratedContext;
|
|
53
|
-
constructor(rootSchema:
|
|
53
|
+
constructor(rootSchema: NormalizedAnnotatedAllowedTypes, flexContext: FlexTreeHydratedContext);
|
|
54
54
|
}
|
|
55
55
|
//# sourceMappingURL=context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/simple-tree/core/context.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAc,KAAK,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAChF,OAAO,KAAK,EACX,eAAe,EACf,uBAAuB,EACvB,MAAM,kCAAkC,CAAC;AAG1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/simple-tree/core/context.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAc,KAAK,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAChF,OAAO,KAAK,EACX,eAAe,EACf,uBAAuB,EACvB,MAAM,kCAAkC,CAAC;AAG1C,OAAO,KAAK,EAAE,+BAA+B,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAG3F;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,2DAAgC,CAAC;AAE/D;;;;;;;;;;;;GAYG;AACH,qBAAa,OAAO;aAmBF,WAAW,EAAE,eAAe;IAlB7C;;;;;;;;OAQG;IACH,SAAgB,MAAM,EAAE,WAAW,CAAC,wBAAwB,EAAE,cAAc,CAAC,CAAC;IAE9E;;;;OAIG;gBAEF,UAAU,EAAE,+BAA+B,EAC3B,WAAW,EAAE,eAAe;CAU7C;AAED;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,OAAO;aAGjB,WAAW,EAAE,uBAAuB;gBAD7D,UAAU,EAAE,+BAA+B,EAClB,WAAW,EAAE,uBAAuB;CAI9D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/simple-tree/core/context.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,kDAAgF;AAKhF,kDAA4C;AAG5C,mDAAmD;AAEnD;;;;;GAKG;AACU,QAAA,iBAAiB,GAAG,IAAA,qBAAU,GAAmB,CAAC;AAE/D;;;;;;;;;;;;GAYG;AACH,MAAa,OAAO;IAYnB;;;;OAIG;IACH,YACC,
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/simple-tree/core/context.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,kDAAgF;AAKhF,kDAA4C;AAG5C,mDAAmD;AAEnD;;;;;GAKG;AACU,QAAA,iBAAiB,GAAG,IAAA,qBAAU,GAAmB,CAAC;AAE/D;;;;;;;;;;;;GAYG;AACH,MAAa,OAAO;IAYnB;;;;OAIG;IACH,YACC,UAA2C,EAC3B,WAA4B;QAA5B,gBAAW,GAAX,WAAW,CAAiB;QAE5C,MAAM,MAAM,GAAkD,IAAI,GAAG,EAAE,CAAC;QACxE,IAAA,gCAAgB,EAAC,UAAU,EAAE;YAC5B,IAAI,CAAC,UAAU;gBACd,MAAM,CAAC,GAAG,CAAC,IAAA,gBAAK,EAAC,UAAU,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC,CAAC;YACtD,CAAC;SACD,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACtB,CAAC;CACD;AA7BD,0BA6BC;AAED;;;GAGG;AACH,MAAa,eAAgB,SAAQ,OAAO;IAC3C,YACC,UAA2C,EAClB,WAAoC;QAE7D,KAAK,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;QAFN,gBAAW,GAAX,WAAW,CAAyB;IAG9D,CAAC;CACD;AAPD,0CAOC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { anchorSlot, type TreeNodeSchemaIdentifier } from \"../../core/index.js\";\nimport type {\n\tFlexTreeContext,\n\tFlexTreeHydratedContext,\n} from \"../../feature-libraries/index.js\";\nimport { brand } from \"../../util/index.js\";\n\nimport type { NormalizedAnnotatedAllowedTypes, TreeNodeSchema } from \"./treeNodeSchema.js\";\nimport { walkAllowedTypes } from \"./walkSchema.js\";\n\n/**\n * Creating multiple simple tree contexts for the same branch, and thus with the same underlying AnchorSet does not work due to how TreeNode caching works.\n * This slot is used to detect if one already exists and error if creating a second.\n * @remarks\n * See also {@link ContextSlot} in which the flex-tree context is stored.\n */\nexport const SimpleContextSlot = anchorSlot<HydratedContext>();\n\n/**\n * Additional information about a collection of {@link TreeNode}s.\n * @remarks\n * Each TreeNode provides a way to navigate to a context for it with additional information.\n *\n * For unhydrated nodes, this information is rather limited since the node doesn't know what tree it might get inserted into (if any),\n * and thus is limited to information derived about that particular unhydrated tree and its schema.\n *\n * Hydrated nodes have more contextual information, and thus can provide a single {@link HydratedContext} for all nodes in the document which can have additional information.\n *\n * @privateRemarks\n * This design is the same as {@link FlexTreeContext} with its base type and {@link FlexTreeHydratedContext} extending it.\n */\nexport class Context {\n\t/**\n\t * All schema which could transitively be used under the associated node.\n\t * @remarks\n\t * While generally {@link TreeNodeSchema} are referenced as objects and thus do not need to be looked up by identifier,\n\t * there are a few cases (mainly constructing new TreeNodes from existing tree data) where such a lookup is useful.\n\t * Having this map in the context addresses this use-case.\n\t * @privateRemarks\n\t * This design mirrors how {@link FlexTreeSchema} are accessed off the {@link FlexTreeContext}, making the migration away from them simpler.\n\t */\n\tpublic readonly schema: ReadonlyMap<TreeNodeSchemaIdentifier, TreeNodeSchema>;\n\n\t/**\n\t * Builds the context.\n\t * @remarks\n\t * Since this walks the schema, it must not be invoked during schema declaration or schema forward references could fail to be resolved.\n\t */\n\tpublic constructor(\n\t\trootSchema: NormalizedAnnotatedAllowedTypes,\n\t\tpublic readonly flexContext: FlexTreeContext,\n\t) {\n\t\tconst schema: Map<TreeNodeSchemaIdentifier, TreeNodeSchema> = new Map();\n\t\twalkAllowedTypes(rootSchema, {\n\t\t\tnode(nodeSchema) {\n\t\t\t\tschema.set(brand(nodeSchema.identifier), nodeSchema);\n\t\t\t},\n\t\t});\n\t\tthis.schema = schema;\n\t}\n}\n\n/**\n * Extends {@link Context} with additional information from the view and/or tree which becomes known when a {@link TreeNode} is hydrated,\n * associating it with the containing {@link TreeView}.\n */\nexport class HydratedContext extends Context {\n\tpublic constructor(\n\t\trootSchema: NormalizedAnnotatedAllowedTypes,\n\t\tpublic override readonly flexContext: FlexTreeHydratedContext,\n\t) {\n\t\tsuper(rootSchema, flexContext);\n\t}\n}\n"]}
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
import type { TreeValue } from "../../core/index.js";
|
|
6
|
+
import { type FlexTreeUnknownUnboxed } from "../../feature-libraries/index.js";
|
|
7
|
+
import type { TreeLeafValue } from "../schemaTypes.js";
|
|
6
8
|
import type { TreeNode } from "./treeNode.js";
|
|
7
9
|
import { type InnerNode } from "./treeNodeKernel.js";
|
|
8
10
|
/**
|
|
@@ -12,4 +14,11 @@ import { type InnerNode } from "./treeNodeKernel.js";
|
|
|
12
14
|
* This supports both hydrated and unhydrated nodes.
|
|
13
15
|
*/
|
|
14
16
|
export declare function getOrCreateNodeFromInnerNode(flexNode: InnerNode): TreeNode | TreeValue;
|
|
17
|
+
/**
|
|
18
|
+
* Returns the TreeNode or TreeValue for the provided {@link FlexTreeUnknownUnboxed}.
|
|
19
|
+
* This will allocate a new one if needed, and otherwise return one from cache.
|
|
20
|
+
* @remarks
|
|
21
|
+
* This supports both hydrated and unhydrated nodes.
|
|
22
|
+
*/
|
|
23
|
+
export declare function getOrCreateNodeFromInnerUnboxedNode(flexTree: FlexTreeUnknownUnboxed): TreeNode | TreeLeafValue;
|
|
15
24
|
//# sourceMappingURL=getOrCreateNode.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getOrCreateNode.d.ts","sourceRoot":"","sources":["../../../src/simple-tree/core/getOrCreateNode.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"getOrCreateNode.d.ts","sourceRoot":"","sources":["../../../src/simple-tree/core/getOrCreateNode.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAkB,KAAK,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAC/F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EACN,KAAK,SAAS,EAId,MAAM,qBAAqB,CAAC;AAG7B;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAatF;AAED;;;;;GAKG;AACH,wBAAgB,mCAAmC,CAClD,QAAQ,EAAE,sBAAsB,GAC9B,QAAQ,GAAG,aAAa,CAE1B"}
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.getOrCreateNodeFromInnerNode = void 0;
|
|
7
|
+
exports.getOrCreateNodeFromInnerUnboxedNode = exports.getOrCreateNodeFromInnerNode = void 0;
|
|
8
|
+
const index_js_1 = require("../../feature-libraries/index.js");
|
|
8
9
|
const treeNodeKernel_js_1 = require("./treeNodeKernel.js");
|
|
9
10
|
const unhydratedFlexTree_js_1 = require("./unhydratedFlexTree.js");
|
|
10
11
|
/**
|
|
@@ -24,4 +25,14 @@ function getOrCreateNodeFromInnerNode(flexNode) {
|
|
|
24
25
|
return (0, treeNodeKernel_js_1.createTreeNodeFromInner)(flexNode);
|
|
25
26
|
}
|
|
26
27
|
exports.getOrCreateNodeFromInnerNode = getOrCreateNodeFromInnerNode;
|
|
28
|
+
/**
|
|
29
|
+
* Returns the TreeNode or TreeValue for the provided {@link FlexTreeUnknownUnboxed}.
|
|
30
|
+
* This will allocate a new one if needed, and otherwise return one from cache.
|
|
31
|
+
* @remarks
|
|
32
|
+
* This supports both hydrated and unhydrated nodes.
|
|
33
|
+
*/
|
|
34
|
+
function getOrCreateNodeFromInnerUnboxedNode(flexTree) {
|
|
35
|
+
return (0, index_js_1.isFlexTreeNode)(flexTree) ? getOrCreateNodeFromInnerNode(flexTree) : flexTree;
|
|
36
|
+
}
|
|
37
|
+
exports.getOrCreateNodeFromInnerUnboxedNode = getOrCreateNodeFromInnerUnboxedNode;
|
|
27
38
|
//# sourceMappingURL=getOrCreateNode.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getOrCreateNode.js","sourceRoot":"","sources":["../../../src/simple-tree/core/getOrCreateNode.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;
|
|
1
|
+
{"version":3,"file":"getOrCreateNode.js","sourceRoot":"","sources":["../../../src/simple-tree/core/getOrCreateNode.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,+DAA+F;AAI/F,2DAK6B;AAC7B,mEAAiE;AAEjE;;;;;GAKG;AACH,SAAgB,4BAA4B,CAAC,QAAmB;IAC/D,IAAA,sCAAkB,EAAC,QAAQ,CAAC,CAAC;IAE7B,MAAM,MAAM,GACX,QAAQ,YAAY,8CAAsB;QACzC,CAAC,CAAC,QAAQ,CAAC,QAAQ;QACnB,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,sCAAkB,CAAC,CAAC;IAEtD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,MAAM,CAAC;IACf,CAAC;IAED,OAAO,IAAA,2CAAuB,EAAC,QAAQ,CAAC,CAAC;AAC1C,CAAC;AAbD,oEAaC;AAED;;;;;GAKG;AACH,SAAgB,mCAAmC,CAClD,QAAgC;IAEhC,OAAO,IAAA,yBAAc,EAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,4BAA4B,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;AACrF,CAAC;AAJD,kFAIC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { TreeValue } from \"../../core/index.js\";\nimport { isFlexTreeNode, type FlexTreeUnknownUnboxed } from \"../../feature-libraries/index.js\";\nimport type { TreeLeafValue } from \"../schemaTypes.js\";\n\nimport type { TreeNode } from \"./treeNode.js\";\nimport {\n\ttype InnerNode,\n\tsimpleTreeNodeSlot,\n\tcreateTreeNodeFromInner,\n\tsplitInnerNodeType,\n} from \"./treeNodeKernel.js\";\nimport { UnhydratedFlexTreeNode } from \"./unhydratedFlexTree.js\";\n\n/**\n * Returns the TreeNode or TreeValue for the provided {@link InnerNode}.\n * This will allocate a new one if needed, and otherwise return one from cache.\n * @remarks\n * This supports both hydrated and unhydrated nodes.\n */\nexport function getOrCreateNodeFromInnerNode(flexNode: InnerNode): TreeNode | TreeValue {\n\tsplitInnerNodeType(flexNode);\n\n\tconst cached =\n\t\tflexNode instanceof UnhydratedFlexTreeNode\n\t\t\t? flexNode.treeNode\n\t\t\t: flexNode.anchorNode.slots.get(simpleTreeNodeSlot);\n\n\tif (cached !== undefined) {\n\t\treturn cached;\n\t}\n\n\treturn createTreeNodeFromInner(flexNode);\n}\n\n/**\n * Returns the TreeNode or TreeValue for the provided {@link FlexTreeUnknownUnboxed}.\n * This will allocate a new one if needed, and otherwise return one from cache.\n * @remarks\n * This supports both hydrated and unhydrated nodes.\n */\nexport function getOrCreateNodeFromInnerUnboxedNode(\n\tflexTree: FlexTreeUnknownUnboxed,\n): TreeNode | TreeLeafValue {\n\treturn isFlexTreeNode(flexTree) ? getOrCreateNodeFromInnerNode(flexTree) : flexTree;\n}\n"]}
|
|
@@ -6,9 +6,9 @@ export { isTreeNode, TreeNodeKernel, getKernel, tryGetTreeNodeSchema, type Inner
|
|
|
6
6
|
export { type WithType, typeNameSymbol, typeSchemaSymbol } from "./withType.js";
|
|
7
7
|
export { type Unhydrated, type InternalTreeNode, } from "./types.js";
|
|
8
8
|
export { TreeNode, privateToken, inPrototypeChain, } from "./treeNode.js";
|
|
9
|
-
export { type TreeNodeSchema, NodeKind, type TreeNodeSchemaClass, type TreeNodeSchemaNonClass, type TreeNodeSchemaCore, type TreeNodeSchemaBoth, } from "./treeNodeSchema.js";
|
|
9
|
+
export { type TreeNodeSchema, NodeKind, type TreeNodeSchemaClass, type TreeNodeSchemaNonClass, type TreeNodeSchemaCore, type TreeNodeSchemaBoth, type AnnotatedAllowedType, type NormalizedAnnotatedAllowedTypes, isAnnotatedAllowedTypes, } from "./treeNodeSchema.js";
|
|
10
10
|
export { walkAllowedTypes, type SchemaVisitor } from "./walkSchema.js";
|
|
11
11
|
export { Context, HydratedContext, SimpleContextSlot } from "./context.js";
|
|
12
|
-
export { getOrCreateNodeFromInnerNode } from "./getOrCreateNode.js";
|
|
12
|
+
export { getOrCreateNodeFromInnerNode, getOrCreateNodeFromInnerUnboxedNode, } from "./getOrCreateNode.js";
|
|
13
13
|
export { UnhydratedFlexTreeNode, UnhydratedSequenceField, UnhydratedContext, createField, } from "./unhydratedFlexTree.js";
|
|
14
14
|
//# sourceMappingURL=index.d.ts.map
|