@fluidframework/presence 2.81.0-374083 → 2.81.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 (168) hide show
  1. package/dist/broadcastControls.d.ts +1 -33
  2. package/dist/broadcastControls.d.ts.map +1 -1
  3. package/dist/broadcastControls.js.map +1 -1
  4. package/dist/broadcastControlsTypes.d.ts +38 -0
  5. package/dist/broadcastControlsTypes.d.ts.map +1 -0
  6. package/dist/broadcastControlsTypes.js +7 -0
  7. package/dist/broadcastControlsTypes.js.map +1 -0
  8. package/dist/exposedInternalTypes.d.ts +3 -3
  9. package/dist/exposedInternalTypes.d.ts.map +1 -1
  10. package/dist/exposedInternalTypes.js.map +1 -1
  11. package/dist/exposedUtilityTypes.d.ts +2 -2
  12. package/dist/exposedUtilityTypes.d.ts.map +1 -1
  13. package/dist/exposedUtilityTypes.js.map +1 -1
  14. package/dist/getPresence.d.ts.map +1 -1
  15. package/dist/getPresence.js.map +1 -1
  16. package/dist/index.d.ts +3 -2
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js.map +1 -1
  19. package/dist/internalUtils.d.ts +1 -3
  20. package/dist/internalUtils.d.ts.map +1 -1
  21. package/dist/internalUtils.js +0 -2
  22. package/dist/internalUtils.js.map +1 -1
  23. package/dist/latestMapValueManager.d.ts +1 -1
  24. package/dist/latestMapValueManager.d.ts.map +1 -1
  25. package/dist/latestMapValueManager.js.map +1 -1
  26. package/dist/latestValueManager.d.ts +1 -8
  27. package/dist/latestValueManager.d.ts.map +1 -1
  28. package/dist/latestValueManager.js +1 -2
  29. package/dist/latestValueManager.js.map +1 -1
  30. package/dist/latestValueTypes.d.ts +1 -1
  31. package/dist/latestValueTypes.d.ts.map +1 -1
  32. package/dist/latestValueTypes.js.map +1 -1
  33. package/dist/notificationsManager.d.ts +1 -102
  34. package/dist/notificationsManager.d.ts.map +1 -1
  35. package/dist/notificationsManager.js.map +1 -1
  36. package/dist/notificationsManagerTypes.d.ts +108 -0
  37. package/dist/notificationsManagerTypes.d.ts.map +1 -0
  38. package/dist/notificationsManagerTypes.js +7 -0
  39. package/dist/notificationsManagerTypes.js.map +1 -0
  40. package/dist/packageVersion.d.ts +1 -1
  41. package/dist/packageVersion.d.ts.map +1 -1
  42. package/dist/packageVersion.js +1 -1
  43. package/dist/packageVersion.js.map +1 -1
  44. package/dist/presence.d.ts +1 -1
  45. package/dist/presence.d.ts.map +1 -1
  46. package/dist/presence.js.map +1 -1
  47. package/dist/presenceDatastoreManager.d.ts +3 -11
  48. package/dist/presenceDatastoreManager.d.ts.map +1 -1
  49. package/dist/presenceDatastoreManager.js +12 -19
  50. package/dist/presenceDatastoreManager.js.map +1 -1
  51. package/dist/presenceManager.d.ts +1 -1
  52. package/dist/presenceManager.d.ts.map +1 -1
  53. package/dist/presenceManager.js +3 -7
  54. package/dist/presenceManager.js.map +1 -1
  55. package/dist/presenceStates.d.ts +4 -2
  56. package/dist/presenceStates.d.ts.map +1 -1
  57. package/dist/presenceStates.js.map +1 -1
  58. package/dist/runtimeTypes.d.ts +26 -0
  59. package/dist/runtimeTypes.d.ts.map +1 -0
  60. package/dist/{internalTypes.js → runtimeTypes.js} +1 -1
  61. package/dist/runtimeTypes.js.map +1 -0
  62. package/dist/stateDatastore.d.ts +11 -2
  63. package/dist/stateDatastore.d.ts.map +1 -1
  64. package/dist/stateDatastore.js.map +1 -1
  65. package/dist/statesManagerTypes.d.ts +27 -0
  66. package/dist/statesManagerTypes.d.ts.map +1 -0
  67. package/dist/statesManagerTypes.js +7 -0
  68. package/dist/statesManagerTypes.js.map +1 -0
  69. package/dist/systemWorkspace.d.ts.map +1 -1
  70. package/dist/systemWorkspace.js +1 -2
  71. package/dist/systemWorkspace.js.map +1 -1
  72. package/dist/types.d.ts +7 -6
  73. package/dist/types.d.ts.map +1 -1
  74. package/dist/types.js.map +1 -1
  75. package/dist/{internalTypes.d.ts → validatableTypes.d.ts} +1 -59
  76. package/dist/validatableTypes.d.ts.map +1 -0
  77. package/dist/validatableTypes.js +7 -0
  78. package/dist/validatableTypes.js.map +1 -0
  79. package/dist/valueManager.d.ts +1 -1
  80. package/dist/valueManager.d.ts.map +1 -1
  81. package/dist/valueManager.js.map +1 -1
  82. package/lib/broadcastControls.d.ts +1 -33
  83. package/lib/broadcastControls.d.ts.map +1 -1
  84. package/lib/broadcastControls.js.map +1 -1
  85. package/lib/broadcastControlsTypes.d.ts +38 -0
  86. package/lib/broadcastControlsTypes.d.ts.map +1 -0
  87. package/lib/broadcastControlsTypes.js +6 -0
  88. package/lib/broadcastControlsTypes.js.map +1 -0
  89. package/lib/exposedInternalTypes.d.ts +3 -3
  90. package/lib/exposedInternalTypes.d.ts.map +1 -1
  91. package/lib/exposedInternalTypes.js.map +1 -1
  92. package/lib/exposedUtilityTypes.d.ts +2 -2
  93. package/lib/exposedUtilityTypes.d.ts.map +1 -1
  94. package/lib/exposedUtilityTypes.js.map +1 -1
  95. package/lib/getPresence.d.ts.map +1 -1
  96. package/lib/getPresence.js.map +1 -1
  97. package/lib/index.d.ts +3 -2
  98. package/lib/index.d.ts.map +1 -1
  99. package/lib/index.js +1 -1
  100. package/lib/index.js.map +1 -1
  101. package/lib/internalUtils.d.ts +1 -3
  102. package/lib/internalUtils.d.ts.map +1 -1
  103. package/lib/internalUtils.js +0 -2
  104. package/lib/internalUtils.js.map +1 -1
  105. package/lib/latestMapValueManager.d.ts +1 -1
  106. package/lib/latestMapValueManager.d.ts.map +1 -1
  107. package/lib/latestMapValueManager.js.map +1 -1
  108. package/lib/latestValueManager.d.ts +1 -8
  109. package/lib/latestValueManager.d.ts.map +1 -1
  110. package/lib/latestValueManager.js +1 -1
  111. package/lib/latestValueManager.js.map +1 -1
  112. package/lib/latestValueTypes.d.ts +1 -1
  113. package/lib/latestValueTypes.d.ts.map +1 -1
  114. package/lib/latestValueTypes.js.map +1 -1
  115. package/lib/notificationsManager.d.ts +1 -102
  116. package/lib/notificationsManager.d.ts.map +1 -1
  117. package/lib/notificationsManager.js.map +1 -1
  118. package/lib/notificationsManagerTypes.d.ts +108 -0
  119. package/lib/notificationsManagerTypes.d.ts.map +1 -0
  120. package/lib/notificationsManagerTypes.js +6 -0
  121. package/lib/notificationsManagerTypes.js.map +1 -0
  122. package/lib/packageVersion.d.ts +1 -1
  123. package/lib/packageVersion.d.ts.map +1 -1
  124. package/lib/packageVersion.js +1 -1
  125. package/lib/packageVersion.js.map +1 -1
  126. package/lib/presence.d.ts +1 -1
  127. package/lib/presence.d.ts.map +1 -1
  128. package/lib/presence.js.map +1 -1
  129. package/lib/presenceDatastoreManager.d.ts +3 -11
  130. package/lib/presenceDatastoreManager.d.ts.map +1 -1
  131. package/lib/presenceDatastoreManager.js +12 -18
  132. package/lib/presenceDatastoreManager.js.map +1 -1
  133. package/lib/presenceManager.d.ts +1 -1
  134. package/lib/presenceManager.d.ts.map +1 -1
  135. package/lib/presenceManager.js +3 -7
  136. package/lib/presenceManager.js.map +1 -1
  137. package/lib/presenceStates.d.ts +4 -2
  138. package/lib/presenceStates.d.ts.map +1 -1
  139. package/lib/presenceStates.js.map +1 -1
  140. package/lib/runtimeTypes.d.ts +26 -0
  141. package/lib/runtimeTypes.d.ts.map +1 -0
  142. package/lib/{internalTypes.js → runtimeTypes.js} +1 -1
  143. package/lib/runtimeTypes.js.map +1 -0
  144. package/lib/stateDatastore.d.ts +11 -2
  145. package/lib/stateDatastore.d.ts.map +1 -1
  146. package/lib/stateDatastore.js.map +1 -1
  147. package/lib/statesManagerTypes.d.ts +27 -0
  148. package/lib/statesManagerTypes.d.ts.map +1 -0
  149. package/lib/statesManagerTypes.js +6 -0
  150. package/lib/statesManagerTypes.js.map +1 -0
  151. package/lib/systemWorkspace.d.ts.map +1 -1
  152. package/lib/systemWorkspace.js +1 -2
  153. package/lib/systemWorkspace.js.map +1 -1
  154. package/lib/types.d.ts +7 -6
  155. package/lib/types.d.ts.map +1 -1
  156. package/lib/types.js.map +1 -1
  157. package/lib/{internalTypes.d.ts → validatableTypes.d.ts} +1 -59
  158. package/lib/validatableTypes.d.ts.map +1 -0
  159. package/lib/validatableTypes.js +6 -0
  160. package/lib/validatableTypes.js.map +1 -0
  161. package/lib/valueManager.d.ts +1 -1
  162. package/lib/valueManager.d.ts.map +1 -1
  163. package/lib/valueManager.js.map +1 -1
  164. package/package.json +16 -16
  165. package/dist/internalTypes.d.ts.map +0 -1
  166. package/dist/internalTypes.js.map +0 -1
  167. package/lib/internalTypes.d.ts.map +0 -1
  168. package/lib/internalTypes.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"latestMapValueManager.js","sourceRoot":"","sources":["../src/latestMapValueManager.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { createEmitter } from \"@fluid-internal/client-utils\";\nimport type { Listenable } from \"@fluidframework/core-interfaces\";\nimport type { IEmitter } from \"@fluidframework/core-interfaces/internal\";\nimport type {\n\tDeepReadonly,\n\tJsonDeserialized,\n\tJsonSerializable,\n} from \"@fluidframework/core-interfaces/internal/exposedUtilityTypes\";\n\nimport type { BroadcastControls, BroadcastControlSettings } from \"./broadcastControls.js\";\nimport { OptionalBroadcastControl } from \"./broadcastControls.js\";\nimport type { InternalTypes } from \"./exposedInternalTypes.js\";\nimport type {\n\tPostUpdateAction,\n\tValidatableOptionalState,\n\tValueManager,\n} from \"./internalTypes.js\";\nimport {\n\tasDeeplyReadonly,\n\tasDeeplyReadonlyDeserializedJson,\n\tisValueRequiredState,\n\tobjectEntries,\n\tobjectKeys,\n\ttoOpaqueJson,\n} from \"./internalUtils.js\";\nimport { createValidatedGetter } from \"./latestValueTypes.js\";\nimport type {\n\tLatestClientData,\n\tLatestData,\n\tLatestMetadata,\n\tProxiedValueAccessor,\n\tRawValueAccessor,\n\tStateSchemaValidator,\n\tValueAccessor,\n} from \"./latestValueTypes.js\";\nimport type { AttendeeId, Attendee, Presence, SpecificAttendee } from \"./presence.js\";\nimport { datastoreFromHandle, type StateDatastore } from \"./stateDatastore.js\";\nimport { brandIVM } from \"./valueManager.js\";\n\n/**\n * A validator function that can optionally be provided to do runtime validation\n * of the custom key listed in a {@link LatestMap}.\n *\n * @param unvalidatedKey - The unknown key that should be validated.\n *\n * @returns True if the key is valid.\n *\n * @beta\n */\nexport type KeySchemaValidator<Keys extends string> = (\n\tunvalidatedKey: string,\n) => unvalidatedKey is Keys;\n\n/**\n * Collection of validatable optional values in a \"map\" structure.\n *\n * @remarks\n * Validatable equivalent of {@link InternalTypes.MapValueState}.\n */\ninterface ValidatableMapValueState<T> {\n\trev: number;\n\titems: {\n\t\t// Caution: any particular item may or may not exist\n\t\t// Typescript does not support absent keys without forcing type to also be undefined.\n\t\t// See https://github.com/microsoft/TypeScript/issues/42810.\n\t\t[name in string]: ValidatableOptionalState<T>;\n\t};\n}\n\n/**\n * Collection of latest known values for a specific {@link Attendee}.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMapClientData<\n\tT,\n\tKeys extends string,\n\tTValueAccessor extends ValueAccessor<T>,\n\tSpecificAttendeeId extends AttendeeId = AttendeeId,\n> {\n\t/**\n\t * Associated {@link Attendee}.\n\t */\n\tattendee: Attendee<SpecificAttendeeId>;\n\n\t/**\n\t * Map of items for the state.\n\t *\n\t * @privateRemarks This could be regular map currently as no Map is\n\t * stored internally and a new instance is created for every request.\n\t */\n\titems: ReadonlyMap<Keys, LatestData<T, TValueAccessor>>;\n}\n\n/**\n * State of a single item value, its key, and its metadata.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMapItemUpdatedClientData<\n\tT,\n\tK extends string,\n\tTValueAccessor extends ValueAccessor<T>,\n> extends LatestClientData<T, TValueAccessor> {\n\t/**\n\t * Key of the updated item.\n\t */\n\tkey: K;\n}\n\n/**\n * Identifier and metadata for a removed item.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMapItemRemovedClientData<K extends string> {\n\t/**\n\t * Associated {@link Attendee}.\n\t */\n\tattendee: Attendee;\n\t/**\n\t * Key of the removed item.\n\t */\n\tkey: K;\n\t/**\n\t * Metadata associated with the removal of the item.\n\t */\n\tmetadata: LatestMetadata;\n}\n\n/**\n * Events from {@link LatestMapRaw}.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMapEvents<\n\tT,\n\tK extends string,\n\tTRemoteValueAccessor extends ValueAccessor<T> = ProxiedValueAccessor<T>,\n> {\n\t/**\n\t * Raised when any item's value for remote client is updated.\n\t * @param updates - Map of one or more values updated.\n\t *\n\t * @remarks The event does not include item removals.\n\t *\n\t * @eventProperty\n\t */\n\tremoteUpdated: (updates: LatestMapClientData<T, K, TRemoteValueAccessor>) => void;\n\n\t/**\n\t * Raised when specific item's value of remote client is updated.\n\t * @param updatedItem - Updated item value.\n\t *\n\t * @eventProperty\n\t */\n\tremoteItemUpdated: (\n\t\tupdatedItem: LatestMapItemUpdatedClientData<T, K, TRemoteValueAccessor>,\n\t) => void;\n\n\t/**\n\t * Raised when specific item of remote client is removed.\n\t * @param removedItem - Removed item.\n\t *\n\t * @eventProperty\n\t */\n\tremoteItemRemoved: (removedItem: LatestMapItemRemovedClientData<K>) => void;\n\n\t/**\n\t * Raised when specific local item's value is updated.\n\t * @param updatedItem - Updated item value.\n\t *\n\t * @eventProperty\n\t */\n\tlocalItemUpdated: (updatedItem: {\n\t\tvalue: DeepReadonly<JsonSerializable<T>>;\n\t\tkey: K;\n\t}) => void;\n\n\t/**\n\t * Raised when specific local item is removed.\n\t * @param removedItem - Removed item.\n\t *\n\t * @eventProperty\n\t */\n\tlocalItemRemoved: (removedItem: {\n\t\tkey: K;\n\t}) => void;\n}\n\n/**\n * Events from {@link LatestMapRaw}.\n *\n * @sealed\n * @beta\n */\nexport type LatestMapRawEvents<T, K extends string> = LatestMapEvents<\n\tT,\n\tK,\n\tRawValueAccessor<T>\n>;\n\n/**\n * Map of local client's values. Modifications are transmitted to all other connected clients.\n *\n * @sealed\n * @beta\n */\nexport interface StateMap<K extends string, 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> implements StateMap<K, T> {\n\tprivate countDefined: number;\n\tpublic constructor(\n\t\tprivate readonly value: InternalTypes.MapValueState<T, K>,\n\t\tprivate readonly emitter: IEmitter<\n\t\t\tPick<LatestMapEvents<T, K, ValueAccessor<T>>, \"localItemUpdated\" | \"localItemRemoved\">\n\t\t>,\n\t\tprivate readonly localUpdate: (\n\t\t\tupdates: InternalTypes.MapValueState<\n\t\t\t\tT,\n\t\t\t\t// This should be `K`, but will only work if properties are optional.\n\t\t\t\tstring\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\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\t// TODO: AB#55932: try fixing typing of objectEntries to avoid this cast\n\t\t\t\tcallbackfn(asDeeplyReadonlyDeserializedJson(item.value), key as unknown as K, 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\t// TODO: AB#55932: try fixing typing of objectEntries to avoid this cast\n\t\t\t\tkeys.push(key as unknown as K);\n\t\t\t}\n\t\t}\n\t\treturn keys[Symbol.iterator]();\n\t}\n}\n\n/**\n * State that provides a `Map` of latest known values from this client to\n * others and read access to their values.\n * Entries in the map may vary over time and by client, but all values are expected to\n * be of the same type, which may be a union type.\n *\n * @remarks Create using {@link StateFactory.latestMap} registered to {@link StatesWorkspace}.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMap<\n\tT,\n\tKeys extends string = string,\n\tTRemoteAccessor extends ValueAccessor<T> = ProxiedValueAccessor<T>,\n> {\n\t/**\n\t * Containing {@link Presence}\n\t */\n\treadonly presence: Presence;\n\n\t/**\n\t * Events for LatestMap.\n\t */\n\treadonly events: Listenable<LatestMapEvents<T, Keys, TRemoteAccessor>>;\n\n\t/**\n\t * Controls for management of sending updates.\n\t */\n\treadonly controls: BroadcastControls;\n\n\t/**\n\t * Current value map for this client.\n\t */\n\treadonly local: StateMap<Keys, T>;\n\t/**\n\t * Iterable access to remote clients' map of values.\n\t */\n\tgetRemotes(): IterableIterator<LatestMapClientData<T, Keys, TRemoteAccessor>>;\n\t/**\n\t * Array of {@link Attendee}s that have provided states.\n\t */\n\tgetStateAttendees(): Attendee[];\n\t/**\n\t * Access to a specific client's map of values.\n\t */\n\tgetRemote(attendee: Attendee): ReadonlyMap<Keys, LatestData<T, TRemoteAccessor>>;\n}\n\n/**\n * State that provides a `Map` of latest known values from this client to\n * others and read access to their values.\n * Entries in the map may vary over time and by client, but all values are expected to\n * be of the same type, which may be a union type.\n *\n * @remarks Create using {@link StateFactory.latestMap} registered to {@link StatesWorkspace}.\n *\n * @sealed\n * @beta\n */\nexport type LatestMapRaw<T, Keys extends string = string> = LatestMap<\n\tT,\n\tKeys,\n\tRawValueAccessor<T>\n>;\n\n/**\n * Simply returns true for all given string keys.\n */\nfunction anyKeyIsValid<Keys extends string>(unvalidatedKey: string): unvalidatedKey is Keys {\n\treturn true;\n}\n\nclass LatestMapValueManagerImpl<\n\tT,\n\tRegistrationKey extends string,\n\tKeys extends string = string,\n> implements\n\t\tLatestMapRaw<T, Keys>,\n\t\tLatestMap<T, Keys>,\n\t\tRequired<ValueManager<T, InternalTypes.MapValueState<T, Keys>>>\n{\n\tpublic readonly events = createEmitter<LatestMapEvents<T, Keys, ValueAccessor<T>>>();\n\tpublic readonly controls: OptionalBroadcastControl;\n\n\tpublic constructor(\n\t\tprivate readonly key: RegistrationKey,\n\t\tprivate readonly datastore: StateDatastore<\n\t\t\tRegistrationKey,\n\t\t\tInternalTypes.MapValueState<T, Keys>,\n\t\t\tValidatableMapValueState<T>\n\t\t>,\n\t\tpublic readonly value: InternalTypes.MapValueState<T, Keys>,\n\t\tcontrolSettings: BroadcastControlSettings | undefined,\n\t\tprivate readonly validator: StateSchemaValidator<T> | undefined,\n\t\tprivate readonly isValidKey: KeySchemaValidator<Keys>,\n\t) {\n\t\tthis.controls = new OptionalBroadcastControl(controlSettings);\n\n\t\tthis.local = new ValueMapImpl<T, Keys>(\n\t\t\tvalue,\n\t\t\tthis.events,\n\t\t\t(updates: InternalTypes.MapValueState<T, Keys>) => {\n\t\t\t\tdatastore.localUpdate(key, updates, {\n\t\t\t\t\tallowableUpdateLatencyMs: this.controls.allowableUpdateLatencyMs,\n\t\t\t\t});\n\t\t\t},\n\t\t);\n\t}\n\n\tpublic get presence(): Presence {\n\t\treturn this.datastore.presence;\n\t}\n\n\tpublic readonly local: StateMap<Keys, T>;\n\n\tpublic *getRemotes(): IterableIterator<LatestMapClientData<T, Keys, ValueAccessor<T>>> {\n\t\tconst allKnownStates = this.datastore.knownValues(this.key);\n\t\tfor (const attendeeId of objectKeys(allKnownStates.states)) {\n\t\t\tif (attendeeId !== allKnownStates.self) {\n\t\t\t\tconst attendee = this.datastore.presence.attendees.getAttendee(attendeeId);\n\t\t\t\tconst items = this.getRemote(attendee);\n\t\t\t\tyield { attendee, items };\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic getStateAttendees(): Attendee[] {\n\t\tconst allKnownStates = this.datastore.knownValues(this.key);\n\t\treturn objectKeys(allKnownStates.states)\n\t\t\t.filter((attendeeId) => attendeeId !== allKnownStates.self)\n\t\t\t.map((attendeeId) => this.datastore.presence.attendees.getAttendee(attendeeId));\n\t}\n\n\tpublic getRemote(attendee: Attendee): ReadonlyMap<Keys, LatestData<T, ValueAccessor<T>>> {\n\t\tconst validator = this.validator;\n\t\tconst allKnownStates = this.datastore.knownValues(this.key);\n\t\tconst attendeeId = attendee.attendeeId;\n\t\tconst clientStateMap = allKnownStates.states[attendeeId];\n\t\tif (clientStateMap === undefined) {\n\t\t\tthrow new Error(\"No entry for attendee\");\n\t\t}\n\t\tconst items = new Map<Keys, LatestData<T, ValueAccessor<T>>>();\n\t\tfor (const [key, item] of objectEntries(clientStateMap.items)) {\n\t\t\tif (this.isValidKey(key) && isValueRequiredState(item)) {\n\t\t\t\titems.set(key, {\n\t\t\t\t\tvalue: createValidatedGetter(item, validator),\n\t\t\t\t\tmetadata: { revision: item.rev, timestamp: item.timestamp },\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn items;\n\t}\n\n\tpublic update<SpecificAttendeeId extends AttendeeId>(\n\t\tattendee: SpecificAttendee<SpecificAttendeeId>,\n\t\t_received: number,\n\t\tvalue: InternalTypes.MapValueState<T, string>,\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: {},\n\t\t\t});\n\t\t// Accumulate individual update keys\n\t\tconst updatedKeyItemPairs: [string, InternalTypes.ValueOptionalState<T>][] = [];\n\t\tfor (const [key, item] of objectEntries(value.items)) {\n\t\t\tconst currentItem = currentState.items[key];\n\t\t\tif (currentItem === undefined || currentItem.rev < item.rev) {\n\t\t\t\tupdatedKeyItemPairs.push([key, item]);\n\t\t\t}\n\t\t}\n\n\t\tif (updatedKeyItemPairs.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\t// Store updates\n\t\tif (value.rev > currentState.rev) {\n\t\t\tcurrentState.rev = value.rev;\n\t\t}\n\t\tconst allUpdates = {\n\t\t\tattendee,\n\t\t\titems: new Map<Keys, LatestData<T, ValueAccessor<T>>>(),\n\t\t};\n\t\tconst postUpdateActions: PostUpdateAction[] = [];\n\t\tfor (const [key, item] of updatedKeyItemPairs) {\n\t\t\tconst hadPriorValue = currentState.items[key]?.value;\n\t\t\tcurrentState.items[key] = item;\n\n\t\t\t// Prepare update events, but only for valid keys.\n\t\t\tif (!this.isValidKey(key)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst metadata = {\n\t\t\t\trevision: item.rev,\n\t\t\t\ttimestamp: item.timestamp,\n\t\t\t};\n\t\t\tif (isValueRequiredState(item)) {\n\t\t\t\tconst updatedItem = {\n\t\t\t\t\tattendee,\n\t\t\t\t\tkey,\n\t\t\t\t\tvalue: createValidatedGetter(item, this.validator),\n\t\t\t\t\tmetadata,\n\t\t\t\t} satisfies LatestMapItemUpdatedClientData<T, Keys, ValueAccessor<T>>;\n\t\t\t\tpostUpdateActions.push(() => this.events.emit(\"remoteItemUpdated\", updatedItem));\n\t\t\t\tallUpdates.items.set(key, {\n\t\t\t\t\tvalue: updatedItem.value,\n\t\t\t\t\tmetadata,\n\t\t\t\t});\n\t\t\t} else if (hadPriorValue !== undefined) {\n\t\t\t\tpostUpdateActions.push(() =>\n\t\t\t\t\tthis.events.emit(\"remoteItemRemoved\", {\n\t\t\t\t\t\tattendee,\n\t\t\t\t\t\tkey,\n\t\t\t\t\t\tmetadata,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tthis.datastore.update(this.key, attendeeId, currentState);\n\t\t// Only emit remoteUpdated if there are any individual updates, which\n\t\t// accounts for the case where all updates were for invalid keys.\n\t\tif (postUpdateActions.length > 0) {\n\t\t\tpostUpdateActions.push(() => this.events.emit(\"remoteUpdated\", allUpdates));\n\t\t}\n\t\treturn postUpdateActions;\n\t}\n}\n\n/**\n * Arguments that are passed to the {@link StateFactory.latestMap} function.\n *\n * @input\n * @beta\n */\nexport interface LatestMapArgumentsRaw<T, Keys extends string = string> {\n\t/**\n\t * The initial value of the local state.\n\t */\n\tlocal?: {\n\t\t[K in Keys]: JsonSerializable<T>;\n\t};\n\n\t/**\n\t * See {@link BroadcastControlSettings}.\n\t */\n\tsettings?: BroadcastControlSettings | undefined;\n}\n\n/**\n * Arguments that are passed to the {@link StateFactory.latestMap} function.\n *\n * @input\n * @beta\n */\nexport interface LatestMapArguments<T, Keys extends string = string>\n\textends LatestMapArgumentsRaw<T, Keys> {\n\t/**\n\t * An optional function that will be called at runtime to validate data value\n\t * under a key. A runtime validator is strongly recommended.\n\t * @see {@link StateSchemaValidator}.\n\t */\n\tvalidator: StateSchemaValidator<T>;\n\t/**\n\t * An optional function that will be called at runtime to validate the presence\n\t * data key. A runtime validator is strongly recommended when key type is not\n\t * simply `string`.\n\t * @see {@link KeySchemaValidator}.\n\t */\n\tkeyValidator?: KeySchemaValidator<Keys>;\n}\n\n// #region factory function overloads\n// Overloads should be ordered from most specific to least specific when combined.\n\n/**\n * Factory for creating a {@link LatestMap} or {@link LatestMapRaw} State object.\n *\n * @beta\n * @sealed\n */\nexport interface LatestMapFactory {\n\t/**\n\t * Factory for creating a {@link LatestMap} State object.\n\t *\n\t * @remarks\n\t * This overload is used when called with {@link LatestMapArguments}.\n\t * That is, if a validator function is provided.\n\t */\n\t<T, Keys extends string = string, RegistrationKey extends string = string>(\n\t\targs: LatestMapArguments<T, Keys>,\n\t): InternalTypes.ManagerFactory<\n\t\tRegistrationKey,\n\t\tInternalTypes.MapValueState<T, Keys>,\n\t\tLatestMap<T, Keys>\n\t>;\n\n\t/**\n\t * Factory for creating a {@link LatestMapRaw} State object.\n\t *\n\t * @remarks\n\t * This overload is used when called with {@link LatestMapArgumentsRaw}.\n\t * That is, if a validator function is _not_ provided.\n\t */\n\t<T, Keys extends string = string, RegistrationKey extends string = string>(\n\t\targs?: LatestMapArgumentsRaw<T, Keys>,\n\t): InternalTypes.ManagerFactory<\n\t\tRegistrationKey,\n\t\tInternalTypes.MapValueState<T, Keys>,\n\t\tLatestMapRaw<T, Keys>\n\t>;\n}\n\n// #endregion\n\n/**\n * Factory for creating a {@link LatestMap} or {@link LatestMapRaw} State object.\n */\nexport const latestMap: LatestMapFactory = <\n\tT,\n\tKeys extends string = string,\n\tRegistrationKey extends string = string,\n>(\n\targs?: Partial<LatestMapArguments<T, Keys>>,\n): InternalTypes.ManagerFactory<\n\tRegistrationKey,\n\tInternalTypes.MapValueState<T, Keys>,\n\tLatestMapRaw<T, Keys> & LatestMap<T, Keys>\n> => {\n\tconst settings = args?.settings;\n\tconst initialValues = args?.local;\n\tconst validator = args?.validator;\n\tconst isKeyValid = args?.keyValidator ?? anyKeyIsValid;\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\n\t> = { rev: 0, items: {} };\n\t// LatestMapRaw takes ownership of values within initialValues.\n\tif (initialValues !== undefined) {\n\t\tfor (const [key, item] of objectEntries(initialValues)) {\n\t\t\t// TODO: AB#55932: try fixing typing of objectEntries to avoid this cast\n\t\t\tconst assumedValidKey = key as unknown as Keys;\n\t\t\tvalue.items[assumedValidKey] = {\n\t\t\t\trev: 0,\n\t\t\t\ttimestamp,\n\t\t\t\tvalue: toOpaqueJson(item),\n\t\t\t};\n\t\t}\n\t}\n\tconst factory = (\n\t\tkey: RegistrationKey,\n\t\tdatastoreHandle: InternalTypes.StateDatastoreHandle<\n\t\t\tRegistrationKey,\n\t\t\tInternalTypes.MapValueState<T, Keys>\n\t\t>,\n\t): {\n\t\tinitialData: { value: typeof value; allowableUpdateLatencyMs: number | undefined };\n\t\tmanager: InternalTypes.StateValue<LatestMapRaw<T, Keys> & LatestMap<T, Keys>>;\n\t} => ({\n\t\tinitialData: { value, allowableUpdateLatencyMs: settings?.allowableUpdateLatencyMs },\n\t\tmanager: brandIVM<\n\t\t\tLatestMapValueManagerImpl<T, RegistrationKey, Keys>,\n\t\t\tT,\n\t\t\tInternalTypes.MapValueState<T, Keys>\n\t\t>(\n\t\t\tnew LatestMapValueManagerImpl(\n\t\t\t\tkey,\n\t\t\t\tdatastoreFromHandle(datastoreHandle),\n\t\t\t\tvalue,\n\t\t\t\tsettings,\n\t\t\t\tvalidator,\n\t\t\t\tisKeyValid,\n\t\t\t),\n\t\t),\n\t});\n\treturn Object.assign(factory, { instanceBase: LatestMapValueManagerImpl });\n};\n"]}
