fluid-framework 2.23.0-323641 → 2.23.0-325054

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,52 @@
1
1
  # fluid-framework
2
2
 
3
+ ## 2.23.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Creating large transactions and processing inbound changes is now faster ([#23929](https://github.com/microsoft/FluidFramework/pull/23929)) [35847b5ffe0](https://github.com/microsoft/FluidFramework/commit/35847b5ffe09d94cef42b74ab59e37c4bd6d8c2d)
8
+
9
+ SharedTree sometimes composes several sequential changes into a single change.
10
+ It does so whenever a transaction is created and when processing inbound changes.
11
+
12
+ Version 2.23.0 makes this composition process asymptotically faster.
13
+ For example, creating a transaction that performs 1000 edits on a single array now takes 170ms instead of 1.5s (an 89% improvement).
14
+
15
+ See [Change #23902](https://github.com/microsoft/FluidFramework/pull/23902) for more details.
16
+
17
+ - Faster processing of events for large transactions ([#23939](https://github.com/microsoft/FluidFramework/pull/23939)) [2a1e7e0617f](https://github.com/microsoft/FluidFramework/commit/2a1e7e0617f618f82134c0bba269119ed980aadc)
18
+
19
+ In versions prior to 2.23.0, event processing time could scale quadratically (`O(N^2)`) with the change count when
20
+ processing a batch of changes.
21
+
22
+ This performance characteristic has been corrected. See change
23
+ [#23908](https://github.com/microsoft/FluidFramework/pull/23908) for more details.
24
+
25
+ - Op bunching performance enhancements ([#23732](https://github.com/microsoft/FluidFramework/pull/23732)) [a98b04fc9e0](https://github.com/microsoft/FluidFramework/commit/a98b04fc9e000971bdfa8135251a7dc3e189502c)
26
+
27
+ `SharedTree` now takes advantage of a new feature called "op bunching" where contiguous ops in a grouped batch are
28
+ bunched and processed together. This improves the performance of processing ops asymptotically; as
29
+ the number of local ops and incoming ops increase, the processing time will reduce.
30
+
31
+ For example, with 10 local ops + 10 incoming ops, the performance increases by 70%; with 100 local ops + 100 incoming ops, the performance increases by 94%.
32
+
33
+ This will help improve performance in the following scenarios:
34
+
35
+ - A client makes a large number of changes in a single JS turn. For example, copy pasting large data like a table.
36
+ - A client has a large number of local changes. For example, slow clients whose changes are slow to ack or clients with
37
+ a local branch with large number of changes.
38
+
39
+ - Invalid schema base classes in Tree.is now throw an error instead of returning false ([#23938](https://github.com/microsoft/FluidFramework/pull/23938)) [00995654070](https://github.com/microsoft/FluidFramework/commit/00995654070a4e13b57b2562ff4a5935aba70a2f)
40
+
41
+ As documented in [`TreeNodeSchemaClass`](https://fluidframework.com/docs/api/fluid-framework/treenodeschemaclass-typealias#treenodeschemaclass-remarks), there are specific rules around sub-classing schema, mainly that only a single most derived class can be used.
42
+ One place where it was easy to accidentally violate this rule and get hard-to-debug results was [`Tree.is`](https://fluidframework.com/docs/data-structures/tree/nodes#treeis).
43
+ This has been mitigated by adding a check in `Tree.is` which detects this mistake (which used to result in `false` being returned) and instead throws a `UsageError` explaining the situation.
44
+ The error will look something like:
45
+
46
+ > Two schema classes were used (CustomObjectNode and Derived) which derived from the same SchemaFactory generated class ("com.example.Test"). This is invalid.
47
+
48
+ For applications wanting to test if a given `TreeNode` is an instance of some schema base class, this can be done using `instanceof` which includes base classes when doing the check.
49
+
3
50
  ## 2.22.0
4
51
 
5
52
  ### Minor Changes
@@ -28,11 +28,22 @@ type ApplyKind<T, Kind extends FieldKind> = {
28
28
  [FieldKind.Identifier]: T;
29
29
  }[Kind];
30
30
 
31
+ // @public
32
+ export type ApplyKindAssignment<T, Kind extends FieldKind> = [Kind] extends [
33
+ FieldKind.Required
34
+ ] ? T : [Kind] extends [FieldKind.Optional] ? T | undefined : never;
35
+
31
36
  // @public
32
37
  type ApplyKindInput<T, Kind extends FieldKind, DefaultsAreOptional extends boolean> = [
33
38
  Kind
34
39
  ] extends [FieldKind.Required] ? T : [Kind] extends [FieldKind.Optional] ? T | undefined : [Kind] extends [FieldKind.Identifier] ? DefaultsAreOptional extends true ? T | undefined : T : never;
35
40
 
41
+ // @public
42
+ export type AssignableTreeFieldFromImplicitField<TSchemaInput extends ImplicitFieldSchema, TSchema = SchemaUnionToIntersection<TSchemaInput>> = [TSchema] extends [FieldSchema<infer Kind, infer Types>] ? ApplyKindAssignment<GetTypes<Types>["readWrite"], Kind> : [TSchema] extends [ImplicitAllowedTypes] ? GetTypes<TSchema>["readWrite"] : never;
43
+
44
+ // @public
45
+ export type AssignableTreeFieldFromImplicitFieldUnsafe<TSchema extends Unenforced<ImplicitFieldSchema>> = TSchema extends FieldSchemaUnsafe<infer Kind, infer Types> ? ApplyKindAssignment<GetTypesUnsafe<Types>["readWrite"], Kind> : GetTypesUnsafe<TSchema>["readWrite"];
46
+
36
47
  // @alpha
37
48
  export function asTreeViewAlpha<TSchema extends ImplicitFieldSchema>(view: TreeView<TSchema>): TreeViewAlpha<TSchema>;
38
49
 
@@ -67,6 +78,13 @@ export interface CommitMetadata {
67
78
  // @alpha
68
79
  export function comparePersistedSchema(persisted: JsonCompatible, view: ImplicitFieldSchema, options: ICodecOptions, canInitialize: boolean): SchemaCompatibilityStatus;
69
80
 
81
+ // @alpha
82
+ export namespace Component {
83
+ export type ComponentSchemaCollection<TConfig, TSchema> = (lazyConfiguration: () => TConfig) => LazyArray<TSchema>;
84
+ export function composeComponentSchema<TConfig, TItem>(allComponents: readonly ComponentSchemaCollection<TConfig, TItem>[], lazyConfiguration: () => TConfig): (() => TItem)[];
85
+ export type LazyArray<T> = readonly (() => T)[];
86
+ }
87
+
70
88
  // @alpha
71
89
  export type ConciseTree<THandle = IFluidHandle> = Exclude<TreeLeafValue, IFluidHandle> | THandle | ConciseTree<THandle>[] | {
72
90
  [key: string]: ConciseTree<THandle>;
@@ -118,10 +136,66 @@ export function createSimpleTreeIndex<TFieldSchema extends ImplicitFieldSchema,
118
136
  // @alpha
119
137
  export function createSimpleTreeIndex<TFieldSchema extends ImplicitFieldSchema, TKey extends TreeIndexKey, TValue, TSchema extends TreeNodeSchema>(view: TreeView<TFieldSchema>, indexer: Map<TreeNodeSchema, string>, getValue: (nodes: TreeIndexNodes<NodeFromSchema<TSchema>>) => TValue, isKeyValid: (key: TreeIndexKey) => key is TKey, indexableSchema: readonly TSchema[]): SimpleTreeIndex<TKey, TValue>;
120
138
 
139
+ // @public
140
+ export type CustomizedSchemaTyping<TSchema, TCustom extends CustomTypes> = TSchema & {
141
+ [CustomizedTyping]: TCustom;
142
+ };
143
+
144
+ // @public
145
+ export const CustomizedTyping: unique symbol;
146
+
147
+ // @public
148
+ export type CustomizedTyping = typeof CustomizedTyping;
149
+
150
+ // @alpha @sealed
151
+ export interface Customizer<TSchema extends ImplicitAllowedTypes> {
152
+ custom<T extends Partial<CustomTypes>>(): CustomizedSchemaTyping<TSchema, {
153
+ [Property in keyof CustomTypes]: Property extends keyof T ? T[Property] extends CustomTypes[Property] ? T[Property] : GetTypes<TSchema>[Property] : GetTypes<TSchema>[Property];
154
+ }>;
155
+ relaxed(): CustomizedSchemaTyping<TSchema, {
156
+ input: TreeNodeSchema extends TSchema ? InsertableContent : TSchema extends TreeNodeSchema ? InsertableTypedNode<TSchema> : TSchema extends AllowedTypes ? TSchema[number] extends LazyItem<infer TSchemaInner extends TreeNodeSchema> ? InsertableTypedNode<TSchemaInner, TSchemaInner> : never : never;
157
+ readWrite: TreeNodeFromImplicitAllowedTypes<TSchema>;
158
+ output: TreeNodeFromImplicitAllowedTypes<TSchema>;
159
+ }>;
160
+ simplified<T extends TreeNodeFromImplicitAllowedTypes<TSchema>>(): CustomizedSchemaTyping<TSchema, {
161
+ input: T;
162
+ readWrite: T;
163
+ output: T;
164
+ }>;
165
+ simplifiedUnrestricted<T extends TreeNode | TreeLeafValue>(): CustomizedSchemaTyping<TSchema, {
166
+ input: T;
167
+ readWrite: T;
168
+ output: T;
169
+ }>;
170
+ strict(): CustomizedSchemaTyping<TSchema, StrictTypes<TSchema>>;
171
+ }
172
+
173
+ // @alpha
174
+ export function customizeSchemaTyping<const TSchema extends ImplicitAllowedTypes>(schema: TSchema): Customizer<TSchema>;
175
+
176
+ // @public @sealed
177
+ export interface CustomTypes {
178
+ readonly input: unknown;
179
+ readonly output: TreeLeafValue | TreeNode;
180
+ readonly readWrite: TreeLeafValue | TreeNode;
181
+ }
182
+
183
+ // @public
184
+ export type DefaultInsertableTreeNodeFromImplicitAllowedTypes<TSchema extends ImplicitAllowedTypes> = [TSchema] extends [TreeNodeSchema] ? InsertableTypedNode<TSchema> : [TSchema] extends [AllowedTypes] ? InsertableTreeNodeFromAllowedTypes<TSchema> : never;
185
+
186
+ // @public
187
+ export type DefaultInsertableTreeNodeFromImplicitAllowedTypesUnsafe<TSchema extends Unenforced<ImplicitAllowedTypes>> = [TSchema] extends [TreeNodeSchemaUnsafe] ? InsertableTypedNodeUnsafe<TSchema> : [TSchema] extends [AllowedTypesUnsafe] ? InsertableTreeNodeFromAllowedTypesUnsafe<TSchema> : never;
188
+
121
189
  // @public @sealed
122
190
  interface DefaultProvider extends ErasedType<"@fluidframework/tree.FieldProvider"> {
123
191
  }
124
192
 
193
+ // @public
194
+ export type DefaultTreeNodeFromImplicitAllowedTypes<TSchema extends ImplicitAllowedTypes = TreeNodeSchema> = TSchema extends TreeNodeSchema ? NodeFromSchema<TSchema> : TSchema extends AllowedTypes ? NodeFromSchema<FlexListToUnion<TSchema>> : unknown;
195
+
196
+ // @public
197
+ export type DefaultTreeNodeFromImplicitAllowedTypesUnsafe<TSchema extends Unenforced<ImplicitAllowedTypes>> = TSchema extends TreeNodeSchemaUnsafe ? NodeFromSchemaUnsafe<TSchema> : TSchema extends AllowedTypesUnsafe ? NodeFromSchemaUnsafe<FlexListToUnion<TSchema>> : unknown;
198
+
125
199
  // @alpha
126
200
  export interface EncodeOptions<TCustom> {
127
201
  readonly useStoredKeys?: boolean;
@@ -145,6 +219,9 @@ export abstract class ErasedType<out Name = unknown> {
145
219
  protected abstract brand(dummy: never): Name;
146
220
  }
147
221
 
222
+ // @alpha
223
+ export function evaluateLazySchema<T extends TreeNodeSchema>(value: LazyItem<T>): T;
224
+
148
225
  // @public
149
226
  type ExtractItemType<Item extends LazyItem> = Item extends () => infer Result ? Result : Item;
150
227
 
@@ -260,6 +337,16 @@ export function getBranch<T extends ImplicitFieldSchema | UnsafeUnknownSchema>(v
260
337
  // @alpha
261
338
  export function getJsonSchema(schema: ImplicitFieldSchema): JsonTreeSchema;
262
339
 
340
+ // @public
341
+ export type GetTypes<TSchema extends ImplicitAllowedTypes> = [TSchema] extends [
342
+ CustomizedSchemaTyping<unknown, infer TCustom>
343
+ ] ? TCustom : StrictTypes<TSchema>;
344
+
345
+ // @public
346
+ export type GetTypesUnsafe<TSchema extends Unenforced<ImplicitAllowedTypes>> = [
347
+ TSchema
348
+ ] extends [CustomizedSchemaTyping<unknown, infer TCustom>] ? TCustom : StrictTypesUnsafe<TSchema>;
349
+
263
350
  // @alpha
264
351
  export interface ICodecOptions {
265
352
  readonly jsonValidator: JsonValidator;
@@ -547,7 +634,7 @@ type _InlineTrick = 0;
547
634
  export type Input<T extends never> = T;
548
635
 
549
636
  // @alpha
550
- export type Insertable<TSchema extends ImplicitAllowedTypes | UnsafeUnknownSchema> = TSchema extends ImplicitAllowedTypes ? InsertableTreeNodeFromImplicitAllowedTypes<TSchema> : InsertableContent;
637
+ export type Insertable<TSchema extends ImplicitAllowedTypes> = InsertableTreeNodeFromImplicitAllowedTypes<TSchema>;
551
638
 
552
639
  // @alpha
553
640
  export type InsertableContent = Unhydrated<TreeNode> | FactoryContent;
@@ -572,7 +659,7 @@ export type InsertableObjectFromSchemaRecordUnsafe<T extends Unenforced<Restrict
572
659
  };
573
660
 
574
661
  // @public
575
- export type InsertableTreeFieldFromImplicitField<TSchemaInput extends ImplicitFieldSchema, TSchema = UnionToIntersection<TSchemaInput>> = [TSchema] extends [FieldSchema<infer Kind, infer Types>] ? ApplyKindInput<InsertableTreeNodeFromImplicitAllowedTypes<Types>, Kind, true> : [TSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes<TSchema> : never;
662
+ export type InsertableTreeFieldFromImplicitField<TSchemaInput extends ImplicitFieldSchema, TSchema = [TSchemaInput] extends [CustomizedSchemaTyping<unknown, CustomTypes>] ? TSchemaInput : SchemaUnionToIntersection<TSchemaInput>> = [TSchema] extends [FieldSchema<infer Kind, infer Types>] ? ApplyKindInput<InsertableTreeNodeFromImplicitAllowedTypes<Types>, Kind, true> : [TSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes<TSchema> : never;
576
663
 
577
664
  // @public
578
665
  export type InsertableTreeFieldFromImplicitFieldUnsafe<TSchemaInput extends Unenforced<ImplicitFieldSchema>, TSchema = UnionToIntersection<TSchemaInput>> = [TSchema] extends [FieldSchemaUnsafe<infer Kind, infer Types>] ? ApplyKindInput<InsertableTreeNodeFromImplicitAllowedTypesUnsafe<Types>, Kind, true> : [TSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypesUnsafe<TSchema> : never;
@@ -590,12 +677,10 @@ LazyItem<infer TSchema extends TreeNodeSchemaUnsafe>,
590
677
  ] ? InsertableTypedNodeUnsafe<TSchema> | InsertableTreeNodeFromAllowedTypesUnsafe<Rest> : never;
591
678
 
592
679
  // @public
593
- export type InsertableTreeNodeFromImplicitAllowedTypes<TSchema extends ImplicitAllowedTypes> = [
594
- TSchema
595
- ] extends [TreeNodeSchema] ? InsertableTypedNode<TSchema> : [TSchema] extends [AllowedTypes] ? InsertableTreeNodeFromAllowedTypes<TSchema> : never;
680
+ export type InsertableTreeNodeFromImplicitAllowedTypes<TSchema extends ImplicitAllowedTypes> = GetTypes<TSchema>["input"];
596
681
 
597
682
  // @public
598
- export type InsertableTreeNodeFromImplicitAllowedTypesUnsafe<TSchema extends Unenforced<ImplicitAllowedTypes>> = [TSchema] extends [TreeNodeSchemaUnsafe] ? InsertableTypedNodeUnsafe<TSchema> : [TSchema] extends [AllowedTypesUnsafe] ? InsertableTreeNodeFromAllowedTypesUnsafe<TSchema> : never;
683
+ export type InsertableTreeNodeFromImplicitAllowedTypesUnsafe<TSchema extends Unenforced<ImplicitAllowedTypes>> = GetTypesUnsafe<TSchema>["input"];
599
684
 
600
685
  // @public
601
686
  export type InsertableTypedNode<TSchema extends TreeNodeSchema, T = UnionToIntersection<TSchema>> = (T extends TreeNodeSchema<string, NodeKind, TreeNode | TreeLeafValue, never, true> ? NodeBuilderData<T> : never) | (T extends TreeNodeSchema ? Unhydrated<TreeNode extends NodeFromSchema<T> ? never : NodeFromSchema<T>> : never);
@@ -706,6 +791,37 @@ export interface JsonArrayNodeSchema extends JsonNodeSchemaBase<NodeKind.Array,
706
791
  readonly items: JsonFieldSchema;
707
792
  }
708
793
 
794
+ // @alpha
795
+ export namespace JsonAsTree {
796
+ const Primitive: readonly [TreeNodeSchemaNonClass_2<"com.fluidframework.leaf.null", NodeKind_2.Leaf, null, null, true, unknown, never, unknown>, TreeNodeSchemaNonClass_2<"com.fluidframework.leaf.boolean", NodeKind_2.Leaf, boolean, boolean, true, unknown, never, unknown>, TreeNodeSchemaNonClass_2<"com.fluidframework.leaf.number", NodeKind_2.Leaf, number, number, true, unknown, never, unknown>, TreeNodeSchemaNonClass_2<"com.fluidframework.leaf.string", NodeKind_2.Leaf, string, string, true, unknown, never, unknown>];
797
+ // @sealed
798
+ export class Array extends _APIExtractorWorkaroundArrayBase {
799
+ }
800
+ const Tree: readonly [() => typeof JsonObject, () => typeof Array, TreeNodeSchemaNonClass_2<"com.fluidframework.leaf.null", NodeKind_2.Leaf, null, null, true, unknown, never, unknown>, TreeNodeSchemaNonClass_2<"com.fluidframework.leaf.boolean", NodeKind_2.Leaf, boolean, boolean, true, unknown, never, unknown>, TreeNodeSchemaNonClass_2<"com.fluidframework.leaf.number", NodeKind_2.Leaf, number, number, true, unknown, never, unknown>, TreeNodeSchemaNonClass_2<"com.fluidframework.leaf.string", NodeKind_2.Leaf, string, string, true, unknown, never, unknown>];
801
+ // @sealed
802
+ export class JsonObject extends _APIExtractorWorkaroundObjectBase {
803
+ }
804
+ const _APIExtractorWorkaroundObjectBase: TreeNodeSchemaClass_2<"com.fluidframework.json.object", NodeKind_2.Map, TreeMapNodeUnsafe_2<readonly [() => typeof JsonObject, () => typeof Array, TreeNodeSchemaNonClass_2<"com.fluidframework.leaf.null", NodeKind_2.Leaf, null, null, true, unknown, never, unknown>, TreeNodeSchemaNonClass_2<"com.fluidframework.leaf.boolean", NodeKind_2.Leaf, boolean, boolean, true, unknown, never, unknown>, TreeNodeSchemaNonClass_2<"com.fluidframework.leaf.number", NodeKind_2.Leaf, number, number, true, unknown, never, unknown>, TreeNodeSchemaNonClass_2<"com.fluidframework.leaf.string", NodeKind_2.Leaf, string, string, true, unknown, never, unknown>]> & WithType_2<"com.fluidframework.json.object", NodeKind_2.Map, unknown>, {
805
+ [Symbol.iterator](): Iterator<[string, string | number | JsonObject | Array | InsertableTypedNodeUnsafe_2<TreeNodeSchemaNonClass_2<"com.fluidframework.leaf.boolean", NodeKind_2.Leaf, boolean, boolean, true, unknown, never, unknown>, TreeNodeSchemaCore_2<"com.fluidframework.leaf.boolean", NodeKind_2.Leaf, true, unknown, boolean, unknown> & {
806
+ create(data: boolean): boolean;
807
+ }> | null], any, undefined>;
808
+ } | {
809
+ readonly [x: string]: string | number | JsonObject | Array | InsertableTypedNodeUnsafe_2<TreeNodeSchemaNonClass_2<"com.fluidframework.leaf.boolean", NodeKind_2.Leaf, boolean, boolean, true, unknown, never, unknown>, TreeNodeSchemaCore_2<"com.fluidframework.leaf.boolean", NodeKind_2.Leaf, true, unknown, boolean, unknown> & {
810
+ create(data: boolean): boolean;
811
+ }> | null;
812
+ }, false, readonly [() => typeof JsonObject, () => typeof Array, TreeNodeSchemaNonClass_2<"com.fluidframework.leaf.null", NodeKind_2.Leaf, null, null, true, unknown, never, unknown>, TreeNodeSchemaNonClass_2<"com.fluidframework.leaf.boolean", NodeKind_2.Leaf, boolean, boolean, true, unknown, never, unknown>, TreeNodeSchemaNonClass_2<"com.fluidframework.leaf.number", NodeKind_2.Leaf, number, number, true, unknown, never, unknown>, TreeNodeSchemaNonClass_2<"com.fluidframework.leaf.string", NodeKind_2.Leaf, string, string, true, unknown, never, unknown>], undefined>;
813
+ // (undocumented)
814
+ export type Primitive = TreeNodeFromImplicitAllowedTypes<typeof Primitive>;
815
+ export type _RecursiveArrayWorkaroundJsonArray = FixRecursiveArraySchema<typeof Array>;
816
+ const _APIExtractorWorkaroundArrayBase: TreeNodeSchemaClass_2<"com.fluidframework.json.array", NodeKind_2.Array, TreeArrayNodeUnsafe_2<readonly [() => typeof JsonObject, () => typeof Array, TreeNodeSchemaNonClass_2<"com.fluidframework.leaf.null", NodeKind_2.Leaf, null, null, true, unknown, never, unknown>, TreeNodeSchemaNonClass_2<"com.fluidframework.leaf.boolean", NodeKind_2.Leaf, boolean, boolean, true, unknown, never, unknown>, TreeNodeSchemaNonClass_2<"com.fluidframework.leaf.number", NodeKind_2.Leaf, number, number, true, unknown, never, unknown>, TreeNodeSchemaNonClass_2<"com.fluidframework.leaf.string", NodeKind_2.Leaf, string, string, true, unknown, never, unknown>]> & WithType_2<"com.fluidframework.json.array", NodeKind_2.Array, unknown>, {
817
+ [Symbol.iterator](): Iterator<string | number | JsonObject | Array | InsertableTypedNodeUnsafe_2<TreeNodeSchemaNonClass_2<"com.fluidframework.leaf.boolean", NodeKind_2.Leaf, boolean, boolean, true, unknown, never, unknown>, TreeNodeSchemaCore_2<"com.fluidframework.leaf.boolean", NodeKind_2.Leaf, true, unknown, boolean, unknown> & {
818
+ create(data: boolean): boolean;
819
+ }> | null, any, undefined>;
820
+ }, false, readonly [() => typeof JsonObject, () => typeof Array, TreeNodeSchemaNonClass_2<"com.fluidframework.leaf.null", NodeKind_2.Leaf, null, null, true, unknown, never, unknown>, TreeNodeSchemaNonClass_2<"com.fluidframework.leaf.boolean", NodeKind_2.Leaf, boolean, boolean, true, unknown, never, unknown>, TreeNodeSchemaNonClass_2<"com.fluidframework.leaf.number", NodeKind_2.Leaf, number, number, true, unknown, never, unknown>, TreeNodeSchemaNonClass_2<"com.fluidframework.leaf.string", NodeKind_2.Leaf, string, string, true, unknown, never, unknown>], undefined>;
821
+ // (undocumented)
822
+ export type Tree = TreeNodeFromImplicitAllowedTypes<typeof Tree>;
823
+ }
824
+
709
825
  // @alpha
710
826
  export type JsonCompatible<TExtra = never> = string | number | boolean | null | JsonCompatible<TExtra>[] | JsonCompatibleObject<TExtra> | TExtra;
711
827
 
@@ -855,12 +971,30 @@ export const noopValidator: JsonValidator;
855
971
 
856
972
  // @public
857
973
  type ObjectFromSchemaRecord<T extends RestrictiveStringRecord<ImplicitFieldSchema>> = {
858
- -readonly [Property in keyof T]: Property extends string ? TreeFieldFromImplicitField<T[Property]> : unknown;
974
+ -readonly [Property in keyof T as [
975
+ AssignableTreeFieldFromImplicitField<T[Property & string]>
976
+ ] extends [never | undefined] ? never : Property]: AssignableTreeFieldFromImplicitField<T[Property & string]>;
977
+ } & {
978
+ readonly [Property in keyof T]: TreeFieldFromImplicitField<T[Property & string]>;
859
979
  };
860
980
 
861
981
  // @public
862
982
  type ObjectFromSchemaRecordUnsafe<T extends Unenforced<RestrictiveStringRecord<ImplicitFieldSchema>>> = {
863
- -readonly [Property in keyof T]: TreeFieldFromImplicitFieldUnsafe<T[Property]>;
983
+ -readonly [Property in keyof T as [T[Property]] extends [
984
+ CustomizedSchemaTyping<unknown, {
985
+ readonly readWrite: never;
986
+ readonly input: unknown;
987
+ readonly output: TreeNode | TreeLeafValue;
988
+ }>
989
+ ] ? never : Property]: AssignableTreeFieldFromImplicitFieldUnsafe<T[Property]>;
990
+ } & {
991
+ readonly [Property in keyof T as [T[Property]] extends [
992
+ CustomizedSchemaTyping<unknown, {
993
+ readonly readWrite: never;
994
+ readonly input: unknown;
995
+ readonly output: TreeNode | TreeLeafValue;
996
+ }>
997
+ ] ? Property : never]: TreeFieldFromImplicitFieldUnsafe<T[Property]>;
864
998
  };
865
999
 
866
1000
  // @public
@@ -1061,6 +1195,11 @@ export const schemaStatics: {
1061
1195
  readonly requiredRecursive: <const T_3 extends unknown>(t: T_3, props?: Omit<FieldProps, "defaultProvider">) => FieldSchemaUnsafe<FieldKind.Required, T_3>;
1062
1196
  };
1063
1197
 
1198
+ // @public
1199
+ export type SchemaUnionToIntersection<T> = [T] extends [
1200
+ CustomizedSchemaTyping<unknown, CustomTypes>
1201
+ ] ? T : UnionToIntersection<T>;
1202
+
1064
1203
  // @alpha
1065
1204
  export interface SchemaValidationFunction<Schema extends TSchema> {
1066
1205
  check(data: unknown): data is Static<Schema>;
@@ -1104,6 +1243,26 @@ export function singletonSchema<TScope extends string, TName extends string | nu
1104
1243
  readonly value: TName;
1105
1244
  }, Record<string, never>, true, Record<string, never>, undefined>;
1106
1245
 
1246
+ // @public @sealed
1247
+ export interface StrictTypes<TSchema extends ImplicitAllowedTypes, TInput = DefaultInsertableTreeNodeFromImplicitAllowedTypes<TSchema>, TOutput extends TreeNode | TreeLeafValue = DefaultTreeNodeFromImplicitAllowedTypes<TSchema>> {
1248
+ // (undocumented)
1249
+ input: TInput;
1250
+ // (undocumented)
1251
+ output: TOutput;
1252
+ // (undocumented)
1253
+ readWrite: TInput extends never ? never : TOutput;
1254
+ }
1255
+
1256
+ // @public
1257
+ export interface StrictTypesUnsafe<TSchema extends Unenforced<ImplicitAllowedTypes>, TInput = DefaultInsertableTreeNodeFromImplicitAllowedTypesUnsafe<TSchema>, TOutput = DefaultTreeNodeFromImplicitAllowedTypesUnsafe<TSchema>> {
1258
+ // (undocumented)
1259
+ input: TInput;
1260
+ // (undocumented)
1261
+ output: TOutput;
1262
+ // (undocumented)
1263
+ readWrite: TOutput;
1264
+ }
1265
+
1107
1266
  // @public
1108
1267
  export interface Tagged<V, T extends string = string> {
1109
1268
  // (undocumented)
@@ -1313,10 +1472,10 @@ export interface TreeNodeApi {
1313
1472
  }
1314
1473
 
1315
1474
  // @public
1316
- export type TreeNodeFromImplicitAllowedTypes<TSchema extends ImplicitAllowedTypes = TreeNodeSchema> = TSchema extends TreeNodeSchema ? NodeFromSchema<TSchema> : TSchema extends AllowedTypes ? NodeFromSchema<FlexListToUnion<TSchema>> : unknown;
1475
+ export type TreeNodeFromImplicitAllowedTypes<TSchema extends ImplicitAllowedTypes = TreeNodeSchema> = GetTypes<TSchema>["output"];
1317
1476
 
1318
1477
  // @public
1319
- type TreeNodeFromImplicitAllowedTypesUnsafe<TSchema extends Unenforced<ImplicitAllowedTypes>> = TSchema extends TreeNodeSchemaUnsafe ? NodeFromSchemaUnsafe<TSchema> : TSchema extends AllowedTypesUnsafe ? NodeFromSchemaUnsafe<FlexListToUnion<TSchema>> : unknown;
1478
+ type TreeNodeFromImplicitAllowedTypesUnsafe<TSchema extends Unenforced<ImplicitAllowedTypes>> = GetTypesUnsafe<TSchema>["output"];
1320
1479
 
1321
1480
  // @public @sealed
1322
1481
  export type TreeNodeSchema<Name extends string = string, Kind extends NodeKind = NodeKind, TNode extends TreeNode | TreeLeafValue = TreeNode | TreeLeafValue, TBuild = never, ImplicitlyConstructable extends boolean = boolean, Info = unknown, TCustomMetadata = unknown> = (TNode extends TreeNode ? TreeNodeSchemaClass<Name, Kind, TNode, TBuild, ImplicitlyConstructable, Info, never, TCustomMetadata> : never) | TreeNodeSchemaNonClass<Name, Kind, TNode, TBuild, ImplicitlyConstructable, Info, never, TCustomMetadata>;
@@ -17,11 +17,22 @@ type ApplyKind<T, Kind extends FieldKind> = {
17
17
  [FieldKind.Identifier]: T;
18
18
  }[Kind];
19
19
 
20
+ // @public
21
+ export type ApplyKindAssignment<T, Kind extends FieldKind> = [Kind] extends [
22
+ FieldKind.Required
23
+ ] ? T : [Kind] extends [FieldKind.Optional] ? T | undefined : never;
24
+
20
25
  // @public
21
26
  type ApplyKindInput<T, Kind extends FieldKind, DefaultsAreOptional extends boolean> = [
22
27
  Kind
23
28
  ] extends [FieldKind.Required] ? T : [Kind] extends [FieldKind.Optional] ? T | undefined : [Kind] extends [FieldKind.Identifier] ? DefaultsAreOptional extends true ? T | undefined : T : never;
24
29
 
30
+ // @public
31
+ export type AssignableTreeFieldFromImplicitField<TSchemaInput extends ImplicitFieldSchema, TSchema = SchemaUnionToIntersection<TSchemaInput>> = [TSchema] extends [FieldSchema<infer Kind, infer Types>] ? ApplyKindAssignment<GetTypes<Types>["readWrite"], Kind> : [TSchema] extends [ImplicitAllowedTypes] ? GetTypes<TSchema>["readWrite"] : never;
32
+
33
+ // @public
34
+ export type AssignableTreeFieldFromImplicitFieldUnsafe<TSchema extends Unenforced<ImplicitFieldSchema>> = TSchema extends FieldSchemaUnsafe<infer Kind, infer Types> ? ApplyKindAssignment<GetTypesUnsafe<Types>["readWrite"], Kind> : GetTypesUnsafe<TSchema>["readWrite"];
35
+
25
36
  // @public
26
37
  export enum AttachState {
27
38
  Attached = "Attached",
@@ -70,10 +81,40 @@ export interface ContainerSchema {
70
81
  readonly initialObjects: Record<string, SharedObjectKind>;
71
82
  }
72
83
 
84
+ // @public
85
+ export type CustomizedSchemaTyping<TSchema, TCustom extends CustomTypes> = TSchema & {
86
+ [CustomizedTyping]: TCustom;
87
+ };
88
+
89
+ // @public
90
+ export const CustomizedTyping: unique symbol;
91
+
92
+ // @public
93
+ export type CustomizedTyping = typeof CustomizedTyping;
94
+
95
+ // @public @sealed
96
+ export interface CustomTypes {
97
+ readonly input: unknown;
98
+ readonly output: TreeLeafValue | TreeNode;
99
+ readonly readWrite: TreeLeafValue | TreeNode;
100
+ }
101
+
102
+ // @public
103
+ export type DefaultInsertableTreeNodeFromImplicitAllowedTypes<TSchema extends ImplicitAllowedTypes> = [TSchema] extends [TreeNodeSchema] ? InsertableTypedNode<TSchema> : [TSchema] extends [AllowedTypes] ? InsertableTreeNodeFromAllowedTypes<TSchema> : never;
104
+
105
+ // @public
106
+ export type DefaultInsertableTreeNodeFromImplicitAllowedTypesUnsafe<TSchema extends Unenforced<ImplicitAllowedTypes>> = [TSchema] extends [TreeNodeSchemaUnsafe] ? InsertableTypedNodeUnsafe<TSchema> : [TSchema] extends [AllowedTypesUnsafe] ? InsertableTreeNodeFromAllowedTypesUnsafe<TSchema> : never;
107
+
73
108
  // @public @sealed
74
109
  interface DefaultProvider extends ErasedType<"@fluidframework/tree.FieldProvider"> {
75
110
  }
76
111
 
112
+ // @public
113
+ export type DefaultTreeNodeFromImplicitAllowedTypes<TSchema extends ImplicitAllowedTypes = TreeNodeSchema> = TSchema extends TreeNodeSchema ? NodeFromSchema<TSchema> : TSchema extends AllowedTypes ? NodeFromSchema<FlexListToUnion<TSchema>> : unknown;
114
+
115
+ // @public
116
+ export type DefaultTreeNodeFromImplicitAllowedTypesUnsafe<TSchema extends Unenforced<ImplicitAllowedTypes>> = TSchema extends TreeNodeSchemaUnsafe ? NodeFromSchemaUnsafe<TSchema> : TSchema extends AllowedTypesUnsafe ? NodeFromSchemaUnsafe<FlexListToUnion<TSchema>> : unknown;
117
+
77
118
  // @public @sealed
78
119
  export abstract class ErasedType<out Name = unknown> {
79
120
  static [Symbol.hasInstance](value: never): value is never;
@@ -146,6 +187,16 @@ export type FluidObject<T = unknown> = {
146
187
  // @public
147
188
  export type FluidObjectProviderKeys<T, TProp extends keyof T = keyof T> = string extends TProp ? never : number extends TProp ? never : TProp extends keyof Required<T>[TProp] ? Required<T>[TProp] extends Required<Required<T>[TProp]>[TProp] ? TProp : never : never;
148
189
 
190
+ // @public
191
+ export type GetTypes<TSchema extends ImplicitAllowedTypes> = [TSchema] extends [
192
+ CustomizedSchemaTyping<unknown, infer TCustom>
193
+ ] ? TCustom : StrictTypes<TSchema>;
194
+
195
+ // @public
196
+ export type GetTypesUnsafe<TSchema extends Unenforced<ImplicitAllowedTypes>> = [
197
+ TSchema
198
+ ] extends [CustomizedSchemaTyping<unknown, infer TCustom>] ? TCustom : StrictTypesUnsafe<TSchema>;
199
+
149
200
  // @public
150
201
  export interface IConnection {
151
202
  readonly id: string;
@@ -431,7 +482,7 @@ export type InsertableObjectFromSchemaRecordUnsafe<T extends Unenforced<Restrict
431
482
  };
432
483
 
433
484
  // @public
434
- export type InsertableTreeFieldFromImplicitField<TSchemaInput extends ImplicitFieldSchema, TSchema = UnionToIntersection<TSchemaInput>> = [TSchema] extends [FieldSchema<infer Kind, infer Types>] ? ApplyKindInput<InsertableTreeNodeFromImplicitAllowedTypes<Types>, Kind, true> : [TSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes<TSchema> : never;
485
+ export type InsertableTreeFieldFromImplicitField<TSchemaInput extends ImplicitFieldSchema, TSchema = [TSchemaInput] extends [CustomizedSchemaTyping<unknown, CustomTypes>] ? TSchemaInput : SchemaUnionToIntersection<TSchemaInput>> = [TSchema] extends [FieldSchema<infer Kind, infer Types>] ? ApplyKindInput<InsertableTreeNodeFromImplicitAllowedTypes<Types>, Kind, true> : [TSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes<TSchema> : never;
435
486
 
436
487
  // @public
437
488
  export type InsertableTreeFieldFromImplicitFieldUnsafe<TSchemaInput extends Unenforced<ImplicitFieldSchema>, TSchema = UnionToIntersection<TSchemaInput>> = [TSchema] extends [FieldSchemaUnsafe<infer Kind, infer Types>] ? ApplyKindInput<InsertableTreeNodeFromImplicitAllowedTypesUnsafe<Types>, Kind, true> : [TSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypesUnsafe<TSchema> : never;
@@ -449,12 +500,10 @@ LazyItem<infer TSchema extends TreeNodeSchemaUnsafe>,
449
500
  ] ? InsertableTypedNodeUnsafe<TSchema> | InsertableTreeNodeFromAllowedTypesUnsafe<Rest> : never;
450
501
 
451
502
  // @public
452
- export type InsertableTreeNodeFromImplicitAllowedTypes<TSchema extends ImplicitAllowedTypes> = [
453
- TSchema
454
- ] extends [TreeNodeSchema] ? InsertableTypedNode<TSchema> : [TSchema] extends [AllowedTypes] ? InsertableTreeNodeFromAllowedTypes<TSchema> : never;
503
+ export type InsertableTreeNodeFromImplicitAllowedTypes<TSchema extends ImplicitAllowedTypes> = GetTypes<TSchema>["input"];
455
504
 
456
505
  // @public
457
- export type InsertableTreeNodeFromImplicitAllowedTypesUnsafe<TSchema extends Unenforced<ImplicitAllowedTypes>> = [TSchema] extends [TreeNodeSchemaUnsafe] ? InsertableTypedNodeUnsafe<TSchema> : [TSchema] extends [AllowedTypesUnsafe] ? InsertableTreeNodeFromAllowedTypesUnsafe<TSchema> : never;
506
+ export type InsertableTreeNodeFromImplicitAllowedTypesUnsafe<TSchema extends Unenforced<ImplicitAllowedTypes>> = GetTypesUnsafe<TSchema>["input"];
458
507
 
459
508
  // @public
460
509
  export type InsertableTypedNode<TSchema extends TreeNodeSchema, T = UnionToIntersection<TSchema>> = (T extends TreeNodeSchema<string, NodeKind, TreeNode | TreeLeafValue, never, true> ? NodeBuilderData<T> : never) | (T extends TreeNodeSchema ? Unhydrated<TreeNode extends NodeFromSchema<T> ? never : NodeFromSchema<T>> : never);
@@ -632,12 +681,30 @@ export interface NodeSchemaOptions<out TCustomMetadata = unknown> {
632
681
 
633
682
  // @public
634
683
  type ObjectFromSchemaRecord<T extends RestrictiveStringRecord<ImplicitFieldSchema>> = {
635
- -readonly [Property in keyof T]: Property extends string ? TreeFieldFromImplicitField<T[Property]> : unknown;
684
+ -readonly [Property in keyof T as [
685
+ AssignableTreeFieldFromImplicitField<T[Property & string]>
686
+ ] extends [never | undefined] ? never : Property]: AssignableTreeFieldFromImplicitField<T[Property & string]>;
687
+ } & {
688
+ readonly [Property in keyof T]: TreeFieldFromImplicitField<T[Property & string]>;
636
689
  };
637
690
 
638
691
  // @public
639
692
  type ObjectFromSchemaRecordUnsafe<T extends Unenforced<RestrictiveStringRecord<ImplicitFieldSchema>>> = {
640
- -readonly [Property in keyof T]: TreeFieldFromImplicitFieldUnsafe<T[Property]>;
693
+ -readonly [Property in keyof T as [T[Property]] extends [
694
+ CustomizedSchemaTyping<unknown, {
695
+ readonly readWrite: never;
696
+ readonly input: unknown;
697
+ readonly output: TreeNode | TreeLeafValue;
698
+ }>
699
+ ] ? never : Property]: AssignableTreeFieldFromImplicitFieldUnsafe<T[Property]>;
700
+ } & {
701
+ readonly [Property in keyof T as [T[Property]] extends [
702
+ CustomizedSchemaTyping<unknown, {
703
+ readonly readWrite: never;
704
+ readonly input: unknown;
705
+ readonly output: TreeNode | TreeLeafValue;
706
+ }>
707
+ ] ? Property : never]: TreeFieldFromImplicitFieldUnsafe<T[Property]>;
641
708
  };
642
709
 
643
710
  // @public
@@ -784,6 +851,11 @@ export const schemaStatics: {
784
851
  readonly requiredRecursive: <const T_3 extends unknown>(t: T_3, props?: Omit<FieldProps, "defaultProvider">) => FieldSchemaUnsafe<FieldKind.Required, T_3>;
785
852
  };
786
853
 
854
+ // @public
855
+ export type SchemaUnionToIntersection<T> = [T] extends [
856
+ CustomizedSchemaTyping<unknown, CustomTypes>
857
+ ] ? T : UnionToIntersection<T>;
858
+
787
859
  // @public
788
860
  type ScopedSchemaName<TScope extends string | undefined, TName extends number | string> = TScope extends undefined ? `${TName}` : `${TScope}.${TName}`;
789
861
 
@@ -795,6 +867,26 @@ export interface SharedObjectKind<out TSharedObject = unknown> extends ErasedTyp
795
867
  // @public
796
868
  export const SharedTree: SharedObjectKind<ITree>;
797
869
 
870
+ // @public @sealed
871
+ export interface StrictTypes<TSchema extends ImplicitAllowedTypes, TInput = DefaultInsertableTreeNodeFromImplicitAllowedTypes<TSchema>, TOutput extends TreeNode | TreeLeafValue = DefaultTreeNodeFromImplicitAllowedTypes<TSchema>> {
872
+ // (undocumented)
873
+ input: TInput;
874
+ // (undocumented)
875
+ output: TOutput;
876
+ // (undocumented)
877
+ readWrite: TInput extends never ? never : TOutput;
878
+ }
879
+
880
+ // @public
881
+ export interface StrictTypesUnsafe<TSchema extends Unenforced<ImplicitAllowedTypes>, TInput = DefaultInsertableTreeNodeFromImplicitAllowedTypesUnsafe<TSchema>, TOutput = DefaultTreeNodeFromImplicitAllowedTypesUnsafe<TSchema>> {
882
+ // (undocumented)
883
+ input: TInput;
884
+ // (undocumented)
885
+ output: TOutput;
886
+ // (undocumented)
887
+ readWrite: TOutput;
888
+ }
889
+
798
890
  // @public
799
891
  export interface Tagged<V, T extends string = string> {
800
892
  // (undocumented)
@@ -916,10 +1008,10 @@ export interface TreeNodeApi {
916
1008
  }
917
1009
 
918
1010
  // @public
919
- export type TreeNodeFromImplicitAllowedTypes<TSchema extends ImplicitAllowedTypes = TreeNodeSchema> = TSchema extends TreeNodeSchema ? NodeFromSchema<TSchema> : TSchema extends AllowedTypes ? NodeFromSchema<FlexListToUnion<TSchema>> : unknown;
1011
+ export type TreeNodeFromImplicitAllowedTypes<TSchema extends ImplicitAllowedTypes = TreeNodeSchema> = GetTypes<TSchema>["output"];
920
1012
 
921
1013
  // @public
922
- type TreeNodeFromImplicitAllowedTypesUnsafe<TSchema extends Unenforced<ImplicitAllowedTypes>> = TSchema extends TreeNodeSchemaUnsafe ? NodeFromSchemaUnsafe<TSchema> : TSchema extends AllowedTypesUnsafe ? NodeFromSchemaUnsafe<FlexListToUnion<TSchema>> : unknown;
1014
+ type TreeNodeFromImplicitAllowedTypesUnsafe<TSchema extends Unenforced<ImplicitAllowedTypes>> = GetTypesUnsafe<TSchema>["output"];
923
1015
 
924
1016
  // @public @sealed
925
1017
  export type TreeNodeSchema<Name extends string = string, Kind extends NodeKind = NodeKind, TNode extends TreeNode | TreeLeafValue = TreeNode | TreeLeafValue, TBuild = never, ImplicitlyConstructable extends boolean = boolean, Info = unknown, TCustomMetadata = unknown> = (TNode extends TreeNode ? TreeNodeSchemaClass<Name, Kind, TNode, TBuild, ImplicitlyConstructable, Info, never, TCustomMetadata> : never) | TreeNodeSchemaNonClass<Name, Kind, TNode, TBuild, ImplicitlyConstructable, Info, never, TCustomMetadata>;