fluid-framework 2.92.0 → 2.100.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,51 @@
1
1
  # fluid-framework
2
2
 
3
+ ## 2.100.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Node 22 is now the minimum supported Node.js version ([#27116](https://github.com/microsoft/FluidFramework/pull/27116)) [e8214d29663](https://github.com/microsoft/FluidFramework/commit/e8214d29663f5ee98d737daed82506a25d8de8d0)
8
+
9
+ All Fluid Framework client packages now require Node.js 22 or later. This aligns with the standing Node upgrade policy as Node 20 reaches end-of-life on April 30, 2026.
10
+
11
+ ## 2.93.0
12
+
13
+ ### Minor Changes
14
+
15
+ - `getPresence` from `@fluidframework/presence` is deprecated and will be removed in a future release. ([#26399](https://github.com/microsoft/FluidFramework/pull/26399)) [d533c19c7c](https://github.com/microsoft/FluidFramework/commit/d533c19c7cb25d48ecab1b742e44dfe560d20534)
16
+
17
+ Now `getPresence` is available for import from the `fluid-framework` package.
18
+
19
+ To prepare, make changes following this pattern:
20
+
21
+ ```diff
22
+ -import { getPresence } from "@fluidframework/presence/beta";
23
+ +import { getPresence } from "fluid-framework";
24
+ ```
25
+
26
+ See [issue #26397](https://github.com/microsoft/FluidFramework/issues/26397) for more details.
27
+
28
+ - Add Fluid-controlled map and iterator interfaces ([#26951](https://github.com/microsoft/FluidFramework/pull/26951)) [4735742f15](https://github.com/microsoft/FluidFramework/commit/4735742f15718419e974ead1d5e2e809863d3723)
29
+
30
+ `TreeIndex` now extends `FluidReadonlyMap` instead of the built-in `ReadonlyMap`, and `TreeMapNodeAlpha` which extends `FluidReadonlyMap` instead of the built-in `ReadonlyMap` has been added.
31
+ This works to uncouple Fluid's public API surface to the TypeScript standard library's map types, preventing future breakage when those types change.
32
+
33
+ - Promote tree index APIs from alpha to beta ([#26993](https://github.com/microsoft/FluidFramework/pull/26993)) [37f2f17c118](https://github.com/microsoft/FluidFramework/commit/37f2f17c118baea142b0e842f5b262255d8bb12c)
34
+
35
+ The following APIs have been promoted from `@alpha` to `@beta`:
36
+ - `TreeIndex`
37
+ - `TreeIndexKey`
38
+ - `TreeIndexNodes`
39
+ - `createTreeIndex`
40
+ - `IdentifierIndex`
41
+ - `createIdentifierIndex`
42
+
43
+ Additionally, the following `@fluidframework/core-interfaces` types have been promoted from `@alpha` to `@beta`:
44
+ - `FluidReadonlyMap`
45
+ - `FluidIterable`
46
+ - `FluidIterableIterator`
47
+ - `FluidMap`
48
+
3
49
  ## 2.92.0
4
50
 
5
51
  ### Minor Changes
package/README.md CHANGED
@@ -91,7 +91,7 @@ When making such a request please include if the configuration already works (an
91
91
 
92
92
  ### Supported Runtimes
93
93
 
94
- - NodeJs ^20.10.0 except that we will drop support for it [when NodeJs 20 loses its upstream support on 2026-04-30](https://github.com/nodejs/release#release-schedule), and will support a newer LTS version of NodeJS (22) at least 1 year before 20 is end-of-life. This same policy applies to NodeJS 22 when it is end of life (2027-04-30).
94
+ - NodeJs ^22.22.2 except that we will drop support for it [when NodeJs 22 loses its upstream support on 2027-04-30](https://github.com/nodejs/release#release-schedule), and will support a newer LTS version of NodeJS at least 1 year before 22 is end-of-life.
95
95
  - Running Fluid in a Node.js environment with the `--no-experimental-fetch` flag is not supported.
96
96
  - Modern browsers supporting the es2022 standard library: in response to asks we can add explicit support for using babel to polyfill to target specific standards or runtimes (meaning we can avoid/remove use of things that don't polyfill robustly, but otherwise target modern standards).
97
97
 
@@ -145,6 +145,14 @@ export const ArrayNodeSchema: {
145
145
  readonly [Symbol.hasInstance]: (value: TreeNodeSchema) => value is ArrayNodeSchema;
146
146
  };
147
147
 
148
+ // @alpha
149
+ export type ArrayNodeTreeChangedDeltaOp = ArrayNodeTreeChangedRetainOp | ArrayNodeInsertOp | ArrayNodeRemoveOp;
150
+
151
+ // @alpha @sealed
152
+ export interface ArrayNodeTreeChangedRetainOp extends ArrayNodeRetainOp {
153
+ readonly subtreeChanged: boolean;
154
+ }
155
+
148
156
  // @alpha @sealed
149
157
  export interface ArrayPlaceAnchor {
150
158
  get index(): number;
@@ -159,6 +167,9 @@ export function asAlpha<TSchema extends ImplicitFieldSchema>(view: TreeViewConfi
159
167
  // @alpha
160
168
  export function asAlpha<TAllowedTypes extends ImplicitAllowedTypes>(node: TreeArrayNode<TAllowedTypes>): TreeArrayNodeAlpha<TAllowedTypes>;
161
169
 
170
+ // @alpha
171
+ export function asAlpha<TAllowedTypes extends ImplicitAllowedTypes>(node: TreeMapNode<TAllowedTypes>): TreeMapNodeAlpha<TAllowedTypes>;
172
+
162
173
  // @beta
163
174
  export function asBeta<TSchema extends ImplicitFieldSchema>(view: TreeView<TSchema>): TreeViewBeta<TSchema>;
164
175
 
@@ -266,7 +277,7 @@ export const contentSchemaSymbol: unique symbol;
266
277
  // @alpha
267
278
  export function createArrayInsertionAnchor(node: TreeArrayNode, currentIndex: number): ArrayPlaceAnchor;
268
279
 
269
- // @alpha
280
+ // @beta
270
281
  export function createIdentifierIndex<TSchema extends ImplicitFieldSchema>(view: TreeView<TSchema>): IdentifierIndex;
271
282
 
272
283
  // @alpha
@@ -283,16 +294,16 @@ export type CreateIndependentTreeAlphaOptions = ForestOptions & ((IndependentVie
283
294
  // @beta
284
295
  export function createIndependentTreeBeta<const TSchema extends ImplicitFieldSchema>(options?: ForestOptions): ViewableTree;
285
296
 
286
- // @alpha
297
+ // @beta
287
298
  export function createTreeIndex<TFieldSchema extends ImplicitFieldSchema, TKey extends TreeIndexKey, TValue>(view: TreeView<TFieldSchema>, indexer: (schema: TreeNodeSchema) => string | undefined, getValue: (nodes: TreeIndexNodes<TreeNode>) => TValue, isKeyValid: (key: TreeIndexKey) => key is TKey): TreeIndex<TKey, TValue>;
288
299
 
289
- // @alpha
300
+ // @beta
290
301
  export function createTreeIndex<TFieldSchema extends ImplicitFieldSchema, TKey extends TreeIndexKey, TValue, TSchema extends TreeNodeSchema>(view: TreeView<TFieldSchema>, indexer: (schema: TSchema) => string | undefined, getValue: (nodes: TreeIndexNodes<NodeFromSchema<TSchema>>) => TValue, isKeyValid: (key: TreeIndexKey) => key is TKey, indexableSchema: readonly TSchema[]): TreeIndex<TKey, TValue>;
291
302
 
292
- // @alpha
303
+ // @beta
293
304
  export function createTreeIndex<TFieldSchema extends ImplicitFieldSchema, TKey extends TreeIndexKey, TValue>(view: TreeView<TFieldSchema>, indexer: Map<TreeNodeSchema, string>, getValue: (nodes: TreeIndexNodes<TreeNode>) => TValue, isKeyValid: (key: TreeIndexKey) => key is TKey): TreeIndex<TKey, TValue>;
294
305
 
295
- // @alpha
306
+ // @beta
296
307
  export function createTreeIndex<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[]): TreeIndex<TKey, TValue>;
297
308
 
298
309
  // @alpha
@@ -362,7 +373,7 @@ export function exportCompatibilitySchemaSnapshot(config: Pick<TreeViewConfigura
362
373
 
363
374
  // @beta
364
375
  export namespace ExtensibleUnionNode {
365
- export function createSchema<const T extends readonly TreeNodeSchema[], const TScope extends string, const TName extends string>(types: T, inputSchemaFactory: SchemaFactoryBeta<TScope>, name: TName): Statics<T> & TreeNodeSchemaCore_2<ScopedSchemaName_2<`com.fluidframework.extensibleUnionNode<${TScope}>`, TName>, NodeKind_2, false, unknown, never, unknown> & (new (data: InternalTreeNode_2) => Members<TreeNodeFromImplicitAllowedTypes<T>> & TreeNode_2 & WithType_2<ScopedSchemaName_2<`com.fluidframework.extensibleUnionNode<${TScope}>`, TName>, NodeKind_2, unknown>);
376
+ export function createSchema<const T extends readonly TreeNodeSchema[], const TScope extends string, const TName extends string>(types: T, inputSchemaFactory: SchemaFactoryBeta<TScope>, name: TName): Statics<T> & TreeNodeSchemaCore<ScopedSchemaName<`com.fluidframework.extensibleUnionNode<${TScope}>`, TName>, NodeKind, false, unknown, never, unknown> & (new (data: InternalTreeNode) => Members<TreeNodeFromImplicitAllowedTypes<T>> & TreeNode & WithType<ScopedSchemaName<`com.fluidframework.extensibleUnionNode<${TScope}>`, TName>, NodeKind, unknown>);
366
377
  export interface Members<T> {
367
378
  isValid(): boolean;
368
379
  readonly union: T | undefined;
@@ -420,6 +431,7 @@ export interface FieldProps<TCustomMetadata = unknown> {
420
431
  // @alpha @input
421
432
  export interface FieldPropsAlpha<TCustomMetadata = unknown> extends FieldProps<TCustomMetadata> {
422
433
  readonly persistedMetadata?: JsonCompatibleReadOnlyObject | undefined;
434
+ readonly stagedOptionalUpgrade?: SchemaUpgrade;
423
435
  }
424
436
 
425
437
  // @public @sealed
@@ -444,6 +456,8 @@ export class FieldSchemaAlpha<Kind extends FieldKind = FieldKind, Types extends
444
456
  // (undocumented)
445
457
  get allowedTypesIdentifiers(): ReadonlySet<string>;
446
458
  // (undocumented)
459
+ get isStagedOptional(): false | SchemaUpgrade;
460
+ // (undocumented)
447
461
  get persistedMetadata(): JsonCompatibleReadOnlyObject | undefined;
448
462
  // (undocumented)
449
463
  get simpleAllowedTypes(): ReadonlyMap<string, SimpleAllowedTypeAttributes<SchemaType.View>>;
@@ -484,6 +498,29 @@ export const FluidClientVersion: {
484
498
  readonly v2_80: "2.80.0";
485
499
  };
486
500
 
501
+ // @beta @sealed
502
+ export interface FluidIterable<T> {
503
+ [Symbol.iterator](): FluidIterableIterator<T>;
504
+ }
505
+
506
+ // @beta @sealed
507
+ export interface FluidIterableIterator<T> extends FluidIterable<T> {
508
+ next(): {
509
+ value: T;
510
+ done?: false;
511
+ } | {
512
+ value: any;
513
+ done: true;
514
+ };
515
+ }
516
+
517
+ // @beta @sealed
518
+ export interface FluidMap<K, V> extends FluidReadonlyMap<K, V> {
519
+ delete(key: K): void;
520
+ forEach(callbackfn: (value: V, key: K, map: FluidMap<K, V>) => void, thisArg?: any): void;
521
+ set(key: K, value: V): void;
522
+ }
523
+
487
524
  // @public
488
525
  export type FluidObject<T = unknown> = {
489
526
  [P in FluidObjectProviderKeys<T>]?: T[P];
@@ -492,26 +529,39 @@ export type FluidObject<T = unknown> = {
492
529
  // @public
493
530
  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;
494
531
 
532
+ // @beta @sealed
533
+ export interface FluidReadonlyMap<K, V> {
534
+ [Symbol.iterator](): FluidIterableIterator<[K, V]>;
535
+ readonly [Symbol.toStringTag]: string;
536
+ entries(): FluidIterableIterator<[K, V]>;
537
+ forEach(callbackfn: (value: V, key: K, map: FluidReadonlyMap<K, V>) => void, thisArg?: any): void;
538
+ get(key: K): V | undefined;
539
+ has(key: K): boolean;
540
+ keys(): FluidIterableIterator<K>;
541
+ readonly size: number;
542
+ values(): FluidIterableIterator<V>;
543
+ }
544
+
495
545
  // @beta
496
546
  export namespace FluidSerializableAsTree {
497
547
  // @sealed
498
548
  export class Array extends _APIExtractorWorkaroundArrayBase {
499
549
  }
500
- const Tree: readonly [() => typeof FluidSerializableObject, () => typeof Array, LeafSchema_2<"string", string>, LeafSchema_2<"number", number>, LeafSchema_2<"boolean", boolean>, LeafSchema_2<"null", null>, LeafSchema_2<"handle", IFluidHandle<unknown>>];
550
+ const Tree: readonly [() => typeof FluidSerializableObject, () => typeof Array, LeafSchema<"string", string>, LeafSchema<"number", number>, LeafSchema<"boolean", boolean>, LeafSchema<"null", null>, LeafSchema<"handle", IFluidHandle<unknown>>];
501
551
  export type Data = JsonCompatible<IFluidHandle>;
502
552
  const // @system
503
- _APIExtractorWorkaroundObjectBase: TreeNodeSchemaClass_2<"com.fluidframework.serializable.object", NodeKind_2.Record, TreeRecordNodeUnsafe_2<readonly [() => typeof FluidSerializableObject, () => typeof Array, LeafSchema_2<"string", string>, LeafSchema_2<"number", number>, LeafSchema_2<"boolean", boolean>, LeafSchema_2<"null", null>, LeafSchema_2<"handle", IFluidHandle<unknown>>]> & WithType_2<"com.fluidframework.serializable.object", NodeKind_2.Record, unknown>, {
504
- readonly [x: string]: string | number | IFluidHandle<unknown> | System_Unsafe_2.InsertableTypedNodeUnsafe<LeafSchema_2<"boolean", boolean>, LeafSchema_2<"boolean", boolean>> | FluidSerializableObject | Array | null;
505
- }, false, readonly [() => typeof FluidSerializableObject, () => typeof Array, LeafSchema_2<"string", string>, LeafSchema_2<"number", number>, LeafSchema_2<"boolean", boolean>, LeafSchema_2<"null", null>, LeafSchema_2<"handle", IFluidHandle<unknown>>], undefined, unknown>;
553
+ _APIExtractorWorkaroundObjectBase: TreeNodeSchemaClass<"com.fluidframework.serializable.object", NodeKind.Record, TreeRecordNodeUnsafe<readonly [() => typeof FluidSerializableObject, () => typeof Array, LeafSchema<"string", string>, LeafSchema<"number", number>, LeafSchema<"boolean", boolean>, LeafSchema<"null", null>, LeafSchema<"handle", IFluidHandle<unknown>>]> & WithType<"com.fluidframework.serializable.object", NodeKind.Record, unknown>, {
554
+ readonly [x: string]: string | number | IFluidHandle<unknown> | System_Unsafe.InsertableTypedNodeUnsafe<LeafSchema<"boolean", boolean>, LeafSchema<"boolean", boolean>> | FluidSerializableObject | Array | null;
555
+ }, false, readonly [() => typeof FluidSerializableObject, () => typeof Array, LeafSchema<"string", string>, LeafSchema<"number", number>, LeafSchema<"boolean", boolean>, LeafSchema<"null", null>, LeafSchema<"handle", IFluidHandle<unknown>>], undefined, unknown>;
506
556
  // @sealed
507
557
  export class FluidSerializableObject extends _APIExtractorWorkaroundObjectBase {
508
558
  }
509
559
  // @system
510
560
  export type _RecursiveArrayWorkaroundJsonArray = FixRecursiveArraySchema<typeof Array>;
511
561
  const // @system
512
- _APIExtractorWorkaroundArrayBase: TreeNodeSchemaClass_2<"com.fluidframework.serializable.array", NodeKind_2.Array, System_Unsafe_2.TreeArrayNodeUnsafe<readonly [() => typeof FluidSerializableObject, () => typeof Array, LeafSchema_2<"string", string>, LeafSchema_2<"number", number>, LeafSchema_2<"boolean", boolean>, LeafSchema_2<"null", null>, LeafSchema_2<"handle", IFluidHandle<unknown>>]> & WithType_2<"com.fluidframework.serializable.array", NodeKind_2.Array, unknown>, {
513
- [Symbol.iterator](): Iterator<string | number | IFluidHandle<unknown> | System_Unsafe_2.InsertableTypedNodeUnsafe<LeafSchema_2<"boolean", boolean>, LeafSchema_2<"boolean", boolean>> | FluidSerializableObject | Array | null, any, undefined>;
514
- }, false, readonly [() => typeof FluidSerializableObject, () => typeof Array, LeafSchema_2<"string", string>, LeafSchema_2<"number", number>, LeafSchema_2<"boolean", boolean>, LeafSchema_2<"null", null>, LeafSchema_2<"handle", IFluidHandle<unknown>>], undefined>;
562
+ _APIExtractorWorkaroundArrayBase: TreeNodeSchemaClass<"com.fluidframework.serializable.array", NodeKind.Array, System_Unsafe.TreeArrayNodeUnsafe<readonly [() => typeof FluidSerializableObject, () => typeof Array, LeafSchema<"string", string>, LeafSchema<"number", number>, LeafSchema<"boolean", boolean>, LeafSchema<"null", null>, LeafSchema<"handle", IFluidHandle<unknown>>]> & WithType<"com.fluidframework.serializable.array", NodeKind.Array, unknown>, {
563
+ [Symbol.iterator](): Iterator<string | number | IFluidHandle<unknown> | System_Unsafe.InsertableTypedNodeUnsafe<LeafSchema<"boolean", boolean>, LeafSchema<"boolean", boolean>> | FluidSerializableObject | Array | null, any, undefined>;
564
+ }, false, readonly [() => typeof FluidSerializableObject, () => typeof Array, LeafSchema<"string", string>, LeafSchema<"number", number>, LeafSchema<"boolean", boolean>, LeafSchema<"null", null>, LeafSchema<"handle", IFluidHandle<unknown>>], undefined>;
515
565
  // (undocumented)
516
566
  export type Tree = TreeNodeFromImplicitAllowedTypes<typeof Tree>;
517
567
  }
@@ -539,7 +589,7 @@ export interface FormatValidator extends ErasedType<"FormatValidator"> {
539
589
  }
540
590
 
541
591
  // @alpha
542
- export const FormatValidatorBasic: FormatValidator_2;
592
+ export const FormatValidatorBasic: FormatValidator;
543
593
 
544
594
  // @alpha
545
595
  export const FormatValidatorNoOp: FormatValidator;
@@ -553,6 +603,12 @@ export function generateSchemaFromSimpleSchema(simple: SimpleTreeSchema): TreeSc
553
603
  // @alpha
554
604
  export function getJsonSchema(schema: ImplicitAllowedTypes, options: Required<TreeSchemaEncodingOptions>): JsonTreeSchema;
555
605
 
606
+ // @public
607
+ export const getPresence: (fluidContainer: IFluidContainer) => Presence;
608
+
609
+ // @alpha
610
+ export function getPresenceAlpha(fluidContainer: IFluidContainer): PresenceWithNotifications;
611
+
556
612
  // @alpha
557
613
  export function getSimpleSchema(schema: ImplicitFieldSchema): SimpleTreeSchema<SchemaType.View>;
558
614
 
@@ -573,7 +629,7 @@ export interface IConnection {
573
629
  // @public
574
630
  export type ICriticalContainerError = IErrorBase;
575
631
 
576
- // @alpha
632
+ // @beta
577
633
  export type IdentifierIndex = TreeIndex<string, TreeNode>;
578
634
 
579
635
  // @public @sealed
@@ -1155,7 +1211,7 @@ export interface MakeNominal {
1155
1211
  }
1156
1212
 
1157
1213
  // @alpha @sealed @system
1158
- export interface MapNodeCustomizableSchema<out TName extends string = string, in out T extends ImplicitAllowedTypes = ImplicitAllowedTypes, out ImplicitlyConstructable extends boolean = true, out TCustomMetadata = unknown> extends TreeNodeSchemaClass<TName, NodeKind.Map, TreeMapNode<T> & WithType<TName, NodeKind.Map, T>, MapNodeInsertableData<T>, ImplicitlyConstructable, T, undefined, TCustomMetadata>, SimpleMapNodeSchema<SchemaType.View, TCustomMetadata> {
1214
+ export interface MapNodeCustomizableSchema<out TName extends string = string, in out T extends ImplicitAllowedTypes = ImplicitAllowedTypes, out ImplicitlyConstructable extends boolean = true, out TCustomMetadata = unknown> extends TreeNodeSchemaClass<TName, NodeKind.Map, TreeMapNodeAlpha<T> & WithType<TName, NodeKind.Map, T>, MapNodeInsertableData<T>, ImplicitlyConstructable, T, undefined, TCustomMetadata>, SimpleMapNodeSchema<SchemaType.View, TCustomMetadata> {
1159
1215
  }
1160
1216
 
1161
1217
  // @alpha @sealed @system
@@ -1173,7 +1229,7 @@ export interface MapNodeCustomizableSchemaUnsafe<out TName extends string, in ou
1173
1229
  export type MapNodeInsertableData<T extends ImplicitAllowedTypes> = Iterable<readonly [string, InsertableTreeNodeFromImplicitAllowedTypes<T>]> | RestrictiveStringRecord<InsertableTreeNodeFromImplicitAllowedTypes<T>>;
1174
1230
 
1175
1231
  // @alpha @sealed @system
1176
- export interface MapNodePojoEmulationSchema<out TName extends string = string, in out T extends ImplicitAllowedTypes = ImplicitAllowedTypes, out ImplicitlyConstructable extends boolean = true, out TCustomMetadata = unknown> extends TreeNodeSchemaNonClass<TName, NodeKind.Map, TreeMapNode<T> & WithType<TName, NodeKind.Map, T>, MapNodeInsertableData<T>, ImplicitlyConstructable, T, undefined, TCustomMetadata>, SimpleMapNodeSchema<SchemaType.View, TCustomMetadata> {
1232
+ export interface MapNodePojoEmulationSchema<out TName extends string = string, in out T extends ImplicitAllowedTypes = ImplicitAllowedTypes, out ImplicitlyConstructable extends boolean = true, out TCustomMetadata = unknown> extends TreeNodeSchemaNonClass<TName, NodeKind.Map, TreeMapNodeAlpha<T> & WithType<TName, NodeKind.Map, T>, MapNodeInsertableData<T>, ImplicitlyConstructable, T, undefined, TCustomMetadata>, SimpleMapNodeSchema<SchemaType.View, TCustomMetadata> {
1177
1233
  }
1178
1234
 
1179
1235
  // @alpha
@@ -1219,6 +1275,11 @@ export interface NodeChangedDataProperties<TNode extends TreeNode = TreeNode> {
1219
1275
  readonly changedProperties: ReadonlySet<TNode extends WithType<string, NodeKind.Object, infer TInfo> ? string & keyof TInfo : string>;
1220
1276
  }
1221
1277
 
1278
+ // @alpha @sealed
1279
+ export interface NodeChangedDataTreeDelta {
1280
+ readonly delta: readonly ArrayNodeTreeChangedDeltaOp[] | undefined;
1281
+ }
1282
+
1222
1283
  // @public
1223
1284
  export type NodeFromSchema<T extends TreeNodeSchema> = T extends TreeNodeSchemaClass<string, NodeKind, infer TNode> ? TNode : T extends TreeNodeSchemaNonClass<string, NodeKind, infer TNode> ? TNode : never;
1224
1285
 
@@ -1472,8 +1533,8 @@ export class SchemaFactoryAlpha<out TScope extends string | undefined = string |
1472
1533
  arrayAlpha<const Name extends TName, const T extends ImplicitAllowedTypes, const TCustomMetadata = unknown>(name: Name, allowedTypes: T, options?: NodeSchemaOptionsAlpha<TCustomMetadata>): ArrayNodeCustomizableSchemaAlpha<ScopedSchemaName<TScope, Name>, T, true, TCustomMetadata>;
1473
1534
  arrayRecursive<const Name extends TName, const T extends System_Unsafe.ImplicitAllowedTypesUnsafe, const TCustomMetadata = unknown>(name: Name, allowedTypes: T, options?: NodeSchemaOptionsAlpha<TCustomMetadata>): ArrayNodeCustomizableSchemaUnsafe<ScopedSchemaName<TScope, Name>, T, TCustomMetadata>;
1474
1535
  static readonly identifier: <const TCustomMetadata = unknown>(props?: Omit<FieldProps<TCustomMetadata>, "defaultProvider"> | undefined) => FieldSchemaAlpha<FieldKind.Identifier, LeafSchema<"string", string> & SimpleLeafNodeSchema<SchemaType>, TCustomMetadata, FieldPropsAlpha<TCustomMetadata>>;
1475
- static readonly leaves: readonly [LeafSchema<"string", string> & SimpleLeafNodeSchema<SchemaType>, LeafSchema<"number", number> & SimpleLeafNodeSchema<SchemaType>, LeafSchema<"boolean", boolean> & SimpleLeafNodeSchema<SchemaType>, LeafSchema<"null", null> & SimpleLeafNodeSchema<SchemaType>, LeafSchema<"handle", IFluidHandle_2<unknown>> & SimpleLeafNodeSchema<SchemaType>];
1476
- readonly leaves: readonly [LeafSchema<"string", string> & SimpleLeafNodeSchema<SchemaType>, LeafSchema<"number", number> & SimpleLeafNodeSchema<SchemaType>, LeafSchema<"boolean", boolean> & SimpleLeafNodeSchema<SchemaType>, LeafSchema<"null", null> & SimpleLeafNodeSchema<SchemaType>, LeafSchema<"handle", IFluidHandle_2<unknown>> & SimpleLeafNodeSchema<SchemaType>];
1536
+ static readonly leaves: readonly [LeafSchema<"string", string> & SimpleLeafNodeSchema<SchemaType>, LeafSchema<"number", number> & SimpleLeafNodeSchema<SchemaType>, LeafSchema<"boolean", boolean> & SimpleLeafNodeSchema<SchemaType>, LeafSchema<"null", null> & SimpleLeafNodeSchema<SchemaType>, LeafSchema<"handle", IFluidHandle<unknown>> & SimpleLeafNodeSchema<SchemaType>];
1537
+ readonly leaves: readonly [LeafSchema<"string", string> & SimpleLeafNodeSchema<SchemaType>, LeafSchema<"number", number> & SimpleLeafNodeSchema<SchemaType>, LeafSchema<"boolean", boolean> & SimpleLeafNodeSchema<SchemaType>, LeafSchema<"null", null> & SimpleLeafNodeSchema<SchemaType>, LeafSchema<"handle", IFluidHandle<unknown>> & SimpleLeafNodeSchema<SchemaType>];
1477
1538
  mapAlpha<Name extends TName, const T extends ImplicitAllowedTypes, const TCustomMetadata = unknown>(name: Name, allowedTypes: T, options?: NodeSchemaOptionsAlpha<TCustomMetadata>): MapNodeCustomizableSchema<ScopedSchemaName<TScope, Name>, T, true, TCustomMetadata>;
1478
1539
  mapRecursive<Name extends TName, const T extends System_Unsafe.ImplicitAllowedTypesUnsafe, const TCustomMetadata = unknown>(name: Name, allowedTypes: T, options?: NodeSchemaOptionsAlpha<TCustomMetadata>): MapNodeCustomizableSchemaUnsafe<ScopedSchemaName<TScope, Name>, T, TCustomMetadata>;
1479
1540
  objectAlpha<const Name extends TName, const T extends RestrictiveStringRecord<ImplicitFieldSchema>, const TCustomMetadata = unknown>(name: Name, fields: T, options?: ObjectSchemaOptionsAlpha<TCustomMetadata>): ObjectNodeSchemaWorkaround<ScopedSchemaName<TScope, Name>, T, true, TCustomMetadata>;
@@ -1492,10 +1553,14 @@ export class SchemaFactoryAlpha<out TScope extends string | undefined = string |
1492
1553
  static readonly requiredRecursive: <const T extends System_Unsafe.ImplicitAllowedTypesUnsafe, const TCustomMetadata = unknown>(t: T, props?: Omit<FieldPropsAlpha<TCustomMetadata>, "defaultProvider"> | undefined) => FieldSchemaAlphaUnsafe<FieldKind.Required, T, TCustomMetadata, FieldPropsAlpha<TCustomMetadata>>;
1493
1554
  readonly requiredRecursive: <const T extends System_Unsafe.ImplicitAllowedTypesUnsafe, const TCustomMetadata = unknown>(t: T, props?: Omit<FieldPropsAlpha<TCustomMetadata>, "defaultProvider"> | undefined) => FieldSchemaAlphaUnsafe<FieldKind.Required, T, TCustomMetadata, FieldPropsAlpha<TCustomMetadata>>;
1494
1555
  scopedFactoryAlpha<const T extends TName, TNameInner extends number | string = string>(name: T): SchemaFactoryAlpha<ScopedSchemaName<TScope, T>, TNameInner>;
1495
- readonly withDefault: <Kind extends FieldKind, Types extends ImplicitAllowedTypes, TCustomMetadata = unknown>(fieldSchema: FieldSchema<Kind, Types, TCustomMetadata>, defaultValue: NodeProvider<ApplyKindInput_2<InsertableTreeNodeFromImplicitAllowedTypes_2<Types>, Kind, true>>) => FieldSchemaAlpha<Kind, Types, TCustomMetadata, FieldPropsAlpha<TCustomMetadata> & {
1556
+ readonly stagedOptional: <const T extends ImplicitAllowedTypes, const TCustomMetadata = unknown>(t: T, props?: Omit<FieldPropsAlpha<TCustomMetadata>, "stagedOptionalUpgrade" | "defaultProvider"> | undefined) => FieldSchemaAlpha<FieldKind.Optional, T, TCustomMetadata, FieldPropsAlpha<TCustomMetadata>>;
1557
+ static readonly stagedOptional: <const T extends ImplicitAllowedTypes, const TCustomMetadata = unknown>(t: T, props?: Omit<FieldPropsAlpha<TCustomMetadata>, "stagedOptionalUpgrade" | "defaultProvider"> | undefined) => FieldSchemaAlpha<FieldKind.Optional, T, TCustomMetadata, FieldPropsAlpha<TCustomMetadata>>;
1558
+ readonly stagedOptionalRecursive: <const T extends System_Unsafe.ImplicitAllowedTypesUnsafe, const TCustomMetadata = unknown>(t: T, props?: Omit<FieldPropsAlpha<TCustomMetadata>, "stagedOptionalUpgrade" | "defaultProvider"> | undefined) => FieldSchemaAlphaUnsafe<FieldKind.Optional, T, TCustomMetadata, FieldPropsAlpha<TCustomMetadata>>;
1559
+ static readonly stagedOptionalRecursive: <const T extends System_Unsafe.ImplicitAllowedTypesUnsafe, const TCustomMetadata = unknown>(t: T, props?: Omit<FieldPropsAlpha<TCustomMetadata>, "stagedOptionalUpgrade" | "defaultProvider"> | undefined) => FieldSchemaAlphaUnsafe<FieldKind.Optional, T, TCustomMetadata, FieldPropsAlpha<TCustomMetadata>>;
1560
+ readonly withDefault: <Kind extends FieldKind, Types extends ImplicitAllowedTypes, TCustomMetadata = unknown>(fieldSchema: FieldSchema<Kind, Types, TCustomMetadata>, defaultValue: NodeProvider<ApplyKindInput<InsertableTreeNodeFromImplicitAllowedTypes<Types>, Kind, true>>) => FieldSchemaAlpha<Kind, Types, TCustomMetadata, FieldPropsAlpha<TCustomMetadata> & {
1496
1561
  defaultProvider: DefaultProvider;
1497
1562
  }>;
1498
- static readonly withDefault: <Kind extends FieldKind, Types extends ImplicitAllowedTypes, TCustomMetadata = unknown>(fieldSchema: FieldSchema<Kind, Types, TCustomMetadata>, defaultValue: NodeProvider<ApplyKindInput_2<InsertableTreeNodeFromImplicitAllowedTypes_2<Types>, Kind, true>>) => FieldSchemaAlpha<Kind, Types, TCustomMetadata, FieldPropsAlpha<TCustomMetadata> & {
1563
+ static readonly withDefault: <Kind extends FieldKind, Types extends ImplicitAllowedTypes, TCustomMetadata = unknown>(fieldSchema: FieldSchema<Kind, Types, TCustomMetadata>, defaultValue: NodeProvider<ApplyKindInput<InsertableTreeNodeFromImplicitAllowedTypes<Types>, Kind, true>>) => FieldSchemaAlpha<Kind, Types, TCustomMetadata, FieldPropsAlpha<TCustomMetadata> & {
1499
1564
  defaultProvider: DefaultProvider;
1500
1565
  }>;
1501
1566
  readonly withDefaultRecursive: <Kind extends FieldKind, Types extends System_Unsafe.ImplicitAllowedTypesUnsafe, TCustomMetadata = unknown>(fieldSchema: System_Unsafe.FieldSchemaUnsafe<Kind, Types, TCustomMetadata>, defaultValue: unknown) => FieldSchemaAlphaUnsafe<Kind, Types, TCustomMetadata, FieldPropsAlpha<TCustomMetadata> & {
@@ -1549,6 +1614,8 @@ export interface SchemaStatics {
1549
1614
 
1550
1615
  // @alpha @sealed @system
1551
1616
  export interface SchemaStaticsAlpha {
1617
+ readonly stagedOptional: <const T extends ImplicitAllowedTypes, const TCustomMetadata = unknown>(t: T, props?: Omit<FieldPropsAlpha<TCustomMetadata>, "defaultProvider" | "stagedOptionalUpgrade">) => FieldSchemaAlpha<FieldKind.Optional, T, TCustomMetadata, FieldPropsAlpha<TCustomMetadata>>;
1618
+ readonly stagedOptionalRecursive: <const T extends System_Unsafe.ImplicitAllowedTypesUnsafe, const TCustomMetadata = unknown>(t: T, props?: Omit<FieldPropsAlpha<TCustomMetadata>, "defaultProvider" | "stagedOptionalUpgrade">) => FieldSchemaAlphaUnsafe<FieldKind.Optional, T, TCustomMetadata, FieldPropsAlpha<TCustomMetadata>>;
1552
1619
  readonly withDefault: <Kind extends FieldKind, Types extends ImplicitAllowedTypes, TCustomMetadata = unknown>(fieldSchema: FieldSchema<Kind, Types, TCustomMetadata>, defaultValue: NodeProvider<InsertableTreeFieldFromImplicitField<FieldSchema<Kind, Types>>>) => FieldSchemaAlpha<Kind, Types, TCustomMetadata, FieldPropsAlpha<TCustomMetadata> & {
1553
1620
  defaultProvider: DefaultProvider;
1554
1621
  }>;
@@ -1614,6 +1681,7 @@ export interface SimpleArrayNodeSchema<Type extends SchemaType = SchemaType, out
1614
1681
 
1615
1682
  // @alpha @sealed
1616
1683
  export interface SimpleFieldSchema<Type extends SchemaType = SchemaType> {
1684
+ readonly isStagedOptional?: Type extends SchemaType.Stored ? undefined : false | SchemaUpgrade;
1617
1685
  readonly kind: FieldKind;
1618
1686
  readonly metadata: FieldSchemaMetadata & (Type extends SchemaType.View ? unknown : {
1619
1687
  readonly custom?: undefined;
@@ -1724,22 +1792,22 @@ export namespace System_TableSchema {
1724
1792
  props: InsertableTreeFieldFromImplicitField<TPropsSchema>;
1725
1793
  }), true, {
1726
1794
  readonly props: TPropsSchema;
1727
- readonly id: FieldSchema_2<FieldKind_2.Identifier, LeafSchema_2<"string", string>, unknown>;
1795
+ readonly id: FieldSchema<FieldKind.Identifier, LeafSchema<"string", string>, unknown>;
1728
1796
  }>;
1729
1797
  // @system
1730
1798
  export type CreateRowOptionsBase<TUserScope extends string = string, TSchemaFactory extends SchemaFactoryBeta<TUserScope> = SchemaFactoryBeta<TUserScope>, TCellSchema extends ImplicitAllowedTypes = ImplicitAllowedTypes> = OptionsWithSchemaFactory<TSchemaFactory> & OptionsWithCellSchema<TCellSchema>;
1731
1799
  // @system
1732
1800
  export function createRowSchema<const TUserScope extends string, const TCellSchema extends ImplicitAllowedTypes, const TPropsSchema extends ImplicitFieldSchema>(inputSchemaFactory: SchemaFactoryBeta<TUserScope>, cellSchema: TCellSchema, propsSchema: TPropsSchema): TreeNodeSchemaClass<ScopedSchemaName<`com.fluidframework.tableV2<${TUserScope}>`, "Row">, NodeKind.Object, TreeNode & TableSchema.Row<TCellSchema, TPropsSchema> & WithType<ScopedSchemaName<`com.fluidframework.tableV2<${TUserScope}>`, "Row">, NodeKind, unknown>, object & {
1733
1801
  readonly id?: string | undefined;
1734
- readonly cells: (InsertableTypedNode_2<TreeNodeSchemaClass<ScopedSchemaName<`com.fluidframework.tableV2<${TUserScope}>`, "Row.cells">, NodeKind.Record, TreeRecordNode<TCellSchema> & WithType<ScopedSchemaName<`com.fluidframework.tableV2<${TUserScope}>`, "Row.cells">, NodeKind.Record, unknown>, RecordNodeInsertableData_2<TCellSchema>, true, TCellSchema, undefined, unknown>> | undefined) & InsertableTypedNode_2<TreeNodeSchemaClass<ScopedSchemaName<`com.fluidframework.tableV2<${TUserScope}>`, "Row.cells">, NodeKind.Record, TreeRecordNode<TCellSchema> & WithType<ScopedSchemaName<`com.fluidframework.tableV2<${TUserScope}>`, "Row.cells">, NodeKind.Record, unknown>, RecordNodeInsertableData_2<TCellSchema>, true, TCellSchema, undefined, unknown>>;
1802
+ readonly cells: (InsertableTypedNode<TreeNodeSchemaClass<ScopedSchemaName<`com.fluidframework.tableV2<${TUserScope}>`, "Row.cells">, NodeKind.Record, TreeRecordNode<TCellSchema> & WithType<ScopedSchemaName<`com.fluidframework.tableV2<${TUserScope}>`, "Row.cells">, NodeKind.Record, unknown>, RecordNodeInsertableData<TCellSchema>, true, TCellSchema, undefined, unknown>> | undefined) & InsertableTypedNode<TreeNodeSchemaClass<ScopedSchemaName<`com.fluidframework.tableV2<${TUserScope}>`, "Row.cells">, NodeKind.Record, TreeRecordNode<TCellSchema> & WithType<ScopedSchemaName<`com.fluidframework.tableV2<${TUserScope}>`, "Row.cells">, NodeKind.Record, unknown>, RecordNodeInsertableData<TCellSchema>, true, TCellSchema, undefined, unknown>>;
1735
1803
  } & (FieldHasDefault<TPropsSchema> extends true ? {
1736
1804
  props?: InsertableTreeFieldFromImplicitField<TPropsSchema> | undefined;
1737
1805
  } : {
1738
1806
  props: InsertableTreeFieldFromImplicitField<TPropsSchema>;
1739
1807
  }), true, {
1740
1808
  readonly props: TPropsSchema;
1741
- readonly id: FieldSchema_2<FieldKind_2.Identifier, LeafSchema_2<"string", string>, unknown>;
1742
- readonly cells: FieldSchema_2<FieldKind_2.Required, TreeNodeSchemaClass<ScopedSchemaName<`com.fluidframework.tableV2<${TUserScope}>`, "Row.cells">, NodeKind.Record, TreeRecordNode<TCellSchema> & WithType<ScopedSchemaName<`com.fluidframework.tableV2<${TUserScope}>`, "Row.cells">, NodeKind.Record, unknown>, RecordNodeInsertableData_2<TCellSchema>, true, TCellSchema, undefined, unknown>, unknown>;
1809
+ readonly id: FieldSchema<FieldKind.Identifier, LeafSchema<"string", string>, unknown>;
1810
+ readonly cells: FieldSchema<FieldKind.Required, TreeNodeSchemaClass<ScopedSchemaName<`com.fluidframework.tableV2<${TUserScope}>`, "Row.cells">, NodeKind.Record, TreeRecordNode<TCellSchema> & WithType<ScopedSchemaName<`com.fluidframework.tableV2<${TUserScope}>`, "Row.cells">, NodeKind.Record, unknown>, RecordNodeInsertableData<TCellSchema>, true, TCellSchema, undefined, unknown>, unknown>;
1743
1811
  }>;
1744
1812
  // @system
1745
1813
  export function createTableSchema<const TUserScope extends string, const TCellSchema extends ImplicitAllowedTypes, const TColumnSchema extends ColumnSchemaBase<TUserScope, TCellSchema>, const TRowSchema extends RowSchemaBase<TUserScope, TCellSchema>>(inputSchemaFactory: SchemaFactoryBeta<TUserScope>, _cellSchema: TCellSchema, columnSchema: TColumnSchema, rowSchema: TRowSchema): {
@@ -2125,6 +2193,7 @@ export interface TreeChangeEvents {
2125
2193
  // @alpha @sealed
2126
2194
  export interface TreeChangeEventsAlpha<TNode extends TreeNode = TreeNode> extends TreeChangeEvents {
2127
2195
  nodeChanged: (data: NodeChangedDataAlpha<TNode>) => void;
2196
+ treeChanged: TNode extends WithType<string, NodeKind.Array> ? (data: NodeChangedDataTreeDelta) => void : TreeChangeEventsBeta<TNode>["treeChanged"];
2128
2197
  }
2129
2198
 
2130
2199
  // @beta @sealed
@@ -2165,15 +2234,15 @@ export interface TreeIdentifierUtils {
2165
2234
  shorten(branch: TreeBranch, nodeIdentifier: string): number | undefined;
2166
2235
  }
2167
2236
 
2168
- // @alpha @sealed
2169
- export interface TreeIndex<TKey, TValue> extends ReadonlyMap<TKey, TValue> {
2237
+ // @beta @sealed
2238
+ export interface TreeIndex<TKey, TValue> extends FluidReadonlyMap<TKey, TValue> {
2170
2239
  dispose(): void;
2171
2240
  }
2172
2241
 
2173
- // @alpha
2242
+ // @beta
2174
2243
  export type TreeIndexKey = TreeLeafValue;
2175
2244
 
2176
- // @alpha
2245
+ // @beta
2177
2246
  export type TreeIndexNodes<TNode> = readonly [first: TNode, ...rest: TNode[]];
2178
2247
 
2179
2248
  // @public
@@ -2189,6 +2258,10 @@ export interface TreeMapNode<T extends ImplicitAllowedTypes = ImplicitAllowedTyp
2189
2258
  values(): IterableIterator<TreeNodeFromImplicitAllowedTypes<T>>;
2190
2259
  }
2191
2260
 
2261
+ // @alpha @sealed
2262
+ export interface TreeMapNodeAlpha<T extends ImplicitAllowedTypes = ImplicitAllowedTypes> extends FluidReadonlyMap<string, TreeNodeFromImplicitAllowedTypes<T>>, TreeNode, Pick<TreeMapNode<T>, "set" | "delete"> {
2263
+ }
2264
+
2192
2265
  // @public @sealed
2193
2266
  export abstract class TreeNode implements WithType {
2194
2267
  static [Symbol.hasInstance](value: unknown): value is TreeNode;
@@ -154,9 +154,24 @@ export interface ContainerSchema {
154
154
  readonly initialObjects: Record<string, SharedObjectKind>;
155
155
  }
156
156
 
157
+ // @beta
158
+ export function createIdentifierIndex<TSchema extends ImplicitFieldSchema>(view: TreeView<TSchema>): IdentifierIndex;
159
+
157
160
  // @beta
158
161
  export function createIndependentTreeBeta<const TSchema extends ImplicitFieldSchema>(options?: ForestOptions): ViewableTree;
159
162
 
163
+ // @beta
164
+ export function createTreeIndex<TFieldSchema extends ImplicitFieldSchema, TKey extends TreeIndexKey, TValue>(view: TreeView<TFieldSchema>, indexer: (schema: TreeNodeSchema) => string | undefined, getValue: (nodes: TreeIndexNodes<TreeNode>) => TValue, isKeyValid: (key: TreeIndexKey) => key is TKey): TreeIndex<TKey, TValue>;
165
+
166
+ // @beta
167
+ export function createTreeIndex<TFieldSchema extends ImplicitFieldSchema, TKey extends TreeIndexKey, TValue, TSchema extends TreeNodeSchema>(view: TreeView<TFieldSchema>, indexer: (schema: TSchema) => string | undefined, getValue: (nodes: TreeIndexNodes<NodeFromSchema<TSchema>>) => TValue, isKeyValid: (key: TreeIndexKey) => key is TKey, indexableSchema: readonly TSchema[]): TreeIndex<TKey, TValue>;
168
+
169
+ // @beta
170
+ export function createTreeIndex<TFieldSchema extends ImplicitFieldSchema, TKey extends TreeIndexKey, TValue>(view: TreeView<TFieldSchema>, indexer: Map<TreeNodeSchema, string>, getValue: (nodes: TreeIndexNodes<TreeNode>) => TValue, isKeyValid: (key: TreeIndexKey) => key is TKey): TreeIndex<TKey, TValue>;
171
+
172
+ // @beta
173
+ export function createTreeIndex<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[]): TreeIndex<TKey, TValue>;
174
+
160
175
  // @public @sealed @system
161
176
  interface DefaultProvider extends ErasedType<"@fluidframework/tree.FieldProvider"> {
162
177
  }
@@ -186,7 +201,7 @@ export abstract class ErasedType<out Name = unknown> {
186
201
 
187
202
  // @beta
188
203
  export namespace ExtensibleUnionNode {
189
- export function createSchema<const T extends readonly TreeNodeSchema[], const TScope extends string, const TName extends string>(types: T, inputSchemaFactory: SchemaFactoryBeta<TScope>, name: TName): Statics<T> & TreeNodeSchemaCore_2<ScopedSchemaName_2<`com.fluidframework.extensibleUnionNode<${TScope}>`, TName>, NodeKind_2, false, unknown, never, unknown> & (new (data: InternalTreeNode_2) => Members<TreeNodeFromImplicitAllowedTypes<T>> & TreeNode_2 & WithType_2<ScopedSchemaName_2<`com.fluidframework.extensibleUnionNode<${TScope}>`, TName>, NodeKind_2, unknown>);
204
+ export function createSchema<const T extends readonly TreeNodeSchema[], const TScope extends string, const TName extends string>(types: T, inputSchemaFactory: SchemaFactoryBeta<TScope>, name: TName): Statics<T> & TreeNodeSchemaCore<ScopedSchemaName<`com.fluidframework.extensibleUnionNode<${TScope}>`, TName>, NodeKind, false, unknown, never, unknown> & (new (data: InternalTreeNode) => Members<TreeNodeFromImplicitAllowedTypes<T>> & TreeNode & WithType<ScopedSchemaName<`com.fluidframework.extensibleUnionNode<${TScope}>`, TName>, NodeKind, unknown>);
190
205
  export interface Members<T> {
191
206
  isValid(): boolean;
192
207
  readonly union: T | undefined;
@@ -253,6 +268,29 @@ type FlexList<Item = unknown> = readonly LazyItem<Item>[];
253
268
  // @public @system
254
269
  type FlexListToUnion<TList extends FlexList> = ExtractItemType<TList[number]>;
255
270
 
271
+ // @beta @sealed
272
+ export interface FluidIterable<T> {
273
+ [Symbol.iterator](): FluidIterableIterator<T>;
274
+ }
275
+
276
+ // @beta @sealed
277
+ export interface FluidIterableIterator<T> extends FluidIterable<T> {
278
+ next(): {
279
+ value: T;
280
+ done?: false;
281
+ } | {
282
+ value: any;
283
+ done: true;
284
+ };
285
+ }
286
+
287
+ // @beta @sealed
288
+ export interface FluidMap<K, V> extends FluidReadonlyMap<K, V> {
289
+ delete(key: K): void;
290
+ forEach(callbackfn: (value: V, key: K, map: FluidMap<K, V>) => void, thisArg?: any): void;
291
+ set(key: K, value: V): void;
292
+ }
293
+
256
294
  // @public
257
295
  export type FluidObject<T = unknown> = {
258
296
  [P in FluidObjectProviderKeys<T>]?: T[P];
@@ -261,26 +299,39 @@ export type FluidObject<T = unknown> = {
261
299
  // @public
262
300
  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;
263
301
 
302
+ // @beta @sealed
303
+ export interface FluidReadonlyMap<K, V> {
304
+ [Symbol.iterator](): FluidIterableIterator<[K, V]>;
305
+ readonly [Symbol.toStringTag]: string;
306
+ entries(): FluidIterableIterator<[K, V]>;
307
+ forEach(callbackfn: (value: V, key: K, map: FluidReadonlyMap<K, V>) => void, thisArg?: any): void;
308
+ get(key: K): V | undefined;
309
+ has(key: K): boolean;
310
+ keys(): FluidIterableIterator<K>;
311
+ readonly size: number;
312
+ values(): FluidIterableIterator<V>;
313
+ }
314
+
264
315
  // @beta
265
316
  export namespace FluidSerializableAsTree {
266
317
  // @sealed
267
318
  export class Array extends _APIExtractorWorkaroundArrayBase {
268
319
  }
269
- const Tree: readonly [() => typeof FluidSerializableObject, () => typeof Array, LeafSchema_2<"string", string>, LeafSchema_2<"number", number>, LeafSchema_2<"boolean", boolean>, LeafSchema_2<"null", null>, LeafSchema_2<"handle", IFluidHandle<unknown>>];
320
+ const Tree: readonly [() => typeof FluidSerializableObject, () => typeof Array, LeafSchema<"string", string>, LeafSchema<"number", number>, LeafSchema<"boolean", boolean>, LeafSchema<"null", null>, LeafSchema<"handle", IFluidHandle<unknown>>];
270
321
  export type Data = JsonCompatible<IFluidHandle>;
271
322
  const // @system
272
- _APIExtractorWorkaroundObjectBase: TreeNodeSchemaClass_2<"com.fluidframework.serializable.object", NodeKind_2.Record, TreeRecordNodeUnsafe_2<readonly [() => typeof FluidSerializableObject, () => typeof Array, LeafSchema_2<"string", string>, LeafSchema_2<"number", number>, LeafSchema_2<"boolean", boolean>, LeafSchema_2<"null", null>, LeafSchema_2<"handle", IFluidHandle<unknown>>]> & WithType_2<"com.fluidframework.serializable.object", NodeKind_2.Record, unknown>, {
273
- readonly [x: string]: string | number | IFluidHandle<unknown> | System_Unsafe_2.InsertableTypedNodeUnsafe<LeafSchema_2<"boolean", boolean>, LeafSchema_2<"boolean", boolean>> | FluidSerializableObject | Array | null;
274
- }, false, readonly [() => typeof FluidSerializableObject, () => typeof Array, LeafSchema_2<"string", string>, LeafSchema_2<"number", number>, LeafSchema_2<"boolean", boolean>, LeafSchema_2<"null", null>, LeafSchema_2<"handle", IFluidHandle<unknown>>], undefined, unknown>;
323
+ _APIExtractorWorkaroundObjectBase: TreeNodeSchemaClass<"com.fluidframework.serializable.object", NodeKind.Record, TreeRecordNodeUnsafe<readonly [() => typeof FluidSerializableObject, () => typeof Array, LeafSchema<"string", string>, LeafSchema<"number", number>, LeafSchema<"boolean", boolean>, LeafSchema<"null", null>, LeafSchema<"handle", IFluidHandle<unknown>>]> & WithType<"com.fluidframework.serializable.object", NodeKind.Record, unknown>, {
324
+ readonly [x: string]: string | number | IFluidHandle<unknown> | System_Unsafe.InsertableTypedNodeUnsafe<LeafSchema<"boolean", boolean>, LeafSchema<"boolean", boolean>> | FluidSerializableObject | Array | null;
325
+ }, false, readonly [() => typeof FluidSerializableObject, () => typeof Array, LeafSchema<"string", string>, LeafSchema<"number", number>, LeafSchema<"boolean", boolean>, LeafSchema<"null", null>, LeafSchema<"handle", IFluidHandle<unknown>>], undefined, unknown>;
275
326
  // @sealed
276
327
  export class FluidSerializableObject extends _APIExtractorWorkaroundObjectBase {
277
328
  }
278
329
  // @system
279
330
  export type _RecursiveArrayWorkaroundJsonArray = FixRecursiveArraySchema<typeof Array>;
280
331
  const // @system
281
- _APIExtractorWorkaroundArrayBase: TreeNodeSchemaClass_2<"com.fluidframework.serializable.array", NodeKind_2.Array, System_Unsafe_2.TreeArrayNodeUnsafe<readonly [() => typeof FluidSerializableObject, () => typeof Array, LeafSchema_2<"string", string>, LeafSchema_2<"number", number>, LeafSchema_2<"boolean", boolean>, LeafSchema_2<"null", null>, LeafSchema_2<"handle", IFluidHandle<unknown>>]> & WithType_2<"com.fluidframework.serializable.array", NodeKind_2.Array, unknown>, {
282
- [Symbol.iterator](): Iterator<string | number | IFluidHandle<unknown> | System_Unsafe_2.InsertableTypedNodeUnsafe<LeafSchema_2<"boolean", boolean>, LeafSchema_2<"boolean", boolean>> | FluidSerializableObject | Array | null, any, undefined>;
283
- }, false, readonly [() => typeof FluidSerializableObject, () => typeof Array, LeafSchema_2<"string", string>, LeafSchema_2<"number", number>, LeafSchema_2<"boolean", boolean>, LeafSchema_2<"null", null>, LeafSchema_2<"handle", IFluidHandle<unknown>>], undefined>;
332
+ _APIExtractorWorkaroundArrayBase: TreeNodeSchemaClass<"com.fluidframework.serializable.array", NodeKind.Array, System_Unsafe.TreeArrayNodeUnsafe<readonly [() => typeof FluidSerializableObject, () => typeof Array, LeafSchema<"string", string>, LeafSchema<"number", number>, LeafSchema<"boolean", boolean>, LeafSchema<"null", null>, LeafSchema<"handle", IFluidHandle<unknown>>]> & WithType<"com.fluidframework.serializable.array", NodeKind.Array, unknown>, {
333
+ [Symbol.iterator](): Iterator<string | number | IFluidHandle<unknown> | System_Unsafe.InsertableTypedNodeUnsafe<LeafSchema<"boolean", boolean>, LeafSchema<"boolean", boolean>> | FluidSerializableObject | Array | null, any, undefined>;
334
+ }, false, readonly [() => typeof FluidSerializableObject, () => typeof Array, LeafSchema<"string", string>, LeafSchema<"number", number>, LeafSchema<"boolean", boolean>, LeafSchema<"null", null>, LeafSchema<"handle", IFluidHandle<unknown>>], undefined>;
284
335
  // (undocumented)
285
336
  export type Tree = TreeNodeFromImplicitAllowedTypes<typeof Tree>;
286
337
  }
@@ -303,6 +354,9 @@ export const ForestTypeOptimized: ForestType;
303
354
  // @beta
304
355
  export const ForestTypeReference: ForestType;
305
356
 
357
+ // @public
358
+ export const getPresence: (fluidContainer: IFluidContainer) => Presence;
359
+
306
360
  // @public
307
361
  export interface IConnection {
308
362
  readonly id: string;
@@ -312,6 +366,9 @@ export interface IConnection {
312
366
  // @public
313
367
  export type ICriticalContainerError = IErrorBase;
314
368
 
369
+ // @beta
370
+ export type IdentifierIndex = TreeIndex<string, TreeNode>;
371
+
315
372
  // @public @sealed
316
373
  export interface IDisposable {
317
374
  dispose(error?: Error): void;
@@ -1009,22 +1066,22 @@ export namespace System_TableSchema {
1009
1066
  props: InsertableTreeFieldFromImplicitField<TPropsSchema>;
1010
1067
  }), true, {
1011
1068
  readonly props: TPropsSchema;
1012
- readonly id: FieldSchema_2<FieldKind_2.Identifier, LeafSchema_2<"string", string>, unknown>;
1069
+ readonly id: FieldSchema<FieldKind.Identifier, LeafSchema<"string", string>, unknown>;
1013
1070
  }>;
1014
1071
  // @system
1015
1072
  export type CreateRowOptionsBase<TUserScope extends string = string, TSchemaFactory extends SchemaFactoryBeta<TUserScope> = SchemaFactoryBeta<TUserScope>, TCellSchema extends ImplicitAllowedTypes = ImplicitAllowedTypes> = OptionsWithSchemaFactory<TSchemaFactory> & OptionsWithCellSchema<TCellSchema>;
1016
1073
  // @system
1017
1074
  export function createRowSchema<const TUserScope extends string, const TCellSchema extends ImplicitAllowedTypes, const TPropsSchema extends ImplicitFieldSchema>(inputSchemaFactory: SchemaFactoryBeta<TUserScope>, cellSchema: TCellSchema, propsSchema: TPropsSchema): TreeNodeSchemaClass<ScopedSchemaName<`com.fluidframework.tableV2<${TUserScope}>`, "Row">, NodeKind.Object, TreeNode & TableSchema.Row<TCellSchema, TPropsSchema> & WithType<ScopedSchemaName<`com.fluidframework.tableV2<${TUserScope}>`, "Row">, NodeKind, unknown>, object & {
1018
1075
  readonly id?: string | undefined;
1019
- readonly cells: (InsertableTypedNode_2<TreeNodeSchemaClass<ScopedSchemaName<`com.fluidframework.tableV2<${TUserScope}>`, "Row.cells">, NodeKind.Record, TreeRecordNode<TCellSchema> & WithType<ScopedSchemaName<`com.fluidframework.tableV2<${TUserScope}>`, "Row.cells">, NodeKind.Record, unknown>, RecordNodeInsertableData_2<TCellSchema>, true, TCellSchema, undefined, unknown>> | undefined) & InsertableTypedNode_2<TreeNodeSchemaClass<ScopedSchemaName<`com.fluidframework.tableV2<${TUserScope}>`, "Row.cells">, NodeKind.Record, TreeRecordNode<TCellSchema> & WithType<ScopedSchemaName<`com.fluidframework.tableV2<${TUserScope}>`, "Row.cells">, NodeKind.Record, unknown>, RecordNodeInsertableData_2<TCellSchema>, true, TCellSchema, undefined, unknown>>;
1076
+ readonly cells: (InsertableTypedNode<TreeNodeSchemaClass<ScopedSchemaName<`com.fluidframework.tableV2<${TUserScope}>`, "Row.cells">, NodeKind.Record, TreeRecordNode<TCellSchema> & WithType<ScopedSchemaName<`com.fluidframework.tableV2<${TUserScope}>`, "Row.cells">, NodeKind.Record, unknown>, RecordNodeInsertableData<TCellSchema>, true, TCellSchema, undefined, unknown>> | undefined) & InsertableTypedNode<TreeNodeSchemaClass<ScopedSchemaName<`com.fluidframework.tableV2<${TUserScope}>`, "Row.cells">, NodeKind.Record, TreeRecordNode<TCellSchema> & WithType<ScopedSchemaName<`com.fluidframework.tableV2<${TUserScope}>`, "Row.cells">, NodeKind.Record, unknown>, RecordNodeInsertableData<TCellSchema>, true, TCellSchema, undefined, unknown>>;
1020
1077
  } & (FieldHasDefault<TPropsSchema> extends true ? {
1021
1078
  props?: InsertableTreeFieldFromImplicitField<TPropsSchema> | undefined;
1022
1079
  } : {
1023
1080
  props: InsertableTreeFieldFromImplicitField<TPropsSchema>;
1024
1081
  }), true, {
1025
1082
  readonly props: TPropsSchema;
1026
- readonly id: FieldSchema_2<FieldKind_2.Identifier, LeafSchema_2<"string", string>, unknown>;
1027
- readonly cells: FieldSchema_2<FieldKind_2.Required, TreeNodeSchemaClass<ScopedSchemaName<`com.fluidframework.tableV2<${TUserScope}>`, "Row.cells">, NodeKind.Record, TreeRecordNode<TCellSchema> & WithType<ScopedSchemaName<`com.fluidframework.tableV2<${TUserScope}>`, "Row.cells">, NodeKind.Record, unknown>, RecordNodeInsertableData_2<TCellSchema>, true, TCellSchema, undefined, unknown>, unknown>;
1083
+ readonly id: FieldSchema<FieldKind.Identifier, LeafSchema<"string", string>, unknown>;
1084
+ readonly cells: FieldSchema<FieldKind.Required, TreeNodeSchemaClass<ScopedSchemaName<`com.fluidframework.tableV2<${TUserScope}>`, "Row.cells">, NodeKind.Record, TreeRecordNode<TCellSchema> & WithType<ScopedSchemaName<`com.fluidframework.tableV2<${TUserScope}>`, "Row.cells">, NodeKind.Record, unknown>, RecordNodeInsertableData<TCellSchema>, true, TCellSchema, undefined, unknown>, unknown>;
1028
1085
  }>;
1029
1086
  // @system
1030
1087
  export function createTableSchema<const TUserScope extends string, const TCellSchema extends ImplicitAllowedTypes, const TColumnSchema extends ColumnSchemaBase<TUserScope, TCellSchema>, const TRowSchema extends RowSchemaBase<TUserScope, TCellSchema>>(inputSchemaFactory: SchemaFactoryBeta<TUserScope>, _cellSchema: TCellSchema, columnSchema: TColumnSchema, rowSchema: TRowSchema): {
@@ -1314,6 +1371,17 @@ export interface TreeEncodingOptions<TKeyOptions = KeyEncodingOptions> {
1314
1371
  // @public
1315
1372
  export type TreeFieldFromImplicitField<TSchema extends ImplicitFieldSchema = FieldSchema> = TSchema extends FieldSchema<infer Kind, infer Types> ? ApplyKind<TreeNodeFromImplicitAllowedTypes<Types>, Kind> : TSchema extends ImplicitAllowedTypes ? TreeNodeFromImplicitAllowedTypes<TSchema> : TreeNode | TreeLeafValue | undefined;
1316
1373
 
1374
+ // @beta @sealed
1375
+ export interface TreeIndex<TKey, TValue> extends FluidReadonlyMap<TKey, TValue> {
1376
+ dispose(): void;
1377
+ }
1378
+
1379
+ // @beta
1380
+ export type TreeIndexKey = TreeLeafValue;
1381
+
1382
+ // @beta
1383
+ export type TreeIndexNodes<TNode> = readonly [first: TNode, ...rest: TNode[]];
1384
+
1317
1385
  // @public
1318
1386
  export type TreeLeafValue = number | string | boolean | IFluidHandle | null;
1319
1387