@fluidframework/tree 2.112.0 → 2.113.1
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 +174 -0
- package/api-report/tree.alpha.api.md +23 -2
- package/dist/entrypoints/alpha.d.ts +1 -1
- package/dist/entrypoints/alpha.d.ts.map +1 -1
- package/dist/entrypoints/alpha.js +3 -2
- package/dist/entrypoints/alpha.js.map +1 -1
- package/dist/feature-libraries/default-schema/defaultFieldKinds.js +1 -1
- package/dist/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
- package/dist/feature-libraries/modular-schema/fieldChangeHandler.d.ts +39 -7
- package/dist/feature-libraries/modular-schema/fieldChangeHandler.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/fieldChangeHandler.js +22 -2
- package/dist/feature-libraries/modular-schema/fieldChangeHandler.js.map +1 -1
- package/dist/feature-libraries/modular-schema/genericFieldKind.js +1 -1
- package/dist/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
- package/dist/feature-libraries/modular-schema/index.d.ts +1 -1
- package/dist/feature-libraries/modular-schema/index.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/index.js +2 -1
- package/dist/feature-libraries/modular-schema/index.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js +8 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/dist/feature-libraries/optional-field/optionalField.d.ts.map +1 -1
- package/dist/feature-libraries/optional-field/optionalField.js +26 -3
- package/dist/feature-libraries/optional-field/optionalField.js.map +1 -1
- package/dist/feature-libraries/sequence-field/filterEdits.d.ts +12 -0
- package/dist/feature-libraries/sequence-field/filterEdits.d.ts.map +1 -0
- package/dist/feature-libraries/sequence-field/filterEdits.js +111 -0
- package/dist/feature-libraries/sequence-field/filterEdits.js.map +1 -0
- package/dist/feature-libraries/sequence-field/markQueue.d.ts +8 -3
- package/dist/feature-libraries/sequence-field/markQueue.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/markQueue.js +22 -8
- package/dist/feature-libraries/sequence-field/markQueue.js.map +1 -1
- package/dist/feature-libraries/sequence-field/moveEffectTable.d.ts +1 -1
- package/dist/feature-libraries/sequence-field/moveEffectTable.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/moveEffectTable.js +2 -6
- package/dist/feature-libraries/sequence-field/moveEffectTable.js.map +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldChangeRebaser.d.ts +7 -6
- package/dist/feature-libraries/sequence-field/sequenceFieldChangeRebaser.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldChangeRebaser.js +2 -4
- package/dist/feature-libraries/sequence-field/sequenceFieldChangeRebaser.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/shared-tree/schematizingTreeView.d.ts +8 -0
- package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
- package/dist/shared-tree/schematizingTreeView.js +25 -13
- package/dist/shared-tree/schematizingTreeView.js.map +1 -1
- package/dist/simple-tree/api/configuration.d.ts +32 -2
- package/dist/simple-tree/api/configuration.d.ts.map +1 -1
- package/dist/simple-tree/api/configuration.js +3 -1
- 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.map +1 -1
- package/dist/simple-tree/api/schemaCompatibilityTester.d.ts +7 -4
- package/dist/simple-tree/api/schemaCompatibilityTester.d.ts.map +1 -1
- package/dist/simple-tree/api/schemaCompatibilityTester.js +7 -5
- package/dist/simple-tree/api/schemaCompatibilityTester.js.map +1 -1
- package/dist/simple-tree/api/tree.d.ts +58 -1
- package/dist/simple-tree/api/tree.d.ts.map +1 -1
- package/dist/simple-tree/api/tree.js.map +1 -1
- package/dist/simple-tree/core/index.d.ts +1 -1
- package/dist/simple-tree/core/index.d.ts.map +1 -1
- package/dist/simple-tree/core/index.js +2 -1
- package/dist/simple-tree/core/index.js.map +1 -1
- package/dist/simple-tree/core/toStored.d.ts +72 -6
- package/dist/simple-tree/core/toStored.d.ts.map +1 -1
- package/dist/simple-tree/core/toStored.js +25 -1
- package/dist/simple-tree/core/toStored.js.map +1 -1
- package/dist/simple-tree/index.d.ts +3 -3
- package/dist/simple-tree/index.d.ts.map +1 -1
- package/dist/simple-tree/index.js +4 -5
- package/dist/simple-tree/index.js.map +1 -1
- package/dist/simple-tree/prepareForInsertion.d.ts.map +1 -1
- package/dist/simple-tree/prepareForInsertion.js +9 -0
- package/dist/simple-tree/prepareForInsertion.js.map +1 -1
- package/dist/simple-tree/toStoredSchema.d.ts +11 -27
- package/dist/simple-tree/toStoredSchema.d.ts.map +1 -1
- package/dist/simple-tree/toStoredSchema.js +25 -33
- package/dist/simple-tree/toStoredSchema.js.map +1 -1
- package/docs/main/runtime-schema-upgrade.md +208 -0
- package/lib/entrypoints/alpha.d.ts +1 -1
- package/lib/entrypoints/alpha.d.ts.map +1 -1
- package/lib/entrypoints/alpha.js +1 -1
- package/lib/entrypoints/alpha.js.map +1 -1
- package/lib/feature-libraries/default-schema/defaultFieldKinds.js +1 -1
- package/lib/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
- package/lib/feature-libraries/modular-schema/fieldChangeHandler.d.ts +39 -7
- package/lib/feature-libraries/modular-schema/fieldChangeHandler.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/fieldChangeHandler.js +21 -1
- package/lib/feature-libraries/modular-schema/fieldChangeHandler.js.map +1 -1
- package/lib/feature-libraries/modular-schema/genericFieldKind.js +1 -1
- package/lib/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
- package/lib/feature-libraries/modular-schema/index.d.ts +1 -1
- package/lib/feature-libraries/modular-schema/index.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/index.js +1 -1
- package/lib/feature-libraries/modular-schema/index.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js +9 -2
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/lib/feature-libraries/optional-field/optionalField.d.ts.map +1 -1
- package/lib/feature-libraries/optional-field/optionalField.js +27 -4
- package/lib/feature-libraries/optional-field/optionalField.js.map +1 -1
- package/lib/feature-libraries/sequence-field/filterEdits.d.ts +12 -0
- package/lib/feature-libraries/sequence-field/filterEdits.d.ts.map +1 -0
- package/lib/feature-libraries/sequence-field/filterEdits.js +107 -0
- package/lib/feature-libraries/sequence-field/filterEdits.js.map +1 -0
- package/lib/feature-libraries/sequence-field/markQueue.d.ts +8 -3
- package/lib/feature-libraries/sequence-field/markQueue.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/markQueue.js +22 -9
- package/lib/feature-libraries/sequence-field/markQueue.js.map +1 -1
- package/lib/feature-libraries/sequence-field/moveEffectTable.d.ts +1 -1
- package/lib/feature-libraries/sequence-field/moveEffectTable.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/moveEffectTable.js +2 -6
- package/lib/feature-libraries/sequence-field/moveEffectTable.js.map +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldChangeRebaser.d.ts +7 -6
- package/lib/feature-libraries/sequence-field/sequenceFieldChangeRebaser.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldChangeRebaser.js +2 -4
- package/lib/feature-libraries/sequence-field/sequenceFieldChangeRebaser.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/shared-tree/schematizingTreeView.d.ts +8 -0
- package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
- package/lib/shared-tree/schematizingTreeView.js +26 -14
- package/lib/shared-tree/schematizingTreeView.js.map +1 -1
- package/lib/simple-tree/api/configuration.d.ts +32 -2
- package/lib/simple-tree/api/configuration.d.ts.map +1 -1
- package/lib/simple-tree/api/configuration.js +4 -2
- 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.map +1 -1
- package/lib/simple-tree/api/schemaCompatibilityTester.d.ts +7 -4
- package/lib/simple-tree/api/schemaCompatibilityTester.d.ts.map +1 -1
- package/lib/simple-tree/api/schemaCompatibilityTester.js +7 -5
- package/lib/simple-tree/api/schemaCompatibilityTester.js.map +1 -1
- package/lib/simple-tree/api/tree.d.ts +58 -1
- package/lib/simple-tree/api/tree.d.ts.map +1 -1
- package/lib/simple-tree/api/tree.js.map +1 -1
- package/lib/simple-tree/core/index.d.ts +1 -1
- package/lib/simple-tree/core/index.d.ts.map +1 -1
- package/lib/simple-tree/core/index.js +1 -1
- package/lib/simple-tree/core/index.js.map +1 -1
- package/lib/simple-tree/core/toStored.d.ts +72 -6
- package/lib/simple-tree/core/toStored.d.ts.map +1 -1
- package/lib/simple-tree/core/toStored.js +24 -0
- package/lib/simple-tree/core/toStored.js.map +1 -1
- package/lib/simple-tree/index.d.ts +3 -3
- package/lib/simple-tree/index.d.ts.map +1 -1
- package/lib/simple-tree/index.js +2 -2
- package/lib/simple-tree/index.js.map +1 -1
- package/lib/simple-tree/prepareForInsertion.d.ts.map +1 -1
- package/lib/simple-tree/prepareForInsertion.js +9 -0
- package/lib/simple-tree/prepareForInsertion.js.map +1 -1
- package/lib/simple-tree/toStoredSchema.d.ts +11 -27
- package/lib/simple-tree/toStoredSchema.d.ts.map +1 -1
- package/lib/simple-tree/toStoredSchema.js +24 -33
- package/lib/simple-tree/toStoredSchema.js.map +1 -1
- package/package.json +21 -21
- package/src/entrypoints/alpha.ts +3 -0
- package/src/feature-libraries/default-schema/defaultFieldKinds.ts +1 -1
- package/src/feature-libraries/modular-schema/fieldChangeHandler.ts +51 -7
- package/src/feature-libraries/modular-schema/genericFieldKind.ts +1 -1
- package/src/feature-libraries/modular-schema/index.ts +4 -2
- package/src/feature-libraries/modular-schema/modularChangeFamily.ts +16 -1
- package/src/feature-libraries/optional-field/optionalField.ts +43 -3
- package/src/feature-libraries/sequence-field/filterEdits.ts +143 -0
- package/src/feature-libraries/sequence-field/markQueue.ts +28 -11
- package/src/feature-libraries/sequence-field/moveEffectTable.ts +2 -7
- package/src/feature-libraries/sequence-field/sequenceFieldChangeRebaser.ts +3 -5
- package/src/index.ts +3 -0
- package/src/packageVersion.ts +1 -1
- package/src/shared-tree/schematizingTreeView.ts +42 -20
- package/src/simple-tree/api/configuration.ts +40 -2
- package/src/simple-tree/api/index.ts +1 -0
- package/src/simple-tree/api/schemaCompatibilityTester.ts +8 -4
- package/src/simple-tree/api/tree.ts +58 -1
- package/src/simple-tree/core/index.ts +2 -1
- package/src/simple-tree/core/toStored.ts +95 -8
- package/src/simple-tree/index.ts +3 -2
- package/src/simple-tree/prepareForInsertion.ts +12 -0
- package/src/simple-tree/toStoredSchema.ts +44 -39
|
@@ -11,6 +11,7 @@ import type { MakeNominal } from "../../util/index.js";
|
|
|
11
11
|
import {
|
|
12
12
|
type AllowedTypesFullEvaluated,
|
|
13
13
|
NodeKind,
|
|
14
|
+
StagedSchemaUpgradePolicy,
|
|
14
15
|
type TreeNodeSchema,
|
|
15
16
|
} from "../core/index.js";
|
|
16
17
|
import { type FieldSchemaAlpha, type ImplicitFieldSchema, FieldKind } from "../fieldSchema.js";
|
|
@@ -155,6 +156,35 @@ export interface ITreeViewConfiguration<
|
|
|
155
156
|
readonly schema: TSchema;
|
|
156
157
|
}
|
|
157
158
|
|
|
159
|
+
/**
|
|
160
|
+
* Property-bag configuration for {@link TreeViewConfigurationAlpha} construction.
|
|
161
|
+
* @alpha
|
|
162
|
+
*/
|
|
163
|
+
export interface ITreeViewConfigurationAlpha<
|
|
164
|
+
TSchema extends ImplicitFieldSchema = ImplicitFieldSchema,
|
|
165
|
+
> extends ITreeViewConfiguration<TSchema> {
|
|
166
|
+
/**
|
|
167
|
+
* Policy for generating stored schema from the view schema.
|
|
168
|
+
*
|
|
169
|
+
* @remarks
|
|
170
|
+
* If omitted or `undefined`, defaults to {@link StagedSchemaUpgradePolicyFactory.restrictive}
|
|
171
|
+
* which does not enable any staged schema upgrades.
|
|
172
|
+
*
|
|
173
|
+
* If provided, this policy is used when generating stored schema to include in documents via
|
|
174
|
+
* `initialize` / `upgradeSchema` as well as in {@link snapshotSchemaCompatibility} to validate
|
|
175
|
+
* the compatibility of such documents.
|
|
176
|
+
*
|
|
177
|
+
* @example Enabling specific staged upgrades
|
|
178
|
+
* ```typescript
|
|
179
|
+
* const config = new TreeViewConfigurationAlpha({
|
|
180
|
+
* schema: MySchema,
|
|
181
|
+
* stagedUpgradePolicy: StagedSchemaUpgradePolicy.enabledStagedUpgrades(myUpgrade),
|
|
182
|
+
* });
|
|
183
|
+
* ```
|
|
184
|
+
*/
|
|
185
|
+
readonly stagedUpgradePolicy?: StagedSchemaUpgradePolicy;
|
|
186
|
+
}
|
|
187
|
+
|
|
158
188
|
/**
|
|
159
189
|
* Configuration for {@link ViewableTree.viewWith}.
|
|
160
190
|
* @sealed @public
|
|
@@ -252,14 +282,22 @@ export class TreeViewConfigurationAlpha<
|
|
|
252
282
|
SimpleNodeSchema<SchemaType.View> & TreeNodeSchema
|
|
253
283
|
>;
|
|
254
284
|
|
|
255
|
-
|
|
285
|
+
/**
|
|
286
|
+
* {@inheritDoc ITreeViewConfigurationAlpha.stagedUpgradePolicy}
|
|
287
|
+
*/
|
|
288
|
+
public readonly stagedUpgradePolicy: StagedSchemaUpgradePolicy;
|
|
289
|
+
|
|
290
|
+
public constructor(props: ITreeViewConfigurationAlpha<TSchema>) {
|
|
256
291
|
super(props);
|
|
257
292
|
const treeSchema = createTreeSchema(this.schema);
|
|
258
293
|
this.root = treeSchema.root;
|
|
259
294
|
this.definitions = treeSchema.definitions;
|
|
260
295
|
|
|
296
|
+
this.stagedUpgradePolicy =
|
|
297
|
+
props.stagedUpgradePolicy ?? StagedSchemaUpgradePolicy.restrictive;
|
|
298
|
+
|
|
261
299
|
// Eagerly perform these conversions to surface errors sooner.
|
|
262
|
-
toInitialSchema(this.root);
|
|
300
|
+
toInitialSchema(this.root, this.stagedUpgradePolicy);
|
|
263
301
|
transformSimpleSchema(treeSchema, toUnhydratedSchema);
|
|
264
302
|
}
|
|
265
303
|
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import type { TreeStoredSchema } from "../../core/index.js";
|
|
7
|
+
import type { SchemaUpgrade, StagedSchemaUpgradePolicy } from "../core/index.js";
|
|
7
8
|
import { allowsRepoSuperset, defaultSchemaPolicy } from "../../feature-libraries/index.js";
|
|
8
9
|
import { toUpgradeSchema } from "../toStoredSchema.js";
|
|
9
10
|
import type { TreeSchema } from "../treeSchema.js";
|
|
@@ -12,19 +13,22 @@ import { getDiscrepanciesInAllowedContent } from "./discrepancies.js";
|
|
|
12
13
|
import type { SchemaCompatibilityStatus } from "./tree.js";
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
|
-
* Determines the compatibility of a stored document
|
|
16
|
-
* (based on its stored schema) with a viewer (based on its view schema).
|
|
16
|
+
* Determines the compatibility of a stored document (based on its stored schema) with a viewer (based on its view schema).
|
|
17
17
|
*
|
|
18
|
-
* @remarks
|
|
19
18
|
* Adapters can be provided to handle differences between the two schema.
|
|
20
19
|
* Adapters should only use to types in the `view` SchemaRepository.
|
|
21
20
|
*
|
|
22
21
|
* TODO: this API violates the parse don't validate design philosophy.
|
|
23
22
|
* It should be wrapped with (or replaced by) a parse style API.
|
|
23
|
+
*
|
|
24
|
+
* @param viewSchema - Schema for the view
|
|
25
|
+
* @param stored - The stored schema to check compatibility against
|
|
26
|
+
* @param stagedSchemaUpgrades - Staged schema upgrades enabled for this view, or explicit stored-schema generation options
|
|
24
27
|
*/
|
|
25
28
|
export function checkSchemaCompatibility(
|
|
26
29
|
viewSchema: TreeSchema,
|
|
27
30
|
stored: TreeStoredSchema,
|
|
31
|
+
stagedSchemaUpgrades?: Iterable<SchemaUpgrade> | StagedSchemaUpgradePolicy,
|
|
28
32
|
): Omit<SchemaCompatibilityStatus, "canInitialize"> {
|
|
29
33
|
// The public API surface assumes defaultSchemaPolicy
|
|
30
34
|
const policy = defaultSchemaPolicy;
|
|
@@ -40,7 +44,7 @@ export function checkSchemaCompatibility(
|
|
|
40
44
|
break;
|
|
41
45
|
}
|
|
42
46
|
|
|
43
|
-
const wouldUpgradeTo = toUpgradeSchema(viewSchema.root);
|
|
47
|
+
const wouldUpgradeTo = toUpgradeSchema(viewSchema.root, stagedSchemaUpgrades);
|
|
44
48
|
|
|
45
49
|
const canUpgrade = allowsRepoSuperset(policy, stored, wouldUpgradeTo);
|
|
46
50
|
|
|
@@ -444,7 +444,7 @@ export interface TreeView<in out TSchema extends ImplicitFieldSchema> extends ID
|
|
|
444
444
|
/**
|
|
445
445
|
* Description of the current compatibility status between the view schema and stored schema.
|
|
446
446
|
* @remarks
|
|
447
|
-
* {@link TreeViewEvents.schemaChanged} is fired when the compatibility status changes.
|
|
447
|
+
* {@link TreeViewEvents.schemaChanged} is fired when the compatibility status of the document's stored schema changes.
|
|
448
448
|
* See {@link https://fluidframework.com/docs/data-structures/tree/schema-evolution/ | schema-evolution} for more guidance on how to change schema while maintaining compatibility.
|
|
449
449
|
* Use {@link snapshotSchemaCompatibility} to write tests to validate that this compatibility behaves as desired across schema changes.
|
|
450
450
|
*/
|
|
@@ -459,6 +459,44 @@ export interface TreeView<in out TSchema extends ImplicitFieldSchema> extends ID
|
|
|
459
459
|
*
|
|
460
460
|
* It is an error to call this when {@link SchemaCompatibilityStatus.canUpgrade} is false.
|
|
461
461
|
* {@link SchemaCompatibilityStatus.canUpgrade} being true does not mean that an upgrade is required, nor that an upgrade will have any effect.
|
|
462
|
+
*
|
|
463
|
+
* When using {@link TreeViewConfigurationAlpha} with a {@link ITreeViewConfigurationAlpha.stagedUpgradePolicy},
|
|
464
|
+
* staged schema upgrades matching the configured policy are included in the target stored schema.
|
|
465
|
+
* Once a staged schema upgrade has been enabled in a document's stored schema, loading that document
|
|
466
|
+
* with a view that does not include equivalent staged members in its construction-time policy will cause
|
|
467
|
+
* `upgradeSchema` to throw a `UsageError` because the requested target would narrow the stored schema.
|
|
468
|
+
*
|
|
469
|
+
* @example Enabling a staged allowed type for documents, selected by a feature flag
|
|
470
|
+
*
|
|
471
|
+
* ```typescript
|
|
472
|
+
* const sf = new SchemaFactoryBeta("my-app");
|
|
473
|
+
*
|
|
474
|
+
* class TaskItem extends sf.object("TaskItem", { title: sf.string }) {}
|
|
475
|
+
* class ChecklistItem extends sf.object("ChecklistItem", { text: sf.string }) {}
|
|
476
|
+
*
|
|
477
|
+
* // `staged` wraps ChecklistItem so it can be enabled at runtime.
|
|
478
|
+
* const stagedChecklist = SchemaFactoryBeta.staged(ChecklistItem);
|
|
479
|
+
* const checklistUpgrade = stagedChecklist.metadata.stagedSchemaUpgrade;
|
|
480
|
+
*
|
|
481
|
+
* class AppSchema extends sf.object("AppSchema", {
|
|
482
|
+
* items: sf.array([TaskItem, stagedChecklist]),
|
|
483
|
+
* }) {}
|
|
484
|
+
*
|
|
485
|
+
* // Feature flag controls whether the upgrade is enabled for this session.
|
|
486
|
+
* const policy = featureFlags.enableChecklist
|
|
487
|
+
* ? StagedSchemaUpgradePolicy.enabledStagedUpgrades(checklistUpgrade)
|
|
488
|
+
* : undefined;
|
|
489
|
+
*
|
|
490
|
+
* const view = tree.viewWith(
|
|
491
|
+
* new TreeViewConfigurationAlpha({ schema: AppSchema, stagedUpgradePolicy: policy }),
|
|
492
|
+
* );
|
|
493
|
+
*
|
|
494
|
+
* if (view.compatibility.canUpgrade) {
|
|
495
|
+
* // Writes the staged type into the document's stored schema.
|
|
496
|
+
* view.upgradeSchema();
|
|
497
|
+
* }
|
|
498
|
+
* ```
|
|
499
|
+
*
|
|
462
500
|
* @privateRemarks
|
|
463
501
|
* In the future, more upgrade options could be provided here.
|
|
464
502
|
* Some options that could be added:
|
|
@@ -476,8 +514,12 @@ export interface TreeView<in out TSchema extends ImplicitFieldSchema> extends ID
|
|
|
476
514
|
/**
|
|
477
515
|
* Initialize the tree, setting the stored schema to match this view's schema and setting the tree content.
|
|
478
516
|
*
|
|
517
|
+
* @remarks
|
|
479
518
|
* Only valid to call when this view's {@link SchemaCompatibilityStatus.canInitialize} is true.
|
|
480
519
|
*
|
|
520
|
+
* When using {@link TreeViewConfigurationAlpha} with a {@link ITreeViewConfigurationAlpha.stagedUpgradePolicy},
|
|
521
|
+
* staged schema upgrades matching the configured policy are included in the initial stored schema.
|
|
522
|
+
*
|
|
481
523
|
* Applications should typically call this function before attaching a `SharedTree`.
|
|
482
524
|
* @param content - The content to initialize the tree with.
|
|
483
525
|
*/
|
|
@@ -585,6 +627,21 @@ export interface TreeViewAlpha<
|
|
|
585
627
|
|
|
586
628
|
set root(newRoot: InsertableField<TSchema>);
|
|
587
629
|
|
|
630
|
+
/**
|
|
631
|
+
* Initialize the tree, setting the stored schema to match this view's schema and setting the tree content.
|
|
632
|
+
*
|
|
633
|
+
* @remarks
|
|
634
|
+
* Only valid to call when this view's {@link SchemaCompatibilityStatus.canInitialize} is true.
|
|
635
|
+
*
|
|
636
|
+
* Enables staged schema upgrades declared by {@link ITreeViewConfigurationAlpha.stagedUpgradePolicy} when generating the initial stored schema.
|
|
637
|
+
* Once a staged schema upgrade has been enabled in a document's stored schema, loading that document
|
|
638
|
+
* with a view that does not include equivalent staged members in its construction-time policy will cause
|
|
639
|
+
* a subsequent `upgradeSchema` call to throw a `UsageError` because the stored schema already contains
|
|
640
|
+
* the upgraded members and the new target would narrow it.
|
|
641
|
+
*
|
|
642
|
+
* Applications should typically call this function before attaching a `SharedTree`.
|
|
643
|
+
* @param content - The content to initialize the tree with.
|
|
644
|
+
*/
|
|
588
645
|
initialize(content: InsertableField<TSchema>): void;
|
|
589
646
|
|
|
590
647
|
readonly events: Listenable<TreeViewEvents & TreeBranchEvents>;
|
|
@@ -115,7 +115,8 @@ export {
|
|
|
115
115
|
export type { SimpleNodeSchemaBase } from "./simpleNodeSchemaBase.js";
|
|
116
116
|
export {
|
|
117
117
|
type StoredSchemaGenerationOptions,
|
|
118
|
-
|
|
118
|
+
StagedSchemaUpgradePolicy,
|
|
119
|
+
type StagedSchemaUpgradePolicyFactory,
|
|
119
120
|
ExpectStored,
|
|
120
121
|
type SimpleSchemaTransformationOptions,
|
|
121
122
|
Unchanged,
|
|
@@ -6,18 +6,20 @@
|
|
|
6
6
|
import type { SchemaUpgrade } from "./allowedTypes.js";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* Policy controlling which staged schema upgrades are included when generating stored schema from a view schema.
|
|
10
|
+
* @input
|
|
11
|
+
* @alpha
|
|
10
12
|
*/
|
|
11
|
-
export interface
|
|
13
|
+
export interface StagedSchemaUpgradePolicy {
|
|
12
14
|
/**
|
|
13
|
-
* Determines whether to include
|
|
15
|
+
* Determines whether to include staged allowed types in the resulting stored schema.
|
|
14
16
|
* @remarks
|
|
15
17
|
* Due to caching, the behavior of this function must be pure.
|
|
16
18
|
*/
|
|
17
19
|
includeStaged(upgrade: SchemaUpgrade): boolean;
|
|
18
20
|
|
|
19
21
|
/**
|
|
20
|
-
* Determines whether to treat a
|
|
22
|
+
* Determines whether to treat a staged optional field as optional
|
|
21
23
|
* (rather than required) in the resulting stored schema.
|
|
22
24
|
* @remarks
|
|
23
25
|
* Due to caching, the behavior of this function must be pure.
|
|
@@ -25,6 +27,93 @@ export interface StoredFromViewSchemaGenerationOptions {
|
|
|
25
27
|
includeStagedOptional(upgrade: SchemaUpgrade): boolean;
|
|
26
28
|
}
|
|
27
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Provides factory methods for creating {@link (StagedSchemaUpgradePolicy:interface)} instances.
|
|
32
|
+
*
|
|
33
|
+
* @remarks
|
|
34
|
+
* Use the properties and methods on this object to obtain staged-schema generation options
|
|
35
|
+
* for different scenarios:
|
|
36
|
+
*
|
|
37
|
+
* - {@link StagedSchemaUpgradePolicyFactory.restrictive} — no staged upgrades (default)
|
|
38
|
+
*
|
|
39
|
+
* - {@link StagedSchemaUpgradePolicyFactory.permissive} — all staged upgrades enabled
|
|
40
|
+
*
|
|
41
|
+
* - {@link StagedSchemaUpgradePolicyFactory.enabledStagedUpgrades} — only specific upgrades enabled
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```typescript
|
|
45
|
+
* // Enable specific upgrades:
|
|
46
|
+
* const options = StagedSchemaUpgradePolicy.enabledStagedUpgrades(myUpgrade);
|
|
47
|
+
*
|
|
48
|
+
* // Use restrictive (default, no staged upgrades):
|
|
49
|
+
* const options = StagedSchemaUpgradePolicy.restrictive;
|
|
50
|
+
*
|
|
51
|
+
* // Use permissive (all staged upgrades, useful for testing):
|
|
52
|
+
* const options = StagedSchemaUpgradePolicy.permissive;
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* @sealed
|
|
56
|
+
* @alpha
|
|
57
|
+
*/
|
|
58
|
+
export interface StagedSchemaUpgradePolicyFactory {
|
|
59
|
+
/**
|
|
60
|
+
* Restrictive policy — excludes all staged schema members.
|
|
61
|
+
*
|
|
62
|
+
* @remarks
|
|
63
|
+
* Use this when you want the most conservative stored schema for compatibility-sensitive
|
|
64
|
+
* scenarios, or when staged schema upgrades should remain disabled.
|
|
65
|
+
*
|
|
66
|
+
* This is the default behavior when no staged upgrades are enabled.
|
|
67
|
+
*/
|
|
68
|
+
readonly restrictive: StagedSchemaUpgradePolicy;
|
|
69
|
+
/**
|
|
70
|
+
* Permissive policy — includes all staged schema upgrades.
|
|
71
|
+
*
|
|
72
|
+
* @remarks
|
|
73
|
+
* Use this for testing, validation, and rollout rehearsal scenarios where you want to exercise
|
|
74
|
+
* future document shapes before enabling staged upgrades broadly.
|
|
75
|
+
*/
|
|
76
|
+
readonly permissive: StagedSchemaUpgradePolicy;
|
|
77
|
+
/**
|
|
78
|
+
* Creates options that include only the specified staged schema upgrades.
|
|
79
|
+
*
|
|
80
|
+
* @param upgrades - The staged schema upgrades to enable.
|
|
81
|
+
* @returns Options that include only the specified upgrades.
|
|
82
|
+
*
|
|
83
|
+
* @remarks
|
|
84
|
+
* If an empty set of upgrades is passed, the result is equivalent to
|
|
85
|
+
* `StagedSchemaUpgradePolicy.restrictive`.
|
|
86
|
+
*/
|
|
87
|
+
enabledStagedUpgrades(...upgrades: SchemaUpgrade[]): StagedSchemaUpgradePolicy;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* {@inheritDoc (StagedSchemaUpgradePolicyFactory:interface)}
|
|
92
|
+
* @alpha
|
|
93
|
+
*/
|
|
94
|
+
export const StagedSchemaUpgradePolicy: StagedSchemaUpgradePolicyFactory = {
|
|
95
|
+
restrictive: {
|
|
96
|
+
includeStaged: () => false,
|
|
97
|
+
includeStagedOptional: () => false,
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
permissive: {
|
|
101
|
+
includeStaged: () => true,
|
|
102
|
+
includeStagedOptional: () => true,
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
enabledStagedUpgrades(...upgrades: SchemaUpgrade[]): StagedSchemaUpgradePolicy {
|
|
106
|
+
if (upgrades.length === 0) {
|
|
107
|
+
return StagedSchemaUpgradePolicy.restrictive;
|
|
108
|
+
}
|
|
109
|
+
const enabledUpgradeSet = new Set(upgrades);
|
|
110
|
+
return {
|
|
111
|
+
includeStaged: (upgrade) => enabledUpgradeSet.has(upgrade),
|
|
112
|
+
includeStagedOptional: (upgrade) => enabledUpgradeSet.has(upgrade),
|
|
113
|
+
};
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
|
|
28
117
|
/**
|
|
29
118
|
* Marker type indicating that the input schema is already a stored schema.
|
|
30
119
|
*/
|
|
@@ -42,9 +131,7 @@ export type Unchanged = typeof Unchanged;
|
|
|
42
131
|
/**
|
|
43
132
|
* Subset of {@link SimpleSchemaTransformationOptions} for when the output is a known to be a stored schema.
|
|
44
133
|
*/
|
|
45
|
-
export type StoredSchemaGenerationOptions =
|
|
46
|
-
| StoredFromViewSchemaGenerationOptions
|
|
47
|
-
| ExpectStored;
|
|
134
|
+
export type StoredSchemaGenerationOptions = StagedSchemaUpgradePolicy | ExpectStored;
|
|
48
135
|
|
|
49
136
|
/**
|
|
50
137
|
* Options for transforming a schema.
|
|
@@ -54,6 +141,6 @@ export type StoredSchemaGenerationOptions =
|
|
|
54
141
|
* we will need to add a "ToView" option here.
|
|
55
142
|
*/
|
|
56
143
|
export type SimpleSchemaTransformationOptions =
|
|
57
|
-
|
|
|
144
|
+
| StagedSchemaUpgradePolicy
|
|
58
145
|
| ExpectStored
|
|
59
146
|
| Unchanged;
|
package/src/simple-tree/index.ts
CHANGED
|
@@ -59,6 +59,8 @@ export {
|
|
|
59
59
|
type AllowedTypesFullFromMixed,
|
|
60
60
|
AnnotatedAllowedTypesInternal,
|
|
61
61
|
type NumberKeys,
|
|
62
|
+
StagedSchemaUpgradePolicy,
|
|
63
|
+
type StagedSchemaUpgradePolicyFactory,
|
|
62
64
|
ExpectStored,
|
|
63
65
|
createSchemaUpgrade,
|
|
64
66
|
} from "./core/index.js";
|
|
@@ -72,6 +74,7 @@ export {
|
|
|
72
74
|
TreeViewConfiguration,
|
|
73
75
|
TreeViewConfigurationAlpha,
|
|
74
76
|
type ITreeViewConfiguration,
|
|
77
|
+
type ITreeViewConfigurationAlpha,
|
|
75
78
|
type SchemaCompatibilityStatus,
|
|
76
79
|
type ITreeConfigurationOptions,
|
|
77
80
|
SchemaFactory,
|
|
@@ -317,8 +320,6 @@ export {
|
|
|
317
320
|
toUpgradeSchema,
|
|
318
321
|
toInitialSchema,
|
|
319
322
|
toUnhydratedSchema,
|
|
320
|
-
restrictiveStoredSchemaGenerationOptions,
|
|
321
|
-
permissiveStoredSchemaGenerationOptions,
|
|
322
323
|
} from "./toStoredSchema.js";
|
|
323
324
|
export {
|
|
324
325
|
numberSchema,
|
|
@@ -155,6 +155,18 @@ function validateAndPrepare(
|
|
|
155
155
|
mapTrees: readonly UnhydratedFlexTreeNode[],
|
|
156
156
|
scheduleHydrationOverride?: HydrationScheduler,
|
|
157
157
|
): void {
|
|
158
|
+
// Detecting duplicates here is the lowest level spot which is the same for hydrated and un-hydrated parents,
|
|
159
|
+
// and is also responsible for other validation, so it seem like the best layer to do this check.
|
|
160
|
+
const seenRoots = new Set<UnhydratedFlexTreeNode>();
|
|
161
|
+
for (const node of mapTrees) {
|
|
162
|
+
if (seenRoots.has(node)) {
|
|
163
|
+
throw new UsageError(
|
|
164
|
+
`A ${JSON.stringify(node.type)} node was provided more than once in a single insertion. A node may not be in more than one place in the tree.`,
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
seenRoots.add(node);
|
|
168
|
+
}
|
|
169
|
+
|
|
158
170
|
if (hydratedData !== undefined) {
|
|
159
171
|
// Run `prepareContentForHydration` before walking the tree in `isFieldInSchema`.
|
|
160
172
|
// This ensures that when `isFieldInSchema` requests identifiers (or any other contextual defaults),
|
|
@@ -37,9 +37,9 @@ import {
|
|
|
37
37
|
ExpectStored,
|
|
38
38
|
NodeKind,
|
|
39
39
|
SchemaUpgrade,
|
|
40
|
+
StagedSchemaUpgradePolicy,
|
|
40
41
|
Unchanged,
|
|
41
42
|
type SimpleSchemaTransformationOptions,
|
|
42
|
-
type StoredFromViewSchemaGenerationOptions,
|
|
43
43
|
type StoredSchemaGenerationOptions,
|
|
44
44
|
} from "./core/index.js";
|
|
45
45
|
import { FieldKind, normalizeFieldSchema, type ImplicitFieldSchema } from "./fieldSchema.js";
|
|
@@ -64,63 +64,68 @@ import { createTreeSchema } from "./treeSchema.js";
|
|
|
64
64
|
// The simple-schema related logic from this file and src/simple-tree/core/toStored.ts can be unified and `toStoredSchema` and its other ImplicitFieldSchema consuming variants should probably be removed in favor of acting on TreeSchema and SimpleTreeSchema directly.
|
|
65
65
|
|
|
66
66
|
const viewToStoredCache = new WeakMap<
|
|
67
|
-
|
|
67
|
+
StagedSchemaUpgradePolicy,
|
|
68
68
|
WeakMap<ImplicitFieldSchema, TreeStoredSchema>
|
|
69
69
|
>();
|
|
70
70
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
includeStagedOptional: () => false,
|
|
81
|
-
};
|
|
71
|
+
function isStagedSchemaUpgradePolicy(
|
|
72
|
+
stagedSchemaUpgrades: Iterable<SchemaUpgrade> | StagedSchemaUpgradePolicy,
|
|
73
|
+
): stagedSchemaUpgrades is StagedSchemaUpgradePolicy {
|
|
74
|
+
return (
|
|
75
|
+
typeof stagedSchemaUpgrades === "object" &&
|
|
76
|
+
"includeStaged" in stagedSchemaUpgrades &&
|
|
77
|
+
"includeStagedOptional" in stagedSchemaUpgrades
|
|
78
|
+
);
|
|
79
|
+
}
|
|
82
80
|
|
|
83
81
|
/**
|
|
84
|
-
*
|
|
82
|
+
* Resolves a collection of staged schema upgrades into stored-schema generation options.
|
|
85
83
|
* @remarks
|
|
86
|
-
*
|
|
87
|
-
* This is typically used for cases where forwards compatibility with future versions of an application is required, like {@link toUnhydratedSchema}.
|
|
88
|
-
*
|
|
89
|
-
* This is unable to include unknown optional fields in the output, which makes it not truly maximally permissive.
|
|
90
|
-
*
|
|
91
|
-
* TODO: {@link StoredFromViewSchemaGenerationOptions} could be updated to allow a way to inject extra optional fields.
|
|
92
|
-
* If done, then this could take in an existing stored schema, and attempt to generate a valid superset.
|
|
93
|
-
* This could be useful to use as the schema for unhydrated content cloned from hydrated content.
|
|
84
|
+
* If `stagedSchemaUpgrades` is omitted, returns restrictive options.
|
|
94
85
|
*/
|
|
95
|
-
export
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
86
|
+
export function resolveStoredSchemaGenerationOptions(
|
|
87
|
+
stagedSchemaUpgrades?: Iterable<SchemaUpgrade> | StagedSchemaUpgradePolicy,
|
|
88
|
+
): StagedSchemaUpgradePolicy {
|
|
89
|
+
if (stagedSchemaUpgrades === undefined) {
|
|
90
|
+
return StagedSchemaUpgradePolicy.restrictive;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (isStagedSchemaUpgradePolicy(stagedSchemaUpgrades)) {
|
|
94
|
+
return stagedSchemaUpgrades;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return StagedSchemaUpgradePolicy.enabledStagedUpgrades(...stagedSchemaUpgrades);
|
|
98
|
+
}
|
|
99
99
|
|
|
100
100
|
/**
|
|
101
101
|
* Converts a {@link ImplicitFieldSchema} into a {@link TreeStoredSchema} for use in schema upgrades.
|
|
102
|
-
*
|
|
103
|
-
* TODO: once upgrades are more flexible, this should take in more options, including the old schema and specific upgrades to enable.
|
|
104
102
|
*/
|
|
105
|
-
export function toUpgradeSchema(
|
|
106
|
-
|
|
103
|
+
export function toUpgradeSchema(
|
|
104
|
+
root: ImplicitFieldSchema,
|
|
105
|
+
stagedSchemaUpgrades?: Iterable<SchemaUpgrade> | StagedSchemaUpgradePolicy,
|
|
106
|
+
): TreeStoredSchema {
|
|
107
|
+
return toStoredSchema(root, resolveStoredSchemaGenerationOptions(stagedSchemaUpgrades));
|
|
107
108
|
}
|
|
108
109
|
|
|
109
110
|
/**
|
|
110
111
|
* Converts a {@link ImplicitFieldSchema} into a {@link TreeStoredSchema} for use as initial document schema.
|
|
111
112
|
*/
|
|
112
|
-
export function toInitialSchema(
|
|
113
|
-
|
|
113
|
+
export function toInitialSchema(
|
|
114
|
+
root: ImplicitFieldSchema,
|
|
115
|
+
stagedSchemaUpgrades?: Iterable<SchemaUpgrade> | StagedSchemaUpgradePolicy,
|
|
116
|
+
): TreeStoredSchema {
|
|
117
|
+
return toStoredSchema(root, resolveStoredSchemaGenerationOptions(stagedSchemaUpgrades));
|
|
114
118
|
}
|
|
115
119
|
|
|
116
120
|
/**
|
|
117
|
-
*
|
|
121
|
+
* Permissive staged schema upgrade policy used for unhydrated node schema generation.
|
|
118
122
|
* @remarks
|
|
119
123
|
* This allows as much as possible, relying on further validation when inserting the content.
|
|
120
124
|
*
|
|
121
125
|
* TODO: this should get additional options to enable support for unknown optional fields.
|
|
122
126
|
*/
|
|
123
|
-
export const toUnhydratedSchema =
|
|
127
|
+
export const toUnhydratedSchema: StagedSchemaUpgradePolicy =
|
|
128
|
+
StagedSchemaUpgradePolicy.permissive;
|
|
124
129
|
|
|
125
130
|
/**
|
|
126
131
|
* Converts a {@link ImplicitFieldSchema} into a {@link TreeStoredSchema}.
|
|
@@ -137,7 +142,7 @@ export const toUnhydratedSchema = permissiveStoredSchemaGenerationOptions;
|
|
|
137
142
|
*/
|
|
138
143
|
export function toStoredSchema(
|
|
139
144
|
root: ImplicitFieldSchema,
|
|
140
|
-
options:
|
|
145
|
+
options: StagedSchemaUpgradePolicy,
|
|
141
146
|
): TreeStoredSchema {
|
|
142
147
|
const cache = getOrCreate(viewToStoredCache, options, () => new WeakMap());
|
|
143
148
|
return getOrCreate(cache, root, () => {
|
|
@@ -152,7 +157,7 @@ export function toStoredSchema(
|
|
|
152
157
|
*/
|
|
153
158
|
export function transformSimpleSchema(
|
|
154
159
|
schema: SimpleTreeSchema<SchemaType.View>,
|
|
155
|
-
options:
|
|
160
|
+
options: StagedSchemaUpgradePolicy,
|
|
156
161
|
): SimpleTreeSchema<SchemaType.Stored>;
|
|
157
162
|
|
|
158
163
|
/**
|
|
@@ -324,7 +329,7 @@ export function getStoredSchema(
|
|
|
324
329
|
*/
|
|
325
330
|
export function transformSimpleNodeSchema(
|
|
326
331
|
schema: SimpleNodeSchema<SchemaType.View>,
|
|
327
|
-
options:
|
|
332
|
+
options: StagedSchemaUpgradePolicy,
|
|
328
333
|
): SimpleNodeSchema<SchemaType.Stored>;
|
|
329
334
|
|
|
330
335
|
/**
|
|
@@ -483,7 +488,7 @@ function allowedTypeFilter(
|
|
|
483
488
|
if (options === ExpectStored) {
|
|
484
489
|
if (data.isStaged !== undefined) {
|
|
485
490
|
throw new UsageError(
|
|
486
|
-
"Failed to covert view schema to stored schema. The simple schema provided was indicated to be a stored schema by the use of `ExpectStored`, but view schema specific content was encountered which requires a `
|
|
491
|
+
"Failed to covert view schema to stored schema. The simple schema provided was indicated to be a stored schema by the use of `ExpectStored`, but view schema specific content was encountered which requires a `StagedSchemaUpgradePolicy` to process.",
|
|
487
492
|
);
|
|
488
493
|
}
|
|
489
494
|
return true;
|
|
@@ -505,7 +510,7 @@ function allowedTypeFilter(
|
|
|
505
510
|
|
|
506
511
|
function isStoredFromView(
|
|
507
512
|
options: SimpleSchemaTransformationOptions,
|
|
508
|
-
): options is
|
|
513
|
+
): options is StagedSchemaUpgradePolicy {
|
|
509
514
|
return typeof options === "object" && "includeStaged" in options;
|
|
510
515
|
}
|
|
511
516
|
|