@fluidframework/presence 2.41.0-338401 → 2.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (209) hide show
  1. package/README.md +6 -10
  2. package/dist/alpha.d.ts +18 -14
  3. package/dist/baseTypes.d.ts +1 -1
  4. package/dist/baseTypes.js.map +1 -1
  5. package/dist/beta.d.ts +53 -0
  6. package/dist/broadcastControls.d.ts +4 -5
  7. package/dist/broadcastControls.d.ts.map +1 -1
  8. package/dist/broadcastControls.js +2 -3
  9. package/dist/broadcastControls.js.map +1 -1
  10. package/dist/datastorePresenceManagerFactory.d.ts +4 -1
  11. package/dist/datastorePresenceManagerFactory.d.ts.map +1 -1
  12. package/dist/datastorePresenceManagerFactory.js +24 -3
  13. package/dist/datastorePresenceManagerFactory.js.map +1 -1
  14. package/dist/datastoreSupport.d.ts +7 -2
  15. package/dist/datastoreSupport.d.ts.map +1 -1
  16. package/dist/datastoreSupport.js +6 -4
  17. package/dist/datastoreSupport.js.map +1 -1
  18. package/dist/experimentalAccess.d.ts +12 -4
  19. package/dist/experimentalAccess.d.ts.map +1 -1
  20. package/dist/experimentalAccess.js +24 -17
  21. package/dist/experimentalAccess.js.map +1 -1
  22. package/dist/exposedInternalTypes.d.ts +23 -5
  23. package/dist/exposedInternalTypes.d.ts.map +1 -1
  24. package/dist/exposedInternalTypes.js +1 -1
  25. package/dist/exposedInternalTypes.js.map +1 -1
  26. package/dist/exposedUtilityTypes.d.ts +6 -5
  27. package/dist/exposedUtilityTypes.d.ts.map +1 -1
  28. package/dist/exposedUtilityTypes.js.map +1 -1
  29. package/dist/index.d.ts +2 -2
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +2 -1
  32. package/dist/index.js.map +1 -1
  33. package/dist/internalTypes.d.ts +32 -11
  34. package/dist/internalTypes.d.ts.map +1 -1
  35. package/dist/internalTypes.js.map +1 -1
  36. package/dist/internalUtils.d.ts +34 -11
  37. package/dist/internalUtils.d.ts.map +1 -1
  38. package/dist/internalUtils.js +39 -7
  39. package/dist/internalUtils.js.map +1 -1
  40. package/dist/latestMapValueManager.d.ts +36 -15
  41. package/dist/latestMapValueManager.d.ts.map +1 -1
  42. package/dist/latestMapValueManager.js +11 -10
  43. package/dist/latestMapValueManager.js.map +1 -1
  44. package/dist/latestValueManager.d.ts +21 -7
  45. package/dist/latestValueManager.d.ts.map +1 -1
  46. package/dist/latestValueManager.js +21 -10
  47. package/dist/latestValueManager.js.map +1 -1
  48. package/dist/latestValueTypes.d.ts +14 -4
  49. package/dist/latestValueTypes.d.ts.map +1 -1
  50. package/dist/latestValueTypes.js.map +1 -1
  51. package/dist/notificationsManager.d.ts +3 -3
  52. package/dist/notificationsManager.d.ts.map +1 -1
  53. package/dist/notificationsManager.js +14 -7
  54. package/dist/notificationsManager.js.map +1 -1
  55. package/dist/package.json +5 -4
  56. package/dist/presence.d.ts +26 -13
  57. package/dist/presence.d.ts.map +1 -1
  58. package/dist/presence.js +1 -1
  59. package/dist/presence.js.map +1 -1
  60. package/dist/presenceDatastoreManager.d.ts +9 -41
  61. package/dist/presenceDatastoreManager.d.ts.map +1 -1
  62. package/dist/presenceDatastoreManager.js +50 -36
  63. package/dist/presenceDatastoreManager.js.map +1 -1
  64. package/dist/presenceManager.d.ts +5 -9
  65. package/dist/presenceManager.d.ts.map +1 -1
  66. package/dist/presenceManager.js +13 -13
  67. package/dist/presenceManager.js.map +1 -1
  68. package/dist/presenceStates.d.ts +9 -14
  69. package/dist/presenceStates.d.ts.map +1 -1
  70. package/dist/presenceStates.js +1 -8
  71. package/dist/presenceStates.js.map +1 -1
  72. package/dist/protocol.d.ts +99 -0
  73. package/dist/protocol.d.ts.map +1 -0
  74. package/dist/protocol.js +20 -0
  75. package/dist/protocol.js.map +1 -0
  76. package/dist/stateDatastore.d.ts +9 -8
  77. package/dist/stateDatastore.d.ts.map +1 -1
  78. package/dist/stateDatastore.js +0 -4
  79. package/dist/stateDatastore.js.map +1 -1
  80. package/dist/stateFactory.d.ts +1 -1
  81. package/dist/stateFactory.js +1 -1
  82. package/dist/stateFactory.js.map +1 -1
  83. package/dist/systemWorkspace.d.ts +12 -6
  84. package/dist/systemWorkspace.d.ts.map +1 -1
  85. package/dist/systemWorkspace.js +14 -4
  86. package/dist/systemWorkspace.js.map +1 -1
  87. package/dist/types.d.ts +12 -10
  88. package/dist/types.d.ts.map +1 -1
  89. package/dist/types.js.map +1 -1
  90. package/dist/valueManager.d.ts +0 -4
  91. package/dist/valueManager.d.ts.map +1 -1
  92. package/dist/valueManager.js +0 -4
  93. package/dist/valueManager.js.map +1 -1
  94. package/lib/alpha.d.ts +18 -14
  95. package/lib/baseTypes.d.ts +1 -1
  96. package/lib/baseTypes.js.map +1 -1
  97. package/lib/beta.d.ts +53 -0
  98. package/lib/broadcastControls.d.ts +4 -5
  99. package/lib/broadcastControls.d.ts.map +1 -1
  100. package/lib/broadcastControls.js +2 -3
  101. package/lib/broadcastControls.js.map +1 -1
  102. package/lib/datastorePresenceManagerFactory.d.ts +4 -1
  103. package/lib/datastorePresenceManagerFactory.d.ts.map +1 -1
  104. package/lib/datastorePresenceManagerFactory.js +24 -3
  105. package/lib/datastorePresenceManagerFactory.js.map +1 -1
  106. package/lib/datastoreSupport.d.ts +7 -2
  107. package/lib/datastoreSupport.d.ts.map +1 -1
  108. package/lib/datastoreSupport.js +6 -4
  109. package/lib/datastoreSupport.js.map +1 -1
  110. package/lib/experimentalAccess.d.ts +12 -4
  111. package/lib/experimentalAccess.d.ts.map +1 -1
  112. package/lib/experimentalAccess.js +22 -15
  113. package/lib/experimentalAccess.js.map +1 -1
  114. package/lib/exposedInternalTypes.d.ts +23 -5
  115. package/lib/exposedInternalTypes.d.ts.map +1 -1
  116. package/lib/exposedInternalTypes.js +1 -1
  117. package/lib/exposedInternalTypes.js.map +1 -1
  118. package/lib/exposedUtilityTypes.d.ts +6 -5
  119. package/lib/exposedUtilityTypes.d.ts.map +1 -1
  120. package/lib/exposedUtilityTypes.js.map +1 -1
  121. package/lib/index.d.ts +2 -2
  122. package/lib/index.d.ts.map +1 -1
  123. package/lib/index.js +1 -1
  124. package/lib/index.js.map +1 -1
  125. package/lib/internalTypes.d.ts +32 -11
  126. package/lib/internalTypes.d.ts.map +1 -1
  127. package/lib/internalTypes.js.map +1 -1
  128. package/lib/internalUtils.d.ts +34 -11
  129. package/lib/internalUtils.d.ts.map +1 -1
  130. package/lib/internalUtils.js +35 -6
  131. package/lib/internalUtils.js.map +1 -1
  132. package/lib/latestMapValueManager.d.ts +36 -15
  133. package/lib/latestMapValueManager.d.ts.map +1 -1
  134. package/lib/latestMapValueManager.js +12 -11
  135. package/lib/latestMapValueManager.js.map +1 -1
  136. package/lib/latestValueManager.d.ts +21 -7
  137. package/lib/latestValueManager.d.ts.map +1 -1
  138. package/lib/latestValueManager.js +20 -10
  139. package/lib/latestValueManager.js.map +1 -1
  140. package/lib/latestValueTypes.d.ts +14 -4
  141. package/lib/latestValueTypes.d.ts.map +1 -1
  142. package/lib/latestValueTypes.js.map +1 -1
  143. package/lib/notificationsManager.d.ts +3 -3
  144. package/lib/notificationsManager.d.ts.map +1 -1
  145. package/lib/notificationsManager.js +14 -7
  146. package/lib/notificationsManager.js.map +1 -1
  147. package/lib/presence.d.ts +26 -13
  148. package/lib/presence.d.ts.map +1 -1
  149. package/lib/presence.js +1 -1
  150. package/lib/presence.js.map +1 -1
  151. package/lib/presenceDatastoreManager.d.ts +9 -41
  152. package/lib/presenceDatastoreManager.d.ts.map +1 -1
  153. package/lib/presenceDatastoreManager.js +49 -35
  154. package/lib/presenceDatastoreManager.js.map +1 -1
  155. package/lib/presenceManager.d.ts +5 -9
  156. package/lib/presenceManager.d.ts.map +1 -1
  157. package/lib/presenceManager.js +13 -13
  158. package/lib/presenceManager.js.map +1 -1
  159. package/lib/presenceStates.d.ts +9 -14
  160. package/lib/presenceStates.d.ts.map +1 -1
  161. package/lib/presenceStates.js +1 -8
  162. package/lib/presenceStates.js.map +1 -1
  163. package/lib/protocol.d.ts +99 -0
  164. package/lib/protocol.d.ts.map +1 -0
  165. package/lib/protocol.js +17 -0
  166. package/lib/protocol.js.map +1 -0
  167. package/lib/stateDatastore.d.ts +9 -8
  168. package/lib/stateDatastore.d.ts.map +1 -1
  169. package/lib/stateDatastore.js +0 -4
  170. package/lib/stateDatastore.js.map +1 -1
  171. package/lib/stateFactory.d.ts +1 -1
  172. package/lib/stateFactory.js +1 -1
  173. package/lib/stateFactory.js.map +1 -1
  174. package/lib/systemWorkspace.d.ts +12 -6
  175. package/lib/systemWorkspace.d.ts.map +1 -1
  176. package/lib/systemWorkspace.js +14 -4
  177. package/lib/systemWorkspace.js.map +1 -1
  178. package/lib/types.d.ts +12 -10
  179. package/lib/types.d.ts.map +1 -1
  180. package/lib/types.js.map +1 -1
  181. package/lib/valueManager.d.ts +0 -4
  182. package/lib/valueManager.d.ts.map +1 -1
  183. package/lib/valueManager.js +0 -4
  184. package/lib/valueManager.js.map +1 -1
  185. package/package.json +30 -23
  186. package/dist/container-definitions/containerExtensions.d.ts +0 -137
  187. package/dist/container-definitions/containerExtensions.d.ts.map +0 -1
  188. package/dist/container-definitions/containerExtensions.js +0 -7
  189. package/dist/container-definitions/containerExtensions.js.map +0 -1
  190. package/dist/container-definitions/index.d.ts +0 -7
  191. package/dist/container-definitions/index.d.ts.map +0 -1
  192. package/dist/container-definitions/index.js +0 -7
  193. package/dist/container-definitions/index.js.map +0 -1
  194. package/dist/container-definitions/runtime.d.ts +0 -12
  195. package/dist/container-definitions/runtime.d.ts.map +0 -1
  196. package/dist/container-definitions/runtime.js +0 -7
  197. package/dist/container-definitions/runtime.js.map +0 -1
  198. package/lib/container-definitions/containerExtensions.d.ts +0 -137
  199. package/lib/container-definitions/containerExtensions.d.ts.map +0 -1
  200. package/lib/container-definitions/containerExtensions.js +0 -6
  201. package/lib/container-definitions/containerExtensions.js.map +0 -1
  202. package/lib/container-definitions/index.d.ts +0 -7
  203. package/lib/container-definitions/index.d.ts.map +0 -1
  204. package/lib/container-definitions/index.js +0 -6
  205. package/lib/container-definitions/index.js.map +0 -1
  206. package/lib/container-definitions/runtime.d.ts +0 -12
  207. package/lib/container-definitions/runtime.d.ts.map +0 -1
  208. package/lib/container-definitions/runtime.js +0 -6
  209. package/lib/container-definitions/runtime.js.map +0 -1