1
+ {"version":3,"file":"latestMapValueManager.js","sourceRoot":"","sources":["../src/latestMapValueManager.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { createEmitter } from \"@fluid-internal/client-utils\";\nimport type { Listenable } from \"@fluidframework/core-interfaces\";\nimport type { IEmitter } from \"@fluidframework/core-interfaces/internal\";\nimport type {\n\tDeepReadonly,\n\tJsonDeserialized,\n\tJsonSerializable,\n} from \"@fluidframework/core-interfaces/internal/exposedUtilityTypes\";\n\nimport { OptionalBroadcastControl } from \"./broadcastControls.js\";\nimport type { BroadcastControls, BroadcastControlSettings } from \"./broadcastControlsTypes.js\";\nimport type { InternalTypes } from \"./exposedInternalTypes.js\";\nimport {\n\tasDeeplyReadonly,\n\tasDeeplyReadonlyDeserializedJson,\n\tisValueRequiredState,\n\tobjectEntries,\n\tobjectKeys,\n\ttoOpaqueJson,\n} from \"./internalUtils.js\";\nimport { createValidatedGetter } from \"./latestValueTypes.js\";\nimport type {\n\tLatestClientData,\n\tLatestData,\n\tLatestMetadata,\n\tProxiedValueAccessor,\n\tRawValueAccessor,\n\tStateSchemaValidator,\n\tValueAccessor,\n} from \"./latestValueTypes.js\";\nimport type { AttendeeId, Attendee, Presence, SpecificAttendee } from \"./presence.js\";\nimport { datastoreFromHandle, type StateDatastore } from \"./stateDatastore.js\";\nimport type { PostUpdateAction, ValueManager } from \"./statesManagerTypes.js\";\nimport type { ValidatableOptionalState } from \"./validatableTypes.js\";\nimport { brandIVM } from \"./valueManager.js\";\n\n/**\n * A validator function that can optionally be provided to do runtime validation\n * of the custom key listed in a {@link LatestMap}.\n *\n * @param unvalidatedKey - The unknown key that should be validated.\n *\n * @returns True if the key is valid.\n *\n * @beta\n */\nexport type KeySchemaValidator<Keys extends string> = (\n\tunvalidatedKey: string,\n) => unvalidatedKey is Keys;\n\n/**\n * Collection of validatable optional values in a \"map\" structure.\n *\n * @remarks\n * Validatable equivalent of {@link InternalTypes.MapValueState}.\n */\ninterface ValidatableMapValueState<T> {\n\trev: number;\n\titems: {\n\t\t// Caution: any particular item may or may not exist\n\t\t// Typescript does not support absent keys without forcing type to also be undefined.\n\t\t// See https://github.com/microsoft/TypeScript/issues/42810.\n\t\t[name in string]: ValidatableOptionalState<T>;\n\t};\n}\n\n/**\n * Collection of latest known values for a specific {@link Attendee}.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMapClientData<\n\tT,\n\tKeys extends string,\n\tTValueAccessor extends ValueAccessor<T>,\n\tSpecificAttendeeId extends AttendeeId = AttendeeId,\n> {\n\t/**\n\t * Associated {@link Attendee}.\n\t */\n\tattendee: Attendee<SpecificAttendeeId>;\n\n\t/**\n\t * Map of items for the state.\n\t *\n\t * @privateRemarks This could be regular map currently as no Map is\n\t * stored internally and a new instance is created for every request.\n\t */\n\titems: ReadonlyMap<Keys, LatestData<T, TValueAccessor>>;\n}\n\n/**\n * State of a single item value, its key, and its metadata.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMapItemUpdatedClientData<\n\tT,\n\tK extends string,\n\tTValueAccessor extends ValueAccessor<T>,\n> extends LatestClientData<T, TValueAccessor> {\n\t/**\n\t * Key of the updated item.\n\t */\n\tkey: K;\n}\n\n/**\n * Identifier and metadata for a removed item.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMapItemRemovedClientData<K extends string> {\n\t/**\n\t * Associated {@link Attendee}.\n\t */\n\tattendee: Attendee;\n\t/**\n\t * Key of the removed item.\n\t */\n\tkey: K;\n\t/**\n\t * Metadata associated with the removal of the item.\n\t */\n\tmetadata: LatestMetadata;\n}\n\n/**\n * Events from {@link LatestMapRaw}.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMapEvents<\n\tT,\n\tK extends string,\n\tTRemoteValueAccessor extends ValueAccessor<T> = ProxiedValueAccessor<T>,\n> {\n\t/**\n\t * Raised when any item's value for remote client is updated.\n\t * @param updates - Map of one or more values updated.\n\t *\n\t * @remarks The event does not include item removals.\n\t *\n\t * @eventProperty\n\t */\n\tremoteUpdated: (updates: LatestMapClientData<T, K, TRemoteValueAccessor>) => void;\n\n\t/**\n\t * Raised when specific item's value of remote client is updated.\n\t * @param updatedItem - Updated item value.\n\t *\n\t * @eventProperty\n\t */\n\tremoteItemUpdated: (\n\t\tupdatedItem: LatestMapItemUpdatedClientData<T, K, TRemoteValueAccessor>,\n\t) => void;\n\n\t/**\n\t * Raised when specific item of remote client is removed.\n\t * @param removedItem - Removed item.\n\t *\n\t * @eventProperty\n\t */\n\tremoteItemRemoved: (removedItem: LatestMapItemRemovedClientData<K>) => void;\n\n\t/**\n\t * Raised when specific local item's value is updated.\n\t * @param updatedItem - Updated item value.\n\t *\n\t * @eventProperty\n\t */\n\tlocalItemUpdated: (updatedItem: {\n\t\tvalue: DeepReadonly<JsonSerializable<T>>;\n\t\tkey: K;\n\t}) => void;\n\n\t/**\n\t * Raised when specific local item is removed.\n\t * @param removedItem - Removed item.\n\t *\n\t * @eventProperty\n\t */\n\tlocalItemRemoved: (removedItem: {\n\t\tkey: K;\n\t}) => void;\n}\n\n/**\n * Events from {@link LatestMapRaw}.\n *\n * @sealed\n * @beta\n */\nexport type LatestMapRawEvents<T, K extends string> = LatestMapEvents<\n\tT,\n\tK,\n\tRawValueAccessor<T>\n>;\n\n/**\n * Map of local client's values. Modifications are transmitted to all other connected clients.\n *\n * @sealed\n * @beta\n */\nexport interface StateMap<K extends string, 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> implements StateMap<K, T> {\n\tprivate countDefined: number;\n\tpublic constructor(\n\t\tprivate readonly value: InternalTypes.MapValueState<T, K>,\n\t\tprivate readonly emitter: IEmitter<\n\t\t\tPick<LatestMapEvents<T, K, ValueAccessor<T>>, \"localItemUpdated\" | \"localItemRemoved\">\n\t\t>,\n\t\tprivate readonly localUpdate: (\n\t\t\tupdates: InternalTypes.MapValueState<\n\t\t\t\tT,\n\t\t\t\t// This should be `K`, but will only work if properties are optional.\n\t\t\t\tstring\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\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\t// TODO: AB#55932: try fixing typing of objectEntries to avoid this cast\n\t\t\t\tcallbackfn(asDeeplyReadonlyDeserializedJson(item.value), key as unknown as K, 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\t// TODO: AB#55932: try fixing typing of objectEntries to avoid this cast\n\t\t\t\tkeys.push(key as unknown as K);\n\t\t\t}\n\t\t}\n\t\treturn keys[Symbol.iterator]();\n\t}\n}\n\n/**\n * State that provides a `Map` of latest known values from this client to\n * others and read access to their values.\n * Entries in the map may vary over time and by client, but all values are expected to\n * be of the same type, which may be a union type.\n *\n * @remarks Create using {@link StateFactory.latestMap} registered to {@link StatesWorkspace}.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMap<\n\tT,\n\tKeys extends string = string,\n\tTRemoteAccessor extends ValueAccessor<T> = ProxiedValueAccessor<T>,\n> {\n\t/**\n\t * Containing {@link Presence}\n\t */\n\treadonly presence: Presence;\n\n\t/**\n\t * Events for LatestMap.\n\t */\n\treadonly events: Listenable<LatestMapEvents<T, Keys, TRemoteAccessor>>;\n\n\t/**\n\t * Controls for management of sending updates.\n\t */\n\treadonly controls: BroadcastControls;\n\n\t/**\n\t * Current value map for this client.\n\t */\n\treadonly local: StateMap<Keys, T>;\n\t/**\n\t * Iterable access to remote clients' map of values.\n\t */\n\tgetRemotes(): IterableIterator<LatestMapClientData<T, Keys, TRemoteAccessor>>;\n\t/**\n\t * Array of {@link Attendee}s that have provided states.\n\t */\n\tgetStateAttendees(): Attendee[];\n\t/**\n\t * Access to a specific client's map of values.\n\t */\n\tgetRemote(attendee: Attendee): ReadonlyMap<Keys, LatestData<T, TRemoteAccessor>>;\n}\n\n/**\n * State that provides a `Map` of latest known values from this client to\n * others and read access to their values.\n * Entries in the map may vary over time and by client, but all values are expected to\n * be of the same type, which may be a union type.\n *\n * @remarks Create using {@link StateFactory.latestMap} registered to {@link StatesWorkspace}.\n *\n * @sealed\n * @beta\n */\nexport type LatestMapRaw<T, Keys extends string = string> = LatestMap<\n\tT,\n\tKeys,\n\tRawValueAccessor<T>\n>;\n\n/**\n * Simply returns true for all given string keys.\n */\nfunction anyKeyIsValid<Keys extends string>(unvalidatedKey: string): unvalidatedKey is Keys {\n\treturn true;\n}\n\nclass LatestMapValueManagerImpl<\n\tT,\n\tRegistrationKey extends string,\n\tKeys extends string = string,\n> implements\n\t\tLatestMapRaw<T, Keys>,\n\t\tLatestMap<T, Keys>,\n\t\tRequired<ValueManager<T, InternalTypes.MapValueState<T, Keys>>>\n{\n\tpublic readonly events = createEmitter<LatestMapEvents<T, Keys, ValueAccessor<T>>>();\n\tpublic readonly controls: OptionalBroadcastControl;\n\n\tpublic constructor(\n\t\tprivate readonly key: RegistrationKey,\n\t\tprivate readonly datastore: StateDatastore<\n\t\t\tRegistrationKey,\n\t\t\tInternalTypes.MapValueState<T, Keys>,\n\t\t\tValidatableMapValueState<T>\n\t\t>,\n\t\tpublic readonly value: InternalTypes.MapValueState<T, Keys>,\n\t\tcontrolSettings: BroadcastControlSettings | undefined,\n\t\tprivate readonly validator: StateSchemaValidator<T> | undefined,\n\t\tprivate readonly isValidKey: KeySchemaValidator<Keys>,\n\t) {\n\t\tthis.controls = new OptionalBroadcastControl(controlSettings);\n\n\t\tthis.local = new ValueMapImpl<T, Keys>(\n\t\t\tvalue,\n\t\t\tthis.events,\n\t\t\t(updates: InternalTypes.MapValueState<T, Keys>) => {\n\t\t\t\tdatastore.localUpdate(key, updates, {\n\t\t\t\t\tallowableUpdateLatencyMs: this.controls.allowableUpdateLatencyMs,\n\t\t\t\t});\n\t\t\t},\n\t\t);\n\t}\n\n\tpublic get presence(): Presence {\n\t\treturn this.datastore.presence;\n\t}\n\n\tpublic readonly local: StateMap<Keys, T>;\n\n\tpublic *getRemotes(): IterableIterator<LatestMapClientData<T, Keys, ValueAccessor<T>>> {\n\t\tconst allKnownStates = this.datastore.knownValues(this.key);\n\t\tfor (const attendeeId of objectKeys(allKnownStates.states)) {\n\t\t\tif (attendeeId !== allKnownStates.self) {\n\t\t\t\tconst attendee = this.datastore.presence.attendees.getAttendee(attendeeId);\n\t\t\t\tconst items = this.getRemote(attendee);\n\t\t\t\tyield { attendee, items };\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic getStateAttendees(): Attendee[] {\n\t\tconst allKnownStates = this.datastore.knownValues(this.key);\n\t\treturn objectKeys(allKnownStates.states)\n\t\t\t.filter((attendeeId) => attendeeId !== allKnownStates.self)\n\t\t\t.map((attendeeId) => this.datastore.presence.attendees.getAttendee(attendeeId));\n\t}\n\n\tpublic getRemote(attendee: Attendee): ReadonlyMap<Keys, LatestData<T, ValueAccessor<T>>> {\n\t\tconst validator = this.validator;\n\t\tconst allKnownStates = this.datastore.knownValues(this.key);\n\t\tconst attendeeId = attendee.attendeeId;\n\t\tconst clientStateMap = allKnownStates.states[attendeeId];\n\t\tif (clientStateMap === undefined) {\n\t\t\tthrow new Error(\"No entry for attendee\");\n\t\t}\n\t\tconst items = new Map<Keys, LatestData<T, ValueAccessor<T>>>();\n\t\tfor (const [key, item] of objectEntries(clientStateMap.items)) {\n\t\t\tif (this.isValidKey(key) && isValueRequiredState(item)) {\n\t\t\t\titems.set(key, {\n\t\t\t\t\tvalue: createValidatedGetter(item, validator),\n\t\t\t\t\tmetadata: { revision: item.rev, timestamp: item.timestamp },\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn items;\n\t}\n\n\tpublic update<SpecificAttendeeId extends AttendeeId>(\n\t\tattendee: SpecificAttendee<SpecificAttendeeId>,\n\t\t_received: number,\n\t\tvalue: InternalTypes.MapValueState<T, string>,\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: {},\n\t\t\t});\n\t\t// Accumulate individual update keys\n\t\tconst updatedKeyItemPairs: [string, InternalTypes.ValueOptionalState<T>][] = [];\n\t\tfor (const [key, item] of objectEntries(value.items)) {\n\t\t\tconst currentItem = currentState.items[key];\n\t\t\tif (currentItem === undefined || currentItem.rev < item.rev) {\n\t\t\t\tupdatedKeyItemPairs.push([key, item]);\n\t\t\t}\n\t\t}\n\n\t\tif (updatedKeyItemPairs.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\t// Store updates\n\t\tif (value.rev > currentState.rev) {\n\t\t\tcurrentState.rev = value.rev;\n\t\t}\n\t\tconst allUpdates = {\n\t\t\tattendee,\n\t\t\titems: new Map<Keys, LatestData<T, ValueAccessor<T>>>(),\n\t\t};\n\t\tconst postUpdateActions: PostUpdateAction[] = [];\n\t\tfor (const [key, item] of updatedKeyItemPairs) {\n\t\t\tconst hadPriorValue = currentState.items[key]?.value;\n\t\t\tcurrentState.items[key] = item;\n\n\t\t\t// Prepare update events, but only for valid keys.\n\t\t\tif (!this.isValidKey(key)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst metadata = {\n\t\t\t\trevision: item.rev,\n\t\t\t\ttimestamp: item.timestamp,\n\t\t\t};\n\t\t\tif (isValueRequiredState(item)) {\n\t\t\t\tconst updatedItem = {\n\t\t\t\t\tattendee,\n\t\t\t\t\tkey,\n\t\t\t\t\tvalue: createValidatedGetter(item, this.validator),\n\t\t\t\t\tmetadata,\n\t\t\t\t} satisfies LatestMapItemUpdatedClientData<T, Keys, ValueAccessor<T>>;\n\t\t\t\tpostUpdateActions.push(() => this.events.emit(\"remoteItemUpdated\", updatedItem));\n\t\t\t\tallUpdates.items.set(key, {\n\t\t\t\t\tvalue: updatedItem.value,\n\t\t\t\t\tmetadata,\n\t\t\t\t});\n\t\t\t} else if (hadPriorValue !== undefined) {\n\t\t\t\tpostUpdateActions.push(() =>\n\t\t\t\t\tthis.events.emit(\"remoteItemRemoved\", {\n\t\t\t\t\t\tattendee,\n\t\t\t\t\t\tkey,\n\t\t\t\t\t\tmetadata,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tthis.datastore.update(this.key, attendeeId, currentState);\n\t\t// Only emit remoteUpdated if there are any individual updates, which\n\t\t// accounts for the case where all updates were for invalid keys.\n\t\tif (postUpdateActions.length > 0) {\n\t\t\tpostUpdateActions.push(() => this.events.emit(\"remoteUpdated\", allUpdates));\n\t\t}\n\t\treturn postUpdateActions;\n\t}\n}\n\n/**\n * Arguments that are passed to the {@link StateFactory.latestMap} function.\n *\n * @input\n * @beta\n */\nexport interface LatestMapArgumentsRaw<T, Keys extends string = string> {\n\t/**\n\t * The initial value of the local state.\n\t */\n\tlocal?: {\n\t\t[K in Keys]: JsonSerializable<T>;\n\t};\n\n\t/**\n\t * See {@link BroadcastControlSettings}.\n\t */\n\tsettings?: BroadcastControlSettings | undefined;\n}\n\n/**\n * Arguments that are passed to the {@link StateFactory.latestMap} function.\n *\n * @input\n * @beta\n */\nexport interface LatestMapArguments<T, Keys extends string = string>\n\textends LatestMapArgumentsRaw<T, Keys> {\n\t/**\n\t * An optional function that will be called at runtime to validate data value\n\t * under a key. A runtime validator is strongly recommended.\n\t * @see {@link StateSchemaValidator}.\n\t */\n\tvalidator: StateSchemaValidator<T>;\n\t/**\n\t * An optional function that will be called at runtime to validate the presence\n\t * data key. A runtime validator is strongly recommended when key type is not\n\t * simply `string`.\n\t * @see {@link KeySchemaValidator}.\n\t */\n\tkeyValidator?: KeySchemaValidator<Keys>;\n}\n\n// #region factory function overloads\n// Overloads should be ordered from most specific to least specific when combined.\n\n/**\n * Factory for creating a {@link LatestMap} or {@link LatestMapRaw} State object.\n *\n * @beta\n * @sealed\n */\nexport interface LatestMapFactory {\n\t/**\n\t * Factory for creating a {@link LatestMap} State object.\n\t *\n\t * @remarks\n\t * This overload is used when called with {@link LatestMapArguments}.\n\t * That is, if a validator function is provided.\n\t */\n\t<T, Keys extends string = string, RegistrationKey extends string = string>(\n\t\targs: LatestMapArguments<T, Keys>,\n\t): InternalTypes.ManagerFactory<\n\t\tRegistrationKey,\n\t\tInternalTypes.MapValueState<T, Keys>,\n\t\tLatestMap<T, Keys>\n\t>;\n\n\t/**\n\t * Factory for creating a {@link LatestMapRaw} State object.\n\t *\n\t * @remarks\n\t * This overload is used when called with {@link LatestMapArgumentsRaw}.\n\t * That is, if a validator function is _not_ provided.\n\t */\n\t<T, Keys extends string = string, RegistrationKey extends string = string>(\n\t\targs?: LatestMapArgumentsRaw<T, Keys>,\n\t): InternalTypes.ManagerFactory<\n\t\tRegistrationKey,\n\t\tInternalTypes.MapValueState<T, Keys>,\n\t\tLatestMapRaw<T, Keys>\n\t>;\n}\n\n// #endregion\n\n/**\n * Factory for creating a {@link LatestMap} or {@link LatestMapRaw} State object.\n */\nexport const latestMap: LatestMapFactory = <\n\tT,\n\tKeys extends string = string,\n\tRegistrationKey extends string = string,\n>(\n\targs?: Partial<LatestMapArguments<T, Keys>>,\n): InternalTypes.ManagerFactory<\n\tRegistrationKey,\n\tInternalTypes.MapValueState<T, Keys>,\n\tLatestMapRaw<T, Keys> & LatestMap<T, Keys>\n> => {\n\tconst settings = args?.settings;\n\tconst initialValues = args?.local;\n\tconst validator = args?.validator;\n\tconst isKeyValid = args?.keyValidator ?? anyKeyIsValid;\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\n\t> = { rev: 0, items: {} };\n\t// LatestMapRaw takes ownership of values within initialValues.\n\tif (initialValues !== undefined) {\n\t\tfor (const [key, item] of objectEntries(initialValues)) {\n\t\t\t// TODO: AB#55932: try fixing typing of objectEntries to avoid this cast\n\t\t\tconst assumedValidKey = key as unknown as Keys;\n\t\t\tvalue.items[assumedValidKey] = {\n\t\t\t\trev: 0,\n\t\t\t\ttimestamp,\n\t\t\t\tvalue: toOpaqueJson(item),\n\t\t\t};\n\t\t}\n\t}\n\tconst factory = (\n\t\tkey: RegistrationKey,\n\t\tdatastoreHandle: InternalTypes.StateDatastoreHandle<\n\t\t\tRegistrationKey,\n\t\t\tInternalTypes.MapValueState<T, Keys>\n\t\t>,\n\t): {\n\t\tinitialData: { value: typeof value; allowableUpdateLatencyMs: number | undefined };\n\t\tmanager: InternalTypes.StateValue<LatestMapRaw<T, Keys> & LatestMap<T, Keys>>;\n\t} => ({\n\t\tinitialData: { value, allowableUpdateLatencyMs: settings?.allowableUpdateLatencyMs },\n\t\tmanager: brandIVM<\n\t\t\tLatestMapValueManagerImpl<T, RegistrationKey, Keys>,\n\t\t\tT,\n\t\t\tInternalTypes.MapValueState<T, Keys>\n\t\t>(\n\t\t\tnew LatestMapValueManagerImpl(\n\t\t\t\tkey,\n\t\t\t\tdatastoreFromHandle(datastoreHandle),\n\t\t\t\tvalue,\n\t\t\t\tsettings,\n\t\t\t\tvalidator,\n\t\t\t\tisKeyValid,\n\t\t\t),\n\t\t),\n\t});\n\treturn Object.assign(factory, { instanceBase: LatestMapValueManagerImpl });\n};\n"]}
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import type { Listenable } from "@fluidframework/core-interfaces";
6
6
  import type { DeepReadonly, JsonDeserialized, JsonSerializable } from "@fluidframework/core-interfaces/internal/exposedUtilityTypes";
