fluid-framework 2.0.0-dev-rc.3.0.0.250606 → 2.0.0-dev-rc.3.0.0.253463

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.
@@ -22,9 +22,6 @@ export type AllowedTypes = readonly LazyItem<TreeNodeSchema>[];
22
22
  // @public
23
23
  export type ApplyKind<T, Kind extends FieldKind> = Kind extends FieldKind.Required ? T : undefined | T;
24
24
 
25
- // @public
26
- export type ArrayToUnion<T extends readonly unknown[]> = T[number];
27
-
28
25
  // @public
29
26
  export enum AttachState {
30
27
  Attached = "Attached",
@@ -41,8 +38,8 @@ export enum CommitKind {
41
38
 
42
39
  // @public
43
40
  export interface CommitMetadata {
44
- isLocal: boolean;
45
- kind: CommitKind;
41
+ readonly isLocal: boolean;
42
+ readonly kind: CommitKind;
46
43
  }
47
44
 
48
45
  // @public
@@ -89,7 +86,7 @@ export interface ContainerSchema {
89
86
  // @public
90
87
  export type DataObjectClass<T extends IFluidLoadable = IFluidLoadable> = {
91
88
  readonly factory: {
92
- IFluidDataStoreFactory: DataObjectClass<T>["factory"];
89
+ readonly IFluidDataStoreFactory: DataObjectClass<T>["factory"];
93
90
  };
94
91
  } & (new (...args: any[]) => T);
95
92
 
@@ -135,13 +132,21 @@ export enum FieldKind {
135
132
  Required = 1
136
133
  }
137
134
 
135
+ // @public
136
+ export interface FieldProps {
137
+ readonly key?: string;
138
+ }
139
+
138
140
  // @public @sealed
139
141
  export class FieldSchema<out Kind extends FieldKind = FieldKind, out Types extends ImplicitAllowedTypes = ImplicitAllowedTypes> {
140
- constructor(kind: Kind, allowedTypes: Types);
141
- // (undocumented)
142
+ constructor(
143
+ kind: Kind,
144
+ allowedTypes: Types,
145
+ props?: FieldProps | undefined);
142
146
  readonly allowedTypes: Types;
143
- // (undocumented)
147
+ get allowedTypeSet(): ReadonlySet<TreeNodeSchema>;
144
148
  readonly kind: Kind;
149
+ readonly props?: FieldProps | undefined;
145
150
  protected _typeCheck?: MakeNominal;
146
151
  }
147
152
 
@@ -149,12 +154,12 @@ export class FieldSchema<out Kind extends FieldKind = FieldKind, out Types exten
149
154
  export type FlexList<Item = unknown> = readonly LazyItem<Item>[];
150
155
 
151
156
  // @public
152
- export type FlexListToUnion<TList extends FlexList> = ExtractItemType<ArrayToUnion<TList>>;
157
+ export type FlexListToUnion<TList extends FlexList> = ExtractItemType<TList[number]>;
153
158
 
154
159
  // @public
155
160
  export interface IConnection {
156
- id: string;
157
- mode: "write" | "read";
161
+ readonly id: string;
162
+ readonly mode: "write" | "read";
158
163
  }
159
164
 
160
165
  // @public
@@ -190,8 +195,8 @@ export interface IFluidContainerEvents extends IEvent {
190
195
 
191
196
  // @public
192
197
  export interface IMember {
193
- connections: IConnection[];
194
- userId: string;
198
+ readonly connections: IConnection[];
199
+ readonly userId: string;
195
200
  }
196
201
 
197
202
  // @public
@@ -223,7 +228,7 @@ export type InsertableTypedNode<T extends TreeNodeSchema> = (T extends {
223
228
 
224
229
  // @public
225
230
  export interface IServiceAudience<M extends IMember> extends IEventProvider<IServiceAudienceEvents<M>> {
226
- getMembers(): Map<string, M>;
231
+ getMembers(): ReadonlyMap<string, M>;
227
232
  getMyself(): Myself<M> | undefined;
228
233
  }
229
234
 
@@ -269,8 +274,8 @@ export interface ITree extends IChannel {
269
274
 
270
275
  // @public @sealed
271
276
  export interface IValueChanged {
272
- key: string;
273
- previousValue: any;
277
+ readonly key: string;
278
+ readonly previousValue: any;
274
279
  }
275
280
 
276
281
  // @public
@@ -291,7 +296,7 @@ export type MemberChangedListener<M extends IMember> = (clientId: string, member
291
296
 
292
297
  // @public
293
298
  export type Myself<M extends IMember = IMember> = M & {
294
- currentConnection: string;
299
+ readonly currentConnection: string;
295
300
  };
296
301
 
297
302
  // @public
@@ -339,15 +344,16 @@ export class SchemaFactory<out TScope extends string | undefined = string | unde
339
344
  readonly boolean: TreeNodeSchema<"com.fluidframework.leaf.boolean", NodeKind.Leaf, boolean, boolean>;
340
345
  // @deprecated
341
346
  fixRecursiveReference<T extends AllowedTypes>(...types: T): void;
342
- readonly handle: TreeNodeSchema<"com.fluidframework.leaf.handle", NodeKind.Leaf, IFluidHandle<FluidObject & IFluidLoadable>, IFluidHandle<FluidObject & IFluidLoadable>>;
347
+ readonly handle: TreeNodeSchema<"com.fluidframework.leaf.handle", NodeKind.Leaf, IFluidHandle<FluidObject<unknown> & IFluidLoadable>, IFluidHandle<FluidObject<unknown> & IFluidLoadable>>;
343
348
  map<const T extends TreeNodeSchema | readonly TreeNodeSchema[]>(allowedTypes: T): TreeNodeSchema<ScopedSchemaName<TScope, `Map<${string}>`>, NodeKind.Map, TreeMapNode<T> & WithType<ScopedSchemaName<TScope, `Map<${string}>`>>, Iterable<[string, InsertableTreeNodeFromImplicitAllowedTypes<T>]>, true, T>;
344
349
  map<Name extends TName, const T extends ImplicitAllowedTypes>(name: Name, allowedTypes: T): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Map, TreeMapNode<T> & WithType<ScopedSchemaName<TScope, Name>>, Iterable<[string, InsertableTreeNodeFromImplicitAllowedTypes<T>]>, true, T>;
345
350
  namedArray_internal<Name extends TName | string, const T extends ImplicitAllowedTypes, const ImplicitlyConstructable extends boolean>(name: Name, allowedTypes: T, customizable: boolean, implicitlyConstructable: ImplicitlyConstructable): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Array, TreeArrayNode<T> & WithType<ScopedSchemaName<TScope, string>>, Iterable<InsertableTreeNodeFromImplicitAllowedTypes<T>>, ImplicitlyConstructable, T>;
346
351
  namedMap_internal<Name extends TName | string, const T extends ImplicitAllowedTypes, const ImplicitlyConstructable extends boolean>(name: Name, allowedTypes: T, customizable: boolean, implicitlyConstructable: ImplicitlyConstructable): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Map, TreeMapNode<T> & WithType<ScopedSchemaName<TScope, Name>>, Iterable<[string, InsertableTreeNodeFromImplicitAllowedTypes<T>]>, ImplicitlyConstructable, T>;
347
352
  readonly null: TreeNodeSchema<"com.fluidframework.leaf.null", NodeKind.Leaf, null, null>;
348
353
  readonly number: TreeNodeSchema<"com.fluidframework.leaf.number", NodeKind.Leaf, number, number>;
349
- object<const Name extends TName, const T extends RestrictiveReadonlyRecord<string, ImplicitFieldSchema>>(name: Name, t: T): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Object, TreeNode & ObjectFromSchemaRecord<T> & WithType<ScopedSchemaName<TScope, Name>>, object & InsertableObjectFromSchemaRecord<T>, true, T>;
350
- optional<const T extends ImplicitAllowedTypes>(t: T): FieldSchema<FieldKind.Optional, T>;
354
+ object<const Name extends TName, const T extends RestrictiveReadonlyRecord<string, ImplicitFieldSchema>>(name: Name, fields: T): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Object, TreeObjectNode<T, ScopedSchemaName<TScope, Name>>, object & InsertableObjectFromSchemaRecord<T>, true, T>;
355
+ optional<const T extends ImplicitAllowedTypes>(t: T, props?: FieldProps): FieldSchema<FieldKind.Optional, T>;
356
+ required<const T extends ImplicitAllowedTypes>(t: T, props?: FieldProps): FieldSchema<FieldKind.Required, T>;
351
357
  // (undocumented)
352
358
  readonly scope: TScope;
353
359
  readonly string: TreeNodeSchema<"com.fluidframework.leaf.string", NodeKind.Leaf, string, string>;
@@ -409,6 +415,12 @@ export interface TreeArrayNodeBase<out T, in TNew, in TMoveFrom> extends Readonl
409
415
  removeRange(start?: number, end?: number): void;
410
416
  }
411
417
 
418
+ // @public
419
+ export interface TreeChangeEvents {
420
+ nodeChanged(): void;
421
+ treeChanged(): void;
422
+ }
423
+
412
424
  // @public
413
425
  export class TreeConfiguration<TSchema extends ImplicitFieldSchema = ImplicitFieldSchema> {
414
426
  constructor(schema: TSchema, initialTree: () => InsertableTreeFieldFromImplicitField<TSchema>);
@@ -439,17 +451,12 @@ export abstract class TreeNode implements WithType {
439
451
  export interface TreeNodeApi {
440
452
  is<TSchema extends TreeNodeSchema>(value: unknown, schema: TSchema): value is NodeFromSchema<TSchema>;
441
453
  key(node: TreeNode): string | number;
442
- on<K extends keyof TreeNodeEvents>(node: TreeNode, eventName: K, listener: TreeNodeEvents[K]): () => void;
454
+ on<K extends keyof TreeChangeEvents>(node: TreeNode, eventName: K, listener: TreeChangeEvents[K]): () => void;
443
455
  parent(node: TreeNode): TreeNode | undefined;
444
456
  schema<T extends TreeNode | TreeLeafValue>(node: T): TreeNodeSchema<string, NodeKind, unknown, T>;
445
457
  readonly status: (node: TreeNode) => TreeStatus;
446
458
  }
447
459
 
448
- // @public
449
- export interface TreeNodeEvents {
450
- afterChange(): void;
451
- }
452
-
453
460
  // @public
454
461
  export type TreeNodeFromImplicitAllowedTypes<TSchema extends ImplicitAllowedTypes = TreeNodeSchema> = TSchema extends TreeNodeSchema ? NodeFromSchema<TSchema> : TSchema extends AllowedTypes ? NodeFromSchema<FlexListToUnion<TSchema>> : unknown;
455
462
 
@@ -478,6 +485,9 @@ export interface TreeNodeSchemaNonClass<out Name extends string = string, out Ki
478
485
  create(data: TInsertable): TNode;
479
486
  }
480
487
 
488
+ // @public
489
+ export type TreeObjectNode<T extends RestrictiveReadonlyRecord<string, ImplicitFieldSchema>, TypeName extends string = string> = TreeNode & ObjectFromSchemaRecord<T> & WithType<TypeName>;
490
+
481
491
  // @public
482
492
  export enum TreeStatus {
483
493
  Deleted = 2,
@@ -30,12 +30,6 @@ export declare type AllowedTypes = readonly LazyItem<TreeNodeSchema>[];
30
30
  */
31
31
  export declare type ApplyKind<T, Kind extends FieldKind> = Kind extends FieldKind.Required ? T : undefined | T;
32
32
 
33
- /**
34
- * Convert a Array type into a union of its value types.
35
- * @public
36
- */
37
- export declare type ArrayToUnion<T extends readonly unknown[]> = T[number];
38
-
39
33
  /**
40
34
  * The attachment state of some Fluid data (e.g. a container or data store), denoting whether it is uploaded to the
41
35
  * service. The transition from detached to attached state is a one-way transition.
@@ -81,11 +75,11 @@ export declare interface CommitMetadata {
81
75
  /**
82
76
  * A {@link CommitKind} enum value describing whether the commit represents an Edit, an Undo, or a Redo.
83
77
  */
84
- kind: CommitKind;
78
+ readonly kind: CommitKind;
85
79
  /**
86
80
  * Indicates whether the commit is a local edit
87
81
  */
88
- isLocal: boolean;
82
+ readonly isLocal: boolean;
89
83
  }
90
84
 
91
85
  /**
@@ -231,7 +225,7 @@ export declare interface ContainerSchema {
231
225
  */
232
226
  export declare type DataObjectClass<T extends IFluidLoadable = IFluidLoadable> = {
233
227
  readonly factory: {
234
- IFluidDataStoreFactory: DataObjectClass<T>["factory"];
228
+ readonly IFluidDataStoreFactory: DataObjectClass<T>["factory"];
235
229
  };
236
230
  } & (new (...args: any[]) => T);
237
231
 
@@ -375,6 +369,65 @@ export declare enum FieldKind {
375
369
  Required = 1
376
370
  }
377
371
 
372
+ /**
373
+ * Additional information to provide to a {@link FieldSchema}.
374
+ *
375
+ * @public
376
+ */
377
+ export declare interface FieldProps {
378
+ /**
379
+ * The unique identifier of a field, used in the persisted form of the tree.
380
+ *
381
+ * @remarks
382
+ * If not explicitly set via the schema, this is the same as the schema's property key.
383
+ *
384
+ * Specifying a stored key that differs from the property key is particularly useful in refactoring scenarios.
385
+ * To update the developer-facing API, while maintaining backwards compatibility with existing SharedTree data,
386
+ * you can change the property key and specify the previous property key as the stored key.
387
+ *
388
+ * Notes:
389
+ *
390
+ * - Stored keys have no impact on standard JavaScript behavior, on tree nodes. For example, `Object.keys`
391
+ * will always return the property keys specified in the schema, ignoring any stored keys that differ from
392
+ * the property keys.
393
+ *
394
+ * - When specifying stored keys in an object schema, you must ensure that the final set of stored keys
395
+ * (accounting for those implicitly derived from property keys) contains no duplicates.
396
+ * This is validated at runtime.
397
+ *
398
+ * @example Refactoring code without breaking compatibility with existing data
399
+ *
400
+ * Consider some existing object schema:
401
+ *
402
+ * ```TypeScript
403
+ * class Point extends schemaFactory.object("Point", {
404
+ * xPosition: schemaFactory.number,
405
+ * yPosition: schemaFactory.number,
406
+ * zPosition: schemaFactory.optional(schemaFactory.number),
407
+ * });
408
+ * ```
409
+ *
410
+ * Developers using nodes of this type would access the the `xPosition` property as `point.xPosition`.
411
+ *
412
+ * We would like to refactor the schema to omit "Position" from the property keys, but application data has
413
+ * already been persisted using the original property keys. To maintain compatibility with existing data,
414
+ * we can refactor the schema as follows:
415
+ *
416
+ * ```TypeScript
417
+ * class Point extends schemaFactory.object("Point", {
418
+ * x: schemaFactory.required(schemaFactory.number, { key: "xPosition" }),
419
+ * y: schemaFactory.required(schemaFactory.number, { key: "yPosition" }),
420
+ * z: schemaFactory.optional(schemaFactory.number, { key: "zPosition" }),
421
+ * });
422
+ * ```
423
+ *
424
+ * Now, developers can access the `x` property as `point.x`, while existing data can still be collaborated on.
425
+ *
426
+ * @defaultValue If not specified, the key that is persisted is the property key that was specified in the schema.
427
+ */
428
+ readonly key?: string;
429
+ }
430
+
378
431
  /**
379
432
  * All policy for a specific field,
380
433
  * including functionality that does not have to be kept consistent across versions or deterministic.
@@ -383,19 +436,44 @@ export declare enum FieldKind {
383
436
  * @sealed @public
384
437
  */
385
438
  export declare class FieldSchema<out Kind extends FieldKind = FieldKind, out Types extends ImplicitAllowedTypes = ImplicitAllowedTypes> {
439
+ /**
440
+ * The {@link https://en.wikipedia.org/wiki/Kind_(type_theory) | kind } of this field.
441
+ * Determines the multiplicity, viewing and editing APIs as well as the merge resolution policy.
442
+ */
386
443
  readonly kind: Kind;
444
+ /**
445
+ * What types of tree nodes are allowed in this field.
446
+ */
387
447
  readonly allowedTypes: Types;
448
+ /**
449
+ * Optional properties associated with the field.
450
+ */
451
+ readonly props?: FieldProps | undefined;
388
452
  /**
389
453
  * This class is used with instanceof, and therefore should have nominal typing.
390
454
  * This field enforces that.
391
455
  */
392
456
  protected _typeCheck?: MakeNominal;
457
+ private readonly lazyTypes;
393
458
  /**
394
- * @param kind - The [kind](https://en.wikipedia.org/wiki/Kind_(type_theory)) of this field.
395
- * Determine the multiplicity, viewing and editing APIs as well as the merge resolution policy.
396
- * @param allowedTypes - What types of tree nodes are allowed in this field.
459
+ * What types of tree nodes are allowed in this field.
460
+ * @remarks Counterpart to {@link FieldSchema.allowedTypes}, with any lazy definitions evaluated.
397
461
  */
398
- constructor(kind: Kind, allowedTypes: Types);
462
+ get allowedTypeSet(): ReadonlySet<TreeNodeSchema>;
463
+ constructor(
464
+ /**
465
+ * The {@link https://en.wikipedia.org/wiki/Kind_(type_theory) | kind } of this field.
466
+ * Determines the multiplicity, viewing and editing APIs as well as the merge resolution policy.
467
+ */
468
+ kind: Kind,
469
+ /**
470
+ * What types of tree nodes are allowed in this field.
471
+ */
472
+ allowedTypes: Types,
473
+ /**
474
+ * Optional properties associated with the field.
475
+ */
476
+ props?: FieldProps | undefined);
399
477
  }
400
478
 
401
479
  /**
@@ -414,7 +492,7 @@ export declare type FlexList<Item = unknown> = readonly LazyItem<Item>[];
414
492
  * Normalize FlexList type to a union.
415
493
  * @public
416
494
  */
417
- export declare type FlexListToUnion<TList extends FlexList> = ExtractItemType<ArrayToUnion<TList>>;
495
+ export declare type FlexListToUnion<TList extends FlexList> = ExtractItemType<TList[number]>;
418
496
 
419
497
  /**
420
498
  * Base interface for information for each connection made to the Fluid session.
@@ -426,11 +504,11 @@ export declare interface IConnection {
426
504
  /**
427
505
  * A unique ID for the connection. A single user may have multiple connections, each with a different ID.
428
506
  */
429
- id: string;
507
+ readonly id: string;
430
508
  /**
431
509
  * Whether the connection is in read or read/write mode.
432
510
  */
433
- mode: "write" | "read";
511
+ readonly mode: "write" | "read";
434
512
  }
435
513
 
436
514
  /**
@@ -657,11 +735,11 @@ export declare interface IMember {
657
735
  /**
658
736
  * An ID for the user, unique among each individual user connecting to the session.
659
737
  */
660
- userId: string;
738
+ readonly userId: string;
661
739
  /**
662
740
  * The set of connections the user has made, e.g. from multiple tabs or devices.
663
741
  */
664
- connections: IConnection[];
742
+ readonly connections: IConnection[];
665
743
  }
666
744
 
667
745
  /**
@@ -743,7 +821,7 @@ export declare interface IServiceAudience<M extends IMember> extends IEventProvi
743
821
  * member object. The implementation may choose to exclude certain connections from the returned map.
744
822
  * E.g. ServiceAudience excludes non-interactive connections to represent only the roster of live users.
745
823
  */
746
- getMembers(): Map<string, M>;
824
+ getMembers(): ReadonlyMap<string, M>;
747
825
  /**
748
826
  * Returns the current active user on this client once they are connected. Otherwise, returns undefined.
749
827
  */
@@ -942,11 +1020,11 @@ export declare interface IValueChanged {
942
1020
  /**
943
1021
  * The key storing the value that changed.
944
1022
  */
945
- key: string;
1023
+ readonly key: string;
946
1024
  /**
947
1025
  * The value that was stored at the key prior to the change.
948
1026
  */
949
- previousValue: any;
1027
+ readonly previousValue: any;
950
1028
  }
951
1029
 
952
1030
  /**
@@ -1070,7 +1148,7 @@ export declare type MemberChangedListener<M extends IMember> = (clientId: string
1070
1148
  * @public
1071
1149
  */
1072
1150
  export declare type Myself<M extends IMember = IMember> = M & {
1073
- currentConnection: string;
1151
+ readonly currentConnection: string;
1074
1152
  };
1075
1153
 
1076
1154
  /**
@@ -1281,18 +1359,19 @@ export declare class SchemaFactory<out TScope extends string | undefined = strin
1281
1359
  /**
1282
1360
  * {@link TreeNodeSchema} for holding an {@link @fluidframework/core-interfaces#(IFluidHandle:interface)}.
1283
1361
  */
1284
- readonly handle: TreeNodeSchema<"com.fluidframework.leaf.handle", NodeKind.Leaf, IFluidHandle<FluidObject & IFluidLoadable>, IFluidHandle<FluidObject & IFluidLoadable>>;
1362
+ readonly handle: TreeNodeSchema<"com.fluidframework.leaf.handle", NodeKind.Leaf, IFluidHandle<FluidObject<unknown> & IFluidLoadable>, IFluidHandle<FluidObject<unknown> & IFluidLoadable>>;
1285
1363
  /**
1286
1364
  * Construct a class that provides the common parts all TreeNodeSchemaClass share.
1287
1365
  * More specific schema extend this class.
1288
1366
  */
1289
1367
  private nodeSchema;
1290
1368
  /**
1291
- * Define a {@link TreeNodeSchema} for an object node.
1369
+ * Define a {@link TreeNodeSchema} for a {@link TreeObjectNode}.
1292
1370
  *
1293
1371
  * @param name - Unique identifier for this schema within this factory's scope.
1372
+ * @param fields - Schema for fields of the object node's schema. Defines what children can be placed under each key.
1294
1373
  */
1295
- object<const Name extends TName, const T extends RestrictiveReadonlyRecord<string, ImplicitFieldSchema>>(name: Name, t: T): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Object, TreeNode & ObjectFromSchemaRecord<T> & WithType<ScopedSchemaName<TScope, Name>>, object & InsertableObjectFromSchemaRecord<T>, true, T>;
1374
+ object<const Name extends TName, const T extends RestrictiveReadonlyRecord<string, ImplicitFieldSchema>>(name: Name, fields: T): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Object, TreeObjectNode<T, ScopedSchemaName<TScope, Name>>, object & InsertableObjectFromSchemaRecord<T>, true, T>;
1296
1375
  /**
1297
1376
  * Define a structurally typed {@link TreeNodeSchema} for a {@link TreeMapNode}.
1298
1377
  *
@@ -1400,9 +1479,23 @@ export declare class SchemaFactory<out TScope extends string | undefined = strin
1400
1479
  */
1401
1480
  namedArray_internal<Name extends TName | string, const T extends ImplicitAllowedTypes, const ImplicitlyConstructable extends boolean>(name: Name, allowedTypes: T, customizable: boolean, implicitlyConstructable: ImplicitlyConstructable): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Array, TreeArrayNode<T> & WithType<ScopedSchemaName<TScope, string>>, Iterable<InsertableTreeNodeFromImplicitAllowedTypes<T>>, ImplicitlyConstructable, T>;
1402
1481
  /**
1403
- * Make a field optional instead of the default which is required.
1482
+ * Make a field optional instead of the default, which is required.
1483
+ *
1484
+ * @param t - The types allowed under the field.
1485
+ * @param props - Optional properties to associate with the field.
1486
+ */
1487
+ optional<const T extends ImplicitAllowedTypes>(t: T, props?: FieldProps): FieldSchema<FieldKind.Optional, T>;
1488
+ /**
1489
+ * Make a field explicitly required.
1490
+ *
1491
+ * @param t - The types allowed under the field.
1492
+ * @param props - Optional properties to associate with the field.
1493
+ *
1494
+ * @remarks
1495
+ * Fields are required by default, but this API can be used to make the required nature explicit in the schema,
1496
+ * and allows associating custom {@link FieldProps | properties} with the field.
1404
1497
  */
1405
- optional<const T extends ImplicitAllowedTypes>(t: T): FieldSchema<FieldKind.Optional, T>;
1498
+ required<const T extends ImplicitAllowedTypes>(t: T, props?: FieldProps): FieldSchema<FieldKind.Required, T>;
1406
1499
  /**
1407
1500
  * Function which can be used for its compile time side-effects to tweak the evaluation order of recursive types to make them compile.
1408
1501
  * @remarks
@@ -1460,14 +1553,14 @@ export declare interface SchemaIncompatible {
1460
1553
  export declare type ScopedSchemaName<TScope extends string | undefined, TName extends number | string> = TScope extends undefined ? `${TName}` : `${TScope}.${TName}`;
1461
1554
 
1462
1555
  /**
1463
- * {@inheritDoc ISharedMap}
1556
+ * Entrypoint for {@link ISharedMap} creation.
1464
1557
  * @public
1465
1558
  * @deprecated Please use SharedTree for new containers. SharedMap is supported for loading preexisting Fluid Framework 1.0 containers only.
1466
1559
  */
1467
1560
  export declare const SharedMap: ISharedObjectKind<ISharedMap>;
1468
1561
 
1469
1562
  /**
1470
- * {@inheritDoc ISharedMap}
1563
+ * Entrypoint for {@link ISharedMap} creation.
1471
1564
  * @public
1472
1565
  * @deprecated Use ISharedMap instead.
1473
1566
  * @privateRemarks
@@ -1694,6 +1787,86 @@ export declare interface TreeArrayNodeBase<out T, in TNew, in TMoveFrom> extends
1694
1787
  moveRangeToIndex(index: number, sourceStart: number, sourceEnd: number, source: TMoveFrom): void;
1695
1788
  }
1696
1789
 
1790
+ /**
1791
+ * A collection of events that can be raised by a {@link TreeNode}.
1792
+ *
1793
+ * @privateRemarks
1794
+ * TODO: add a way to subscribe to a specific field (for nodeChanged and treeChanged).
1795
+ * Probably have object node and map node specific APIs for this.
1796
+ *
1797
+ * TODO: ensure that subscription API for fields aligns with API for subscribing to the root.
1798
+ *
1799
+ * TODO: add more wider area (avoid needing tons of nodeChanged registration) events for use-cases other than treeChanged.
1800
+ * Some ideas:
1801
+ *
1802
+ * - treeChanged, but with some subtrees/fields/paths excluded
1803
+ * - helper to batch several nodeChanged calls to a treeChanged scope
1804
+ * - parent change (ex: registration on the parent field for a specific index: maybe allow it for a range. Ex: node event takes optional field and optional index range?)
1805
+ * - new content inserted into subtree. Either provide event for this and/or enough info to treeChanged to find and search the new sub-trees.
1806
+ * Add separate (non event related) API to efficiently scan tree for given set of types (using low level cursor and schema based filtering)
1807
+ * to allow efficiently searching for new content (and initial content) of a given type.
1808
+ *
1809
+ * @public
1810
+ */
1811
+ export declare interface TreeChangeEvents {
1812
+ /**
1813
+ * Emitted by a node when a batch of changes is applied to it, where a change is:
1814
+ *
1815
+ * - For an object node, when the value of one of its properties changes (i.e., the property's value is set
1816
+ * to something else, including `undefined`).
1817
+ *
1818
+ * - For an array node, when an element is added, removed, or moved.
1819
+ *
1820
+ * - For a map node, when an entry is added, updated, or removed.
1821
+ *
1822
+ * @remarks
1823
+ * This event is not raised when:
1824
+ *
1825
+ * - Properties of a child node change. Notably, updates to an array node or a map node (like adding or removing
1826
+ * elements/entries) will raise this event on the array/map node itself, but not on the node that contains the
1827
+ * array/map node as one of its properties.
1828
+ *
1829
+ * - The node is moved to a different location in the tree or removed from the tree.
1830
+ * In this case the event is raised on the _parent_ node, not the node itself.
1831
+ *
1832
+ * For remote edits, this event is not guaranteed to occur in the same order or quantity that it did in
1833
+ * the client that made the original edit.
1834
+ * While a batch of edits will as a whole update the tree to the appropriate end state, no guarantees are made about
1835
+ * how many times this event will be raised during any intermediate states.
1836
+ * When it is raised, the tree is guaranteed to be in-schema.
1837
+ *
1838
+ * @privateRemarks
1839
+ * This event occurs whenever the apparent contents of the node instance change, regardless of what caused the change.
1840
+ * For example, it will fire when the local client reassigns a child, when part of a remote edit is applied to the
1841
+ * node, or when the node has to be updated due to resolution of a merge conflict
1842
+ * (for example a previously applied local change might be undone, then reapplied differently or not at all).
1843
+ */
1844
+ nodeChanged(): void;
1845
+ /**
1846
+ * Emitted by a node when something _may_ have changed anywhere in the subtree rooted at it.
1847
+ *
1848
+ * @remarks
1849
+ * This event is guaranteed to be emitted whenever the subtree _has_ changed.
1850
+ * However, it might also be emitted when the subtree has no visible changes compared to before the event firing.
1851
+ *
1852
+ * Consumers of this event have the guarantee that they won't miss any changes, but should also handle the scenario
1853
+ * where the event fires with no visible changes as well.
1854
+ *
1855
+ * This event is not raised when the node itself is moved to a different location in the tree or removed from the tree.
1856
+ * In that case it is raised on the _parent_ node, not the node itself.
1857
+ *
1858
+ * The node itself is part of the subtree, so this event will be emitted even if the only changes are to the properties
1859
+ * of the node itself.
1860
+ *
1861
+ * For remote edits, this event is not guaranteed to occur in the same order or quantity that it did in
1862
+ * the client that made the original edit.
1863
+ * While a batch of edits will as a whole update the tree to the appropriate end state, no guarantees are made about
1864
+ * how many times this event will be raised during any intermediate states.
1865
+ * When it is raised, the tree is guaranteed to be in-schema.
1866
+ */
1867
+ treeChanged(): void;
1868
+ }
1869
+
1697
1870
  /**
1698
1871
  * Configuration for how to {@link ITree.schematize|schematize} a tree.
1699
1872
  * @public
@@ -1847,27 +2020,19 @@ export declare interface TreeNodeApi {
1847
2020
  key(node: TreeNode): string | number;
1848
2021
  /**
1849
2022
  * Register an event listener on the given node.
2023
+ * @param node - The node whose events should be subscribed to.
2024
+ * @param eventName - Which event to subscribe to.
2025
+ * @param listener - The callback to trigger for the event. The tree can be read during the callback, but it is invalid to modify the tree during this callback.
1850
2026
  * @returns A callback function which will deregister the event.
1851
2027
  * This callback should be called only once.
1852
2028
  */
1853
- on<K extends keyof TreeNodeEvents>(node: TreeNode, eventName: K, listener: TreeNodeEvents[K]): () => void;
2029
+ on<K extends keyof TreeChangeEvents>(node: TreeNode, eventName: K, listener: TreeChangeEvents[K]): () => void;
1854
2030
  /**
1855
2031
  * Returns the {@link TreeStatus} of the given node.
1856
2032
  */
1857
2033
  readonly status: (node: TreeNode) => TreeStatus;
1858
2034
  }
1859
2035
 
1860
- /**
1861
- * A collection of events that can be raised by a {@link TreeNode}.
1862
- * @public
1863
- */
1864
- export declare interface TreeNodeEvents {
1865
- /**
1866
- * Raised on a node right after a change is applied to one of its fields or the fields of a descendant node.
1867
- */
1868
- afterChange(): void;
1869
- }
1870
-
1871
2036
  /**
1872
2037
  * Type of of tree node for a field of the given schema.
1873
2038
  * @public
@@ -1948,6 +2113,18 @@ export declare interface TreeNodeSchemaNonClass<out Name extends string = string
1948
2113
  create(data: TInsertable): TNode;
1949
2114
  }
1950
2115
 
2116
+ /**
2117
+ * A {@link TreeNode} which modules a JavaScript object.
2118
+ * @remarks
2119
+ * Object nodes consist of a type which specifies which {@link TreeNodeSchema} they use (see {@link TreeNodeApi.schema}), and a collections of fields, each with a distinct `key` and its own {@link FieldSchema} defining what can be placed under that key.
2120
+ *
2121
+ * All non-empty fields on an object node are exposed as enumerable own properties with string keys.
2122
+ * No other own `own` or `enumerable` properties are included on object nodes unless the user of the node manually adds custom session only state.
2123
+ * This allows a majority of general purpose JavaScript object processing operations (like `for...in`, `Reflect.ownKeys()` and `Object.entries()`) to enumerate all the children.
2124
+ * @public
2125
+ */
2126
+ export declare type TreeObjectNode<T extends RestrictiveReadonlyRecord<string, ImplicitFieldSchema>, TypeName extends string = string> = TreeNode & ObjectFromSchemaRecord<T> & WithType<TypeName>;
2127
+
1951
2128
  /**
1952
2129
  * Status of the tree that a particular node belongs to.
1953
2130
  * @public