@fluidframework/presence 2.51.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 +220 -10
- package/dist/alpha.d.ts +1 -0
- package/dist/beta.d.ts +1 -0
- package/dist/datastorePresenceManagerFactory.d.ts.map +1 -1
- package/dist/datastorePresenceManagerFactory.js +2 -2
- package/dist/datastorePresenceManagerFactory.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/latestMapValueManager.d.ts +11 -15
- package/dist/latestMapValueManager.d.ts.map +1 -1
- package/dist/latestMapValueManager.js +11 -9
- package/dist/latestMapValueManager.js.map +1 -1
- package/dist/presenceDatastoreManager.d.ts.map +1 -1
- package/dist/presenceDatastoreManager.js +5 -4
- package/dist/presenceDatastoreManager.js.map +1 -1
- package/dist/presenceManager.d.ts.map +1 -1
- package/dist/presenceManager.js +7 -5
- package/dist/presenceManager.js.map +1 -1
- package/dist/stateFactory.d.ts +2 -11
- package/dist/stateFactory.d.ts.map +1 -1
- package/dist/stateFactory.js +5 -9
- package/dist/stateFactory.js.map +1 -1
- package/lib/alpha.d.ts +1 -0
- package/lib/beta.d.ts +1 -0
- package/lib/datastorePresenceManagerFactory.d.ts.map +1 -1
- package/lib/datastorePresenceManagerFactory.js +2 -2
- package/lib/datastorePresenceManagerFactory.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/latestMapValueManager.d.ts +11 -15
- package/lib/latestMapValueManager.d.ts.map +1 -1
- package/lib/latestMapValueManager.js +11 -9
- package/lib/latestMapValueManager.js.map +1 -1
- package/lib/presenceDatastoreManager.d.ts.map +1 -1
- package/lib/presenceDatastoreManager.js +5 -4
- package/lib/presenceDatastoreManager.js.map +1 -1
- package/lib/presenceManager.d.ts.map +1 -1
- package/lib/presenceManager.js +7 -5
- package/lib/presenceManager.js.map +1 -1
- package/lib/stateFactory.d.ts +2 -11
- package/lib/stateFactory.d.ts.map +1 -1
- package/lib/stateFactory.js +4 -8
- package/lib/stateFactory.js.map +1 -1
- package/package.json +19 -19
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
|
|
71
|
+
A `NotificationsWorkspace` is similar to `StatesWorkspace`, but is dedicated to notification use-cases via `NotificationsManager`.
|
|
72
72
|
|
|
73
|
-
###
|
|
73
|
+
### State objects
|
|
74
74
|
|
|
75
|
-
#### Latest
|
|
75
|
+
#### Latest, LatestRaw
|
|
76
76
|
|
|
77
|
-
`Latest`
|
|
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`
|
|
82
|
-
key may be set to `undefined` to represent deletion.
|
|
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
|
-
|
|
105
|
-
|
|
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](#
|
|
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
package/dist/beta.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"datastorePresenceManagerFactory.d.ts","sourceRoot":"","sources":["../src/datastorePresenceManagerFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAGtE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAG3E,OAAO,KAAK,EAAE,yBAAyB,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"datastorePresenceManagerFactory.d.ts","sourceRoot":"","sources":["../src/datastorePresenceManagerFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAGtE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAG3E,OAAO,KAAK,EAAE,yBAAyB,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AAqE3E;;;;;;;;;GASG;AACH,MAAM,CAAC,OAAO,OAAO,sBAAsB;IAC1C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAyB;CAC/C;AAED;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B,2DAGtC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,wBAAwB,CAAC,aAAa,EAAE,sBAAsB,GAAG,QAAQ,CAMxF"}
|
|
@@ -30,10 +30,10 @@ class PresenceManagerDataObject extends datastoreSupport_js_1.LoadableFluidObjec
|
|
|
30
30
|
// Signals) is readily detectable here and use that presence manager directly.
|
|
31
31
|
const runtime = this.runtime;
|
|
32
32
|
const events = (0, client_utils_1.createEmitter)();
|
|
33
|
-
runtime.on("connected", (clientId) => events.emit("
|
|
33
|
+
runtime.on("connected", (clientId) => events.emit("joined", { clientId, canWrite: true }));
|
|
34
34
|
runtime.on("disconnected", () => events.emit("disconnected"));
|
|
35
35
|
const manager = (0, presenceManager_js_1.createPresenceManager)({
|
|
36
|
-
|
|
36
|
+
getJoinedStatus: () => (runtime.connected ? "joinedForWriting" : "disconnected"),
|
|
37
37
|
getClientId: () => runtime.clientId,
|
|
38
38
|
events,
|
|
39
39
|
getQuorum: runtime.getQuorum.bind(runtime),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"datastorePresenceManagerFactory.js","sourceRoot":"","sources":["../src/datastorePresenceManagerFactory.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH;;GAEG;AAEH,+DAA6D;AAM7D,kEAA6D;AAI7D,+DAAmF;AAEnF,6DAA6D;AAG7D;;GAEG;AACH,SAAS,0BAA0B,CAClC,OAA2E;IAE3E,IAAA,iBAAM,EAAC,OAAO,CAAC,QAAQ,KAAK,IAAI,EAAE,KAAK,CAAC,kCAAkC,CAAC,CAAC;IAC5E,8DAA8D;IAC9D,gFAAgF;AACjF,CAAC;AAED;;GAEG;AACH,MAAM,yBAA0B,SAAQ,yCAAmB;IAKnD,eAAe;QACrB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC5B,+EAA+E;YAC/E,8EAA8E;YAC9E,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;YAC7B,MAAM,MAAM,GAAG,IAAA,4BAAa,GAAuB,CAAC;YACpD,OAAO,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,EAAE,
|
|
1
|
+
{"version":3,"file":"datastorePresenceManagerFactory.js","sourceRoot":"","sources":["../src/datastorePresenceManagerFactory.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH;;GAEG;AAEH,+DAA6D;AAM7D,kEAA6D;AAI7D,+DAAmF;AAEnF,6DAA6D;AAG7D;;GAEG;AACH,SAAS,0BAA0B,CAClC,OAA2E;IAE3E,IAAA,iBAAM,EAAC,OAAO,CAAC,QAAQ,KAAK,IAAI,EAAE,KAAK,CAAC,kCAAkC,CAAC,CAAC;IAC5E,8DAA8D;IAC9D,gFAAgF;AACjF,CAAC;AAED;;GAEG;AACH,MAAM,yBAA0B,SAAQ,yCAAmB;IAKnD,eAAe;QACrB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC5B,+EAA+E;YAC/E,8EAA8E;YAC9E,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;YAC7B,MAAM,MAAM,GAAG,IAAA,4BAAa,GAAuB,CAAC;YACpD,OAAO,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,EAAE,CACpC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CACnD,CAAC;YACF,OAAO,CAAC,EAAE,CAAC,cAAc,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;YAE9D,MAAM,OAAO,GAAG,IAAA,0CAAqB,EAAC;gBACrC,eAAe,EAAE,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,cAAc,CAAC;gBAChF,WAAW,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,QAAQ;gBACnC,MAAM;gBACN,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC;gBAC1C,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC;gBAC9C,YAAY,EAAE,CAAC,OAAgC,EAAE,EAAE,CAClD,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC;gBAC5E,iBAAiB,EAChB,IAAI,GAAG,EAAE,CAAC,gFAAgF;aAC3F,CAAC,CAAC;YACH,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,OAA8B,EAAE,KAAc,EAAE,EAAE;gBAC5E,0BAA0B,CAAC,OAAO,CAAC,CAAC;gBACpC,OAAO,CAAC,aAAa,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;YAC3C,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC;QACjC,CAAC;QACD,OAAO,IAAI,CAAC,gBAAgB,CAAC;IAC9B,CAAC;CACD;AAED;;GAEG;AACH,MAAM,sBAAsB;IAA5B;QAKiB,YAAO,GAAG,IAAI,2CAAqB,CAClD,0BAA0B,EAC1B,yBAAyB,CACzB,CAAC;IACH,CAAC;IARO,EAAE,CAAC,KAA8C;QACvD,OAAO,KAAK,YAAY,yBAAyB,CAAC;IACnD,CAAC;CAMD;AAgBD;;;;;;GAMG;AACU,QAAA,2BAA2B,GACvC,IAAI,sBAAsB,EAEzB,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,SAAgB,wBAAwB,CAAC,aAAqC;IAC7E,IAAI,aAAa,YAAY,yBAAyB,EAAE,CAAC;QACxD,OAAO,aAAa,CAAC,eAAe,EAAE,CAAC;IACxC,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,qEAAqE,CAAC,CAAC;AACxF,CAAC;AAND,4DAMC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/*\n * Hacky support for internal datastore based usages.\n */\n\nimport { createEmitter } from \"@fluid-internal/client-utils\";\nimport type {\n\tExtensionHostEvents,\n\tRawInboundExtensionMessage,\n} from \"@fluidframework/container-runtime-definitions/internal\";\nimport type { IFluidLoadable } from \"@fluidframework/core-interfaces\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport type { IInboundSignalMessage } from \"@fluidframework/runtime-definitions/internal\";\nimport type { SharedObjectKind } from \"@fluidframework/shared-object-base\";\n\nimport { BasicDataStoreFactory, LoadableFluidObject } from \"./datastoreSupport.js\";\nimport type { PresenceWithNotifications as Presence } from \"./presence.js\";\nimport { createPresenceManager } from \"./presenceManager.js\";\nimport type { OutboundPresenceMessage, SignalMessages } from \"./protocol.js\";\n\n/**\n * This provides faux validation of the signal message.\n */\nfunction assertSignalMessageIsValid(\n\tmessage: IInboundSignalMessage | RawInboundExtensionMessage<SignalMessages>,\n): asserts message is RawInboundExtensionMessage<SignalMessages> {\n\tassert(message.clientId !== null, 0xa58 /* Signal must have a client ID */);\n\t// The other difference between messages is that `content` for\n\t// RawInboundExtensionMessage is JsonDeserialized and we are fine assuming that.\n}\n\n/**\n * Simple FluidObject holding Presence Manager.\n */\nclass PresenceManagerDataObject extends LoadableFluidObject {\n\t// Creation of presence manager is deferred until first acquisition to avoid\n\t// instantiations and stand-up by Summarizer that has no actual use.\n\tprivate _presenceManager: Presence | undefined;\n\n\tpublic presenceManager(): Presence {\n\t\tif (!this._presenceManager) {\n\t\t\t// TODO: investigate if ContainerExtensionStore (path-based address routing for\n\t\t\t// Signals) is readily detectable here and use that presence manager directly.\n\t\t\tconst runtime = this.runtime;\n\t\t\tconst events = createEmitter<ExtensionHostEvents>();\n\t\t\truntime.on(\"connected\", (clientId) =>\n\t\t\t\tevents.emit(\"joined\", { clientId, canWrite: true }),\n\t\t\t);\n\t\t\truntime.on(\"disconnected\", () => events.emit(\"disconnected\"));\n\n\t\t\tconst manager = createPresenceManager({\n\t\t\t\tgetJoinedStatus: () => (runtime.connected ? \"joinedForWriting\" : \"disconnected\"),\n\t\t\t\tgetClientId: () => runtime.clientId,\n\t\t\t\tevents,\n\t\t\t\tgetQuorum: runtime.getQuorum.bind(runtime),\n\t\t\t\tgetAudience: runtime.getAudience.bind(runtime),\n\t\t\t\tsubmitSignal: (message: OutboundPresenceMessage) =>\n\t\t\t\t\truntime.submitSignal(message.type, message.content, message.targetClientId),\n\t\t\t\tsupportedFeatures:\n\t\t\t\t\tnew Set() /* We do not implement feature detection here since this is a deprecated path */,\n\t\t\t});\n\t\t\tthis.runtime.on(\"signal\", (message: IInboundSignalMessage, local: boolean) => {\n\t\t\t\tassertSignalMessageIsValid(message);\n\t\t\t\tmanager.processSignal([], message, local);\n\t\t\t});\n\t\t\tthis._presenceManager = manager;\n\t\t}\n\t\treturn this._presenceManager;\n\t}\n}\n\n/**\n * Factory class to create {@link Presence} in own data store.\n */\nclass PresenceManagerFactory {\n\tpublic is(value: IFluidLoadable | ExperimentalPresenceDO): value is ExperimentalPresenceDO {\n\t\treturn value instanceof PresenceManagerDataObject;\n\t}\n\n\tpublic readonly factory = new BasicDataStoreFactory(\n\t\t\"@fluidframework/presence\",\n\t\tPresenceManagerDataObject,\n\t);\n}\n\n/**\n * Brand for Experimental Presence Data Object.\n *\n * @remarks\n * See {@link getPresenceViaDataObject} for example usage.\n *\n * @deprecated Use {@link getPresence} instead.\n * @sealed\n * @alpha\n */\nexport declare class ExperimentalPresenceDO {\n\tprivate readonly _self: ExperimentalPresenceDO;\n}\n\n/**\n * DataStore based Presence Manager that is used as fallback for preferred Container\n * Extension based version requires registration. Export SharedObjectKind for registration.\n *\n * @deprecated Use {@link getPresence} instead.\n * @alpha\n */\nexport const ExperimentalPresenceManager =\n\tnew PresenceManagerFactory() as unknown as SharedObjectKind<\n\t\tIFluidLoadable & ExperimentalPresenceDO\n\t>;\n\n/**\n * Acquire Presence from a DataStore based Presence Manager\n *\n * @example\n * ```typescript\n * const containerSchema = {\n * \tinitialObjects: {\n * \t\texperimentalPresence: ExperimentalPresenceDO,\n * \t},\n * } satisfies ContainerSchema;\n * ```\n * then\n * ```typescript\n * const presence = getPresenceViaDataObject(\n * \tcontainer.initialObjects.experimentalPresence,\n * \t);\n * ```\n *\n * @deprecated Use {@link getPresence} instead.\n * @alpha\n */\nexport function getPresenceViaDataObject(fluidLoadable: ExperimentalPresenceDO): Presence {\n\tif (fluidLoadable instanceof PresenceManagerDataObject) {\n\t\treturn fluidLoadable.presenceManager();\n\t}\n\n\tthrow new Error(\"Incompatible loadable; make sure to use ExperimentalPresenceManager\");\n}\n"]}
|
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";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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,
|
|
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\
|
|
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
|
|
274
|
+
* Factory for creating a {@link LatestMap} State object.
|
|
275
275
|
*
|
|
276
|
-
* @
|
|
277
|
-
* This overload is used when called with {@link
|
|
278
|
-
* That is, if a validator function is
|
|
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
|
|
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
|
|
282
|
+
* Factory for creating a {@link LatestMapRaw} State object.
|
|
288
283
|
*
|
|
289
284
|
* @remarks
|
|
290
|
-
* This overload is used when called with {@link
|
|
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
|
|
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:
|
|
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;
|
|
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,
|
|
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:
|
|
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, {
|
|
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
|
};
|