7
- import type { BroadcastControls, BroadcastControlSettings } from "./broadcastControls.js";
7
+ import type { BroadcastControls, BroadcastControlSettings } from "./broadcastControlsTypes.js";
8
8
  import type { InternalTypes } from "./exposedInternalTypes.js";
9
9
  import type { LatestClientData, LatestData, ProxiedValueAccessor, RawValueAccessor, StateSchemaValidator, ValueAccessor } from "./latestValueTypes.js";
10
10
  import type { Attendee, Presence } from "./presence.js";
@@ -90,13 +90,6 @@ export interface Latest<T, TRemoteAccessor extends ValueAccessor<T> = ProxiedVal
90
90
  */
91
91
  getRemote(attendee: Attendee): LatestData<T, TRemoteAccessor>;
92
92
  }
93
- /**
94
- * Shallow clone an object that might be null.
95
- *
96
- * @param value - The object to clone
97
- * @returns A shallow clone of the input value
98
- */
99
- export declare function shallowCloneNullableObject<T extends object | null>(value: T): T;
100
93
  /**
101
94
  * Arguments that are passed to the {@link StateFactory.latest} function to create a {@link LatestRaw} State object.
102
95
  *
@@ -1 +1 @@
1
- {"version":3,"file":"latestValueManager.d.ts","sourceRoot":"","sources":["../src/latestValueManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"latestValueManager.d.ts","sourceRoot":"","sources":["../src/latestValueManager.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@
4
4
  * Licensed under the MIT License.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.latest = exports.shallowCloneNullableObject = void 0;
7
+ exports.latest = 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");
@@ -94,7 +94,6 @@ class LatestValueManagerImpl {
94
94
  function shallowCloneNullableObject(value) {
95
95
  return value === null ? value : (0, internal_1.shallowCloneObject)(value);
96
96
  }
97
- exports.shallowCloneNullableObject = shallowCloneNullableObject;
98
97
  // #endregion
99
98
  /**
100
99
  * Factory for creating a {@link Latest} or {@link LatestRaw} State object.
@@ -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 type { FlattenUnionWithOptionals } from \"./internalUtils.js\";\nimport {\n\tasDeeplyReadonly,\n\tasDeeplyReadonlyDeserializedJson,\n\tobjectEntries,\n\ttoOpaqueJson,\n} from \"./internalUtils.js\";\nimport { createValidatedGetter } from \"./latestValueTypes.js\";\nimport type {\n\tLatestClientData,\n\tLatestData,\n\tProxiedValueAccessor,\n\tRawValueAccessor,\n\tStateSchemaValidator,\n\tValueAccessor,\n} 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 LatestEvents<\n\tT,\n\tTRemoteValueAccessor extends ValueAccessor<T> = ProxiedValueAccessor<T>,\n> {\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, TRemoteValueAccessor>) => 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 * Events from {@link LatestRaw}.\n *\n * @sealed\n * @beta\n */\nexport type LatestRawEvents<T> = LatestEvents<T, RawValueAccessor<T>>;\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 type LatestRaw<T> = Latest<T, RawValueAccessor<T>>;\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 Latest<\n\tT,\n\tTRemoteAccessor extends ValueAccessor<T> = ProxiedValueAccessor<T>,\n> {\n\t/**\n\t * Containing {@link Presence}\n\t */\n\treadonly presence: Presence;\n\n\t/**\n\t * Events for LatestRaw.\n\t */\n\treadonly events: Listenable<LatestEvents<T, TRemoteAccessor>>;\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 * Array of {@link Attendee}s that have provided states.\n\t */\n\tgetStateAttendees(): Attendee[];\n\n\t/**\n\t * Iterable access to remote clients' values.\n\t */\n\tgetRemotes(): IterableIterator<LatestClientData<T, TRemoteAccessor>>;\n\n\t/**\n\t * Access to a specific attendee's value.\n\t */\n\tgetRemote(attendee: Attendee): LatestData<T, TRemoteAccessor>;\n}\n\nclass LatestValueManagerImpl<T, Key extends string>\n\timplements\n\t\tLatestRaw<T>,\n\t\tLatest<T>,\n\t\tRequired<ValueManager<T, InternalTypes.ValueRequiredState<T>>>\n{\n\tpublic readonly events = createEmitter<LatestEvents<T, ValueAccessor<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\tprivate readonly validator: StateSchemaValidator<T> | 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, ValueAccessor<T>>> {\n\t\tconst allKnownStates = this.datastore.knownValues(this.key);\n\t\tfor (const [attendeeId, clientState] 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: createValidatedGetter(clientState, this.validator),\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\trevision: clientState.rev,\n\t\t\t\t\t\ttimestamp: clientState.timestamp,\n\t\t\t\t\t},\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, ValueAccessor<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 attendee\");\n\t\t}\n\t\treturn {\n\t\t\tvalue: createValidatedGetter(clientState, this.validator),\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: createValidatedGetter(value, this.validator),\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 to create a {@link LatestRaw} State object.\n *\n * @input\n * @beta\n */\nexport interface LatestArgumentsRaw<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 * Arguments that are passed to the {@link StateFactory.latest} function to create a {@link Latest} State object.\n *\n * @input\n * @beta\n */\nexport interface LatestArguments<T extends object | null> extends LatestArgumentsRaw<T> {\n\t/**\n\t * See {@link StateSchemaValidator}.\n\t */\n\tvalidator: StateSchemaValidator<T>;\n}\n\n// #region factory function overloads\n// Overloads should be ordered from most specific to least specific when combined.\n\n/**\n * Factory for creating a {@link Latest} or {@link LatestRaw} State object.\n *\n * @beta\n * @sealed\n */\nexport interface LatestFactory {\n\t/**\n\t * Factory for creating a {@link Latest} State object.\n\t *\n\t * @remarks\n\t * This overload is used when called with {@link LatestArguments}.\n\t * That is, if a validator function is provided.\n\t */\n\t<T extends object | null, Key extends string = string>(\n\t\targs: LatestArguments<T>,\n\t): InternalTypes.ManagerFactory<Key, InternalTypes.ValueRequiredState<T>, Latest<T>>;\n\n\t/**\n\t * Factory for creating a {@link LatestRaw} State object.\n\t *\n\t * @remarks\n\t * This overload is used when called with {@link LatestArgumentsRaw}.\n\t * That is, if a validator function is _not_ provided.\n\t */\n\t<T extends object | null, Key extends string = string>(\n\t\targs: LatestArgumentsRaw<T>,\n\t): InternalTypes.ManagerFactory<Key, InternalTypes.ValueRequiredState<T>, LatestRaw<T>>;\n}\n\n// #endregion\n\n/**\n * Factory for creating a {@link Latest} or {@link LatestRaw} State object.\n */\nexport const latest: LatestFactory = <T extends object | null, Key extends string = string>(\n\targs: FlattenUnionWithOptionals<LatestArguments<T> | LatestArgumentsRaw<T>>,\n): InternalTypes.ManagerFactory<\n\tKey,\n\tInternalTypes.ValueRequiredState<T>,\n\tLatestRaw<T> & Latest<T>\n> => {\n\tconst { local, settings, validator } = args;\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> & Latest<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(\n\t\t\t\tkey,\n\t\t\t\tdatastoreFromHandle(datastoreHandle),\n\t\t\t\tvalue,\n\t\t\t\tsettings,\n\t\t\t\tvalidator,\n\t\t\t),\n\t\t),\n\t});\n\treturn Object.assign(factory, { instanceBase: LatestValueManagerImpl });\n};\n"]}
1
+ {"version":3,"file":"latestValueManager.js","sourceRoot":"","sources":["../src/latestValueManager.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+DAA6D;AAO7D,kEAAyE;AAEzE,iEAAkE;AAIlE,yDAK4B;AAC5B,+DAA8D;AAU9D,2DAA+E;AAE/E,uDAA6C;AAqG7C,MAAM,sBAAsB;IAS3B,YACkB,GAAQ,EACR,SAAmE,EACpE,KAA0C,EAC1D,eAAqD,EACpC,SAA8C;QAJ9C,QAAG,GAAH,GAAG,CAAK;QACR,cAAS,GAAT,SAAS,CAA0D;QACpE,UAAK,GAAL,KAAK,CAAqC;QAEzC,cAAS,GAAT,SAAS,CAAqC;QARhD,WAAM,GAAG,IAAA,4BAAa,GAAqC,CAAC;QAU3E,IAAI,CAAC,QAAQ,GAAG,IAAI,+CAAwB,CAAC,eAAe,CAAC,CAAC;IAC/D,CAAC;IAED,IAAW,QAAQ;QAClB,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;IAChC,CAAC;IAED,IAAW,KAAK;QACf,OAAO,IAAA,mDAAgC,EAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC3D,CAAC;IAED,IAAW,KAAK,CAAC,KAA0B;QAC1C,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;QACpB,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAClC,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAA,+BAAY,EAAI,KAAK,CAAC,CAAC;QAC1C,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,EAAE;YAChD,wBAAwB,EAAE,IAAI,CAAC,QAAQ,CAAC,wBAAwB;SAChE,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,KAAK,EAAE,IAAA,mCAAgB,EAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACtE,CAAC;IAEM,CAAC,UAAU;QACjB,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5D,KAAK,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,IAAI,IAAA,gCAAa,EAAC,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9E,IAAI,UAAU,KAAK,cAAc,CAAC,IAAI,EAAE,CAAC;gBACxC,MAAM;oBACL,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,WAAW,CAAC,UAAU,CAAC;oBACnE,KAAK,EAAE,IAAA,2CAAqB,EAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC;oBACzD,QAAQ,EAAE;wBACT,QAAQ,EAAE,WAAW,CAAC,GAAG;wBACzB,SAAS,EAAE,WAAW,CAAC,SAAS;qBAChC;iBACD,CAAC;YACH,CAAC;QACF,CAAC;IACF,CAAC;IAEM,iBAAiB;QACvB,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5D,OAAO,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC;aACvC,MAAM,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,KAAK,cAAc,CAAC,IAAI,CAAC;aAC1D,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC;IAClF,CAAC;IAEM,SAAS,CAAC,QAAkB;QAClC,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5D,MAAM,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAC/D,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAC1C,CAAC;QACD,OAAO;YACN,KAAK,EAAE,IAAA,2CAAqB,EAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC;YACzD,QAAQ,EAAE,EAAE,QAAQ,EAAE,WAAW,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE;SAC9D,CAAC;IACH,CAAC;IAEM,MAAM,CACZ,QAAkB,EAClB,SAAiB,EACjB,KAA0C;QAE1C,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5D,MAAM,UAAU,GAAG,QAAQ,CAAC,UAAU,CAAC;QACvC,MAAM,YAAY,GAAG,cAAc,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACvD,IAAI,YAAY,KAAK,SAAS,IAAI,YAAY,CAAC,GAAG,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;YACjE,OAAO,EAAE,CAAC;QACX,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;QACnD,OAAO;YACN,GAAG,EAAE,CACJ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE;gBACjC,QAAQ;gBACR,KAAK,EAAE,IAAA,2CAAqB,EAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnD,QAAQ,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE;aAC7D,CAAC;SACH,CAAC;IACH,CAAC;CACD;AAED;;;;;GAKG;AACH,SAAS,0BAA0B,CAA0B,KAAQ;IACpE,OAAO,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAA,6BAAkB,EAAC,KAAK,CAAC,CAAC;AAC3D,CAAC;AAsED,aAAa;AAEb;;GAEG;AACI,MAAM,MAAM,GAAkB,CACpC,IAA2E,EAK1E,EAAE;IACH,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;IAC5C,wEAAwE;IACxE,6BAA6B;IAC7B,MAAM,WAAW,GAAG,IAAA,+BAAY,EAAI,KAAK,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAwC;QAClD,GAAG,EAAE,CAAC;QACN,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;QACrB,KAAK,EAAE,0BAA0B,CAAC,WAAW,CAAC;KAC9C,CAAC;IACF,MAAM,OAAO,GAAG,CACf,GAAQ,EACR,eAGC,EAIA,EAAE,CAAC,CAAC;QACL,WAAW,EAAE,EAAE,KAAK,EAAE,wBAAwB,EAAE,QAAQ,EAAE,wBAAwB,EAAE;QACpF,OAAO,EAAE,IAAA,0BAAQ,EAChB,IAAI,sBAAsB,CACzB,GAAG,EACH,IAAA,uCAAmB,EAAC,eAAe,CAAC,EACpC,KAAK,EACL,QAAQ,EACR,SAAS,CACT,CACD;KACD,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,YAAY,EAAE,sBAAsB,EAAE,CAAC,CAAC;AACzE,CAAC,CAAC;AAtCW,QAAA,MAAM,UAsCjB","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 { OptionalBroadcastControl } from \"./broadcastControls.js\";\nimport type { BroadcastControls, BroadcastControlSettings } from \"./broadcastControlsTypes.js\";\nimport type { InternalTypes } from \"./exposedInternalTypes.js\";\nimport type { FlattenUnionWithOptionals } from \"./internalUtils.js\";\nimport {\n\tasDeeplyReadonly,\n\tasDeeplyReadonlyDeserializedJson,\n\tobjectEntries,\n\ttoOpaqueJson,\n} from \"./internalUtils.js\";\nimport { createValidatedGetter } from \"./latestValueTypes.js\";\nimport type {\n\tLatestClientData,\n\tLatestData,\n\tProxiedValueAccessor,\n\tRawValueAccessor,\n\tStateSchemaValidator,\n\tValueAccessor,\n} from \"./latestValueTypes.js\";\nimport type { Attendee, Presence } from \"./presence.js\";\nimport { datastoreFromHandle, type StateDatastore } from \"./stateDatastore.js\";\nimport type { PostUpdateAction, ValueManager } from \"./statesManagerTypes.js\";\nimport { brandIVM } from \"./valueManager.js\";\n\n/**\n * Events from {@link LatestRaw}.\n *\n * @sealed\n * @beta\n */\nexport interface LatestEvents<\n\tT,\n\tTRemoteValueAccessor extends ValueAccessor<T> = ProxiedValueAccessor<T>,\n> {\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, TRemoteValueAccessor>) => 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 * Events from {@link LatestRaw}.\n *\n * @sealed\n * @beta\n */\nexport type LatestRawEvents<T> = LatestEvents<T, RawValueAccessor<T>>;\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 type LatestRaw<T> = Latest<T, RawValueAccessor<T>>;\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 Latest<\n\tT,\n\tTRemoteAccessor extends ValueAccessor<T> = ProxiedValueAccessor<T>,\n> {\n\t/**\n\t * Containing {@link Presence}\n\t */\n\treadonly presence: Presence;\n\n\t/**\n\t * Events for LatestRaw.\n\t */\n\treadonly events: Listenable<LatestEvents<T, TRemoteAccessor>>;\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 * Array of {@link Attendee}s that have provided states.\n\t */\n\tgetStateAttendees(): Attendee[];\n\n\t/**\n\t * Iterable access to remote clients' values.\n\t */\n\tgetRemotes(): IterableIterator<LatestClientData<T, TRemoteAccessor>>;\n\n\t/**\n\t * Access to a specific attendee's value.\n\t */\n\tgetRemote(attendee: Attendee): LatestData<T, TRemoteAccessor>;\n}\n\nclass LatestValueManagerImpl<T, Key extends string>\n\timplements\n\t\tLatestRaw<T>,\n\t\tLatest<T>,\n\t\tRequired<ValueManager<T, InternalTypes.ValueRequiredState<T>>>\n{\n\tpublic readonly events = createEmitter<LatestEvents<T, ValueAccessor<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\tprivate readonly validator: StateSchemaValidator<T> | 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, ValueAccessor<T>>> {\n\t\tconst allKnownStates = this.datastore.knownValues(this.key);\n\t\tfor (const [attendeeId, clientState] 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: createValidatedGetter(clientState, this.validator),\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\trevision: clientState.rev,\n\t\t\t\t\t\ttimestamp: clientState.timestamp,\n\t\t\t\t\t},\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, ValueAccessor<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 attendee\");\n\t\t}\n\t\treturn {\n\t\t\tvalue: createValidatedGetter(clientState, this.validator),\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: createValidatedGetter(value, this.validator),\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 */\nfunction 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 to create a {@link LatestRaw} State object.\n *\n * @input\n * @beta\n */\nexport interface LatestArgumentsRaw<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 * Arguments that are passed to the {@link StateFactory.latest} function to create a {@link Latest} State object.\n *\n * @input\n * @beta\n */\nexport interface LatestArguments<T extends object | null> extends LatestArgumentsRaw<T> {\n\t/**\n\t * See {@link StateSchemaValidator}.\n\t */\n\tvalidator: StateSchemaValidator<T>;\n}\n\n// #region factory function overloads\n// Overloads should be ordered from most specific to least specific when combined.\n\n/**\n * Factory for creating a {@link Latest} or {@link LatestRaw} State object.\n *\n * @beta\n * @sealed\n */\nexport interface LatestFactory {\n\t/**\n\t * Factory for creating a {@link Latest} State object.\n\t *\n\t * @remarks\n\t * This overload is used when called with {@link LatestArguments}.\n\t * That is, if a validator function is provided.\n\t */\n\t<T extends object | null, Key extends string = string>(\n\t\targs: LatestArguments<T>,\n\t): InternalTypes.ManagerFactory<Key, InternalTypes.ValueRequiredState<T>, Latest<T>>;\n\n\t/**\n\t * Factory for creating a {@link LatestRaw} State object.\n\t *\n\t * @remarks\n\t * This overload is used when called with {@link LatestArgumentsRaw}.\n\t * That is, if a validator function is _not_ provided.\n\t */\n\t<T extends object | null, Key extends string = string>(\n\t\targs: LatestArgumentsRaw<T>,\n\t): InternalTypes.ManagerFactory<Key, InternalTypes.ValueRequiredState<T>, LatestRaw<T>>;\n}\n\n// #endregion\n\n/**\n * Factory for creating a {@link Latest} or {@link LatestRaw} State object.\n */\nexport const latest: LatestFactory = <T extends object | null, Key extends string = string>(\n\targs: FlattenUnionWithOptionals<LatestArguments<T> | LatestArgumentsRaw<T>>,\n): InternalTypes.ManagerFactory<\n\tKey,\n\tInternalTypes.ValueRequiredState<T>,\n\tLatestRaw<T> & Latest<T>\n> => {\n\tconst { local, settings, validator } = args;\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> & Latest<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(\n\t\t\t\tkey,\n\t\t\t\tdatastoreFromHandle(datastoreHandle),\n\t\t\t\tvalue,\n\t\t\t\tsettings,\n\t\t\t\tvalidator,\n\t\t\t),\n\t\t),\n\t});\n\treturn Object.assign(factory, { instanceBase: LatestValueManagerImpl });\n};\n"]}
@@ -3,8 +3,8 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  import type { DeepReadonly, JsonDeserialized } from "@fluidframework/core-interfaces/internal/exposedUtilityTypes";
6
- import type { ValidatableRequiredState } from "./internalTypes.js";
7
6
  import type { Attendee } from "./presence.js";
