@fluidframework/tree 2.4.0-299374 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/settings.json +1 -9
- package/CHANGELOG.md +192 -0
- package/api-report/tree.alpha.api.md +23 -79
- package/api-report/tree.beta.api.md +23 -47
- package/api-report/tree.legacy.alpha.api.md +21 -46
- package/api-report/tree.legacy.public.api.md +21 -46
- package/api-report/tree.public.api.md +21 -46
- package/dist/alpha.d.ts +0 -9
- package/dist/beta.d.ts +0 -2
- package/dist/feature-libraries/flex-tree/lazyField.js +1 -1
- package/dist/feature-libraries/flex-tree/lazyField.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js +3 -3
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/internalTypes.d.ts +1 -1
- package/dist/internalTypes.d.ts.map +1 -1
- package/dist/internalTypes.js.map +1 -1
- package/dist/legacy.d.ts +0 -2
- 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/public.d.ts +0 -2
- package/dist/shared-tree/schematizingTreeView.js +1 -1
- package/dist/shared-tree/schematizingTreeView.js.map +1 -1
- package/dist/shared-tree/sharedTree.js +1 -1
- package/dist/shared-tree/sharedTree.js.map +1 -1
- package/dist/shared-tree/treeApi.d.ts +6 -6
- package/dist/shared-tree/treeApi.d.ts.map +1 -1
- package/dist/shared-tree/treeApi.js.map +1 -1
- package/dist/shared-tree-core/branch.js +1 -1
- package/dist/shared-tree-core/branch.js.map +1 -1
- package/dist/simple-tree/api/customTree.js +5 -5
- package/dist/simple-tree/api/customTree.js.map +1 -1
- package/dist/simple-tree/api/index.d.ts +2 -2
- 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/tree.d.ts +3 -12
- 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/api/treeApiBeta.d.ts +14 -2
- package/dist/simple-tree/api/treeApiBeta.d.ts.map +1 -1
- package/dist/simple-tree/api/treeApiBeta.js +23 -8
- package/dist/simple-tree/api/treeApiBeta.js.map +1 -1
- package/dist/simple-tree/api/typesUnsafe.d.ts +9 -48
- package/dist/simple-tree/api/typesUnsafe.d.ts.map +1 -1
- package/dist/simple-tree/api/typesUnsafe.js.map +1 -1
- package/dist/simple-tree/arrayNode.d.ts +3 -14
- package/dist/simple-tree/arrayNode.d.ts.map +1 -1
- package/dist/simple-tree/arrayNode.js.map +1 -1
- package/dist/simple-tree/core/schemaCaching.js +1 -1
- package/dist/simple-tree/core/schemaCaching.js.map +1 -1
- package/dist/simple-tree/core/treeNodeKernel.d.ts +6 -1
- package/dist/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
- package/dist/simple-tree/core/treeNodeKernel.js +7 -1
- package/dist/simple-tree/core/treeNodeKernel.js.map +1 -1
- package/dist/simple-tree/core/treeNodeSchema.d.ts +5 -6
- package/dist/simple-tree/core/treeNodeSchema.d.ts.map +1 -1
- package/dist/simple-tree/core/treeNodeSchema.js.map +1 -1
- package/dist/simple-tree/core/unhydratedFlexTree.js +1 -1
- package/dist/simple-tree/core/unhydratedFlexTree.js.map +1 -1
- package/dist/simple-tree/core/withType.d.ts +1 -3
- package/dist/simple-tree/core/withType.d.ts.map +1 -1
- package/dist/simple-tree/core/withType.js.map +1 -1
- package/dist/simple-tree/index.d.ts +4 -4
- package/dist/simple-tree/index.d.ts.map +1 -1
- package/dist/simple-tree/index.js.map +1 -1
- package/dist/simple-tree/schemaTypes.d.ts +6 -58
- package/dist/simple-tree/schemaTypes.d.ts.map +1 -1
- package/dist/simple-tree/schemaTypes.js +1 -6
- package/dist/simple-tree/schemaTypes.js.map +1 -1
- package/dist/simple-tree/toFlexSchema.js +2 -2
- package/dist/simple-tree/toFlexSchema.js.map +1 -1
- package/dist/simple-tree/toMapTree.d.ts +2 -4
- package/dist/simple-tree/toMapTree.d.ts.map +1 -1
- package/dist/simple-tree/toMapTree.js.map +1 -1
- package/lib/alpha.d.ts +0 -9
- package/lib/beta.d.ts +0 -2
- package/lib/feature-libraries/flex-tree/lazyField.js +1 -1
- package/lib/feature-libraries/flex-tree/lazyField.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js +3 -3
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/internalTypes.d.ts +1 -1
- package/lib/internalTypes.d.ts.map +1 -1
- package/lib/internalTypes.js.map +1 -1
- package/lib/legacy.d.ts +0 -2
- 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/public.d.ts +0 -2
- package/lib/shared-tree/schematizingTreeView.js +1 -1
- package/lib/shared-tree/schematizingTreeView.js.map +1 -1
- package/lib/shared-tree/sharedTree.js +1 -1
- package/lib/shared-tree/sharedTree.js.map +1 -1
- package/lib/shared-tree/treeApi.d.ts +6 -6
- package/lib/shared-tree/treeApi.d.ts.map +1 -1
- package/lib/shared-tree/treeApi.js.map +1 -1
- package/lib/shared-tree-core/branch.js +1 -1
- package/lib/shared-tree-core/branch.js.map +1 -1
- package/lib/simple-tree/api/customTree.js +5 -5
- package/lib/simple-tree/api/customTree.js.map +1 -1
- package/lib/simple-tree/api/index.d.ts +2 -2
- 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/tree.d.ts +3 -12
- 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/api/treeApiBeta.d.ts +14 -2
- package/lib/simple-tree/api/treeApiBeta.d.ts.map +1 -1
- package/lib/simple-tree/api/treeApiBeta.js +23 -8
- package/lib/simple-tree/api/treeApiBeta.js.map +1 -1
- package/lib/simple-tree/api/typesUnsafe.d.ts +9 -48
- package/lib/simple-tree/api/typesUnsafe.d.ts.map +1 -1
- package/lib/simple-tree/api/typesUnsafe.js.map +1 -1
- package/lib/simple-tree/arrayNode.d.ts +3 -14
- package/lib/simple-tree/arrayNode.d.ts.map +1 -1
- package/lib/simple-tree/arrayNode.js.map +1 -1
- package/lib/simple-tree/core/schemaCaching.js +1 -1
- package/lib/simple-tree/core/schemaCaching.js.map +1 -1
- package/lib/simple-tree/core/treeNodeKernel.d.ts +6 -1
- package/lib/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
- package/lib/simple-tree/core/treeNodeKernel.js +7 -1
- package/lib/simple-tree/core/treeNodeKernel.js.map +1 -1
- package/lib/simple-tree/core/treeNodeSchema.d.ts +5 -6
- package/lib/simple-tree/core/treeNodeSchema.d.ts.map +1 -1
- package/lib/simple-tree/core/treeNodeSchema.js.map +1 -1
- package/lib/simple-tree/core/unhydratedFlexTree.js +1 -1
- package/lib/simple-tree/core/unhydratedFlexTree.js.map +1 -1
- package/lib/simple-tree/core/withType.d.ts +1 -3
- package/lib/simple-tree/core/withType.d.ts.map +1 -1
- package/lib/simple-tree/core/withType.js.map +1 -1
- package/lib/simple-tree/index.d.ts +4 -4
- package/lib/simple-tree/index.d.ts.map +1 -1
- package/lib/simple-tree/index.js +1 -1
- package/lib/simple-tree/index.js.map +1 -1
- package/lib/simple-tree/schemaTypes.d.ts +6 -58
- package/lib/simple-tree/schemaTypes.d.ts.map +1 -1
- package/lib/simple-tree/schemaTypes.js +0 -5
- package/lib/simple-tree/schemaTypes.js.map +1 -1
- package/lib/simple-tree/toFlexSchema.js +2 -2
- package/lib/simple-tree/toFlexSchema.js.map +1 -1
- package/lib/simple-tree/toMapTree.d.ts +2 -4
- package/lib/simple-tree/toMapTree.d.ts.map +1 -1
- package/lib/simple-tree/toMapTree.js.map +1 -1
- package/package.json +23 -39
- package/src/feature-libraries/flex-tree/lazyField.ts +1 -1
- package/src/feature-libraries/modular-schema/modularChangeFamily.ts +9 -3
- package/src/index.ts +0 -9
- package/src/internalTypes.ts +0 -3
- package/src/packageVersion.ts +1 -1
- package/src/shared-tree/schematizingTreeView.ts +1 -1
- package/src/shared-tree/sharedTree.ts +1 -1
- package/src/shared-tree/treeApi.ts +9 -19
- package/src/shared-tree-core/branch.ts +1 -1
- package/src/simple-tree/api/customTree.ts +5 -5
- package/src/simple-tree/api/index.ts +0 -5
- package/src/simple-tree/api/tree.ts +2 -24
- package/src/simple-tree/api/treeApiBeta.ts +65 -3
- package/src/simple-tree/api/typesUnsafe.ts +18 -82
- package/src/simple-tree/arrayNode.ts +14 -34
- package/src/simple-tree/core/schemaCaching.ts +1 -1
- package/src/simple-tree/core/treeNodeKernel.ts +10 -2
- package/src/simple-tree/core/treeNodeSchema.ts +5 -7
- package/src/simple-tree/core/unhydratedFlexTree.ts +1 -1
- package/src/simple-tree/core/withType.ts +1 -10
- package/src/simple-tree/index.ts +1 -15
- package/src/simple-tree/schemaTypes.ts +5 -68
- package/src/simple-tree/toFlexSchema.ts +2 -2
- package/src/simple-tree/toMapTree.ts +1 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schemaTypes.js","sourceRoot":"","sources":["../../src/simple-tree/schemaTypes.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 type { ErasedType, IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport { Lazy } from \"@fluidframework/core-utils/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport type { NodeKeyManager } from \"../feature-libraries/index.js\";\nimport { type MakeNominal, brand, isReadonlyArray } from \"../util/index.js\";\nimport type {\n\tUnhydrated,\n\tNodeKind,\n\tTreeNodeSchema,\n\tTreeNodeSchemaClass,\n\tTreeNode,\n} from \"./core/index.js\";\nimport type { FieldKey } from \"../core/index.js\";\nimport type { InsertableContent } from \"./toMapTree.js\";\nimport { isLazy, type FlexListToUnion, type LazyItem } from \"./flexList.js\";\n\n/**\n * Returns true if the given schema is a {@link TreeNodeSchemaClass}, or otherwise false if it is a {@link TreeNodeSchemaNonClass}.\n */\nexport function isTreeNodeSchemaClass<\n\tName extends string,\n\tKind extends NodeKind,\n\tTNode extends TreeNode | TreeLeafValue,\n\tTBuild,\n\tImplicitlyConstructable extends boolean,\n\tInfo,\n>(\n\tschema: TreeNodeSchema<Name, Kind, TNode, TBuild, ImplicitlyConstructable, Info>,\n): schema is TreeNodeSchemaClass<Name, Kind, TNode, TBuild, ImplicitlyConstructable, Info> {\n\treturn schema.constructor !== undefined;\n}\n\n/**\n * Types for use in fields.\n * @remarks\n * Type constraint used in schema declaration APIs.\n * Not intended for direct use outside of package.\n * @public\n */\nexport type AllowedTypes = readonly LazyItem<TreeNodeSchema>[];\n\n/**\n * Kind of a field on a node.\n * @remarks\n * More kinds may be added over time, so do not assume this is an exhaustive set.\n * @public\n */\nexport enum FieldKind {\n\t/**\n\t * A field which can be empty or filled.\n\t * @remarks\n\t * Allows 0 or one child.\n\t */\n\tOptional,\n\t/**\n\t * A field which must always be filled.\n\t * @remarks\n\t * Only allows exactly one child.\n\t */\n\tRequired,\n\t/**\n\t * A special field used for node identifiers.\n\t * @remarks\n\t * Only allows exactly one child.\n\t */\n\tIdentifier,\n}\n\n/**\n * Maps from a property key to its corresponding {@link FieldProps.key | stored key} for the provided\n * {@link ImplicitFieldSchema | field schema}.\n *\n * @remarks\n * If an explicit stored key was specified in the schema, it will be used.\n * Otherwise, the stored key is the same as the property key.\n */\nexport function getStoredKey(propertyKey: string, fieldSchema: ImplicitFieldSchema): FieldKey {\n\treturn brand(getExplicitStoredKey(fieldSchema) ?? propertyKey);\n}\n\n/**\n * Gets the {@link FieldProps.key | stored key} specified by the schema, if one was explicitly specified.\n * Otherwise, returns undefined.\n */\nexport function getExplicitStoredKey(fieldSchema: ImplicitFieldSchema): string | undefined {\n\treturn fieldSchema instanceof FieldSchema ? fieldSchema.props?.key : undefined;\n}\n\n/**\n * Additional information to provide to a {@link FieldSchema}.\n *\n * @typeParam TCustomMetadata - Custom metadata properties to associate with the field.\n * See {@link FieldSchemaMetadata.custom}.\n *\n * @public\n */\nexport interface FieldProps<TCustomMetadata = unknown> {\n\t/**\n\t * The unique identifier of a field, used in the persisted form of the tree.\n\t *\n\t * @remarks\n\t * If not explicitly set via the schema, this is the same as the schema's property key.\n\t *\n\t * Specifying a stored key that differs from the property key is particularly useful in refactoring scenarios.\n\t * To update the developer-facing API, while maintaining backwards compatibility with existing SharedTree data,\n\t * you can change the property key and specify the previous property key as the stored key.\n\t *\n\t * Notes:\n\t *\n\t * - Stored keys have no impact on standard JavaScript behavior, on tree nodes. For example, `Object.keys`\n\t * will always return the property keys specified in the schema, ignoring any stored keys that differ from\n\t * the property keys.\n\t *\n\t * - When specifying stored keys in an object schema, you must ensure that the final set of stored keys\n\t * (accounting for those implicitly derived from property keys) contains no duplicates.\n\t * This is validated at runtime.\n\t *\n\t * @example Refactoring code without breaking compatibility with existing data\n\t *\n\t * Consider some existing object schema:\n\t *\n\t * ```TypeScript\n\t * class Point extends schemaFactory.object(\"Point\", {\n\t * \txPosition: schemaFactory.number,\n\t * \tyPosition: schemaFactory.number,\n\t * \tzPosition: schemaFactory.optional(schemaFactory.number),\n\t * });\n\t * ```\n\t *\n\t * Developers using nodes of this type would access the the `xPosition` property as `point.xPosition`.\n\t *\n\t * We would like to refactor the schema to omit \"Position\" from the property keys, but application data has\n\t * already been persisted using the original property keys. To maintain compatibility with existing data,\n\t * we can refactor the schema as follows:\n\t *\n\t * ```TypeScript\n\t * class Point extends schemaFactory.object(\"Point\", {\n\t * \tx: schemaFactory.required(schemaFactory.number, { key: \"xPosition\" }),\n\t * \ty: schemaFactory.required(schemaFactory.number, { key: \"yPosition\" }),\n\t * \tz: schemaFactory.optional(schemaFactory.number, { key: \"zPosition\" }),\n\t * });\n\t * ```\n\t *\n\t * Now, developers can access the `x` property as `point.x`, while existing data can still be collaborated on.\n\t *\n\t * @defaultValue If not specified, the key that is persisted is the property key that was specified in the schema.\n\t */\n\treadonly key?: string;\n\n\t/**\n\t * A default provider used for fields which were not provided any values.\n\t * @privateRemarks\n\t * We are using an erased type here, as we want to expose this API but `InsertableContent` and `NodeKeyManager` are not public.\n\t */\n\treadonly defaultProvider?: DefaultProvider;\n\n\t/**\n\t * Optional metadata to associate with the field.\n\t * @remarks Note: this metadata is not persisted in the document.\n\t */\n\treadonly metadata?: FieldSchemaMetadata<TCustomMetadata>;\n}\n\n/**\n * A {@link FieldProvider} which requires additional context in order to produce its content\n */\nexport type ContextualFieldProvider = (\n\tcontext: NodeKeyManager,\n) => InsertableContent | undefined;\n/**\n * A {@link FieldProvider} which can produce its content in a vacuum\n */\nexport type ConstantFieldProvider = () => InsertableContent | undefined;\n/**\n * A function which produces content for a field every time that it is called\n */\nexport type FieldProvider = ContextualFieldProvider | ConstantFieldProvider;\n/**\n * Returns true if the given {@link FieldProvider} is a {@link ConstantFieldProvider}\n */\nexport function isConstant(\n\tfieldProvider: FieldProvider,\n): fieldProvider is ConstantFieldProvider {\n\treturn fieldProvider.length === 0;\n}\n\n/**\n * Provides a default value for a field.\n * @remarks\n * If present in a `FieldSchema`, when constructing new tree content that field can be omitted, and a default will be provided.\n * @system @sealed @public\n */\nexport interface DefaultProvider extends ErasedType<\"@fluidframework/tree.FieldProvider\"> {}\n\nexport function extractFieldProvider(input: DefaultProvider): FieldProvider {\n\treturn input as unknown as FieldProvider;\n}\n\nexport function getDefaultProvider(input: FieldProvider): DefaultProvider {\n\treturn input as unknown as DefaultProvider;\n}\n\n/**\n * Metadata associated with a {@link FieldSchema}.\n *\n * @remarks Specified via {@link FieldProps.metadata}.\n *\n * @sealed\n * @public\n */\nexport interface FieldSchemaMetadata<TCustomMetadata = unknown> {\n\t/**\n\t * User-defined metadata.\n\t */\n\treadonly custom?: TCustomMetadata;\n\n\t/**\n\t * The description of the field.\n\t *\n\t * @remarks\n\t *\n\t * If provided, will be used by the system in scenarios where a description of the field is useful.\n\t * E.g., when converting a field schema to {@link https://json-schema.org/ | JSON Schema}, this description will be\n\t * used as the `description` field.\n\t */\n\treadonly description?: string | undefined;\n}\n\n/**\n * Package internal construction API.\n */\nexport let createFieldSchema: <\n\tKind extends FieldKind = FieldKind,\n\tTypes extends ImplicitAllowedTypes = ImplicitAllowedTypes,\n\tTCustomMetadata = unknown,\n>(\n\tkind: Kind,\n\tallowedTypes: Types,\n\tprops?: FieldProps<TCustomMetadata>,\n) => FieldSchema<Kind, Types, TCustomMetadata>;\n\n/**\n * All policy for a specific field,\n * including functionality that does not have to be kept consistent across versions or deterministic.\n *\n * This can include policy for how to use this schema for \"view\" purposes, and well as how to expose editing APIs.\n * Use {@link SchemaFactory} to create the FieldSchema instances, for example {@link SchemaFactory.optional}.\n * @privateRemarks\n * Public access to the constructor is removed to prevent creating expressible but unsupported (or not stable) configurations.\n * {@link createFieldSchema} can be used internally to create instances.\n *\n * @typeParam TCustomMetadata - Custom metadata properties to associate with the field.\n * See {@link FieldSchemaMetadata.custom}.\n *\n * @sealed @public\n */\nexport class FieldSchema<\n\tout Kind extends FieldKind = FieldKind,\n\tout Types extends ImplicitAllowedTypes = ImplicitAllowedTypes,\n\tout TCustomMetadata = unknown,\n> {\n\tstatic {\n\t\tcreateFieldSchema = <\n\t\t\tKind2 extends FieldKind = FieldKind,\n\t\t\tTypes2 extends ImplicitAllowedTypes = ImplicitAllowedTypes,\n\t\t\tTCustomMetadata2 = unknown,\n\t\t>(\n\t\t\tkind: Kind2,\n\t\t\tallowedTypes: Types2,\n\t\t\tprops?: FieldProps<TCustomMetadata2>,\n\t\t) => new FieldSchema(kind, allowedTypes, props);\n\t}\n\t/**\n\t * This class is used with instanceof, and therefore should have nominal typing.\n\t * This field enforces that.\n\t */\n\tprotected _typeCheck!: MakeNominal;\n\n\tprivate readonly lazyTypes: Lazy<ReadonlySet<TreeNodeSchema>>;\n\n\t/**\n\t * What types of tree nodes are allowed in this field.\n\t * @remarks Counterpart to {@link FieldSchema.allowedTypes}, with any lazy definitions evaluated.\n\t */\n\tpublic get allowedTypeSet(): ReadonlySet<TreeNodeSchema> {\n\t\treturn this.lazyTypes.value;\n\t}\n\n\t/**\n\t * True if and only if, when constructing a node with this field, a value must be provided for it.\n\t */\n\tpublic readonly requiresValue: boolean;\n\n\t/**\n\t * {@inheritDoc FieldProps.metadata}\n\t */\n\tpublic get metadata(): FieldSchemaMetadata<TCustomMetadata> | undefined {\n\t\treturn this.props?.metadata;\n\t}\n\n\tprivate constructor(\n\t\t/**\n\t\t * The {@link https://en.wikipedia.org/wiki/Kind_(type_theory) | kind } of this field.\n\t\t * Determines the multiplicity, viewing and editing APIs as well as the merge resolution policy.\n\t\t */\n\t\tpublic readonly kind: Kind,\n\t\t/**\n\t\t * What types of tree nodes are allowed in this field.\n\t\t */\n\t\tpublic readonly allowedTypes: Types,\n\t\t/**\n\t\t * Optional properties associated with the field.\n\t\t */\n\t\tpublic readonly props?: FieldProps<TCustomMetadata>,\n\t) {\n\t\tthis.lazyTypes = new Lazy(() => normalizeAllowedTypes(this.allowedTypes));\n\t\t// TODO: optional fields should (by default) get a default provider that returns undefined, removing the need to special case them here:\n\t\tthis.requiresValue =\n\t\t\tthis.props?.defaultProvider === undefined && this.kind !== FieldKind.Optional;\n\t}\n}\n\n/**\n * Normalizes a {@link ImplicitFieldSchema} to a {@link FieldSchema}.\n */\nexport function normalizeFieldSchema(schema: ImplicitFieldSchema): FieldSchema {\n\treturn schema instanceof FieldSchema\n\t\t? schema\n\t\t: createFieldSchema(FieldKind.Required, schema);\n}\n/**\n * Normalizes a {@link ImplicitAllowedTypes} to a set of {@link TreeNodeSchema}s, by eagerly evaluating any\n * lazy schema declarations.\n *\n * @remarks Note: this must only be called after all required schemas have been declared, otherwise evaluation of\n * recursive schemas may fail.\n */\nexport function normalizeAllowedTypes(\n\ttypes: ImplicitAllowedTypes,\n): ReadonlySet<TreeNodeSchema> {\n\tconst normalized = new Set<TreeNodeSchema>();\n\tif (isReadonlyArray(types)) {\n\t\tfor (const lazyType of types) {\n\t\t\tnormalized.add(evaluateLazySchema(lazyType));\n\t\t}\n\t} else {\n\t\tnormalized.add(evaluateLazySchema(types));\n\t}\n\treturn normalized;\n}\n\nfunction evaluateLazySchema(value: LazyItem<TreeNodeSchema>): TreeNodeSchema {\n\tconst evaluatedSchema = isLazy(value) ? value() : value;\n\tif (evaluatedSchema === undefined) {\n\t\tthrow new UsageError(\n\t\t\t`Encountered an undefined schema. This could indicate that some referenced schema has not yet been instantiated.`,\n\t\t);\n\t}\n\treturn evaluatedSchema;\n}\n\n/**\n * Types allowed in a field.\n * @remarks\n * Implicitly treats a single type as an array of one type.\n * @public\n */\nexport type ImplicitAllowedTypes = AllowedTypes | TreeNodeSchema;\n\n/**\n * Schema for a field of a tree node.\n * @remarks\n * Implicitly treats {@link ImplicitAllowedTypes} as a Required field of that type.\n * @public\n */\nexport type ImplicitFieldSchema = FieldSchema | ImplicitAllowedTypes;\n\n/**\n * Converts an `ImplicitFieldSchema` to a property type suitable for reading a field with this that schema.\n *\n * @typeparam TSchema - When non-exact schema are provided this errors on the side of returning too general of a type (a conservative union of all possibilities).\n * This is ideal for \"output APIs\" - i.e. it converts the schema type to the runtime type that a user will _read_ from the tree.\n * Examples of such \"non-exact\" schema include `ImplicitFieldSchema`, `ImplicitAllowedTypes`, and TypeScript unions of schema types.\n * @privateRemarks\n * TODO:\n * There are two known problematic usages of this type (which produce invalid/unsound results when given non-specific schema):\n * 1. setters for fields (on object nodes the Tree.view.root).\n * 2. Indirectly in InsertableTreeFieldFromImplicitField via InsertableTypedNode including NodeFromSchema.\n * These cases should be mitigated by introducing a way to detect inexact schema and special casing them in these two places.\n * @public\n */\nexport type TreeFieldFromImplicitField<TSchema extends ImplicitFieldSchema = FieldSchema> =\n\tTSchema extends FieldSchema<infer Kind, infer Types>\n\t\t? ApplyKind<TreeNodeFromImplicitAllowedTypes<Types>, Kind, false>\n\t\t: TSchema extends ImplicitAllowedTypes\n\t\t\t? TreeNodeFromImplicitAllowedTypes<TSchema>\n\t\t\t: TreeNode | TreeLeafValue | undefined;\n\n/**\n * Type of content that can be inserted into the tree for a field of the given schema.\n * @public\n */\nexport type InsertableTreeFieldFromImplicitField<\n\tTSchema extends ImplicitFieldSchema = FieldSchema,\n> = TSchema extends FieldSchema<infer Kind, infer Types>\n\t? ApplyKind<InsertableTreeNodeFromImplicitAllowedTypes<Types>, Kind, true>\n\t: TSchema extends ImplicitAllowedTypes\n\t\t? InsertableTreeNodeFromImplicitAllowedTypes<TSchema>\n\t\t: never;\n\n/**\n * {@inheritdoc (UnsafeUnknownSchema:type)}\n * @alpha\n */\nexport const UnsafeUnknownSchema: unique symbol = Symbol(\"UnsafeUnknownSchema\");\n\n/**\n * A special type which can be provided to some APIs as the schema type parameter when schema cannot easily be provided at compile time and an unsafe (instead of disabled) editing API is desired.\n * @remarks\n * When used this means the TypeScript typing should error on the side of completeness (allow all inputs that could be valid).\n * This introduces the risk that out of schema data could be allowed at compile time, and only error at runtime.\n *\n * @privateRemarks\n * This only applies to APIs which input data which is expected to be in schema, since APIs outputting have easy mechanisms to do so in a type safe way even when the schema is unknown.\n * In most cases that amounts to returning `TreeNode | TreeLeafValue`.\n *\n * This can be contrasted with the default behavior of TypeScript, which is to require the intersection of the possible types for input APIs,\n * which for unknown schema defining input trees results in the `never` type.\n *\n * Any APIs which use this must produce UsageErrors when out of schema data is encountered, and never produce unrecoverable errors,\n * or silently accept invalid data.\n * This is currently only type exported from the package: the symbol is just used as a way to get a named type.\n * @alpha\n */\nexport type UnsafeUnknownSchema = typeof UnsafeUnknownSchema;\n\n/**\n * Content which could be inserted into a tree.\n * @remarks\n * Extended version of {@link InsertableTreeNodeFromImplicitAllowedTypes} that also allows {@link (UnsafeUnknownSchema:type)}.\n * @alpha\n */\nexport type Insertable<TSchema extends ImplicitAllowedTypes | UnsafeUnknownSchema> =\n\tTSchema extends ImplicitAllowedTypes\n\t\t? InsertableTreeNodeFromImplicitAllowedTypes<TSchema>\n\t\t: InsertableContent;\n\n/**\n * Content which could be inserted into a field within a tree.\n * @remarks\n * Extended version of {@link InsertableTreeFieldFromImplicitField} that also allows {@link (UnsafeUnknownSchema:type)}.\n * @alpha\n */\nexport type InsertableField<TSchema extends ImplicitFieldSchema | UnsafeUnknownSchema> =\n\tTSchema extends ImplicitFieldSchema\n\t\t? InsertableTreeFieldFromImplicitField<TSchema>\n\t\t: InsertableContent | undefined;\n\n/**\n * Suitable for output.\n * For input must error on side of excluding undefined instead.\n * @system @public\n */\nexport type ApplyKind<T, Kind extends FieldKind, DefaultsAreOptional extends boolean> = {\n\t[FieldKind.Required]: T;\n\t[FieldKind.Optional]: T | undefined;\n\t[FieldKind.Identifier]: DefaultsAreOptional extends true ? T | undefined : T;\n}[Kind];\n\n/**\n * Type of tree node for a field of the given schema.\n * @public\n */\nexport type TreeNodeFromImplicitAllowedTypes<\n\tTSchema extends ImplicitAllowedTypes = TreeNodeSchema,\n> = TSchema extends TreeNodeSchema\n\t? NodeFromSchema<TSchema>\n\t: TSchema extends AllowedTypes\n\t\t? NodeFromSchema<FlexListToUnion<TSchema>>\n\t\t: unknown;\n\n/**\n * Type of content that can be inserted into the tree for a node of the given schema.\n * @public\n */\nexport type InsertableTreeNodeFromImplicitAllowedTypes<\n\tTSchema extends ImplicitAllowedTypes = TreeNodeSchema,\n> = TSchema extends TreeNodeSchema\n\t? InsertableTypedNode<TSchema>\n\t: TSchema extends AllowedTypes\n\t\t? InsertableTypedNode<FlexListToUnion<TSchema>>\n\t\t: never;\n\n/**\n * Takes in `TreeNodeSchema[]` and returns a TypedNode union.\n * @public\n */\nexport type NodeFromSchema<T extends TreeNodeSchema> = T extends TreeNodeSchema<\n\tstring,\n\tNodeKind,\n\tinfer TNode\n>\n\t? TNode\n\t: never;\n\n/**\n * Data which can be used as a node to be inserted.\n * Either an unhydrated node, or content to build a new node.\n * @privateRemarks\n * TODO:\n * This should behave contravariantly, but it uses NodeFromSchema which behaves covariantly.\n * This results in unsoundness where when the schema is less specific, more types are allowed instead of less.\n * @public\n */\nexport type InsertableTypedNode<T extends TreeNodeSchema> =\n\t| (T extends { implicitlyConstructable: true } ? NodeBuilderData<T> : never)\n\t| Unhydrated<NodeFromSchema<T>>;\n\n/**\n * Given a node's schema, return the corresponding object from which the node could be built.\n * @privateRemarks\n * Currently this assumes factory functions take exactly one argument.\n * This could be changed if needed.\n *\n * These factory functions can also take a FlexTreeNode, but this is not exposed in the public facing types.\n * @system @public\n */\nexport type NodeBuilderData<T extends TreeNodeSchema> = T extends TreeNodeSchema<\n\tstring,\n\tNodeKind,\n\tTreeNode | TreeLeafValue,\n\tinfer TBuild\n>\n\t? TBuild\n\t: never;\n\n/**\n * Value that may be stored as a leaf node.\n * @remarks\n * Some limitations apply, see the documentation for {@link SchemaFactory.number} and {@link SchemaFactory.string} for those restrictions.\n * @public\n */\n// eslint-disable-next-line @rushstack/no-new-null\nexport type TreeLeafValue = number | string | boolean | IFluidHandle | null;\n"]}
|
|
1
|
+
{"version":3,"file":"schemaTypes.js","sourceRoot":"","sources":["../../src/simple-tree/schemaTypes.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 type { ErasedType, IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport { Lazy } from \"@fluidframework/core-utils/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport type { NodeKeyManager } from \"../feature-libraries/index.js\";\nimport { type MakeNominal, brand, isReadonlyArray } from \"../util/index.js\";\nimport type {\n\tUnhydrated,\n\tNodeKind,\n\tTreeNodeSchema,\n\tTreeNodeSchemaClass,\n} from \"./core/index.js\";\nimport type { FieldKey } from \"../core/index.js\";\nimport type { InsertableContent } from \"./toMapTree.js\";\nimport { isLazy, type FlexListToUnion, type LazyItem } from \"./flexList.js\";\n\n/**\n * Returns true if the given schema is a {@link TreeNodeSchemaClass}, or otherwise false if it is a {@link TreeNodeSchemaNonClass}.\n */\nexport function isTreeNodeSchemaClass<\n\tName extends string,\n\tKind extends NodeKind,\n\tTNode,\n\tTBuild,\n\tImplicitlyConstructable extends boolean,\n\tInfo,\n>(\n\tschema: TreeNodeSchema<Name, Kind, TNode, TBuild, ImplicitlyConstructable, Info>,\n): schema is TreeNodeSchemaClass<Name, Kind, TNode, TBuild, ImplicitlyConstructable, Info> {\n\treturn schema.constructor !== undefined;\n}\n\n/**\n * Types for use in fields.\n * @remarks\n * Type constraint used in schema declaration APIs.\n * Not intended for direct use outside of package.\n * @public\n */\nexport type AllowedTypes = readonly LazyItem<TreeNodeSchema>[];\n\n/**\n * Kind of a field on a node.\n * @remarks\n * More kinds may be added over time, so do not assume this is an exhaustive set.\n * @public\n */\nexport enum FieldKind {\n\t/**\n\t * A field which can be empty or filled.\n\t * @remarks\n\t * Allows 0 or one child.\n\t */\n\tOptional,\n\t/**\n\t * A field which must always be filled.\n\t * @remarks\n\t * Only allows exactly one child.\n\t */\n\tRequired,\n\t/**\n\t * A special field used for node identifiers.\n\t * @remarks\n\t * Only allows exactly one child.\n\t */\n\tIdentifier,\n}\n\n/**\n * Maps from a property key to its corresponding {@link FieldProps.key | stored key} for the provided\n * {@link ImplicitFieldSchema | field schema}.\n *\n * @remarks\n * If an explicit stored key was specified in the schema, it will be used.\n * Otherwise, the stored key is the same as the property key.\n */\nexport function getStoredKey(propertyKey: string, fieldSchema: ImplicitFieldSchema): FieldKey {\n\treturn brand(getExplicitStoredKey(fieldSchema) ?? propertyKey);\n}\n\n/**\n * Gets the {@link FieldProps.key | stored key} specified by the schema, if one was explicitly specified.\n * Otherwise, returns undefined.\n */\nexport function getExplicitStoredKey(fieldSchema: ImplicitFieldSchema): string | undefined {\n\treturn fieldSchema instanceof FieldSchema ? fieldSchema.props?.key : undefined;\n}\n\n/**\n * Additional information to provide to a {@link FieldSchema}.\n *\n * @typeParam TCustomMetadata - Custom metadata properties to associate with the field.\n * See {@link FieldSchemaMetadata.custom}.\n *\n * @public\n */\nexport interface FieldProps<TCustomMetadata = unknown> {\n\t/**\n\t * The unique identifier of a field, used in the persisted form of the tree.\n\t *\n\t * @remarks\n\t * If not explicitly set via the schema, this is the same as the schema's property key.\n\t *\n\t * Specifying a stored key that differs from the property key is particularly useful in refactoring scenarios.\n\t * To update the developer-facing API, while maintaining backwards compatibility with existing SharedTree data,\n\t * you can change the property key and specify the previous property key as the stored key.\n\t *\n\t * Notes:\n\t *\n\t * - Stored keys have no impact on standard JavaScript behavior, on tree nodes. For example, `Object.keys`\n\t * will always return the property keys specified in the schema, ignoring any stored keys that differ from\n\t * the property keys.\n\t *\n\t * - When specifying stored keys in an object schema, you must ensure that the final set of stored keys\n\t * (accounting for those implicitly derived from property keys) contains no duplicates.\n\t * This is validated at runtime.\n\t *\n\t * @example Refactoring code without breaking compatibility with existing data\n\t *\n\t * Consider some existing object schema:\n\t *\n\t * ```TypeScript\n\t * class Point extends schemaFactory.object(\"Point\", {\n\t * \txPosition: schemaFactory.number,\n\t * \tyPosition: schemaFactory.number,\n\t * \tzPosition: schemaFactory.optional(schemaFactory.number),\n\t * });\n\t * ```\n\t *\n\t * Developers using nodes of this type would access the the `xPosition` property as `point.xPosition`.\n\t *\n\t * We would like to refactor the schema to omit \"Position\" from the property keys, but application data has\n\t * already been persisted using the original property keys. To maintain compatibility with existing data,\n\t * we can refactor the schema as follows:\n\t *\n\t * ```TypeScript\n\t * class Point extends schemaFactory.object(\"Point\", {\n\t * \tx: schemaFactory.required(schemaFactory.number, { key: \"xPosition\" }),\n\t * \ty: schemaFactory.required(schemaFactory.number, { key: \"yPosition\" }),\n\t * \tz: schemaFactory.optional(schemaFactory.number, { key: \"zPosition\" }),\n\t * });\n\t * ```\n\t *\n\t * Now, developers can access the `x` property as `point.x`, while existing data can still be collaborated on.\n\t *\n\t * @defaultValue If not specified, the key that is persisted is the property key that was specified in the schema.\n\t */\n\treadonly key?: string;\n\n\t/**\n\t * A default provider used for fields which were not provided any values.\n\t * @privateRemarks\n\t * We are using an erased type here, as we want to expose this API but `InsertableContent` and `NodeKeyManager` are not public.\n\t */\n\treadonly defaultProvider?: DefaultProvider;\n\n\t/**\n\t * Optional metadata to associate with the field.\n\t * @remarks Note: this metadata is not persisted in the document.\n\t */\n\treadonly metadata?: FieldSchemaMetadata<TCustomMetadata>;\n}\n\n/**\n * A {@link FieldProvider} which requires additional context in order to produce its content\n */\nexport type ContextualFieldProvider = (\n\tcontext: NodeKeyManager,\n) => InsertableContent | undefined;\n/**\n * A {@link FieldProvider} which can produce its content in a vacuum\n */\nexport type ConstantFieldProvider = () => InsertableContent | undefined;\n/**\n * A function which produces content for a field every time that it is called\n */\nexport type FieldProvider = ContextualFieldProvider | ConstantFieldProvider;\n/**\n * Returns true if the given {@link FieldProvider} is a {@link ConstantFieldProvider}\n */\nexport function isConstant(\n\tfieldProvider: FieldProvider,\n): fieldProvider is ConstantFieldProvider {\n\treturn fieldProvider.length === 0;\n}\n\n/**\n * Provides a default value for a field.\n * @remarks\n * If present in a `FieldSchema`, when constructing new tree content that field can be omitted, and a default will be provided.\n * @system @sealed @public\n */\nexport interface DefaultProvider extends ErasedType<\"@fluidframework/tree.FieldProvider\"> {}\n\nexport function extractFieldProvider(input: DefaultProvider): FieldProvider {\n\treturn input as unknown as FieldProvider;\n}\n\nexport function getDefaultProvider(input: FieldProvider): DefaultProvider {\n\treturn input as unknown as DefaultProvider;\n}\n\n/**\n * Metadata associated with a {@link FieldSchema}.\n *\n * @remarks Specified via {@link FieldProps.metadata}.\n *\n * @sealed\n * @public\n */\nexport interface FieldSchemaMetadata<TCustomMetadata = unknown> {\n\t/**\n\t * User-defined metadata.\n\t */\n\treadonly custom?: TCustomMetadata;\n\n\t/**\n\t * The description of the field.\n\t *\n\t * @remarks\n\t *\n\t * If provided, will be used by the system in scenarios where a description of the field is useful.\n\t * E.g., when converting a field schema to {@link https://json-schema.org/ | JSON Schema}, this description will be\n\t * used as the `description` field.\n\t */\n\treadonly description?: string | undefined;\n}\n\n/**\n * Package internal construction API.\n */\nexport let createFieldSchema: <\n\tKind extends FieldKind = FieldKind,\n\tTypes extends ImplicitAllowedTypes = ImplicitAllowedTypes,\n\tTCustomMetadata = unknown,\n>(\n\tkind: Kind,\n\tallowedTypes: Types,\n\tprops?: FieldProps<TCustomMetadata>,\n) => FieldSchema<Kind, Types, TCustomMetadata>;\n\n/**\n * All policy for a specific field,\n * including functionality that does not have to be kept consistent across versions or deterministic.\n *\n * This can include policy for how to use this schema for \"view\" purposes, and well as how to expose editing APIs.\n * Use {@link SchemaFactory} to create the FieldSchema instances, for example {@link SchemaFactory.optional}.\n * @privateRemarks\n * Public access to the constructor is removed to prevent creating expressible but unsupported (or not stable) configurations.\n * {@link createFieldSchema} can be used internally to create instances.\n *\n * @typeParam TCustomMetadata - Custom metadata properties to associate with the field.\n * See {@link FieldSchemaMetadata.custom}.\n *\n * @sealed @public\n */\nexport class FieldSchema<\n\tout Kind extends FieldKind = FieldKind,\n\tout Types extends ImplicitAllowedTypes = ImplicitAllowedTypes,\n\tout TCustomMetadata = unknown,\n> {\n\tstatic {\n\t\tcreateFieldSchema = <\n\t\t\tKind2 extends FieldKind = FieldKind,\n\t\t\tTypes2 extends ImplicitAllowedTypes = ImplicitAllowedTypes,\n\t\t\tTCustomMetadata2 = unknown,\n\t\t>(\n\t\t\tkind: Kind2,\n\t\t\tallowedTypes: Types2,\n\t\t\tprops?: FieldProps<TCustomMetadata2>,\n\t\t) => new FieldSchema(kind, allowedTypes, props);\n\t}\n\t/**\n\t * This class is used with instanceof, and therefore should have nominal typing.\n\t * This field enforces that.\n\t */\n\tprotected _typeCheck!: MakeNominal;\n\n\tprivate readonly lazyTypes: Lazy<ReadonlySet<TreeNodeSchema>>;\n\n\t/**\n\t * What types of tree nodes are allowed in this field.\n\t * @remarks Counterpart to {@link FieldSchema.allowedTypes}, with any lazy definitions evaluated.\n\t */\n\tpublic get allowedTypeSet(): ReadonlySet<TreeNodeSchema> {\n\t\treturn this.lazyTypes.value;\n\t}\n\n\t/**\n\t * True if and only if, when constructing a node with this field, a value must be provided for it.\n\t */\n\tpublic readonly requiresValue: boolean;\n\n\t/**\n\t * {@inheritDoc FieldProps.metadata}\n\t */\n\tpublic get metadata(): FieldSchemaMetadata<TCustomMetadata> | undefined {\n\t\treturn this.props?.metadata;\n\t}\n\n\tprivate constructor(\n\t\t/**\n\t\t * The {@link https://en.wikipedia.org/wiki/Kind_(type_theory) | kind } of this field.\n\t\t * Determines the multiplicity, viewing and editing APIs as well as the merge resolution policy.\n\t\t */\n\t\tpublic readonly kind: Kind,\n\t\t/**\n\t\t * What types of tree nodes are allowed in this field.\n\t\t */\n\t\tpublic readonly allowedTypes: Types,\n\t\t/**\n\t\t * Optional properties associated with the field.\n\t\t */\n\t\tpublic readonly props?: FieldProps<TCustomMetadata>,\n\t) {\n\t\tthis.lazyTypes = new Lazy(() => normalizeAllowedTypes(this.allowedTypes));\n\t\t// TODO: optional fields should (by default) get a default provider that returns undefined, removing the need to special case them here:\n\t\tthis.requiresValue =\n\t\t\tthis.props?.defaultProvider === undefined && this.kind !== FieldKind.Optional;\n\t}\n}\n\n/**\n * Normalizes a {@link ImplicitFieldSchema} to a {@link FieldSchema}.\n */\nexport function normalizeFieldSchema(schema: ImplicitFieldSchema): FieldSchema {\n\treturn schema instanceof FieldSchema\n\t\t? schema\n\t\t: createFieldSchema(FieldKind.Required, schema);\n}\n/**\n * Normalizes a {@link ImplicitAllowedTypes} to a set of {@link TreeNodeSchema}s, by eagerly evaluating any\n * lazy schema declarations.\n *\n * @remarks Note: this must only be called after all required schemas have been declared, otherwise evaluation of\n * recursive schemas may fail.\n */\nexport function normalizeAllowedTypes(\n\ttypes: ImplicitAllowedTypes,\n): ReadonlySet<TreeNodeSchema> {\n\tconst normalized = new Set<TreeNodeSchema>();\n\tif (isReadonlyArray(types)) {\n\t\tfor (const lazyType of types) {\n\t\t\tnormalized.add(evaluateLazySchema(lazyType));\n\t\t}\n\t} else {\n\t\tnormalized.add(evaluateLazySchema(types));\n\t}\n\treturn normalized;\n}\n\nfunction evaluateLazySchema(value: LazyItem<TreeNodeSchema>): TreeNodeSchema {\n\tconst evaluatedSchema = isLazy(value) ? value() : value;\n\tif (evaluatedSchema === undefined) {\n\t\tthrow new UsageError(\n\t\t\t`Encountered an undefined schema. This could indicate that some referenced schema has not yet been instantiated.`,\n\t\t);\n\t}\n\treturn evaluatedSchema;\n}\n\n/**\n * Types allowed in a field.\n * @remarks\n * Implicitly treats a single type as an array of one type.\n * @public\n */\nexport type ImplicitAllowedTypes = AllowedTypes | TreeNodeSchema;\n\n/**\n * Schema for a field of a tree node.\n * @remarks\n * Implicitly treats {@link ImplicitAllowedTypes} as a Required field of that type.\n * @public\n */\nexport type ImplicitFieldSchema = FieldSchema | ImplicitAllowedTypes;\n\n/**\n * Converts ImplicitFieldSchema to the corresponding tree node's field type.\n * @public\n */\nexport type TreeFieldFromImplicitField<TSchema extends ImplicitFieldSchema = FieldSchema> =\n\tTSchema extends FieldSchema<infer Kind, infer Types>\n\t\t? ApplyKind<TreeNodeFromImplicitAllowedTypes<Types>, Kind, false>\n\t\t: TSchema extends ImplicitAllowedTypes\n\t\t\t? TreeNodeFromImplicitAllowedTypes<TSchema>\n\t\t\t: unknown;\n\n/**\n * Type of content that can be inserted into the tree for a field of the given schema.\n * @public\n */\nexport type InsertableTreeFieldFromImplicitField<\n\tTSchema extends ImplicitFieldSchema = FieldSchema,\n> = TSchema extends FieldSchema<infer Kind, infer Types>\n\t? ApplyKind<InsertableTreeNodeFromImplicitAllowedTypes<Types>, Kind, true>\n\t: TSchema extends ImplicitAllowedTypes\n\t\t? InsertableTreeNodeFromImplicitAllowedTypes<TSchema>\n\t\t: unknown;\n\n/**\n * Suitable for output.\n * For input must error on side of excluding undefined instead.\n * @system @public\n */\nexport type ApplyKind<T, Kind extends FieldKind, DefaultsAreOptional extends boolean> = {\n\t[FieldKind.Required]: T;\n\t[FieldKind.Optional]: T | undefined;\n\t[FieldKind.Identifier]: DefaultsAreOptional extends true ? T | undefined : T;\n}[Kind];\n\n/**\n * Type of tree node for a field of the given schema.\n * @public\n */\nexport type TreeNodeFromImplicitAllowedTypes<\n\tTSchema extends ImplicitAllowedTypes = TreeNodeSchema,\n> = TSchema extends TreeNodeSchema\n\t? NodeFromSchema<TSchema>\n\t: TSchema extends AllowedTypes\n\t\t? NodeFromSchema<FlexListToUnion<TSchema>>\n\t\t: unknown;\n\n/**\n * Type of content that can be inserted into the tree for a node of the given schema.\n * @public\n */\nexport type InsertableTreeNodeFromImplicitAllowedTypes<\n\tTSchema extends ImplicitAllowedTypes = TreeNodeSchema,\n> = TSchema extends TreeNodeSchema\n\t? InsertableTypedNode<TSchema>\n\t: TSchema extends AllowedTypes\n\t\t? InsertableTypedNode<FlexListToUnion<TSchema>>\n\t\t: never;\n\n/**\n * Takes in `TreeNodeSchema[]` and returns a TypedNode union.\n * @public\n */\nexport type NodeFromSchema<T extends TreeNodeSchema> = T extends TreeNodeSchema<\n\tstring,\n\tNodeKind,\n\tinfer TNode\n>\n\t? TNode\n\t: never;\n\n/**\n * Data which can be used as a node to be inserted.\n * Either an unhydrated node, or content to build a new node.\n * @public\n */\nexport type InsertableTypedNode<T extends TreeNodeSchema> =\n\t| (T extends { implicitlyConstructable: true } ? NodeBuilderData<T> : never)\n\t| Unhydrated<NodeFromSchema<T>>;\n\n/**\n * Given a node's schema, return the corresponding object from which the node could be built.\n * @privateRemarks\n * Currently this assumes factory functions take exactly one argument.\n * This could be changed if needed.\n *\n * These factory functions can also take a FlexTreeNode, but this is not exposed in the public facing types.\n * @system @public\n */\nexport type NodeBuilderData<T extends TreeNodeSchema> = T extends TreeNodeSchema<\n\tstring,\n\tNodeKind,\n\tunknown,\n\tinfer TBuild\n>\n\t? TBuild\n\t: never;\n\n/**\n * Value that may be stored as a leaf node.\n * @remarks\n * Some limitations apply, see the documentation for {@link SchemaFactory.number} and {@link SchemaFactory.string} for those restrictions.\n * @public\n */\n// eslint-disable-next-line @rushstack/no-new-null\nexport type TreeLeafValue = number | string | boolean | IFluidHandle | null;\n"]}
|
|
@@ -76,7 +76,7 @@ function getStoredSchema(schema) {
|
|
|
76
76
|
const kind = schema.kind;
|
|
77
77
|
switch (kind) {
|
|
78
78
|
case index_js_4.NodeKind.Leaf: {
|
|
79
|
-
(0, internal_1.assert)(schema instanceof leafNodeSchema_js_1.LeafNodeSchema,
|
|
79
|
+
(0, internal_1.assert)(schema instanceof leafNodeSchema_js_1.LeafNodeSchema, 0xa4a /* invalid kind */);
|
|
80
80
|
return new index_js_1.LeafNodeStoredSchema(schema.info);
|
|
81
81
|
}
|
|
82
82
|
case index_js_4.NodeKind.Map: {
|
|
@@ -94,7 +94,7 @@ function getStoredSchema(schema) {
|
|
|
94
94
|
return new index_js_1.ObjectNodeStoredSchema(fields);
|
|
95
95
|
}
|
|
96
96
|
case index_js_4.NodeKind.Object: {
|
|
97
|
-
(0, internal_1.assert)((0, objectNodeTypes_js_1.isObjectNodeSchema)(schema),
|
|
97
|
+
(0, internal_1.assert)((0, objectNodeTypes_js_1.isObjectNodeSchema)(schema), 0xa4b /* invalid kind */);
|
|
98
98
|
const fields = new Map();
|
|
99
99
|
for (const field of schema.flexKeyMap.values()) {
|
|
100
100
|
fields.set(field.storedKey, convertField(field.schema));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toFlexSchema.js","sourceRoot":"","sources":["../../src/simple-tree/toFlexSchema.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,kEAA8E;AAC9E,uEAAsE;AAEtE,+CAY0B;AAC1B,4DAA+E;AAC/E,+CAAgE;AAChE,8CAAgE;AAChE,qDAK0B;AAC1B,6DAAuD;AACvD,2DAAqD;AACrD,6DAA0D;AAC1D,+CAAuD;AAEvD;;GAEG;AACH,SAAgB,cAAc,CAAC,IAAyB;IACvD,MAAM,UAAU,GAAwD,IAAI,GAAG,EAAE,CAAC;IAClF,IAAA,oCAAe,EAAC,IAAI,EAAE;QACrB,IAAI,CAAC,MAAM;YACV,IAAI,UAAU,CAAC,GAAG,CAAC,IAAA,gBAAK,EAAC,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;gBAC9C,4DAA4D;gBAC5D,MAAM,IAAI,qBAAU,CACnB,mDAAmD,IAAI,CAAC,SAAS,CAChE,MAAM,CAAC,UAAU,CACjB,iDAAiD,CAClD,CAAC;YACH,CAAC;YACD,UAAU,CAAC,GAAG,CAAC,IAAA,gBAAK,EAAC,MAAM,CAAC,UAAU,CAAC,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;QACnE,CAAC;KACD,CAAC,CAAC;IAEH,OAAO;QACN,UAAU;QACV,eAAe,EAAE,YAAY,CAAC,IAAI,CAAC;KACnC,CAAC;AACH,CAAC;AApBD,wCAoBC;AAED;;GAEG;AACH,SAAgB,YAAY,CAAC,MAA2B;IACvD,IAAI,IAAyB,CAAC;IAC9B,IAAI,YAAkC,CAAC;IACvC,IAAI,MAAM,YAAY,4BAAW,EAAE,CAAC;QACnC,IAAI,GAAG,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,UAAU,IAAI,IAAA,eAAI,EAAC,oBAAoB,CAAC,CAAC;QACnF,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;IACpC,CAAC;SAAM,CAAC;QACP,IAAI,GAAG,qBAAU,CAAC,QAAQ,CAAC,UAAU,CAAC;QACtC,YAAY,GAAG,MAAM,CAAC;IACvB,CAAC;IACD,MAAM,KAAK,GAAG,mBAAmB,CAAC,YAAY,CAAC,CAAC;IAChD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AACxB,CAAC;AAZD,oCAYC;AAED,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAA2B;IAC1D,CAAC,0BAAS,CAAC,QAAQ,EAAE,qBAAU,CAAC,QAAQ,CAAC;IACzC,CAAC,0BAAS,CAAC,QAAQ,EAAE,qBAAU,CAAC,QAAQ,CAAC;IACzC,CAAC,0BAAS,CAAC,UAAU,EAAE,qBAAU,CAAC,UAAU,CAAC;CAC7C,CAAC,CAAC;AAEH;;GAEG;AACH,SAAgB,mBAAmB,CAAC,MAA4B;IAC/D,IAAI,IAAA,0BAAe,EAAC,MAAM,CAAC,EAAE,CAAC;QAC7B,OAAO,IAAI,GAAG,CAAC,IAAA,oCAAsB,EAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAA,gBAAK,EAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IACtF,CAAC;IACD,OAAO,IAAI,GAAG,CAAC,CAAC,IAAA,gBAAK,EAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AAC5C,CAAC;AALD,kDAKC;AAED;;GAEG;AACH,SAAgB,eAAe,CAAC,MAAsB;IACrD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;IACzB,QAAQ,IAAI,EAAE,CAAC;QACd,KAAK,mBAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;YACpB,IAAA,iBAAM,EAAC,MAAM,YAAY,kCAAc,EAAE,
|
|
1
|
+
{"version":3,"file":"toFlexSchema.js","sourceRoot":"","sources":["../../src/simple-tree/toFlexSchema.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, unreachableCase } from \"@fluidframework/core-utils/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport {\n\tEmptyKey,\n\tLeafNodeStoredSchema,\n\tMapNodeStoredSchema,\n\tObjectNodeStoredSchema,\n\ttype FieldKey,\n\ttype FieldKindIdentifier,\n\ttype TreeFieldStoredSchema,\n\ttype TreeNodeSchemaIdentifier,\n\ttype TreeNodeStoredSchema,\n\ttype TreeStoredSchema,\n\ttype TreeTypeSet,\n} from \"../core/index.js\";\nimport { FieldKinds, type FlexFieldKind } from \"../feature-libraries/index.js\";\nimport { brand, fail, isReadonlyArray } from \"../util/index.js\";\nimport { NodeKind, type TreeNodeSchema } from \"./core/index.js\";\nimport {\n\tFieldKind,\n\tFieldSchema,\n\ttype ImplicitAllowedTypes,\n\ttype ImplicitFieldSchema,\n} from \"./schemaTypes.js\";\nimport { walkFieldSchema } from \"./walkFieldSchema.js\";\nimport { LeafNodeSchema } from \"./leafNodeSchema.js\";\nimport { isObjectNodeSchema } from \"./objectNodeTypes.js\";\nimport { normalizeFlexListEager } from \"./flexList.js\";\n\n/**\n * Converts a {@link ImplicitFieldSchema} into a {@link TreeStoredSchema}.\n */\nexport function toStoredSchema(root: ImplicitFieldSchema): TreeStoredSchema {\n\tconst nodeSchema: Map<TreeNodeSchemaIdentifier, TreeNodeStoredSchema> = new Map();\n\twalkFieldSchema(root, {\n\t\tnode(schema) {\n\t\t\tif (nodeSchema.has(brand(schema.identifier))) {\n\t\t\t\t// Use JSON.stringify to quote and escape identifier string.\n\t\t\t\tthrow new UsageError(\n\t\t\t\t\t`Multiple schema encountered with the identifier ${JSON.stringify(\n\t\t\t\t\t\tschema.identifier,\n\t\t\t\t\t)}. Remove or rename them to avoid the collision.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tnodeSchema.set(brand(schema.identifier), getStoredSchema(schema));\n\t\t},\n\t});\n\n\treturn {\n\t\tnodeSchema,\n\t\trootFieldSchema: convertField(root),\n\t};\n}\n\n/**\n * Normalizes an {@link ImplicitFieldSchema} into a {@link TreeFieldSchema}.\n */\nexport function convertField(schema: ImplicitFieldSchema): TreeFieldStoredSchema {\n\tlet kind: FieldKindIdentifier;\n\tlet allowedTypes: ImplicitAllowedTypes;\n\tif (schema instanceof FieldSchema) {\n\t\tkind = convertFieldKind.get(schema.kind)?.identifier ?? fail(\"Invalid field kind\");\n\t\tallowedTypes = schema.allowedTypes;\n\t} else {\n\t\tkind = FieldKinds.required.identifier;\n\t\tallowedTypes = schema;\n\t}\n\tconst types = convertAllowedTypes(allowedTypes);\n\treturn { kind, types };\n}\n\nconst convertFieldKind = new Map<FieldKind, FlexFieldKind>([\n\t[FieldKind.Optional, FieldKinds.optional],\n\t[FieldKind.Required, FieldKinds.required],\n\t[FieldKind.Identifier, FieldKinds.identifier],\n]);\n\n/**\n * Normalizes an {@link ImplicitAllowedTypes} into an {@link TreeTypeSet}.\n */\nexport function convertAllowedTypes(schema: ImplicitAllowedTypes): TreeTypeSet {\n\tif (isReadonlyArray(schema)) {\n\t\treturn new Set(normalizeFlexListEager(schema).map((item) => brand(item.identifier)));\n\t}\n\treturn new Set([brand(schema.identifier)]);\n}\n\n/**\n * Converts a {@link TreeNodeSchema} into a {@link TreeNodeStoredSchema}.\n */\nexport function getStoredSchema(schema: TreeNodeSchema): TreeNodeStoredSchema {\n\tconst kind = schema.kind;\n\tswitch (kind) {\n\t\tcase NodeKind.Leaf: {\n\t\t\tassert(schema instanceof LeafNodeSchema, 0xa4a /* invalid kind */);\n\t\t\treturn new LeafNodeStoredSchema(schema.info);\n\t\t}\n\t\tcase NodeKind.Map: {\n\t\t\tconst fieldInfo = schema.info as ImplicitAllowedTypes;\n\t\t\tconst types = convertAllowedTypes(fieldInfo);\n\t\t\treturn new MapNodeStoredSchema({ kind: FieldKinds.optional.identifier, types });\n\t\t}\n\t\tcase NodeKind.Array: {\n\t\t\tconst fieldInfo = schema.info as ImplicitAllowedTypes;\n\t\t\tconst field = {\n\t\t\t\tkind: FieldKinds.sequence.identifier,\n\t\t\t\ttypes: convertAllowedTypes(fieldInfo),\n\t\t\t};\n\t\t\tconst fields = new Map([[EmptyKey, field]]);\n\t\t\treturn new ObjectNodeStoredSchema(fields);\n\t\t}\n\t\tcase NodeKind.Object: {\n\t\t\tassert(isObjectNodeSchema(schema), 0xa4b /* invalid kind */);\n\t\t\tconst fields: Map<FieldKey, TreeFieldStoredSchema> = new Map();\n\t\t\tfor (const field of schema.flexKeyMap.values()) {\n\t\t\t\tfields.set(field.storedKey, convertField(field.schema));\n\t\t\t}\n\t\t\treturn new ObjectNodeStoredSchema(fields);\n\t\t}\n\t\tdefault:\n\t\t\tunreachableCase(kind);\n\t}\n}\n"]}
|
|
@@ -81,7 +81,6 @@ export declare function addDefaultsToMapTree(mapTree: ExclusiveMapTree, allowedT
|
|
|
81
81
|
* Content which can be used to build a node.
|
|
82
82
|
* @remarks
|
|
83
83
|
* Can contain unhydrated nodes, but can not be an unhydrated node at the root.
|
|
84
|
-
* @system @alpha
|
|
85
84
|
*/
|
|
86
85
|
export type FactoryContent = IFluidHandle | string | number | boolean | null | Iterable<readonly [string, InsertableContent]> | readonly InsertableContent[] | FactoryContentObject;
|
|
87
86
|
/**
|
|
@@ -90,14 +89,13 @@ export type FactoryContent = IFluidHandle | string | number | boolean | null | I
|
|
|
90
89
|
* Can contain unhydrated nodes, but can not be an unhydrated node at the root.
|
|
91
90
|
*
|
|
92
91
|
* Supports object and map nodes.
|
|
93
|
-
* @system @alpha
|
|
94
92
|
*/
|
|
95
|
-
|
|
93
|
+
type FactoryContentObject = {
|
|
96
94
|
readonly [P in string]?: InsertableContent;
|
|
97
95
|
};
|
|
98
96
|
/**
|
|
99
97
|
* Content which can be inserted into a tree.
|
|
100
|
-
* @system @alpha
|
|
101
98
|
*/
|
|
102
99
|
export type InsertableContent = Unhydrated<TreeNode> | FactoryContent;
|
|
100
|
+
export {};
|
|
103
101
|
//# sourceMappingURL=toMapTree.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toMapTree.d.ts","sourceRoot":"","sources":["../../src/simple-tree/toMapTree.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAMN,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAGN,KAAK,cAAc,EACnB,MAAM,+BAA+B,CAAC;AAIvC,OAAO,EAEN,KAAK,oBAAoB,EAKzB,KAAK,mBAAmB,EAIxB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAMN,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,UAAU,EAEf,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,sBAAsB,EAAkB,MAAM,+BAA+B,CAAC;AAEvF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAEpE;;;;;;;;;GASG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,mBAAmB,CAClC,IAAI,EAAE,iBAAiB,EACvB,YAAY,EAAE,oBAAoB,EAClC,OAAO,CAAC,EAAE,cAAc,EACxB,sBAAsB,CAAC,EAAE,eAAe,GACtC,gBAAgB,CAAC;AACpB,wBAAgB,mBAAmB,CAClC,IAAI,EAAE,iBAAiB,GAAG,SAAS,EACnC,YAAY,EAAE,mBAAmB,EACjC,OAAO,CAAC,EAAE,cAAc,EACxB,sBAAsB,CAAC,EAAE,eAAe,GACtC,gBAAgB,GAAG,SAAS,CAAC;AA0FhC;;GAEG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,sBAAsB,GAAG,IAAI,CAIxE;AAgRD;;GAEG;AACH,wBAAgB,gBAAgB,CAC/B,YAAY,EAAE,WAAW,CAAC,cAAc,CAAC,EACzC,IAAI,EAAE,cAAc,GAClB,cAAc,EAAE,CAclB;AA6HD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CACnC,OAAO,EAAE,gBAAgB,EACzB,YAAY,EAAE,oBAAoB,EAClC,OAAO,EAAE,cAAc,GAAG,SAAS,GACjC,IAAI,CA8CN;AAqCD
|
|
1
|
+
{"version":3,"file":"toMapTree.d.ts","sourceRoot":"","sources":["../../src/simple-tree/toMapTree.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAMN,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAGN,KAAK,cAAc,EACnB,MAAM,+BAA+B,CAAC;AAIvC,OAAO,EAEN,KAAK,oBAAoB,EAKzB,KAAK,mBAAmB,EAIxB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAMN,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,UAAU,EAEf,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,sBAAsB,EAAkB,MAAM,+BAA+B,CAAC;AAEvF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAEpE;;;;;;;;;GASG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,mBAAmB,CAClC,IAAI,EAAE,iBAAiB,EACvB,YAAY,EAAE,oBAAoB,EAClC,OAAO,CAAC,EAAE,cAAc,EACxB,sBAAsB,CAAC,EAAE,eAAe,GACtC,gBAAgB,CAAC;AACpB,wBAAgB,mBAAmB,CAClC,IAAI,EAAE,iBAAiB,GAAG,SAAS,EACnC,YAAY,EAAE,mBAAmB,EACjC,OAAO,CAAC,EAAE,cAAc,EACxB,sBAAsB,CAAC,EAAE,eAAe,GACtC,gBAAgB,GAAG,SAAS,CAAC;AA0FhC;;GAEG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,sBAAsB,GAAG,IAAI,CAIxE;AAgRD;;GAEG;AACH,wBAAgB,gBAAgB,CAC/B,YAAY,EAAE,WAAW,CAAC,cAAc,CAAC,EACzC,IAAI,EAAE,cAAc,GAClB,cAAc,EAAE,CAclB;AA6HD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CACnC,OAAO,EAAE,gBAAgB,EACzB,YAAY,EAAE,oBAAoB,EAClC,OAAO,EAAE,cAAc,GAAG,SAAS,GACjC,IAAI,CA8CN;AAqCD;;;;GAIG;AACH,MAAM,MAAM,cAAc,GACvB,YAAY,GACZ,MAAM,GACN,MAAM,GACN,OAAO,GAEP,IAAI,GACJ,QAAQ,CAAC,SAAS,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,GAC9C,SAAS,iBAAiB,EAAE,GAC5B,oBAAoB,CAAC;AAExB;;;;;;GAMG;AACH,KAAK,oBAAoB,GAAG;IAC3B,QAAQ,EAAE,CAAC,IAAI,MAAM,CAAC,CAAC,EAAE,iBAAiB;CAC1C,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,UAAU,CAAC,QAAQ,CAAC,GAAG,cAAc,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toMapTree.js","sourceRoot":"","sources":["../../src/simple-tree/toMapTree.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 } from \"@fluidframework/core-utils/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\nimport { isFluidHandle } from \"@fluidframework/runtime-utils/internal\";\n\nimport {\n\tEmptyKey,\n\ttype FieldKey,\n\ttype MapTree,\n\ttype TreeValue,\n\ttype ValueSchema,\n\ttype SchemaAndPolicy,\n\ttype ExclusiveMapTree,\n} from \"../core/index.js\";\nimport {\n\tisTreeValue,\n\tvalueSchemaAllows,\n\ttype NodeKeyManager,\n} from \"../feature-libraries/index.js\";\nimport { brand, fail, isReadonlyArray, find } from \"../util/index.js\";\n\nimport { nullSchema } from \"./leafNodeSchema.js\";\nimport {\n\ttype FieldSchema,\n\ttype ImplicitAllowedTypes,\n\tnormalizeAllowedTypes,\n\textractFieldProvider,\n\tisConstant,\n\ttype FieldProvider,\n\ttype ImplicitFieldSchema,\n\tnormalizeFieldSchema,\n\tFieldKind,\n\ttype TreeLeafValue,\n} from \"./schemaTypes.js\";\nimport {\n\tgetKernel,\n\tgetSimpleNodeSchemaFromInnerNode,\n\tisTreeNode,\n\tNodeKind,\n\ttype InnerNode,\n\ttype TreeNode,\n\ttype TreeNodeSchema,\n\ttype Unhydrated,\n\tUnhydratedFlexTreeNode,\n} from \"./core/index.js\";\nimport { SchemaValidationErrors, isNodeInSchema } from \"../feature-libraries/index.js\";\nimport { isObjectNodeSchema } from \"./objectNodeTypes.js\";\nimport type { IFluidHandle } from \"@fluidframework/core-interfaces\";\n\n/**\n * Module notes:\n *\n * The flow of the below code is in terms of the structure of the input data. We then verify that the associated\n * schema is appropriate for that kind of data. This is fine while we have a 1:1 mapping of kind of input data to\n * the kind of schema we expect for it (e.g. an input that is an array always need to be associated with a sequence in\n * the schema). If/when we begin accepting kinds of input data that are ambiguous (e.g. accepting an input that is an\n * array of key/value tuples to instantiate a map) we may need to rethink the structure here to be based more on the\n * schema than on the input data.\n */\n\n/**\n * Transforms an input {@link TypedNode} tree to a {@link MapTree}.\n * @param data - The input tree to be converted.\n * If the data is an unsupported value (e.g. NaN), a fallback value will be used when supported,\n * otherwise an error will be thrown.\n *\n * Fallbacks:\n *\n * * `NaN` =\\> `null`\n *\n * * `+/-∞` =\\> `null`\n *\n * * `-0` =\\> `+0`\n *\n * For fields with a default value, the field may be omitted.\n * If `context` is not provided, defaults which require a context will be left empty which can be out of schema.\n *\n * @param allowedTypes - The set of types allowed by the parent context. Used to validate the input tree.\n * @param context - An optional context which, if present, will allow defaults to be created by {@link ContextualFieldProvider}s.\n * If absent, only defaults from {@link ConstantFieldProvider}s will be created.\n * @param schemaValidationPolicy - The stored schema and policy to be used for validation, if the policy says schema\n * validation should happen. If it does, the input tree will be validated against this schema + policy, and an error will\n * be thrown if the tree does not conform to the schema. If undefined, no validation against the stored schema is done.\n *\n * TODO:BUG: AB#9131\n * This schema validation is done before defaults are provided.\n * This can not easily be fixed by reordering things within this implementation since even at the end of this function defaults requiring a context may not have been filled.\n * This means schema validation reject required fields getting their value from a default like identifier fields.\n *\n * @remarks The resulting tree will be populated with any defaults from {@link FieldProvider}s in the schema.\n *\n * @privateRemarks\n * TODO: AB#9126 AB#9131\n * When an app wants schema validation, we should ensure data is validated. Doing the validation here is not robust (since many callers to this don't have a context and thus can't opt into validation).\n * Additionally the validation here does not correctly handle default values, and introduces a second schema representation which is a bit odd API wise as its typically derivable from the view schema.\n * It may make more sense to validate when hydrating the MapTreeNode when the context is known and the defaults are available.\n * Applying the \"parse don't validate\" idiom here could help ensuring we capture when the validation optionally happens in the type system to avoid missing or redundant validation,\n * as well as ensuring validation happens after defaulting (or can handle validating data missing defaults)\n */\nexport function mapTreeFromNodeData(\n\tdata: InsertableContent,\n\tallowedTypes: ImplicitAllowedTypes,\n\tcontext?: NodeKeyManager,\n\tschemaValidationPolicy?: SchemaAndPolicy,\n): ExclusiveMapTree;\nexport function mapTreeFromNodeData(\n\tdata: InsertableContent | undefined,\n\tallowedTypes: ImplicitFieldSchema,\n\tcontext?: NodeKeyManager,\n\tschemaValidationPolicy?: SchemaAndPolicy,\n): ExclusiveMapTree | undefined;\nexport function mapTreeFromNodeData(\n\tdata: InsertableContent | undefined,\n\tallowedTypes: ImplicitFieldSchema,\n\tcontext?: NodeKeyManager,\n\tschemaValidationPolicy?: SchemaAndPolicy,\n): ExclusiveMapTree | undefined {\n\tconst normalizedFieldSchema = normalizeFieldSchema(allowedTypes);\n\n\tif (data === undefined) {\n\t\t// TODO: this code-path should support defaults\n\t\tif (normalizedFieldSchema.kind !== FieldKind.Optional) {\n\t\t\tthrow new UsageError(\"Got undefined for non-optional field.\");\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tconst mapTree = nodeDataToMapTree(data, normalizedFieldSchema.allowedTypeSet);\n\t// Add what defaults can be provided. If no `context` is providing, some defaults may still be missing.\n\taddDefaultsToMapTree(mapTree, normalizedFieldSchema.allowedTypes, context);\n\n\tif (schemaValidationPolicy?.policy.validateSchema === true) {\n\t\t// TODO: BUG: AB#9131\n\t\t// Since some defaults may still be missing, this can give false positives when context is undefined but schemaValidationPolicy is provided.\n\t\t// For now disable this check when context is undefined:\n\t\tif (context !== undefined) {\n\t\t\tconst maybeError = isNodeInSchema(mapTree, schemaValidationPolicy);\n\t\t\tinSchemaOrThrow(maybeError);\n\t\t}\n\t}\n\n\treturn mapTree;\n}\n\n/**\n * Copy content from `data` into a MapTree.\n * Does NOT generate and default values for fields.\n * Often throws UsageErrors for invalid data, but may miss some cases.\n * @remarks\n * Output is likely out of schema even for valid input due to missing defaults.\n */\nfunction nodeDataToMapTree(\n\tdata: InsertableContent,\n\tallowedTypes: ReadonlySet<TreeNodeSchema>,\n): ExclusiveMapTree {\n\t// A special cache path for processing unhydrated nodes.\n\t// They already have the mapTree, so there is no need to recompute it.\n\tconst innerNode = tryGetInnerNode(data);\n\tif (innerNode !== undefined) {\n\t\tif (innerNode instanceof UnhydratedFlexTreeNode) {\n\t\t\tif (!allowedTypes.has(getSimpleNodeSchemaFromInnerNode(innerNode))) {\n\t\t\t\tthrow new UsageError(\"Invalid schema for this context.\");\n\t\t\t}\n\t\t\t// TODO: mapTreeFromNodeData modifies the trees it gets to add defaults.\n\t\t\t// Using a cached value here can result in this tree having defaults applied to it more than once.\n\t\t\t// This is unnecessary and inefficient, but should be a no-op if all calls provide the same context (which they might not).\n\t\t\t// A cleaner design (avoiding this cast) might be to apply defaults eagerly if they don't need a context, and lazily (when hydrating) if they do.\n\t\t\t// This could avoid having to mutate the map tree to apply defaults, removing the need for this cast.\n\t\t\treturn innerNode.mapTree;\n\t\t} else {\n\t\t\t// The node is already hydrated, meaning that it already got inserted into the tree previously\n\t\t\tthrow new UsageError(\"A node may not be inserted into the tree more than once\");\n\t\t}\n\t}\n\n\tassert(!isTreeNode(data), 0xa23 /* data without an inner node cannot be TreeNode */);\n\n\tconst schema = getType(data, allowedTypes);\n\n\tlet result: ExclusiveMapTree;\n\tswitch (schema.kind) {\n\t\tcase NodeKind.Leaf:\n\t\t\tresult = leafToMapTree(data, schema, allowedTypes);\n\t\t\tbreak;\n\t\tcase NodeKind.Array:\n\t\t\tresult = arrayToMapTree(data, schema);\n\t\t\tbreak;\n\t\tcase NodeKind.Map:\n\t\t\tresult = mapToMapTree(data, schema);\n\t\t\tbreak;\n\t\tcase NodeKind.Object:\n\t\t\tresult = objectToMapTree(data, schema);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tfail(`Unrecognized schema kind: ${schema.kind}.`);\n\t}\n\n\treturn result;\n}\n\n/**\n * Throws a UsageError if maybeError indicates a tree is out of schema.\n */\nexport function inSchemaOrThrow(maybeError: SchemaValidationErrors): void {\n\tif (maybeError !== SchemaValidationErrors.NoError) {\n\t\tthrow new UsageError(\"Tree does not conform to schema.\");\n\t}\n}\n\n/**\n * Transforms data under a Leaf schema.\n * @param data - The tree data to be transformed. Must be a {@link TreeValue}.\n * @param schema - The schema associated with the value.\n * @param allowedTypes - The allowed types specified by the parent.\n * Used to determine which fallback values may be appropriate.\n */\nfunction leafToMapTree(\n\tdata: FactoryContent,\n\tschema: TreeNodeSchema,\n\tallowedTypes: ReadonlySet<TreeNodeSchema>,\n): ExclusiveMapTree {\n\tassert(schema.kind === NodeKind.Leaf, 0x921 /* Expected a leaf schema. */);\n\tif (!isTreeValue(data)) {\n\t\t// This rule exists to protect against useless `toString` output like `[object Object]`.\n\t\t// In this case, that's actually reasonable behavior, since object input is not compatible with Leaf schemas.\n\t\t// eslint-disable-next-line @typescript-eslint/no-base-to-string\n\t\tthrow new UsageError(`Input data is incompatible with leaf schema: ${data}`);\n\t}\n\n\tconst mappedValue = mapValueWithFallbacks(data, allowedTypes);\n\tconst mappedSchema = getType(mappedValue, allowedTypes);\n\n\tassert(\n\t\tallowsValue(mappedSchema, mappedValue),\n\t\t0x84a /* Unsupported schema for provided primitive. */,\n\t);\n\n\treturn {\n\t\tvalue: mappedValue,\n\t\ttype: brand(mappedSchema.identifier),\n\t\tfields: new Map(),\n\t};\n}\n\n/**\n * Checks an incoming {@link TreeLeafValue} to ensure it is compatible with its requirements.\n * For unsupported values with a schema-compatible replacement, return the replacement value.\n * For unsupported values without a schema-compatible replacement, throw.\n * For supported values, return the input.\n */\nfunction mapValueWithFallbacks(\n\tvalue: TreeLeafValue,\n\tallowedTypes: ReadonlySet<TreeNodeSchema>,\n): TreeValue {\n\tswitch (typeof value) {\n\t\tcase \"number\": {\n\t\t\tif (Object.is(value, -0)) {\n\t\t\t\t// Our serialized data format does not support -0.\n\t\t\t\t// Map such input to +0.\n\t\t\t\treturn 0;\n\t\t\t} else if (!Number.isFinite(value)) {\n\t\t\t\t// Our serialized data format does not support NaN nor +/-∞.\n\t\t\t\t// If the schema supports `null`, fall back to that. Otherwise, throw.\n\t\t\t\t// This is intended to match JSON's behavior for such values.\n\t\t\t\tif (allowedTypes.has(nullSchema)) {\n\t\t\t\t\treturn null;\n\t\t\t\t} else {\n\t\t\t\t\tthrow new UsageError(`Received unsupported numeric value: ${value}.`);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\t\tcase \"string\":\n\t\t// TODO:\n\t\t// This should detect invalid strings. Something like @stdlib/regexp-utf16-unpaired-surrogate could be used to do this.\n\t\t// See SchemaFactory.string for details.\n\t\tcase \"boolean\":\n\t\t\treturn value;\n\t\tcase \"object\": {\n\t\t\tif (value === null || isFluidHandle(value)) {\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\t\tdefault:\n\t\t\tthrow new UsageError(`Received unsupported leaf value: ${value}.`);\n\t}\n}\n\n/**\n * Transforms data under an Array schema.\n * @param data - The tree data to be transformed.\n * @param allowedTypes - The set of types allowed by the parent context. Used to validate the input tree.\n */\nfunction arrayChildToMapTree(\n\tchild: InsertableContent,\n\tallowedTypes: ReadonlySet<TreeNodeSchema>,\n): ExclusiveMapTree {\n\t// We do not support undefined sequence entries.\n\t// If we encounter an undefined entry, use null instead if supported by the schema, otherwise throw.\n\tlet childWithFallback = child;\n\tif (child === undefined) {\n\t\tif (allowedTypes.has(nullSchema)) {\n\t\t\tchildWithFallback = null;\n\t\t} else {\n\t\t\tthrow new TypeError(`Received unsupported array entry value: ${child}.`);\n\t\t}\n\t}\n\treturn nodeDataToMapTree(childWithFallback, allowedTypes);\n}\n\n/**\n * Transforms data under an Array schema.\n * @param data - The tree data to be transformed. Must be an iterable.\n * @param schema - The schema associated with the value.\n * @param schemaValidationPolicy - The stored schema and policy to be used for validation, if the policy says schema\n * validation should happen. If it does, the input tree will be validated against this schema + policy, and an error will\n * be thrown if the tree does not conform to the schema. If undefined, no validation against the stored schema is done.\n */\nfunction arrayToMapTree(data: FactoryContent, schema: TreeNodeSchema): ExclusiveMapTree {\n\tassert(schema.kind === NodeKind.Array, 0x922 /* Expected an array schema. */);\n\tif (!(typeof data === \"object\" && data !== null && Symbol.iterator in data)) {\n\t\tthrow new UsageError(`Input data is incompatible with Array schema: ${data}`);\n\t}\n\n\tconst allowedChildTypes = normalizeAllowedTypes(schema.info as ImplicitAllowedTypes);\n\n\tconst mappedData = Array.from(data, (child) =>\n\t\tarrayChildToMapTree(child, allowedChildTypes),\n\t);\n\n\t// Array nodes have a single `EmptyKey` field:\n\tconst fieldsEntries = mappedData.length === 0 ? [] : ([[EmptyKey, mappedData]] as const);\n\n\treturn {\n\t\ttype: brand(schema.identifier),\n\t\tfields: new Map(fieldsEntries),\n\t};\n}\n\n/**\n * Transforms data under a Map schema.\n * @param data - The tree data to be transformed. Must be an iterable.\n * @param schema - The schema associated with the value.\n * @param schemaValidationPolicy - The stored schema and policy to be used for validation, if the policy says schema\n * validation should happen. If it does, the input tree will be validated against this schema + policy, and an error will\n * be thrown if the tree does not conform to the schema. If undefined, no validation against the stored schema is done.\n */\nfunction mapToMapTree(data: FactoryContent, schema: TreeNodeSchema): ExclusiveMapTree {\n\tassert(schema.kind === NodeKind.Map, 0x923 /* Expected a Map schema. */);\n\tif (!(typeof data === \"object\" && data !== null)) {\n\t\tthrow new UsageError(`Input data is incompatible with Map schema: ${data}`);\n\t}\n\n\tconst allowedChildTypes = normalizeAllowedTypes(schema.info as ImplicitAllowedTypes);\n\n\tconst fieldsIterator = (\n\t\tSymbol.iterator in data\n\t\t\t? // Support iterables of key value pairs (including Map objects)\n\t\t\t\tdata\n\t\t\t: // Support record objects for JSON style Map data\n\t\t\t\tObject.entries(data)\n\t) as Iterable<readonly [string, InsertableContent]>;\n\n\tconst transformedFields = new Map<FieldKey, ExclusiveMapTree[]>();\n\tfor (const item of fieldsIterator) {\n\t\tif (!isReadonlyArray(item) || item.length !== 2 || typeof item[0] !== \"string\") {\n\t\t\tthrow new UsageError(`Input data is incompatible with map entry: ${item}`);\n\t\t}\n\t\tconst [key, value] = item;\n\t\tassert(!transformedFields.has(brand(key)), 0x84c /* Keys should not be duplicated */);\n\n\t\t// Omit undefined values - an entry with an undefined value is equivalent to one that has been removed or omitted\n\t\tif (value !== undefined) {\n\t\t\tconst mappedField = nodeDataToMapTree(value, allowedChildTypes);\n\t\t\ttransformedFields.set(brand(key), [mappedField]);\n\t\t}\n\t}\n\n\treturn {\n\t\ttype: brand(schema.identifier),\n\t\tfields: transformedFields,\n\t};\n}\n\n/**\n * Transforms data under an Object schema.\n * @param data - The tree data to be transformed. Must be a Record-like object.\n * @param schema - The schema associated with the value.\n */\nfunction objectToMapTree(data: FactoryContent, schema: TreeNodeSchema): ExclusiveMapTree {\n\tassert(isObjectNodeSchema(schema), 0x924 /* Expected an Object schema. */);\n\tif (\n\t\ttypeof data !== \"object\" ||\n\t\tdata === null ||\n\t\tSymbol.iterator in data ||\n\t\tisFluidHandle(data)\n\t) {\n\t\tthrow new UsageError(`Input data is incompatible with Object schema: ${data}`);\n\t}\n\n\tconst fields = new Map<FieldKey, ExclusiveMapTree[]>();\n\n\t// Loop through field keys without data.\n\t// This does NOT apply defaults.\n\tfor (const [key, fieldInfo] of schema.flexKeyMap) {\n\t\tif (checkFieldProperty(data, key)) {\n\t\t\tconst value = (data as Record<string, InsertableContent>)[key as string];\n\t\t\tsetFieldValue(fields, value, fieldInfo.schema, fieldInfo.storedKey);\n\t\t}\n\t}\n\n\treturn {\n\t\ttype: brand(schema.identifier),\n\t\tfields,\n\t};\n}\n\n/**\n * Check {@link FactoryContentObject} for a property which could be store a field.\n * @remarks\n * The currently policy is to only consider own properties.\n * See {@link InsertableObjectFromSchemaRecord} for where this policy is documented in the public API.\n *\n * Explicit undefined members are considered to exist, as long as they are own properties.\n */\nfunction checkFieldProperty(\n\tdata: FactoryContentObject,\n\tkey: string | symbol,\n): data is {\n\treadonly [P in string]: InsertableContent | undefined;\n} {\n\t// This policy only allows own properties.\n\treturn Object.hasOwnProperty.call(data, key);\n}\n\nfunction setFieldValue(\n\tfields: Map<FieldKey, readonly MapTree[]>,\n\tfieldValue: InsertableContent | undefined,\n\tfieldSchema: FieldSchema,\n\tflexKey: FieldKey,\n): void {\n\tif (fieldValue !== undefined) {\n\t\tconst mappedChildTree = nodeDataToMapTree(fieldValue, fieldSchema.allowedTypeSet);\n\n\t\tassert(!fields.has(flexKey), 0x956 /* Keys must not be duplicated */);\n\t\tfields.set(flexKey, [mappedChildTree]);\n\t}\n}\n\nfunction getType(\n\tdata: FactoryContent,\n\tallowedTypes: ReadonlySet<TreeNodeSchema>,\n): TreeNodeSchema {\n\tconst possibleTypes = getPossibleTypes(allowedTypes, data);\n\tif (possibleTypes.length === 0) {\n\t\tthrow new UsageError(\n\t\t\t`The provided data is incompatible with all of the types allowed by the schema. The set of allowed types is: ${JSON.stringify(\n\t\t\t\t[...allowedTypes].map((schema) => schema.identifier),\n\t\t\t)}.`,\n\t\t);\n\t}\n\tassert(\n\t\tpossibleTypes.length !== 0,\n\t\t0x84e /* data is incompatible with all types allowed by the schema */,\n\t);\n\tif (possibleTypes.length !== 1) {\n\t\tthrow new UsageError(\n\t\t\t`The provided data is compatible with more than one type allowed by the schema.\nThe set of possible types is ${JSON.stringify([\n\t\t\t\t...possibleTypes.map((schema) => schema.identifier),\n\t\t\t])}.\nExplicitly construct an unhydrated node of the desired type to disambiguate.\nFor class-based schema, this can be done by replacing an expression like \"{foo: 1}\" with \"new MySchema({foo: 1})\".`,\n\t\t);\n\t}\n\treturn possibleTypes[0] ?? oob();\n}\n\n/**\n * @returns all types for which the data is schema-compatible.\n */\nexport function getPossibleTypes(\n\tallowedTypes: ReadonlySet<TreeNodeSchema>,\n\tdata: FactoryContent,\n): TreeNodeSchema[] {\n\tlet best = CompatibilityLevel.None;\n\tconst possibleTypes: TreeNodeSchema[] = [];\n\tfor (const schema of allowedTypes) {\n\t\tconst level = shallowCompatibilityTest(schema, data);\n\t\tif (level > best) {\n\t\t\tpossibleTypes.length = 0;\n\t\t\tbest = level;\n\t\t}\n\t\tif (best === level) {\n\t\t\tpossibleTypes.push(schema);\n\t\t}\n\t}\n\treturn best === CompatibilityLevel.None ? [] : possibleTypes;\n}\n\n/**\n * Indicates a compatibility level for inferring a schema to apply to insertable data.\n * @remarks\n * Only the highest compatibility options are used.\n * This approach allows adding new possible matching at a new lower compatibility level as a non breaking change,\n * since that way they can't make a case that was compatible before ambiguous now.\n */\nenum CompatibilityLevel {\n\t/**\n\t * Not compatible. Constructor typing indicates incompatibility.\n\t */\n\tNone = 0,\n\t/**\n\t * Additional compatibility cases added in Fluid Framework 2.2.\n\t */\n\tLow = 1,\n\t/**\n\t * Compatible in Fluid Framework 2.0.\n\t */\n\tNormal = 2,\n}\n\n/**\n * Checks if data might be schema-compatible.\n *\n * @returns false if `data` is incompatible with `type` based on a cheap/shallow check.\n *\n * Note that this may return true for cases where data is incompatible, but it must not return false in cases where the data is compatible.\n */\nfunction shallowCompatibilityTest(\n\tschema: TreeNodeSchema,\n\tdata: FactoryContent,\n): CompatibilityLevel {\n\tassert(data !== undefined, 0x889 /* undefined cannot be used as FactoryContent. */);\n\n\tif (isTreeValue(data)) {\n\t\treturn allowsValue(schema, data) ? CompatibilityLevel.Normal : CompatibilityLevel.None;\n\t}\n\tif (schema.kind === NodeKind.Leaf) {\n\t\treturn CompatibilityLevel.None;\n\t}\n\n\t// Typing (of schema based constructors and thus implicit node construction)\n\t// allows iterables for constructing maps and arrays.\n\t// Some users of this API may have unions of maps and arrays,\n\t// and rely on Arrays ending up as array nodes and maps as Map nodes,\n\t// despite both being iterable and thus compatible with both.\n\t// This uses a priority based system where an array would be parsed as an array when unioned with a map,\n\t// but if in a map only context, could still be used as a map.\n\n\tif (data instanceof Map) {\n\t\tswitch (schema.kind) {\n\t\t\tcase NodeKind.Map:\n\t\t\t\treturn CompatibilityLevel.Normal;\n\t\t\tcase NodeKind.Array:\n\t\t\t\t// Maps are iterable, so type checking does allow constructing an ArrayNode from a map if the array's type is an array that includes the key and value types of the map.\n\t\t\t\treturn CompatibilityLevel.Low;\n\t\t\tdefault:\n\t\t\t\treturn CompatibilityLevel.None;\n\t\t}\n\t}\n\n\tif (isReadonlyArray(data)) {\n\t\tswitch (schema.kind) {\n\t\t\tcase NodeKind.Array:\n\t\t\t\treturn CompatibilityLevel.Normal;\n\t\t\tcase NodeKind.Map:\n\t\t\t\t// Arrays are iterable, so type checking does allow constructing an array from a MapNode from an if the array's type is key values pairs for the map.\n\t\t\t\treturn CompatibilityLevel.Low;\n\t\t\tdefault:\n\t\t\t\treturn CompatibilityLevel.None;\n\t\t}\n\t}\n\n\tconst mapOrArray = schema.kind === NodeKind.Array || schema.kind === NodeKind.Map;\n\n\tif (Symbol.iterator in data) {\n\t\treturn mapOrArray ? CompatibilityLevel.Normal : CompatibilityLevel.None;\n\t}\n\n\t// At this point, it is assumed data is a record-like object since all the other cases have been eliminated.\n\n\tif (schema.kind === NodeKind.Array) {\n\t\treturn CompatibilityLevel.None;\n\t}\n\n\tif (schema.kind === NodeKind.Map) {\n\t\t// When not unioned with an ObjectNode, allow objects to be used to create maps.\n\t\treturn CompatibilityLevel.Low;\n\t}\n\n\tassert(isObjectNodeSchema(schema), 0x9e6 /* unexpected schema kind */);\n\n\t// TODO: Improve type inference by making this logic more thorough. Handle at least:\n\t// * Types which are strict subsets of other types in the same polymorphic union\n\t// * Types which have the same keys but different types for those keys in the polymorphic union\n\t// * Types which have the same required fields but different optional fields and enough of those optional fields are populated to disambiguate\n\n\t// TODO#7441: Consider allowing data to be inserted which has keys that are extraneous/unknown to the schema (those keys are ignored)\n\n\t// If the schema has a required key which is not present in the input object, reject it.\n\tfor (const [fieldKey, fieldSchema] of schema.fields) {\n\t\tif (fieldSchema.requiresValue) {\n\t\t\tif (checkFieldProperty(data, fieldKey)) {\n\t\t\t\tif (data[fieldKey] === undefined) {\n\t\t\t\t\treturn CompatibilityLevel.None;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn CompatibilityLevel.None;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn CompatibilityLevel.Normal;\n}\n\nfunction allowsValue(schema: TreeNodeSchema, value: TreeValue): boolean {\n\tif (schema.kind === NodeKind.Leaf) {\n\t\treturn valueSchemaAllows(schema.info as ValueSchema, value);\n\t}\n\treturn false;\n}\n\n/**\n * Walk the given {@link ExclusiveMapTree} and deeply provide any field defaults for fields that are missing in the tree but present in the schema.\n * @param mapTree - The tree to populate with defaults. This is borrowed: no references to it are kept by this function.\n * @param allowedTypes - Some {@link TreeNodeSchema}, at least one of which the input tree must conform to\n * @param context - An optional context for generating defaults.\n * If present, all applicable defaults will be provided.\n * If absent, only defaults produced by a {@link ConstantFieldProvider} will be provided, and defaults produced by a {@link ContextualFieldProvider} will be ignored.\n * @remarks This function mutates the input tree by deeply adding new fields to the field maps where applicable.\n */\nexport function addDefaultsToMapTree(\n\tmapTree: ExclusiveMapTree,\n\tallowedTypes: ImplicitAllowedTypes,\n\tcontext: NodeKeyManager | undefined,\n): void {\n\tconst schema =\n\t\tfind(normalizeAllowedTypes(allowedTypes), (s) => s.identifier === mapTree.type) ??\n\t\tfail(\"MapTree is incompatible with schema\");\n\n\tif (isObjectNodeSchema(schema)) {\n\t\tfor (const [_key, fieldInfo] of schema.flexKeyMap) {\n\t\t\tconst field = mapTree.fields.get(fieldInfo.storedKey);\n\t\t\tif (field !== undefined) {\n\t\t\t\tfor (const child of field) {\n\t\t\t\t\taddDefaultsToMapTree(child, fieldInfo.schema.allowedTypes, context);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst defaultProvider = fieldInfo.schema.props?.defaultProvider;\n\t\t\t\tif (defaultProvider !== undefined) {\n\t\t\t\t\tconst fieldProvider = extractFieldProvider(defaultProvider);\n\t\t\t\t\tconst data = provideDefault(fieldProvider, context);\n\t\t\t\t\tif (data !== undefined) {\n\t\t\t\t\t\tsetFieldValue(mapTree.fields, data, fieldInfo.schema, fieldInfo.storedKey);\n\t\t\t\t\t\t// call addDefaultsToMapTree on newly inserted default values\n\t\t\t\t\t\tfor (const child of mapTree.fields.get(fieldInfo.storedKey) ??\n\t\t\t\t\t\t\tfail(\"Expected field to be populated\")) {\n\t\t\t\t\t\t\taddDefaultsToMapTree(child, fieldInfo.schema.allowedTypes, context);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn;\n\t}\n\n\tswitch (schema.kind) {\n\t\tcase NodeKind.Array:\n\t\tcase NodeKind.Map:\n\t\t\t{\n\t\t\t\tfor (const field of mapTree.fields.values()) {\n\t\t\t\t\tfor (const child of field) {\n\t\t\t\t\t\taddDefaultsToMapTree(child, schema.info as ImplicitAllowedTypes, context);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tassert(schema.kind === NodeKind.Leaf, 0x989 /* Unrecognized schema kind */);\n\t\t\tbreak;\n\t}\n}\n\n/**\n * Provides the default value (which can be undefined, for example with optional fields), or undefined if a context is required but not provided.\n * @privateRemarks\n * It is a bit concerning that there is no way for the caller to know when undefined is returned if that is the default value, or a context was required.\n * TODO: maybe better formalize the two stage defaulting (without then with context), or rework this design we only do one stage.\n */\nfunction provideDefault(\n\tfieldProvider: FieldProvider,\n\tcontext: NodeKeyManager | undefined,\n): InsertableContent | undefined {\n\tif (context !== undefined) {\n\t\treturn fieldProvider(context);\n\t} else {\n\t\tif (isConstant(fieldProvider)) {\n\t\t\treturn fieldProvider();\n\t\t} else {\n\t\t\t// Leaving field empty despite it needing a default value since a context was required and none was provided.\n\t\t\t// Caller better handle this case by providing the default at some other point in time when the context becomes known.\n\t\t}\n\t}\n}\n\n/**\n * Retrieves the InnerNode associated with the given target via {@link setInnerNode}, if any.\n * @remarks\n * If `target` is a unhydrated node, returns its MapTreeNode.\n * If `target` is a cooked node (or marinated but a FlexTreeNode exists) returns the FlexTreeNode.\n * If the target is not a node, or a marinated node with no FlexTreeNode for its anchor, returns undefined.\n */\nfunction tryGetInnerNode(target: unknown): InnerNode | undefined {\n\tif (isTreeNode(target)) {\n\t\treturn getKernel(target).tryGetInnerNode();\n\t}\n}\n\n/**\n * Content which can be used to build a node.\n * @remarks\n * Can contain unhydrated nodes, but can not be an unhydrated node at the root.\n * @system @alpha\n */\nexport type FactoryContent =\n\t| IFluidHandle\n\t| string\n\t| number\n\t| boolean\n\t// eslint-disable-next-line @rushstack/no-new-null\n\t| null\n\t| Iterable<readonly [string, InsertableContent]>\n\t| readonly InsertableContent[]\n\t| FactoryContentObject;\n\n/**\n * Record-like object which can be used to build some kinds of nodes.\n * @remarks\n * Can contain unhydrated nodes, but can not be an unhydrated node at the root.\n *\n * Supports object and map nodes.\n * @system @alpha\n */\nexport type FactoryContentObject = {\n\treadonly [P in string]?: InsertableContent;\n};\n\n/**\n * Content which can be inserted into a tree.\n * @system @alpha\n */\nexport type InsertableContent = Unhydrated<TreeNode> | FactoryContent;\n"]}
|
|
1
|
+
{"version":3,"file":"toMapTree.js","sourceRoot":"","sources":["../../src/simple-tree/toMapTree.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,kEAAkE;AAClE,uEAAsE;AACtE,qEAAuE;AAEvE,+CAQ0B;AAC1B,4DAIuC;AACvC,+CAAsE;AAEtE,2DAAiD;AACjD,qDAW0B;AAC1B,8CAUyB;AACzB,4DAAuF;AACvF,6DAA0D;AAiE1D,SAAgB,mBAAmB,CAClC,IAAmC,EACnC,YAAiC,EACjC,OAAwB,EACxB,sBAAwC;IAExC,MAAM,qBAAqB,GAAG,IAAA,qCAAoB,EAAC,YAAY,CAAC,CAAC;IAEjE,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACxB,+CAA+C;QAC/C,IAAI,qBAAqB,CAAC,IAAI,KAAK,0BAAS,CAAC,QAAQ,EAAE,CAAC;YACvD,MAAM,IAAI,qBAAU,CAAC,uCAAuC,CAAC,CAAC;QAC/D,CAAC;QACD,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,EAAE,qBAAqB,CAAC,cAAc,CAAC,CAAC;IAC9E,uGAAuG;IACvG,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAE3E,IAAI,sBAAsB,EAAE,MAAM,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;QAC5D,qBAAqB;QACrB,4IAA4I;QAC5I,wDAAwD;QACxD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC3B,MAAM,UAAU,GAAG,IAAA,yBAAc,EAAC,OAAO,EAAE,sBAAsB,CAAC,CAAC;YACnE,eAAe,CAAC,UAAU,CAAC,CAAC;QAC7B,CAAC;IACF,CAAC;IAED,OAAO,OAAO,CAAC;AAChB,CAAC;AA/BD,kDA+BC;AAED;;;;;;GAMG;AACH,SAAS,iBAAiB,CACzB,IAAuB,EACvB,YAAyC;IAEzC,wDAAwD;IACxD,sEAAsE;IACtE,MAAM,SAAS,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC7B,IAAI,SAAS,YAAY,iCAAsB,EAAE,CAAC;YACjD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAA,2CAAgC,EAAC,SAAS,CAAC,CAAC,EAAE,CAAC;gBACpE,MAAM,IAAI,qBAAU,CAAC,kCAAkC,CAAC,CAAC;YAC1D,CAAC;YACD,wEAAwE;YACxE,kGAAkG;YAClG,2HAA2H;YAC3H,iJAAiJ;YACjJ,qGAAqG;YACrG,OAAO,SAAS,CAAC,OAAO,CAAC;QAC1B,CAAC;aAAM,CAAC;YACP,8FAA8F;YAC9F,MAAM,IAAI,qBAAU,CAAC,yDAAyD,CAAC,CAAC;QACjF,CAAC;IACF,CAAC;IAED,IAAA,iBAAM,EAAC,CAAC,IAAA,qBAAU,EAAC,IAAI,CAAC,EAAE,KAAK,CAAC,mDAAmD,CAAC,CAAC;IAErF,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAE3C,IAAI,MAAwB,CAAC;IAC7B,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACrB,KAAK,mBAAQ,CAAC,IAAI;YACjB,MAAM,GAAG,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;YACnD,MAAM;QACP,KAAK,mBAAQ,CAAC,KAAK;YAClB,MAAM,GAAG,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACtC,MAAM;QACP,KAAK,mBAAQ,CAAC,GAAG;YAChB,MAAM,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACpC,MAAM;QACP,KAAK,mBAAQ,CAAC,MAAM;YACnB,MAAM,GAAG,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACvC,MAAM;QACP;YACC,IAAA,eAAI,EAAC,6BAA6B,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC;IACpD,CAAC;IAED,OAAO,MAAM,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAgB,eAAe,CAAC,UAAkC;IACjE,IAAI,UAAU,2CAAmC,EAAE,CAAC;QACnD,MAAM,IAAI,qBAAU,CAAC,kCAAkC,CAAC,CAAC;IAC1D,CAAC;AACF,CAAC;AAJD,0CAIC;AAED;;;;;;GAMG;AACH,SAAS,aAAa,CACrB,IAAoB,EACpB,MAAsB,EACtB,YAAyC;IAEzC,IAAA,iBAAM,EAAC,MAAM,CAAC,IAAI,KAAK,mBAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,6BAA6B,CAAC,CAAC;IAC3E,IAAI,CAAC,IAAA,sBAAW,EAAC,IAAI,CAAC,EAAE,CAAC;QACxB,wFAAwF;QACxF,6GAA6G;QAC7G,gEAAgE;QAChE,MAAM,IAAI,qBAAU,CAAC,gDAAgD,IAAI,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED,MAAM,WAAW,GAAG,qBAAqB,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAC9D,MAAM,YAAY,GAAG,OAAO,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAExD,IAAA,iBAAM,EACL,WAAW,CAAC,YAAY,EAAE,WAAW,CAAC,EACtC,KAAK,CAAC,gDAAgD,CACtD,CAAC;IAEF,OAAO;QACN,KAAK,EAAE,WAAW;QAClB,IAAI,EAAE,IAAA,gBAAK,EAAC,YAAY,CAAC,UAAU,CAAC;QACpC,MAAM,EAAE,IAAI,GAAG,EAAE;KACjB,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAS,qBAAqB,CAC7B,KAAoB,EACpB,YAAyC;IAEzC,QAAQ,OAAO,KAAK,EAAE,CAAC;QACtB,KAAK,QAAQ,CAAC,CAAC,CAAC;YACf,IAAI,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC1B,kDAAkD;gBAClD,wBAAwB;gBACxB,OAAO,CAAC,CAAC;YACV,CAAC;iBAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBACpC,4DAA4D;gBAC5D,sEAAsE;gBACtE,6DAA6D;gBAC7D,IAAI,YAAY,CAAC,GAAG,CAAC,8BAAU,CAAC,EAAE,CAAC;oBAClC,OAAO,IAAI,CAAC;gBACb,CAAC;qBAAM,CAAC;oBACP,MAAM,IAAI,qBAAU,CAAC,uCAAuC,KAAK,GAAG,CAAC,CAAC;gBACvE,CAAC;YACF,CAAC;iBAAM,CAAC;gBACP,OAAO,KAAK,CAAC;YACd,CAAC;QACF,CAAC;QACD,KAAK,QAAQ,CAAC;QACd,QAAQ;QACR,uHAAuH;QACvH,wCAAwC;QACxC,KAAK,SAAS;YACb,OAAO,KAAK,CAAC;QACd,KAAK,QAAQ,CAAC,CAAC,CAAC;YACf,IAAI,KAAK,KAAK,IAAI,IAAI,IAAA,wBAAa,EAAC,KAAK,CAAC,EAAE,CAAC;gBAC5C,OAAO,KAAK,CAAC;YACd,CAAC;QACF,CAAC;QACD;YACC,MAAM,IAAI,qBAAU,CAAC,oCAAoC,KAAK,GAAG,CAAC,CAAC;IACrE,CAAC;AACF,CAAC;AAED;;;;GAIG;AACH,SAAS,mBAAmB,CAC3B,KAAwB,EACxB,YAAyC;IAEzC,gDAAgD;IAChD,oGAAoG;IACpG,IAAI,iBAAiB,GAAG,KAAK,CAAC;IAC9B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACzB,IAAI,YAAY,CAAC,GAAG,CAAC,8BAAU,CAAC,EAAE,CAAC;YAClC,iBAAiB,GAAG,IAAI,CAAC;QAC1B,CAAC;aAAM,CAAC;YACP,MAAM,IAAI,SAAS,CAAC,2CAA2C,KAAK,GAAG,CAAC,CAAC;QAC1E,CAAC;IACF,CAAC;IACD,OAAO,iBAAiB,CAAC,iBAAiB,EAAE,YAAY,CAAC,CAAC;AAC3D,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,cAAc,CAAC,IAAoB,EAAE,MAAsB;IACnE,IAAA,iBAAM,EAAC,MAAM,CAAC,IAAI,KAAK,mBAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,+BAA+B,CAAC,CAAC;IAC9E,IAAI,CAAC,CAAC,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,MAAM,CAAC,QAAQ,IAAI,IAAI,CAAC,EAAE,CAAC;QAC7E,MAAM,IAAI,qBAAU,CAAC,iDAAiD,IAAI,EAAE,CAAC,CAAC;IAC/E,CAAC;IAED,MAAM,iBAAiB,GAAG,IAAA,sCAAqB,EAAC,MAAM,CAAC,IAA4B,CAAC,CAAC;IAErF,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CAC7C,mBAAmB,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAC7C,CAAC;IAEF,8CAA8C;IAC9C,MAAM,aAAa,GAAG,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAE,CAAC,CAAC,mBAAQ,EAAE,UAAU,CAAC,CAAW,CAAC;IAEzF,OAAO;QACN,IAAI,EAAE,IAAA,gBAAK,EAAC,MAAM,CAAC,UAAU,CAAC;QAC9B,MAAM,EAAE,IAAI,GAAG,CAAC,aAAa,CAAC;KAC9B,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,YAAY,CAAC,IAAoB,EAAE,MAAsB;IACjE,IAAA,iBAAM,EAAC,MAAM,CAAC,IAAI,KAAK,mBAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,4BAA4B,CAAC,CAAC;IACzE,IAAI,CAAC,CAAC,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,qBAAU,CAAC,+CAA+C,IAAI,EAAE,CAAC,CAAC;IAC7E,CAAC;IAED,MAAM,iBAAiB,GAAG,IAAA,sCAAqB,EAAC,MAAM,CAAC,IAA4B,CAAC,CAAC;IAErF,MAAM,cAAc,GAAG,CACtB,MAAM,CAAC,QAAQ,IAAI,IAAI;QACtB,CAAC,CAAC,+DAA+D;YAChE,IAAI;QACL,CAAC,CAAC,iDAAiD;YAClD,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAC4B,CAAC;IAEpD,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAgC,CAAC;IAClE,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE,CAAC;QACnC,IAAI,CAAC,IAAA,0BAAe,EAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;YAChF,MAAM,IAAI,qBAAU,CAAC,8CAA8C,IAAI,EAAE,CAAC,CAAC;QAC5E,CAAC;QACD,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,IAAI,CAAC;QAC1B,IAAA,iBAAM,EAAC,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAA,gBAAK,EAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,mCAAmC,CAAC,CAAC;QAEtF,iHAAiH;QACjH,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACzB,MAAM,WAAW,GAAG,iBAAiB,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC;YAChE,iBAAiB,CAAC,GAAG,CAAC,IAAA,gBAAK,EAAC,GAAG,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;QAClD,CAAC;IACF,CAAC;IAED,OAAO;QACN,IAAI,EAAE,IAAA,gBAAK,EAAC,MAAM,CAAC,UAAU,CAAC;QAC9B,MAAM,EAAE,iBAAiB;KACzB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,eAAe,CAAC,IAAoB,EAAE,MAAsB;IACpE,IAAA,iBAAM,EAAC,IAAA,uCAAkB,EAAC,MAAM,CAAC,EAAE,KAAK,CAAC,gCAAgC,CAAC,CAAC;IAC3E,IACC,OAAO,IAAI,KAAK,QAAQ;QACxB,IAAI,KAAK,IAAI;QACb,MAAM,CAAC,QAAQ,IAAI,IAAI;QACvB,IAAA,wBAAa,EAAC,IAAI,CAAC,EAClB,CAAC;QACF,MAAM,IAAI,qBAAU,CAAC,kDAAkD,IAAI,EAAE,CAAC,CAAC;IAChF,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,GAAG,EAAgC,CAAC;IAEvD,wCAAwC;IACxC,gCAAgC;IAChC,KAAK,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QAClD,IAAI,kBAAkB,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;YACnC,MAAM,KAAK,GAAI,IAA0C,CAAC,GAAa,CAAC,CAAC;YACzE,aAAa,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;QACrE,CAAC;IACF,CAAC;IAED,OAAO;QACN,IAAI,EAAE,IAAA,gBAAK,EAAC,MAAM,CAAC,UAAU,CAAC;QAC9B,MAAM;KACN,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,kBAAkB,CAC1B,IAA0B,EAC1B,GAAoB;IAIpB,0CAA0C;IAC1C,OAAO,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AAC9C,CAAC;AAED,SAAS,aAAa,CACrB,MAAyC,EACzC,UAAyC,EACzC,WAAwB,EACxB,OAAiB;IAEjB,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC9B,MAAM,eAAe,GAAG,iBAAiB,CAAC,UAAU,EAAE,WAAW,CAAC,cAAc,CAAC,CAAC;QAElF,IAAA,iBAAM,EAAC,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACtE,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC;IACxC,CAAC;AACF,CAAC;AAED,SAAS,OAAO,CACf,IAAoB,EACpB,YAAyC;IAEzC,MAAM,aAAa,GAAG,gBAAgB,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;IAC3D,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,qBAAU,CACnB,+GAA+G,IAAI,CAAC,SAAS,CAC5H,CAAC,GAAG,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CACpD,GAAG,CACJ,CAAC;IACH,CAAC;IACD,IAAA,iBAAM,EACL,aAAa,CAAC,MAAM,KAAK,CAAC,EAC1B,KAAK,CAAC,+DAA+D,CACrE,CAAC;IACF,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,qBAAU,CACnB;+BAC4B,IAAI,CAAC,SAAS,CAAC;YAC1C,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC;SACnD,CAAC;;mHAE8G,CAChH,CAAC;IACH,CAAC;IACD,OAAO,aAAa,CAAC,CAAC,CAAC,IAAI,IAAA,cAAG,GAAE,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,SAAgB,gBAAgB,CAC/B,YAAyC,EACzC,IAAoB;IAEpB,IAAI,IAAI,GAAG,kBAAkB,CAAC,IAAI,CAAC;IACnC,MAAM,aAAa,GAAqB,EAAE,CAAC;IAC3C,KAAK,MAAM,MAAM,IAAI,YAAY,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,wBAAwB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACrD,IAAI,KAAK,GAAG,IAAI,EAAE,CAAC;YAClB,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC;YACzB,IAAI,GAAG,KAAK,CAAC;QACd,CAAC;QACD,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;YACpB,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC5B,CAAC;IACF,CAAC;IACD,OAAO,IAAI,KAAK,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC;AAC9D,CAAC;AAjBD,4CAiBC;AAED;;;;;;GAMG;AACH,IAAK,kBAaJ;AAbD,WAAK,kBAAkB;IACtB;;OAEG;IACH,2DAAQ,CAAA;IACR;;OAEG;IACH,yDAAO,CAAA;IACP;;OAEG;IACH,+DAAU,CAAA;AACX,CAAC,EAbI,kBAAkB,KAAlB,kBAAkB,QAatB;AAED;;;;;;GAMG;AACH,SAAS,wBAAwB,CAChC,MAAsB,EACtB,IAAoB;IAEpB,IAAA,iBAAM,EAAC,IAAI,KAAK,SAAS,EAAE,KAAK,CAAC,iDAAiD,CAAC,CAAC;IAEpF,IAAI,IAAA,sBAAW,EAAC,IAAI,CAAC,EAAE,CAAC;QACvB,OAAO,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC;IACxF,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,mBAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,OAAO,kBAAkB,CAAC,IAAI,CAAC;IAChC,CAAC;IAED,4EAA4E;IAC5E,qDAAqD;IACrD,6DAA6D;IAC7D,qEAAqE;IACrE,6DAA6D;IAC7D,wGAAwG;IACxG,8DAA8D;IAE9D,IAAI,IAAI,YAAY,GAAG,EAAE,CAAC;QACzB,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;YACrB,KAAK,mBAAQ,CAAC,GAAG;gBAChB,OAAO,kBAAkB,CAAC,MAAM,CAAC;YAClC,KAAK,mBAAQ,CAAC,KAAK;gBAClB,wKAAwK;gBACxK,OAAO,kBAAkB,CAAC,GAAG,CAAC;YAC/B;gBACC,OAAO,kBAAkB,CAAC,IAAI,CAAC;QACjC,CAAC;IACF,CAAC;IAED,IAAI,IAAA,0BAAe,EAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;YACrB,KAAK,mBAAQ,CAAC,KAAK;gBAClB,OAAO,kBAAkB,CAAC,MAAM,CAAC;YAClC,KAAK,mBAAQ,CAAC,GAAG;gBAChB,qJAAqJ;gBACrJ,OAAO,kBAAkB,CAAC,GAAG,CAAC;YAC/B;gBACC,OAAO,kBAAkB,CAAC,IAAI,CAAC;QACjC,CAAC;IACF,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,KAAK,mBAAQ,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,KAAK,mBAAQ,CAAC,GAAG,CAAC;IAElF,IAAI,MAAM,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC;QAC7B,OAAO,UAAU,CAAC,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC;IACzE,CAAC;IAED,4GAA4G;IAE5G,IAAI,MAAM,CAAC,IAAI,KAAK,mBAAQ,CAAC,KAAK,EAAE,CAAC;QACpC,OAAO,kBAAkB,CAAC,IAAI,CAAC;IAChC,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,KAAK,mBAAQ,CAAC,GAAG,EAAE,CAAC;QAClC,gFAAgF;QAChF,OAAO,kBAAkB,CAAC,GAAG,CAAC;IAC/B,CAAC;IAED,IAAA,iBAAM,EAAC,IAAA,uCAAkB,EAAC,MAAM,CAAC,EAAE,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAEvE,oFAAoF;IACpF,gFAAgF;IAChF,+FAA+F;IAC/F,8IAA8I;IAE9I,qIAAqI;IAErI,wFAAwF;IACxF,KAAK,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QACrD,IAAI,WAAW,CAAC,aAAa,EAAE,CAAC;YAC/B,IAAI,kBAAkB,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,CAAC;gBACxC,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,SAAS,EAAE,CAAC;oBAClC,OAAO,kBAAkB,CAAC,IAAI,CAAC;gBAChC,CAAC;YACF,CAAC;iBAAM,CAAC;gBACP,OAAO,kBAAkB,CAAC,IAAI,CAAC;YAChC,CAAC;QACF,CAAC;IACF,CAAC;IAED,OAAO,kBAAkB,CAAC,MAAM,CAAC;AAClC,CAAC;AAED,SAAS,WAAW,CAAC,MAAsB,EAAE,KAAgB;IAC5D,IAAI,MAAM,CAAC,IAAI,KAAK,mBAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,OAAO,IAAA,4BAAiB,EAAC,MAAM,CAAC,IAAmB,EAAE,KAAK,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,oBAAoB,CACnC,OAAyB,EACzB,YAAkC,EAClC,OAAmC;IAEnC,MAAM,MAAM,GACX,IAAA,eAAI,EAAC,IAAA,sCAAqB,EAAC,YAAY,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC;QAC/E,IAAA,eAAI,EAAC,qCAAqC,CAAC,CAAC;IAE7C,IAAI,IAAA,uCAAkB,EAAC,MAAM,CAAC,EAAE,CAAC;QAChC,KAAK,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACnD,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;YACtD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACzB,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;oBAC3B,oBAAoB,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;gBACrE,CAAC;YACF,CAAC;iBAAM,CAAC;gBACP,MAAM,eAAe,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,eAAe,CAAC;gBAChE,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;oBACnC,MAAM,aAAa,GAAG,IAAA,qCAAoB,EAAC,eAAe,CAAC,CAAC;oBAC5D,MAAM,IAAI,GAAG,cAAc,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;oBACpD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;wBACxB,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;wBAC3E,6DAA6D;wBAC7D,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC;4BAC1D,IAAA,eAAI,EAAC,gCAAgC,CAAC,EAAE,CAAC;4BACzC,oBAAoB,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;wBACrE,CAAC;oBACF,CAAC;gBACF,CAAC;YACF,CAAC;QACF,CAAC;QACD,OAAO;IACR,CAAC;IAED,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACrB,KAAK,mBAAQ,CAAC,KAAK,CAAC;QACpB,KAAK,mBAAQ,CAAC,GAAG;YAChB,CAAC;gBACA,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;oBAC7C,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;wBAC3B,oBAAoB,CAAC,KAAK,EAAE,MAAM,CAAC,IAA4B,EAAE,OAAO,CAAC,CAAC;oBAC3E,CAAC;gBACF,CAAC;YACF,CAAC;YACD,MAAM;QACP;YACC,IAAA,iBAAM,EAAC,MAAM,CAAC,IAAI,KAAK,mBAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,8BAA8B,CAAC,CAAC;YAC5E,MAAM;IACR,CAAC;AACF,CAAC;AAlDD,oDAkDC;AAED;;;;;GAKG;AACH,SAAS,cAAc,CACtB,aAA4B,EAC5B,OAAmC;IAEnC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,aAAa,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;SAAM,CAAC;QACP,IAAI,IAAA,2BAAU,EAAC,aAAa,CAAC,EAAE,CAAC;YAC/B,OAAO,aAAa,EAAE,CAAC;QACxB,CAAC;aAAM,CAAC;YACP,6GAA6G;YAC7G,sHAAsH;QACvH,CAAC;IACF,CAAC;AACF,CAAC;AAED;;;;;;GAMG;AACH,SAAS,eAAe,CAAC,MAAe;IACvC,IAAI,IAAA,qBAAU,EAAC,MAAM,CAAC,EAAE,CAAC;QACxB,OAAO,IAAA,oBAAS,EAAC,MAAM,CAAC,CAAC,eAAe,EAAE,CAAC;IAC5C,CAAC;AACF,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, oob } from \"@fluidframework/core-utils/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\nimport { isFluidHandle } from \"@fluidframework/runtime-utils/internal\";\n\nimport {\n\tEmptyKey,\n\ttype FieldKey,\n\ttype MapTree,\n\ttype TreeValue,\n\ttype ValueSchema,\n\ttype SchemaAndPolicy,\n\ttype ExclusiveMapTree,\n} from \"../core/index.js\";\nimport {\n\tisTreeValue,\n\tvalueSchemaAllows,\n\ttype NodeKeyManager,\n} from \"../feature-libraries/index.js\";\nimport { brand, fail, isReadonlyArray, find } from \"../util/index.js\";\n\nimport { nullSchema } from \"./leafNodeSchema.js\";\nimport {\n\ttype FieldSchema,\n\ttype ImplicitAllowedTypes,\n\tnormalizeAllowedTypes,\n\textractFieldProvider,\n\tisConstant,\n\ttype FieldProvider,\n\ttype ImplicitFieldSchema,\n\tnormalizeFieldSchema,\n\tFieldKind,\n\ttype TreeLeafValue,\n} from \"./schemaTypes.js\";\nimport {\n\tgetKernel,\n\tgetSimpleNodeSchemaFromInnerNode,\n\tisTreeNode,\n\tNodeKind,\n\ttype InnerNode,\n\ttype TreeNode,\n\ttype TreeNodeSchema,\n\ttype Unhydrated,\n\tUnhydratedFlexTreeNode,\n} from \"./core/index.js\";\nimport { SchemaValidationErrors, isNodeInSchema } from \"../feature-libraries/index.js\";\nimport { isObjectNodeSchema } from \"./objectNodeTypes.js\";\nimport type { IFluidHandle } from \"@fluidframework/core-interfaces\";\n\n/**\n * Module notes:\n *\n * The flow of the below code is in terms of the structure of the input data. We then verify that the associated\n * schema is appropriate for that kind of data. This is fine while we have a 1:1 mapping of kind of input data to\n * the kind of schema we expect for it (e.g. an input that is an array always need to be associated with a sequence in\n * the schema). If/when we begin accepting kinds of input data that are ambiguous (e.g. accepting an input that is an\n * array of key/value tuples to instantiate a map) we may need to rethink the structure here to be based more on the\n * schema than on the input data.\n */\n\n/**\n * Transforms an input {@link TypedNode} tree to a {@link MapTree}.\n * @param data - The input tree to be converted.\n * If the data is an unsupported value (e.g. NaN), a fallback value will be used when supported,\n * otherwise an error will be thrown.\n *\n * Fallbacks:\n *\n * * `NaN` =\\> `null`\n *\n * * `+/-∞` =\\> `null`\n *\n * * `-0` =\\> `+0`\n *\n * For fields with a default value, the field may be omitted.\n * If `context` is not provided, defaults which require a context will be left empty which can be out of schema.\n *\n * @param allowedTypes - The set of types allowed by the parent context. Used to validate the input tree.\n * @param context - An optional context which, if present, will allow defaults to be created by {@link ContextualFieldProvider}s.\n * If absent, only defaults from {@link ConstantFieldProvider}s will be created.\n * @param schemaValidationPolicy - The stored schema and policy to be used for validation, if the policy says schema\n * validation should happen. If it does, the input tree will be validated against this schema + policy, and an error will\n * be thrown if the tree does not conform to the schema. If undefined, no validation against the stored schema is done.\n *\n * TODO:BUG: AB#9131\n * This schema validation is done before defaults are provided.\n * This can not easily be fixed by reordering things within this implementation since even at the end of this function defaults requiring a context may not have been filled.\n * This means schema validation reject required fields getting their value from a default like identifier fields.\n *\n * @remarks The resulting tree will be populated with any defaults from {@link FieldProvider}s in the schema.\n *\n * @privateRemarks\n * TODO: AB#9126 AB#9131\n * When an app wants schema validation, we should ensure data is validated. Doing the validation here is not robust (since many callers to this don't have a context and thus can't opt into validation).\n * Additionally the validation here does not correctly handle default values, and introduces a second schema representation which is a bit odd API wise as its typically derivable from the view schema.\n * It may make more sense to validate when hydrating the MapTreeNode when the context is known and the defaults are available.\n * Applying the \"parse don't validate\" idiom here could help ensuring we capture when the validation optionally happens in the type system to avoid missing or redundant validation,\n * as well as ensuring validation happens after defaulting (or can handle validating data missing defaults)\n */\nexport function mapTreeFromNodeData(\n\tdata: InsertableContent,\n\tallowedTypes: ImplicitAllowedTypes,\n\tcontext?: NodeKeyManager,\n\tschemaValidationPolicy?: SchemaAndPolicy,\n): ExclusiveMapTree;\nexport function mapTreeFromNodeData(\n\tdata: InsertableContent | undefined,\n\tallowedTypes: ImplicitFieldSchema,\n\tcontext?: NodeKeyManager,\n\tschemaValidationPolicy?: SchemaAndPolicy,\n): ExclusiveMapTree | undefined;\nexport function mapTreeFromNodeData(\n\tdata: InsertableContent | undefined,\n\tallowedTypes: ImplicitFieldSchema,\n\tcontext?: NodeKeyManager,\n\tschemaValidationPolicy?: SchemaAndPolicy,\n): ExclusiveMapTree | undefined {\n\tconst normalizedFieldSchema = normalizeFieldSchema(allowedTypes);\n\n\tif (data === undefined) {\n\t\t// TODO: this code-path should support defaults\n\t\tif (normalizedFieldSchema.kind !== FieldKind.Optional) {\n\t\t\tthrow new UsageError(\"Got undefined for non-optional field.\");\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tconst mapTree = nodeDataToMapTree(data, normalizedFieldSchema.allowedTypeSet);\n\t// Add what defaults can be provided. If no `context` is providing, some defaults may still be missing.\n\taddDefaultsToMapTree(mapTree, normalizedFieldSchema.allowedTypes, context);\n\n\tif (schemaValidationPolicy?.policy.validateSchema === true) {\n\t\t// TODO: BUG: AB#9131\n\t\t// Since some defaults may still be missing, this can give false positives when context is undefined but schemaValidationPolicy is provided.\n\t\t// For now disable this check when context is undefined:\n\t\tif (context !== undefined) {\n\t\t\tconst maybeError = isNodeInSchema(mapTree, schemaValidationPolicy);\n\t\t\tinSchemaOrThrow(maybeError);\n\t\t}\n\t}\n\n\treturn mapTree;\n}\n\n/**\n * Copy content from `data` into a MapTree.\n * Does NOT generate and default values for fields.\n * Often throws UsageErrors for invalid data, but may miss some cases.\n * @remarks\n * Output is likely out of schema even for valid input due to missing defaults.\n */\nfunction nodeDataToMapTree(\n\tdata: InsertableContent,\n\tallowedTypes: ReadonlySet<TreeNodeSchema>,\n): ExclusiveMapTree {\n\t// A special cache path for processing unhydrated nodes.\n\t// They already have the mapTree, so there is no need to recompute it.\n\tconst innerNode = tryGetInnerNode(data);\n\tif (innerNode !== undefined) {\n\t\tif (innerNode instanceof UnhydratedFlexTreeNode) {\n\t\t\tif (!allowedTypes.has(getSimpleNodeSchemaFromInnerNode(innerNode))) {\n\t\t\t\tthrow new UsageError(\"Invalid schema for this context.\");\n\t\t\t}\n\t\t\t// TODO: mapTreeFromNodeData modifies the trees it gets to add defaults.\n\t\t\t// Using a cached value here can result in this tree having defaults applied to it more than once.\n\t\t\t// This is unnecessary and inefficient, but should be a no-op if all calls provide the same context (which they might not).\n\t\t\t// A cleaner design (avoiding this cast) might be to apply defaults eagerly if they don't need a context, and lazily (when hydrating) if they do.\n\t\t\t// This could avoid having to mutate the map tree to apply defaults, removing the need for this cast.\n\t\t\treturn innerNode.mapTree;\n\t\t} else {\n\t\t\t// The node is already hydrated, meaning that it already got inserted into the tree previously\n\t\t\tthrow new UsageError(\"A node may not be inserted into the tree more than once\");\n\t\t}\n\t}\n\n\tassert(!isTreeNode(data), 0xa23 /* data without an inner node cannot be TreeNode */);\n\n\tconst schema = getType(data, allowedTypes);\n\n\tlet result: ExclusiveMapTree;\n\tswitch (schema.kind) {\n\t\tcase NodeKind.Leaf:\n\t\t\tresult = leafToMapTree(data, schema, allowedTypes);\n\t\t\tbreak;\n\t\tcase NodeKind.Array:\n\t\t\tresult = arrayToMapTree(data, schema);\n\t\t\tbreak;\n\t\tcase NodeKind.Map:\n\t\t\tresult = mapToMapTree(data, schema);\n\t\t\tbreak;\n\t\tcase NodeKind.Object:\n\t\t\tresult = objectToMapTree(data, schema);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tfail(`Unrecognized schema kind: ${schema.kind}.`);\n\t}\n\n\treturn result;\n}\n\n/**\n * Throws a UsageError if maybeError indicates a tree is out of schema.\n */\nexport function inSchemaOrThrow(maybeError: SchemaValidationErrors): void {\n\tif (maybeError !== SchemaValidationErrors.NoError) {\n\t\tthrow new UsageError(\"Tree does not conform to schema.\");\n\t}\n}\n\n/**\n * Transforms data under a Leaf schema.\n * @param data - The tree data to be transformed. Must be a {@link TreeValue}.\n * @param schema - The schema associated with the value.\n * @param allowedTypes - The allowed types specified by the parent.\n * Used to determine which fallback values may be appropriate.\n */\nfunction leafToMapTree(\n\tdata: FactoryContent,\n\tschema: TreeNodeSchema,\n\tallowedTypes: ReadonlySet<TreeNodeSchema>,\n): ExclusiveMapTree {\n\tassert(schema.kind === NodeKind.Leaf, 0x921 /* Expected a leaf schema. */);\n\tif (!isTreeValue(data)) {\n\t\t// This rule exists to protect against useless `toString` output like `[object Object]`.\n\t\t// In this case, that's actually reasonable behavior, since object input is not compatible with Leaf schemas.\n\t\t// eslint-disable-next-line @typescript-eslint/no-base-to-string\n\t\tthrow new UsageError(`Input data is incompatible with leaf schema: ${data}`);\n\t}\n\n\tconst mappedValue = mapValueWithFallbacks(data, allowedTypes);\n\tconst mappedSchema = getType(mappedValue, allowedTypes);\n\n\tassert(\n\t\tallowsValue(mappedSchema, mappedValue),\n\t\t0x84a /* Unsupported schema for provided primitive. */,\n\t);\n\n\treturn {\n\t\tvalue: mappedValue,\n\t\ttype: brand(mappedSchema.identifier),\n\t\tfields: new Map(),\n\t};\n}\n\n/**\n * Checks an incoming {@link TreeLeafValue} to ensure it is compatible with its requirements.\n * For unsupported values with a schema-compatible replacement, return the replacement value.\n * For unsupported values without a schema-compatible replacement, throw.\n * For supported values, return the input.\n */\nfunction mapValueWithFallbacks(\n\tvalue: TreeLeafValue,\n\tallowedTypes: ReadonlySet<TreeNodeSchema>,\n): TreeValue {\n\tswitch (typeof value) {\n\t\tcase \"number\": {\n\t\t\tif (Object.is(value, -0)) {\n\t\t\t\t// Our serialized data format does not support -0.\n\t\t\t\t// Map such input to +0.\n\t\t\t\treturn 0;\n\t\t\t} else if (!Number.isFinite(value)) {\n\t\t\t\t// Our serialized data format does not support NaN nor +/-∞.\n\t\t\t\t// If the schema supports `null`, fall back to that. Otherwise, throw.\n\t\t\t\t// This is intended to match JSON's behavior for such values.\n\t\t\t\tif (allowedTypes.has(nullSchema)) {\n\t\t\t\t\treturn null;\n\t\t\t\t} else {\n\t\t\t\t\tthrow new UsageError(`Received unsupported numeric value: ${value}.`);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\t\tcase \"string\":\n\t\t// TODO:\n\t\t// This should detect invalid strings. Something like @stdlib/regexp-utf16-unpaired-surrogate could be used to do this.\n\t\t// See SchemaFactory.string for details.\n\t\tcase \"boolean\":\n\t\t\treturn value;\n\t\tcase \"object\": {\n\t\t\tif (value === null || isFluidHandle(value)) {\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\t\tdefault:\n\t\t\tthrow new UsageError(`Received unsupported leaf value: ${value}.`);\n\t}\n}\n\n/**\n * Transforms data under an Array schema.\n * @param data - The tree data to be transformed.\n * @param allowedTypes - The set of types allowed by the parent context. Used to validate the input tree.\n */\nfunction arrayChildToMapTree(\n\tchild: InsertableContent,\n\tallowedTypes: ReadonlySet<TreeNodeSchema>,\n): ExclusiveMapTree {\n\t// We do not support undefined sequence entries.\n\t// If we encounter an undefined entry, use null instead if supported by the schema, otherwise throw.\n\tlet childWithFallback = child;\n\tif (child === undefined) {\n\t\tif (allowedTypes.has(nullSchema)) {\n\t\t\tchildWithFallback = null;\n\t\t} else {\n\t\t\tthrow new TypeError(`Received unsupported array entry value: ${child}.`);\n\t\t}\n\t}\n\treturn nodeDataToMapTree(childWithFallback, allowedTypes);\n}\n\n/**\n * Transforms data under an Array schema.\n * @param data - The tree data to be transformed. Must be an iterable.\n * @param schema - The schema associated with the value.\n * @param schemaValidationPolicy - The stored schema and policy to be used for validation, if the policy says schema\n * validation should happen. If it does, the input tree will be validated against this schema + policy, and an error will\n * be thrown if the tree does not conform to the schema. If undefined, no validation against the stored schema is done.\n */\nfunction arrayToMapTree(data: FactoryContent, schema: TreeNodeSchema): ExclusiveMapTree {\n\tassert(schema.kind === NodeKind.Array, 0x922 /* Expected an array schema. */);\n\tif (!(typeof data === \"object\" && data !== null && Symbol.iterator in data)) {\n\t\tthrow new UsageError(`Input data is incompatible with Array schema: ${data}`);\n\t}\n\n\tconst allowedChildTypes = normalizeAllowedTypes(schema.info as ImplicitAllowedTypes);\n\n\tconst mappedData = Array.from(data, (child) =>\n\t\tarrayChildToMapTree(child, allowedChildTypes),\n\t);\n\n\t// Array nodes have a single `EmptyKey` field:\n\tconst fieldsEntries = mappedData.length === 0 ? [] : ([[EmptyKey, mappedData]] as const);\n\n\treturn {\n\t\ttype: brand(schema.identifier),\n\t\tfields: new Map(fieldsEntries),\n\t};\n}\n\n/**\n * Transforms data under a Map schema.\n * @param data - The tree data to be transformed. Must be an iterable.\n * @param schema - The schema associated with the value.\n * @param schemaValidationPolicy - The stored schema and policy to be used for validation, if the policy says schema\n * validation should happen. If it does, the input tree will be validated against this schema + policy, and an error will\n * be thrown if the tree does not conform to the schema. If undefined, no validation against the stored schema is done.\n */\nfunction mapToMapTree(data: FactoryContent, schema: TreeNodeSchema): ExclusiveMapTree {\n\tassert(schema.kind === NodeKind.Map, 0x923 /* Expected a Map schema. */);\n\tif (!(typeof data === \"object\" && data !== null)) {\n\t\tthrow new UsageError(`Input data is incompatible with Map schema: ${data}`);\n\t}\n\n\tconst allowedChildTypes = normalizeAllowedTypes(schema.info as ImplicitAllowedTypes);\n\n\tconst fieldsIterator = (\n\t\tSymbol.iterator in data\n\t\t\t? // Support iterables of key value pairs (including Map objects)\n\t\t\t\tdata\n\t\t\t: // Support record objects for JSON style Map data\n\t\t\t\tObject.entries(data)\n\t) as Iterable<readonly [string, InsertableContent]>;\n\n\tconst transformedFields = new Map<FieldKey, ExclusiveMapTree[]>();\n\tfor (const item of fieldsIterator) {\n\t\tif (!isReadonlyArray(item) || item.length !== 2 || typeof item[0] !== \"string\") {\n\t\t\tthrow new UsageError(`Input data is incompatible with map entry: ${item}`);\n\t\t}\n\t\tconst [key, value] = item;\n\t\tassert(!transformedFields.has(brand(key)), 0x84c /* Keys should not be duplicated */);\n\n\t\t// Omit undefined values - an entry with an undefined value is equivalent to one that has been removed or omitted\n\t\tif (value !== undefined) {\n\t\t\tconst mappedField = nodeDataToMapTree(value, allowedChildTypes);\n\t\t\ttransformedFields.set(brand(key), [mappedField]);\n\t\t}\n\t}\n\n\treturn {\n\t\ttype: brand(schema.identifier),\n\t\tfields: transformedFields,\n\t};\n}\n\n/**\n * Transforms data under an Object schema.\n * @param data - The tree data to be transformed. Must be a Record-like object.\n * @param schema - The schema associated with the value.\n */\nfunction objectToMapTree(data: FactoryContent, schema: TreeNodeSchema): ExclusiveMapTree {\n\tassert(isObjectNodeSchema(schema), 0x924 /* Expected an Object schema. */);\n\tif (\n\t\ttypeof data !== \"object\" ||\n\t\tdata === null ||\n\t\tSymbol.iterator in data ||\n\t\tisFluidHandle(data)\n\t) {\n\t\tthrow new UsageError(`Input data is incompatible with Object schema: ${data}`);\n\t}\n\n\tconst fields = new Map<FieldKey, ExclusiveMapTree[]>();\n\n\t// Loop through field keys without data.\n\t// This does NOT apply defaults.\n\tfor (const [key, fieldInfo] of schema.flexKeyMap) {\n\t\tif (checkFieldProperty(data, key)) {\n\t\t\tconst value = (data as Record<string, InsertableContent>)[key as string];\n\t\t\tsetFieldValue(fields, value, fieldInfo.schema, fieldInfo.storedKey);\n\t\t}\n\t}\n\n\treturn {\n\t\ttype: brand(schema.identifier),\n\t\tfields,\n\t};\n}\n\n/**\n * Check {@link FactoryContentObject} for a property which could be store a field.\n * @remarks\n * The currently policy is to only consider own properties.\n * See {@link InsertableObjectFromSchemaRecord} for where this policy is documented in the public API.\n *\n * Explicit undefined members are considered to exist, as long as they are own properties.\n */\nfunction checkFieldProperty(\n\tdata: FactoryContentObject,\n\tkey: string | symbol,\n): data is {\n\treadonly [P in string]: InsertableContent | undefined;\n} {\n\t// This policy only allows own properties.\n\treturn Object.hasOwnProperty.call(data, key);\n}\n\nfunction setFieldValue(\n\tfields: Map<FieldKey, readonly MapTree[]>,\n\tfieldValue: InsertableContent | undefined,\n\tfieldSchema: FieldSchema,\n\tflexKey: FieldKey,\n): void {\n\tif (fieldValue !== undefined) {\n\t\tconst mappedChildTree = nodeDataToMapTree(fieldValue, fieldSchema.allowedTypeSet);\n\n\t\tassert(!fields.has(flexKey), 0x956 /* Keys must not be duplicated */);\n\t\tfields.set(flexKey, [mappedChildTree]);\n\t}\n}\n\nfunction getType(\n\tdata: FactoryContent,\n\tallowedTypes: ReadonlySet<TreeNodeSchema>,\n): TreeNodeSchema {\n\tconst possibleTypes = getPossibleTypes(allowedTypes, data);\n\tif (possibleTypes.length === 0) {\n\t\tthrow new UsageError(\n\t\t\t`The provided data is incompatible with all of the types allowed by the schema. The set of allowed types is: ${JSON.stringify(\n\t\t\t\t[...allowedTypes].map((schema) => schema.identifier),\n\t\t\t)}.`,\n\t\t);\n\t}\n\tassert(\n\t\tpossibleTypes.length !== 0,\n\t\t0x84e /* data is incompatible with all types allowed by the schema */,\n\t);\n\tif (possibleTypes.length !== 1) {\n\t\tthrow new UsageError(\n\t\t\t`The provided data is compatible with more than one type allowed by the schema.\nThe set of possible types is ${JSON.stringify([\n\t\t\t\t...possibleTypes.map((schema) => schema.identifier),\n\t\t\t])}.\nExplicitly construct an unhydrated node of the desired type to disambiguate.\nFor class-based schema, this can be done by replacing an expression like \"{foo: 1}\" with \"new MySchema({foo: 1})\".`,\n\t\t);\n\t}\n\treturn possibleTypes[0] ?? oob();\n}\n\n/**\n * @returns all types for which the data is schema-compatible.\n */\nexport function getPossibleTypes(\n\tallowedTypes: ReadonlySet<TreeNodeSchema>,\n\tdata: FactoryContent,\n): TreeNodeSchema[] {\n\tlet best = CompatibilityLevel.None;\n\tconst possibleTypes: TreeNodeSchema[] = [];\n\tfor (const schema of allowedTypes) {\n\t\tconst level = shallowCompatibilityTest(schema, data);\n\t\tif (level > best) {\n\t\t\tpossibleTypes.length = 0;\n\t\t\tbest = level;\n\t\t}\n\t\tif (best === level) {\n\t\t\tpossibleTypes.push(schema);\n\t\t}\n\t}\n\treturn best === CompatibilityLevel.None ? [] : possibleTypes;\n}\n\n/**\n * Indicates a compatibility level for inferring a schema to apply to insertable data.\n * @remarks\n * Only the highest compatibility options are used.\n * This approach allows adding new possible matching at a new lower compatibility level as a non breaking change,\n * since that way they can't make a case that was compatible before ambiguous now.\n */\nenum CompatibilityLevel {\n\t/**\n\t * Not compatible. Constructor typing indicates incompatibility.\n\t */\n\tNone = 0,\n\t/**\n\t * Additional compatibility cases added in Fluid Framework 2.2.\n\t */\n\tLow = 1,\n\t/**\n\t * Compatible in Fluid Framework 2.0.\n\t */\n\tNormal = 2,\n}\n\n/**\n * Checks if data might be schema-compatible.\n *\n * @returns false if `data` is incompatible with `type` based on a cheap/shallow check.\n *\n * Note that this may return true for cases where data is incompatible, but it must not return false in cases where the data is compatible.\n */\nfunction shallowCompatibilityTest(\n\tschema: TreeNodeSchema,\n\tdata: FactoryContent,\n): CompatibilityLevel {\n\tassert(data !== undefined, 0x889 /* undefined cannot be used as FactoryContent. */);\n\n\tif (isTreeValue(data)) {\n\t\treturn allowsValue(schema, data) ? CompatibilityLevel.Normal : CompatibilityLevel.None;\n\t}\n\tif (schema.kind === NodeKind.Leaf) {\n\t\treturn CompatibilityLevel.None;\n\t}\n\n\t// Typing (of schema based constructors and thus implicit node construction)\n\t// allows iterables for constructing maps and arrays.\n\t// Some users of this API may have unions of maps and arrays,\n\t// and rely on Arrays ending up as array nodes and maps as Map nodes,\n\t// despite both being iterable and thus compatible with both.\n\t// This uses a priority based system where an array would be parsed as an array when unioned with a map,\n\t// but if in a map only context, could still be used as a map.\n\n\tif (data instanceof Map) {\n\t\tswitch (schema.kind) {\n\t\t\tcase NodeKind.Map:\n\t\t\t\treturn CompatibilityLevel.Normal;\n\t\t\tcase NodeKind.Array:\n\t\t\t\t// Maps are iterable, so type checking does allow constructing an ArrayNode from a map if the array's type is an array that includes the key and value types of the map.\n\t\t\t\treturn CompatibilityLevel.Low;\n\t\t\tdefault:\n\t\t\t\treturn CompatibilityLevel.None;\n\t\t}\n\t}\n\n\tif (isReadonlyArray(data)) {\n\t\tswitch (schema.kind) {\n\t\t\tcase NodeKind.Array:\n\t\t\t\treturn CompatibilityLevel.Normal;\n\t\t\tcase NodeKind.Map:\n\t\t\t\t// Arrays are iterable, so type checking does allow constructing an array from a MapNode from an if the array's type is key values pairs for the map.\n\t\t\t\treturn CompatibilityLevel.Low;\n\t\t\tdefault:\n\t\t\t\treturn CompatibilityLevel.None;\n\t\t}\n\t}\n\n\tconst mapOrArray = schema.kind === NodeKind.Array || schema.kind === NodeKind.Map;\n\n\tif (Symbol.iterator in data) {\n\t\treturn mapOrArray ? CompatibilityLevel.Normal : CompatibilityLevel.None;\n\t}\n\n\t// At this point, it is assumed data is a record-like object since all the other cases have been eliminated.\n\n\tif (schema.kind === NodeKind.Array) {\n\t\treturn CompatibilityLevel.None;\n\t}\n\n\tif (schema.kind === NodeKind.Map) {\n\t\t// When not unioned with an ObjectNode, allow objects to be used to create maps.\n\t\treturn CompatibilityLevel.Low;\n\t}\n\n\tassert(isObjectNodeSchema(schema), 0x9e6 /* unexpected schema kind */);\n\n\t// TODO: Improve type inference by making this logic more thorough. Handle at least:\n\t// * Types which are strict subsets of other types in the same polymorphic union\n\t// * Types which have the same keys but different types for those keys in the polymorphic union\n\t// * Types which have the same required fields but different optional fields and enough of those optional fields are populated to disambiguate\n\n\t// TODO#7441: Consider allowing data to be inserted which has keys that are extraneous/unknown to the schema (those keys are ignored)\n\n\t// If the schema has a required key which is not present in the input object, reject it.\n\tfor (const [fieldKey, fieldSchema] of schema.fields) {\n\t\tif (fieldSchema.requiresValue) {\n\t\t\tif (checkFieldProperty(data, fieldKey)) {\n\t\t\t\tif (data[fieldKey] === undefined) {\n\t\t\t\t\treturn CompatibilityLevel.None;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn CompatibilityLevel.None;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn CompatibilityLevel.Normal;\n}\n\nfunction allowsValue(schema: TreeNodeSchema, value: TreeValue): boolean {\n\tif (schema.kind === NodeKind.Leaf) {\n\t\treturn valueSchemaAllows(schema.info as ValueSchema, value);\n\t}\n\treturn false;\n}\n\n/**\n * Walk the given {@link ExclusiveMapTree} and deeply provide any field defaults for fields that are missing in the tree but present in the schema.\n * @param mapTree - The tree to populate with defaults. This is borrowed: no references to it are kept by this function.\n * @param allowedTypes - Some {@link TreeNodeSchema}, at least one of which the input tree must conform to\n * @param context - An optional context for generating defaults.\n * If present, all applicable defaults will be provided.\n * If absent, only defaults produced by a {@link ConstantFieldProvider} will be provided, and defaults produced by a {@link ContextualFieldProvider} will be ignored.\n * @remarks This function mutates the input tree by deeply adding new fields to the field maps where applicable.\n */\nexport function addDefaultsToMapTree(\n\tmapTree: ExclusiveMapTree,\n\tallowedTypes: ImplicitAllowedTypes,\n\tcontext: NodeKeyManager | undefined,\n): void {\n\tconst schema =\n\t\tfind(normalizeAllowedTypes(allowedTypes), (s) => s.identifier === mapTree.type) ??\n\t\tfail(\"MapTree is incompatible with schema\");\n\n\tif (isObjectNodeSchema(schema)) {\n\t\tfor (const [_key, fieldInfo] of schema.flexKeyMap) {\n\t\t\tconst field = mapTree.fields.get(fieldInfo.storedKey);\n\t\t\tif (field !== undefined) {\n\t\t\t\tfor (const child of field) {\n\t\t\t\t\taddDefaultsToMapTree(child, fieldInfo.schema.allowedTypes, context);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst defaultProvider = fieldInfo.schema.props?.defaultProvider;\n\t\t\t\tif (defaultProvider !== undefined) {\n\t\t\t\t\tconst fieldProvider = extractFieldProvider(defaultProvider);\n\t\t\t\t\tconst data = provideDefault(fieldProvider, context);\n\t\t\t\t\tif (data !== undefined) {\n\t\t\t\t\t\tsetFieldValue(mapTree.fields, data, fieldInfo.schema, fieldInfo.storedKey);\n\t\t\t\t\t\t// call addDefaultsToMapTree on newly inserted default values\n\t\t\t\t\t\tfor (const child of mapTree.fields.get(fieldInfo.storedKey) ??\n\t\t\t\t\t\t\tfail(\"Expected field to be populated\")) {\n\t\t\t\t\t\t\taddDefaultsToMapTree(child, fieldInfo.schema.allowedTypes, context);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn;\n\t}\n\n\tswitch (schema.kind) {\n\t\tcase NodeKind.Array:\n\t\tcase NodeKind.Map:\n\t\t\t{\n\t\t\t\tfor (const field of mapTree.fields.values()) {\n\t\t\t\t\tfor (const child of field) {\n\t\t\t\t\t\taddDefaultsToMapTree(child, schema.info as ImplicitAllowedTypes, context);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tassert(schema.kind === NodeKind.Leaf, 0x989 /* Unrecognized schema kind */);\n\t\t\tbreak;\n\t}\n}\n\n/**\n * Provides the default value (which can be undefined, for example with optional fields), or undefined if a context is required but not provided.\n * @privateRemarks\n * It is a bit concerning that there is no way for the caller to know when undefined is returned if that is the default value, or a context was required.\n * TODO: maybe better formalize the two stage defaulting (without then with context), or rework this design we only do one stage.\n */\nfunction provideDefault(\n\tfieldProvider: FieldProvider,\n\tcontext: NodeKeyManager | undefined,\n): InsertableContent | undefined {\n\tif (context !== undefined) {\n\t\treturn fieldProvider(context);\n\t} else {\n\t\tif (isConstant(fieldProvider)) {\n\t\t\treturn fieldProvider();\n\t\t} else {\n\t\t\t// Leaving field empty despite it needing a default value since a context was required and none was provided.\n\t\t\t// Caller better handle this case by providing the default at some other point in time when the context becomes known.\n\t\t}\n\t}\n}\n\n/**\n * Retrieves the InnerNode associated with the given target via {@link setInnerNode}, if any.\n * @remarks\n * If `target` is a unhydrated node, returns its MapTreeNode.\n * If `target` is a cooked node (or marinated but a FlexTreeNode exists) returns the FlexTreeNode.\n * If the target is not a node, or a marinated node with no FlexTreeNode for its anchor, returns undefined.\n */\nfunction tryGetInnerNode(target: unknown): InnerNode | undefined {\n\tif (isTreeNode(target)) {\n\t\treturn getKernel(target).tryGetInnerNode();\n\t}\n}\n\n/**\n * Content which can be used to build a node.\n * @remarks\n * Can contain unhydrated nodes, but can not be an unhydrated node at the root.\n */\nexport type FactoryContent =\n\t| IFluidHandle\n\t| string\n\t| number\n\t| boolean\n\t// eslint-disable-next-line @rushstack/no-new-null\n\t| null\n\t| Iterable<readonly [string, InsertableContent]>\n\t| readonly InsertableContent[]\n\t| FactoryContentObject;\n\n/**\n * Record-like object which can be used to build some kinds of nodes.\n * @remarks\n * Can contain unhydrated nodes, but can not be an unhydrated node at the root.\n *\n * Supports object and map nodes.\n */\ntype FactoryContentObject = {\n\treadonly [P in string]?: InsertableContent;\n};\n\n/**\n * Content which can be inserted into a tree.\n */\nexport type InsertableContent = Unhydrated<TreeNode> | FactoryContent;\n"]}
|
package/lib/alpha.d.ts
CHANGED
|
@@ -44,7 +44,6 @@ export {
|
|
|
44
44
|
NodeInDocumentConstraint,
|
|
45
45
|
NodeKind,
|
|
46
46
|
Off,
|
|
47
|
-
ReadonlyArrayNode,
|
|
48
47
|
RestrictiveReadonlyRecord,
|
|
49
48
|
RestrictiveStringRecord,
|
|
50
49
|
Revertible,
|
|
@@ -67,7 +66,6 @@ export {
|
|
|
67
66
|
TreeNodeFromImplicitAllowedTypes,
|
|
68
67
|
TreeNodeSchema,
|
|
69
68
|
TreeNodeSchemaClass,
|
|
70
|
-
TreeNodeSchemaClassUnsafe,
|
|
71
69
|
TreeNodeSchemaCore,
|
|
72
70
|
TreeNodeSchemaNonClass,
|
|
73
71
|
TreeObjectNode,
|
|
@@ -90,15 +88,10 @@ export {
|
|
|
90
88
|
TreeChangeEventsBeta,
|
|
91
89
|
|
|
92
90
|
// @alpha APIs
|
|
93
|
-
FactoryContent,
|
|
94
|
-
FactoryContentObject,
|
|
95
91
|
FixRecursiveArraySchema,
|
|
96
92
|
ForestOptions,
|
|
97
93
|
ForestType,
|
|
98
94
|
ICodecOptions,
|
|
99
|
-
Insertable,
|
|
100
|
-
InsertableContent,
|
|
101
|
-
InsertableField,
|
|
102
95
|
JsonArrayNodeSchema,
|
|
103
96
|
JsonCompatible,
|
|
104
97
|
JsonCompatibleObject,
|
|
@@ -122,8 +115,6 @@ export {
|
|
|
122
115
|
TreeBranch,
|
|
123
116
|
TreeBranchFork,
|
|
124
117
|
TreeCompressionStrategy,
|
|
125
|
-
TreeViewAlpha,
|
|
126
|
-
UnsafeUnknownSchema,
|
|
127
118
|
adaptEnum,
|
|
128
119
|
comparePersistedSchema,
|
|
129
120
|
enumFromStrings,
|
package/lib/beta.d.ts
CHANGED
|
@@ -44,7 +44,6 @@ export {
|
|
|
44
44
|
NodeInDocumentConstraint,
|
|
45
45
|
NodeKind,
|
|
46
46
|
Off,
|
|
47
|
-
ReadonlyArrayNode,
|
|
48
47
|
RestrictiveReadonlyRecord,
|
|
49
48
|
RestrictiveStringRecord,
|
|
50
49
|
Revertible,
|
|
@@ -67,7 +66,6 @@ export {
|
|
|
67
66
|
TreeNodeFromImplicitAllowedTypes,
|
|
68
67
|
TreeNodeSchema,
|
|
69
68
|
TreeNodeSchemaClass,
|
|
70
|
-
TreeNodeSchemaClassUnsafe,
|
|
71
69
|
TreeNodeSchemaCore,
|
|
72
70
|
TreeNodeSchemaNonClass,
|
|
73
71
|
TreeObjectNode,
|
|
@@ -243,7 +243,7 @@ export function unboxedFlexNode(context, cursor, fieldAnchor) {
|
|
|
243
243
|
let child;
|
|
244
244
|
if (anchor !== undefined) {
|
|
245
245
|
const anchorNode = context.checkout.forest.anchors.locate(anchor);
|
|
246
|
-
assert(anchorNode !== undefined,
|
|
246
|
+
assert(anchorNode !== undefined, 0xa4c /* missing anchor */);
|
|
247
247
|
child = anchorNode.childIfAnchored(fieldAnchor.fieldKey, cursor.fieldIndex);
|
|
248
248
|
}
|
|
249
249
|
else {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lazyField.js","sourceRoot":"","sources":["../../../src/feature-libraries/flex-tree/lazyField.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 } from \"@fluidframework/core-utils/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport {\n\ttype AnchorNode,\n\tCursorLocationType,\n\ttype ExclusiveMapTree,\n\ttype FieldAnchor,\n\ttype FieldKey,\n\ttype FieldKindIdentifier,\n\ttype FieldUpPath,\n\ttype ITreeCursorSynchronous,\n\ttype ITreeSubscriptionCursor,\n\ttype TreeNavigationResult,\n\tinCursorNode,\n\titerateCursorField,\n\trootFieldKey,\n} from \"../../core/index.js\";\nimport { disposeSymbol, fail, getOrCreate } from \"../../util/index.js\";\nimport {\n\tFieldKinds,\n\ttype OptionalFieldEditBuilder,\n\ttype SequenceFieldEditBuilder,\n\ttype ValueFieldEditBuilder,\n} from \"../default-schema/index.js\";\nimport type { FlexFieldKind } from \"../modular-schema/index.js\";\n\nimport type { Context } from \"./context.js\";\nimport {\n\tFlexTreeEntityKind,\n\ttype FlexTreeField,\n\ttype FlexTreeNode,\n\ttype FlexTreeOptionalField,\n\ttype FlexTreeRequiredField,\n\ttype FlexTreeSequenceField,\n\ttype FlexTreeTypedField,\n\ttype FlexTreeUnknownUnboxed,\n\tTreeStatus,\n\tflexTreeMarker,\n\tflexTreeSlot,\n} from \"./flexTreeTypes.js\";\nimport {\n\tLazyEntity,\n\tanchorSymbol,\n\tcursorSymbol,\n\tforgetAnchorSymbol,\n\tisFreedSymbol,\n\ttryMoveCursorToAnchorSymbol,\n} from \"./lazyEntity.js\";\nimport { type LazyTreeNode, makeTree } from \"./lazyNode.js\";\nimport { indexForAt, treeStatusFromAnchorCache } from \"./utilities.js\";\nimport { cursorForMapTreeField, cursorForMapTreeNode } from \"../mapTreeCursor.js\";\n\n/**\n * Reuse fields.\n * Since field currently own cursors and register themselves for disposal when the node hit end of life,\n * not reusing them results in memory leaks every time the field is accessed.\n * Since the fields stay alive until the node is end of life reusing them this way is safe.\n *\n * This ins't a perfect solution:\n *\n * - This can cause leaks, like map nodes will keep all accessed field objects around. Since other things cause this same leak already, its not too bad.\n * - This does not cache the root.\n * - Finding the parent anchor to do the caching on has significant cost.\n *\n * Despite these limitations, this cache provides a large performance win in some common cases (over 10x), especially with how simple tree requests far more field objects than necessary currently.\n */\nconst fieldCache: WeakMap<LazyTreeNode, Map<FieldKey, FlexTreeField>> = new WeakMap();\n\nexport function makeField(\n\tcontext: Context,\n\tschema: FieldKindIdentifier,\n\tcursor: ITreeSubscriptionCursor,\n): FlexTreeField {\n\tconst fieldAnchor = cursor.buildFieldAnchor();\n\tlet usedAnchor = false;\n\n\tconst makeFlexTreeField = (): FlexTreeField => {\n\t\tusedAnchor = true;\n\t\tconst field = new (kindToClass.get(schema) ?? fail(\"missing field implementation\"))(\n\t\t\tcontext,\n\t\t\tschema,\n\t\t\tcursor,\n\t\t\tfieldAnchor,\n\t\t);\n\t\treturn field;\n\t};\n\n\tif (fieldAnchor.parent === undefined) {\n\t\treturn makeFlexTreeField();\n\t}\n\n\t// For the common case (all but roots), cache field associated with its node's anchor and field key.\n\tconst anchorNode =\n\t\tcontext.checkout.forest.anchors.locate(fieldAnchor.parent) ?? fail(\"missing anchor\");\n\n\t// Since anchor-set could be reused across a flex tree context getting disposed, key off the flex tree node not the anchor.\n\tconst cacheKey = anchorNode.slots.get(flexTreeSlot);\n\n\t// If there is no flex tree parent node, skip caching: this is not expected to be a hot path, but should probably be fixed at some point.\n\tif (cacheKey === undefined) {\n\t\treturn makeFlexTreeField();\n\t}\n\n\tconst innerCache = getOrCreate(\n\t\tfieldCache,\n\t\tcacheKey,\n\t\t() => new Map<FieldKey, FlexTreeField>(),\n\t);\n\tconst result = getOrCreate(innerCache, fieldAnchor.fieldKey, makeFlexTreeField);\n\tif (!usedAnchor) {\n\t\t// The anchor must be disposed to avoid leaking. In the case of a cache hit,\n\t\t// we are not transferring ownership to a new FlexTreeField, so it must be disposed of here to avoid the leak.\n\t\tcontext.checkout.forest.anchors.forget(fieldAnchor.parent);\n\t}\n\treturn result;\n}\n\n/**\n * Base type for fields implementing {@link FlexTreeField} using cursors.\n */\nexport abstract class LazyField extends LazyEntity<FieldAnchor> implements FlexTreeField {\n\tpublic get [flexTreeMarker](): FlexTreeEntityKind.Field {\n\t\treturn FlexTreeEntityKind.Field;\n\t}\n\tpublic readonly key: FieldKey;\n\n\t/**\n\t * If this field ends its lifetime before the Anchor does, this needs to be invoked to avoid a double free\n\t * if/when the Anchor is destroyed.\n\t */\n\tprivate readonly offAfterDestroy?: () => void;\n\n\tpublic constructor(\n\t\tcontext: Context,\n\t\tpublic readonly schema: FieldKindIdentifier,\n\t\tcursor: ITreeSubscriptionCursor,\n\t\tfieldAnchor: FieldAnchor,\n\t) {\n\t\tsuper(context, cursor, fieldAnchor);\n\t\tassert(cursor.mode === CursorLocationType.Fields, 0x77b /* must be in fields mode */);\n\t\tthis.key = cursor.getFieldKey();\n\t\t// Fields currently live as long as their parent does.\n\t\t// For root fields, this means forever, but other cases can be cleaned up when their parent anchor is deleted.\n\t\tif (fieldAnchor.parent !== undefined) {\n\t\t\tconst anchorNode =\n\t\t\t\tcontext.checkout.forest.anchors.locate(fieldAnchor.parent) ??\n\t\t\t\tfail(\"parent anchor node should always exist since field is under a node\");\n\t\t\tthis.offAfterDestroy = anchorNode.on(\"afterDestroy\", () => {\n\t\t\t\tthis[disposeSymbol]();\n\t\t\t});\n\t\t}\n\t}\n\n\tpublic is<TKind2 extends FlexFieldKind>(kind: TKind2): this is FlexTreeTypedField<TKind2> {\n\t\tassert(\n\t\t\tthis.context.schemaPolicy.fieldKinds.get(kind.identifier) === kind,\n\t\t\t0xa26 /* Narrowing must be done to a kind that exists in this context */,\n\t\t);\n\n\t\treturn this.schema === kind.identifier;\n\t}\n\n\tpublic get parent(): FlexTreeNode | undefined {\n\t\tif (this[anchorSymbol].parent === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst cursor = this[cursorSymbol];\n\t\tcursor.exitField();\n\t\tconst output = makeTree(this.context, cursor);\n\t\tcursor.enterField(this.key);\n\t\treturn output;\n\t}\n\n\tprotected override [tryMoveCursorToAnchorSymbol](\n\t\tcursor: ITreeSubscriptionCursor,\n\t): TreeNavigationResult {\n\t\treturn this.context.checkout.forest.tryMoveCursorToField(this[anchorSymbol], cursor);\n\t}\n\n\tprotected override [forgetAnchorSymbol](): void {\n\t\tthis.offAfterDestroy?.();\n\t\tif (this[anchorSymbol].parent === undefined) return;\n\t\tthis.context.checkout.forest.anchors.forget(this[anchorSymbol].parent);\n\t}\n\n\tpublic get length(): number {\n\t\treturn this[cursorSymbol].getFieldLength();\n\t}\n\n\tpublic atIndex(index: number): FlexTreeUnknownUnboxed {\n\t\treturn inCursorNode(this[cursorSymbol], index, (cursor) =>\n\t\t\tunboxedFlexNode(this.context, cursor, this[anchorSymbol]),\n\t\t);\n\t}\n\n\tpublic boxedAt(index: number): FlexTreeNode | undefined {\n\t\tconst finalIndex = indexForAt(index, this.length);\n\n\t\tif (finalIndex === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn inCursorNode(this[cursorSymbol], finalIndex, (cursor) =>\n\t\t\tmakeTree(this.context, cursor),\n\t\t);\n\t}\n\n\tpublic map<U>(callbackfn: (value: FlexTreeUnknownUnboxed, index: number) => U): U[] {\n\t\treturn Array.from(this, callbackfn);\n\t}\n\n\tpublic boxedIterator(): IterableIterator<FlexTreeNode> {\n\t\treturn iterateCursorField(this[cursorSymbol], (cursor) => makeTree(this.context, cursor));\n\t}\n\n\tpublic [Symbol.iterator](): IterableIterator<FlexTreeUnknownUnboxed> {\n\t\treturn iterateCursorField(this[cursorSymbol], (cursor) =>\n\t\t\tunboxedFlexNode(this.context, cursor, this[anchorSymbol]),\n\t\t);\n\t}\n\n\tpublic getFieldPath(): FieldUpPath {\n\t\treturn this[cursorSymbol].getFieldPath();\n\t}\n\n\t/**\n\t * Returns the path to this field to use for editing. Throws iff this path is not {@link TreeStatus#InDocument}.\n\t * This path is not valid to hold onto across edits: this must be recalled for each edit.\n\t */\n\tpublic getFieldPathForEditing(): FieldUpPath {\n\t\tif (!this[isFreedSymbol]()) {\n\t\t\tif (\n\t\t\t\t// Only allow editing if we are the root document field...\n\t\t\t\t(this.parent === undefined && this[anchorSymbol].fieldKey === rootFieldKey) ||\n\t\t\t\t// ...or are under a node in the document\n\t\t\t\t(this.parent !== undefined &&\n\t\t\t\t\ttreeStatusFromAnchorCache(this.parent.anchorNode) === TreeStatus.InDocument)\n\t\t\t) {\n\t\t\t\treturn this.getFieldPath();\n\t\t\t}\n\t\t}\n\n\t\tthrow new UsageError(\"Editing only allowed on fields with TreeStatus.InDocument status\");\n\t}\n}\n\nexport class LazySequence extends LazyField implements FlexTreeSequenceField {\n\tpublic at(index: number): FlexTreeUnknownUnboxed | undefined {\n\t\tconst finalIndex = indexForAt(index, this.length);\n\n\t\tif (finalIndex === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn this.atIndex(finalIndex);\n\t}\n\tpublic get asArray(): readonly FlexTreeUnknownUnboxed[] {\n\t\treturn this.map((x) => x);\n\t}\n\n\tpublic editor: SequenceFieldEditBuilder<ExclusiveMapTree[]> = {\n\t\tinsert: (index, newContent) => {\n\t\t\tthis.sequenceEditor().insert(index, cursorForMapTreeField(newContent));\n\t\t},\n\t\tremove: (index, count) => {\n\t\t\tthis.sequenceEditor().remove(index, count);\n\t\t},\n\t};\n\n\tprivate sequenceEditor(): SequenceFieldEditBuilder<ITreeCursorSynchronous> {\n\t\tconst fieldPath = this.getFieldPathForEditing();\n\t\treturn this.context.checkout.editor.sequenceField(fieldPath);\n\t}\n}\n\nexport class ReadonlyLazyValueField extends LazyField implements FlexTreeRequiredField {\n\tpublic editor: ValueFieldEditBuilder<ExclusiveMapTree> = {\n\t\tset: (newContent) => {\n\t\t\tassert(false, 0xa0c /* Unexpected set of readonly field */);\n\t\t},\n\t};\n\n\tpublic get content(): FlexTreeUnknownUnboxed {\n\t\treturn this.atIndex(0);\n\t}\n}\n\nexport class LazyValueField extends ReadonlyLazyValueField implements FlexTreeRequiredField {\n\tpublic override editor: ValueFieldEditBuilder<ExclusiveMapTree> = {\n\t\tset: (newContent) => {\n\t\t\tthis.valueFieldEditor().set(cursorForMapTreeNode(newContent));\n\t\t},\n\t};\n\n\tprivate valueFieldEditor(): ValueFieldEditBuilder<ITreeCursorSynchronous> {\n\t\tconst fieldPath = this.getFieldPathForEditing();\n\t\tconst fieldEditor = this.context.checkout.editor.valueField(fieldPath);\n\t\treturn fieldEditor;\n\t}\n\n\tpublic override get content(): FlexTreeUnknownUnboxed {\n\t\treturn this.atIndex(0);\n\t}\n}\n\nexport class LazyOptionalField extends LazyField implements FlexTreeOptionalField {\n\tpublic editor: OptionalFieldEditBuilder<ExclusiveMapTree> = {\n\t\tset: (newContent, wasEmpty) => {\n\t\t\tthis.optionalEditor().set(\n\t\t\t\tnewContent !== undefined ? cursorForMapTreeNode(newContent) : newContent,\n\t\t\t\twasEmpty,\n\t\t\t);\n\t\t},\n\t};\n\n\tprivate optionalEditor(): OptionalFieldEditBuilder<ITreeCursorSynchronous> {\n\t\tconst fieldPath = this.getFieldPathForEditing();\n\t\tconst fieldEditor = this.context.checkout.editor.optionalField(fieldPath);\n\t\treturn fieldEditor;\n\t}\n\n\tpublic get content(): FlexTreeUnknownUnboxed | undefined {\n\t\treturn this.length === 0 ? undefined : this.atIndex(0);\n\t}\n}\n\nexport class LazyForbiddenField extends LazyField {}\n\ntype Builder = new (\n\tcontext: Context,\n\t// Correct use of these builders requires the builder of the matching type to be used.\n\tschema: FieldKindIdentifier,\n\tcursor: ITreeSubscriptionCursor,\n\tfieldAnchor: FieldAnchor,\n) => LazyField;\n\nconst builderList: [FieldKindIdentifier, Builder][] = [\n\t[FieldKinds.forbidden.identifier, LazyForbiddenField],\n\t[FieldKinds.optional.identifier, LazyOptionalField],\n\t[FieldKinds.sequence.identifier, LazySequence],\n\t[FieldKinds.required.identifier, LazyValueField],\n\t[FieldKinds.identifier.identifier, LazyValueField],\n];\n\nconst kindToClass: ReadonlyMap<FieldKindIdentifier, Builder> = new Map(builderList);\n\n/**\n * Returns the flex tree node, or the value if it has one.\n */\nexport function unboxedFlexNode(\n\tcontext: Context,\n\tcursor: ITreeSubscriptionCursor,\n\tfieldAnchor: FieldAnchor,\n): FlexTreeUnknownUnboxed {\n\tconst value = cursor.value;\n\tif (value !== undefined) {\n\t\treturn value;\n\t}\n\n\t// Try accessing cached child node via anchors.\n\t// This avoids O(depth) related costs from makeTree in the cached case.\n\tconst anchor = fieldAnchor.parent;\n\tlet child: AnchorNode | undefined;\n\tif (anchor !== undefined) {\n\t\tconst anchorNode = context.checkout.forest.anchors.locate(anchor);\n\t\tassert(anchorNode !== undefined, \"missing anchor\");\n\t\tchild = anchorNode.childIfAnchored(fieldAnchor.fieldKey, cursor.fieldIndex);\n\t} else {\n\t\tchild = context.checkout.forest.anchors.find({\n\t\t\tparent: undefined,\n\t\t\tparentField: fieldAnchor.fieldKey,\n\t\t\tparentIndex: cursor.fieldIndex,\n\t\t});\n\t}\n\n\tif (child !== undefined) {\n\t\tconst cached = child.slots.get(flexTreeSlot);\n\t\tif (cached !== undefined) {\n\t\t\treturn cached;\n\t\t}\n\t}\n\n\treturn makeTree(context, cursor);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"lazyField.js","sourceRoot":"","sources":["../../../src/feature-libraries/flex-tree/lazyField.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 } from \"@fluidframework/core-utils/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport {\n\ttype AnchorNode,\n\tCursorLocationType,\n\ttype ExclusiveMapTree,\n\ttype FieldAnchor,\n\ttype FieldKey,\n\ttype FieldKindIdentifier,\n\ttype FieldUpPath,\n\ttype ITreeCursorSynchronous,\n\ttype ITreeSubscriptionCursor,\n\ttype TreeNavigationResult,\n\tinCursorNode,\n\titerateCursorField,\n\trootFieldKey,\n} from \"../../core/index.js\";\nimport { disposeSymbol, fail, getOrCreate } from \"../../util/index.js\";\nimport {\n\tFieldKinds,\n\ttype OptionalFieldEditBuilder,\n\ttype SequenceFieldEditBuilder,\n\ttype ValueFieldEditBuilder,\n} from \"../default-schema/index.js\";\nimport type { FlexFieldKind } from \"../modular-schema/index.js\";\n\nimport type { Context } from \"./context.js\";\nimport {\n\tFlexTreeEntityKind,\n\ttype FlexTreeField,\n\ttype FlexTreeNode,\n\ttype FlexTreeOptionalField,\n\ttype FlexTreeRequiredField,\n\ttype FlexTreeSequenceField,\n\ttype FlexTreeTypedField,\n\ttype FlexTreeUnknownUnboxed,\n\tTreeStatus,\n\tflexTreeMarker,\n\tflexTreeSlot,\n} from \"./flexTreeTypes.js\";\nimport {\n\tLazyEntity,\n\tanchorSymbol,\n\tcursorSymbol,\n\tforgetAnchorSymbol,\n\tisFreedSymbol,\n\ttryMoveCursorToAnchorSymbol,\n} from \"./lazyEntity.js\";\nimport { type LazyTreeNode, makeTree } from \"./lazyNode.js\";\nimport { indexForAt, treeStatusFromAnchorCache } from \"./utilities.js\";\nimport { cursorForMapTreeField, cursorForMapTreeNode } from \"../mapTreeCursor.js\";\n\n/**\n * Reuse fields.\n * Since field currently own cursors and register themselves for disposal when the node hit end of life,\n * not reusing them results in memory leaks every time the field is accessed.\n * Since the fields stay alive until the node is end of life reusing them this way is safe.\n *\n * This ins't a perfect solution:\n *\n * - This can cause leaks, like map nodes will keep all accessed field objects around. Since other things cause this same leak already, its not too bad.\n * - This does not cache the root.\n * - Finding the parent anchor to do the caching on has significant cost.\n *\n * Despite these limitations, this cache provides a large performance win in some common cases (over 10x), especially with how simple tree requests far more field objects than necessary currently.\n */\nconst fieldCache: WeakMap<LazyTreeNode, Map<FieldKey, FlexTreeField>> = new WeakMap();\n\nexport function makeField(\n\tcontext: Context,\n\tschema: FieldKindIdentifier,\n\tcursor: ITreeSubscriptionCursor,\n): FlexTreeField {\n\tconst fieldAnchor = cursor.buildFieldAnchor();\n\tlet usedAnchor = false;\n\n\tconst makeFlexTreeField = (): FlexTreeField => {\n\t\tusedAnchor = true;\n\t\tconst field = new (kindToClass.get(schema) ?? fail(\"missing field implementation\"))(\n\t\t\tcontext,\n\t\t\tschema,\n\t\t\tcursor,\n\t\t\tfieldAnchor,\n\t\t);\n\t\treturn field;\n\t};\n\n\tif (fieldAnchor.parent === undefined) {\n\t\treturn makeFlexTreeField();\n\t}\n\n\t// For the common case (all but roots), cache field associated with its node's anchor and field key.\n\tconst anchorNode =\n\t\tcontext.checkout.forest.anchors.locate(fieldAnchor.parent) ?? fail(\"missing anchor\");\n\n\t// Since anchor-set could be reused across a flex tree context getting disposed, key off the flex tree node not the anchor.\n\tconst cacheKey = anchorNode.slots.get(flexTreeSlot);\n\n\t// If there is no flex tree parent node, skip caching: this is not expected to be a hot path, but should probably be fixed at some point.\n\tif (cacheKey === undefined) {\n\t\treturn makeFlexTreeField();\n\t}\n\n\tconst innerCache = getOrCreate(\n\t\tfieldCache,\n\t\tcacheKey,\n\t\t() => new Map<FieldKey, FlexTreeField>(),\n\t);\n\tconst result = getOrCreate(innerCache, fieldAnchor.fieldKey, makeFlexTreeField);\n\tif (!usedAnchor) {\n\t\t// The anchor must be disposed to avoid leaking. In the case of a cache hit,\n\t\t// we are not transferring ownership to a new FlexTreeField, so it must be disposed of here to avoid the leak.\n\t\tcontext.checkout.forest.anchors.forget(fieldAnchor.parent);\n\t}\n\treturn result;\n}\n\n/**\n * Base type for fields implementing {@link FlexTreeField} using cursors.\n */\nexport abstract class LazyField extends LazyEntity<FieldAnchor> implements FlexTreeField {\n\tpublic get [flexTreeMarker](): FlexTreeEntityKind.Field {\n\t\treturn FlexTreeEntityKind.Field;\n\t}\n\tpublic readonly key: FieldKey;\n\n\t/**\n\t * If this field ends its lifetime before the Anchor does, this needs to be invoked to avoid a double free\n\t * if/when the Anchor is destroyed.\n\t */\n\tprivate readonly offAfterDestroy?: () => void;\n\n\tpublic constructor(\n\t\tcontext: Context,\n\t\tpublic readonly schema: FieldKindIdentifier,\n\t\tcursor: ITreeSubscriptionCursor,\n\t\tfieldAnchor: FieldAnchor,\n\t) {\n\t\tsuper(context, cursor, fieldAnchor);\n\t\tassert(cursor.mode === CursorLocationType.Fields, 0x77b /* must be in fields mode */);\n\t\tthis.key = cursor.getFieldKey();\n\t\t// Fields currently live as long as their parent does.\n\t\t// For root fields, this means forever, but other cases can be cleaned up when their parent anchor is deleted.\n\t\tif (fieldAnchor.parent !== undefined) {\n\t\t\tconst anchorNode =\n\t\t\t\tcontext.checkout.forest.anchors.locate(fieldAnchor.parent) ??\n\t\t\t\tfail(\"parent anchor node should always exist since field is under a node\");\n\t\t\tthis.offAfterDestroy = anchorNode.on(\"afterDestroy\", () => {\n\t\t\t\tthis[disposeSymbol]();\n\t\t\t});\n\t\t}\n\t}\n\n\tpublic is<TKind2 extends FlexFieldKind>(kind: TKind2): this is FlexTreeTypedField<TKind2> {\n\t\tassert(\n\t\t\tthis.context.schemaPolicy.fieldKinds.get(kind.identifier) === kind,\n\t\t\t0xa26 /* Narrowing must be done to a kind that exists in this context */,\n\t\t);\n\n\t\treturn this.schema === kind.identifier;\n\t}\n\n\tpublic get parent(): FlexTreeNode | undefined {\n\t\tif (this[anchorSymbol].parent === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst cursor = this[cursorSymbol];\n\t\tcursor.exitField();\n\t\tconst output = makeTree(this.context, cursor);\n\t\tcursor.enterField(this.key);\n\t\treturn output;\n\t}\n\n\tprotected override [tryMoveCursorToAnchorSymbol](\n\t\tcursor: ITreeSubscriptionCursor,\n\t): TreeNavigationResult {\n\t\treturn this.context.checkout.forest.tryMoveCursorToField(this[anchorSymbol], cursor);\n\t}\n\n\tprotected override [forgetAnchorSymbol](): void {\n\t\tthis.offAfterDestroy?.();\n\t\tif (this[anchorSymbol].parent === undefined) return;\n\t\tthis.context.checkout.forest.anchors.forget(this[anchorSymbol].parent);\n\t}\n\n\tpublic get length(): number {\n\t\treturn this[cursorSymbol].getFieldLength();\n\t}\n\n\tpublic atIndex(index: number): FlexTreeUnknownUnboxed {\n\t\treturn inCursorNode(this[cursorSymbol], index, (cursor) =>\n\t\t\tunboxedFlexNode(this.context, cursor, this[anchorSymbol]),\n\t\t);\n\t}\n\n\tpublic boxedAt(index: number): FlexTreeNode | undefined {\n\t\tconst finalIndex = indexForAt(index, this.length);\n\n\t\tif (finalIndex === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn inCursorNode(this[cursorSymbol], finalIndex, (cursor) =>\n\t\t\tmakeTree(this.context, cursor),\n\t\t);\n\t}\n\n\tpublic map<U>(callbackfn: (value: FlexTreeUnknownUnboxed, index: number) => U): U[] {\n\t\treturn Array.from(this, callbackfn);\n\t}\n\n\tpublic boxedIterator(): IterableIterator<FlexTreeNode> {\n\t\treturn iterateCursorField(this[cursorSymbol], (cursor) => makeTree(this.context, cursor));\n\t}\n\n\tpublic [Symbol.iterator](): IterableIterator<FlexTreeUnknownUnboxed> {\n\t\treturn iterateCursorField(this[cursorSymbol], (cursor) =>\n\t\t\tunboxedFlexNode(this.context, cursor, this[anchorSymbol]),\n\t\t);\n\t}\n\n\tpublic getFieldPath(): FieldUpPath {\n\t\treturn this[cursorSymbol].getFieldPath();\n\t}\n\n\t/**\n\t * Returns the path to this field to use for editing. Throws iff this path is not {@link TreeStatus#InDocument}.\n\t * This path is not valid to hold onto across edits: this must be recalled for each edit.\n\t */\n\tpublic getFieldPathForEditing(): FieldUpPath {\n\t\tif (!this[isFreedSymbol]()) {\n\t\t\tif (\n\t\t\t\t// Only allow editing if we are the root document field...\n\t\t\t\t(this.parent === undefined && this[anchorSymbol].fieldKey === rootFieldKey) ||\n\t\t\t\t// ...or are under a node in the document\n\t\t\t\t(this.parent !== undefined &&\n\t\t\t\t\ttreeStatusFromAnchorCache(this.parent.anchorNode) === TreeStatus.InDocument)\n\t\t\t) {\n\t\t\t\treturn this.getFieldPath();\n\t\t\t}\n\t\t}\n\n\t\tthrow new UsageError(\"Editing only allowed on fields with TreeStatus.InDocument status\");\n\t}\n}\n\nexport class LazySequence extends LazyField implements FlexTreeSequenceField {\n\tpublic at(index: number): FlexTreeUnknownUnboxed | undefined {\n\t\tconst finalIndex = indexForAt(index, this.length);\n\n\t\tif (finalIndex === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn this.atIndex(finalIndex);\n\t}\n\tpublic get asArray(): readonly FlexTreeUnknownUnboxed[] {\n\t\treturn this.map((x) => x);\n\t}\n\n\tpublic editor: SequenceFieldEditBuilder<ExclusiveMapTree[]> = {\n\t\tinsert: (index, newContent) => {\n\t\t\tthis.sequenceEditor().insert(index, cursorForMapTreeField(newContent));\n\t\t},\n\t\tremove: (index, count) => {\n\t\t\tthis.sequenceEditor().remove(index, count);\n\t\t},\n\t};\n\n\tprivate sequenceEditor(): SequenceFieldEditBuilder<ITreeCursorSynchronous> {\n\t\tconst fieldPath = this.getFieldPathForEditing();\n\t\treturn this.context.checkout.editor.sequenceField(fieldPath);\n\t}\n}\n\nexport class ReadonlyLazyValueField extends LazyField implements FlexTreeRequiredField {\n\tpublic editor: ValueFieldEditBuilder<ExclusiveMapTree> = {\n\t\tset: (newContent) => {\n\t\t\tassert(false, 0xa0c /* Unexpected set of readonly field */);\n\t\t},\n\t};\n\n\tpublic get content(): FlexTreeUnknownUnboxed {\n\t\treturn this.atIndex(0);\n\t}\n}\n\nexport class LazyValueField extends ReadonlyLazyValueField implements FlexTreeRequiredField {\n\tpublic override editor: ValueFieldEditBuilder<ExclusiveMapTree> = {\n\t\tset: (newContent) => {\n\t\t\tthis.valueFieldEditor().set(cursorForMapTreeNode(newContent));\n\t\t},\n\t};\n\n\tprivate valueFieldEditor(): ValueFieldEditBuilder<ITreeCursorSynchronous> {\n\t\tconst fieldPath = this.getFieldPathForEditing();\n\t\tconst fieldEditor = this.context.checkout.editor.valueField(fieldPath);\n\t\treturn fieldEditor;\n\t}\n\n\tpublic override get content(): FlexTreeUnknownUnboxed {\n\t\treturn this.atIndex(0);\n\t}\n}\n\nexport class LazyOptionalField extends LazyField implements FlexTreeOptionalField {\n\tpublic editor: OptionalFieldEditBuilder<ExclusiveMapTree> = {\n\t\tset: (newContent, wasEmpty) => {\n\t\t\tthis.optionalEditor().set(\n\t\t\t\tnewContent !== undefined ? cursorForMapTreeNode(newContent) : newContent,\n\t\t\t\twasEmpty,\n\t\t\t);\n\t\t},\n\t};\n\n\tprivate optionalEditor(): OptionalFieldEditBuilder<ITreeCursorSynchronous> {\n\t\tconst fieldPath = this.getFieldPathForEditing();\n\t\tconst fieldEditor = this.context.checkout.editor.optionalField(fieldPath);\n\t\treturn fieldEditor;\n\t}\n\n\tpublic get content(): FlexTreeUnknownUnboxed | undefined {\n\t\treturn this.length === 0 ? undefined : this.atIndex(0);\n\t}\n}\n\nexport class LazyForbiddenField extends LazyField {}\n\ntype Builder = new (\n\tcontext: Context,\n\t// Correct use of these builders requires the builder of the matching type to be used.\n\tschema: FieldKindIdentifier,\n\tcursor: ITreeSubscriptionCursor,\n\tfieldAnchor: FieldAnchor,\n) => LazyField;\n\nconst builderList: [FieldKindIdentifier, Builder][] = [\n\t[FieldKinds.forbidden.identifier, LazyForbiddenField],\n\t[FieldKinds.optional.identifier, LazyOptionalField],\n\t[FieldKinds.sequence.identifier, LazySequence],\n\t[FieldKinds.required.identifier, LazyValueField],\n\t[FieldKinds.identifier.identifier, LazyValueField],\n];\n\nconst kindToClass: ReadonlyMap<FieldKindIdentifier, Builder> = new Map(builderList);\n\n/**\n * Returns the flex tree node, or the value if it has one.\n */\nexport function unboxedFlexNode(\n\tcontext: Context,\n\tcursor: ITreeSubscriptionCursor,\n\tfieldAnchor: FieldAnchor,\n): FlexTreeUnknownUnboxed {\n\tconst value = cursor.value;\n\tif (value !== undefined) {\n\t\treturn value;\n\t}\n\n\t// Try accessing cached child node via anchors.\n\t// This avoids O(depth) related costs from makeTree in the cached case.\n\tconst anchor = fieldAnchor.parent;\n\tlet child: AnchorNode | undefined;\n\tif (anchor !== undefined) {\n\t\tconst anchorNode = context.checkout.forest.anchors.locate(anchor);\n\t\tassert(anchorNode !== undefined, 0xa4c /* missing anchor */);\n\t\tchild = anchorNode.childIfAnchored(fieldAnchor.fieldKey, cursor.fieldIndex);\n\t} else {\n\t\tchild = context.checkout.forest.anchors.find({\n\t\t\tparent: undefined,\n\t\t\tparentField: fieldAnchor.fieldKey,\n\t\t\tparentIndex: cursor.fieldIndex,\n\t\t});\n\t}\n\n\tif (child !== undefined) {\n\t\tconst cached = child.slots.get(flexTreeSlot);\n\t\tif (cached !== undefined) {\n\t\t\treturn cached;\n\t\t}\n\t}\n\n\treturn makeTree(context, cursor);\n}\n"]}
|