@fluidframework/presence 2.52.0 → 2.53.0-350190

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/README.md CHANGED
@@ -68,18 +68,21 @@ A `StatesWorkspace` allows sharing of simple data across attendees where each at
68
68
 
69
69
  #### Notifications Workspace
70
70
 
71
- A `NotificationsWorkspace` is similar to states workspace, but is dedicated to notification use-cases via `NotificationsManager`.
71
+ A `NotificationsWorkspace` is similar to `StatesWorkspace`, but is dedicated to notification use-cases via `NotificationsManager`.
72
72
 
73
- ### States
73
+ ### State objects
74
74
 
75
- #### Latest
75
+ #### Latest, LatestRaw
76
76
 
77
- `Latest` retains the most recent atomic value each attendee has shared. Use `StateFactory.latest` to add one to `StatesWorkspace`.
77
+ `Latest` and `LatestRaw` (unvalidated data) retain the most recent atomic value each attendee has shared.
78
+ Use `StateFactory.latest` to add one to `StatesWorkspace`.
78
79
 
79
- #### LatestMap
80
+ #### LatestMap, LatestMapRaw
80
81
 
81
- `LatestMap` retains the most recent atomic value each attendee has shared under arbitrary keys. Values associated with a
82
- key may be set to `undefined` to represent deletion. Use `StateFactory.latestMap` to add one to a `StatesWorkspace`.
82
+ `LatestMap` and `LatestMapRaw` (unvalidated data) retain the most recent atomic value each attendee has shared under arbitrary keys (mimics `Map` data structure).
83
+ Values associated with a key may be set to `undefined` to represent deletion.
84
+ Use `StateFactory.latestMap` to add one to a `StatesWorkspace`.
85
+ (`LatestMap` support is pending.)
83
86
 
84
87
  #### NotificationsManager
85
88
 
@@ -87,6 +90,116 @@ Notifications are a special case where no data is retained during a session and
87
90
 
88
91
  ## Using Presence
89
92
 