7
+ import type { ValidatableRequiredState } from "./validatableTypes.js";
8
8
  /**
9
9
  * Metadata for the value state.
10
10
  *
@@ -1 +1 @@
1
- {"version":3,"file":"latestValueTypes.d.ts","sourceRoot":"","sources":["../src/latestValueTypes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACX,YAAY,EACZ,gBAAgB,EAEhB,MAAM,8DAA8D,CAAC;AAEtE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAEnE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC9B;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB,CAAC,CAAC;IAClC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;CACjB;AAED;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB,CAAC,CAAC;IACtC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;CACjB;AAED;;;;;GAKG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,gBAAgB,CAAC,CAAC,CAAC,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAC;AAE7E;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,CACnB,CAAC,EACD,YAAY,SAAS,aAAa,CAAC,CAAC,CAAC,IAClC,YAAY,SAAS,oBAAoB,CAAC,CAAC,CAAC,GAC7C,MAAM,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,GACnD,YAAY,SAAS,gBAAgB,CAAC,CAAC,CAAC,GACvC,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,GACjC,KAAK,CAAC;AAEV;;;;;GAKG;AACH,MAAM,WAAW,UAAU,CAAC,CAAC,EAAE,cAAc,SAAS,aAAa,CAAC,CAAC,CAAC;IACrE;;;;;;;;;OASG;IACH,KAAK,EAAE,QAAQ,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;IAEnC;;OAEG;IACH,QAAQ,EAAE,cAAc,CAAC;CACzB;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB,CAChC,CAAC,EACD,cAAc,SAAS,aAAa,CAAC,CAAC,CAAC,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAChE,SAAQ,UAAU,CAAC,CAAC,EAAE,cAAc,CAAC;IACtC;;OAEG;IACH,QAAQ,EAAE,QAAQ,CAAC;CACnB;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,oBAAoB,CAAC,CAAC,IAAI;AACrC;;GAEG;AACH,eAAe,EAAE,OAAO,KACpB,gBAAgB,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;AAmBrC;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EACtC,WAAW,EAAE,wBAAwB,CAAC,CAAC,CAAC,EACxC,SAAS,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAAG,SAAS,GAC5C,CAAC,MAAM,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,GAAG,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAgB3F"}
1
+ {"version":3,"file":"latestValueTypes.d.ts","sourceRoot":"","sources":["../src/latestValueTypes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACX,YAAY,EACZ,gBAAgB,EAEhB,MAAM,8DAA8D,CAAC;AAGtE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAEtE;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC9B;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB,CAAC,CAAC;IAClC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;CACjB;AAED;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB,CAAC,CAAC;IACtC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;CACjB;AAED;;;;;GAKG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,gBAAgB,CAAC,CAAC,CAAC,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAC;AAE7E;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,CACnB,CAAC,EACD,YAAY,SAAS,aAAa,CAAC,CAAC,CAAC,IAClC,YAAY,SAAS,oBAAoB,CAAC,CAAC,CAAC,GAC7C,MAAM,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,GACnD,YAAY,SAAS,gBAAgB,CAAC,CAAC,CAAC,GACvC,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,GACjC,KAAK,CAAC;AAEV;;;;;GAKG;AACH,MAAM,WAAW,UAAU,CAAC,CAAC,EAAE,cAAc,SAAS,aAAa,CAAC,CAAC,CAAC;IACrE;;;;;;;;;OASG;IACH,KAAK,EAAE,QAAQ,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;IAEnC;;OAEG;IACH,QAAQ,EAAE,cAAc,CAAC;CACzB;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB,CAChC,CAAC,EACD,cAAc,SAAS,aAAa,CAAC,CAAC,CAAC,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAChE,SAAQ,UAAU,CAAC,CAAC,EAAE,cAAc,CAAC;IACtC;;OAEG;IACH,QAAQ,EAAE,QAAQ,CAAC;CACnB;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,oBAAoB,CAAC,CAAC,IAAI;AACrC;;GAEG;AACH,eAAe,EAAE,OAAO,KACpB,gBAAgB,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;AAmBrC;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EACtC,WAAW,EAAE,wBAAwB,CAAC,CAAC,CAAC,EACxC,SAAS,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAAG,SAAS,GAC5C,CAAC,MAAM,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,GAAG,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAgB3F"}
@@ -1 +1 @@
1
- {"version":3,"file":"latestValueTypes.js","sourceRoot":"","sources":["../src/latestValueTypes.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AASH,yDAAsE;AAgItE,SAAS,oBAAoB,CAC5B,WAAwC,EACxC,SAA0C;IAE1C,OAAO,GAAkD,EAAE;QAC1D,IAAI,CAAC,CAAC,gBAAgB,IAAI,WAAW,CAAC,EAAE,CAAC;YACxC,iFAAiF;YACjF,WAAW,CAAC,cAAc,GAAG,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAC3D,CAAC;QACD,OAAO,IAAA,mDAAgC,EAAC,WAAW,CAAC,cAAc,CAAC,CAAC;IACrE,CAAC,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,qBAAqB,CACpC,WAAwC,EACxC,SAA8C;IAE9C,eAAe;IACf,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,IAAA,mDAAgC,EAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAC5D,CAAC;IAED,uEAAuE;IACvE,IAAI,OAAO,WAAW,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;QAC7C,OAAO,WAAW,CAAC,KAAK,CAAC;IAC1B,CAAC;IAED,sHAAsH;IACtH,mHAAmH;IACnH,sHAAsH;IACtH,2BAA2B;IAC3B,OAAO,oBAAoB,CAAC,WAAW,EAAE,SAA4C,CAAC,CAAC;AACxF,CAAC;AAnBD,sDAmBC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type {\n\tDeepReadonly,\n\tJsonDeserialized,\n\tOpaqueJsonDeserialized,\n} from \"@fluidframework/core-interfaces/internal/exposedUtilityTypes\";\n\nimport type { ValidatableRequiredState } from \"./internalTypes.js\";\nimport { asDeeplyReadonlyDeserializedJson } from \"./internalUtils.js\";\nimport type { Attendee } from \"./presence.js\";\n\n/**\n * Metadata for the value state.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMetadata {\n\t/**\n\t * The revision number for value that increases as value is changed.\n\t */\n\trevision: number;\n\t/**\n\t * Local time when the value was last updated.\n\t * @remarks Currently this is a placeholder for future implementation.\n\t */\n\ttimestamp: number;\n}\n\n/**\n * Represents a value that is accessed directly.\n *\n * @system\n * @beta\n */\nexport interface RawValueAccessor<T> {\n\treadonly kind: \"raw\";\n\treadonly data: T;\n}\n\n/**\n * Represents a value that is accessed via a function call, which may result in no value.\n *\n * @system\n * @beta\n */\nexport interface ProxiedValueAccessor<T> {\n\treadonly kind: \"proxied\";\n\treadonly data: T;\n}\n\n/**\n * Union of possible accessor types for a value.\n *\n * @system\n * @beta\n */\nexport type ValueAccessor<T> = RawValueAccessor<T> | ProxiedValueAccessor<T>;\n\n/**\n * Utility type that conditionally represents an accessor type based on the base accessor type.\n *\n * @system\n * @beta\n */\nexport type Accessor<\n\tT,\n\tBaseAccessor extends ValueAccessor<T>,\n> = BaseAccessor extends ProxiedValueAccessor<T>\n\t? () => DeepReadonly<JsonDeserialized<T>> | undefined\n\t: BaseAccessor extends RawValueAccessor<T>\n\t\t? DeepReadonly<JsonDeserialized<T>>\n\t\t: never;\n\n/**\n * State of a value and its metadata.\n *\n * @sealed\n * @beta\n */\nexport interface LatestData<T, TValueAccessor extends ValueAccessor<T>> {\n\t/**\n\t * The value of the state or an accessor function.\n\t *\n\t * @remarks\n\t * If the State object was created with a {@link StateSchemaValidator}, then the `value`\n\t * will be a function returning a validated, deeply readonly `T` or `undefined`.\n\t * Without a validator, `value` will be an unvalidated, deeply readonly `T`.\n\t *\n\t * Any `T` is always deeply readonly, meaning it cannot be modified.\n\t */\n\tvalue: Accessor<T, TValueAccessor>;\n\n\t/**\n\t * Metadata associated with the value.\n\t */\n\tmetadata: LatestMetadata;\n}\n\n/**\n * State of a specific {@link Attendee}'s value and its metadata.\n *\n * @sealed\n * @beta\n */\nexport interface LatestClientData<\n\tT,\n\tTValueAccessor extends ValueAccessor<T> = ProxiedValueAccessor<T>,\n> extends LatestData<T, TValueAccessor> {\n\t/**\n\t * Associated {@link Attendee}.\n\t */\n\tattendee: Attendee;\n}\n\n/**\n * A validator function that can optionally be provided to do runtime validation of the custom data stored in a\n * presence workspace and managed by a state object.\n *\n * @param unvalidatedData - The unknown data that should be validated. **This data should not be mutated.**\n *\n * @returns The validated data, or `undefined` if the data is invalid.\n *\n * @beta\n */\nexport type StateSchemaValidator<T> = (\n\t/**\n\t * Unknown data that should be validated. **This data should not be mutated.**\n\t */\n\tunvalidatedData: unknown,\n) => JsonDeserialized<T> | undefined;\n\ntype StateSchemaValidatorToOpaque<T> = (\n\trawData: OpaqueJsonDeserialized<T>,\n) => OpaqueJsonDeserialized<T> | undefined;\n\nfunction createGetterFunction<T>(\n\tclientState: ValidatableRequiredState<T>,\n\tvalidator: StateSchemaValidatorToOpaque<T>,\n): () => DeepReadonly<JsonDeserialized<T>> | undefined {\n\treturn (): DeepReadonly<JsonDeserialized<T>> | undefined => {\n\t\tif (!(\"validatedValue\" in clientState)) {\n\t\t\t// Stored `value` has not been validated yet, so validate it and save the result.\n\t\t\tclientState.validatedValue = validator(clientState.value);\n\t\t}\n\t\treturn asDeeplyReadonlyDeserializedJson(clientState.validatedValue);\n\t};\n}\n\n/**\n * Creates a getter for a state value that validates the data with a validator if one is provided. Otherwise the value\n * is returned directly.\n *\n * @param clientState - The client state to be validated.\n * @param validator - The validator function to run.\n * @returns Either returns the value directly if a validator is not provided, or a function that will return the\n * validated data.\n */\nexport function createValidatedGetter<T>(\n\tclientState: ValidatableRequiredState<T>,\n\tvalidator: StateSchemaValidator<T> | undefined,\n): (() => DeepReadonly<JsonDeserialized<T>> | undefined) | DeepReadonly<JsonDeserialized<T>> {\n\t// No validator\n\tif (validator === undefined) {\n\t\treturn asDeeplyReadonlyDeserializedJson(clientState.value);\n\t}\n\n\t// Avoid creating another function since one already exists on the item\n\tif (typeof clientState.value === \"function\") {\n\t\treturn clientState.value;\n\t}\n\n\t// OpaqueJsonDeserialized<T> is just a branded alias of JsonDeserialized<T>. At runtime the functions are still passed\n\t// JSON data, regardless of their type representation. Passing that data to a function that expects `unknown`, like\n\t// the user-provided validator function, is always valid, so StateSchemaValidator and StateSchemaValidatorToOpaque are\n\t// functionally equivalent.\n\treturn createGetterFunction(clientState, validator as StateSchemaValidatorToOpaque<T>);\n}\n"]}
1
+ {"version":3,"file":"latestValueTypes.js","sourceRoot":"","sources":["../src/latestValueTypes.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAQH,yDAAsE;AAiItE,SAAS,oBAAoB,CAC5B,WAAwC,EACxC,SAA0C;IAE1C,OAAO,GAAkD,EAAE;QAC1D,IAAI,CAAC,CAAC,gBAAgB,IAAI,WAAW,CAAC,EAAE,CAAC;YACxC,iFAAiF;YACjF,WAAW,CAAC,cAAc,GAAG,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAC3D,CAAC;QACD,OAAO,IAAA,mDAAgC,EAAC,WAAW,CAAC,cAAc,CAAC,CAAC;IACrE,CAAC,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,qBAAqB,CACpC,WAAwC,EACxC,SAA8C;IAE9C,eAAe;IACf,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,IAAA,mDAAgC,EAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAC5D,CAAC;IAED,uEAAuE;IACvE,IAAI,OAAO,WAAW,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;QAC7C,OAAO,WAAW,CAAC,KAAK,CAAC;IAC1B,CAAC;IAED,sHAAsH;IACtH,mHAAmH;IACnH,sHAAsH;IACtH,2BAA2B;IAC3B,OAAO,oBAAoB,CAAC,WAAW,EAAE,SAA4C,CAAC,CAAC;AACxF,CAAC;AAnBD,sDAmBC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type {\n\tDeepReadonly,\n\tJsonDeserialized,\n\tOpaqueJsonDeserialized,\n} from \"@fluidframework/core-interfaces/internal/exposedUtilityTypes\";\n\nimport { asDeeplyReadonlyDeserializedJson } from \"./internalUtils.js\";\nimport type { Attendee } from \"./presence.js\";\nimport type { ValidatableRequiredState } from \"./validatableTypes.js\";\n\n/**\n * Metadata for the value state.\n *\n * @sealed\n * @beta\n */\nexport interface LatestMetadata {\n\t/**\n\t * The revision number for value that increases as value is changed.\n\t */\n\trevision: number;\n\t/**\n\t * Local time when the value was last updated.\n\t * @remarks Currently this is a placeholder for future implementation.\n\t */\n\ttimestamp: number;\n}\n\n/**\n * Represents a value that is accessed directly.\n *\n * @system\n * @beta\n */\nexport interface RawValueAccessor<T> {\n\treadonly kind: \"raw\";\n\treadonly data: T;\n}\n\n/**\n * Represents a value that is accessed via a function call, which may result in no value.\n *\n * @system\n * @beta\n */\nexport interface ProxiedValueAccessor<T> {\n\treadonly kind: \"proxied\";\n\treadonly data: T;\n}\n\n/**\n * Union of possible accessor types for a value.\n *\n * @system\n * @beta\n */\nexport type ValueAccessor<T> = RawValueAccessor<T> | ProxiedValueAccessor<T>;\n\n/**\n * Utility type that conditionally represents an accessor type based on the base accessor type.\n *\n * @system\n * @beta\n */\nexport type Accessor<\n\tT,\n\tBaseAccessor extends ValueAccessor<T>,\n> = BaseAccessor extends ProxiedValueAccessor<T>\n\t? () => DeepReadonly<JsonDeserialized<T>> | undefined\n\t: BaseAccessor extends RawValueAccessor<T>\n\t\t? DeepReadonly<JsonDeserialized<T>>\n\t\t: never;\n\n/**\n * State of a value and its metadata.\n *\n * @sealed\n * @beta\n */\nexport interface LatestData<T, TValueAccessor extends ValueAccessor<T>> {\n\t/**\n\t * The value of the state or an accessor function.\n\t *\n\t * @remarks\n\t * If the State object was created with a {@link StateSchemaValidator}, then the `value`\n\t * will be a function returning a validated, deeply readonly `T` or `undefined`.\n\t * Without a validator, `value` will be an unvalidated, deeply readonly `T`.\n\t *\n\t * Any `T` is always deeply readonly, meaning it cannot be modified.\n\t */\n\tvalue: Accessor<T, TValueAccessor>;\n\n\t/**\n\t * Metadata associated with the value.\n\t */\n\tmetadata: LatestMetadata;\n}\n\n/**\n * State of a specific {@link Attendee}'s value and its metadata.\n *\n * @sealed\n * @beta\n */\nexport interface LatestClientData<\n\tT,\n\tTValueAccessor extends ValueAccessor<T> = ProxiedValueAccessor<T>,\n> extends LatestData<T, TValueAccessor> {\n\t/**\n\t * Associated {@link Attendee}.\n\t */\n\tattendee: Attendee;\n}\n\n/**\n * A validator function that can optionally be provided to do runtime validation of the custom data stored in a\n * presence workspace and managed by a state object.\n *\n * @param unvalidatedData - The unknown data that should be validated. **This data should not be mutated.**\n *\n * @returns The validated data, or `undefined` if the data is invalid.\n *\n * @beta\n */\nexport type StateSchemaValidator<T> = (\n\t/**\n\t * Unknown data that should be validated. **This data should not be mutated.**\n\t */\n\tunvalidatedData: unknown,\n) => JsonDeserialized<T> | undefined;\n\ntype StateSchemaValidatorToOpaque<T> = (\n\trawData: OpaqueJsonDeserialized<T>,\n) => OpaqueJsonDeserialized<T> | undefined;\n\nfunction createGetterFunction<T>(\n\tclientState: ValidatableRequiredState<T>,\n\tvalidator: StateSchemaValidatorToOpaque<T>,\n): () => DeepReadonly<JsonDeserialized<T>> | undefined {\n\treturn (): DeepReadonly<JsonDeserialized<T>> | undefined => {\n\t\tif (!(\"validatedValue\" in clientState)) {\n\t\t\t// Stored `value` has not been validated yet, so validate it and save the result.\n\t\t\tclientState.validatedValue = validator(clientState.value);\n\t\t}\n\t\treturn asDeeplyReadonlyDeserializedJson(clientState.validatedValue);\n\t};\n}\n\n/**\n * Creates a getter for a state value that validates the data with a validator if one is provided. Otherwise the value\n * is returned directly.\n *\n * @param clientState - The client state to be validated.\n * @param validator - The validator function to run.\n * @returns Either returns the value directly if a validator is not provided, or a function that will return the\n * validated data.\n */\nexport function createValidatedGetter<T>(\n\tclientState: ValidatableRequiredState<T>,\n\tvalidator: StateSchemaValidator<T> | undefined,\n): (() => DeepReadonly<JsonDeserialized<T>> | undefined) | DeepReadonly<JsonDeserialized<T>> {\n\t// No validator\n\tif (validator === undefined) {\n\t\treturn asDeeplyReadonlyDeserializedJson(clientState.value);\n\t}\n\n\t// Avoid creating another function since one already exists on the item\n\tif (typeof clientState.value === \"function\") {\n\t\treturn clientState.value;\n\t}\n\n\t// OpaqueJsonDeserialized<T> is just a branded alias of JsonDeserialized<T>. At runtime the functions are still passed\n\t// JSON data, regardless of their type representation. Passing that data to a function that expects `unknown`, like\n\t// the user-provided validator function, is always valid, so StateSchemaValidator and StateSchemaValidatorToOpaque are\n\t// functionally equivalent.\n\treturn createGetterFunction(clientState, validator as StateSchemaValidatorToOpaque<T>);\n}\n"]}
@@ -2,110 +2,9 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import type { Listenable, Off } from "@fluidframework/core-interfaces";
6
5
  import type { InternalTypes } from "./exposedInternalTypes.js";