@@ -9,17 +9,19 @@ import type { InternalTypes } from "./exposedInternalTypes.js";
9
9
  import type { LatestClientData, LatestData, LatestMetadata } from "./latestValueTypes.js";
10
10
  import type { AttendeeId, Attendee, Presence } from "./presence.js";
11
11
  /**
12
- * Collection of latest known values for a specific client.
12
+ * Collection of latest known values for a specific {@link Attendee}.
13
13
  *
14
14
  * @sealed
15
- * @alpha
15
+ * @beta
16
16
  */
17
17
  export interface LatestMapClientData<T, Keys extends string | number, SpecificAttendeeId extends AttendeeId = AttendeeId> {
18
18
  /**
19
- * Associated attendee.
19
+ * Associated {@link Attendee}.
20
20
  */
21
21
  attendee: Attendee<SpecificAttendeeId>;
22
22
  /**
23
+ * Map of items for the state.
24
+ *
23
25
  * @privateRemarks This could be regular map currently as no Map is
24
26
  * stored internally and a new instance is created for every request.
25
27
  */
@@ -29,25 +31,39 @@ export interface LatestMapClientData<T, Keys extends string | number, SpecificAt
29
31
  * State of a single item value, its key, and its metadata.
30
32
  *
31
33
  * @sealed
32
- * @alpha
34
+ * @beta
33
35
  */
34
36
  export interface LatestMapItemUpdatedClientData<T, K extends string | number> extends LatestClientData<T> {
37
+ /**
38
+ * Key of the updated item.
39
+ */
35
40
  key: K;
36
41
  }
37
42
  /**
38
43
  * Identifier and metadata for a removed item.
39
44
  *
40
45
  * @sealed
41
- * @alpha
46
+ * @beta
42
47
  */
43
48
  export interface LatestMapItemRemovedClientData<K extends string | number> {
49
+ /**
50
+ * Associated {@link Attendee}.
51
+ */
44
52
  attendee: Attendee;
53
+ /**
54
+ * Key of the removed item.
55
+ */
45
56
  key: K;
57
+ /**
58
+ * Metadata associated with the removal of the item.
59
+ */
46
60
  metadata: LatestMetadata;
47
61
  }
48
62
  /**
63
+ * Events from {@link LatestMapRaw}.
64
+ *
49
65
  * @sealed
50
- * @alpha
66
+ * @beta
51
67
  */
52
68
  export interface LatestMapRawEvents<T, K extends string | number> {
53
69
  /**
@@ -80,7 +96,7 @@ export interface LatestMapRawEvents<T, K extends string | number> {
80
96
  * @eventProperty
81
97
  */
82
98
  localItemUpdated: (updatedItem: {
83
- value: DeepReadonly<JsonSerializable<T> & JsonDeserialized<T>>;
99
+ value: DeepReadonly<JsonSerializable<T>>;
84
100
  key: K;
85
101
  }) => void;
86
102
  /**
@@ -97,7 +113,7 @@ export interface LatestMapRawEvents<T, K extends string | number> {
97
113
  * Map of local client's values. Modifications are transmitted to all other connected clients.
98
114
  *
99
115
  * @sealed
100
- * @alpha
116
+ * @beta
101
117
  */
102
118
  export interface StateMap<K extends string | number, V> {
103
119
  /**
@@ -106,6 +122,8 @@ export interface StateMap<K extends string | number, V> {
106
122
  */
107
123
  clear(): void;
108
124
  /**
125
+ * Removes the element with the specified key from the StateMap, if it exists.
126
+ *
109
127
  * @returns true if an element in the StateMap existed and has been removed, or false if
110
128
  * the element does not exist.
111
129
  * @remarks No entry is fully removed. Instead an undefined placeholder is locally and
@@ -120,11 +138,13 @@ export interface StateMap<K extends string | number, V> {
120
138
  */
121
139
  forEach(callbackfn: (value: DeepReadonly<JsonDeserialized<V>>, key: K, map: StateMap<K, V>) => void, thisArg?: unknown): void;
122
140
  /**
123
- * Returns a specified element from the StateMap object.
141
+ * Returns the element with the specified key from the StateMap, if it exists.
142
+ *
124
143
  * @returns Returns the element associated with the specified key. If no element is associated with the specified key, undefined is returned.
125
144
  */
126
145
  get(key: K): DeepReadonly<JsonDeserialized<V>> | undefined;
127
146
  /**
147
+ * Checks if an element with the specified key exists in the StateMap.
128
148
  * @returns boolean indicating whether an element with the specified key exists or not.
129
149
  */
130
150
  has(key: K): boolean;
@@ -136,9 +156,9 @@ export interface StateMap<K extends string | number, V> {
136
156
  * Make a deep clone before setting, if needed. No comparison is done to detect changes; all
137
157
  * sets are transmitted.
138
158
  */
139
- set(key: K, value: JsonSerializable<V> & JsonDeserialized<V>): this;
159
+ set(key: K, value: JsonSerializable<V>): this;
140
160
  /**
141
- * @returns the number of elements in the StateMap.
161
+ * The number of elements in the StateMap.
142
162
  */
143
163
  readonly size: number;
144
164
  /**
@@ -161,7 +181,7 @@ export interface StateMap<K extends string | number, V> {
161
181
  * @remarks Create using {@link StateFactory.latestMap} registered to {@link StatesWorkspace}.
162
182
  *
163
183
  * @sealed
164
- * @alpha
184
+ * @beta
165
185
  */
166
186
  export interface LatestMapRaw<T, Keys extends string | number = string | number> {
167
187
  /**
@@ -196,14 +216,15 @@ export interface LatestMapRaw<T, Keys extends string | number = string | number>
196
216
  /**
197
217
  * Arguments that are passed to the {@link StateFactory.latestMap} function.
198
218
  *
199
- * @alpha
219
+ * @input
220
+ * @beta
200
221
  */
201
222
  export interface LatestMapArguments<T, Keys extends string | number = string | number> {
202
223
  /**
203
224
  * The initial value of the local state.
204
225
  */
205
226
  local?: {
206
- [K in Keys]: JsonSerializable<T> & JsonDeserialized<T>;
227
+ [K in Keys]: JsonSerializable<T>;
207
228
  };
208
229
  /**
209
230
  * See {@link BroadcastControlSettings}.
@@ -213,7 +234,7 @@ export interface LatestMapArguments<T, Keys extends string | number = string | n
213
234
  /**
214
235
  * Factory for creating a {@link LatestMapRaw} State object.
215
236
  *
216
- * @alpha
237
+ * @beta
217
238
  */
218
239
  export declare function latestMap<T, Keys extends string | number = string | number, RegistrationKey extends string = string>(args?: LatestMapArguments<T, Keys>): InternalTypes.ManagerFactory<RegistrationKey, InternalTypes.MapValueState<T, Keys>, LatestMapRaw<T, Keys>>;
219
240
  //# 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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"}
@@ -54,23 +54,24 @@ class ValueMapImpl {
54
54
  forEach(callbackfn, thisArg) {
55
55
  for (const [key, item] of (0, internalUtils_js_1.objectEntries)(this.value.items)) {
56
56
  if (item.value !== undefined) {
57
- callbackfn((0, internalUtils_js_1.asDeeplyReadonly)(item.value), key, this);
57
+ callbackfn((0, internalUtils_js_1.asDeeplyReadonlyDeserializedJson)(item.value), key, this);
58
58
  }
59
59
  }
60
60
  }
61
61
  get(key) {
62
- return (0, internalUtils_js_1.asDeeplyReadonly)(this.value.items[key]?.value);
62
+ return (0, internalUtils_js_1.asDeeplyReadonlyDeserializedJson)(this.value.items[key]?.value);
63
63
  }
64
64
  has(key) {
65
65
  return this.value.items[key]?.value !== undefined;
66
66
  }
67
- set(key, value) {
67
+ set(key, inValue) {
68
+ const value = (0, internalUtils_js_1.toOpaqueJson)(inValue);
68
69
  if (!(key in this.value.items)) {
69
70
  this.countDefined += 1;
70
71
  this.value.items[key] = { rev: 0, timestamp: 0, value };
71
72
  }
72
73
  this.updateItem(key, value);
73
- this.emitter.emit("localItemUpdated", { key, value: (0, internalUtils_js_1.asDeeplyReadonly)(value) });
74
+ this.emitter.emit("localItemUpdated", { key, value: (0, internalUtils_js_1.asDeeplyReadonly)(inValue) });
74
75
  return this;
75
76
  }
76
77
  get size() {
@@ -106,7 +107,7 @@ class LatestMapRawValueManagerImpl {
106
107
  const allKnownStates = this.datastore.knownValues(this.key);
107
108
  for (const attendeeId of (0, internalUtils_js_1.objectKeys)(allKnownStates.states)) {
108
109
  if (attendeeId !== allKnownStates.self) {
109
- const attendee = this.datastore.lookupClient(attendeeId);
110
+ const attendee = this.datastore.presence.attendees.getAttendee(attendeeId);
110
111
  const items = this.getRemote(attendee);
111
112
  yield { attendee, items };
112
113
  }
@@ -116,7 +117,7 @@ class LatestMapRawValueManagerImpl {
116
117
  const allKnownStates = this.datastore.knownValues(this.key);
117
118
  return (0, internalUtils_js_1.objectKeys)(allKnownStates.states)
118
119
  .filter((attendeeId) => attendeeId !== allKnownStates.self)
119
- .map((attendeeId) => this.datastore.lookupClient(attendeeId));
120
+ .map((attendeeId) => this.datastore.presence.attendees.getAttendee(attendeeId));
120
121
  }
121
122
  getRemote(attendee) {
122
123
  const allKnownStates = this.datastore.knownValues(this.key);
@@ -130,7 +131,7 @@ class LatestMapRawValueManagerImpl {
130
131
  const value = item.value;
131
132
  if (value !== undefined) {
132
133
  items.set(key, {
133
- value: (0, internalUtils_js_1.asDeeplyReadonly)(value),
134
+ value: (0, internalUtils_js_1.asDeeplyReadonlyDeserializedJson)(value),
134
135
  metadata: { revision: item.rev, timestamp: item.timestamp },
135
136
  });
136
137
  }
@@ -174,7 +175,7 @@ class LatestMapRawValueManagerImpl {
174
175
  currentState.items[key] = item;
175
176
  const metadata = { revision: item.rev, timestamp: item.timestamp };
176
177
  if (item.value !== undefined) {
177
- const itemValue = (0, internalUtils_js_1.asDeeplyReadonly)(item.value);
178
+ const itemValue = (0, internalUtils_js_1.asDeeplyReadonlyDeserializedJson)(item.value);
178
179
  const updatedItem = {
179
180
  attendee,
180
181
  key,
@@ -200,7 +201,7 @@ class LatestMapRawValueManagerImpl {
200
201
  /**
201
202
  * Factory for creating a {@link LatestMapRaw} State object.
202
203
  *
203
- * @alpha
204
+ * @beta
204
205
  */
205
206
  function latestMap(args) {
206
207
  const settings = args?.settings;
@@ -213,7 +214,7 @@ function latestMap(args) {
213
214
  value.items[key] = {
214
215
  rev: 0,
215
216
  timestamp,
216
- value: initialValues[key],
217
+ value: (0, internalUtils_js_1.toOpaqueJson)(initialValues[key]),
217
218
  };
218
219
  }
219
220
  }
@@ -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 { PostUpdateAction, ValueManager } from \"./internalTypes.js\";\nimport { asDeeplyReadonly, objectEntries, objectKeys } from \"./internalUtils.js\";\nimport type { LatestClientData, LatestData, LatestMetadata } 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 latest known values for a specific client.\n *\n * @sealed\n * @alpha\n */\nexport interface LatestMapClientData<\n\tT,\n\tKeys extends string | number,\n\tSpecificAttendeeId extends AttendeeId = AttendeeId,\n> {\n\t/**\n\t * Associated attendee.\n\t */\n\tattendee: Attendee<SpecificAttendeeId>;\n\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>>;\n}\n\n/**\n * State of a single item value, its key, and its metadata.\n *\n * @sealed\n * @alpha\n */\nexport interface LatestMapItemUpdatedClientData<T, K extends string | number>\n\textends LatestClientData<T> {\n\tkey: K;\n}\n\n/**\n * Identifier and metadata for a removed item.\n *\n * @sealed\n * @alpha\n */\nexport interface LatestMapItemRemovedClientData<K extends string | number> {\n\tattendee: Attendee;\n\tkey: K;\n\tmetadata: LatestMetadata;\n}\n\n/**\n * @sealed\n * @alpha\n */\nexport interface LatestMapRawEvents<T, K extends string | number> {\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>) => 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: (updatedItem: LatestMapItemUpdatedClientData<T, K>) => 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> & JsonDeserialized<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 * Map of local client's values. Modifications are transmitted to all other connected clients.\n *\n * @sealed\n * @alpha\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 * @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 a specified element from the StateMap object.\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 * @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> & JsonDeserialized<V>): this;\n\n\t/**\n\t * @returns 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<LatestMapRawEvents<T, K>, \"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(asDeeplyReadonly(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 asDeeplyReadonly(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, value: JsonSerializable<T> & JsonDeserialized<T>): this {\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(value) });\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 * @alpha\n */\nexport interface LatestMapRaw<T, Keys extends string | number = string | number> {\n\t/**\n\t * Containing {@link Presence}\n\t */\n\treadonly presence: Presence;\n\n\t/**\n\t * Events for LatestMapRaw.\n\t */\n\treadonly events: Listenable<LatestMapRawEvents<T, Keys>>;\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>>;\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>>;\n}\n\nclass LatestMapRawValueManagerImpl<\n\tT,\n\tRegistrationKey extends string,\n\tKeys extends string | number = string | number,\n> implements\n\t\tLatestMapRaw<T, Keys>,\n\t\tRequired<ValueManager<T, InternalTypes.MapValueState<T, Keys>>>\n{\n\tpublic readonly events = createEmitter<LatestMapRawEvents<T, Keys>>();\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>,\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>> {\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.lookupClient(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.lookupClient(attendeeId));\n\t}\n\n\tpublic getRemote(attendee: Attendee): ReadonlyMap<Keys, LatestData<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>>();\n\t\tfor (const [key, item] of objectEntries(clientStateMap.items)) {\n\t\t\tconst value = item.value;\n\t\t\tif (value !== undefined) {\n\t\t\t\titems.set(key, {\n\t\t\t\t\tvalue: asDeeplyReadonly(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\titems: {} as unknown as InternalTypes.MapValueState<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>>(),\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 = { revision: item.rev, timestamp: item.timestamp };\n\t\t\tif (item.value !== undefined) {\n\t\t\t\tconst itemValue = asDeeplyReadonly(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};\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 * @alpha\n */\nexport interface LatestMapArguments<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> & JsonDeserialized<T>;\n\t};\n\n\t/**\n\t * See {@link BroadcastControlSettings}.\n\t */\n\tsettings?: BroadcastControlSettings | undefined;\n}\n\n/**\n * Factory for creating a {@link LatestMapRaw} State object.\n *\n * @alpha\n */\nexport function latestMap<\n\tT,\n\tKeys extends string | number = string | number,\n\tRegistrationKey extends string = string,\n>(\n\targs?: LatestMapArguments<T, Keys>,\n): InternalTypes.ManagerFactory<\n\tRegistrationKey,\n\tInternalTypes.MapValueState<T, Keys>,\n\tLatestMapRaw<T, Keys>\n> {\n\tconst settings = args?.settings;\n\tconst initialValues = args?.local;\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: 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>>;\n\t} => ({\n\t\tinitialData: { value, allowableUpdateLatencyMs: settings?.allowableUpdateLatencyMs },\n\t\tmanager: brandIVM<\n\t\t\tLatestMapRawValueManagerImpl<T, RegistrationKey, Keys>,\n\t\t\tT,\n\t\t\tInternalTypes.MapValueState<T, Keys>\n\t\t>(\n\t\t\tnew LatestMapRawValueManagerImpl(\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: LatestMapRawValueManagerImpl });\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 { PostUpdateAction, ValueManager } from \"./internalTypes.js\";\nimport {\n\tasDeeplyReadonly,\n\tasDeeplyReadonlyDeserializedJson,\n\tobjectEntries,\n\tobjectKeys,\n\ttoOpaqueJson,\n} from \"./internalUtils.js\";\nimport type { LatestClientData, LatestData, LatestMetadata } 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 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\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>>;\n}\n\n/**\n * State of a single item value, its key, and its metadata.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMapItemUpdatedClientData<T, K extends string | number>\n\textends LatestClientData<T> {\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 LatestMapRawEvents<T, K extends string | number> {\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>) => 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: (updatedItem: LatestMapItemUpdatedClientData<T, K>) => 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 * 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<LatestMapRawEvents<T, K>, \"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 LatestMapRaw<T, Keys extends string | number = string | number> {\n\t/**\n\t * Containing {@link Presence}\n\t */\n\treadonly presence: Presence;\n\n\t/**\n\t * Events for LatestMapRaw.\n\t */\n\treadonly events: Listenable<LatestMapRawEvents<T, Keys>>;\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>>;\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>>;\n}\n\nclass LatestMapRawValueManagerImpl<\n\tT,\n\tRegistrationKey extends string,\n\tKeys extends string | number = string | number,\n> implements\n\t\tLatestMapRaw<T, Keys>,\n\t\tRequired<ValueManager<T, InternalTypes.MapValueState<T, Keys>>>\n{\n\tpublic readonly events = createEmitter<LatestMapRawEvents<T, Keys>>();\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>,\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>> {\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>> {\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>>();\n\t\tfor (const [key, item] of objectEntries(clientStateMap.items)) {\n\t\t\tconst value = item.value;\n\t\t\tif (value !== undefined) {\n\t\t\t\titems.set(key, {\n\t\t\t\t\tvalue: asDeeplyReadonlyDeserializedJson(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\titems: {} as unknown as InternalTypes.MapValueState<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>>(),\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 = { revision: item.rev, timestamp: item.timestamp };\n\t\t\tif (item.value !== undefined) {\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};\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 LatestMapArguments<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 * Factory for creating a {@link LatestMapRaw} State object.\n *\n * @beta\n */\nexport function latestMap<\n\tT,\n\tKeys extends string | number = string | number,\n\tRegistrationKey extends string = string,\n>(\n\targs?: LatestMapArguments<T, Keys>,\n): InternalTypes.ManagerFactory<\n\tRegistrationKey,\n\tInternalTypes.MapValueState<T, Keys>,\n\tLatestMapRaw<T, Keys>\n> {\n\tconst settings = args?.settings;\n\tconst initialValues = args?.local;\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>>;\n\t} => ({\n\t\tinitialData: { value, allowableUpdateLatencyMs: settings?.allowableUpdateLatencyMs },\n\t\tmanager: brandIVM<\n\t\t\tLatestMapRawValueManagerImpl<T, RegistrationKey, Keys>,\n\t\t\tT,\n\t\t\tInternalTypes.MapValueState<T, Keys>\n\t\t>(\n\t\t\tnew LatestMapRawValueManagerImpl(\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: LatestMapRawValueManagerImpl });\n}\n"]}
@@ -9,8 +9,10 @@ import type { InternalTypes } from "./exposedInternalTypes.js";
9
9
  import type { LatestClientData, LatestData } from "./latestValueTypes.js";
10
10
  import type { Attendee, Presence } from "./presence.js";
11
11
  /**
12
+ * Events from {@link LatestRaw}.
13
+ *
12
14
  * @sealed
13
- * @alpha
15
+ * @beta
14
16
  */
15
17
  export interface LatestRawEvents<T> {
16
18
  /**
@@ -25,7 +27,7 @@ export interface LatestRawEvents<T> {
25
27
  * @eventProperty
26
28
  */
27
29
  localUpdated: (update: {
28
- value: DeepReadonly<JsonSerializable<T> & JsonDeserialized<T>>;
30
+ value: DeepReadonly<JsonSerializable<T>>;
29
31
  }) => void;
30
32
  }
31
33
  /**
@@ -35,7 +37,7 @@ export interface LatestRawEvents<T> {
35
37
  * @remarks Create using {@link StateFactory.latest} registered to {@link StatesWorkspace}.
36
38
  *
37
39
  * @sealed
38
- * @alpha
40
+ * @beta
39
41
  */
40
42
  export interface LatestRaw<T> {
41
43
  /**
@@ -57,7 +59,7 @@ export interface LatestRaw<T> {
57
59
  * setting, if needed. No comparison is done to detect changes; all sets are transmitted.
58
60
  */
59
61
  get local(): DeepReadonly<JsonDeserialized<T>>;
60
- set local(value: JsonSerializable<T> & JsonDeserialized<T>);
62
+ set local(value: JsonSerializable<T>);
61
63
  /**
62
64
  * Iterable access to remote clients' values.
63
65
  */
@@ -71,16 +73,28 @@ export interface LatestRaw<T> {
71
73
  */
72
74
  getRemote(attendee: Attendee): LatestData<T>;
73
75
  }
76
+ /**
77
+ * Shallow clone an object that might be null.
78
+ *
79
+ * @param value - The object to clone
80
+ * @returns A shallow clone of the input value
81
+ */
82
+ export declare function shallowCloneNullableObject<T extends object | null>(value: T): T;
74
83
  /**
75
84
  * Arguments that are passed to the {@link StateFactory.latest} function.
76
85
  *
77
- * @alpha
86
+ * @input
87
+ * @beta
78
88
  */
79
89
  export interface LatestArguments<T extends object | null> {
80
90
  /**
81
91
  * The initial value of the local state.
92
+ *
93
+ * @remarks
94
+ * `latest` assumes ownership of the value and its references.
95
+ * Make a deep clone before passing, if needed.
82
96
  */
83
- local: JsonSerializable<T> & JsonDeserialized<T> & (object | null);
97
+ local: JsonSerializable<T>;
84
98
  /**
85
99
  * See {@link BroadcastControlSettings}.
86
100
  */
@@ -89,7 +103,7 @@ export interface LatestArguments<T extends object | null> {
89
103
  /**
90
104
  * Factory for creating a {@link LatestRaw} State object.
91
105
  *
92
- * @alpha
106
+ * @beta
93
107
  */
94
108
  export declare function latest<T extends object | null, Key extends string = string>(args: LatestArguments<T>): InternalTypes.ManagerFactory<Key, InternalTypes.ValueRequiredState<T>, LatestRaw<T>>;
95
109
  //# sourceMappingURL=latestValueManager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"latestValueManager.d.ts","sourceRoot":"","sources":["../src/latestValueManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,KAAK,EACX,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,MAAM,8DAA8D,CAAC;AAGtE,OAAO,KAAK,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAE1F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAG/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAC1E,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAIxD;;;GAGG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC;IACjC;;;;OAIG;IACH,aAAa,EAAE,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IAErD;;;;OAIG;IACH,YAAY,EAAE,CAAC,MAAM,EAAE;QACtB,KAAK,EAAE,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;KAC/D,KAAK,IAAI,CAAC;CACX;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,SAAS,CAAC,CAAC;IAC3B;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAE5B;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;IAEhD;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IAErC;;;;;OAKG;IACH,IAAI,KAAK,IAAI,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/C,IAAI,KAAK,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,EAAE;IAE5D;;OAEG;IACH,UAAU,IAAI,gBAAgB,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD;;OAEG;IACH,iBAAiB,IAAI,QAAQ,EAAE,CAAC;IAChC;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;CAC7C;AA2FD;;;;GAIG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC,SAAS,MAAM,GAAG,IAAI;IACvD;;OAEG;IAEH,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAEnE;;OAEG;IACH,QAAQ,CAAC,EAAE,wBAAwB,GAAG,SAAS,CAAC;CAChD;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,MAAM,GAAG,IAAI,EAAE,GAAG,SAAS,MAAM,GAAG,MAAM,EAC1E,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,GACtB,aAAa,CAAC,cAAc,CAAC,GAAG,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CA0BtF"}
1
+ {"version":3,"file":"latestValueManager.d.ts","sourceRoot":"","sources":["../src/latestValueManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,KAAK,EACX,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,MAAM,8DAA8D,CAAC;AAGtE,OAAO,KAAK,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAE1F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAQ/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAC1E,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAIxD;;;;;GAKG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC;IACjC;;;;OAIG;IACH,aAAa,EAAE,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IAErD;;;;OAIG;IACH,YAAY,EAAE,CAAC,MAAM,EAAE;QACtB,KAAK,EAAE,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;KACzC,KAAK,IAAI,CAAC;CACX;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,SAAS,CAAC,CAAC;IAC3B;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAE5B;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;IAEhD;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IAErC;;;;;OAKG;IACH,IAAI,KAAK,IAAI,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/C,IAAI,KAAK,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAAE;IAEtC;;OAEG;IACH,UAAU,IAAI,gBAAgB,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD;;OAEG;IACH,iBAAiB,IAAI,QAAQ,EAAE,CAAC;IAChC;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;CAC7C;AA2FD;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,CAAC,SAAS,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAE/E;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC,SAAS,MAAM,GAAG,IAAI;IACvD;;;;;;OAMG;IACH,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC;IAE3B;;OAEG;IACH,QAAQ,CAAC,EAAE,wBAAwB,GAAG,SAAS,CAAC;CAChD;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,MAAM,GAAG,IAAI,EAAE,GAAG,SAAS,MAAM,GAAG,MAAM,EAC1E,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,GACtB,aAAa,CAAC,cAAc,CAAC,GAAG,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CA2BtF"}
@@ -4,7 +4,7 @@
4
4
  * Licensed under the MIT License.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.latest = void 0;
7
+ exports.latest = exports.shallowCloneNullableObject = void 0;
8
8
  const client_utils_1 = require("@fluid-internal/client-utils");
9
9
  const internal_1 = require("@fluidframework/core-utils/internal");
10
10
  const broadcastControls_js_1 = require("./broadcastControls.js");
@@ -23,12 +23,12 @@ class LatestValueManagerImpl {
23
23
  return this.datastore.presence;
24
24
  }
25
25
  get local() {
26
- return (0, internalUtils_js_1.asDeeplyReadonly)(this.value.value);
26
+ return (0, internalUtils_js_1.asDeeplyReadonlyDeserializedJson)(this.value.value);
27
27
  }
28
28
  set local(value) {
29
29
  this.value.rev += 1;
30
30
  this.value.timestamp = Date.now();
31
- this.value.value = value;
31
+ this.value.value = (0, internalUtils_js_1.toOpaqueJson)(value);
32
32
  this.datastore.localUpdate(this.key, this.value, {
33
33
  allowableUpdateLatencyMs: this.controls.allowableUpdateLatencyMs,
34
34
  });
@@ -39,8 +39,8 @@ class LatestValueManagerImpl {
39
39
  for (const [attendeeId, value] of (0, internalUtils_js_1.objectEntries)(allKnownStates.states)) {
40
40
  if (attendeeId !== allKnownStates.self) {
41
41
  yield {
42
- attendee: this.datastore.lookupClient(attendeeId),
43
- value: (0, internalUtils_js_1.asDeeplyReadonly)(value.value),
42
+ attendee: this.datastore.presence.attendees.getAttendee(attendeeId),
43
+ value: (0, internalUtils_js_1.asDeeplyReadonlyDeserializedJson)(value.value),
44
44
  metadata: { revision: value.rev, timestamp: value.timestamp },
45
45
  };
46
46
  }
@@ -50,7 +50,7 @@ class LatestValueManagerImpl {
50
50
  const allKnownStates = this.datastore.knownValues(this.key);
51
51
  return Object.keys(allKnownStates.states)
52
52
  .filter((attendeeId) => attendeeId !== allKnownStates.self)
53
- .map((attendeeId) => this.datastore.lookupClient(attendeeId));
53
+ .map((attendeeId) => this.datastore.presence.attendees.getAttendee(attendeeId));
54
54
  }
55
55
  getRemote(attendee) {
56
56
  const allKnownStates = this.datastore.knownValues(this.key);
@@ -59,7 +59,7 @@ class LatestValueManagerImpl {
59
59
  throw new Error("No entry for clientId");
60
60
  }
61
61
  return {
62
- value: (0, internalUtils_js_1.asDeeplyReadonly)(clientState.value),
62
+ value: (0, internalUtils_js_1.asDeeplyReadonlyDeserializedJson)(clientState.value),
63
63
  metadata: { revision: clientState.rev, timestamp: Date.now() },
64
64
  };
65
65
  }
@@ -74,25 +74,36 @@ class LatestValueManagerImpl {
74
74
  return [
75
75
  () => this.events.emit("remoteUpdated", {
76
76
  attendee,
77
- value: (0, internalUtils_js_1.asDeeplyReadonly)(value.value),
77
+ value: (0, internalUtils_js_1.asDeeplyReadonlyDeserializedJson)(value.value),
78
78
  metadata: { revision: value.rev, timestamp: value.timestamp },
79
79
  }),
80
80
  ];
81
81
  }
82
82
  }
83
+ /**
84
+ * Shallow clone an object that might be null.
85
+ *
86
+ * @param value - The object to clone
87
+ * @returns A shallow clone of the input value
88
+ */
89
+ function shallowCloneNullableObject(value) {
90
+ return value === null ? value : (0, internal_1.shallowCloneObject)(value);
91
+ }
92
+ exports.shallowCloneNullableObject = shallowCloneNullableObject;
83
93
  /**
84
94
  * Factory for creating a {@link LatestRaw} State object.
85
95
  *
86
- * @alpha
96
+ * @beta
87
97
  */
88
98
  function latest(args) {
89
99
  const { local, settings } = args;
90
100
  // Latest takes ownership of the initial local value but makes a shallow
91
101
  // copy for basic protection.
102
+ const opaqueLocal = (0, internalUtils_js_1.toOpaqueJson)(local);
92
103
  const value = {
93
104
  rev: 0,
94
105
  timestamp: Date.now(),
95
- value: local === null ? local : (0, internal_1.shallowCloneObject)(local),
106
+ value: shallowCloneNullableObject(opaqueLocal),
96
107
  };
97
108
  const factory = (key, datastoreHandle) => ({
98
109
  initialData: { value, allowableUpdateLatencyMs: settings?.allowableUpdateLatencyMs },
@@ -1 +1 @@
1
- {"version":3,"file":"latestValueManager.js","sourceRoot":"","sources":["../src/latestValueManager.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 {\n\tDeepReadonly,\n\tJsonDeserialized,\n\tJsonSerializable,\n} from \"@fluidframework/core-interfaces/internal/exposedUtilityTypes\";\nimport { shallowCloneObject } from \"@fluidframework/core-utils/internal\";\n\nimport type { BroadcastControls, BroadcastControlSettings } from \"./broadcastControls.js\";\nimport { OptionalBroadcastControl } from \"./broadcastControls.js\";\nimport type { InternalTypes } from \"./exposedInternalTypes.js\";\nimport type { PostUpdateAction, ValueManager } from \"./internalTypes.js\";\nimport { asDeeplyReadonly, objectEntries } from \"./internalUtils.js\";\nimport type { LatestClientData, LatestData } from \"./latestValueTypes.js\";\nimport type { Attendee, Presence } from \"./presence.js\";\nimport { datastoreFromHandle, type StateDatastore } from \"./stateDatastore.js\";\nimport { brandIVM } from \"./valueManager.js\";\n\n/**\n * @sealed\n * @alpha\n */\nexport interface LatestRawEvents<T> {\n\t/**\n\t * Raised when remote client's value is updated, which may be the same value.\n\t *\n\t * @eventProperty\n\t */\n\tremoteUpdated: (update: LatestClientData<T>) => void;\n\n\t/**\n\t * Raised when local client's value is updated, which may be the same value.\n\t *\n\t * @eventProperty\n\t */\n\tlocalUpdated: (update: {\n\t\tvalue: DeepReadonly<JsonSerializable<T> & JsonDeserialized<T>>;\n\t}) => void;\n}\n\n/**\n * State that provides the latest known value from this client to others and read access to their values.\n * All participant clients must provide a value.\n *\n * @remarks Create using {@link StateFactory.latest} registered to {@link StatesWorkspace}.\n *\n * @sealed\n * @alpha\n */\nexport interface LatestRaw<T> {\n\t/**\n\t * Containing {@link Presence}\n\t */\n\treadonly presence: Presence;\n\n\t/**\n\t * Events for LatestRaw.\n\t */\n\treadonly events: Listenable<LatestRawEvents<T>>;\n\n\t/**\n\t * Controls for management of sending updates.\n\t */\n\treadonly controls: BroadcastControls;\n\n\t/**\n\t * Current state for this client.\n\t * State for this client that will be transmitted to all other connected clients.\n\t * @remarks Manager assumes ownership of the value and its references. Make a deep clone before\n\t * setting, if needed. No comparison is done to detect changes; all sets are transmitted.\n\t */\n\tget local(): DeepReadonly<JsonDeserialized<T>>;\n\tset local(value: JsonSerializable<T> & JsonDeserialized<T>);\n\n\t/**\n\t * Iterable access to remote clients' values.\n\t */\n\tgetRemotes(): IterableIterator<LatestClientData<T>>;\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 attendee's value.\n\t */\n\tgetRemote(attendee: Attendee): LatestData<T>;\n}\n\nclass LatestValueManagerImpl<T, Key extends string>\n\timplements LatestRaw<T>, Required<ValueManager<T, InternalTypes.ValueRequiredState<T>>>\n{\n\tpublic readonly events = createEmitter<LatestRawEvents<T>>();\n\tpublic readonly controls: OptionalBroadcastControl;\n\n\tpublic constructor(\n\t\tprivate readonly key: Key,\n\t\tprivate readonly datastore: StateDatastore<Key, InternalTypes.ValueRequiredState<T>>,\n\t\tpublic readonly value: InternalTypes.ValueRequiredState<T>,\n\t\tcontrolSettings: BroadcastControlSettings | undefined,\n\t) {\n\t\tthis.controls = new OptionalBroadcastControl(controlSettings);\n\t}\n\n\tpublic get presence(): Presence {\n\t\treturn this.datastore.presence;\n\t}\n\n\tpublic get local(): DeepReadonly<JsonDeserialized<T>> {\n\t\treturn asDeeplyReadonly(this.value.value);\n\t}\n\n\tpublic set local(value: JsonSerializable<T> & JsonDeserialized<T>) {\n\t\tthis.value.rev += 1;\n\t\tthis.value.timestamp = Date.now();\n\t\tthis.value.value = value;\n\t\tthis.datastore.localUpdate(this.key, this.value, {\n\t\t\tallowableUpdateLatencyMs: this.controls.allowableUpdateLatencyMs,\n\t\t});\n\n\t\tthis.events.emit(\"localUpdated\", { value: asDeeplyReadonly(value) });\n\t}\n\n\tpublic *getRemotes(): IterableIterator<LatestClientData<T>> {\n\t\tconst allKnownStates = this.datastore.knownValues(this.key);\n\t\tfor (const [attendeeId, value] of objectEntries(allKnownStates.states)) {\n\t\t\tif (attendeeId !== allKnownStates.self) {\n\t\t\t\tyield {\n\t\t\t\t\tattendee: this.datastore.lookupClient(attendeeId),\n\t\t\t\t\tvalue: asDeeplyReadonly(value.value),\n\t\t\t\t\tmetadata: { revision: value.rev, timestamp: value.timestamp },\n\t\t\t\t};\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 Object.keys(allKnownStates.states)\n\t\t\t.filter((attendeeId) => attendeeId !== allKnownStates.self)\n\t\t\t.map((attendeeId) => this.datastore.lookupClient(attendeeId));\n\t}\n\n\tpublic getRemote(attendee: Attendee): LatestData<T> {\n\t\tconst allKnownStates = this.datastore.knownValues(this.key);\n\t\tconst clientState = allKnownStates.states[attendee.attendeeId];\n\t\tif (clientState === undefined) {\n\t\t\tthrow new Error(\"No entry for clientId\");\n\t\t}\n\t\treturn {\n\t\t\tvalue: asDeeplyReadonly(clientState.value),\n\t\t\tmetadata: { revision: clientState.rev, timestamp: Date.now() },\n\t\t};\n\t}\n\n\tpublic update(\n\t\tattendee: Attendee,\n\t\t_received: number,\n\t\tvalue: InternalTypes.ValueRequiredState<T>,\n\t): PostUpdateAction[] {\n\t\tconst allKnownStates = this.datastore.knownValues(this.key);\n\t\tconst attendeeId = attendee.attendeeId;\n\t\tconst currentState = allKnownStates.states[attendeeId];\n\t\tif (currentState !== undefined && currentState.rev >= value.rev) {\n\t\t\treturn [];\n\t\t}\n\t\tthis.datastore.update(this.key, attendeeId, value);\n\t\treturn [\n\t\t\t() =>\n\t\t\t\tthis.events.emit(\"remoteUpdated\", {\n\t\t\t\t\tattendee,\n\t\t\t\t\tvalue: asDeeplyReadonly(value.value),\n\t\t\t\t\tmetadata: { revision: value.rev, timestamp: value.timestamp },\n\t\t\t\t}),\n\t\t];\n\t}\n}\n\n/**\n * Arguments that are passed to the {@link StateFactory.latest} function.\n *\n * @alpha\n */\nexport interface LatestArguments<T extends object | null> {\n\t/**\n\t * The initial value of the local state.\n\t */\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tlocal: JsonSerializable<T> & JsonDeserialized<T> & (object | null);\n\n\t/**\n\t * See {@link BroadcastControlSettings}.\n\t */\n\tsettings?: BroadcastControlSettings | undefined;\n}\n\n/**\n * Factory for creating a {@link LatestRaw} State object.\n *\n * @alpha\n */\nexport function latest<T extends object | null, Key extends string = string>(\n\targs: LatestArguments<T>,\n): InternalTypes.ManagerFactory<Key, InternalTypes.ValueRequiredState<T>, LatestRaw<T>> {\n\tconst { local, settings } = args;\n\n\t// Latest takes ownership of the initial local value but makes a shallow\n\t// copy for basic protection.\n\tconst value: InternalTypes.ValueRequiredState<T> = {\n\t\trev: 0,\n\t\ttimestamp: Date.now(),\n\t\tvalue: local === null ? local : shallowCloneObject(local),\n\t};\n\tconst factory = (\n\t\tkey: Key,\n\t\tdatastoreHandle: InternalTypes.StateDatastoreHandle<\n\t\t\tKey,\n\t\t\tInternalTypes.ValueRequiredState<T>\n\t\t>,\n\t): {\n\t\tinitialData: { value: typeof value; allowableUpdateLatencyMs: number | undefined };\n\t\tmanager: InternalTypes.StateValue<LatestRaw<T>>;\n\t} => ({\n\t\tinitialData: { value, allowableUpdateLatencyMs: settings?.allowableUpdateLatencyMs },\n\t\tmanager: brandIVM<LatestValueManagerImpl<T, Key>, T, InternalTypes.ValueRequiredState<T>>(\n\t\t\tnew LatestValueManagerImpl(key, datastoreFromHandle(datastoreHandle), value, settings),\n\t\t),\n\t});\n\treturn Object.assign(factory, { instanceBase: LatestValueManagerImpl });\n}\n"]}
1
+ {"version":3,"file":"latestValueManager.js","sourceRoot":"","sources":["../src/latestValueManager.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 {\n\tDeepReadonly,\n\tJsonDeserialized,\n\tJsonSerializable,\n} from \"@fluidframework/core-interfaces/internal/exposedUtilityTypes\";\nimport { shallowCloneObject } from \"@fluidframework/core-utils/internal\";\n\nimport type { BroadcastControls, BroadcastControlSettings } from \"./broadcastControls.js\";\nimport { OptionalBroadcastControl } from \"./broadcastControls.js\";\nimport type { InternalTypes } from \"./exposedInternalTypes.js\";\nimport type { PostUpdateAction, ValueManager } from \"./internalTypes.js\";\nimport {\n\tasDeeplyReadonly,\n\tasDeeplyReadonlyDeserializedJson,\n\tobjectEntries,\n\ttoOpaqueJson,\n} from \"./internalUtils.js\";\nimport type { LatestClientData, LatestData } from \"./latestValueTypes.js\";\nimport type { Attendee, Presence } from \"./presence.js\";\nimport { datastoreFromHandle, type StateDatastore } from \"./stateDatastore.js\";\nimport { brandIVM } from \"./valueManager.js\";\n\n/**\n * Events from {@link LatestRaw}.\n *\n * @sealed\n * @beta\n */\nexport interface LatestRawEvents<T> {\n\t/**\n\t * Raised when remote client's value is updated, which may be the same value.\n\t *\n\t * @eventProperty\n\t */\n\tremoteUpdated: (update: LatestClientData<T>) => void;\n\n\t/**\n\t * Raised when local client's value is updated, which may be the same value.\n\t *\n\t * @eventProperty\n\t */\n\tlocalUpdated: (update: {\n\t\tvalue: DeepReadonly<JsonSerializable<T>>;\n\t}) => void;\n}\n\n/**\n * State that provides the latest known value from this client to others and read access to their values.\n * All participant clients must provide a value.\n *\n * @remarks Create using {@link StateFactory.latest} registered to {@link StatesWorkspace}.\n *\n * @sealed\n * @beta\n */\nexport interface LatestRaw<T> {\n\t/**\n\t * Containing {@link Presence}\n\t */\n\treadonly presence: Presence;\n\n\t/**\n\t * Events for LatestRaw.\n\t */\n\treadonly events: Listenable<LatestRawEvents<T>>;\n\n\t/**\n\t * Controls for management of sending updates.\n\t */\n\treadonly controls: BroadcastControls;\n\n\t/**\n\t * Current state for this client.\n\t * State for this client that will be transmitted to all other connected clients.\n\t * @remarks Manager assumes ownership of the value and its references. Make a deep clone before\n\t * setting, if needed. No comparison is done to detect changes; all sets are transmitted.\n\t */\n\tget local(): DeepReadonly<JsonDeserialized<T>>;\n\tset local(value: JsonSerializable<T>);\n\n\t/**\n\t * Iterable access to remote clients' values.\n\t */\n\tgetRemotes(): IterableIterator<LatestClientData<T>>;\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 attendee's value.\n\t */\n\tgetRemote(attendee: Attendee): LatestData<T>;\n}\n\nclass LatestValueManagerImpl<T, Key extends string>\n\timplements LatestRaw<T>, Required<ValueManager<T, InternalTypes.ValueRequiredState<T>>>\n{\n\tpublic readonly events = createEmitter<LatestRawEvents<T>>();\n\tpublic readonly controls: OptionalBroadcastControl;\n\n\tpublic constructor(\n\t\tprivate readonly key: Key,\n\t\tprivate readonly datastore: StateDatastore<Key, InternalTypes.ValueRequiredState<T>>,\n\t\tpublic readonly value: InternalTypes.ValueRequiredState<T>,\n\t\tcontrolSettings: BroadcastControlSettings | undefined,\n\t) {\n\t\tthis.controls = new OptionalBroadcastControl(controlSettings);\n\t}\n\n\tpublic get presence(): Presence {\n\t\treturn this.datastore.presence;\n\t}\n\n\tpublic get local(): DeepReadonly<JsonDeserialized<T>> {\n\t\treturn asDeeplyReadonlyDeserializedJson(this.value.value);\n\t}\n\n\tpublic set local(value: JsonSerializable<T>) {\n\t\tthis.value.rev += 1;\n\t\tthis.value.timestamp = Date.now();\n\t\tthis.value.value = toOpaqueJson<T>(value);\n\t\tthis.datastore.localUpdate(this.key, this.value, {\n\t\t\tallowableUpdateLatencyMs: this.controls.allowableUpdateLatencyMs,\n\t\t});\n\n\t\tthis.events.emit(\"localUpdated\", { value: asDeeplyReadonly(value) });\n\t}\n\n\tpublic *getRemotes(): IterableIterator<LatestClientData<T>> {\n\t\tconst allKnownStates = this.datastore.knownValues(this.key);\n\t\tfor (const [attendeeId, value] of objectEntries(allKnownStates.states)) {\n\t\t\tif (attendeeId !== allKnownStates.self) {\n\t\t\t\tyield {\n\t\t\t\t\tattendee: this.datastore.presence.attendees.getAttendee(attendeeId),\n\t\t\t\t\tvalue: asDeeplyReadonlyDeserializedJson(value.value),\n\t\t\t\t\tmetadata: { revision: value.rev, timestamp: value.timestamp },\n\t\t\t\t};\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 Object.keys(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): LatestData<T> {\n\t\tconst allKnownStates = this.datastore.knownValues(this.key);\n\t\tconst clientState = allKnownStates.states[attendee.attendeeId];\n\t\tif (clientState === undefined) {\n\t\t\tthrow new Error(\"No entry for clientId\");\n\t\t}\n\t\treturn {\n\t\t\tvalue: asDeeplyReadonlyDeserializedJson(clientState.value),\n\t\t\tmetadata: { revision: clientState.rev, timestamp: Date.now() },\n\t\t};\n\t}\n\n\tpublic update(\n\t\tattendee: Attendee,\n\t\t_received: number,\n\t\tvalue: InternalTypes.ValueRequiredState<T>,\n\t): PostUpdateAction[] {\n\t\tconst allKnownStates = this.datastore.knownValues(this.key);\n\t\tconst attendeeId = attendee.attendeeId;\n\t\tconst currentState = allKnownStates.states[attendeeId];\n\t\tif (currentState !== undefined && currentState.rev >= value.rev) {\n\t\t\treturn [];\n\t\t}\n\t\tthis.datastore.update(this.key, attendeeId, value);\n\t\treturn [\n\t\t\t() =>\n\t\t\t\tthis.events.emit(\"remoteUpdated\", {\n\t\t\t\t\tattendee,\n\t\t\t\t\tvalue: asDeeplyReadonlyDeserializedJson(value.value),\n\t\t\t\t\tmetadata: { revision: value.rev, timestamp: value.timestamp },\n\t\t\t\t}),\n\t\t];\n\t}\n}\n\n/**\n * Shallow clone an object that might be null.\n *\n * @param value - The object to clone\n * @returns A shallow clone of the input value\n */\nexport function shallowCloneNullableObject<T extends object | null>(value: T): T {\n\treturn value === null ? value : shallowCloneObject(value);\n}\n\n/**\n * Arguments that are passed to the {@link StateFactory.latest} function.\n *\n * @input\n * @beta\n */\nexport interface LatestArguments<T extends object | null> {\n\t/**\n\t * The initial value of the local state.\n\t *\n\t * @remarks\n\t * `latest` assumes ownership of the value and its references.\n\t * Make a deep clone before passing, if needed.\n\t */\n\tlocal: JsonSerializable<T>;\n\n\t/**\n\t * See {@link BroadcastControlSettings}.\n\t */\n\tsettings?: BroadcastControlSettings | undefined;\n}\n\n/**\n * Factory for creating a {@link LatestRaw} State object.\n *\n * @beta\n */\nexport function latest<T extends object | null, Key extends string = string>(\n\targs: LatestArguments<T>,\n): InternalTypes.ManagerFactory<Key, InternalTypes.ValueRequiredState<T>, LatestRaw<T>> {\n\tconst { local, settings } = args;\n\n\t// Latest takes ownership of the initial local value but makes a shallow\n\t// copy for basic protection.\n\tconst opaqueLocal = toOpaqueJson<T>(local);\n\tconst value: InternalTypes.ValueRequiredState<T> = {\n\t\trev: 0,\n\t\ttimestamp: Date.now(),\n\t\tvalue: shallowCloneNullableObject(opaqueLocal),\n\t};\n\tconst factory = (\n\t\tkey: Key,\n\t\tdatastoreHandle: InternalTypes.StateDatastoreHandle<\n\t\t\tKey,\n\t\t\tInternalTypes.ValueRequiredState<T>\n\t\t>,\n\t): {\n\t\tinitialData: { value: typeof value; allowableUpdateLatencyMs: number | undefined };\n\t\tmanager: InternalTypes.StateValue<LatestRaw<T>>;\n\t} => ({\n\t\tinitialData: { value, allowableUpdateLatencyMs: settings?.allowableUpdateLatencyMs },\n\t\tmanager: brandIVM<LatestValueManagerImpl<T, Key>, T, InternalTypes.ValueRequiredState<T>>(\n\t\t\tnew LatestValueManagerImpl(key, datastoreFromHandle(datastoreHandle), value, settings),\n\t\t),\n\t});\n\treturn Object.assign(factory, { instanceBase: LatestValueManagerImpl });\n}\n"]}