93
+ ### State object use
94
+
95
+ State objects have:
96
+
97
+ 1. a `local` property representing local clients state data
98
+ 1. an `events` property to listen for remote and local updates
99
+ 1. several `get*` methods to access other attendees and their data
100
+
101
+ #### Latest, LatestRaw use
102
+
103
+ Simple assignment of new value (new object) initiates broadcast of new value to other attendees.
104
+
105
+ ```typescript
106
+ function updateMyPosition(positionTracker: Latest<PointXY>, newPosition: PointXY): void {
107
+ positionTracker.local = newPosition;
108
+ }
109
+ ```
110
+
111
+ Updates from remote clients can be listened for using `events`.
112
+
113
+ ```typescript
114
+ function startTrackingOthersPositions(positionTracker: Latest<PointXY>): (() => void) {
115
+ const stop = positionTracker.events.on("remoteUpdated", (update) => {
116
+ const pos = update.value();
117
+ if (pos === undefined) {
118
+ console.warn(`Attendee ${update.attendee.attendeeId} sent invalid position data`);
119
+ } else {
120
+ console.log(`Attendee ${update.attendee.attendeeId} now at (${pos.x}, ${pos.y})`);
121
+ }
122
+ });
123
+ return stop;
124
+ }
125
+ ```
126
+
127
+ Accumulated data can be enumerated using `getRemotes`.
128
+
129
+ ```typescript
130
+ // Logs other attendees' current positions (includes now disconnected attendees)
131
+ function logOthersPositions(positionTracker: Latest<PointXY>): void {
132
+ for (const { attendee, value } of positionTracker.getRemotes()) {
133
+ const validated = value();
134
+ const position = validated === undefined ? "<invalid>" : `(${validated.x}, ${validated.y})`;
135
+ console.log(`${attendee.attendeeId} ${position} [${attendee.getConnectionStatus()}]:`);
136
+ }
137
+ }
138
+ ```
139
+
140
+ #### LatestMap, LatestMapRaw use
141
+
142
+ A change to the `local` property automatically initiates a broadcast of updates to other attendees.
143
+ `local` is a [StateMap](https://fluidframework.com/docs/api/presence/statemap-interface) that mimics `Map` though it only supports `string | number` as property keys.
144
+
145
+ ```typescript
146
+ function updateCounter(counterTracker: LatestMap<number, string>, counterName: string, value: number): void {
147
+ counterTracker.local.set(counterName, value);
148
+ }
149
+ ```
150
+
151
+ Updates from remote clients can be listened for using `events`.
152
+ `"remoteItemUpdated"` and `"remoteItemRemoved"` provide fine-grain updates and `"remoteUpdated"` (use not shown) notes any change but only provides complete new map.
153
+
154
+ ```typescript
155
+ function startTrackingOthersCounters(counterTracker: LatestMapRaw<number, string>): (() => void) {
156
+ const stopUpdated = counterTracker.events.on("remoteItemUpdated", (update) => {
157
+ console.log(`Attendee ${update.attendee.attendeeId} updated counter ${update.key} to ${update.value}.`);
158
+ });
159
+ const stopRemoved = counterTracker.events.on("remoteItemRemoved", (update) => {
160
+ console.log(`Attendee ${update.attendee.attendeeId} removed counter ${update.key}.`);
161
+ });
162
+ return () => { stopUpdated(); stopRemoved(); };
163
+ }
164
+ ```
165
+
166
+ Accumulated data can be enumerated using `getRemotes`.
167
+
168
+ ```typescript
169
+ // Logs other attendee's current counters (excludes now _disconnected_ attendees)
170
+ function logOthersCounters(counterTracker: LatestMap<number, string>): void {
171
+ const counterMap = new Map<string, { attendee: Attendee; value: number }[]>();
172
+ // Collect counters from all remote attendees
173
+ for (const { attendee, items } of counterTracker.getRemotes()) {
174
+ // Only collect from *connected* attendees
175
+ if (attendee.getConnectionStatus() === AttendeeStatus.Connected) {
176
+ // `items` is a simple `ReadonlyMap` of remote data
177
+ for (const [counterName, state] of items.entries()) {
178
+ let entry = counterMap.get(counterName);
179
+ if (!entry) {
180
+ entry = [];
181
+ counterMap.set(counterName, entry);
182
+ }
183
+ const value = state.value();
184
+ // Just skip unrecognized data
185
+ if (value !== undefined) {
186
+ entry.push({ attendee, value });
187
+ }
188
+ }
189
+ }
190
+ }
191
+
192
+ for (const [key, items] of counterMap.entries()) {
193
+ console.log(`Counter ${key}:`);
194
+ for (const { attendee, value } of items) {
195
+ console.log(` ${attendee.attendeeId}: ${value}`);
196
+ }
197
+ }
198
+ }
199
+ ```
200
+
201
+ ### Setup
202
+
90
203
  To access Presence APIs, use `getPresence()` with any `IFluidContainer`.
91
204
 
92
205
  ```typescript
@@ -97,15 +210,112 @@ function usePresence(container: IFluidContainer): void {
97
210
  }
98
211
  ```
99
212
 
213
+ #### Schema Definition and Workspace
214
+
215
+ ```typescript
216
+ import type { Latest, LatestMap, Presence, StatesWorkspaceSchema } from "@fluidframework/presence/beta";
217
+ import { StateFactory } from "@fluidframework/presence/beta";
218
+
219
+ interface PointXY { x: number; y: number }
220
+
221
+ // Basic custom type guard
222
+ function isPointXY(value: unknown): value is PointXY {
223
+ return typeof value === "object" && value !== null && "x" in value && "y" in value &&
224
+ typeof value.x === "number" && typeof value.y === "number";
225
+ }
226
+
227
+ function numberOrUndefined(value: unknown): number | undefined {
228
+ return typeof value === 'number' ? value : undefined;
229
+ }
230
+
231
+ // A Presence workspace schema with two State objects named "position" and "counters".
232
+ const PresenceSchemaV1 = {
233
+ // This `Latest<PointXY>` state defaults all values to (0, 0).
234
+ position: StateFactory.latest<PointXY>({
235
+ local: { x: 0, y: 0 },
236
+ validator: (v) => isPointXY(v) ? v : undefined
237
+ }),
238
+ // This `LatestMap<number, string>` state has `string` keys storing `number` values.
239
+ counters: StateFactory.latestMap<number, string>({ validator: numberOrUndefined }),
240
+ } as const satisfies StatesWorkspaceSchema;
241
+
242
+ // Creates our unique workspace with the State objects declared in above schema.
243
+ function getOurWorkspace(presence: Presence):
244
+ {
245
+ position: Latest<PointXY>;
246
+ counters: LatestMap<number, string>;
247
+ } {
248
+ return presence.states.getWorkspace("name:PointsAndCountersV1", PresenceSchemaV1).states;
249
+ }
250
+ ```
251
+
100
252
  ## Other Capabilities
101
253
 
102
254
  ### Runtime data validation
103
255
 
104
- Runtime data validation is not yet implemented. The StateFactory.latest and StateFactory.latestMap APIs do not yet
105
- accept a `validator` argument. The validator argument is reserved for future use. **Passing the `validator` argument in version 2.43.0 will result in a runtime exception.**
256
+ The Presence API provides a simple mechanism (fully added in version 2.53.0) to validate that state data received within session from other clients matches the types declared.
257
+
258
+ When creating State objects using `StateFactory.latest` or `StateFactory.latestMap`, it is recommended that a validator function is specified.
259
+ That function will be called on-demand at runtime to verify data from other clients is valid.
260
+
261
+ When you provide a validator function, the data in a State object must be accessed via `.value()` function call instead of a directly accessing `.value` as a property.
262
+ This is reflected in the types.
263
+
264
+ > [!IMPORTANT]
265
+ > If no validator function is provided, then the data shared in Presence is assumed to be compatible.
266
+ > This may result in runtime errors if the data does not match the expected type.
267
+ > It is recommended to always provide a validator function to ensure that the data is valid and to prevent runtime errors.
268
+
269
+ #### Validator Requirements
270
+
271
+ 1. Validator functions take the form `function validator(value: unknown): ExpectedType | undefined`.
272
+ 1. Validator functions may not manipulate the given value.
273
+ 1. Validator functions are not expected to throw exceptions.
274
+ 1. When malformed data is found, a validator function may either return `undefined` or create a substitute value.
275
+
276
+ The result of call to validator is returned as-is to the `.value()` call that first attempted access to remote data.
277
+ That result is cached and will be returned to future `.value()` callers without invoking the validator.
278
+
279
+ #### Example Validated Setup
280
+
281
+ Custom validators can be convenient for simple types.
282
+ See [Schema Definition and Workspace](#schema-definition-and-workspace) for example.
283
+ For more complex types or peace of mind, consider a schema builder / validation package such as [TypeBox](https://github.com/sinclairzx81/typebox) or [Zod](https://zod.dev/).
284
+
285
+ Example using TypeBox:
286
+ ```typescript
287
+ import { type Static, Type } from "@sinclair/typebox";
288
+ import { TypeCompiler } from '@sinclair/typebox/compiler'
289
+
290
+ const PointXY = Type.Object({
291
+ x: Type.Number(),
292
+ y: Type.Number(),
293
+ });
294
+ type PointXY = Static<typeof PointXY>;
295
+
296
+ const typeCheckPointXY = TypeCompiler.Compile(PointXY);
297
+
298
+ function validatorPointXY(value: unknown): PointXY | undefined {
299
+ return typeCheckPointXY.Check(value) ? value : undefined;
300
+ }
301
+
302
+ const PresenceSchemaV1 = {
303
+ position: StateFactory.latest({
304
+ local: { x: 0, y: 0 },
305
+ validator: validatorPointXY
306
+ }),
307
+ } as const satisfies StatesWorkspaceSchema;
308
+ ```
106
309
 
107
310
  ## Limitations
108
311
 
312
+ ### Data Supported
313
+
314
+ Only plain old data is supported.
315
+ If `JSON.parse(JSON.stringify(foo))` returns a deeply equal value, then that data is supported.
316
+ Large data is not recommended and if used may exceed system capacity.
317
+ A small image could be shared but sharing a URL to an image is recommended.
318
+
109
319
  ### Compatibility and Versioning
110
320
 
111
321
  The schema of workspace address, states and notifications names, and their types will only be consistent when all
@@ -147,7 +357,7 @@ Notifications are fundamentally unreliable at this time as there are no built-in
147
357
 
148
358
  Presence updates are grouped together and throttled to prevent flooding the network with messages when presence values are rapidly updated. This means the presence infrastructure will not immediately broadcast updates but will broadcast them after a configurable delay.
149
359
 
150
- The `allowableUpdateLatencyMs` property configures how long a local update may be delayed under normal circumstances, enabling grouping with other updates. The default `allowableUpdateLatencyMs` is **60 milliseconds** but may be (1) specified during configuration of a [States Workspace](#states-workspace) or [States](#states) and/or (2) updated later using the `controls` member of Workspace or States. The [States Workspace](#states-workspace) configuration is used when States do not have their own setting.
360
+ The `allowableUpdateLatencyMs` property configures how long a local update may be delayed under normal circumstances, enabling grouping with other updates. The default `allowableUpdateLatencyMs` is **60 milliseconds** but may be (1) specified during configuration of a [States Workspace](#states-workspace) or [States](#state-objects) and/or (2) updated later using the `controls` member of Workspace or States. The [States Workspace](#states-workspace) configuration is used when States do not have their own setting.
151
361
 
152
362
  Notifications are never queued; they effectively always have an `allowableUpdateLatencyMs` of 0. However, they may be grouped with other updates that were already queued.
153
363
 
package/dist/alpha.d.ts CHANGED
@@ -35,6 +35,7 @@ export {
35
35
  LatestEvents,
36
36
  LatestFactory,
37
37
  LatestMap,
38
+ LatestMapArguments,
38
39
  LatestMapArgumentsRaw,
39
40
  LatestMapClientData,
40
41
  LatestMapEvents,
package/dist/beta.d.ts CHANGED
@@ -35,6 +35,7 @@ export {
35
35
  LatestEvents,
36
36
  LatestFactory,
37
37
  LatestMap,
38
+ LatestMapArguments,
38
39
  LatestMapArgumentsRaw,
39
40
  LatestMapClientData,
40
41
  LatestMapEvents,
package/dist/index.d.ts CHANGED
@@ -15,7 +15,7 @@ export { type Attendee, type AttendeesEvents, type AttendeeId, AttendeeStatus, t
15
15
  export type { BroadcastControls, BroadcastControlSettings, } from "./broadcastControls.js";
16
16
  export { getPresence, getPresenceAlpha } from "./getPresence.js";
17
17
  export { getPresenceViaDataObject, type ExperimentalPresenceDO, ExperimentalPresenceManager, } from "./datastorePresenceManagerFactory.js";
18
- export type { LatestMap, LatestMapArgumentsRaw, LatestMapClientData, LatestMapEvents, LatestMapFactory, LatestMapItemRemovedClientData, LatestMapItemUpdatedClientData, LatestMapRaw, LatestMapRawEvents, StateMap, } from "./latestMapValueManager.js";
18
+ export type { LatestMap, LatestMapArguments, LatestMapArgumentsRaw, LatestMapClientData, LatestMapEvents, LatestMapFactory, LatestMapItemRemovedClientData, LatestMapItemUpdatedClientData, LatestMapRaw, LatestMapRawEvents, StateMap, } from "./latestMapValueManager.js";
19
19
  export type { Latest, LatestArguments, LatestArgumentsRaw, LatestEvents, LatestFactory, LatestRaw, LatestRawEvents, } from "./latestValueManager.js";
20
20
  export type { Accessor, LatestClientData, LatestData, LatestMetadata, ProxiedValueAccessor, RawValueAccessor, StateSchemaValidator, ValueAccessor, } from "./latestValueTypes.js";
21
21
  export { type NotificationEmitter, type NotificationListenable, type NotificationSubscriptions, Notifications, type NotificationsManager, type NotificationsManagerEvents, } from "./notificationsManager.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;GAMG;AAEH,YAAY,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEzD,YAAY,EACX,sBAAsB,EACtB,4BAA4B,EAC5B,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACN,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,cAAc,EACd,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,yBAAyB,GAC9B,MAAM,eAAe,CAAC;AAEvB,YAAY,EACX,iBAAiB,EACjB,wBAAwB,GACxB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEjE,OAAO,EACN,wBAAwB,EACxB,KAAK,sBAAsB,EAC3B,2BAA2B,GAC3B,MAAM,sCAAsC,CAAC;AAE9C,YAAY,EACX,SAAS,EAET,qBAAqB,EACrB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,8BAA8B,EAC9B,8BAA8B,EAC9B,YAAY,EACZ,kBAAkB,EAClB,QAAQ,GACR,MAAM,4BAA4B,CAAC;AACpC,YAAY,EACX,MAAM,EACN,eAAe,EACf,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,SAAS,EACT,eAAe,GACf,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACX,QAAQ,EACR,gBAAgB,EAChB,UAAU,EACV,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,GACb,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACN,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,yBAAyB,EAC9B,aAAa,EACb,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,GAC/B,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,YAAY,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,YAAY,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;GAMG;AAEH,YAAY,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEzD,YAAY,EACX,sBAAsB,EACtB,4BAA4B,EAC5B,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACN,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,cAAc,EACd,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,yBAAyB,GAC9B,MAAM,eAAe,CAAC;AAEvB,YAAY,EACX,iBAAiB,EACjB,wBAAwB,GACxB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEjE,OAAO,EACN,wBAAwB,EACxB,KAAK,sBAAsB,EAC3B,2BAA2B,GAC3B,MAAM,sCAAsC,CAAC;AAE9C,YAAY,EACX,SAAS,EACT,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,8BAA8B,EAC9B,8BAA8B,EAC9B,YAAY,EACZ,kBAAkB,EAClB,QAAQ,GACR,MAAM,4BAA4B,CAAC;AACpC,YAAY,EACX,MAAM,EACN,eAAe,EACf,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,SAAS,EACT,eAAe,GACf,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACX,QAAQ,EACR,gBAAgB,EAChB,UAAU,EACV,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,GACb,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACN,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,yBAAyB,EAC9B,aAAa,EACb,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,GAC/B,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,YAAY,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,YAAY,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC"}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAsBH,6CAQuB;AAJtB,6GAAA,cAAc,OAAA;AAWf,mDAAiE;AAAxD,6GAAA,WAAW,OAAA;AAAE,kHAAA,gBAAgB,OAAA;AAEtC,2FAI8C;AAH7C,8IAAA,wBAAwB,OAAA;AAExB,iJAAA,2BAA2B,OAAA;AAoC5B,qEAOmC;AAHlC,wHAAA,aAAa,OAAA;AAKd,qDAAiD;AAAxC,+GAAA,YAAY,OAAA","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * Package for client presence within a connected session.\n *\n * See {@link https://github.com/microsoft/FluidFramework/tree/main/packages/framework/presence#readme | README.md } for an overview of the package.\n *\n * @packageDocumentation\n */\n\nexport type { ClientConnectionId } from \"./baseTypes.js\";\n\nexport type {\n\tNotificationsWorkspace,\n\tNotificationsWorkspaceSchema,\n\tStatesWorkspace,\n\tStatesWorkspaceEntries,\n\tStatesWorkspaceSchema,\n\tStatesWorkspaceEntry,\n\tWorkspaceAddress,\n} from \"./types.js\";\n\nexport {\n\ttype Attendee,\n\ttype AttendeesEvents,\n\ttype AttendeeId,\n\tAttendeeStatus,\n\ttype Presence,\n\ttype PresenceEvents,\n\ttype PresenceWithNotifications,\n} from \"./presence.js\";\n\nexport type {\n\tBroadcastControls,\n\tBroadcastControlSettings,\n} from \"./broadcastControls.js\";\n\nexport { getPresence, getPresenceAlpha } from \"./getPresence.js\";\n\nexport {\n\tgetPresenceViaDataObject,\n\ttype ExperimentalPresenceDO,\n\tExperimentalPresenceManager,\n} from \"./datastorePresenceManagerFactory.js\";\n\nexport type {\n\tLatestMap,\n\t// LatestMapArguments,\n\tLatestMapArgumentsRaw,\n\tLatestMapClientData,\n\tLatestMapEvents,\n\tLatestMapFactory,\n\tLatestMapItemRemovedClientData,\n\tLatestMapItemUpdatedClientData,\n\tLatestMapRaw,\n\tLatestMapRawEvents,\n\tStateMap,\n} from \"./latestMapValueManager.js\";\nexport type {\n\tLatest,\n\tLatestArguments,\n\tLatestArgumentsRaw,\n\tLatestEvents,\n\tLatestFactory,\n\tLatestRaw,\n\tLatestRawEvents,\n} from \"./latestValueManager.js\";\nexport type {\n\tAccessor,\n\tLatestClientData,\n\tLatestData,\n\tLatestMetadata,\n\tProxiedValueAccessor,\n\tRawValueAccessor,\n\tStateSchemaValidator,\n\tValueAccessor,\n} from \"./latestValueTypes.js\";\n\nexport {\n\ttype NotificationEmitter,\n\ttype NotificationListenable,\n\ttype NotificationSubscriptions,\n\tNotifications,\n\ttype NotificationsManager,\n\ttype NotificationsManagerEvents,\n} from \"./notificationsManager.js\";\n\nexport { StateFactory } from \"./stateFactory.js\";\n\nexport type { InternalTypes } from \"./exposedInternalTypes.js\";\nexport type { InternalUtilityTypes } from \"./exposedUtilityTypes.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAsBH,6CAQuB;AAJtB,6GAAA,cAAc,OAAA;AAWf,mDAAiE;AAAxD,6GAAA,WAAW,OAAA;AAAE,kHAAA,gBAAgB,OAAA;AAEtC,2FAI8C;AAH7C,8IAAA,wBAAwB,OAAA;AAExB,iJAAA,2BAA2B,OAAA;AAoC5B,qEAOmC;AAHlC,wHAAA,aAAa,OAAA;AAKd,qDAAiD;AAAxC,+GAAA,YAAY,OAAA","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * Package for client presence within a connected session.\n *\n * See {@link https://github.com/microsoft/FluidFramework/tree/main/packages/framework/presence#readme | README.md } for an overview of the package.\n *\n * @packageDocumentation\n */\n\nexport type { ClientConnectionId } from \"./baseTypes.js\";\n\nexport type {\n\tNotificationsWorkspace,\n\tNotificationsWorkspaceSchema,\n\tStatesWorkspace,\n\tStatesWorkspaceEntries,\n\tStatesWorkspaceSchema,\n\tStatesWorkspaceEntry,\n\tWorkspaceAddress,\n} from \"./types.js\";\n\nexport {\n\ttype Attendee,\n\ttype AttendeesEvents,\n\ttype AttendeeId,\n\tAttendeeStatus,\n\ttype Presence,\n\ttype PresenceEvents,\n\ttype PresenceWithNotifications,\n} from \"./presence.js\";\n\nexport type {\n\tBroadcastControls,\n\tBroadcastControlSettings,\n} from \"./broadcastControls.js\";\n\nexport { getPresence, getPresenceAlpha } from \"./getPresence.js\";\n\nexport {\n\tgetPresenceViaDataObject,\n\ttype ExperimentalPresenceDO,\n\tExperimentalPresenceManager,\n} from \"./datastorePresenceManagerFactory.js\";\n\nexport type {\n\tLatestMap,\n\tLatestMapArguments,\n\tLatestMapArgumentsRaw,\n\tLatestMapClientData,\n\tLatestMapEvents,\n\tLatestMapFactory,\n\tLatestMapItemRemovedClientData,\n\tLatestMapItemUpdatedClientData,\n\tLatestMapRaw,\n\tLatestMapRawEvents,\n\tStateMap,\n} from \"./latestMapValueManager.js\";\nexport type {\n\tLatest,\n\tLatestArguments,\n\tLatestArgumentsRaw,\n\tLatestEvents,\n\tLatestFactory,\n\tLatestRaw,\n\tLatestRawEvents,\n} from \"./latestValueManager.js\";\nexport type {\n\tAccessor,\n\tLatestClientData,\n\tLatestData,\n\tLatestMetadata,\n\tProxiedValueAccessor,\n\tRawValueAccessor,\n\tStateSchemaValidator,\n\tValueAccessor,\n} from \"./latestValueTypes.js\";\n\nexport {\n\ttype NotificationEmitter,\n\ttype NotificationListenable,\n\ttype NotificationSubscriptions,\n\tNotifications,\n\ttype NotificationsManager,\n\ttype NotificationsManagerEvents,\n} from \"./notificationsManager.js\";\n\nexport { StateFactory } from \"./stateFactory.js\";\n\nexport type { InternalTypes } from \"./exposedInternalTypes.js\";\nexport type { InternalUtilityTypes } from \"./exposedUtilityTypes.js\";\n"]}
@@ -264,35 +264,31 @@ export interface LatestMapArguments<T, Keys extends string | number = string | n
264
264
  validator: StateSchemaValidator<T>;
265
265
  }
266
266
  /**
267
- * Factory for creating a {@link LatestMapRaw} State object.
267
+ * Factory for creating a {@link LatestMap} or {@link LatestMapRaw} State object.
268
268
  *
269
269
  * @beta
270
270
  * @sealed
271
271
  */
272
272
  export interface LatestMapFactory {
273
273
  /**
274
- * Factory for creating a {@link LatestMapRaw} State object.
274
+ * Factory for creating a {@link LatestMap} State object.
275
275
  *
276
- * @privateRemarks (change to `remarks` when adding signature overload)
277
- * This overload is used when called with {@link LatestMapArgumentsRaw}.
278
- * That is, if a validator function is _not_ provided.
276
+ * @remarks
277
+ * This overload is used when called with {@link LatestMapArguments}.
278
+ * That is, if a validator function is provided.
279
279
  */
280
- <T, Keys extends string | number = string | number, RegistrationKey extends string = string>(args?: LatestMapArgumentsRaw<T, Keys>): InternalTypes.ManagerFactory<RegistrationKey, InternalTypes.MapValueState<T, Keys>, LatestMapRaw<T, Keys>>;
281
- }
282
- /**
283
- * Factory for creating a {@link LatestMap} or {@link LatestMapRaw} State object.
284
- */
285
- export interface LatestMapFactoryInternal extends LatestMapFactory {
280
+ <T, Keys extends string | number = string | number, RegistrationKey extends string = string>(args: LatestMapArguments<T, Keys>): InternalTypes.ManagerFactory<RegistrationKey, InternalTypes.MapValueState<T, Keys>, LatestMap<T, Keys>>;
286
281
  /**
287
- * Factory for creating a {@link LatestMap} State object.
282
+ * Factory for creating a {@link LatestMapRaw} State object.
288
283
  *
289
284
  * @remarks
290
- * This overload is used when called with {@link LatestMapArguments}. That is, if a validator function is provided.
285
+ * This overload is used when called with {@link LatestMapArgumentsRaw}.
286
+ * That is, if a validator function is _not_ provided.
291
287
  */
292
- <T, Keys extends string | number = string | number, RegistrationKey extends string = string>(args: LatestMapArguments<T, Keys>): InternalTypes.ManagerFactory<RegistrationKey, InternalTypes.MapValueState<T, Keys>, LatestMap<T, Keys>>;
288
+ <T, Keys extends string | number = string | number, RegistrationKey extends string = string>(args?: LatestMapArgumentsRaw<T, Keys>): InternalTypes.ManagerFactory<RegistrationKey, InternalTypes.MapValueState<T, Keys>, LatestMapRaw<T, Keys>>;
293
289
  }
294
290
  /**
295
291
  * Factory for creating a {@link LatestMap} or {@link LatestMapRaw} State object.
296
292
  */
297
- export declare const latestMap: LatestMapFactoryInternal;
293
+ export declare const latestMap: LatestMapFactory;
298
294
  //# sourceMappingURL=latestMapValueManager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"latestMapValueManager.d.ts","sourceRoot":"","sources":["../src/latestMapValueManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAElE,OAAO,KAAK,EACX,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,MAAM,8DAA8D,CAAC;AAEtE,OAAO,KAAK,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAE1F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAc/D,OAAO,KAAK,EACX,gBAAgB,EAChB,UAAU,EACV,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,EACb,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAoB,MAAM,eAAe,CAAC;AAoBtF;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB,CACnC,CAAC,EACD,IAAI,SAAS,MAAM,GAAG,MAAM,EAC5B,cAAc,SAAS,aAAa,CAAC,CAAC,CAAC,EACvC,kBAAkB,SAAS,UAAU,GAAG,UAAU;IAElD;;OAEG;IACH,QAAQ,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IAEvC;;;;;OAKG;IACH,KAAK,EAAE,WAAW,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC;CACxD;AAED;;;;;GAKG;AACH,MAAM,WAAW,8BAA8B,CAC9C,CAAC,EACD,CAAC,SAAS,MAAM,GAAG,MAAM,EACzB,cAAc,SAAS,aAAa,CAAC,CAAC,CAAC,CACtC,SAAQ,gBAAgB,CAAC,CAAC,EAAE,cAAc,CAAC;IAC5C;;OAEG;IACH,GAAG,EAAE,CAAC,CAAC;CACP;AAED;;;;;GAKG;AACH,MAAM,WAAW,8BAA8B,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IACxE;;OAEG;IACH,QAAQ,EAAE,QAAQ,CAAC;IACnB;;OAEG;IACH,GAAG,EAAE,CAAC,CAAC;IACP;;OAEG;IACH,QAAQ,EAAE,cAAc,CAAC;CACzB;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe,CAC/B,CAAC,EACD,CAAC,SAAS,MAAM,GAAG,MAAM,EACzB,oBAAoB,SAAS,aAAa,CAAC,CAAC,CAAC,GAAG,oBAAoB,CAAC,CAAC,CAAC;IAEvE;;;;;;;OAOG;IACH,aAAa,EAAE,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,EAAE,oBAAoB,CAAC,KAAK,IAAI,CAAC;IAElF;;;;;OAKG;IACH,iBAAiB,EAAE,CAClB,WAAW,EAAE,8BAA8B,CAAC,CAAC,EAAE,CAAC,EAAE,oBAAoB,CAAC,KACnE,IAAI,CAAC;IAEV;;;;;OAKG;IACH,iBAAiB,EAAE,CAAC,WAAW,EAAE,8BAA8B,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IAE5E;;;;;OAKG;IACH,gBAAgB,EAAE,CAAC,WAAW,EAAE;QAC/B,KAAK,EAAE,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;QACzC,GAAG,EAAE,CAAC,CAAC;KACP,KAAK,IAAI,CAAC;IAEX;;;;;OAKG;IACH,gBAAgB,EAAE,CAAC,WAAW,EAAE;QAC/B,GAAG,EAAE,CAAC,CAAC;KACP,KAAK,IAAI,CAAC;CACX;AAED;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI,eAAe,CAC7E,CAAC,EACD,CAAC,EACD,gBAAgB,CAAC,CAAC,CAAC,CACnB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,WAAW,QAAQ,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,CAAC;IACrD;;;OAGG;IACH,KAAK,IAAI,IAAI,CAAC;IAEd;;;;;;;;;;OAUG;IACH,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC;IAExB;;OAEG;IACH,OAAO,CACN,UAAU,EAAE,CACX,KAAK,EAAE,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,EACxC,GAAG,EAAE,CAAC,EACN,GAAG,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,KACf,IAAI,EACT,OAAO,CAAC,EAAE,OAAO,GACf,IAAI,CAAC;IAER;;;;OAIG;IACH,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IAE3D;;;OAGG;IACH,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC;IAErB;;;;;;;OAOG;IACH,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAE9C;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;OAEG;IAGH;;OAEG;IAGH;;OAEG;IACH,IAAI,IAAI,gBAAgB,CAAC,CAAC,CAAC,CAAC;CAM5B;AAkGD;;;;;;;;;;GAUG;AACH,MAAM,WAAW,SAAS,CACzB,CAAC,EACD,IAAI,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,EAC9C,eAAe,SAAS,aAAa,CAAC,CAAC,CAAC,GAAG,oBAAoB,CAAC,CAAC,CAAC;IAElE;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAE5B;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC;IAEvE;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IAErC;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAClC;;OAEG;IACH,UAAU,IAAI,gBAAgB,CAAC,mBAAmB,CAAC,CAAC,EAAE,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC;IAC9E;;OAEG;IACH,iBAAiB,IAAI,QAAQ,EAAE,CAAC;IAChC;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,QAAQ,GAAG,WAAW,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC;CACjF;AAED;;;;;;;;;;GAUG;AACH,MAAM,MAAM,YAAY,CAAC,CAAC,EAAE,IAAI,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,IAAI,SAAS,CACtF,CAAC,EACD,IAAI,EACJ,gBAAgB,CAAC,CAAC,CAAC,CACnB,CAAC;AAwJF;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB,CAAC,CAAC,EAAE,IAAI,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM;IACvF;;OAEG;IACH,KAAK,CAAC,EAAE;SACN,CAAC,IAAI,IAAI,GAAG,gBAAgB,CAAC,CAAC,CAAC;KAChC,CAAC;IAEF;;OAEG;IACH,QAAQ,CAAC,EAAE,wBAAwB,GAAG,SAAS,CAAC;CAChD;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB,CAAC,CAAC,EAAE,IAAI,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CACpF,SAAQ,qBAAqB,CAAC,CAAC,EAAE,IAAI,CAAC;IACtC;;;OAGG;IACH,SAAS,EAAE,oBAAoB,CAAC,CAAC,CAAC,CAAC;CACnC;AAKD;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAChC;;;;;;OAMG;IAEH,CAAC,CAAC,EAAE,IAAI,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,eAAe,SAAS,MAAM,GAAG,MAAM,EAC1F,IAAI,CAAC,EAAE,qBAAqB,CAAC,CAAC,EAAE,IAAI,CAAC,GACnC,aAAa,CAAC,cAAc,CAC9B,eAAe,EACf,aAAa,CAAC,aAAa,CAAC,CAAC,EAAE,IAAI,CAAC,EACpC,YAAY,CAAC,CAAC,EAAE,IAAI,CAAC,CACrB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,WAAW,wBAAyB,SAAQ,gBAAgB;IACjE;;;;;OAKG;IACH,CAAC,CAAC,EAAE,IAAI,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,eAAe,SAAS,MAAM,GAAG,MAAM,EAC1F,IAAI,EAAE,kBAAkB,CAAC,CAAC,EAAE,IAAI,CAAC,GAC/B,aAAa,CAAC,cAAc,CAC9B,eAAe,EACf,aAAa,CAAC,aAAa,CAAC,CAAC,EAAE,IAAI,CAAC,EACpC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,CAClB,CAAC;CACF;AAID;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE,wBA4DvB,CAAC"}
1
+ {"version":3,"file":"latestMapValueManager.d.ts","sourceRoot":"","sources":["../src/latestMapValueManager.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,7 @@ exports.latestMap = void 0;
8
8
  const client_utils_1 = require("@fluid-internal/client-utils");
9
9
  const broadcastControls_js_1 = require("./broadcastControls.js");
10
10
  const internalUtils_js_1 = require("./internalUtils.js");
11
+ const latestValueTypes_js_1 = require("./latestValueTypes.js");
11
12
  const stateDatastore_js_1 = require("./stateDatastore.js");
12
13
  const valueManager_js_1 = require("./valueManager.js");
13
14
  class ValueMapImpl {
@@ -88,10 +89,11 @@ class ValueMapImpl {
88
89
  }
89
90
  }
90
91
  class LatestMapValueManagerImpl {
91
- constructor(key, datastore, value, controlSettings) {
92
+ constructor(key, datastore, value, controlSettings, validator) {
92
93
  this.key = key;
93
94
  this.datastore = datastore;
94
95
  this.value = value;
96
+ this.validator = validator;
95
97
  this.events = (0, client_utils_1.createEmitter)();
96
98
  this.controls = new broadcastControls_js_1.OptionalBroadcastControl(controlSettings);
97
99
  this.local = new ValueMapImpl(value, this.events, (updates) => {
@@ -120,6 +122,7 @@ class LatestMapValueManagerImpl {
120
122
  .map((attendeeId) => this.datastore.presence.attendees.getAttendee(attendeeId));
121
123
  }
122
124
  getRemote(attendee) {
125
+ const validator = this.validator;
123
126
  const allKnownStates = this.datastore.knownValues(this.key);
124
127
  const attendeeId = attendee.attendeeId;
125
128
  const clientStateMap = allKnownStates.states[attendeeId];
@@ -130,7 +133,7 @@ class LatestMapValueManagerImpl {
130
133
  for (const [key, item] of (0, internalUtils_js_1.objectEntries)(clientStateMap.items)) {
131
134
  if ((0, internalUtils_js_1.isValueRequiredState)(item)) {
132
135
  items.set(key, {
133
- value: (0, internalUtils_js_1.asDeeplyReadonlyDeserializedJson)(item.value),
136
+ value: (0, latestValueTypes_js_1.createValidatedGetter)(item, validator),
134
137
  metadata: { revision: item.rev, timestamp: item.timestamp },
135
138
  });
136
139
  }
@@ -178,15 +181,17 @@ class LatestMapValueManagerImpl {
178
181
  timestamp: item.timestamp,
179
182
  };
180
183
  if ((0, internalUtils_js_1.isValueRequiredState)(item)) {
181
- const itemValue = (0, internalUtils_js_1.asDeeplyReadonlyDeserializedJson)(item.value);
182
184
  const updatedItem = {
183
185
  attendee,
184
186
  key,
185
- value: itemValue,
187
+ value: (0, latestValueTypes_js_1.createValidatedGetter)(item, this.validator),
186
188
  metadata,
187
189
  };
188
190
  postUpdateActions.push(() => this.events.emit("remoteItemUpdated", updatedItem));
189
- allUpdates.items.set(key, { value: itemValue, metadata });
191
+ allUpdates.items.set(key, {
192
+ value: updatedItem.value,
193
+ metadata,
194
+ });
190
195
  }
191
196
  else if (hadPriorValue !== undefined) {
192
197
  postUpdateActions.push(() => this.events.emit("remoteItemRemoved", {
@@ -209,9 +214,6 @@ const latestMap = (args) => {
209
214
  const settings = args?.settings;
210
215
  const initialValues = args?.local;
211
216
  const validator = args?.validator;
212
- if (validator !== undefined) {
213
- throw new Error(`Validators are not yet implemented.`);
214
- }
215
217
  const timestamp = Date.now();
216
218
  const value = { rev: 0, items: {} };
217
219
  // LatestMapRaw takes ownership of values within initialValues.
@@ -226,7 +228,7 @@ const latestMap = (args) => {
226
228
  }
227
229
  const factory = (key, datastoreHandle) => ({
228
230
  initialData: { value, allowableUpdateLatencyMs: settings?.allowableUpdateLatencyMs },
229
- manager: (0, valueManager_js_1.brandIVM)(new LatestMapValueManagerImpl(key, (0, stateDatastore_js_1.datastoreFromHandle)(datastoreHandle), value, settings)),
231
+ manager: (0, valueManager_js_1.brandIVM)(new LatestMapValueManagerImpl(key, (0, stateDatastore_js_1.datastoreFromHandle)(datastoreHandle), value, settings, validator)),
230
232
  });
231
233
  return Object.assign(factory, { instanceBase: LatestMapValueManagerImpl });
232
234
  };
@@ -1 +1 @@
1
- {"version":3,"file":"latestMapValueManager.js","sourceRoot":"","sources":["../src/latestMapValueManager.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { createEmitter } from \"@fluid-internal/client-utils\";\nimport type { Listenable } from \"@fluidframework/core-interfaces\";\nimport type { IEmitter } from \"@fluidframework/core-interfaces/internal\";\nimport type {\n\tDeepReadonly,\n\tJsonDeserialized,\n\tJsonSerializable,\n} from \"@fluidframework/core-interfaces/internal/exposedUtilityTypes\";\n\nimport type { BroadcastControls, BroadcastControlSettings } from \"./broadcastControls.js\";\nimport { OptionalBroadcastControl } from \"./broadcastControls.js\";\nimport type { InternalTypes } from \"./exposedInternalTypes.js\";\nimport type {\n\tPostUpdateAction,\n\tValidatableOptionalState,\n\tValueManager,\n} from \"./internalTypes.js\";\nimport {\n\tasDeeplyReadonly,\n\tasDeeplyReadonlyDeserializedJson,\n\tisValueRequiredState,\n\tobjectEntries,\n\tobjectKeys,\n\ttoOpaqueJson,\n} from \"./internalUtils.js\";\nimport type {\n\tLatestClientData,\n\tLatestData,\n\tLatestMetadata,\n\tProxiedValueAccessor,\n\tRawValueAccessor,\n\tStateSchemaValidator,\n\tValueAccessor,\n} from \"./latestValueTypes.js\";\nimport type { AttendeeId, Attendee, Presence, SpecificAttendee } from \"./presence.js\";\nimport { datastoreFromHandle, type StateDatastore } from \"./stateDatastore.js\";\nimport { brandIVM } from \"./valueManager.js\";\n\n/**\n * Collection of validatable optional values in a \"map\" structure.\n *\n * @remarks\n * Validatable equivalent of {@link InternalTypes.MapValueState}.\n */\ninterface ValidatableMapValueState<T, Keys extends string | number> {\n\trev: number;\n\titems: {\n\t\t// Caution: any particular item may or may not exist\n\t\t// Typescript does not support absent keys without forcing type to also be undefined.\n\t\t// See https://github.com/microsoft/TypeScript/issues/42810.\n\t\t[name in Keys]: ValidatableOptionalState<T>;\n\t};\n}\n\n/**\n * Collection of latest known values for a specific {@link Attendee}.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMapClientData<\n\tT,\n\tKeys extends string | number,\n\tTValueAccessor extends ValueAccessor<T>,\n\tSpecificAttendeeId extends AttendeeId = AttendeeId,\n> {\n\t/**\n\t * Associated {@link Attendee}.\n\t */\n\tattendee: Attendee<SpecificAttendeeId>;\n\n\t/**\n\t * Map of items for the state.\n\t *\n\t * @privateRemarks This could be regular map currently as no Map is\n\t * stored internally and a new instance is created for every request.\n\t */\n\titems: ReadonlyMap<Keys, LatestData<T, TValueAccessor>>;\n}\n\n/**\n * State of a single item value, its key, and its metadata.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMapItemUpdatedClientData<\n\tT,\n\tK extends string | number,\n\tTValueAccessor extends ValueAccessor<T>,\n> extends LatestClientData<T, TValueAccessor> {\n\t/**\n\t * Key of the updated item.\n\t */\n\tkey: K;\n}\n\n/**\n * Identifier and metadata for a removed item.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMapItemRemovedClientData<K extends string | number> {\n\t/**\n\t * Associated {@link Attendee}.\n\t */\n\tattendee: Attendee;\n\t/**\n\t * Key of the removed item.\n\t */\n\tkey: K;\n\t/**\n\t * Metadata associated with the removal of the item.\n\t */\n\tmetadata: LatestMetadata;\n}\n\n/**\n * Events from {@link LatestMapRaw}.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMapEvents<\n\tT,\n\tK extends string | number,\n\tTRemoteValueAccessor extends ValueAccessor<T> = ProxiedValueAccessor<T>,\n> {\n\t/**\n\t * Raised when any item's value for remote client is updated.\n\t * @param updates - Map of one or more values updated.\n\t *\n\t * @remarks The event does not include item removals.\n\t *\n\t * @eventProperty\n\t */\n\tremoteUpdated: (updates: LatestMapClientData<T, K, TRemoteValueAccessor>) => void;\n\n\t/**\n\t * Raised when specific item's value of remote client is updated.\n\t * @param updatedItem - Updated item value.\n\t *\n\t * @eventProperty\n\t */\n\tremoteItemUpdated: (\n\t\tupdatedItem: LatestMapItemUpdatedClientData<T, K, TRemoteValueAccessor>,\n\t) => void;\n\n\t/**\n\t * Raised when specific item of remote client is removed.\n\t * @param removedItem - Removed item.\n\t *\n\t * @eventProperty\n\t */\n\tremoteItemRemoved: (removedItem: LatestMapItemRemovedClientData<K>) => void;\n\n\t/**\n\t * Raised when specific local item's value is updated.\n\t * @param updatedItem - Updated item value.\n\t *\n\t * @eventProperty\n\t */\n\tlocalItemUpdated: (updatedItem: {\n\t\tvalue: DeepReadonly<JsonSerializable<T>>;\n\t\tkey: K;\n\t}) => void;\n\n\t/**\n\t * Raised when specific local item is removed.\n\t * @param removedItem - Removed item.\n\t *\n\t * @eventProperty\n\t */\n\tlocalItemRemoved: (removedItem: {\n\t\tkey: K;\n\t}) => void;\n}\n\n/**\n * Events from {@link LatestMapRaw}.\n *\n * @sealed\n * @beta\n */\nexport type LatestMapRawEvents<T, K extends string | number> = LatestMapEvents<\n\tT,\n\tK,\n\tRawValueAccessor<T>\n>;\n\n/**\n * Map of local client's values. Modifications are transmitted to all other connected clients.\n *\n * @sealed\n * @beta\n */\nexport interface StateMap<K extends string | number, V> {\n\t/**\n\t * ${@link StateMap.delete}s all elements in the StateMap.\n\t * @remarks This is not yet implemented.\n\t */\n\tclear(): void;\n\n\t/**\n\t * Removes the element with the specified key from the StateMap, if it exists.\n\t *\n\t * @returns true if an element in the StateMap existed and has been removed, or false if\n\t * the element does not exist.\n\t * @remarks No entry is fully removed. Instead an undefined placeholder is locally and\n\t * transmitted to all other clients. For better performance limit the number of deleted\n\t * entries and reuse keys when possible.\n\t * @privateRemarks In the future we may add a mechanism to remove the placeholder, at least\n\t * from transmissions after sufficient time has passed.\n\t */\n\tdelete(key: K): boolean;\n\n\t/**\n\t * Executes a provided function once per each key/value pair in the StateMap, in arbitrary order.\n\t */\n\tforEach(\n\t\tcallbackfn: (\n\t\t\tvalue: DeepReadonly<JsonDeserialized<V>>,\n\t\t\tkey: K,\n\t\t\tmap: StateMap<K, V>,\n\t\t) => void,\n\t\tthisArg?: unknown,\n\t): void;\n\n\t/**\n\t * Returns the element with the specified key from the StateMap, if it exists.\n\t *\n\t * @returns Returns the element associated with the specified key. If no element is associated with the specified key, undefined is returned.\n\t */\n\tget(key: K): DeepReadonly<JsonDeserialized<V>> | undefined;\n\n\t/**\n\t * Checks if an element with the specified key exists in the StateMap.\n\t * @returns boolean indicating whether an element with the specified key exists or not.\n\t */\n\thas(key: K): boolean;\n\n\t/**\n\t * Adds a new element with a specified key and value to the StateMap. If an element with the same key already exists, the element will be updated.\n\t * The value will be transmitted to all other connected clients.\n\t *\n\t * @remarks Manager assumes ownership of the value and its references.\n\t * Make a deep clone before setting, if needed. No comparison is done to detect changes; all\n\t * sets are transmitted.\n\t */\n\tset(key: K, value: JsonSerializable<V>): this;\n\n\t/**\n\t * The number of elements in the StateMap.\n\t */\n\treadonly size: number;\n\n\t/**\n\t * Returns an iterable of entries in the map.\n\t */\n\t// [Symbol.iterator](): IterableIterator<[K, DeepReadonly<JsonDeserialized<V>>]>;\n\n\t/**\n\t * Returns an iterable of key, value pairs for every entry in the map.\n\t */\n\t// entries(): IterableIterator<[K, DeepReadonly<JsonDeserialized<V>>]>;\n\n\t/**\n\t * Returns an iterable of keys in the map.\n\t */\n\tkeys(): IterableIterator<K>;\n\n\t/**\n\t * Returns an iterable of values in the map.\n\t */\n\t// values(): IterableIterator<DeepReadonly<JsonDeserialized<V>>>;\n}\n\nclass ValueMapImpl<T, K extends string | number> implements StateMap<K, T> {\n\tprivate countDefined: number;\n\tpublic constructor(\n\t\tprivate readonly value: InternalTypes.MapValueState<T, K>,\n\t\tprivate readonly emitter: IEmitter<\n\t\t\tPick<LatestMapEvents<T, K, ValueAccessor<T>>, \"localItemUpdated\" | \"localItemRemoved\">\n\t\t>,\n\t\tprivate readonly localUpdate: (\n\t\t\tupdates: InternalTypes.MapValueState<\n\t\t\t\tT,\n\t\t\t\t// This should be `K`, but will only work if properties are optional.\n\t\t\t\tstring | number\n\t\t\t>,\n\t\t) => void,\n\t) {\n\t\t// All initial items are expected to be defined.\n\t\t// TODO assert all defined and/or update type.\n\t\tthis.countDefined = Object.keys(value.items).length;\n\t}\n\n\t/**\n\t * Note: caller must ensure key exists in this.value.items.\n\t */\n\tprivate updateItem(key: K, value: InternalTypes.ValueOptionalState<T>[\"value\"]): void {\n\t\tthis.value.rev += 1;\n\t\t// Caller is required to ensure key exists.\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\tconst item = this.value.items[key]!;\n\t\titem.rev += 1;\n\t\titem.timestamp = Date.now();\n\t\tif (value === undefined) {\n\t\t\tdelete item.value;\n\t\t} else {\n\t\t\titem.value = value;\n\t\t}\n\t\tconst update = { rev: this.value.rev, items: { [key]: item } };\n\t\tthis.localUpdate(update);\n\t}\n\n\tpublic clear(): void {\n\t\tthrow new Error(\"Method not implemented.\");\n\t}\n\tpublic delete(key: K): boolean {\n\t\tconst { items } = this.value;\n\t\tconst hasKey = items[key]?.value !== undefined;\n\t\tif (hasKey) {\n\t\t\tthis.countDefined -= 1;\n\t\t\tthis.updateItem(key, undefined);\n\t\t\tthis.emitter.emit(\"localItemRemoved\", { key });\n\t\t}\n\t\treturn hasKey;\n\t}\n\tpublic forEach(\n\t\tcallbackfn: (\n\t\t\tvalue: DeepReadonly<JsonDeserialized<T>>,\n\t\t\tkey: K,\n\t\t\tmap: StateMap<K, T>,\n\t\t) => void,\n\t\tthisArg?: unknown,\n\t): void {\n\t\tfor (const [key, item] of objectEntries(this.value.items)) {\n\t\t\tif (item.value !== undefined) {\n\t\t\t\tcallbackfn(asDeeplyReadonlyDeserializedJson(item.value), key, this);\n\t\t\t}\n\t\t}\n\t}\n\tpublic get(key: K): DeepReadonly<JsonDeserialized<T>> | undefined {\n\t\treturn asDeeplyReadonlyDeserializedJson(this.value.items[key]?.value);\n\t}\n\tpublic has(key: K): boolean {\n\t\treturn this.value.items[key]?.value !== undefined;\n\t}\n\tpublic set(key: K, inValue: JsonSerializable<T>): this {\n\t\tconst value = toOpaqueJson<T>(inValue);\n\t\tif (!(key in this.value.items)) {\n\t\t\tthis.countDefined += 1;\n\t\t\tthis.value.items[key] = { rev: 0, timestamp: 0, value };\n\t\t}\n\t\tthis.updateItem(key, value);\n\t\tthis.emitter.emit(\"localItemUpdated\", { key, value: asDeeplyReadonly(inValue) });\n\t\treturn this;\n\t}\n\tpublic get size(): number {\n\t\treturn this.countDefined;\n\t}\n\tpublic keys(): IterableIterator<K> {\n\t\tconst keys: K[] = [];\n\t\tfor (const [key, item] of objectEntries(this.value.items)) {\n\t\t\tif (item.value !== undefined) {\n\t\t\t\tkeys.push(key);\n\t\t\t}\n\t\t}\n\t\treturn keys[Symbol.iterator]();\n\t}\n}\n\n/**\n * State that provides a `Map` of latest known values from this client to\n * others and read access to their values.\n * Entries in the map may vary over time and by client, but all values are expected to\n * be of the same type, which may be a union type.\n *\n * @remarks Create using {@link StateFactory.latestMap} registered to {@link StatesWorkspace}.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMap<\n\tT,\n\tKeys extends string | number = string | number,\n\tTRemoteAccessor extends ValueAccessor<T> = ProxiedValueAccessor<T>,\n> {\n\t/**\n\t * Containing {@link Presence}\n\t */\n\treadonly presence: Presence;\n\n\t/**\n\t * Events for LatestMap.\n\t */\n\treadonly events: Listenable<LatestMapEvents<T, Keys, TRemoteAccessor>>;\n\n\t/**\n\t * Controls for management of sending updates.\n\t */\n\treadonly controls: BroadcastControls;\n\n\t/**\n\t * Current value map for this client.\n\t */\n\treadonly local: StateMap<Keys, T>;\n\t/**\n\t * Iterable access to remote clients' map of values.\n\t */\n\tgetRemotes(): IterableIterator<LatestMapClientData<T, Keys, TRemoteAccessor>>;\n\t/**\n\t * Array of {@link Attendee}s that have provided states.\n\t */\n\tgetStateAttendees(): Attendee[];\n\t/**\n\t * Access to a specific client's map of values.\n\t */\n\tgetRemote(attendee: Attendee): ReadonlyMap<Keys, LatestData<T, TRemoteAccessor>>;\n}\n\n/**\n * State that provides a `Map` of latest known values from this client to\n * others and read access to their values.\n * Entries in the map may vary over time and by client, but all values are expected to\n * be of the same type, which may be a union type.\n *\n * @remarks Create using {@link StateFactory.latestMap} registered to {@link StatesWorkspace}.\n *\n * @sealed\n * @beta\n */\nexport type LatestMapRaw<T, Keys extends string | number = string | number> = LatestMap<\n\tT,\n\tKeys,\n\tRawValueAccessor<T>\n>;\n\nclass LatestMapValueManagerImpl<\n\tT,\n\tRegistrationKey extends string,\n\tKeys extends string | number = string | number,\n> implements\n\t\tLatestMapRaw<T, Keys>,\n\t\tLatestMap<T, Keys>,\n\t\tRequired<ValueManager<T, InternalTypes.MapValueState<T, Keys>>>\n{\n\tpublic readonly events = createEmitter<LatestMapEvents<T, Keys, RawValueAccessor<T>>>();\n\tpublic readonly controls: OptionalBroadcastControl;\n\n\tpublic constructor(\n\t\tprivate readonly key: RegistrationKey,\n\t\tprivate readonly datastore: StateDatastore<\n\t\t\tRegistrationKey,\n\t\t\tInternalTypes.MapValueState<T, Keys>,\n\t\t\tValidatableMapValueState<T, Keys>\n\t\t>,\n\t\tpublic readonly value: InternalTypes.MapValueState<T, Keys>,\n\t\tcontrolSettings: BroadcastControlSettings | undefined,\n\t) {\n\t\tthis.controls = new OptionalBroadcastControl(controlSettings);\n\n\t\tthis.local = new ValueMapImpl<T, Keys>(\n\t\t\tvalue,\n\t\t\tthis.events,\n\t\t\t(updates: InternalTypes.MapValueState<T, Keys>) => {\n\t\t\t\tdatastore.localUpdate(key, updates, {\n\t\t\t\t\tallowableUpdateLatencyMs: this.controls.allowableUpdateLatencyMs,\n\t\t\t\t});\n\t\t\t},\n\t\t);\n\t}\n\n\tpublic get presence(): Presence {\n\t\treturn this.datastore.presence;\n\t}\n\n\tpublic readonly local: StateMap<Keys, T>;\n\n\tpublic *getRemotes(): IterableIterator<LatestMapClientData<T, Keys, ValueAccessor<T>>> {\n\t\tconst allKnownStates = this.datastore.knownValues(this.key);\n\t\tfor (const attendeeId of objectKeys(allKnownStates.states)) {\n\t\t\tif (attendeeId !== allKnownStates.self) {\n\t\t\t\tconst attendee = this.datastore.presence.attendees.getAttendee(attendeeId);\n\t\t\t\tconst items = this.getRemote(attendee);\n\t\t\t\tyield { attendee, items };\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic getStateAttendees(): Attendee[] {\n\t\tconst allKnownStates = this.datastore.knownValues(this.key);\n\t\treturn objectKeys(allKnownStates.states)\n\t\t\t.filter((attendeeId) => attendeeId !== allKnownStates.self)\n\t\t\t.map((attendeeId) => this.datastore.presence.attendees.getAttendee(attendeeId));\n\t}\n\n\tpublic getRemote(attendee: Attendee): ReadonlyMap<Keys, LatestData<T, ValueAccessor<T>>> {\n\t\tconst allKnownStates = this.datastore.knownValues(this.key);\n\t\tconst attendeeId = attendee.attendeeId;\n\t\tconst clientStateMap = allKnownStates.states[attendeeId];\n\t\tif (clientStateMap === undefined) {\n\t\t\tthrow new Error(\"No entry for attendee\");\n\t\t}\n\t\tconst items = new Map<Keys, LatestData<T, ValueAccessor<T>>>();\n\t\tfor (const [key, item] of objectEntries(clientStateMap.items)) {\n\t\t\tif (isValueRequiredState(item)) {\n\t\t\t\titems.set(key, {\n\t\t\t\t\tvalue: asDeeplyReadonlyDeserializedJson(item.value),\n\t\t\t\t\tmetadata: { revision: item.rev, timestamp: item.timestamp },\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn items;\n\t}\n\n\tpublic update<SpecificAttendeeId extends AttendeeId>(\n\t\tattendee: SpecificAttendee<SpecificAttendeeId>,\n\t\t_received: number,\n\t\tvalue: InternalTypes.MapValueState<T, string | number>,\n\t): PostUpdateAction[] {\n\t\tconst allKnownStates = this.datastore.knownValues(this.key);\n\t\tconst attendeeId: SpecificAttendeeId = attendee.attendeeId;\n\t\tconst currentState = (allKnownStates.states[attendeeId] ??=\n\t\t\t// New attendee - prepare new attendee state directory\n\t\t\t{\n\t\t\t\trev: value.rev,\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- items entries can't be optional per https://github.com/microsoft/TypeScript/issues/42810; so forced cast\n\t\t\t\titems: {} as ValidatableMapValueState<T, Keys>[\"items\"],\n\t\t\t});\n\t\t// Accumulate individual update keys\n\t\tconst updatedItemKeys: Keys[] = [];\n\t\tfor (const [key, item] of objectEntries(value.items)) {\n\t\t\t// TODO: Key validation needs to be added here.\n\t\t\tconst validKey = key as Keys;\n\t\t\tif (!(key in currentState.items) || currentState.items[validKey].rev < item.rev) {\n\t\t\t\tupdatedItemKeys.push(validKey);\n\t\t\t}\n\t\t}\n\n\t\tif (updatedItemKeys.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\t// Store updates\n\t\tif (value.rev > currentState.rev) {\n\t\t\tcurrentState.rev = value.rev;\n\t\t}\n\t\tconst allUpdates = {\n\t\t\tattendee,\n\t\t\titems: new Map<Keys, LatestData<T, ValueAccessor<T>>>(),\n\t\t};\n\t\tconst postUpdateActions: PostUpdateAction[] = [];\n\t\tfor (const key of updatedItemKeys) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tconst item = value.items[key]!;\n\t\t\tconst hadPriorValue = currentState.items[key]?.value;\n\t\t\tcurrentState.items[key] = item;\n\t\t\tconst metadata = {\n\t\t\t\trevision: item.rev,\n\t\t\t\ttimestamp: item.timestamp,\n\t\t\t};\n\t\t\tif (isValueRequiredState(item)) {\n\t\t\t\tconst itemValue = asDeeplyReadonlyDeserializedJson(item.value);\n\t\t\t\tconst updatedItem = {\n\t\t\t\t\tattendee,\n\t\t\t\t\tkey,\n\t\t\t\t\tvalue: itemValue,\n\t\t\t\t\tmetadata,\n\t\t\t\t} satisfies LatestMapItemUpdatedClientData<T, Keys, RawValueAccessor<T>>;\n\t\t\t\tpostUpdateActions.push(() => this.events.emit(\"remoteItemUpdated\", updatedItem));\n\t\t\t\tallUpdates.items.set(key, { value: itemValue, metadata });\n\t\t\t} else if (hadPriorValue !== undefined) {\n\t\t\t\tpostUpdateActions.push(() =>\n\t\t\t\t\tthis.events.emit(\"remoteItemRemoved\", {\n\t\t\t\t\t\tattendee,\n\t\t\t\t\t\tkey,\n\t\t\t\t\t\tmetadata,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tthis.datastore.update(this.key, attendeeId, currentState);\n\t\tpostUpdateActions.push(() => this.events.emit(\"remoteUpdated\", allUpdates));\n\t\treturn postUpdateActions;\n\t}\n}\n\n/**\n * Arguments that are passed to the {@link StateFactory.latestMap} function.\n *\n * @input\n * @beta\n */\nexport interface LatestMapArgumentsRaw<T, Keys extends string | number = string | number> {\n\t/**\n\t * The initial value of the local state.\n\t */\n\tlocal?: {\n\t\t[K in Keys]: JsonSerializable<T>;\n\t};\n\n\t/**\n\t * See {@link BroadcastControlSettings}.\n\t */\n\tsettings?: BroadcastControlSettings | undefined;\n}\n\n/**\n * Arguments that are passed to the {@link StateFactory.latestMap} function.\n *\n * @input\n * @beta\n */\nexport interface LatestMapArguments<T, Keys extends string | number = string | number>\n\textends LatestMapArgumentsRaw<T, Keys> {\n\t/**\n\t * An optional function that will be called at runtime to validate the presence data. A runtime validator is strongly\n\t * recommended. See {@link StateSchemaValidator}.\n\t */\n\tvalidator: StateSchemaValidator<T>;\n}\n\n// #region factory function overloads\n// Overloads should be ordered from most specific to least specific when combined.\n\n/**\n * Factory for creating a {@link LatestMapRaw} State object.\n *\n * @beta\n * @sealed\n */\nexport interface LatestMapFactory {\n\t/**\n\t * Factory for creating a {@link LatestMapRaw} State object.\n\t *\n\t * @privateRemarks (change to `remarks` when adding signature overload)\n\t * This overload is used when called with {@link LatestMapArgumentsRaw}.\n\t * That is, if a validator function is _not_ provided.\n\t */\n\t// eslint-disable-next-line @typescript-eslint/prefer-function-type -- interface to allow for clean overload evolution\n\t<T, Keys extends string | number = string | number, RegistrationKey extends string = string>(\n\t\targs?: LatestMapArgumentsRaw<T, Keys>,\n\t): InternalTypes.ManagerFactory<\n\t\tRegistrationKey,\n\t\tInternalTypes.MapValueState<T, Keys>,\n\t\tLatestMapRaw<T, Keys>\n\t>;\n}\n\n/**\n * Factory for creating a {@link LatestMap} or {@link LatestMapRaw} State object.\n */\nexport interface LatestMapFactoryInternal extends LatestMapFactory {\n\t/**\n\t * Factory for creating a {@link LatestMap} State object.\n\t *\n\t * @remarks\n\t * This overload is used when called with {@link LatestMapArguments}. That is, if a validator function is provided.\n\t */\n\t<T, Keys extends string | number = string | number, RegistrationKey extends string = string>(\n\t\targs: LatestMapArguments<T, Keys>,\n\t): InternalTypes.ManagerFactory<\n\t\tRegistrationKey,\n\t\tInternalTypes.MapValueState<T, Keys>,\n\t\tLatestMap<T, Keys>\n\t>;\n}\n\n// #endregion\n\n/**\n * Factory for creating a {@link LatestMap} or {@link LatestMapRaw} State object.\n */\nexport const latestMap: LatestMapFactoryInternal = <\n\tT,\n\tKeys extends string | number = string | number,\n\tRegistrationKey extends string = string,\n>(\n\targs?: Partial<LatestMapArguments<T, Keys>>,\n): InternalTypes.ManagerFactory<\n\tRegistrationKey,\n\tInternalTypes.MapValueState<T, Keys>,\n\tLatestMapRaw<T, Keys> & LatestMap<T, Keys>\n> => {\n\tconst settings = args?.settings;\n\tconst initialValues = args?.local;\n\tconst validator = args?.validator;\n\n\tif (validator !== undefined) {\n\t\tthrow new Error(`Validators are not yet implemented.`);\n\t}\n\n\tconst timestamp = Date.now();\n\tconst value: InternalTypes.MapValueState<\n\t\tT,\n\t\t// This should be `Keys`, but will only work if properties are optional.\n\t\tstring | number\n\t> = { rev: 0, items: {} };\n\t// LatestMapRaw takes ownership of values within initialValues.\n\tif (initialValues !== undefined) {\n\t\tfor (const key of objectKeys(initialValues)) {\n\t\t\tvalue.items[key] = {\n\t\t\t\trev: 0,\n\t\t\t\ttimestamp,\n\t\t\t\tvalue: toOpaqueJson(initialValues[key]),\n\t\t\t};\n\t\t}\n\t}\n\tconst factory = (\n\t\tkey: RegistrationKey,\n\t\tdatastoreHandle: InternalTypes.StateDatastoreHandle<\n\t\t\tRegistrationKey,\n\t\t\tInternalTypes.MapValueState<T, Keys>\n\t\t>,\n\t): {\n\t\tinitialData: { value: typeof value; allowableUpdateLatencyMs: number | undefined };\n\t\tmanager: InternalTypes.StateValue<LatestMapRaw<T, Keys> & LatestMap<T, Keys>>;\n\t} => ({\n\t\tinitialData: { value, allowableUpdateLatencyMs: settings?.allowableUpdateLatencyMs },\n\t\tmanager: brandIVM<\n\t\t\tLatestMapValueManagerImpl<T, RegistrationKey, Keys>,\n\t\t\tT,\n\t\t\tInternalTypes.MapValueState<T, Keys>\n\t\t>(\n\t\t\tnew LatestMapValueManagerImpl(\n\t\t\t\tkey,\n\t\t\t\tdatastoreFromHandle(datastoreHandle),\n\t\t\t\tvalue,\n\t\t\t\tsettings,\n\t\t\t),\n\t\t),\n\t});\n\treturn Object.assign(factory, { instanceBase: LatestMapValueManagerImpl });\n};\n"]}
1
+ {"version":3,"file":"latestMapValueManager.js","sourceRoot":"","sources":["../src/latestMapValueManager.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { createEmitter } from \"@fluid-internal/client-utils\";\nimport type { Listenable } from \"@fluidframework/core-interfaces\";\nimport type { IEmitter } from \"@fluidframework/core-interfaces/internal\";\nimport type {\n\tDeepReadonly,\n\tJsonDeserialized,\n\tJsonSerializable,\n} from \"@fluidframework/core-interfaces/internal/exposedUtilityTypes\";\n\nimport type { BroadcastControls, BroadcastControlSettings } from \"./broadcastControls.js\";\nimport { OptionalBroadcastControl } from \"./broadcastControls.js\";\nimport type { InternalTypes } from \"./exposedInternalTypes.js\";\nimport type {\n\tPostUpdateAction,\n\tValidatableOptionalState,\n\tValueManager,\n} from \"./internalTypes.js\";\nimport {\n\tasDeeplyReadonly,\n\tasDeeplyReadonlyDeserializedJson,\n\tisValueRequiredState,\n\tobjectEntries,\n\tobjectKeys,\n\ttoOpaqueJson,\n} from \"./internalUtils.js\";\nimport { createValidatedGetter } from \"./latestValueTypes.js\";\nimport type {\n\tLatestClientData,\n\tLatestData,\n\tLatestMetadata,\n\tProxiedValueAccessor,\n\tRawValueAccessor,\n\tStateSchemaValidator,\n\tValueAccessor,\n} from \"./latestValueTypes.js\";\nimport type { AttendeeId, Attendee, Presence, SpecificAttendee } from \"./presence.js\";\nimport { datastoreFromHandle, type StateDatastore } from \"./stateDatastore.js\";\nimport { brandIVM } from \"./valueManager.js\";\n\n/**\n * Collection of validatable optional values in a \"map\" structure.\n *\n * @remarks\n * Validatable equivalent of {@link InternalTypes.MapValueState}.\n */\ninterface ValidatableMapValueState<T, Keys extends string | number> {\n\trev: number;\n\titems: {\n\t\t// Caution: any particular item may or may not exist\n\t\t// Typescript does not support absent keys without forcing type to also be undefined.\n\t\t// See https://github.com/microsoft/TypeScript/issues/42810.\n\t\t[name in Keys]: ValidatableOptionalState<T>;\n\t};\n}\n\n/**\n * Collection of latest known values for a specific {@link Attendee}.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMapClientData<\n\tT,\n\tKeys extends string | number,\n\tTValueAccessor extends ValueAccessor<T>,\n\tSpecificAttendeeId extends AttendeeId = AttendeeId,\n> {\n\t/**\n\t * Associated {@link Attendee}.\n\t */\n\tattendee: Attendee<SpecificAttendeeId>;\n\n\t/**\n\t * Map of items for the state.\n\t *\n\t * @privateRemarks This could be regular map currently as no Map is\n\t * stored internally and a new instance is created for every request.\n\t */\n\titems: ReadonlyMap<Keys, LatestData<T, TValueAccessor>>;\n}\n\n/**\n * State of a single item value, its key, and its metadata.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMapItemUpdatedClientData<\n\tT,\n\tK extends string | number,\n\tTValueAccessor extends ValueAccessor<T>,\n> extends LatestClientData<T, TValueAccessor> {\n\t/**\n\t * Key of the updated item.\n\t */\n\tkey: K;\n}\n\n/**\n * Identifier and metadata for a removed item.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMapItemRemovedClientData<K extends string | number> {\n\t/**\n\t * Associated {@link Attendee}.\n\t */\n\tattendee: Attendee;\n\t/**\n\t * Key of the removed item.\n\t */\n\tkey: K;\n\t/**\n\t * Metadata associated with the removal of the item.\n\t */\n\tmetadata: LatestMetadata;\n}\n\n/**\n * Events from {@link LatestMapRaw}.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMapEvents<\n\tT,\n\tK extends string | number,\n\tTRemoteValueAccessor extends ValueAccessor<T> = ProxiedValueAccessor<T>,\n> {\n\t/**\n\t * Raised when any item's value for remote client is updated.\n\t * @param updates - Map of one or more values updated.\n\t *\n\t * @remarks The event does not include item removals.\n\t *\n\t * @eventProperty\n\t */\n\tremoteUpdated: (updates: LatestMapClientData<T, K, TRemoteValueAccessor>) => void;\n\n\t/**\n\t * Raised when specific item's value of remote client is updated.\n\t * @param updatedItem - Updated item value.\n\t *\n\t * @eventProperty\n\t */\n\tremoteItemUpdated: (\n\t\tupdatedItem: LatestMapItemUpdatedClientData<T, K, TRemoteValueAccessor>,\n\t) => void;\n\n\t/**\n\t * Raised when specific item of remote client is removed.\n\t * @param removedItem - Removed item.\n\t *\n\t * @eventProperty\n\t */\n\tremoteItemRemoved: (removedItem: LatestMapItemRemovedClientData<K>) => void;\n\n\t/**\n\t * Raised when specific local item's value is updated.\n\t * @param updatedItem - Updated item value.\n\t *\n\t * @eventProperty\n\t */\n\tlocalItemUpdated: (updatedItem: {\n\t\tvalue: DeepReadonly<JsonSerializable<T>>;\n\t\tkey: K;\n\t}) => void;\n\n\t/**\n\t * Raised when specific local item is removed.\n\t * @param removedItem - Removed item.\n\t *\n\t * @eventProperty\n\t */\n\tlocalItemRemoved: (removedItem: {\n\t\tkey: K;\n\t}) => void;\n}\n\n/**\n * Events from {@link LatestMapRaw}.\n *\n * @sealed\n * @beta\n */\nexport type LatestMapRawEvents<T, K extends string | number> = LatestMapEvents<\n\tT,\n\tK,\n\tRawValueAccessor<T>\n>;\n\n/**\n * Map of local client's values. Modifications are transmitted to all other connected clients.\n *\n * @sealed\n * @beta\n */\nexport interface StateMap<K extends string | number, V> {\n\t/**\n\t * ${@link StateMap.delete}s all elements in the StateMap.\n\t * @remarks This is not yet implemented.\n\t */\n\tclear(): void;\n\n\t/**\n\t * Removes the element with the specified key from the StateMap, if it exists.\n\t *\n\t * @returns true if an element in the StateMap existed and has been removed, or false if\n\t * the element does not exist.\n\t * @remarks No entry is fully removed. Instead an undefined placeholder is locally and\n\t * transmitted to all other clients. For better performance limit the number of deleted\n\t * entries and reuse keys when possible.\n\t * @privateRemarks In the future we may add a mechanism to remove the placeholder, at least\n\t * from transmissions after sufficient time has passed.\n\t */\n\tdelete(key: K): boolean;\n\n\t/**\n\t * Executes a provided function once per each key/value pair in the StateMap, in arbitrary order.\n\t */\n\tforEach(\n\t\tcallbackfn: (\n\t\t\tvalue: DeepReadonly<JsonDeserialized<V>>,\n\t\t\tkey: K,\n\t\t\tmap: StateMap<K, V>,\n\t\t) => void,\n\t\tthisArg?: unknown,\n\t): void;\n\n\t/**\n\t * Returns the element with the specified key from the StateMap, if it exists.\n\t *\n\t * @returns Returns the element associated with the specified key. If no element is associated with the specified key, undefined is returned.\n\t */\n\tget(key: K): DeepReadonly<JsonDeserialized<V>> | undefined;\n\n\t/**\n\t * Checks if an element with the specified key exists in the StateMap.\n\t * @returns boolean indicating whether an element with the specified key exists or not.\n\t */\n\thas(key: K): boolean;\n\n\t/**\n\t * Adds a new element with a specified key and value to the StateMap. If an element with the same key already exists, the element will be updated.\n\t * The value will be transmitted to all other connected clients.\n\t *\n\t * @remarks Manager assumes ownership of the value and its references.\n\t * Make a deep clone before setting, if needed. No comparison is done to detect changes; all\n\t * sets are transmitted.\n\t */\n\tset(key: K, value: JsonSerializable<V>): this;\n\n\t/**\n\t * The number of elements in the StateMap.\n\t */\n\treadonly size: number;\n\n\t/**\n\t * Returns an iterable of entries in the map.\n\t */\n\t// [Symbol.iterator](): IterableIterator<[K, DeepReadonly<JsonDeserialized<V>>]>;\n\n\t/**\n\t * Returns an iterable of key, value pairs for every entry in the map.\n\t */\n\t// entries(): IterableIterator<[K, DeepReadonly<JsonDeserialized<V>>]>;\n\n\t/**\n\t * Returns an iterable of keys in the map.\n\t */\n\tkeys(): IterableIterator<K>;\n\n\t/**\n\t * Returns an iterable of values in the map.\n\t */\n\t// values(): IterableIterator<DeepReadonly<JsonDeserialized<V>>>;\n}\n\nclass ValueMapImpl<T, K extends string | number> implements StateMap<K, T> {\n\tprivate countDefined: number;\n\tpublic constructor(\n\t\tprivate readonly value: InternalTypes.MapValueState<T, K>,\n\t\tprivate readonly emitter: IEmitter<\n\t\t\tPick<LatestMapEvents<T, K, ValueAccessor<T>>, \"localItemUpdated\" | \"localItemRemoved\">\n\t\t>,\n\t\tprivate readonly localUpdate: (\n\t\t\tupdates: InternalTypes.MapValueState<\n\t\t\t\tT,\n\t\t\t\t// This should be `K`, but will only work if properties are optional.\n\t\t\t\tstring | number\n\t\t\t>,\n\t\t) => void,\n\t) {\n\t\t// All initial items are expected to be defined.\n\t\t// TODO assert all defined and/or update type.\n\t\tthis.countDefined = Object.keys(value.items).length;\n\t}\n\n\t/**\n\t * Note: caller must ensure key exists in this.value.items.\n\t */\n\tprivate updateItem(key: K, value: InternalTypes.ValueOptionalState<T>[\"value\"]): void {\n\t\tthis.value.rev += 1;\n\t\t// Caller is required to ensure key exists.\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\tconst item = this.value.items[key]!;\n\t\titem.rev += 1;\n\t\titem.timestamp = Date.now();\n\t\tif (value === undefined) {\n\t\t\tdelete item.value;\n\t\t} else {\n\t\t\titem.value = value;\n\t\t}\n\t\tconst update = { rev: this.value.rev, items: { [key]: item } };\n\t\tthis.localUpdate(update);\n\t}\n\n\tpublic clear(): void {\n\t\tthrow new Error(\"Method not implemented.\");\n\t}\n\tpublic delete(key: K): boolean {\n\t\tconst { items } = this.value;\n\t\tconst hasKey = items[key]?.value !== undefined;\n\t\tif (hasKey) {\n\t\t\tthis.countDefined -= 1;\n\t\t\tthis.updateItem(key, undefined);\n\t\t\tthis.emitter.emit(\"localItemRemoved\", { key });\n\t\t}\n\t\treturn hasKey;\n\t}\n\tpublic forEach(\n\t\tcallbackfn: (\n\t\t\tvalue: DeepReadonly<JsonDeserialized<T>>,\n\t\t\tkey: K,\n\t\t\tmap: StateMap<K, T>,\n\t\t) => void,\n\t\tthisArg?: unknown,\n\t): void {\n\t\tfor (const [key, item] of objectEntries(this.value.items)) {\n\t\t\tif (item.value !== undefined) {\n\t\t\t\tcallbackfn(asDeeplyReadonlyDeserializedJson(item.value), key, this);\n\t\t\t}\n\t\t}\n\t}\n\tpublic get(key: K): DeepReadonly<JsonDeserialized<T>> | undefined {\n\t\treturn asDeeplyReadonlyDeserializedJson(this.value.items[key]?.value);\n\t}\n\tpublic has(key: K): boolean {\n\t\treturn this.value.items[key]?.value !== undefined;\n\t}\n\tpublic set(key: K, inValue: JsonSerializable<T>): this {\n\t\tconst value = toOpaqueJson<T>(inValue);\n\t\tif (!(key in this.value.items)) {\n\t\t\tthis.countDefined += 1;\n\t\t\tthis.value.items[key] = { rev: 0, timestamp: 0, value };\n\t\t}\n\t\tthis.updateItem(key, value);\n\t\tthis.emitter.emit(\"localItemUpdated\", { key, value: asDeeplyReadonly(inValue) });\n\t\treturn this;\n\t}\n\tpublic get size(): number {\n\t\treturn this.countDefined;\n\t}\n\tpublic keys(): IterableIterator<K> {\n\t\tconst keys: K[] = [];\n\t\tfor (const [key, item] of objectEntries(this.value.items)) {\n\t\t\tif (item.value !== undefined) {\n\t\t\t\tkeys.push(key);\n\t\t\t}\n\t\t}\n\t\treturn keys[Symbol.iterator]();\n\t}\n}\n\n/**\n * State that provides a `Map` of latest known values from this client to\n * others and read access to their values.\n * Entries in the map may vary over time and by client, but all values are expected to\n * be of the same type, which may be a union type.\n *\n * @remarks Create using {@link StateFactory.latestMap} registered to {@link StatesWorkspace}.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMap<\n\tT,\n\tKeys extends string | number = string | number,\n\tTRemoteAccessor extends ValueAccessor<T> = ProxiedValueAccessor<T>,\n> {\n\t/**\n\t * Containing {@link Presence}\n\t */\n\treadonly presence: Presence;\n\n\t/**\n\t * Events for LatestMap.\n\t */\n\treadonly events: Listenable<LatestMapEvents<T, Keys, TRemoteAccessor>>;\n\n\t/**\n\t * Controls for management of sending updates.\n\t */\n\treadonly controls: BroadcastControls;\n\n\t/**\n\t * Current value map for this client.\n\t */\n\treadonly local: StateMap<Keys, T>;\n\t/**\n\t * Iterable access to remote clients' map of values.\n\t */\n\tgetRemotes(): IterableIterator<LatestMapClientData<T, Keys, TRemoteAccessor>>;\n\t/**\n\t * Array of {@link Attendee}s that have provided states.\n\t */\n\tgetStateAttendees(): Attendee[];\n\t/**\n\t * Access to a specific client's map of values.\n\t */\n\tgetRemote(attendee: Attendee): ReadonlyMap<Keys, LatestData<T, TRemoteAccessor>>;\n}\n\n/**\n * State that provides a `Map` of latest known values from this client to\n * others and read access to their values.\n * Entries in the map may vary over time and by client, but all values are expected to\n * be of the same type, which may be a union type.\n *\n * @remarks Create using {@link StateFactory.latestMap} registered to {@link StatesWorkspace}.\n *\n * @sealed\n * @beta\n */\nexport type LatestMapRaw<T, Keys extends string | number = string | number> = LatestMap<\n\tT,\n\tKeys,\n\tRawValueAccessor<T>\n>;\n\nclass LatestMapValueManagerImpl<\n\tT,\n\tRegistrationKey extends string,\n\tKeys extends string | number = string | number,\n> implements\n\t\tLatestMapRaw<T, Keys>,\n\t\tLatestMap<T, Keys>,\n\t\tRequired<ValueManager<T, InternalTypes.MapValueState<T, Keys>>>\n{\n\tpublic readonly events = createEmitter<LatestMapEvents<T, Keys, ValueAccessor<T>>>();\n\tpublic readonly controls: OptionalBroadcastControl;\n\n\tpublic constructor(\n\t\tprivate readonly key: RegistrationKey,\n\t\tprivate readonly datastore: StateDatastore<\n\t\t\tRegistrationKey,\n\t\t\tInternalTypes.MapValueState<T, Keys>,\n\t\t\tValidatableMapValueState<T, Keys>\n\t\t>,\n\t\tpublic readonly value: InternalTypes.MapValueState<T, Keys>,\n\t\tcontrolSettings: BroadcastControlSettings | undefined,\n\t\tprivate readonly validator: StateSchemaValidator<T> | undefined,\n\t) {\n\t\tthis.controls = new OptionalBroadcastControl(controlSettings);\n\n\t\tthis.local = new ValueMapImpl<T, Keys>(\n\t\t\tvalue,\n\t\t\tthis.events,\n\t\t\t(updates: InternalTypes.MapValueState<T, Keys>) => {\n\t\t\t\tdatastore.localUpdate(key, updates, {\n\t\t\t\t\tallowableUpdateLatencyMs: this.controls.allowableUpdateLatencyMs,\n\t\t\t\t});\n\t\t\t},\n\t\t);\n\t}\n\n\tpublic get presence(): Presence {\n\t\treturn this.datastore.presence;\n\t}\n\n\tpublic readonly local: StateMap<Keys, T>;\n\n\tpublic *getRemotes(): IterableIterator<LatestMapClientData<T, Keys, ValueAccessor<T>>> {\n\t\tconst allKnownStates = this.datastore.knownValues(this.key);\n\t\tfor (const attendeeId of objectKeys(allKnownStates.states)) {\n\t\t\tif (attendeeId !== allKnownStates.self) {\n\t\t\t\tconst attendee = this.datastore.presence.attendees.getAttendee(attendeeId);\n\t\t\t\tconst items = this.getRemote(attendee);\n\t\t\t\tyield { attendee, items };\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic getStateAttendees(): Attendee[] {\n\t\tconst allKnownStates = this.datastore.knownValues(this.key);\n\t\treturn objectKeys(allKnownStates.states)\n\t\t\t.filter((attendeeId) => attendeeId !== allKnownStates.self)\n\t\t\t.map((attendeeId) => this.datastore.presence.attendees.getAttendee(attendeeId));\n\t}\n\n\tpublic getRemote(attendee: Attendee): ReadonlyMap<Keys, LatestData<T, ValueAccessor<T>>> {\n\t\tconst validator = this.validator;\n\t\tconst allKnownStates = this.datastore.knownValues(this.key);\n\t\tconst attendeeId = attendee.attendeeId;\n\t\tconst clientStateMap = allKnownStates.states[attendeeId];\n\t\tif (clientStateMap === undefined) {\n\t\t\tthrow new Error(\"No entry for attendee\");\n\t\t}\n\t\tconst items = new Map<Keys, LatestData<T, ValueAccessor<T>>>();\n\t\tfor (const [key, item] of objectEntries(clientStateMap.items)) {\n\t\t\tif (isValueRequiredState(item)) {\n\t\t\t\titems.set(key, {\n\t\t\t\t\tvalue: createValidatedGetter(item, validator),\n\t\t\t\t\tmetadata: { revision: item.rev, timestamp: item.timestamp },\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn items;\n\t}\n\n\tpublic update<SpecificAttendeeId extends AttendeeId>(\n\t\tattendee: SpecificAttendee<SpecificAttendeeId>,\n\t\t_received: number,\n\t\tvalue: InternalTypes.MapValueState<T, string | number>,\n\t): PostUpdateAction[] {\n\t\tconst allKnownStates = this.datastore.knownValues(this.key);\n\t\tconst attendeeId: SpecificAttendeeId = attendee.attendeeId;\n\t\tconst currentState = (allKnownStates.states[attendeeId] ??=\n\t\t\t// New attendee - prepare new attendee state directory\n\t\t\t{\n\t\t\t\trev: value.rev,\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- items entries can't be optional per https://github.com/microsoft/TypeScript/issues/42810; so forced cast\n\t\t\t\titems: {} as ValidatableMapValueState<T, Keys>[\"items\"],\n\t\t\t});\n\t\t// Accumulate individual update keys\n\t\tconst updatedItemKeys: Keys[] = [];\n\t\tfor (const [key, item] of objectEntries(value.items)) {\n\t\t\t// TODO: Key validation needs to be added here.\n\t\t\tconst validKey = key as Keys;\n\t\t\tif (!(key in currentState.items) || currentState.items[validKey].rev < item.rev) {\n\t\t\t\tupdatedItemKeys.push(validKey);\n\t\t\t}\n\t\t}\n\n\t\tif (updatedItemKeys.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\t// Store updates\n\t\tif (value.rev > currentState.rev) {\n\t\t\tcurrentState.rev = value.rev;\n\t\t}\n\t\tconst allUpdates = {\n\t\t\tattendee,\n\t\t\titems: new Map<Keys, LatestData<T, ValueAccessor<T>>>(),\n\t\t};\n\t\tconst postUpdateActions: PostUpdateAction[] = [];\n\t\tfor (const key of updatedItemKeys) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tconst item = value.items[key]!;\n\t\t\tconst hadPriorValue = currentState.items[key]?.value;\n\t\t\tcurrentState.items[key] = item;\n\t\t\tconst metadata = {\n\t\t\t\trevision: item.rev,\n\t\t\t\ttimestamp: item.timestamp,\n\t\t\t};\n\t\t\tif (isValueRequiredState(item)) {\n\t\t\t\tconst updatedItem = {\n\t\t\t\t\tattendee,\n\t\t\t\t\tkey,\n\t\t\t\t\tvalue: createValidatedGetter(item, this.validator),\n\t\t\t\t\tmetadata,\n\t\t\t\t} satisfies LatestMapItemUpdatedClientData<T, Keys, ValueAccessor<T>>;\n\t\t\t\tpostUpdateActions.push(() => this.events.emit(\"remoteItemUpdated\", updatedItem));\n\t\t\t\tallUpdates.items.set(key, {\n\t\t\t\t\tvalue: updatedItem.value,\n\t\t\t\t\tmetadata,\n\t\t\t\t});\n\t\t\t} else if (hadPriorValue !== undefined) {\n\t\t\t\tpostUpdateActions.push(() =>\n\t\t\t\t\tthis.events.emit(\"remoteItemRemoved\", {\n\t\t\t\t\t\tattendee,\n\t\t\t\t\t\tkey,\n\t\t\t\t\t\tmetadata,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tthis.datastore.update(this.key, attendeeId, currentState);\n\t\tpostUpdateActions.push(() => this.events.emit(\"remoteUpdated\", allUpdates));\n\t\treturn postUpdateActions;\n\t}\n}\n\n/**\n * Arguments that are passed to the {@link StateFactory.latestMap} function.\n *\n * @input\n * @beta\n */\nexport interface LatestMapArgumentsRaw<T, Keys extends string | number = string | number> {\n\t/**\n\t * The initial value of the local state.\n\t */\n\tlocal?: {\n\t\t[K in Keys]: JsonSerializable<T>;\n\t};\n\n\t/**\n\t * See {@link BroadcastControlSettings}.\n\t */\n\tsettings?: BroadcastControlSettings | undefined;\n}\n\n/**\n * Arguments that are passed to the {@link StateFactory.latestMap} function.\n *\n * @input\n * @beta\n */\nexport interface LatestMapArguments<T, Keys extends string | number = string | number>\n\textends LatestMapArgumentsRaw<T, Keys> {\n\t/**\n\t * An optional function that will be called at runtime to validate the presence data. A runtime validator is strongly\n\t * recommended. See {@link StateSchemaValidator}.\n\t */\n\tvalidator: StateSchemaValidator<T>;\n}\n\n// #region factory function overloads\n// Overloads should be ordered from most specific to least specific when combined.\n\n/**\n * Factory for creating a {@link LatestMap} or {@link LatestMapRaw} State object.\n *\n * @beta\n * @sealed\n */\nexport interface LatestMapFactory {\n\t/**\n\t * Factory for creating a {@link LatestMap} State object.\n\t *\n\t * @remarks\n\t * This overload is used when called with {@link LatestMapArguments}.\n\t * That is, if a validator function is provided.\n\t */\n\t<T, Keys extends string | number = string | number, RegistrationKey extends string = string>(\n\t\targs: LatestMapArguments<T, Keys>,\n\t): InternalTypes.ManagerFactory<\n\t\tRegistrationKey,\n\t\tInternalTypes.MapValueState<T, Keys>,\n\t\tLatestMap<T, Keys>\n\t>;\n\n\t/**\n\t * Factory for creating a {@link LatestMapRaw} State object.\n\t *\n\t * @remarks\n\t * This overload is used when called with {@link LatestMapArgumentsRaw}.\n\t * That is, if a validator function is _not_ provided.\n\t */\n\t<T, Keys extends string | number = string | number, RegistrationKey extends string = string>(\n\t\targs?: LatestMapArgumentsRaw<T, Keys>,\n\t): InternalTypes.ManagerFactory<\n\t\tRegistrationKey,\n\t\tInternalTypes.MapValueState<T, Keys>,\n\t\tLatestMapRaw<T, Keys>\n\t>;\n}\n\n// #endregion\n\n/**\n * Factory for creating a {@link LatestMap} or {@link LatestMapRaw} State object.\n */\nexport const latestMap: LatestMapFactory = <\n\tT,\n\tKeys extends string | number = string | number,\n\tRegistrationKey extends string = string,\n>(\n\targs?: Partial<LatestMapArguments<T, Keys>>,\n): InternalTypes.ManagerFactory<\n\tRegistrationKey,\n\tInternalTypes.MapValueState<T, Keys>,\n\tLatestMapRaw<T, Keys> & LatestMap<T, Keys>\n> => {\n\tconst settings = args?.settings;\n\tconst initialValues = args?.local;\n\tconst validator = args?.validator;\n\n\tconst timestamp = Date.now();\n\tconst value: InternalTypes.MapValueState<\n\t\tT,\n\t\t// This should be `Keys`, but will only work if properties are optional.\n\t\tstring | number\n\t> = { rev: 0, items: {} };\n\t// LatestMapRaw takes ownership of values within initialValues.\n\tif (initialValues !== undefined) {\n\t\tfor (const key of objectKeys(initialValues)) {\n\t\t\tvalue.items[key] = {\n\t\t\t\trev: 0,\n\t\t\t\ttimestamp,\n\t\t\t\tvalue: toOpaqueJson(initialValues[key]),\n\t\t\t};\n\t\t}\n\t}\n\tconst factory = (\n\t\tkey: RegistrationKey,\n\t\tdatastoreHandle: InternalTypes.StateDatastoreHandle<\n\t\t\tRegistrationKey,\n\t\t\tInternalTypes.MapValueState<T, Keys>\n\t\t>,\n\t): {\n\t\tinitialData: { value: typeof value; allowableUpdateLatencyMs: number | undefined };\n\t\tmanager: InternalTypes.StateValue<LatestMapRaw<T, Keys> & LatestMap<T, Keys>>;\n\t} => ({\n\t\tinitialData: { value, allowableUpdateLatencyMs: settings?.allowableUpdateLatencyMs },\n\t\tmanager: brandIVM<\n\t\t\tLatestMapValueManagerImpl<T, RegistrationKey, Keys>,\n\t\t\tT,\n\t\t\tInternalTypes.MapValueState<T, Keys>\n\t\t>(\n\t\t\tnew LatestMapValueManagerImpl(\n\t\t\t\tkey,\n\t\t\t\tdatastoreFromHandle(datastoreHandle),\n\t\t\t\tvalue,\n\t\t\t\tsettings,\n\t\t\t\tvalidator,\n\t\t\t),\n\t\t),\n\t});\n\treturn Object.assign(factory, { instanceBase: LatestMapValueManagerImpl });\n};\n"]}
@@ -2,15 +2,6 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import type { LatestMapFactory } from "./latestMapValueManager.js";
6
- import type { LatestFactory } from "./latestValueManager.js";
7
- /**
8
- * Factory for creating presence State objects.
9
- */
10
- export declare const StateFactoryInternal: {
11
- latest: LatestFactory;
12
- latestMap: import("./latestMapValueManager.js").LatestMapFactoryInternal;
13
- };
14
5
  /**
15
6
  * Factory for creating presence State objects.
16
7
  *
@@ -21,7 +12,7 @@ export declare const StateFactoryInternal: {
21
12
  * @beta
22
13
  */
23
14
  export declare const StateFactory: {
24
- latest: LatestFactory;
25
- latestMap: LatestMapFactory;
15
+ latest: import("./latestValueManager.js").LatestFactory;
16
+ latestMap: import("./latestMapValueManager.js").LatestMapFactory;
26
17
  };
27
18
  //# sourceMappingURL=stateFactory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stateFactory.d.ts","sourceRoot":"","sources":["../src/stateFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAG7D;;GAEG;AACH,eAAO,MAAM,oBAAoB;;;CAGhC,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,EAAE;IAC1B,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,EAAE,gBAAgB,CAAC;CACL,CAAC"}
1
+ {"version":3,"file":"stateFactory.d.ts","sourceRoot":"","sources":["../src/stateFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY;;;CAGxB,CAAC"}
@@ -4,16 +4,9 @@
4
4
  * Licensed under the MIT License.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.StateFactory = exports.StateFactoryInternal = void 0;
7
+ exports.StateFactory = void 0;
8
8
  const latestMapValueManager_js_1 = require("./latestMapValueManager.js");
9
9
  const latestValueManager_js_1 = require("./latestValueManager.js");
10
- /**
11
- * Factory for creating presence State objects.
12
- */
13
- exports.StateFactoryInternal = {
14
- latest: latestValueManager_js_1.latest,
15
- latestMap: latestMapValueManager_js_1.latestMap,
16
- };
17
10
  /**
18
11
  * Factory for creating presence State objects.
19
12
  *
@@ -23,5 +16,8 @@ exports.StateFactoryInternal = {
23
16
  *
24
17
  * @beta
25
18
  */
26
- exports.StateFactory = exports.StateFactoryInternal;
19
+ exports.StateFactory = {
20
+ latest: latestValueManager_js_1.latest,
21
+ latestMap: latestMapValueManager_js_1.latestMap,
22
+ };
27
23
  //# sourceMappingURL=stateFactory.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"stateFactory.js","sourceRoot":"","sources":["../src/stateFactory.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,yEAAuD;AAEvD,mEAAiD;AAEjD;;GAEG;AACU,QAAA,oBAAoB,GAAG;IACnC,MAAM,EAAN,8BAAM;IACN,SAAS,EAAT,oCAAS;CACT,CAAC;AAEF;;;;;;;;GAQG;AACU,QAAA,YAAY,GAGrB,4BAAoB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { LatestMapFactory } from \"./latestMapValueManager.js\";\nimport { latestMap } from \"./latestMapValueManager.js\";\nimport type { LatestFactory } from \"./latestValueManager.js\";\nimport { latest } from \"./latestValueManager.js\";\n\n/**\n * Factory for creating presence State objects.\n */\nexport const StateFactoryInternal = {\n\tlatest,\n\tlatestMap,\n};\n\n/**\n * Factory for creating presence State objects.\n *\n * @remarks\n * Use `latest` to create a {@link LatestRaw} State object.\n * Use `latestMap` to create a {@link LatestMapRaw} State object.\n *\n * @beta\n */\nexport const StateFactory: {\n\tlatest: LatestFactory;\n\tlatestMap: LatestMapFactory;\n} = StateFactoryInternal;\n"]}
1
+ {"version":3,"file":"stateFactory.js","sourceRoot":"","sources":["../src/stateFactory.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,yEAAuD;AACvD,mEAAiD;AAEjD;;;;;;;;GAQG;AACU,QAAA,YAAY,GAAG;IAC3B,MAAM,EAAN,8BAAM;IACN,SAAS,EAAT,oCAAS;CACT,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { latestMap } from \"./latestMapValueManager.js\";\nimport { latest } from \"./latestValueManager.js\";\n\n/**\n * Factory for creating presence State objects.\n *\n * @remarks\n * Use `latest` to create a {@link LatestRaw} State object.\n * Use `latestMap` to create a {@link LatestMapRaw} State object.\n *\n * @beta\n */\nexport const StateFactory = {\n\tlatest,\n\tlatestMap,\n};\n"]}
package/lib/alpha.d.ts CHANGED
@@ -35,6 +35,7 @@ export {
35
35
  LatestEvents,
36
36
  LatestFactory,
37
37
  LatestMap,
38
+ LatestMapArguments,
38
39
  LatestMapArgumentsRaw,
39
40
  LatestMapClientData,
40
41
  LatestMapEvents,
package/lib/beta.d.ts CHANGED
@@ -35,6 +35,7 @@ export {
35
35
  LatestEvents,
36
36
  LatestFactory,
37
37
  LatestMap,
38
+ LatestMapArguments,
38
39
  LatestMapArgumentsRaw,
39
40
  LatestMapClientData,
40
41
  LatestMapEvents,
package/lib/index.d.ts CHANGED
@@ -15,7 +15,7 @@ export { type Attendee, type AttendeesEvents, type AttendeeId, AttendeeStatus, t
15
15
  export type { BroadcastControls, BroadcastControlSettings, } from "./broadcastControls.js";
16
16
  export { getPresence, getPresenceAlpha } from "./getPresence.js";
17
17
  export { getPresenceViaDataObject, type ExperimentalPresenceDO, ExperimentalPresenceManager, } from "./datastorePresenceManagerFactory.js";
18
- export type { LatestMap, LatestMapArgumentsRaw, LatestMapClientData, LatestMapEvents, LatestMapFactory, LatestMapItemRemovedClientData, LatestMapItemUpdatedClientData, LatestMapRaw, LatestMapRawEvents, StateMap, } from "./latestMapValueManager.js";
18
+ export type { LatestMap, LatestMapArguments, LatestMapArgumentsRaw, LatestMapClientData, LatestMapEvents, LatestMapFactory, LatestMapItemRemovedClientData, LatestMapItemUpdatedClientData, LatestMapRaw, LatestMapRawEvents, StateMap, } from "./latestMapValueManager.js";
19
19
  export type { Latest, LatestArguments, LatestArgumentsRaw, LatestEvents, LatestFactory, LatestRaw, LatestRawEvents, } from "./latestValueManager.js";
20
20
  export type { Accessor, LatestClientData, LatestData, LatestMetadata, ProxiedValueAccessor, RawValueAccessor, StateSchemaValidator, ValueAccessor, } from "./latestValueTypes.js";
21
21
  export { type NotificationEmitter, type NotificationListenable, type NotificationSubscriptions, Notifications, type NotificationsManager, type NotificationsManagerEvents, } from "./notificationsManager.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;GAMG;AAEH,YAAY,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEzD,YAAY,EACX,sBAAsB,EACtB,4BAA4B,EAC5B,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACN,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,cAAc,EACd,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,yBAAyB,GAC9B,MAAM,eAAe,CAAC;AAEvB,YAAY,EACX,iBAAiB,EACjB,wBAAwB,GACxB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEjE,OAAO,EACN,wBAAwB,EACxB,KAAK,sBAAsB,EAC3B,2BAA2B,GAC3B,MAAM,sCAAsC,CAAC;AAE9C,YAAY,EACX,SAAS,EAET,qBAAqB,EACrB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,8BAA8B,EAC9B,8BAA8B,EAC9B,YAAY,EACZ,kBAAkB,EAClB,QAAQ,GACR,MAAM,4BAA4B,CAAC;AACpC,YAAY,EACX,MAAM,EACN,eAAe,EACf,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,SAAS,EACT,eAAe,GACf,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACX,QAAQ,EACR,gBAAgB,EAChB,UAAU,EACV,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,GACb,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACN,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,yBAAyB,EAC9B,aAAa,EACb,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,GAC/B,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,YAAY,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,YAAY,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;GAMG;AAEH,YAAY,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEzD,YAAY,EACX,sBAAsB,EACtB,4BAA4B,EAC5B,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACN,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,cAAc,EACd,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,yBAAyB,GAC9B,MAAM,eAAe,CAAC;AAEvB,YAAY,EACX,iBAAiB,EACjB,wBAAwB,GACxB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEjE,OAAO,EACN,wBAAwB,EACxB,KAAK,sBAAsB,EAC3B,2BAA2B,GAC3B,MAAM,sCAAsC,CAAC;AAE9C,YAAY,EACX,SAAS,EACT,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,8BAA8B,EAC9B,8BAA8B,EAC9B,YAAY,EACZ,kBAAkB,EAClB,QAAQ,GACR,MAAM,4BAA4B,CAAC;AACpC,YAAY,EACX,MAAM,EACN,eAAe,EACf,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,SAAS,EACT,eAAe,GACf,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACX,QAAQ,EACR,gBAAgB,EAChB,UAAU,EACV,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,GACb,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACN,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,yBAAyB,EAC9B,aAAa,EACb,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,GAC/B,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,YAAY,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,YAAY,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC"}
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAsBH,OAAO,EAIN,cAAc,GAId,MAAM,eAAe,CAAC;AAOvB,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEjE,OAAO,EACN,wBAAwB,EAExB,2BAA2B,GAC3B,MAAM,sCAAsC,CAAC;AAmC9C,OAAO,EAIN,aAAa,GAGb,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * Package for client presence within a connected session.\n *\n * See {@link https://github.com/microsoft/FluidFramework/tree/main/packages/framework/presence#readme | README.md } for an overview of the package.\n *\n * @packageDocumentation\n */\n\nexport type { ClientConnectionId } from \"./baseTypes.js\";\n\nexport type {\n\tNotificationsWorkspace,\n\tNotificationsWorkspaceSchema,\n\tStatesWorkspace,\n\tStatesWorkspaceEntries,\n\tStatesWorkspaceSchema,\n\tStatesWorkspaceEntry,\n\tWorkspaceAddress,\n} from \"./types.js\";\n\nexport {\n\ttype Attendee,\n\ttype AttendeesEvents,\n\ttype AttendeeId,\n\tAttendeeStatus,\n\ttype Presence,\n\ttype PresenceEvents,\n\ttype PresenceWithNotifications,\n} from \"./presence.js\";\n\nexport type {\n\tBroadcastControls,\n\tBroadcastControlSettings,\n} from \"./broadcastControls.js\";\n\nexport { getPresence, getPresenceAlpha } from \"./getPresence.js\";\n\nexport {\n\tgetPresenceViaDataObject,\n\ttype ExperimentalPresenceDO,\n\tExperimentalPresenceManager,\n} from \"./datastorePresenceManagerFactory.js\";\n\nexport type {\n\tLatestMap,\n\t// LatestMapArguments,\n\tLatestMapArgumentsRaw,\n\tLatestMapClientData,\n\tLatestMapEvents,\n\tLatestMapFactory,\n\tLatestMapItemRemovedClientData,\n\tLatestMapItemUpdatedClientData,\n\tLatestMapRaw,\n\tLatestMapRawEvents,\n\tStateMap,\n} from \"./latestMapValueManager.js\";\nexport type {\n\tLatest,\n\tLatestArguments,\n\tLatestArgumentsRaw,\n\tLatestEvents,\n\tLatestFactory,\n\tLatestRaw,\n\tLatestRawEvents,\n} from \"./latestValueManager.js\";\nexport type {\n\tAccessor,\n\tLatestClientData,\n\tLatestData,\n\tLatestMetadata,\n\tProxiedValueAccessor,\n\tRawValueAccessor,\n\tStateSchemaValidator,\n\tValueAccessor,\n} from \"./latestValueTypes.js\";\n\nexport {\n\ttype NotificationEmitter,\n\ttype NotificationListenable,\n\ttype NotificationSubscriptions,\n\tNotifications,\n\ttype NotificationsManager,\n\ttype NotificationsManagerEvents,\n} from \"./notificationsManager.js\";\n\nexport { StateFactory } from \"./stateFactory.js\";\n\nexport type { InternalTypes } from \"./exposedInternalTypes.js\";\nexport type { InternalUtilityTypes } from \"./exposedUtilityTypes.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAsBH,OAAO,EAIN,cAAc,GAId,MAAM,eAAe,CAAC;AAOvB,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEjE,OAAO,EACN,wBAAwB,EAExB,2BAA2B,GAC3B,MAAM,sCAAsC,CAAC;AAmC9C,OAAO,EAIN,aAAa,GAGb,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * Package for client presence within a connected session.\n *\n * See {@link https://github.com/microsoft/FluidFramework/tree/main/packages/framework/presence#readme | README.md } for an overview of the package.\n *\n * @packageDocumentation\n */\n\nexport type { ClientConnectionId } from \"./baseTypes.js\";\n\nexport type {\n\tNotificationsWorkspace,\n\tNotificationsWorkspaceSchema,\n\tStatesWorkspace,\n\tStatesWorkspaceEntries,\n\tStatesWorkspaceSchema,\n\tStatesWorkspaceEntry,\n\tWorkspaceAddress,\n} from \"./types.js\";\n\nexport {\n\ttype Attendee,\n\ttype AttendeesEvents,\n\ttype AttendeeId,\n\tAttendeeStatus,\n\ttype Presence,\n\ttype PresenceEvents,\n\ttype PresenceWithNotifications,\n} from \"./presence.js\";\n\nexport type {\n\tBroadcastControls,\n\tBroadcastControlSettings,\n} from \"./broadcastControls.js\";\n\nexport { getPresence, getPresenceAlpha } from \"./getPresence.js\";\n\nexport {\n\tgetPresenceViaDataObject,\n\ttype ExperimentalPresenceDO,\n\tExperimentalPresenceManager,\n} from \"./datastorePresenceManagerFactory.js\";\n\nexport type {\n\tLatestMap,\n\tLatestMapArguments,\n\tLatestMapArgumentsRaw,\n\tLatestMapClientData,\n\tLatestMapEvents,\n\tLatestMapFactory,\n\tLatestMapItemRemovedClientData,\n\tLatestMapItemUpdatedClientData,\n\tLatestMapRaw,\n\tLatestMapRawEvents,\n\tStateMap,\n} from \"./latestMapValueManager.js\";\nexport type {\n\tLatest,\n\tLatestArguments,\n\tLatestArgumentsRaw,\n\tLatestEvents,\n\tLatestFactory,\n\tLatestRaw,\n\tLatestRawEvents,\n} from \"./latestValueManager.js\";\nexport type {\n\tAccessor,\n\tLatestClientData,\n\tLatestData,\n\tLatestMetadata,\n\tProxiedValueAccessor,\n\tRawValueAccessor,\n\tStateSchemaValidator,\n\tValueAccessor,\n} from \"./latestValueTypes.js\";\n\nexport {\n\ttype NotificationEmitter,\n\ttype NotificationListenable,\n\ttype NotificationSubscriptions,\n\tNotifications,\n\ttype NotificationsManager,\n\ttype NotificationsManagerEvents,\n} from \"./notificationsManager.js\";\n\nexport { StateFactory } from \"./stateFactory.js\";\n\nexport type { InternalTypes } from \"./exposedInternalTypes.js\";\nexport type { InternalUtilityTypes } from \"./exposedUtilityTypes.js\";\n"]}
@@ -264,35 +264,31 @@ export interface LatestMapArguments<T, Keys extends string | number = string | n
264
264
  validator: StateSchemaValidator<T>;
265
265
  }
266
266
  /**
267
- * Factory for creating a {@link LatestMapRaw} State object.
267
+ * Factory for creating a {@link LatestMap} or {@link LatestMapRaw} State object.
268
268
  *
269
269
  * @beta
270
270
  * @sealed
271
271
  */
272
272
  export interface LatestMapFactory {
273
273
  /**
274
- * Factory for creating a {@link LatestMapRaw} State object.
274
+ * Factory for creating a {@link LatestMap} State object.
275
275
  *
276
- * @privateRemarks (change to `remarks` when adding signature overload)
277
- * This overload is used when called with {@link LatestMapArgumentsRaw}.
278
- * That is, if a validator function is _not_ provided.
276
+ * @remarks
277
+ * This overload is used when called with {@link LatestMapArguments}.
278
+ * That is, if a validator function is provided.
279
279
  */
280
- <T, Keys extends string | number = string | number, RegistrationKey extends string = string>(args?: LatestMapArgumentsRaw<T, Keys>): InternalTypes.ManagerFactory<RegistrationKey, InternalTypes.MapValueState<T, Keys>, LatestMapRaw<T, Keys>>;
281
- }
282
- /**
283
- * Factory for creating a {@link LatestMap} or {@link LatestMapRaw} State object.
284
- */
285
- export interface LatestMapFactoryInternal extends LatestMapFactory {
280
+ <T, Keys extends string | number = string | number, RegistrationKey extends string = string>(args: LatestMapArguments<T, Keys>): InternalTypes.ManagerFactory<RegistrationKey, InternalTypes.MapValueState<T, Keys>, LatestMap<T, Keys>>;
286
281
  /**
287
- * Factory for creating a {@link LatestMap} State object.
282
+ * Factory for creating a {@link LatestMapRaw} State object.
288
283
  *
289
284
  * @remarks
290
- * This overload is used when called with {@link LatestMapArguments}. That is, if a validator function is provided.
285
+ * This overload is used when called with {@link LatestMapArgumentsRaw}.
286
+ * That is, if a validator function is _not_ provided.
291
287
  */
292
- <T, Keys extends string | number = string | number, RegistrationKey extends string = string>(args: LatestMapArguments<T, Keys>): InternalTypes.ManagerFactory<RegistrationKey, InternalTypes.MapValueState<T, Keys>, LatestMap<T, Keys>>;
288
+ <T, Keys extends string | number = string | number, RegistrationKey extends string = string>(args?: LatestMapArgumentsRaw<T, Keys>): InternalTypes.ManagerFactory<RegistrationKey, InternalTypes.MapValueState<T, Keys>, LatestMapRaw<T, Keys>>;
293
289
  }
294
290
  /**
295
291
  * Factory for creating a {@link LatestMap} or {@link LatestMapRaw} State object.
296
292
  */
297
- export declare const latestMap: LatestMapFactoryInternal;
293
+ export declare const latestMap: LatestMapFactory;
298
294
  //# sourceMappingURL=latestMapValueManager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"latestMapValueManager.d.ts","sourceRoot":"","sources":["../src/latestMapValueManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"latestMapValueManager.d.ts","sourceRoot":"","sources":["../src/latestMapValueManager.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,7 @@
5
5
  import { createEmitter } from "@fluid-internal/client-utils";
6
6
  import { OptionalBroadcastControl } from "./broadcastControls.js";
7
7
  import { asDeeplyReadonly, asDeeplyReadonlyDeserializedJson, isValueRequiredState, objectEntries, objectKeys, toOpaqueJson, } from "./internalUtils.js";
8
+ import { createValidatedGetter } from "./latestValueTypes.js";
8
9
  import { datastoreFromHandle } from "./stateDatastore.js";
9
10
  import { brandIVM } from "./valueManager.js";
10
11
  class ValueMapImpl {
@@ -85,10 +86,11 @@ class ValueMapImpl {
85
86
  }
86
87
  }
87
88
  class LatestMapValueManagerImpl {
88
- constructor(key, datastore, value, controlSettings) {
89
+ constructor(key, datastore, value, controlSettings, validator) {
89
90
  this.key = key;
90
91
  this.datastore = datastore;
91
92
  this.value = value;
93
+ this.validator = validator;
92
94
  this.events = createEmitter();
93
95
  this.controls = new OptionalBroadcastControl(controlSettings);
94
96
  this.local = new ValueMapImpl(value, this.events, (updates) => {
@@ -117,6 +119,7 @@ class LatestMapValueManagerImpl {
117
119
  .map((attendeeId) => this.datastore.presence.attendees.getAttendee(attendeeId));
118
120
  }
119
121
  getRemote(attendee) {
122
+ const validator = this.validator;
120
123
  const allKnownStates = this.datastore.knownValues(this.key);
121
124
  const attendeeId = attendee.attendeeId;
122
125
  const clientStateMap = allKnownStates.states[attendeeId];
@@ -127,7 +130,7 @@ class LatestMapValueManagerImpl {
127
130
  for (const [key, item] of objectEntries(clientStateMap.items)) {
128
131
  if (isValueRequiredState(item)) {
129
132
  items.set(key, {
130
- value: asDeeplyReadonlyDeserializedJson(item.value),
133
+ value: createValidatedGetter(item, validator),
131
134
  metadata: { revision: item.rev, timestamp: item.timestamp },
132
135
  });
133
136
  }
@@ -175,15 +178,17 @@ class LatestMapValueManagerImpl {
175
178
  timestamp: item.timestamp,
176
179
  };
177
180
  if (isValueRequiredState(item)) {
178
- const itemValue = asDeeplyReadonlyDeserializedJson(item.value);
179
181
  const updatedItem = {
180
182
  attendee,
181
183
  key,
182
- value: itemValue,
184
+ value: createValidatedGetter(item, this.validator),
183
185
  metadata,
184
186
  };
185
187
  postUpdateActions.push(() => this.events.emit("remoteItemUpdated", updatedItem));
186
- allUpdates.items.set(key, { value: itemValue, metadata });
188
+ allUpdates.items.set(key, {
189
+ value: updatedItem.value,
190
+ metadata,
191
+ });
187
192
  }
188
193
  else if (hadPriorValue !== undefined) {
189
194
  postUpdateActions.push(() => this.events.emit("remoteItemRemoved", {
@@ -206,9 +211,6 @@ export const latestMap = (args) => {
206
211
  const settings = args?.settings;
207
212
  const initialValues = args?.local;
208
213
  const validator = args?.validator;
209
- if (validator !== undefined) {
210
- throw new Error(`Validators are not yet implemented.`);
211
- }
212
214
  const timestamp = Date.now();
213
215
  const value = { rev: 0, items: {} };
214
216
  // LatestMapRaw takes ownership of values within initialValues.
@@ -223,7 +225,7 @@ export const latestMap = (args) => {
223
225
  }
224
226
  const factory = (key, datastoreHandle) => ({
225
227
  initialData: { value, allowableUpdateLatencyMs: settings?.allowableUpdateLatencyMs },
226
- manager: brandIVM(new LatestMapValueManagerImpl(key, datastoreFromHandle(datastoreHandle), value, settings)),
228
+ manager: brandIVM(new LatestMapValueManagerImpl(key, datastoreFromHandle(datastoreHandle), value, settings, validator)),
227
229
  });
228
230
  return Object.assign(factory, { instanceBase: LatestMapValueManagerImpl });
229
231
  };
@@ -1 +1 @@
1
- {"version":3,"file":"latestMapValueManager.js","sourceRoot":"","sources":["../src/latestMapValueManager.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { createEmitter } from \"@fluid-internal/client-utils\";\nimport type { Listenable } from \"@fluidframework/core-interfaces\";\nimport type { IEmitter } from \"@fluidframework/core-interfaces/internal\";\nimport type {\n\tDeepReadonly,\n\tJsonDeserialized,\n\tJsonSerializable,\n} from \"@fluidframework/core-interfaces/internal/exposedUtilityTypes\";\n\nimport type { BroadcastControls, BroadcastControlSettings } from \"./broadcastControls.js\";\nimport { OptionalBroadcastControl } from \"./broadcastControls.js\";\nimport type { InternalTypes } from \"./exposedInternalTypes.js\";\nimport type {\n\tPostUpdateAction,\n\tValidatableOptionalState,\n\tValueManager,\n} from \"./internalTypes.js\";\nimport {\n\tasDeeplyReadonly,\n\tasDeeplyReadonlyDeserializedJson,\n\tisValueRequiredState,\n\tobjectEntries,\n\tobjectKeys,\n\ttoOpaqueJson,\n} from \"./internalUtils.js\";\nimport type {\n\tLatestClientData,\n\tLatestData,\n\tLatestMetadata,\n\tProxiedValueAccessor,\n\tRawValueAccessor,\n\tStateSchemaValidator,\n\tValueAccessor,\n} from \"./latestValueTypes.js\";\nimport type { AttendeeId, Attendee, Presence, SpecificAttendee } from \"./presence.js\";\nimport { datastoreFromHandle, type StateDatastore } from \"./stateDatastore.js\";\nimport { brandIVM } from \"./valueManager.js\";\n\n/**\n * Collection of validatable optional values in a \"map\" structure.\n *\n * @remarks\n * Validatable equivalent of {@link InternalTypes.MapValueState}.\n */\ninterface ValidatableMapValueState<T, Keys extends string | number> {\n\trev: number;\n\titems: {\n\t\t// Caution: any particular item may or may not exist\n\t\t// Typescript does not support absent keys without forcing type to also be undefined.\n\t\t// See https://github.com/microsoft/TypeScript/issues/42810.\n\t\t[name in Keys]: ValidatableOptionalState<T>;\n\t};\n}\n\n/**\n * Collection of latest known values for a specific {@link Attendee}.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMapClientData<\n\tT,\n\tKeys extends string | number,\n\tTValueAccessor extends ValueAccessor<T>,\n\tSpecificAttendeeId extends AttendeeId = AttendeeId,\n> {\n\t/**\n\t * Associated {@link Attendee}.\n\t */\n\tattendee: Attendee<SpecificAttendeeId>;\n\n\t/**\n\t * Map of items for the state.\n\t *\n\t * @privateRemarks This could be regular map currently as no Map is\n\t * stored internally and a new instance is created for every request.\n\t */\n\titems: ReadonlyMap<Keys, LatestData<T, TValueAccessor>>;\n}\n\n/**\n * State of a single item value, its key, and its metadata.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMapItemUpdatedClientData<\n\tT,\n\tK extends string | number,\n\tTValueAccessor extends ValueAccessor<T>,\n> extends LatestClientData<T, TValueAccessor> {\n\t/**\n\t * Key of the updated item.\n\t */\n\tkey: K;\n}\n\n/**\n * Identifier and metadata for a removed item.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMapItemRemovedClientData<K extends string | number> {\n\t/**\n\t * Associated {@link Attendee}.\n\t */\n\tattendee: Attendee;\n\t/**\n\t * Key of the removed item.\n\t */\n\tkey: K;\n\t/**\n\t * Metadata associated with the removal of the item.\n\t */\n\tmetadata: LatestMetadata;\n}\n\n/**\n * Events from {@link LatestMapRaw}.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMapEvents<\n\tT,\n\tK extends string | number,\n\tTRemoteValueAccessor extends ValueAccessor<T> = ProxiedValueAccessor<T>,\n> {\n\t/**\n\t * Raised when any item's value for remote client is updated.\n\t * @param updates - Map of one or more values updated.\n\t *\n\t * @remarks The event does not include item removals.\n\t *\n\t * @eventProperty\n\t */\n\tremoteUpdated: (updates: LatestMapClientData<T, K, TRemoteValueAccessor>) => void;\n\n\t/**\n\t * Raised when specific item's value of remote client is updated.\n\t * @param updatedItem - Updated item value.\n\t *\n\t * @eventProperty\n\t */\n\tremoteItemUpdated: (\n\t\tupdatedItem: LatestMapItemUpdatedClientData<T, K, TRemoteValueAccessor>,\n\t) => void;\n\n\t/**\n\t * Raised when specific item of remote client is removed.\n\t * @param removedItem - Removed item.\n\t *\n\t * @eventProperty\n\t */\n\tremoteItemRemoved: (removedItem: LatestMapItemRemovedClientData<K>) => void;\n\n\t/**\n\t * Raised when specific local item's value is updated.\n\t * @param updatedItem - Updated item value.\n\t *\n\t * @eventProperty\n\t */\n\tlocalItemUpdated: (updatedItem: {\n\t\tvalue: DeepReadonly<JsonSerializable<T>>;\n\t\tkey: K;\n\t}) => void;\n\n\t/**\n\t * Raised when specific local item is removed.\n\t * @param removedItem - Removed item.\n\t *\n\t * @eventProperty\n\t */\n\tlocalItemRemoved: (removedItem: {\n\t\tkey: K;\n\t}) => void;\n}\n\n/**\n * Events from {@link LatestMapRaw}.\n *\n * @sealed\n * @beta\n */\nexport type LatestMapRawEvents<T, K extends string | number> = LatestMapEvents<\n\tT,\n\tK,\n\tRawValueAccessor<T>\n>;\n\n/**\n * Map of local client's values. Modifications are transmitted to all other connected clients.\n *\n * @sealed\n * @beta\n */\nexport interface StateMap<K extends string | number, V> {\n\t/**\n\t * ${@link StateMap.delete}s all elements in the StateMap.\n\t * @remarks This is not yet implemented.\n\t */\n\tclear(): void;\n\n\t/**\n\t * Removes the element with the specified key from the StateMap, if it exists.\n\t *\n\t * @returns true if an element in the StateMap existed and has been removed, or false if\n\t * the element does not exist.\n\t * @remarks No entry is fully removed. Instead an undefined placeholder is locally and\n\t * transmitted to all other clients. For better performance limit the number of deleted\n\t * entries and reuse keys when possible.\n\t * @privateRemarks In the future we may add a mechanism to remove the placeholder, at least\n\t * from transmissions after sufficient time has passed.\n\t */\n\tdelete(key: K): boolean;\n\n\t/**\n\t * Executes a provided function once per each key/value pair in the StateMap, in arbitrary order.\n\t */\n\tforEach(\n\t\tcallbackfn: (\n\t\t\tvalue: DeepReadonly<JsonDeserialized<V>>,\n\t\t\tkey: K,\n\t\t\tmap: StateMap<K, V>,\n\t\t) => void,\n\t\tthisArg?: unknown,\n\t): void;\n\n\t/**\n\t * Returns the element with the specified key from the StateMap, if it exists.\n\t *\n\t * @returns Returns the element associated with the specified key. If no element is associated with the specified key, undefined is returned.\n\t */\n\tget(key: K): DeepReadonly<JsonDeserialized<V>> | undefined;\n\n\t/**\n\t * Checks if an element with the specified key exists in the StateMap.\n\t * @returns boolean indicating whether an element with the specified key exists or not.\n\t */\n\thas(key: K): boolean;\n\n\t/**\n\t * Adds a new element with a specified key and value to the StateMap. If an element with the same key already exists, the element will be updated.\n\t * The value will be transmitted to all other connected clients.\n\t *\n\t * @remarks Manager assumes ownership of the value and its references.\n\t * Make a deep clone before setting, if needed. No comparison is done to detect changes; all\n\t * sets are transmitted.\n\t */\n\tset(key: K, value: JsonSerializable<V>): this;\n\n\t/**\n\t * The number of elements in the StateMap.\n\t */\n\treadonly size: number;\n\n\t/**\n\t * Returns an iterable of entries in the map.\n\t */\n\t// [Symbol.iterator](): IterableIterator<[K, DeepReadonly<JsonDeserialized<V>>]>;\n\n\t/**\n\t * Returns an iterable of key, value pairs for every entry in the map.\n\t */\n\t// entries(): IterableIterator<[K, DeepReadonly<JsonDeserialized<V>>]>;\n\n\t/**\n\t * Returns an iterable of keys in the map.\n\t */\n\tkeys(): IterableIterator<K>;\n\n\t/**\n\t * Returns an iterable of values in the map.\n\t */\n\t// values(): IterableIterator<DeepReadonly<JsonDeserialized<V>>>;\n}\n\nclass ValueMapImpl<T, K extends string | number> implements StateMap<K, T> {\n\tprivate countDefined: number;\n\tpublic constructor(\n\t\tprivate readonly value: InternalTypes.MapValueState<T, K>,\n\t\tprivate readonly emitter: IEmitter<\n\t\t\tPick<LatestMapEvents<T, K, ValueAccessor<T>>, \"localItemUpdated\" | \"localItemRemoved\">\n\t\t>,\n\t\tprivate readonly localUpdate: (\n\t\t\tupdates: InternalTypes.MapValueState<\n\t\t\t\tT,\n\t\t\t\t// This should be `K`, but will only work if properties are optional.\n\t\t\t\tstring | number\n\t\t\t>,\n\t\t) => void,\n\t) {\n\t\t// All initial items are expected to be defined.\n\t\t// TODO assert all defined and/or update type.\n\t\tthis.countDefined = Object.keys(value.items).length;\n\t}\n\n\t/**\n\t * Note: caller must ensure key exists in this.value.items.\n\t */\n\tprivate updateItem(key: K, value: InternalTypes.ValueOptionalState<T>[\"value\"]): void {\n\t\tthis.value.rev += 1;\n\t\t// Caller is required to ensure key exists.\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\tconst item = this.value.items[key]!;\n\t\titem.rev += 1;\n\t\titem.timestamp = Date.now();\n\t\tif (value === undefined) {\n\t\t\tdelete item.value;\n\t\t} else {\n\t\t\titem.value = value;\n\t\t}\n\t\tconst update = { rev: this.value.rev, items: { [key]: item } };\n\t\tthis.localUpdate(update);\n\t}\n\n\tpublic clear(): void {\n\t\tthrow new Error(\"Method not implemented.\");\n\t}\n\tpublic delete(key: K): boolean {\n\t\tconst { items } = this.value;\n\t\tconst hasKey = items[key]?.value !== undefined;\n\t\tif (hasKey) {\n\t\t\tthis.countDefined -= 1;\n\t\t\tthis.updateItem(key, undefined);\n\t\t\tthis.emitter.emit(\"localItemRemoved\", { key });\n\t\t}\n\t\treturn hasKey;\n\t}\n\tpublic forEach(\n\t\tcallbackfn: (\n\t\t\tvalue: DeepReadonly<JsonDeserialized<T>>,\n\t\t\tkey: K,\n\t\t\tmap: StateMap<K, T>,\n\t\t) => void,\n\t\tthisArg?: unknown,\n\t): void {\n\t\tfor (const [key, item] of objectEntries(this.value.items)) {\n\t\t\tif (item.value !== undefined) {\n\t\t\t\tcallbackfn(asDeeplyReadonlyDeserializedJson(item.value), key, this);\n\t\t\t}\n\t\t}\n\t}\n\tpublic get(key: K): DeepReadonly<JsonDeserialized<T>> | undefined {\n\t\treturn asDeeplyReadonlyDeserializedJson(this.value.items[key]?.value);\n\t}\n\tpublic has(key: K): boolean {\n\t\treturn this.value.items[key]?.value !== undefined;\n\t}\n\tpublic set(key: K, inValue: JsonSerializable<T>): this {\n\t\tconst value = toOpaqueJson<T>(inValue);\n\t\tif (!(key in this.value.items)) {\n\t\t\tthis.countDefined += 1;\n\t\t\tthis.value.items[key] = { rev: 0, timestamp: 0, value };\n\t\t}\n\t\tthis.updateItem(key, value);\n\t\tthis.emitter.emit(\"localItemUpdated\", { key, value: asDeeplyReadonly(inValue) });\n\t\treturn this;\n\t}\n\tpublic get size(): number {\n\t\treturn this.countDefined;\n\t}\n\tpublic keys(): IterableIterator<K> {\n\t\tconst keys: K[] = [];\n\t\tfor (const [key, item] of objectEntries(this.value.items)) {\n\t\t\tif (item.value !== undefined) {\n\t\t\t\tkeys.push(key);\n\t\t\t}\n\t\t}\n\t\treturn keys[Symbol.iterator]();\n\t}\n}\n\n/**\n * State that provides a `Map` of latest known values from this client to\n * others and read access to their values.\n * Entries in the map may vary over time and by client, but all values are expected to\n * be of the same type, which may be a union type.\n *\n * @remarks Create using {@link StateFactory.latestMap} registered to {@link StatesWorkspace}.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMap<\n\tT,\n\tKeys extends string | number = string | number,\n\tTRemoteAccessor extends ValueAccessor<T> = ProxiedValueAccessor<T>,\n> {\n\t/**\n\t * Containing {@link Presence}\n\t */\n\treadonly presence: Presence;\n\n\t/**\n\t * Events for LatestMap.\n\t */\n\treadonly events: Listenable<LatestMapEvents<T, Keys, TRemoteAccessor>>;\n\n\t/**\n\t * Controls for management of sending updates.\n\t */\n\treadonly controls: BroadcastControls;\n\n\t/**\n\t * Current value map for this client.\n\t */\n\treadonly local: StateMap<Keys, T>;\n\t/**\n\t * Iterable access to remote clients' map of values.\n\t */\n\tgetRemotes(): IterableIterator<LatestMapClientData<T, Keys, TRemoteAccessor>>;\n\t/**\n\t * Array of {@link Attendee}s that have provided states.\n\t */\n\tgetStateAttendees(): Attendee[];\n\t/**\n\t * Access to a specific client's map of values.\n\t */\n\tgetRemote(attendee: Attendee): ReadonlyMap<Keys, LatestData<T, TRemoteAccessor>>;\n}\n\n/**\n * State that provides a `Map` of latest known values from this client to\n * others and read access to their values.\n * Entries in the map may vary over time and by client, but all values are expected to\n * be of the same type, which may be a union type.\n *\n * @remarks Create using {@link StateFactory.latestMap} registered to {@link StatesWorkspace}.\n *\n * @sealed\n * @beta\n */\nexport type LatestMapRaw<T, Keys extends string | number = string | number> = LatestMap<\n\tT,\n\tKeys,\n\tRawValueAccessor<T>\n>;\n\nclass LatestMapValueManagerImpl<\n\tT,\n\tRegistrationKey extends string,\n\tKeys extends string | number = string | number,\n> implements\n\t\tLatestMapRaw<T, Keys>,\n\t\tLatestMap<T, Keys>,\n\t\tRequired<ValueManager<T, InternalTypes.MapValueState<T, Keys>>>\n{\n\tpublic readonly events = createEmitter<LatestMapEvents<T, Keys, RawValueAccessor<T>>>();\n\tpublic readonly controls: OptionalBroadcastControl;\n\n\tpublic constructor(\n\t\tprivate readonly key: RegistrationKey,\n\t\tprivate readonly datastore: StateDatastore<\n\t\t\tRegistrationKey,\n\t\t\tInternalTypes.MapValueState<T, Keys>,\n\t\t\tValidatableMapValueState<T, Keys>\n\t\t>,\n\t\tpublic readonly value: InternalTypes.MapValueState<T, Keys>,\n\t\tcontrolSettings: BroadcastControlSettings | undefined,\n\t) {\n\t\tthis.controls = new OptionalBroadcastControl(controlSettings);\n\n\t\tthis.local = new ValueMapImpl<T, Keys>(\n\t\t\tvalue,\n\t\t\tthis.events,\n\t\t\t(updates: InternalTypes.MapValueState<T, Keys>) => {\n\t\t\t\tdatastore.localUpdate(key, updates, {\n\t\t\t\t\tallowableUpdateLatencyMs: this.controls.allowableUpdateLatencyMs,\n\t\t\t\t});\n\t\t\t},\n\t\t);\n\t}\n\n\tpublic get presence(): Presence {\n\t\treturn this.datastore.presence;\n\t}\n\n\tpublic readonly local: StateMap<Keys, T>;\n\n\tpublic *getRemotes(): IterableIterator<LatestMapClientData<T, Keys, ValueAccessor<T>>> {\n\t\tconst allKnownStates = this.datastore.knownValues(this.key);\n\t\tfor (const attendeeId of objectKeys(allKnownStates.states)) {\n\t\t\tif (attendeeId !== allKnownStates.self) {\n\t\t\t\tconst attendee = this.datastore.presence.attendees.getAttendee(attendeeId);\n\t\t\t\tconst items = this.getRemote(attendee);\n\t\t\t\tyield { attendee, items };\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic getStateAttendees(): Attendee[] {\n\t\tconst allKnownStates = this.datastore.knownValues(this.key);\n\t\treturn objectKeys(allKnownStates.states)\n\t\t\t.filter((attendeeId) => attendeeId !== allKnownStates.self)\n\t\t\t.map((attendeeId) => this.datastore.presence.attendees.getAttendee(attendeeId));\n\t}\n\n\tpublic getRemote(attendee: Attendee): ReadonlyMap<Keys, LatestData<T, ValueAccessor<T>>> {\n\t\tconst allKnownStates = this.datastore.knownValues(this.key);\n\t\tconst attendeeId = attendee.attendeeId;\n\t\tconst clientStateMap = allKnownStates.states[attendeeId];\n\t\tif (clientStateMap === undefined) {\n\t\t\tthrow new Error(\"No entry for attendee\");\n\t\t}\n\t\tconst items = new Map<Keys, LatestData<T, ValueAccessor<T>>>();\n\t\tfor (const [key, item] of objectEntries(clientStateMap.items)) {\n\t\t\tif (isValueRequiredState(item)) {\n\t\t\t\titems.set(key, {\n\t\t\t\t\tvalue: asDeeplyReadonlyDeserializedJson(item.value),\n\t\t\t\t\tmetadata: { revision: item.rev, timestamp: item.timestamp },\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn items;\n\t}\n\n\tpublic update<SpecificAttendeeId extends AttendeeId>(\n\t\tattendee: SpecificAttendee<SpecificAttendeeId>,\n\t\t_received: number,\n\t\tvalue: InternalTypes.MapValueState<T, string | number>,\n\t): PostUpdateAction[] {\n\t\tconst allKnownStates = this.datastore.knownValues(this.key);\n\t\tconst attendeeId: SpecificAttendeeId = attendee.attendeeId;\n\t\tconst currentState = (allKnownStates.states[attendeeId] ??=\n\t\t\t// New attendee - prepare new attendee state directory\n\t\t\t{\n\t\t\t\trev: value.rev,\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- items entries can't be optional per https://github.com/microsoft/TypeScript/issues/42810; so forced cast\n\t\t\t\titems: {} as ValidatableMapValueState<T, Keys>[\"items\"],\n\t\t\t});\n\t\t// Accumulate individual update keys\n\t\tconst updatedItemKeys: Keys[] = [];\n\t\tfor (const [key, item] of objectEntries(value.items)) {\n\t\t\t// TODO: Key validation needs to be added here.\n\t\t\tconst validKey = key as Keys;\n\t\t\tif (!(key in currentState.items) || currentState.items[validKey].rev < item.rev) {\n\t\t\t\tupdatedItemKeys.push(validKey);\n\t\t\t}\n\t\t}\n\n\t\tif (updatedItemKeys.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\t// Store updates\n\t\tif (value.rev > currentState.rev) {\n\t\t\tcurrentState.rev = value.rev;\n\t\t}\n\t\tconst allUpdates = {\n\t\t\tattendee,\n\t\t\titems: new Map<Keys, LatestData<T, ValueAccessor<T>>>(),\n\t\t};\n\t\tconst postUpdateActions: PostUpdateAction[] = [];\n\t\tfor (const key of updatedItemKeys) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tconst item = value.items[key]!;\n\t\t\tconst hadPriorValue = currentState.items[key]?.value;\n\t\t\tcurrentState.items[key] = item;\n\t\t\tconst metadata = {\n\t\t\t\trevision: item.rev,\n\t\t\t\ttimestamp: item.timestamp,\n\t\t\t};\n\t\t\tif (isValueRequiredState(item)) {\n\t\t\t\tconst itemValue = asDeeplyReadonlyDeserializedJson(item.value);\n\t\t\t\tconst updatedItem = {\n\t\t\t\t\tattendee,\n\t\t\t\t\tkey,\n\t\t\t\t\tvalue: itemValue,\n\t\t\t\t\tmetadata,\n\t\t\t\t} satisfies LatestMapItemUpdatedClientData<T, Keys, RawValueAccessor<T>>;\n\t\t\t\tpostUpdateActions.push(() => this.events.emit(\"remoteItemUpdated\", updatedItem));\n\t\t\t\tallUpdates.items.set(key, { value: itemValue, metadata });\n\t\t\t} else if (hadPriorValue !== undefined) {\n\t\t\t\tpostUpdateActions.push(() =>\n\t\t\t\t\tthis.events.emit(\"remoteItemRemoved\", {\n\t\t\t\t\t\tattendee,\n\t\t\t\t\t\tkey,\n\t\t\t\t\t\tmetadata,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tthis.datastore.update(this.key, attendeeId, currentState);\n\t\tpostUpdateActions.push(() => this.events.emit(\"remoteUpdated\", allUpdates));\n\t\treturn postUpdateActions;\n\t}\n}\n\n/**\n * Arguments that are passed to the {@link StateFactory.latestMap} function.\n *\n * @input\n * @beta\n */\nexport interface LatestMapArgumentsRaw<T, Keys extends string | number = string | number> {\n\t/**\n\t * The initial value of the local state.\n\t */\n\tlocal?: {\n\t\t[K in Keys]: JsonSerializable<T>;\n\t};\n\n\t/**\n\t * See {@link BroadcastControlSettings}.\n\t */\n\tsettings?: BroadcastControlSettings | undefined;\n}\n\n/**\n * Arguments that are passed to the {@link StateFactory.latestMap} function.\n *\n * @input\n * @beta\n */\nexport interface LatestMapArguments<T, Keys extends string | number = string | number>\n\textends LatestMapArgumentsRaw<T, Keys> {\n\t/**\n\t * An optional function that will be called at runtime to validate the presence data. A runtime validator is strongly\n\t * recommended. See {@link StateSchemaValidator}.\n\t */\n\tvalidator: StateSchemaValidator<T>;\n}\n\n// #region factory function overloads\n// Overloads should be ordered from most specific to least specific when combined.\n\n/**\n * Factory for creating a {@link LatestMapRaw} State object.\n *\n * @beta\n * @sealed\n */\nexport interface LatestMapFactory {\n\t/**\n\t * Factory for creating a {@link LatestMapRaw} State object.\n\t *\n\t * @privateRemarks (change to `remarks` when adding signature overload)\n\t * This overload is used when called with {@link LatestMapArgumentsRaw}.\n\t * That is, if a validator function is _not_ provided.\n\t */\n\t// eslint-disable-next-line @typescript-eslint/prefer-function-type -- interface to allow for clean overload evolution\n\t<T, Keys extends string | number = string | number, RegistrationKey extends string = string>(\n\t\targs?: LatestMapArgumentsRaw<T, Keys>,\n\t): InternalTypes.ManagerFactory<\n\t\tRegistrationKey,\n\t\tInternalTypes.MapValueState<T, Keys>,\n\t\tLatestMapRaw<T, Keys>\n\t>;\n}\n\n/**\n * Factory for creating a {@link LatestMap} or {@link LatestMapRaw} State object.\n */\nexport interface LatestMapFactoryInternal extends LatestMapFactory {\n\t/**\n\t * Factory for creating a {@link LatestMap} State object.\n\t *\n\t * @remarks\n\t * This overload is used when called with {@link LatestMapArguments}. That is, if a validator function is provided.\n\t */\n\t<T, Keys extends string | number = string | number, RegistrationKey extends string = string>(\n\t\targs: LatestMapArguments<T, Keys>,\n\t): InternalTypes.ManagerFactory<\n\t\tRegistrationKey,\n\t\tInternalTypes.MapValueState<T, Keys>,\n\t\tLatestMap<T, Keys>\n\t>;\n}\n\n// #endregion\n\n/**\n * Factory for creating a {@link LatestMap} or {@link LatestMapRaw} State object.\n */\nexport const latestMap: LatestMapFactoryInternal = <\n\tT,\n\tKeys extends string | number = string | number,\n\tRegistrationKey extends string = string,\n>(\n\targs?: Partial<LatestMapArguments<T, Keys>>,\n): InternalTypes.ManagerFactory<\n\tRegistrationKey,\n\tInternalTypes.MapValueState<T, Keys>,\n\tLatestMapRaw<T, Keys> & LatestMap<T, Keys>\n> => {\n\tconst settings = args?.settings;\n\tconst initialValues = args?.local;\n\tconst validator = args?.validator;\n\n\tif (validator !== undefined) {\n\t\tthrow new Error(`Validators are not yet implemented.`);\n\t}\n\n\tconst timestamp = Date.now();\n\tconst value: InternalTypes.MapValueState<\n\t\tT,\n\t\t// This should be `Keys`, but will only work if properties are optional.\n\t\tstring | number\n\t> = { rev: 0, items: {} };\n\t// LatestMapRaw takes ownership of values within initialValues.\n\tif (initialValues !== undefined) {\n\t\tfor (const key of objectKeys(initialValues)) {\n\t\t\tvalue.items[key] = {\n\t\t\t\trev: 0,\n\t\t\t\ttimestamp,\n\t\t\t\tvalue: toOpaqueJson(initialValues[key]),\n\t\t\t};\n\t\t}\n\t}\n\tconst factory = (\n\t\tkey: RegistrationKey,\n\t\tdatastoreHandle: InternalTypes.StateDatastoreHandle<\n\t\t\tRegistrationKey,\n\t\t\tInternalTypes.MapValueState<T, Keys>\n\t\t>,\n\t): {\n\t\tinitialData: { value: typeof value; allowableUpdateLatencyMs: number | undefined };\n\t\tmanager: InternalTypes.StateValue<LatestMapRaw<T, Keys> & LatestMap<T, Keys>>;\n\t} => ({\n\t\tinitialData: { value, allowableUpdateLatencyMs: settings?.allowableUpdateLatencyMs },\n\t\tmanager: brandIVM<\n\t\t\tLatestMapValueManagerImpl<T, RegistrationKey, Keys>,\n\t\t\tT,\n\t\t\tInternalTypes.MapValueState<T, Keys>\n\t\t>(\n\t\t\tnew LatestMapValueManagerImpl(\n\t\t\t\tkey,\n\t\t\t\tdatastoreFromHandle(datastoreHandle),\n\t\t\t\tvalue,\n\t\t\t\tsettings,\n\t\t\t),\n\t\t),\n\t});\n\treturn Object.assign(factory, { instanceBase: LatestMapValueManagerImpl });\n};\n"]}
1
+ {"version":3,"file":"latestMapValueManager.js","sourceRoot":"","sources":["../src/latestMapValueManager.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { createEmitter } from \"@fluid-internal/client-utils\";\nimport type { Listenable } from \"@fluidframework/core-interfaces\";\nimport type { IEmitter } from \"@fluidframework/core-interfaces/internal\";\nimport type {\n\tDeepReadonly,\n\tJsonDeserialized,\n\tJsonSerializable,\n} from \"@fluidframework/core-interfaces/internal/exposedUtilityTypes\";\n\nimport type { BroadcastControls, BroadcastControlSettings } from \"./broadcastControls.js\";\nimport { OptionalBroadcastControl } from \"./broadcastControls.js\";\nimport type { InternalTypes } from \"./exposedInternalTypes.js\";\nimport type {\n\tPostUpdateAction,\n\tValidatableOptionalState,\n\tValueManager,\n} from \"./internalTypes.js\";\nimport {\n\tasDeeplyReadonly,\n\tasDeeplyReadonlyDeserializedJson,\n\tisValueRequiredState,\n\tobjectEntries,\n\tobjectKeys,\n\ttoOpaqueJson,\n} from \"./internalUtils.js\";\nimport { createValidatedGetter } from \"./latestValueTypes.js\";\nimport type {\n\tLatestClientData,\n\tLatestData,\n\tLatestMetadata,\n\tProxiedValueAccessor,\n\tRawValueAccessor,\n\tStateSchemaValidator,\n\tValueAccessor,\n} from \"./latestValueTypes.js\";\nimport type { AttendeeId, Attendee, Presence, SpecificAttendee } from \"./presence.js\";\nimport { datastoreFromHandle, type StateDatastore } from \"./stateDatastore.js\";\nimport { brandIVM } from \"./valueManager.js\";\n\n/**\n * Collection of validatable optional values in a \"map\" structure.\n *\n * @remarks\n * Validatable equivalent of {@link InternalTypes.MapValueState}.\n */\ninterface ValidatableMapValueState<T, Keys extends string | number> {\n\trev: number;\n\titems: {\n\t\t// Caution: any particular item may or may not exist\n\t\t// Typescript does not support absent keys without forcing type to also be undefined.\n\t\t// See https://github.com/microsoft/TypeScript/issues/42810.\n\t\t[name in Keys]: ValidatableOptionalState<T>;\n\t};\n}\n\n/**\n * Collection of latest known values for a specific {@link Attendee}.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMapClientData<\n\tT,\n\tKeys extends string | number,\n\tTValueAccessor extends ValueAccessor<T>,\n\tSpecificAttendeeId extends AttendeeId = AttendeeId,\n> {\n\t/**\n\t * Associated {@link Attendee}.\n\t */\n\tattendee: Attendee<SpecificAttendeeId>;\n\n\t/**\n\t * Map of items for the state.\n\t *\n\t * @privateRemarks This could be regular map currently as no Map is\n\t * stored internally and a new instance is created for every request.\n\t */\n\titems: ReadonlyMap<Keys, LatestData<T, TValueAccessor>>;\n}\n\n/**\n * State of a single item value, its key, and its metadata.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMapItemUpdatedClientData<\n\tT,\n\tK extends string | number,\n\tTValueAccessor extends ValueAccessor<T>,\n> extends LatestClientData<T, TValueAccessor> {\n\t/**\n\t * Key of the updated item.\n\t */\n\tkey: K;\n}\n\n/**\n * Identifier and metadata for a removed item.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMapItemRemovedClientData<K extends string | number> {\n\t/**\n\t * Associated {@link Attendee}.\n\t */\n\tattendee: Attendee;\n\t/**\n\t * Key of the removed item.\n\t */\n\tkey: K;\n\t/**\n\t * Metadata associated with the removal of the item.\n\t */\n\tmetadata: LatestMetadata;\n}\n\n/**\n * Events from {@link LatestMapRaw}.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMapEvents<\n\tT,\n\tK extends string | number,\n\tTRemoteValueAccessor extends ValueAccessor<T> = ProxiedValueAccessor<T>,\n> {\n\t/**\n\t * Raised when any item's value for remote client is updated.\n\t * @param updates - Map of one or more values updated.\n\t *\n\t * @remarks The event does not include item removals.\n\t *\n\t * @eventProperty\n\t */\n\tremoteUpdated: (updates: LatestMapClientData<T, K, TRemoteValueAccessor>) => void;\n\n\t/**\n\t * Raised when specific item's value of remote client is updated.\n\t * @param updatedItem - Updated item value.\n\t *\n\t * @eventProperty\n\t */\n\tremoteItemUpdated: (\n\t\tupdatedItem: LatestMapItemUpdatedClientData<T, K, TRemoteValueAccessor>,\n\t) => void;\n\n\t/**\n\t * Raised when specific item of remote client is removed.\n\t * @param removedItem - Removed item.\n\t *\n\t * @eventProperty\n\t */\n\tremoteItemRemoved: (removedItem: LatestMapItemRemovedClientData<K>) => void;\n\n\t/**\n\t * Raised when specific local item's value is updated.\n\t * @param updatedItem - Updated item value.\n\t *\n\t * @eventProperty\n\t */\n\tlocalItemUpdated: (updatedItem: {\n\t\tvalue: DeepReadonly<JsonSerializable<T>>;\n\t\tkey: K;\n\t}) => void;\n\n\t/**\n\t * Raised when specific local item is removed.\n\t * @param removedItem - Removed item.\n\t *\n\t * @eventProperty\n\t */\n\tlocalItemRemoved: (removedItem: {\n\t\tkey: K;\n\t}) => void;\n}\n\n/**\n * Events from {@link LatestMapRaw}.\n *\n * @sealed\n * @beta\n */\nexport type LatestMapRawEvents<T, K extends string | number> = LatestMapEvents<\n\tT,\n\tK,\n\tRawValueAccessor<T>\n>;\n\n/**\n * Map of local client's values. Modifications are transmitted to all other connected clients.\n *\n * @sealed\n * @beta\n */\nexport interface StateMap<K extends string | number, V> {\n\t/**\n\t * ${@link StateMap.delete}s all elements in the StateMap.\n\t * @remarks This is not yet implemented.\n\t */\n\tclear(): void;\n\n\t/**\n\t * Removes the element with the specified key from the StateMap, if it exists.\n\t *\n\t * @returns true if an element in the StateMap existed and has been removed, or false if\n\t * the element does not exist.\n\t * @remarks No entry is fully removed. Instead an undefined placeholder is locally and\n\t * transmitted to all other clients. For better performance limit the number of deleted\n\t * entries and reuse keys when possible.\n\t * @privateRemarks In the future we may add a mechanism to remove the placeholder, at least\n\t * from transmissions after sufficient time has passed.\n\t */\n\tdelete(key: K): boolean;\n\n\t/**\n\t * Executes a provided function once per each key/value pair in the StateMap, in arbitrary order.\n\t */\n\tforEach(\n\t\tcallbackfn: (\n\t\t\tvalue: DeepReadonly<JsonDeserialized<V>>,\n\t\t\tkey: K,\n\t\t\tmap: StateMap<K, V>,\n\t\t) => void,\n\t\tthisArg?: unknown,\n\t): void;\n\n\t/**\n\t * Returns the element with the specified key from the StateMap, if it exists.\n\t *\n\t * @returns Returns the element associated with the specified key. If no element is associated with the specified key, undefined is returned.\n\t */\n\tget(key: K): DeepReadonly<JsonDeserialized<V>> | undefined;\n\n\t/**\n\t * Checks if an element with the specified key exists in the StateMap.\n\t * @returns boolean indicating whether an element with the specified key exists or not.\n\t */\n\thas(key: K): boolean;\n\n\t/**\n\t * Adds a new element with a specified key and value to the StateMap. If an element with the same key already exists, the element will be updated.\n\t * The value will be transmitted to all other connected clients.\n\t *\n\t * @remarks Manager assumes ownership of the value and its references.\n\t * Make a deep clone before setting, if needed. No comparison is done to detect changes; all\n\t * sets are transmitted.\n\t */\n\tset(key: K, value: JsonSerializable<V>): this;\n\n\t/**\n\t * The number of elements in the StateMap.\n\t */\n\treadonly size: number;\n\n\t/**\n\t * Returns an iterable of entries in the map.\n\t */\n\t// [Symbol.iterator](): IterableIterator<[K, DeepReadonly<JsonDeserialized<V>>]>;\n\n\t/**\n\t * Returns an iterable of key, value pairs for every entry in the map.\n\t */\n\t// entries(): IterableIterator<[K, DeepReadonly<JsonDeserialized<V>>]>;\n\n\t/**\n\t * Returns an iterable of keys in the map.\n\t */\n\tkeys(): IterableIterator<K>;\n\n\t/**\n\t * Returns an iterable of values in the map.\n\t */\n\t// values(): IterableIterator<DeepReadonly<JsonDeserialized<V>>>;\n}\n\nclass ValueMapImpl<T, K extends string | number> implements StateMap<K, T> {\n\tprivate countDefined: number;\n\tpublic constructor(\n\t\tprivate readonly value: InternalTypes.MapValueState<T, K>,\n\t\tprivate readonly emitter: IEmitter<\n\t\t\tPick<LatestMapEvents<T, K, ValueAccessor<T>>, \"localItemUpdated\" | \"localItemRemoved\">\n\t\t>,\n\t\tprivate readonly localUpdate: (\n\t\t\tupdates: InternalTypes.MapValueState<\n\t\t\t\tT,\n\t\t\t\t// This should be `K`, but will only work if properties are optional.\n\t\t\t\tstring | number\n\t\t\t>,\n\t\t) => void,\n\t) {\n\t\t// All initial items are expected to be defined.\n\t\t// TODO assert all defined and/or update type.\n\t\tthis.countDefined = Object.keys(value.items).length;\n\t}\n\n\t/**\n\t * Note: caller must ensure key exists in this.value.items.\n\t */\n\tprivate updateItem(key: K, value: InternalTypes.ValueOptionalState<T>[\"value\"]): void {\n\t\tthis.value.rev += 1;\n\t\t// Caller is required to ensure key exists.\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\tconst item = this.value.items[key]!;\n\t\titem.rev += 1;\n\t\titem.timestamp = Date.now();\n\t\tif (value === undefined) {\n\t\t\tdelete item.value;\n\t\t} else {\n\t\t\titem.value = value;\n\t\t}\n\t\tconst update = { rev: this.value.rev, items: { [key]: item } };\n\t\tthis.localUpdate(update);\n\t}\n\n\tpublic clear(): void {\n\t\tthrow new Error(\"Method not implemented.\");\n\t}\n\tpublic delete(key: K): boolean {\n\t\tconst { items } = this.value;\n\t\tconst hasKey = items[key]?.value !== undefined;\n\t\tif (hasKey) {\n\t\t\tthis.countDefined -= 1;\n\t\t\tthis.updateItem(key, undefined);\n\t\t\tthis.emitter.emit(\"localItemRemoved\", { key });\n\t\t}\n\t\treturn hasKey;\n\t}\n\tpublic forEach(\n\t\tcallbackfn: (\n\t\t\tvalue: DeepReadonly<JsonDeserialized<T>>,\n\t\t\tkey: K,\n\t\t\tmap: StateMap<K, T>,\n\t\t) => void,\n\t\tthisArg?: unknown,\n\t): void {\n\t\tfor (const [key, item] of objectEntries(this.value.items)) {\n\t\t\tif (item.value !== undefined) {\n\t\t\t\tcallbackfn(asDeeplyReadonlyDeserializedJson(item.value), key, this);\n\t\t\t}\n\t\t}\n\t}\n\tpublic get(key: K): DeepReadonly<JsonDeserialized<T>> | undefined {\n\t\treturn asDeeplyReadonlyDeserializedJson(this.value.items[key]?.value);\n\t}\n\tpublic has(key: K): boolean {\n\t\treturn this.value.items[key]?.value !== undefined;\n\t}\n\tpublic set(key: K, inValue: JsonSerializable<T>): this {\n\t\tconst value = toOpaqueJson<T>(inValue);\n\t\tif (!(key in this.value.items)) {\n\t\t\tthis.countDefined += 1;\n\t\t\tthis.value.items[key] = { rev: 0, timestamp: 0, value };\n\t\t}\n\t\tthis.updateItem(key, value);\n\t\tthis.emitter.emit(\"localItemUpdated\", { key, value: asDeeplyReadonly(inValue) });\n\t\treturn this;\n\t}\n\tpublic get size(): number {\n\t\treturn this.countDefined;\n\t}\n\tpublic keys(): IterableIterator<K> {\n\t\tconst keys: K[] = [];\n\t\tfor (const [key, item] of objectEntries(this.value.items)) {\n\t\t\tif (item.value !== undefined) {\n\t\t\t\tkeys.push(key);\n\t\t\t}\n\t\t}\n\t\treturn keys[Symbol.iterator]();\n\t}\n}\n\n/**\n * State that provides a `Map` of latest known values from this client to\n * others and read access to their values.\n * Entries in the map may vary over time and by client, but all values are expected to\n * be of the same type, which may be a union type.\n *\n * @remarks Create using {@link StateFactory.latestMap} registered to {@link StatesWorkspace}.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMap<\n\tT,\n\tKeys extends string | number = string | number,\n\tTRemoteAccessor extends ValueAccessor<T> = ProxiedValueAccessor<T>,\n> {\n\t/**\n\t * Containing {@link Presence}\n\t */\n\treadonly presence: Presence;\n\n\t/**\n\t * Events for LatestMap.\n\t */\n\treadonly events: Listenable<LatestMapEvents<T, Keys, TRemoteAccessor>>;\n\n\t/**\n\t * Controls for management of sending updates.\n\t */\n\treadonly controls: BroadcastControls;\n\n\t/**\n\t * Current value map for this client.\n\t */\n\treadonly local: StateMap<Keys, T>;\n\t/**\n\t * Iterable access to remote clients' map of values.\n\t */\n\tgetRemotes(): IterableIterator<LatestMapClientData<T, Keys, TRemoteAccessor>>;\n\t/**\n\t * Array of {@link Attendee}s that have provided states.\n\t */\n\tgetStateAttendees(): Attendee[];\n\t/**\n\t * Access to a specific client's map of values.\n\t */\n\tgetRemote(attendee: Attendee): ReadonlyMap<Keys, LatestData<T, TRemoteAccessor>>;\n}\n\n/**\n * State that provides a `Map` of latest known values from this client to\n * others and read access to their values.\n * Entries in the map may vary over time and by client, but all values are expected to\n * be of the same type, which may be a union type.\n *\n * @remarks Create using {@link StateFactory.latestMap} registered to {@link StatesWorkspace}.\n *\n * @sealed\n * @beta\n */\nexport type LatestMapRaw<T, Keys extends string | number = string | number> = LatestMap<\n\tT,\n\tKeys,\n\tRawValueAccessor<T>\n>;\n\nclass LatestMapValueManagerImpl<\n\tT,\n\tRegistrationKey extends string,\n\tKeys extends string | number = string | number,\n> implements\n\t\tLatestMapRaw<T, Keys>,\n\t\tLatestMap<T, Keys>,\n\t\tRequired<ValueManager<T, InternalTypes.MapValueState<T, Keys>>>\n{\n\tpublic readonly events = createEmitter<LatestMapEvents<T, Keys, ValueAccessor<T>>>();\n\tpublic readonly controls: OptionalBroadcastControl;\n\n\tpublic constructor(\n\t\tprivate readonly key: RegistrationKey,\n\t\tprivate readonly datastore: StateDatastore<\n\t\t\tRegistrationKey,\n\t\t\tInternalTypes.MapValueState<T, Keys>,\n\t\t\tValidatableMapValueState<T, Keys>\n\t\t>,\n\t\tpublic readonly value: InternalTypes.MapValueState<T, Keys>,\n\t\tcontrolSettings: BroadcastControlSettings | undefined,\n\t\tprivate readonly validator: StateSchemaValidator<T> | undefined,\n\t) {\n\t\tthis.controls = new OptionalBroadcastControl(controlSettings);\n\n\t\tthis.local = new ValueMapImpl<T, Keys>(\n\t\t\tvalue,\n\t\t\tthis.events,\n\t\t\t(updates: InternalTypes.MapValueState<T, Keys>) => {\n\t\t\t\tdatastore.localUpdate(key, updates, {\n\t\t\t\t\tallowableUpdateLatencyMs: this.controls.allowableUpdateLatencyMs,\n\t\t\t\t});\n\t\t\t},\n\t\t);\n\t}\n\n\tpublic get presence(): Presence {\n\t\treturn this.datastore.presence;\n\t}\n\n\tpublic readonly local: StateMap<Keys, T>;\n\n\tpublic *getRemotes(): IterableIterator<LatestMapClientData<T, Keys, ValueAccessor<T>>> {\n\t\tconst allKnownStates = this.datastore.knownValues(this.key);\n\t\tfor (const attendeeId of objectKeys(allKnownStates.states)) {\n\t\t\tif (attendeeId !== allKnownStates.self) {\n\t\t\t\tconst attendee = this.datastore.presence.attendees.getAttendee(attendeeId);\n\t\t\t\tconst items = this.getRemote(attendee);\n\t\t\t\tyield { attendee, items };\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic getStateAttendees(): Attendee[] {\n\t\tconst allKnownStates = this.datastore.knownValues(this.key);\n\t\treturn objectKeys(allKnownStates.states)\n\t\t\t.filter((attendeeId) => attendeeId !== allKnownStates.self)\n\t\t\t.map((attendeeId) => this.datastore.presence.attendees.getAttendee(attendeeId));\n\t}\n\n\tpublic getRemote(attendee: Attendee): ReadonlyMap<Keys, LatestData<T, ValueAccessor<T>>> {\n\t\tconst validator = this.validator;\n\t\tconst allKnownStates = this.datastore.knownValues(this.key);\n\t\tconst attendeeId = attendee.attendeeId;\n\t\tconst clientStateMap = allKnownStates.states[attendeeId];\n\t\tif (clientStateMap === undefined) {\n\t\t\tthrow new Error(\"No entry for attendee\");\n\t\t}\n\t\tconst items = new Map<Keys, LatestData<T, ValueAccessor<T>>>();\n\t\tfor (const [key, item] of objectEntries(clientStateMap.items)) {\n\t\t\tif (isValueRequiredState(item)) {\n\t\t\t\titems.set(key, {\n\t\t\t\t\tvalue: createValidatedGetter(item, validator),\n\t\t\t\t\tmetadata: { revision: item.rev, timestamp: item.timestamp },\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn items;\n\t}\n\n\tpublic update<SpecificAttendeeId extends AttendeeId>(\n\t\tattendee: SpecificAttendee<SpecificAttendeeId>,\n\t\t_received: number,\n\t\tvalue: InternalTypes.MapValueState<T, string | number>,\n\t): PostUpdateAction[] {\n\t\tconst allKnownStates = this.datastore.knownValues(this.key);\n\t\tconst attendeeId: SpecificAttendeeId = attendee.attendeeId;\n\t\tconst currentState = (allKnownStates.states[attendeeId] ??=\n\t\t\t// New attendee - prepare new attendee state directory\n\t\t\t{\n\t\t\t\trev: value.rev,\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- items entries can't be optional per https://github.com/microsoft/TypeScript/issues/42810; so forced cast\n\t\t\t\titems: {} as ValidatableMapValueState<T, Keys>[\"items\"],\n\t\t\t});\n\t\t// Accumulate individual update keys\n\t\tconst updatedItemKeys: Keys[] = [];\n\t\tfor (const [key, item] of objectEntries(value.items)) {\n\t\t\t// TODO: Key validation needs to be added here.\n\t\t\tconst validKey = key as Keys;\n\t\t\tif (!(key in currentState.items) || currentState.items[validKey].rev < item.rev) {\n\t\t\t\tupdatedItemKeys.push(validKey);\n\t\t\t}\n\t\t}\n\n\t\tif (updatedItemKeys.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\t// Store updates\n\t\tif (value.rev > currentState.rev) {\n\t\t\tcurrentState.rev = value.rev;\n\t\t}\n\t\tconst allUpdates = {\n\t\t\tattendee,\n\t\t\titems: new Map<Keys, LatestData<T, ValueAccessor<T>>>(),\n\t\t};\n\t\tconst postUpdateActions: PostUpdateAction[] = [];\n\t\tfor (const key of updatedItemKeys) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tconst item = value.items[key]!;\n\t\t\tconst hadPriorValue = currentState.items[key]?.value;\n\t\t\tcurrentState.items[key] = item;\n\t\t\tconst metadata = {\n\t\t\t\trevision: item.rev,\n\t\t\t\ttimestamp: item.timestamp,\n\t\t\t};\n\t\t\tif (isValueRequiredState(item)) {\n\t\t\t\tconst updatedItem = {\n\t\t\t\t\tattendee,\n\t\t\t\t\tkey,\n\t\t\t\t\tvalue: createValidatedGetter(item, this.validator),\n\t\t\t\t\tmetadata,\n\t\t\t\t} satisfies LatestMapItemUpdatedClientData<T, Keys, ValueAccessor<T>>;\n\t\t\t\tpostUpdateActions.push(() => this.events.emit(\"remoteItemUpdated\", updatedItem));\n\t\t\t\tallUpdates.items.set(key, {\n\t\t\t\t\tvalue: updatedItem.value,\n\t\t\t\t\tmetadata,\n\t\t\t\t});\n\t\t\t} else if (hadPriorValue !== undefined) {\n\t\t\t\tpostUpdateActions.push(() =>\n\t\t\t\t\tthis.events.emit(\"remoteItemRemoved\", {\n\t\t\t\t\t\tattendee,\n\t\t\t\t\t\tkey,\n\t\t\t\t\t\tmetadata,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tthis.datastore.update(this.key, attendeeId, currentState);\n\t\tpostUpdateActions.push(() => this.events.emit(\"remoteUpdated\", allUpdates));\n\t\treturn postUpdateActions;\n\t}\n}\n\n/**\n * Arguments that are passed to the {@link StateFactory.latestMap} function.\n *\n * @input\n * @beta\n */\nexport interface LatestMapArgumentsRaw<T, Keys extends string | number = string | number> {\n\t/**\n\t * The initial value of the local state.\n\t */\n\tlocal?: {\n\t\t[K in Keys]: JsonSerializable<T>;\n\t};\n\n\t/**\n\t * See {@link BroadcastControlSettings}.\n\t */\n\tsettings?: BroadcastControlSettings | undefined;\n}\n\n/**\n * Arguments that are passed to the {@link StateFactory.latestMap} function.\n *\n * @input\n * @beta\n */\nexport interface LatestMapArguments<T, Keys extends string | number = string | number>\n\textends LatestMapArgumentsRaw<T, Keys> {\n\t/**\n\t * An optional function that will be called at runtime to validate the presence data. A runtime validator is strongly\n\t * recommended. See {@link StateSchemaValidator}.\n\t */\n\tvalidator: StateSchemaValidator<T>;\n}\n\n// #region factory function overloads\n// Overloads should be ordered from most specific to least specific when combined.\n\n/**\n * Factory for creating a {@link LatestMap} or {@link LatestMapRaw} State object.\n *\n * @beta\n * @sealed\n */\nexport interface LatestMapFactory {\n\t/**\n\t * Factory for creating a {@link LatestMap} State object.\n\t *\n\t * @remarks\n\t * This overload is used when called with {@link LatestMapArguments}.\n\t * That is, if a validator function is provided.\n\t */\n\t<T, Keys extends string | number = string | number, RegistrationKey extends string = string>(\n\t\targs: LatestMapArguments<T, Keys>,\n\t): InternalTypes.ManagerFactory<\n\t\tRegistrationKey,\n\t\tInternalTypes.MapValueState<T, Keys>,\n\t\tLatestMap<T, Keys>\n\t>;\n\n\t/**\n\t * Factory for creating a {@link LatestMapRaw} State object.\n\t *\n\t * @remarks\n\t * This overload is used when called with {@link LatestMapArgumentsRaw}.\n\t * That is, if a validator function is _not_ provided.\n\t */\n\t<T, Keys extends string | number = string | number, RegistrationKey extends string = string>(\n\t\targs?: LatestMapArgumentsRaw<T, Keys>,\n\t): InternalTypes.ManagerFactory<\n\t\tRegistrationKey,\n\t\tInternalTypes.MapValueState<T, Keys>,\n\t\tLatestMapRaw<T, Keys>\n\t>;\n}\n\n// #endregion\n\n/**\n * Factory for creating a {@link LatestMap} or {@link LatestMapRaw} State object.\n */\nexport const latestMap: LatestMapFactory = <\n\tT,\n\tKeys extends string | number = string | number,\n\tRegistrationKey extends string = string,\n>(\n\targs?: Partial<LatestMapArguments<T, Keys>>,\n): InternalTypes.ManagerFactory<\n\tRegistrationKey,\n\tInternalTypes.MapValueState<T, Keys>,\n\tLatestMapRaw<T, Keys> & LatestMap<T, Keys>\n> => {\n\tconst settings = args?.settings;\n\tconst initialValues = args?.local;\n\tconst validator = args?.validator;\n\n\tconst timestamp = Date.now();\n\tconst value: InternalTypes.MapValueState<\n\t\tT,\n\t\t// This should be `Keys`, but will only work if properties are optional.\n\t\tstring | number\n\t> = { rev: 0, items: {} };\n\t// LatestMapRaw takes ownership of values within initialValues.\n\tif (initialValues !== undefined) {\n\t\tfor (const key of objectKeys(initialValues)) {\n\t\t\tvalue.items[key] = {\n\t\t\t\trev: 0,\n\t\t\t\ttimestamp,\n\t\t\t\tvalue: toOpaqueJson(initialValues[key]),\n\t\t\t};\n\t\t}\n\t}\n\tconst factory = (\n\t\tkey: RegistrationKey,\n\t\tdatastoreHandle: InternalTypes.StateDatastoreHandle<\n\t\t\tRegistrationKey,\n\t\t\tInternalTypes.MapValueState<T, Keys>\n\t\t>,\n\t): {\n\t\tinitialData: { value: typeof value; allowableUpdateLatencyMs: number | undefined };\n\t\tmanager: InternalTypes.StateValue<LatestMapRaw<T, Keys> & LatestMap<T, Keys>>;\n\t} => ({\n\t\tinitialData: { value, allowableUpdateLatencyMs: settings?.allowableUpdateLatencyMs },\n\t\tmanager: brandIVM<\n\t\t\tLatestMapValueManagerImpl<T, RegistrationKey, Keys>,\n\t\t\tT,\n\t\t\tInternalTypes.MapValueState<T, Keys>\n\t\t>(\n\t\t\tnew LatestMapValueManagerImpl(\n\t\t\t\tkey,\n\t\t\t\tdatastoreFromHandle(datastoreHandle),\n\t\t\t\tvalue,\n\t\t\t\tsettings,\n\t\t\t\tvalidator,\n\t\t\t),\n\t\t),\n\t});\n\treturn Object.assign(factory, { instanceBase: LatestMapValueManagerImpl });\n};\n"]}
@@ -2,15 +2,6 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import type { LatestMapFactory } from "./latestMapValueManager.js";
6
- import type { LatestFactory } from "./latestValueManager.js";
7
- /**
8
- * Factory for creating presence State objects.
9
- */
10
- export declare const StateFactoryInternal: {
11
- latest: LatestFactory;
12
- latestMap: import("./latestMapValueManager.js").LatestMapFactoryInternal;
13
- };
14
5
  /**
15
6
  * Factory for creating presence State objects.
16
7
  *
@@ -21,7 +12,7 @@ export declare const StateFactoryInternal: {
21
12
  * @beta
22
13
  */
23
14
  export declare const StateFactory: {
24
- latest: LatestFactory;
25
- latestMap: LatestMapFactory;
15
+ latest: import("./latestValueManager.js").LatestFactory;
16
+ latestMap: import("./latestMapValueManager.js").LatestMapFactory;
26
17
  };
27
18
  //# sourceMappingURL=stateFactory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stateFactory.d.ts","sourceRoot":"","sources":["../src/stateFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAG7D;;GAEG;AACH,eAAO,MAAM,oBAAoB;;;CAGhC,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,EAAE;IAC1B,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,EAAE,gBAAgB,CAAC;CACL,CAAC"}
1
+ {"version":3,"file":"stateFactory.d.ts","sourceRoot":"","sources":["../src/stateFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY;;;CAGxB,CAAC"}
@@ -4,13 +4,6 @@
4
4
  */
5
5
  import { latestMap } from "./latestMapValueManager.js";
6
6
  import { latest } from "./latestValueManager.js";
7
- /**
8
- * Factory for creating presence State objects.
9
- */
10
- export const StateFactoryInternal = {
11
- latest,
12
- latestMap,
13
- };
14
7
  /**
15
8
  * Factory for creating presence State objects.
16
9
  *
@@ -20,5 +13,8 @@ export const StateFactoryInternal = {
20
13
  *
21
14
  * @beta
22
15
  */
23
- export const StateFactory = StateFactoryInternal;
16
+ export const StateFactory = {
17
+ latest,
18
+ latestMap,
19
+ };
24
20
  //# sourceMappingURL=stateFactory.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"stateFactory.js","sourceRoot":"","sources":["../src/stateFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAEvD,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEjD;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;IACnC,MAAM;IACN,SAAS;CACT,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,YAAY,GAGrB,oBAAoB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { LatestMapFactory } from \"./latestMapValueManager.js\";\nimport { latestMap } from \"./latestMapValueManager.js\";\nimport type { LatestFactory } from \"./latestValueManager.js\";\nimport { latest } from \"./latestValueManager.js\";\n\n/**\n * Factory for creating presence State objects.\n */\nexport const StateFactoryInternal = {\n\tlatest,\n\tlatestMap,\n};\n\n/**\n * Factory for creating presence State objects.\n *\n * @remarks\n * Use `latest` to create a {@link LatestRaw} State object.\n * Use `latestMap` to create a {@link LatestMapRaw} State object.\n *\n * @beta\n */\nexport const StateFactory: {\n\tlatest: LatestFactory;\n\tlatestMap: LatestMapFactory;\n} = StateFactoryInternal;\n"]}
1
+ {"version":3,"file":"stateFactory.js","sourceRoot":"","sources":["../src/stateFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEjD;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC3B,MAAM;IACN,SAAS;CACT,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { latestMap } from \"./latestMapValueManager.js\";\nimport { latest } from \"./latestValueManager.js\";\n\n/**\n * Factory for creating presence State objects.\n *\n * @remarks\n * Use `latest` to create a {@link LatestRaw} State object.\n * Use `latestMap` to create a {@link LatestMapRaw} State object.\n *\n * @beta\n */\nexport const StateFactory = {\n\tlatest,\n\tlatestMap,\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/presence",
3
- "version": "2.52.0",
3
+ "version": "2.53.0-350190",
4
4
  "description": "A component for lightweight data sharing within a single session",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -63,19 +63,19 @@
63
63
  "temp-directory": "nyc/.nyc_output"
64
64
  },
65
65
  "dependencies": {
66
- "@fluid-internal/client-utils": "~2.52.0",
67
- "@fluidframework/container-definitions": "~2.52.0",
68
- "@fluidframework/container-runtime-definitions": "~2.52.0",
69
- "@fluidframework/core-interfaces": "~2.52.0",
70
- "@fluidframework/core-utils": "~2.52.0",
71
- "@fluidframework/datastore": "~2.52.0",
72
- "@fluidframework/datastore-definitions": "~2.52.0",
73
- "@fluidframework/fluid-static": "~2.52.0",
74
- "@fluidframework/id-compressor": "~2.52.0",
75
- "@fluidframework/runtime-definitions": "~2.52.0",
76
- "@fluidframework/runtime-utils": "~2.52.0",
77
- "@fluidframework/shared-object-base": "~2.52.0",
78
- "@fluidframework/telemetry-utils": "~2.52.0"
66
+ "@fluid-internal/client-utils": "2.53.0-350190",
67
+ "@fluidframework/container-definitions": "2.53.0-350190",
68
+ "@fluidframework/container-runtime-definitions": "2.53.0-350190",
69
+ "@fluidframework/core-interfaces": "2.53.0-350190",
70
+ "@fluidframework/core-utils": "2.53.0-350190",
71
+ "@fluidframework/datastore": "2.53.0-350190",
72
+ "@fluidframework/datastore-definitions": "2.53.0-350190",
73
+ "@fluidframework/fluid-static": "2.53.0-350190",
74
+ "@fluidframework/id-compressor": "2.53.0-350190",
75
+ "@fluidframework/runtime-definitions": "2.53.0-350190",
76
+ "@fluidframework/runtime-utils": "2.53.0-350190",
77
+ "@fluidframework/shared-object-base": "2.53.0-350190",
78
+ "@fluidframework/telemetry-utils": "2.53.0-350190"
79
79
  },
80
80
  "devDependencies": {
81
81
  "@arethetypeswrong/cli": "^0.17.1",
@@ -83,10 +83,10 @@
83
83
  "@fluid-tools/build-cli": "^0.57.0",
84
84
  "@fluidframework/build-common": "^2.0.3",
85
85
  "@fluidframework/build-tools": "^0.57.0",
86
- "@fluidframework/driver-definitions": "~2.52.0",
86
+ "@fluidframework/driver-definitions": "2.53.0-350190",
87
87
  "@fluidframework/eslint-config-fluid": "^5.7.4",
88
- "@fluidframework/test-runtime-utils": "~2.52.0",
89
- "@fluidframework/test-utils": "~2.52.0",
88
+ "@fluidframework/test-runtime-utils": "2.53.0-350190",
89
+ "@fluidframework/test-utils": "2.53.0-350190",
90
90
  "@microsoft/api-extractor": "7.52.8",
91
91
  "@types/mocha": "^10.0.10",
92
92
  "@types/node": "^18.19.0",