7
6
  import type { InternalUtilityTypes } from "./exposedUtilityTypes.js";
8
- import type { Attendee, PresenceWithNotifications as Presence } from "./presence.js";
9
- /**
10
- * @sealed
11
- * @alpha
12
- */
13
- export interface NotificationsManagerEvents {
14
- /**
15
- * Raised when notification is received, but no subscribers were found.
16
- *
17
- * @eventProperty
18
- */
19
- unattendedNotification: (name: string, sender: Attendee, ...content: unknown[]) => void;
20
- }
21
- /**
22
- * An object which allows the registration of listeners so that subscribers can be
23
- * notified when a notification happens.
24
- *
25
- * @sealed
26
- * @alpha
27
- */
28
- export interface NotificationListenable<TListeners extends InternalUtilityTypes.NotificationListeners<TListeners>> {
29
- /**
30
- * Register a notification listener.
31
- * @param notificationName - the name of the notification
32
- * @param listener - The listener function to run when the notification is fired.
33
- * @returns A {@link @fluidframework/core-interfaces#Off | function} which will deregister the listener when called.
34
- * Calling the deregistration function more than once will have no effect.
35
- *
36
- * Listeners may also be deregistered by passing the listener to {@link NotificationListenable.off | off()}.
37
- * @remarks Registering the exact same `listener` object for the same notification more than once will throw an error.
38
- * If registering the same listener for the same notification multiple times is desired, consider using a wrapper function for the second subscription.
39
- */
40
- on<K extends keyof InternalUtilityTypes.NotificationListeners<TListeners>>(notificationName: K, listener: (sender: Attendee, ...args: InternalUtilityTypes.JsonDeserializedParameters<TListeners[K]>) => void): Off;
41
- /**
42
- * Deregister notification listener.
43
- * @param notificationName - The name of the notification.
44
- * @param listener - The listener function to remove from the current set of notification listeners.
45
- * @remarks If `listener` is not currently registered, this method will have no effect.
46
- *
47
- * Listeners may also be deregistered by calling the {@link @fluidframework/core-interfaces#Off | deregistration function} returned when they are {@link NotificationListenable.on | registered}.
48
- */
49
- off<K extends keyof InternalUtilityTypes.NotificationListeners<TListeners>>(notificationName: K, listener: (sender: Attendee, ...args: InternalUtilityTypes.JsonDeserializedParameters<TListeners[K]>) => void): void;
50
- }
51
- /**
52
- * Record of notification subscriptions.
53
- *
54
- * @sealed
55
- * @alpha
56
- */
57
- export type NotificationSubscriptions<E extends InternalUtilityTypes.NotificationListeners<E>> = {
58
- [K in string & keyof InternalUtilityTypes.NotificationListeners<E>]: (sender: Attendee, ...args: InternalUtilityTypes.JsonDeserializedParameters<E[K]>) => void;
59
- };
60
- /**
61
- * Interface for a notification emitter that can send typed notification to other clients.
62
- *
63
- * @sealed
64
- * @alpha
65
- */
66
- export interface NotificationEmitter<E extends InternalUtilityTypes.NotificationListeners<E>> {
67
- /**
68
- * Emits a notification with the specified name and arguments, notifying all clients.
69
- * @param notificationName - the name of the notification to fire
70
- * @param args - the arguments sent with the notification
71
- */
72
- broadcast<K extends keyof InternalUtilityTypes.NotificationListeners<E>>(notificationName: K, ...args: Parameters<E[K]>): void;
73
- /**
74
- * Emits a notification with the specified name and arguments, notifying a single attendee.
75
- * @param notificationName - the name of the notification to fire
76
- * @param targetAttendee - the single attendee to notify
77
- * @param args - the arguments sent with the notification
78
- */
79
- unicast<K extends keyof InternalUtilityTypes.NotificationListeners<E>>(notificationName: K, targetAttendee: Attendee, ...args: Parameters<E[K]>): void;
80
- }
81
- /**
82
- * Provides notifications from this client to others and subscription
83
- * to their notifications.
84
- *
85
- * @remarks Create using {@link Notifications} registered to
86
- * {@link NotificationsWorkspace} or {@link StatesWorkspace}.
87
- *
88
- * @sealed
89
- * @alpha
90
- */
91
- export interface NotificationsManager<T extends InternalUtilityTypes.NotificationListeners<T>> {
92
- /**
93
- * Containing {@link Presence}
94
- */
95
- readonly presence: Presence;
96
- /**
97
- * Events for Notifications manager.
98
- */
99
- readonly events: Listenable<NotificationsManagerEvents>;
100
- /**
101
- * Send notifications to other clients.
102
- */
103
- readonly emit: NotificationEmitter<T>;
104
- /**
105
- * Provides subscription to notifications from other clients.
106
- */
107
- readonly notifications: NotificationListenable<T>;
108
- }
7
+ import type { NotificationsManager, NotificationSubscriptions } from "./notificationsManagerTypes.js";
109
8
  /**
110
9
  * Factory for creating a {@link NotificationsManager}.
111
10
  *
@@ -1 +1 @@
1
- {"version":3,"file":"notificationsManager.d.ts","sourceRoot":"","sources":["../src/notificationsManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"notificationsManager.d.ts","sourceRoot":"","sources":["../src/notificationsManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAErE,OAAO,KAAK,EACX,oBAAoB,EAGpB,yBAAyB,EAEzB,MAAM,gCAAgC,CAAC;AAmHxC;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC5B,CAAC,SAAS,oBAAoB,CAAC,qBAAqB,CAAC,CAAC,CAAC,EACvD,GAAG,SAAS,MAAM,GAAG,MAAM,EAE3B,oBAAoB,EAAE,OAAO,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,GACzD,aAAa,CAAC,cAAc,CAC9B,GAAG,EACH,aAAa,CAAC,kBAAkB,CAAC,aAAa,CAAC,gBAAgB,CAAC,EAChE,oBAAoB,CAAC,CAAC,CAAC,CACvB,CAuBA"}
@@ -1 +1 @@
1
- {"version":3,"file":"notificationsManager.js","sourceRoot":"","sources":["../src/notificationsManager.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 { Listeners, Listenable, Off } from \"@fluidframework/core-interfaces\";\nimport type { JsonTypeWith } from \"@fluidframework/core-interfaces/internal\";\n\nimport type { InternalTypes } from \"./exposedInternalTypes.js\";\nimport type { InternalUtilityTypes } from \"./exposedUtilityTypes.js\";\nimport type { PostUpdateAction, ValueManager } from \"./internalTypes.js\";\nimport { revealOpaqueJson, toOpaqueJson } from \"./internalUtils.js\";\nimport type { Attendee, PresenceWithNotifications as 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 NotificationsManagerEvents {\n\t/**\n\t * Raised when notification is received, but no subscribers were found.\n\t *\n\t * @eventProperty\n\t */\n\tunattendedNotification: (name: string, sender: Attendee, ...content: unknown[]) => void;\n}\n\n/**\n * An object which allows the registration of listeners so that subscribers can be\n * notified when a notification happens.\n *\n * @sealed\n * @alpha\n */\nexport interface NotificationListenable<\n\tTListeners extends InternalUtilityTypes.NotificationListeners<TListeners>,\n> {\n\t/**\n\t * Register a notification listener.\n\t * @param notificationName - the name of the notification\n\t * @param listener - The listener function to run when the notification is fired.\n\t * @returns A {@link @fluidframework/core-interfaces#Off | function} which will deregister the listener when called.\n\t * Calling the deregistration function more than once will have no effect.\n\t *\n\t * Listeners may also be deregistered by passing the listener to {@link NotificationListenable.off | off()}.\n\t * @remarks Registering the exact same `listener` object for the same notification more than once will throw an error.\n\t * If registering the same listener for the same notification multiple times is desired, consider using a wrapper function for the second subscription.\n\t */\n\ton<K extends keyof InternalUtilityTypes.NotificationListeners<TListeners>>(\n\t\tnotificationName: K,\n\t\tlistener: (\n\t\t\tsender: Attendee,\n\t\t\t...args: InternalUtilityTypes.JsonDeserializedParameters<TListeners[K]>\n\t\t) => void,\n\t): Off;\n\n\t/**\n\t * Deregister notification listener.\n\t * @param notificationName - The name of the notification.\n\t * @param listener - The listener function to remove from the current set of notification listeners.\n\t * @remarks If `listener` is not currently registered, this method will have no effect.\n\t *\n\t * Listeners may also be deregistered by calling the {@link @fluidframework/core-interfaces#Off | deregistration function} returned when they are {@link NotificationListenable.on | registered}.\n\t */\n\toff<K extends keyof InternalUtilityTypes.NotificationListeners<TListeners>>(\n\t\tnotificationName: K,\n\t\tlistener: (\n\t\t\tsender: Attendee,\n\t\t\t...args: InternalUtilityTypes.JsonDeserializedParameters<TListeners[K]>\n\t\t) => void,\n\t): void;\n}\n\n/**\n * Record of notification subscriptions.\n *\n * @sealed\n * @alpha\n */\nexport type NotificationSubscriptions<\n\tE extends InternalUtilityTypes.NotificationListeners<E>,\n> = {\n\t[K in string & keyof InternalUtilityTypes.NotificationListeners<E>]: (\n\t\tsender: Attendee,\n\t\t...args: InternalUtilityTypes.JsonDeserializedParameters<E[K]>\n\t) => void;\n};\n\n/**\n * Interface for a notification emitter that can send typed notification to other clients.\n *\n * @sealed\n * @alpha\n */\nexport interface NotificationEmitter<E extends InternalUtilityTypes.NotificationListeners<E>> {\n\t/**\n\t * Emits a notification with the specified name and arguments, notifying all clients.\n\t * @param notificationName - the name of the notification to fire\n\t * @param args - the arguments sent with the notification\n\t */\n\tbroadcast<K extends keyof InternalUtilityTypes.NotificationListeners<E>>(\n\t\tnotificationName: K,\n\t\t...args: Parameters<E[K]>\n\t): void;\n\n\t/**\n\t * Emits a notification with the specified name and arguments, notifying a single attendee.\n\t * @param notificationName - the name of the notification to fire\n\t * @param targetAttendee - the single attendee to notify\n\t * @param args - the arguments sent with the notification\n\t */\n\tunicast<K extends keyof InternalUtilityTypes.NotificationListeners<E>>(\n\t\tnotificationName: K,\n\t\ttargetAttendee: Attendee,\n\t\t...args: Parameters<E[K]>\n\t): void;\n}\n\n/**\n * Provides notifications from this client to others and subscription\n * to their notifications.\n *\n * @remarks Create using {@link Notifications} registered to\n * {@link NotificationsWorkspace} or {@link StatesWorkspace}.\n *\n * @sealed\n * @alpha\n */\nexport interface NotificationsManager<\n\tT extends InternalUtilityTypes.NotificationListeners<T>,\n> {\n\t/**\n\t * Containing {@link Presence}\n\t */\n\treadonly presence: Presence;\n\n\t/**\n\t * Events for Notifications manager.\n\t */\n\treadonly events: Listenable<NotificationsManagerEvents>;\n\n\t/**\n\t * Send notifications to other clients.\n\t */\n\treadonly emit: NotificationEmitter<T>;\n\n\t/**\n\t * Provides subscription to notifications from other clients.\n\t */\n\treadonly notifications: NotificationListenable<T>;\n}\n\n/**\n * Object.keys retyped to support specific records keys and\n * branded string-based keys.\n */\nconst recordKeys = Object.keys as <K extends string>(o: Partial<Record<K, unknown>>) => K[];\n\nclass NotificationsManagerImpl<\n\tT extends InternalUtilityTypes.NotificationListeners<T>,\n\tKey extends string,\n> implements\n\t\tNotificationsManager<T>,\n\t\tValueManager<\n\t\t\tInternalTypes.NotificationType,\n\t\t\tInternalTypes.ValueRequiredState<InternalTypes.NotificationType>\n\t\t>\n{\n\tpublic readonly events = createEmitter<NotificationsManagerEvents>();\n\n\tpublic readonly emit: NotificationEmitter<T> = {\n\t\tbroadcast: (name: string, ...args) => {\n\t\t\tthis.datastore.localUpdate(\n\t\t\t\tthis.key,\n\t\t\t\t{\n\t\t\t\t\trev: 0,\n\t\t\t\t\ttimestamp: 0,\n\t\t\t\t\tvalue: toOpaqueJson({\n\t\t\t\t\t\tname,\n\t\t\t\t\t\targs: [...(args as JsonTypeWith<never>[])],\n\t\t\t\t\t}),\n\t\t\t\t\tignoreUnmonitored: true,\n\t\t\t\t},\n\t\t\t\t// This is a notification, so we want to send it immediately.\n\t\t\t\t{ allowableUpdateLatencyMs: 0 },\n\t\t\t);\n\t\t},\n\t\tunicast: (name: string, targetAttendee, ...args) => {\n\t\t\tthis.datastore.localUpdate(\n\t\t\t\tthis.key,\n\t\t\t\t{\n\t\t\t\t\trev: 0,\n\t\t\t\t\ttimestamp: 0,\n\t\t\t\t\tvalue: toOpaqueJson({\n\t\t\t\t\t\tname,\n\t\t\t\t\t\targs: [...(args as JsonTypeWith<never>[])],\n\t\t\t\t\t}),\n\t\t\t\t\tignoreUnmonitored: true,\n\t\t\t\t},\n\t\t\t\t// This is a notification, so we want to send it immediately.\n\t\t\t\t{ allowableUpdateLatencyMs: 0, targetClientId: targetAttendee.getConnectionId() },\n\t\t\t);\n\t\t},\n\t};\n\n\t// Workaround for types\n\tprivate readonly notificationsInternal = createEmitter<NotificationSubscriptions<T>>();\n\n\tpublic readonly notifications: NotificationListenable<T> = this.notificationsInternal;\n\n\tpublic constructor(\n\t\tprivate readonly key: Key,\n\t\tprivate readonly datastore: StateDatastore<\n\t\t\tKey,\n\t\t\tInternalTypes.ValueRequiredState<InternalTypes.NotificationType>\n\t\t>,\n\t\tinitialSubscriptions: Partial<NotificationSubscriptions<T>>,\n\t) {\n\t\t// Add event listeners provided at instantiation\n\t\tfor (const subscriptionName of recordKeys(initialSubscriptions)) {\n\t\t\t// Lingering Event typing issues with Notifications specialization requires\n\t\t\t// this cast. The only thing that really matters is that name is a string.\n\t\t\tconst name = subscriptionName as keyof Listeners<NotificationSubscriptions<T>>;\n\t\t\tconst value = initialSubscriptions[subscriptionName];\n\t\t\t// This check should not be needed while using exactOptionalPropertyTypes, but\n\t\t\t// typescript appears to ignore that with Partial<>. Good to be defensive\n\t\t\t// against callers sending `undefined` anyway.\n\t\t\tif (value !== undefined) {\n\t\t\t\tthis.notificationsInternal.on(name, value);\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 update(\n\t\tattendee: Attendee,\n\t\t_received: number,\n\t\tupdateValue: InternalTypes.ValueRequiredState<InternalTypes.NotificationType>,\n\t): PostUpdateAction[] {\n\t\tconst postUpdateActions: PostUpdateAction[] = [];\n\t\tconst value = revealOpaqueJson(updateValue.value);\n\t\tconst eventName = value.name as keyof Listeners<NotificationSubscriptions<T>>;\n\t\tif (this.notificationsInternal.hasListeners(eventName)) {\n\t\t\t// Without schema validation, we don't know that the args are the correct type.\n\t\t\t// For now we assume the user is sending the correct types and there is no corruption along the way.\n\t\t\tconst args = [attendee, ...value.args] as Parameters<\n\t\t\t\tNotificationSubscriptions<T>[typeof eventName]\n\t\t\t>;\n\t\t\tpostUpdateActions.push(() => this.notificationsInternal.emit(eventName, ...args));\n\t\t} else {\n\t\t\tpostUpdateActions.push(() =>\n\t\t\t\tthis.events.emit(\"unattendedNotification\", value.name, attendee, ...value.args),\n\t\t\t);\n\t\t}\n\t\treturn postUpdateActions;\n\t}\n}\n\n/**\n * Factory for creating a {@link NotificationsManager}.\n *\n * @remarks\n * Typescript inference for `Notifications` is not working correctly yet.\n * Explicitly specify generics to make result types usable.\n *\n * @alpha\n */\nexport function Notifications<\n\tT extends InternalUtilityTypes.NotificationListeners<T>,\n\tKey extends string = string,\n>(\n\tinitialSubscriptions: Partial<NotificationSubscriptions<T>>,\n): InternalTypes.ManagerFactory<\n\tKey,\n\tInternalTypes.ValueRequiredState<InternalTypes.NotificationType>,\n\tNotificationsManager<T>\n> {\n\tconst factory = (\n\t\tkey: Key,\n\t\tdatastoreHandle: InternalTypes.StateDatastoreHandle<\n\t\t\tKey,\n\t\t\tInternalTypes.ValueRequiredState<InternalTypes.NotificationType>\n\t\t>,\n\t): {\n\t\tmanager: InternalTypes.StateValue<NotificationsManager<T>>;\n\t} => ({\n\t\tmanager: brandIVM<\n\t\t\tNotificationsManagerImpl<T, Key>,\n\t\t\tInternalTypes.NotificationType,\n\t\t\tInternalTypes.ValueRequiredState<InternalTypes.NotificationType>\n\t\t>(\n\t\t\tnew NotificationsManagerImpl(\n\t\t\t\tkey,\n\t\t\t\tdatastoreFromHandle(datastoreHandle),\n\t\t\t\tinitialSubscriptions,\n\t\t\t),\n\t\t),\n\t});\n\treturn Object.assign(factory, { instanceBase: NotificationsManagerImpl });\n}\n"]}
1
+ {"version":3,"file":"notificationsManager.js","sourceRoot":"","sources":["../src/notificationsManager.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 { Listeners } from \"@fluidframework/core-interfaces\";\nimport type { JsonTypeWith } from \"@fluidframework/core-interfaces/internal\";\n\nimport type { InternalTypes } from \"./exposedInternalTypes.js\";\nimport type { InternalUtilityTypes } from \"./exposedUtilityTypes.js\";\nimport { revealOpaqueJson, toOpaqueJson } from \"./internalUtils.js\";\nimport type {\n\tNotificationsManager,\n\tNotificationsManagerEvents,\n\tNotificationEmitter,\n\tNotificationSubscriptions,\n\tNotificationListenable,\n} from \"./notificationsManagerTypes.js\";\nimport type { Attendee, PresenceWithNotifications as Presence } from \"./presence.js\";\nimport { datastoreFromHandle, type StateDatastore } from \"./stateDatastore.js\";\nimport type { PostUpdateAction, ValueManager } from \"./statesManagerTypes.js\";\nimport { brandIVM } from \"./valueManager.js\";\n\n/**\n * Object.keys retyped to support specific records keys and\n * branded string-based keys.\n */\nconst recordKeys = Object.keys as <K extends string>(o: Partial<Record<K, unknown>>) => K[];\n\nclass NotificationsManagerImpl<\n\tT extends InternalUtilityTypes.NotificationListeners<T>,\n\tKey extends string,\n> implements\n\t\tNotificationsManager<T>,\n\t\tValueManager<\n\t\t\tInternalTypes.NotificationType,\n\t\t\tInternalTypes.ValueRequiredState<InternalTypes.NotificationType>\n\t\t>\n{\n\tpublic readonly events = createEmitter<NotificationsManagerEvents>();\n\n\tpublic readonly emit: NotificationEmitter<T> = {\n\t\tbroadcast: (name: string, ...args) => {\n\t\t\tthis.datastore.localUpdate(\n\t\t\t\tthis.key,\n\t\t\t\t{\n\t\t\t\t\trev: 0,\n\t\t\t\t\ttimestamp: 0,\n\t\t\t\t\tvalue: toOpaqueJson({\n\t\t\t\t\t\tname,\n\t\t\t\t\t\targs: [...(args as JsonTypeWith<never>[])],\n\t\t\t\t\t}),\n\t\t\t\t\tignoreUnmonitored: true,\n\t\t\t\t},\n\t\t\t\t// This is a notification, so we want to send it immediately.\n\t\t\t\t{ allowableUpdateLatencyMs: 0 },\n\t\t\t);\n\t\t},\n\t\tunicast: (name: string, targetAttendee, ...args) => {\n\t\t\tthis.datastore.localUpdate(\n\t\t\t\tthis.key,\n\t\t\t\t{\n\t\t\t\t\trev: 0,\n\t\t\t\t\ttimestamp: 0,\n\t\t\t\t\tvalue: toOpaqueJson({\n\t\t\t\t\t\tname,\n\t\t\t\t\t\targs: [...(args as JsonTypeWith<never>[])],\n\t\t\t\t\t}),\n\t\t\t\t\tignoreUnmonitored: true,\n\t\t\t\t},\n\t\t\t\t// This is a notification, so we want to send it immediately.\n\t\t\t\t{ allowableUpdateLatencyMs: 0, targetClientId: targetAttendee.getConnectionId() },\n\t\t\t);\n\t\t},\n\t};\n\n\t// Workaround for types\n\tprivate readonly notificationsInternal = createEmitter<NotificationSubscriptions<T>>();\n\n\tpublic readonly notifications: NotificationListenable<T> = this.notificationsInternal;\n\n\tpublic constructor(\n\t\tprivate readonly key: Key,\n\t\tprivate readonly datastore: StateDatastore<\n\t\t\tKey,\n\t\t\tInternalTypes.ValueRequiredState<InternalTypes.NotificationType>\n\t\t>,\n\t\tinitialSubscriptions: Partial<NotificationSubscriptions<T>>,\n\t) {\n\t\t// Add event listeners provided at instantiation\n\t\tfor (const subscriptionName of recordKeys(initialSubscriptions)) {\n\t\t\t// Lingering Event typing issues with Notifications specialization requires\n\t\t\t// this cast. The only thing that really matters is that name is a string.\n\t\t\tconst name = subscriptionName as keyof Listeners<NotificationSubscriptions<T>>;\n\t\t\tconst value = initialSubscriptions[subscriptionName];\n\t\t\t// This check should not be needed while using exactOptionalPropertyTypes, but\n\t\t\t// typescript appears to ignore that with Partial<>. Good to be defensive\n\t\t\t// against callers sending `undefined` anyway.\n\t\t\tif (value !== undefined) {\n\t\t\t\tthis.notificationsInternal.on(name, value);\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 update(\n\t\tattendee: Attendee,\n\t\t_received: number,\n\t\tupdateValue: InternalTypes.ValueRequiredState<InternalTypes.NotificationType>,\n\t): PostUpdateAction[] {\n\t\tconst postUpdateActions: PostUpdateAction[] = [];\n\t\tconst value = revealOpaqueJson(updateValue.value);\n\t\tconst eventName = value.name as keyof Listeners<NotificationSubscriptions<T>>;\n\t\tif (this.notificationsInternal.hasListeners(eventName)) {\n\t\t\t// Without schema validation, we don't know that the args are the correct type.\n\t\t\t// For now we assume the user is sending the correct types and there is no corruption along the way.\n\t\t\tconst args = [attendee, ...value.args] as Parameters<\n\t\t\t\tNotificationSubscriptions<T>[typeof eventName]\n\t\t\t>;\n\t\t\tpostUpdateActions.push(() => this.notificationsInternal.emit(eventName, ...args));\n\t\t} else {\n\t\t\tpostUpdateActions.push(() =>\n\t\t\t\tthis.events.emit(\"unattendedNotification\", value.name, attendee, ...value.args),\n\t\t\t);\n\t\t}\n\t\treturn postUpdateActions;\n\t}\n}\n\n/**\n * Factory for creating a {@link NotificationsManager}.\n *\n * @remarks\n * Typescript inference for `Notifications` is not working correctly yet.\n * Explicitly specify generics to make result types usable.\n *\n * @alpha\n */\nexport function Notifications<\n\tT extends InternalUtilityTypes.NotificationListeners<T>,\n\tKey extends string = string,\n>(\n\tinitialSubscriptions: Partial<NotificationSubscriptions<T>>,\n): InternalTypes.ManagerFactory<\n\tKey,\n\tInternalTypes.ValueRequiredState<InternalTypes.NotificationType>,\n\tNotificationsManager<T>\n> {\n\tconst factory = (\n\t\tkey: Key,\n\t\tdatastoreHandle: InternalTypes.StateDatastoreHandle<\n\t\t\tKey,\n\t\t\tInternalTypes.ValueRequiredState<InternalTypes.NotificationType>\n\t\t>,\n\t): {\n\t\tmanager: InternalTypes.StateValue<NotificationsManager<T>>;\n\t} => ({\n\t\tmanager: brandIVM<\n\t\t\tNotificationsManagerImpl<T, Key>,\n\t\t\tInternalTypes.NotificationType,\n\t\t\tInternalTypes.ValueRequiredState<InternalTypes.NotificationType>\n\t\t>(\n\t\t\tnew NotificationsManagerImpl(\n\t\t\t\tkey,\n\t\t\t\tdatastoreFromHandle(datastoreHandle),\n\t\t\t\tinitialSubscriptions,\n\t\t\t),\n\t\t),\n\t});\n\treturn Object.assign(factory, { instanceBase: NotificationsManagerImpl });\n}\n"]}