@fluidframework/presence 2.81.0-374083 → 2.81.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/broadcastControls.d.ts +1 -33
- package/dist/broadcastControls.d.ts.map +1 -1
- package/dist/broadcastControls.js.map +1 -1
- package/dist/broadcastControlsTypes.d.ts +38 -0
- package/dist/broadcastControlsTypes.d.ts.map +1 -0
- package/dist/broadcastControlsTypes.js +7 -0
- package/dist/broadcastControlsTypes.js.map +1 -0
- package/dist/exposedInternalTypes.d.ts +3 -3
- package/dist/exposedInternalTypes.d.ts.map +1 -1
- package/dist/exposedInternalTypes.js.map +1 -1
- package/dist/exposedUtilityTypes.d.ts +2 -2
- package/dist/exposedUtilityTypes.d.ts.map +1 -1
- package/dist/exposedUtilityTypes.js.map +1 -1
- package/dist/getPresence.d.ts.map +1 -1
- package/dist/getPresence.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/internalUtils.d.ts +1 -3
- package/dist/internalUtils.d.ts.map +1 -1
- package/dist/internalUtils.js +0 -2
- package/dist/internalUtils.js.map +1 -1
- package/dist/latestMapValueManager.d.ts +1 -1
- package/dist/latestMapValueManager.d.ts.map +1 -1
- package/dist/latestMapValueManager.js.map +1 -1
- package/dist/latestValueManager.d.ts +1 -8
- package/dist/latestValueManager.d.ts.map +1 -1
- package/dist/latestValueManager.js +1 -2
- package/dist/latestValueManager.js.map +1 -1
- package/dist/latestValueTypes.d.ts +1 -1
- package/dist/latestValueTypes.d.ts.map +1 -1
- package/dist/latestValueTypes.js.map +1 -1
- package/dist/notificationsManager.d.ts +1 -102
- package/dist/notificationsManager.d.ts.map +1 -1
- package/dist/notificationsManager.js.map +1 -1
- package/dist/notificationsManagerTypes.d.ts +108 -0
- package/dist/notificationsManagerTypes.d.ts.map +1 -0
- package/dist/notificationsManagerTypes.js +7 -0
- package/dist/notificationsManagerTypes.js.map +1 -0
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/presence.d.ts +1 -1
- package/dist/presence.d.ts.map +1 -1
- package/dist/presence.js.map +1 -1
- package/dist/presenceDatastoreManager.d.ts +3 -11
- package/dist/presenceDatastoreManager.d.ts.map +1 -1
- package/dist/presenceDatastoreManager.js +12 -19
- package/dist/presenceDatastoreManager.js.map +1 -1
- package/dist/presenceManager.d.ts +1 -1
- package/dist/presenceManager.d.ts.map +1 -1
- package/dist/presenceManager.js +3 -7
- package/dist/presenceManager.js.map +1 -1
- package/dist/presenceStates.d.ts +4 -2
- package/dist/presenceStates.d.ts.map +1 -1
- package/dist/presenceStates.js.map +1 -1
- package/dist/runtimeTypes.d.ts +26 -0
- package/dist/runtimeTypes.d.ts.map +1 -0
- package/dist/{internalTypes.js → runtimeTypes.js} +1 -1
- package/dist/runtimeTypes.js.map +1 -0
- package/dist/stateDatastore.d.ts +11 -2
- package/dist/stateDatastore.d.ts.map +1 -1
- package/dist/stateDatastore.js.map +1 -1
- package/dist/statesManagerTypes.d.ts +27 -0
- package/dist/statesManagerTypes.d.ts.map +1 -0
- package/dist/statesManagerTypes.js +7 -0
- package/dist/statesManagerTypes.js.map +1 -0
- package/dist/systemWorkspace.d.ts.map +1 -1
- package/dist/systemWorkspace.js +1 -2
- package/dist/systemWorkspace.js.map +1 -1
- package/dist/types.d.ts +7 -6
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/{internalTypes.d.ts → validatableTypes.d.ts} +1 -59
- package/dist/validatableTypes.d.ts.map +1 -0
- package/dist/validatableTypes.js +7 -0
- package/dist/validatableTypes.js.map +1 -0
- package/dist/valueManager.d.ts +1 -1
- package/dist/valueManager.d.ts.map +1 -1
- package/dist/valueManager.js.map +1 -1
- package/lib/broadcastControls.d.ts +1 -33
- package/lib/broadcastControls.d.ts.map +1 -1
- package/lib/broadcastControls.js.map +1 -1
- package/lib/broadcastControlsTypes.d.ts +38 -0
- package/lib/broadcastControlsTypes.d.ts.map +1 -0
- package/lib/broadcastControlsTypes.js +6 -0
- package/lib/broadcastControlsTypes.js.map +1 -0
- package/lib/exposedInternalTypes.d.ts +3 -3
- package/lib/exposedInternalTypes.d.ts.map +1 -1
- package/lib/exposedInternalTypes.js.map +1 -1
- package/lib/exposedUtilityTypes.d.ts +2 -2
- package/lib/exposedUtilityTypes.d.ts.map +1 -1
- package/lib/exposedUtilityTypes.js.map +1 -1
- package/lib/getPresence.d.ts.map +1 -1
- package/lib/getPresence.js.map +1 -1
- package/lib/index.d.ts +3 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/internalUtils.d.ts +1 -3
- package/lib/internalUtils.d.ts.map +1 -1
- package/lib/internalUtils.js +0 -2
- package/lib/internalUtils.js.map +1 -1
- package/lib/latestMapValueManager.d.ts +1 -1
- package/lib/latestMapValueManager.d.ts.map +1 -1
- package/lib/latestMapValueManager.js.map +1 -1
- package/lib/latestValueManager.d.ts +1 -8
- package/lib/latestValueManager.d.ts.map +1 -1
- package/lib/latestValueManager.js +1 -1
- package/lib/latestValueManager.js.map +1 -1
- package/lib/latestValueTypes.d.ts +1 -1
- package/lib/latestValueTypes.d.ts.map +1 -1
- package/lib/latestValueTypes.js.map +1 -1
- package/lib/notificationsManager.d.ts +1 -102
- package/lib/notificationsManager.d.ts.map +1 -1
- package/lib/notificationsManager.js.map +1 -1
- package/lib/notificationsManagerTypes.d.ts +108 -0
- package/lib/notificationsManagerTypes.d.ts.map +1 -0
- package/lib/notificationsManagerTypes.js +6 -0
- package/lib/notificationsManagerTypes.js.map +1 -0
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/presence.d.ts +1 -1
- package/lib/presence.d.ts.map +1 -1
- package/lib/presence.js.map +1 -1
- package/lib/presenceDatastoreManager.d.ts +3 -11
- package/lib/presenceDatastoreManager.d.ts.map +1 -1
- package/lib/presenceDatastoreManager.js +12 -18
- package/lib/presenceDatastoreManager.js.map +1 -1
- package/lib/presenceManager.d.ts +1 -1
- package/lib/presenceManager.d.ts.map +1 -1
- package/lib/presenceManager.js +3 -7
- package/lib/presenceManager.js.map +1 -1
- package/lib/presenceStates.d.ts +4 -2
- package/lib/presenceStates.d.ts.map +1 -1
- package/lib/presenceStates.js.map +1 -1
- package/lib/runtimeTypes.d.ts +26 -0
- package/lib/runtimeTypes.d.ts.map +1 -0
- package/lib/{internalTypes.js → runtimeTypes.js} +1 -1
- package/lib/runtimeTypes.js.map +1 -0
- package/lib/stateDatastore.d.ts +11 -2
- package/lib/stateDatastore.d.ts.map +1 -1
- package/lib/stateDatastore.js.map +1 -1
- package/lib/statesManagerTypes.d.ts +27 -0
- package/lib/statesManagerTypes.d.ts.map +1 -0
- package/lib/statesManagerTypes.js +6 -0
- package/lib/statesManagerTypes.js.map +1 -0
- package/lib/systemWorkspace.d.ts.map +1 -1
- package/lib/systemWorkspace.js +1 -2
- package/lib/systemWorkspace.js.map +1 -1
- package/lib/types.d.ts +7 -6
- package/lib/types.d.ts.map +1 -1
- package/lib/types.js.map +1 -1
- package/lib/{internalTypes.d.ts → validatableTypes.d.ts} +1 -59
- package/lib/validatableTypes.d.ts.map +1 -0
- package/lib/validatableTypes.js +6 -0
- package/lib/validatableTypes.js.map +1 -0
- package/lib/valueManager.d.ts +1 -1
- package/lib/valueManager.d.ts.map +1 -1
- package/lib/valueManager.js.map +1 -1
- package/package.json +16 -16
- package/dist/internalTypes.d.ts.map +0 -1
- package/dist/internalTypes.js.map +0 -1
- package/lib/internalTypes.d.ts.map +0 -1
- package/lib/internalTypes.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presenceStates.js","sourceRoot":"","sources":["../src/presenceStates.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 { assert } from \"@fluidframework/core-utils/internal\";\n\nimport type { ClientConnectionId } from \"./baseTypes.js\";\nimport type { BroadcastControlSettings } from \"./broadcastControls.js\";\nimport { RequiredBroadcastControl } from \"./broadcastControls.js\";\nimport type { InternalTypes } from \"./exposedInternalTypes.js\";\nimport type {\n\tClientRecord,\n\tPostUpdateAction,\n\tValidatableOptionalState,\n\tValidatableRequiredState,\n\tValidatableValueDirectory,\n\tValidatableValueDirectoryOrState,\n\tValidatableValueStructure,\n} from \"./internalTypes.js\";\nimport type { RecordEntryTypes } from \"./internalUtils.js\";\nimport { getOrCreateRecord, objectEntries } from \"./internalUtils.js\";\nimport type { AttendeeId, PresenceWithNotifications as Presence } from \"./presence.js\";\nimport type { LocalStateUpdateOptions, StateDatastore } from \"./stateDatastore.js\";\nimport { handleFromDatastore } from \"./stateDatastore.js\";\nimport type { AnyWorkspace, StatesWorkspace, StatesWorkspaceSchema } from \"./types.js\";\nimport { unbrandIVM } from \"./valueManager.js\";\n\n/**\n * Extracts `Part` from {@link InternalTypes.ManagerFactory} return type\n * matching the {@link StatesWorkspaceSchema} `Keys` given.\n *\n * @remarks\n * If the `Part` is an optional property, undefined will be included in the\n * result. Applying `Required` to the return type prior to extracting `Part`\n * does not work as expected. Exclude\\<, undefined\\> can be used as needed.\n */\nexport type MapSchemaElement<\n\tTSchema extends StatesWorkspaceSchema,\n\tPart extends keyof ReturnType<TSchema[keyof TSchema]>,\n\tKeys extends keyof TSchema = keyof TSchema,\n> = ReturnType<TSchema[Keys]>[Part];\n\n/**\n * Miscellaneous options for local state updates\n */\nexport interface RuntimeLocalUpdateOptions {\n\t/**\n\t * The maximum time in milliseconds that this update is allowed to be\n\t * delayed before it must be sent to the service.\n\t */\n\tallowableUpdateLatencyMs: number;\n\n\t/**\n\t * Special option allowed for unicast notifications.\n\t */\n\ttargetClientId?: ClientConnectionId;\n}\n\n/**\n * Contract for `PresenceDatastoreManager` as required by States Workspaces ({@link PresenceStatesImpl}).\n */\nexport interface PresenceRuntime {\n\treadonly presence: Presence;\n\treadonly attendeeId: AttendeeId;\n\tlocalUpdate(\n\t\tstates: { [key: string]: ClientUpdateEntry },\n\t\toptions: RuntimeLocalUpdateOptions,\n\t): void;\n}\n\ntype PresenceSubSchemaFromWorkspaceSchema<\n\tTSchema extends StatesWorkspaceSchema,\n\tPart extends keyof ReturnType<TSchema[keyof TSchema]>,\n> = {\n\t[Key in keyof TSchema]: MapSchemaElement<TSchema, Part, Key>;\n};\n\ntype MapEntries<TSchema extends StatesWorkspaceSchema> = PresenceSubSchemaFromWorkspaceSchema<\n\tTSchema,\n\t\"manager\"\n>;\n\n/**\n * ValueElementMap is a map of key to a map of clientId to ValueState.\n * It is not restricted to the schema of the map as it may receive updates from other clients\n * with managers that have not been registered locally. Each map node is responsible for keeping\n * all session's state to be able to pick arbitrary client to rebroadcast to others.\n *\n * This generic aspect makes some typing difficult. The loose typing is not broadcast to the\n * consumers that are expected to maintain their schema over multiple versions of clients.\n */\nexport interface ValueElementMap<_TSchema extends StatesWorkspaceSchema> {\n\t[key: string]: ClientRecord<ValidatableValueDirectoryOrState<unknown>>;\n}\n\n// An attempt to make the type more precise, but it is not working.\n// If the casting in support code is too much we could keep two references to the same\n// complete datastore, but with the respective types desired.\n// type ValueElementMap<TSchema extends PresenceStatesNodeSchema> =\n// \t| {\n// \t\t\t[Key in keyof TSchema & string]?: {\n// \t\t\t\t[AttendeeId: AttendeeId]: InternalTypes.ValueDirectoryOrState<MapSchemaElement<TSchema,\"value\",Key>>;\n// \t\t\t};\n// \t }\n// \t| {\n// \t\t\t[key: string]: ClientRecord<InternalTypes.ValueDirectoryOrState<unknown>>;\n// \t };\n// interface ValueElementMap<TValue> {\n// \t[Id: string]: ClientRecord<InternalTypes.ValueDirectoryOrState<TValue>>;\n// \t// Version with local packed in is convenient for map, but not for join broadcast to serialize simply.\n// \t// [Id: string]: {\n// \t// \tlocal: InternalTypes.ValueDirectoryOrState<TValue>;\n// \t// \tall: ClientRecord<InternalTypes.ValueDirectoryOrState<TValue>>;\n// \t// };\n// }\n\n/**\n * Data content of a datastore entry in update messages\n */\nexport type ClientUpdateEntry = InternalTypes.ValueDirectoryOrState<unknown> & {\n\tignoreUnmonitored?: true;\n};\n\ninterface ClientUpdateRecord {\n\t[AttendeeId: AttendeeId]: ClientUpdateEntry;\n}\n\ninterface ValueUpdateRecord {\n\t[valueKey: string]: ClientUpdateRecord;\n}\n\n/**\n * Contract for Workspaces as required by `PresenceDatastoreManager`\n */\nexport interface PresenceStatesInternal {\n\tensureContent<TSchemaAdditional extends StatesWorkspaceSchema>(\n\t\tcontent: TSchemaAdditional,\n\t\tcontrols: BroadcastControlSettings | undefined,\n\t): AnyWorkspace<TSchemaAdditional>;\n\tprocessUpdate(\n\t\treceived: number,\n\t\ttimeModifier: number,\n\t\tremoteDatastore: ValueUpdateRecord,\n\t\tsenderConnectionId: ClientConnectionId,\n\t): PostUpdateAction[];\n}\n\nfunction isValueDirectory<\n\tT,\n\tTValueState extends\n\t\t| InternalTypes.ValueRequiredState<T>\n\t\t| InternalTypes.ValueOptionalState<T>,\n>(\n\tvalue: InternalTypes.ValueDirectory<T> | TValueState,\n): value is InternalTypes.ValueDirectory<T> {\n\treturn \"items\" in value;\n}\n\n// function overloads\n// Non-validatable types\nexport function mergeValueDirectory<\n\tT,\n\tTValueState extends\n\t\t| InternalTypes.ValueRequiredState<T>\n\t\t| InternalTypes.ValueOptionalState<T>,\n>(\n\tbase: TValueState | InternalTypes.ValueDirectory<T> | undefined,\n\tupdate: TValueState | InternalTypes.ValueDirectory<T>,\n\ttimeDelta: number,\n): TValueState | InternalTypes.ValueDirectory<T>;\n// Validatable base type with non-validatable update types\nexport function mergeValueDirectory<\n\tT,\n\tTBaseState extends ValidatableRequiredState<T> | ValidatableOptionalState<T>,\n\tTUpdateState extends\n\t\t| InternalTypes.ValueRequiredState<T>\n\t\t| InternalTypes.ValueOptionalState<T>,\n>(\n\tbase: TBaseState | ValidatableValueDirectory<T> | undefined,\n\tupdate: TUpdateState | InternalTypes.ValueDirectory<T>,\n\ttimeDelta: number,\n): TBaseState | ValidatableValueDirectory<T>;\n// Fully validatable types\nexport function mergeValueDirectory<\n\tT,\n\tTValueState extends ValidatableRequiredState<T> | ValidatableOptionalState<T>,\n>(\n\tbase: TValueState | ValidatableValueDirectory<T> | undefined,\n\tupdate: TValueState | ValidatableValueDirectory<T>,\n\ttimeDelta: number,\n): TValueState | ValidatableValueDirectory<T>;\n/**\n * Merge a value directory.\n *\n * @privateRemarks\n * This implementation uses the InternalTypes set of Value types but it is\n * agnostic so long as the validatable versions don't start requiring\n * properties.\n */\nexport function mergeValueDirectory<\n\tT,\n\tTValueState extends\n\t\t| InternalTypes.ValueRequiredState<T>\n\t\t| InternalTypes.ValueOptionalState<T>,\n>(\n\tbase: TValueState | InternalTypes.ValueDirectory<T> | undefined,\n\tupdate: TValueState | InternalTypes.ValueDirectory<T>,\n\ttimeDelta: number,\n): TValueState | InternalTypes.ValueDirectory<T> {\n\tif (!isValueDirectory(update)) {\n\t\tif (base === undefined || update.rev > base.rev) {\n\t\t\treturn { ...update, timestamp: update.timestamp + timeDelta };\n\t\t}\n\t\treturn base;\n\t}\n\n\tlet mergeBase: InternalTypes.ValueDirectory<T>;\n\tif (base === undefined) {\n\t\tmergeBase = { rev: update.rev, items: {} };\n\t} else {\n\t\tconst baseIsDirectory = isValueDirectory(base);\n\t\tif (base.rev >= update.rev) {\n\t\t\tif (!baseIsDirectory) {\n\t\t\t\t// base is leaf value that is more recent - nothing to do\n\t\t\t\treturn base;\n\t\t\t}\n\t\t\t// While base has more advanced revision, assume mis-ordering or\n\t\t\t// missed and catchup update needs merged in.\n\t\t\tmergeBase = base;\n\t\t} else {\n\t\t\tmergeBase = { rev: update.rev, items: baseIsDirectory ? base.items : {} };\n\t\t}\n\t}\n\tfor (const [key, value] of Object.entries(update.items)) {\n\t\tconst baseElement = mergeBase.items[key];\n\t\tmergeBase.items[key] = mergeValueDirectory(baseElement, value, timeDelta);\n\t}\n\treturn mergeBase;\n}\n\n/**\n * Updates remote state into the local [untracked] datastore.\n *\n * @param key - The key of the datastore to merge the untracked data into.\n * @param remoteAllKnownState - The remote state to merge into the datastore.\n * @param datastore - The datastore to merge the untracked data into.\n *\n * @remarks\n * In the case of ignored unmonitored data, the client entries are not stored,\n * though the value keys will be populated and often remain empty.\n */\nexport function mergeUntrackedDatastore(\n\tkey: string,\n\tremoteAllKnownState: ClientUpdateRecord,\n\tdatastore: ValueElementMap<StatesWorkspaceSchema>,\n\ttimeModifier: number,\n): void {\n\tconst localAllKnownState = getOrCreateRecord(\n\t\tdatastore,\n\t\tkey,\n\t\t(): RecordEntryTypes<typeof datastore> => ({}),\n\t);\n\tfor (const [attendeeId, value] of objectEntries(remoteAllKnownState)) {\n\t\tif (!(\"ignoreUnmonitored\" in value)) {\n\t\t\tlocalAllKnownState[attendeeId] = mergeValueDirectory(\n\t\t\t\tlocalAllKnownState[attendeeId],\n\t\t\t\tvalue,\n\t\t\t\ttimeModifier,\n\t\t\t);\n\t\t}\n\t}\n}\n\n/**\n * The default allowable update latency for StatesWorkspace in milliseconds.\n */\nconst defaultAllowableUpdateLatencyMs = 60;\n\n/**\n * Produces the value type of a schema element or set of elements.\n */\ntype SchemaElementValueType<\n\tTSchema extends StatesWorkspaceSchema,\n\tKeys extends keyof TSchema,\n> = Exclude<MapSchemaElement<TSchema, \"initialData\", Keys>, undefined>[\"value\"];\n\n/**\n * No-runtime-effect helper to protect cast from unknown datastore to specific\n * schema record type. (It is up to consumer to check that record conforms to\n * expectations.)\n */\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nfunction castUnknownRecordToSchemaRecord<\n\tTSchema extends StatesWorkspaceSchema,\n\tKey extends keyof TSchema & string,\n>(record: ClientRecord<ValidatableValueDirectoryOrState<unknown>>) {\n\treturn record as ClientRecord<\n\t\tValidatableValueStructure<SchemaElementValueType<TSchema, Key>>\n\t>;\n}\n\nclass PresenceStatesImpl<TSchema extends StatesWorkspaceSchema>\n\timplements\n\t\tPresenceStatesInternal,\n\t\tAnyWorkspace<TSchema>,\n\t\tStateDatastore<\n\t\t\tkeyof TSchema & string,\n\t\t\tSchemaElementValueType<TSchema, keyof TSchema & string>\n\t\t>\n{\n\tprivate readonly nodes: MapEntries<TSchema>;\n\tpublic readonly states: StatesWorkspace<TSchema>[\"states\"];\n\tpublic readonly notifications: AnyWorkspace<TSchema>[\"notifications\"];\n\n\tpublic readonly controls: RequiredBroadcastControl;\n\n\tpublic constructor(\n\t\tprivate readonly runtime: PresenceRuntime,\n\t\tprivate readonly datastore: ValueElementMap<TSchema>,\n\t\tinitialContent: TSchema,\n\t\tcontrolsSettings: BroadcastControlSettings | undefined,\n\t) {\n\t\tthis.controls = new RequiredBroadcastControl(defaultAllowableUpdateLatencyMs);\n\t\tif (controlsSettings?.allowableUpdateLatencyMs !== undefined) {\n\t\t\tthis.controls.allowableUpdateLatencyMs = controlsSettings.allowableUpdateLatencyMs;\n\t\t}\n\n\t\t// Prepare initial map content from initial state\n\t\t{\n\t\t\tconst attendeeId = this.runtime.attendeeId;\n\t\t\t// Empty record does not satisfy the type, but nodes will post loop.\n\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\t\tconst nodes = {} as MapEntries<TSchema>;\n\t\t\tlet anyInitialValues = false;\n\t\t\tconst newValues: { [key: string]: InternalTypes.ValueDirectoryOrState<unknown> } = {};\n\t\t\tlet cumulativeAllowableUpdateLatencyMs: number | undefined;\n\t\t\tfor (const [key, nodeFactory] of Object.entries(initialContent)) {\n\t\t\t\tconst newNodeData = nodeFactory(key, handleFromDatastore(this));\n\t\t\t\tnodes[key as keyof TSchema] = newNodeData.manager;\n\t\t\t\tif (\"initialData\" in newNodeData) {\n\t\t\t\t\tconst { value, allowableUpdateLatencyMs } = newNodeData.initialData;\n\t\t\t\t\t(datastore[key] ??= {})[attendeeId] = value;\n\t\t\t\t\tnewValues[key] = value;\n\t\t\t\t\tif (allowableUpdateLatencyMs !== undefined) {\n\t\t\t\t\t\tcumulativeAllowableUpdateLatencyMs =\n\t\t\t\t\t\t\tcumulativeAllowableUpdateLatencyMs === undefined\n\t\t\t\t\t\t\t\t? allowableUpdateLatencyMs\n\t\t\t\t\t\t\t\t: Math.min(cumulativeAllowableUpdateLatencyMs, allowableUpdateLatencyMs);\n\t\t\t\t\t}\n\t\t\t\t\tanyInitialValues = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.nodes = nodes;\n\t\t\t// states and notifications are the public view of nodes that limits the entries\n\t\t\t// types to the public interface of State objects with an additional type\n\t\t\t// filter that beguiles the type system. So just reinterpret cast.\n\t\t\tconst properties = nodes as unknown as AnyWorkspace<TSchema>[\"states\"];\n\t\t\t// `AnyWorkspace` support comes from defining both `states` for\n\t\t\t// `StatesWorkspace` and `notifications` for `NotificationsWorkspace`.\n\t\t\t// `notifications` is always a subset of what `states` can be; so the same.\n\t\t\tthis.notifications = this.states = properties;\n\n\t\t\tif (anyInitialValues) {\n\t\t\t\tthis.runtime.localUpdate(newValues, {\n\t\t\t\t\tallowableUpdateLatencyMs:\n\t\t\t\t\t\tcumulativeAllowableUpdateLatencyMs ?? 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.runtime.presence;\n\t}\n\n\tpublic knownValues<Key extends keyof TSchema & string>(\n\t\tkey: Key,\n\t): {\n\t\tself: AttendeeId | undefined;\n\t\tstates: ClientRecord<ValidatableValueStructure<SchemaElementValueType<TSchema, Key>>>;\n\t} {\n\t\treturn {\n\t\t\tself: this.runtime.attendeeId,\n\t\t\t// Caller must only use `key`s that are part of `this.datastore`.\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tstates: castUnknownRecordToSchemaRecord(this.datastore[key]!),\n\t\t};\n\t}\n\n\tpublic localUpdate<Key extends keyof TSchema & string>(\n\t\tkey: Key,\n\t\tvalue: SchemaElementValueType<TSchema, Key> & ClientUpdateEntry,\n\t\toptions: LocalStateUpdateOptions,\n\t): void {\n\t\tthis.runtime.localUpdate(\n\t\t\t{ [key]: value },\n\t\t\t{\n\t\t\t\t...options,\n\t\t\t\tallowableUpdateLatencyMs:\n\t\t\t\t\toptions.allowableUpdateLatencyMs ?? this.controls.allowableUpdateLatencyMs,\n\t\t\t},\n\t\t);\n\t}\n\n\tpublic update<Key extends keyof TSchema & string>(\n\t\tkey: Key,\n\t\tclientId: AttendeeId,\n\t\tvalue: ValidatableValueDirectoryOrState<unknown>,\n\t): void {\n\t\t// Callers my only use `key`s that are part of `this.datastore`.\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\tconst allKnownState = this.datastore[key]!;\n\t\tallKnownState[clientId] = mergeValueDirectory<unknown, ValidatableRequiredState<unknown>>(\n\t\t\tallKnownState[clientId],\n\t\t\tvalue,\n\t\t\t0,\n\t\t);\n\t}\n\n\tpublic add<\n\t\tTKey extends string,\n\t\tTValue extends InternalTypes.ValueDirectoryOrState<unknown>,\n\t\tTValueManager,\n\t>(\n\t\tkey: TKey,\n\t\tnodeFactory: InternalTypes.ManagerFactory<TKey, TValue, TValueManager>,\n\t): asserts this is StatesWorkspace<\n\t\tTSchema & Record<TKey, InternalTypes.ManagerFactory<TKey, TValue, TValueManager>>\n\t> {\n\t\tassert(!(key in this.nodes), 0xa3c /* Already have entry for key in map */);\n\t\tconst nodeData = nodeFactory(key, handleFromDatastore(this));\n\t\tthis.nodes[key] = nodeData.manager;\n\t\tif (\"initialData\" in nodeData) {\n\t\t\tconst { value, allowableUpdateLatencyMs } = nodeData.initialData;\n\t\t\tlet datastoreValue = this.datastore[key];\n\t\t\tif (datastoreValue === undefined) {\n\t\t\t\tdatastoreValue = this.datastore[key] = {};\n\t\t\t} else {\n\t\t\t\t// Already have received state from other clients. Kept in `all`.\n\t\t\t\t// TODO: Send current `all` state to state manager.\n\t\t\t}\n\t\t\tdatastoreValue[this.runtime.attendeeId] = value;\n\t\t\tthis.runtime.localUpdate(\n\t\t\t\t{ [key]: value },\n\t\t\t\t{\n\t\t\t\t\tallowableUpdateLatencyMs:\n\t\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 ensureContent<TSchemaAdditional extends StatesWorkspaceSchema>(\n\t\tcontent: TSchemaAdditional,\n\t\tcontrols: BroadcastControlSettings | undefined,\n\t): AnyWorkspace<TSchema & TSchemaAdditional> {\n\t\tif (controls?.allowableUpdateLatencyMs !== undefined) {\n\t\t\tthis.controls.allowableUpdateLatencyMs = controls.allowableUpdateLatencyMs;\n\t\t}\n\t\tfor (const [key, nodeFactory] of Object.entries(content)) {\n\t\t\tconst brandedIVM = this.nodes[key];\n\t\t\tif (brandedIVM === undefined) {\n\t\t\t\tthis.add(key, nodeFactory);\n\t\t\t} else {\n\t\t\t\tconst node = unbrandIVM(brandedIVM);\n\t\t\t\tif (!(node instanceof nodeFactory.instanceBase)) {\n\t\t\t\t\tthrow new TypeError(`State \"${key}\" previously created by different State object.`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this as AnyWorkspace<TSchema & TSchemaAdditional>;\n\t}\n\n\tpublic processUpdate(\n\t\treceived: number,\n\t\ttimeModifier: number,\n\t\tremoteDatastore: ValueUpdateRecord,\n\t): PostUpdateAction[] {\n\t\tconst postUpdateActions: PostUpdateAction[] = [];\n\t\tfor (const [key, remoteAllKnownState] of Object.entries(remoteDatastore)) {\n\t\t\tconst brandedIVM = this.nodes[key];\n\t\t\tif (brandedIVM === undefined) {\n\t\t\t\t// Assume all broadcast state is meant to be kept even if not currently registered.\n\t\t\t\tmergeUntrackedDatastore(key, remoteAllKnownState, this.datastore, timeModifier);\n\t\t\t} else {\n\t\t\t\tconst node = unbrandIVM(brandedIVM);\n\t\t\t\tfor (const [attendeeId, value] of objectEntries(remoteAllKnownState)) {\n\t\t\t\t\tconst client = this.runtime.presence.attendees.getAttendee(attendeeId);\n\t\t\t\t\tpostUpdateActions.push(...node.update(client, received, value));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn postUpdateActions;\n\t}\n}\n\n/**\n * Create a new Workspace using the DataStoreRuntime provided.\n * @param initialContent - The initial State objects to register.\n */\nexport function createPresenceStates<TSchema extends StatesWorkspaceSchema>(\n\truntime: PresenceRuntime,\n\tdatastore: ValueElementMap<StatesWorkspaceSchema>,\n\tinitialContent: TSchema,\n\tcontrols: BroadcastControlSettings | undefined,\n): { public: AnyWorkspace<TSchema>; internal: PresenceStatesInternal } {\n\tconst impl = new PresenceStatesImpl<TSchema>(runtime, datastore, initialContent, controls);\n\n\treturn {\n\t\tpublic: impl,\n\t\tinternal: impl,\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"presenceStates.js","sourceRoot":"","sources":["../src/presenceStates.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 { assert } from \"@fluidframework/core-utils/internal\";\n\nimport type { ClientConnectionId } from \"./baseTypes.js\";\nimport { RequiredBroadcastControl } from \"./broadcastControls.js\";\nimport type { BroadcastControlSettings } from \"./broadcastControlsTypes.js\";\nimport type { InternalTypes } from \"./exposedInternalTypes.js\";\nimport type { RecordEntryTypes } from \"./internalUtils.js\";\nimport { getOrCreateRecord, objectEntries } from \"./internalUtils.js\";\nimport type { AttendeeId, PresenceWithNotifications as Presence } from \"./presence.js\";\nimport type {\n\tClientRecord,\n\tLocalStateUpdateOptions,\n\tStateDatastore,\n} from \"./stateDatastore.js\";\nimport { handleFromDatastore } from \"./stateDatastore.js\";\nimport type { PostUpdateAction } from \"./statesManagerTypes.js\";\nimport type { AnyWorkspace, StatesWorkspace, StatesWorkspaceSchema } from \"./types.js\";\nimport type {\n\tValidatableOptionalState,\n\tValidatableRequiredState,\n\tValidatableValueDirectory,\n\tValidatableValueDirectoryOrState,\n\tValidatableValueStructure,\n} from \"./validatableTypes.js\";\nimport { unbrandIVM } from \"./valueManager.js\";\n\n/**\n * Extracts `Part` from {@link InternalTypes.ManagerFactory} return type\n * matching the {@link StatesWorkspaceSchema} `Keys` given.\n *\n * @remarks\n * If the `Part` is an optional property, undefined will be included in the\n * result. Applying `Required` to the return type prior to extracting `Part`\n * does not work as expected. Exclude\\<, undefined\\> can be used as needed.\n */\nexport type MapSchemaElement<\n\tTSchema extends StatesWorkspaceSchema,\n\tPart extends keyof ReturnType<TSchema[keyof TSchema]>,\n\tKeys extends keyof TSchema = keyof TSchema,\n> = ReturnType<TSchema[Keys]>[Part];\n\n/**\n * Miscellaneous options for local state updates\n */\nexport interface RuntimeLocalUpdateOptions {\n\t/**\n\t * The maximum time in milliseconds that this update is allowed to be\n\t * delayed before it must be sent to the service.\n\t */\n\tallowableUpdateLatencyMs: number;\n\n\t/**\n\t * Special option allowed for unicast notifications.\n\t */\n\ttargetClientId?: ClientConnectionId;\n}\n\n/**\n * Contract for `PresenceDatastoreManager` as required by States Workspaces ({@link PresenceStatesImpl}).\n */\nexport interface PresenceRuntime {\n\treadonly presence: Presence;\n\treadonly attendeeId: AttendeeId;\n\tlocalUpdate(\n\t\tstates: { [key: string]: ClientUpdateEntry },\n\t\toptions: RuntimeLocalUpdateOptions,\n\t): void;\n}\n\ntype PresenceSubSchemaFromWorkspaceSchema<\n\tTSchema extends StatesWorkspaceSchema,\n\tPart extends keyof ReturnType<TSchema[keyof TSchema]>,\n> = {\n\t[Key in keyof TSchema]: MapSchemaElement<TSchema, Part, Key>;\n};\n\ntype MapEntries<TSchema extends StatesWorkspaceSchema> = PresenceSubSchemaFromWorkspaceSchema<\n\tTSchema,\n\t\"manager\"\n>;\n\n/**\n * ValueElementMap is a map of key to a map of clientId to ValueState.\n * It is not restricted to the schema of the map as it may receive updates from other clients\n * with managers that have not been registered locally. Each map node is responsible for keeping\n * all session's state to be able to pick arbitrary client to rebroadcast to others.\n *\n * This generic aspect makes some typing difficult. The loose typing is not broadcast to the\n * consumers that are expected to maintain their schema over multiple versions of clients.\n */\nexport interface ValueElementMap<_TSchema extends StatesWorkspaceSchema> {\n\t[key: string]: ClientRecord<ValidatableValueDirectoryOrState<unknown>>;\n}\n\n// An attempt to make the type more precise, but it is not working.\n// If the casting in support code is too much we could keep two references to the same\n// complete datastore, but with the respective types desired.\n// type ValueElementMap<TSchema extends PresenceStatesNodeSchema> =\n// \t| {\n// \t\t\t[Key in keyof TSchema & string]?: {\n// \t\t\t\t[AttendeeId: AttendeeId]: InternalTypes.ValueDirectoryOrState<MapSchemaElement<TSchema,\"value\",Key>>;\n// \t\t\t};\n// \t }\n// \t| {\n// \t\t\t[key: string]: ClientRecord<InternalTypes.ValueDirectoryOrState<unknown>>;\n// \t };\n// interface ValueElementMap<TValue> {\n// \t[Id: string]: ClientRecord<InternalTypes.ValueDirectoryOrState<TValue>>;\n// \t// Version with local packed in is convenient for map, but not for join broadcast to serialize simply.\n// \t// [Id: string]: {\n// \t// \tlocal: InternalTypes.ValueDirectoryOrState<TValue>;\n// \t// \tall: ClientRecord<InternalTypes.ValueDirectoryOrState<TValue>>;\n// \t// };\n// }\n\n/**\n * Data content of a datastore entry in update messages\n */\nexport type ClientUpdateEntry = InternalTypes.ValueDirectoryOrState<unknown> & {\n\tignoreUnmonitored?: true;\n};\n\ninterface ClientUpdateRecord {\n\t[AttendeeId: AttendeeId]: ClientUpdateEntry;\n}\n\ninterface ValueUpdateRecord {\n\t[valueKey: string]: ClientUpdateRecord;\n}\n\n/**\n * Contract for Workspaces as required by `PresenceDatastoreManager`\n */\nexport interface PresenceStatesInternal {\n\tensureContent<TSchemaAdditional extends StatesWorkspaceSchema>(\n\t\tcontent: TSchemaAdditional,\n\t\tcontrols: BroadcastControlSettings | undefined,\n\t): AnyWorkspace<TSchemaAdditional>;\n\tprocessUpdate(\n\t\treceived: number,\n\t\ttimeModifier: number,\n\t\tremoteDatastore: ValueUpdateRecord,\n\t\tsenderConnectionId: ClientConnectionId,\n\t): PostUpdateAction[];\n}\n\nfunction isValueDirectory<\n\tT,\n\tTValueState extends\n\t\t| InternalTypes.ValueRequiredState<T>\n\t\t| InternalTypes.ValueOptionalState<T>,\n>(\n\tvalue: InternalTypes.ValueDirectory<T> | TValueState,\n): value is InternalTypes.ValueDirectory<T> {\n\treturn \"items\" in value;\n}\n\n// function overloads\n// Non-validatable types\nexport function mergeValueDirectory<\n\tT,\n\tTValueState extends\n\t\t| InternalTypes.ValueRequiredState<T>\n\t\t| InternalTypes.ValueOptionalState<T>,\n>(\n\tbase: TValueState | InternalTypes.ValueDirectory<T> | undefined,\n\tupdate: TValueState | InternalTypes.ValueDirectory<T>,\n\ttimeDelta: number,\n): TValueState | InternalTypes.ValueDirectory<T>;\n// Validatable base type with non-validatable update types\nexport function mergeValueDirectory<\n\tT,\n\tTBaseState extends ValidatableRequiredState<T> | ValidatableOptionalState<T>,\n\tTUpdateState extends\n\t\t| InternalTypes.ValueRequiredState<T>\n\t\t| InternalTypes.ValueOptionalState<T>,\n>(\n\tbase: TBaseState | ValidatableValueDirectory<T> | undefined,\n\tupdate: TUpdateState | InternalTypes.ValueDirectory<T>,\n\ttimeDelta: number,\n): TBaseState | ValidatableValueDirectory<T>;\n// Fully validatable types\nexport function mergeValueDirectory<\n\tT,\n\tTValueState extends ValidatableRequiredState<T> | ValidatableOptionalState<T>,\n>(\n\tbase: TValueState | ValidatableValueDirectory<T> | undefined,\n\tupdate: TValueState | ValidatableValueDirectory<T>,\n\ttimeDelta: number,\n): TValueState | ValidatableValueDirectory<T>;\n/**\n * Merge a value directory.\n *\n * @privateRemarks\n * This implementation uses the InternalTypes set of Value types but it is\n * agnostic so long as the validatable versions don't start requiring\n * properties.\n */\nexport function mergeValueDirectory<\n\tT,\n\tTValueState extends\n\t\t| InternalTypes.ValueRequiredState<T>\n\t\t| InternalTypes.ValueOptionalState<T>,\n>(\n\tbase: TValueState | InternalTypes.ValueDirectory<T> | undefined,\n\tupdate: TValueState | InternalTypes.ValueDirectory<T>,\n\ttimeDelta: number,\n): TValueState | InternalTypes.ValueDirectory<T> {\n\tif (!isValueDirectory(update)) {\n\t\tif (base === undefined || update.rev > base.rev) {\n\t\t\treturn { ...update, timestamp: update.timestamp + timeDelta };\n\t\t}\n\t\treturn base;\n\t}\n\n\tlet mergeBase: InternalTypes.ValueDirectory<T>;\n\tif (base === undefined) {\n\t\tmergeBase = { rev: update.rev, items: {} };\n\t} else {\n\t\tconst baseIsDirectory = isValueDirectory(base);\n\t\tif (base.rev >= update.rev) {\n\t\t\tif (!baseIsDirectory) {\n\t\t\t\t// base is leaf value that is more recent - nothing to do\n\t\t\t\treturn base;\n\t\t\t}\n\t\t\t// While base has more advanced revision, assume mis-ordering or\n\t\t\t// missed and catchup update needs merged in.\n\t\t\tmergeBase = base;\n\t\t} else {\n\t\t\tmergeBase = { rev: update.rev, items: baseIsDirectory ? base.items : {} };\n\t\t}\n\t}\n\tfor (const [key, value] of Object.entries(update.items)) {\n\t\tconst baseElement = mergeBase.items[key];\n\t\tmergeBase.items[key] = mergeValueDirectory(baseElement, value, timeDelta);\n\t}\n\treturn mergeBase;\n}\n\n/**\n * Updates remote state into the local [untracked] datastore.\n *\n * @param key - The key of the datastore to merge the untracked data into.\n * @param remoteAllKnownState - The remote state to merge into the datastore.\n * @param datastore - The datastore to merge the untracked data into.\n *\n * @remarks\n * In the case of ignored unmonitored data, the client entries are not stored,\n * though the value keys will be populated and often remain empty.\n */\nexport function mergeUntrackedDatastore(\n\tkey: string,\n\tremoteAllKnownState: ClientUpdateRecord,\n\tdatastore: ValueElementMap<StatesWorkspaceSchema>,\n\ttimeModifier: number,\n): void {\n\tconst localAllKnownState = getOrCreateRecord(\n\t\tdatastore,\n\t\tkey,\n\t\t(): RecordEntryTypes<typeof datastore> => ({}),\n\t);\n\tfor (const [attendeeId, value] of objectEntries(remoteAllKnownState)) {\n\t\tif (!(\"ignoreUnmonitored\" in value)) {\n\t\t\tlocalAllKnownState[attendeeId] = mergeValueDirectory(\n\t\t\t\tlocalAllKnownState[attendeeId],\n\t\t\t\tvalue,\n\t\t\t\ttimeModifier,\n\t\t\t);\n\t\t}\n\t}\n}\n\n/**\n * The default allowable update latency for StatesWorkspace in milliseconds.\n */\nconst defaultAllowableUpdateLatencyMs = 60;\n\n/**\n * Produces the value type of a schema element or set of elements.\n */\ntype SchemaElementValueType<\n\tTSchema extends StatesWorkspaceSchema,\n\tKeys extends keyof TSchema,\n> = Exclude<MapSchemaElement<TSchema, \"initialData\", Keys>, undefined>[\"value\"];\n\n/**\n * No-runtime-effect helper to protect cast from unknown datastore to specific\n * schema record type. (It is up to consumer to check that record conforms to\n * expectations.)\n */\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nfunction castUnknownRecordToSchemaRecord<\n\tTSchema extends StatesWorkspaceSchema,\n\tKey extends keyof TSchema & string,\n>(record: ClientRecord<ValidatableValueDirectoryOrState<unknown>>) {\n\treturn record as ClientRecord<\n\t\tValidatableValueStructure<SchemaElementValueType<TSchema, Key>>\n\t>;\n}\n\nclass PresenceStatesImpl<TSchema extends StatesWorkspaceSchema>\n\timplements\n\t\tPresenceStatesInternal,\n\t\tAnyWorkspace<TSchema>,\n\t\tStateDatastore<\n\t\t\tkeyof TSchema & string,\n\t\t\tSchemaElementValueType<TSchema, keyof TSchema & string>\n\t\t>\n{\n\tprivate readonly nodes: MapEntries<TSchema>;\n\tpublic readonly states: StatesWorkspace<TSchema>[\"states\"];\n\tpublic readonly notifications: AnyWorkspace<TSchema>[\"notifications\"];\n\n\tpublic readonly controls: RequiredBroadcastControl;\n\n\tpublic constructor(\n\t\tprivate readonly runtime: PresenceRuntime,\n\t\tprivate readonly datastore: ValueElementMap<TSchema>,\n\t\tinitialContent: TSchema,\n\t\tcontrolsSettings: BroadcastControlSettings | undefined,\n\t) {\n\t\tthis.controls = new RequiredBroadcastControl(defaultAllowableUpdateLatencyMs);\n\t\tif (controlsSettings?.allowableUpdateLatencyMs !== undefined) {\n\t\t\tthis.controls.allowableUpdateLatencyMs = controlsSettings.allowableUpdateLatencyMs;\n\t\t}\n\n\t\t// Prepare initial map content from initial state\n\t\t{\n\t\t\tconst attendeeId = this.runtime.attendeeId;\n\t\t\t// Empty record does not satisfy the type, but nodes will post loop.\n\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\t\tconst nodes = {} as MapEntries<TSchema>;\n\t\t\tlet anyInitialValues = false;\n\t\t\tconst newValues: { [key: string]: InternalTypes.ValueDirectoryOrState<unknown> } = {};\n\t\t\tlet cumulativeAllowableUpdateLatencyMs: number | undefined;\n\t\t\tfor (const [key, nodeFactory] of Object.entries(initialContent)) {\n\t\t\t\tconst newNodeData = nodeFactory(key, handleFromDatastore(this));\n\t\t\t\tnodes[key as keyof TSchema] = newNodeData.manager;\n\t\t\t\tif (\"initialData\" in newNodeData) {\n\t\t\t\t\tconst { value, allowableUpdateLatencyMs } = newNodeData.initialData;\n\t\t\t\t\t(datastore[key] ??= {})[attendeeId] = value;\n\t\t\t\t\tnewValues[key] = value;\n\t\t\t\t\tif (allowableUpdateLatencyMs !== undefined) {\n\t\t\t\t\t\tcumulativeAllowableUpdateLatencyMs =\n\t\t\t\t\t\t\tcumulativeAllowableUpdateLatencyMs === undefined\n\t\t\t\t\t\t\t\t? allowableUpdateLatencyMs\n\t\t\t\t\t\t\t\t: Math.min(cumulativeAllowableUpdateLatencyMs, allowableUpdateLatencyMs);\n\t\t\t\t\t}\n\t\t\t\t\tanyInitialValues = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.nodes = nodes;\n\t\t\t// states and notifications are the public view of nodes that limits the entries\n\t\t\t// types to the public interface of State objects with an additional type\n\t\t\t// filter that beguiles the type system. So just reinterpret cast.\n\t\t\tconst properties = nodes as unknown as AnyWorkspace<TSchema>[\"states\"];\n\t\t\t// `AnyWorkspace` support comes from defining both `states` for\n\t\t\t// `StatesWorkspace` and `notifications` for `NotificationsWorkspace`.\n\t\t\t// `notifications` is always a subset of what `states` can be; so the same.\n\t\t\tthis.notifications = this.states = properties;\n\n\t\t\tif (anyInitialValues) {\n\t\t\t\tthis.runtime.localUpdate(newValues, {\n\t\t\t\t\tallowableUpdateLatencyMs:\n\t\t\t\t\t\tcumulativeAllowableUpdateLatencyMs ?? 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.runtime.presence;\n\t}\n\n\tpublic knownValues<Key extends keyof TSchema & string>(\n\t\tkey: Key,\n\t): {\n\t\tself: AttendeeId | undefined;\n\t\tstates: ClientRecord<ValidatableValueStructure<SchemaElementValueType<TSchema, Key>>>;\n\t} {\n\t\treturn {\n\t\t\tself: this.runtime.attendeeId,\n\t\t\t// Caller must only use `key`s that are part of `this.datastore`.\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tstates: castUnknownRecordToSchemaRecord(this.datastore[key]!),\n\t\t};\n\t}\n\n\tpublic localUpdate<Key extends keyof TSchema & string>(\n\t\tkey: Key,\n\t\tvalue: SchemaElementValueType<TSchema, Key> & ClientUpdateEntry,\n\t\toptions: LocalStateUpdateOptions,\n\t): void {\n\t\tthis.runtime.localUpdate(\n\t\t\t{ [key]: value },\n\t\t\t{\n\t\t\t\t...options,\n\t\t\t\tallowableUpdateLatencyMs:\n\t\t\t\t\toptions.allowableUpdateLatencyMs ?? this.controls.allowableUpdateLatencyMs,\n\t\t\t},\n\t\t);\n\t}\n\n\tpublic update<Key extends keyof TSchema & string>(\n\t\tkey: Key,\n\t\tclientId: AttendeeId,\n\t\tvalue: ValidatableValueDirectoryOrState<unknown>,\n\t): void {\n\t\t// Callers my only use `key`s that are part of `this.datastore`.\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\tconst allKnownState = this.datastore[key]!;\n\t\tallKnownState[clientId] = mergeValueDirectory<unknown, ValidatableRequiredState<unknown>>(\n\t\t\tallKnownState[clientId],\n\t\t\tvalue,\n\t\t\t0,\n\t\t);\n\t}\n\n\tpublic add<\n\t\tTKey extends string,\n\t\tTValue extends InternalTypes.ValueDirectoryOrState<unknown>,\n\t\tTValueManager,\n\t>(\n\t\tkey: TKey,\n\t\tnodeFactory: InternalTypes.ManagerFactory<TKey, TValue, TValueManager>,\n\t): asserts this is StatesWorkspace<\n\t\tTSchema & Record<TKey, InternalTypes.ManagerFactory<TKey, TValue, TValueManager>>\n\t> {\n\t\tassert(!(key in this.nodes), 0xa3c /* Already have entry for key in map */);\n\t\tconst nodeData = nodeFactory(key, handleFromDatastore(this));\n\t\tthis.nodes[key] = nodeData.manager;\n\t\tif (\"initialData\" in nodeData) {\n\t\t\tconst { value, allowableUpdateLatencyMs } = nodeData.initialData;\n\t\t\tlet datastoreValue = this.datastore[key];\n\t\t\tif (datastoreValue === undefined) {\n\t\t\t\tdatastoreValue = this.datastore[key] = {};\n\t\t\t} else {\n\t\t\t\t// Already have received state from other clients. Kept in `all`.\n\t\t\t\t// TODO: Send current `all` state to state manager.\n\t\t\t}\n\t\t\tdatastoreValue[this.runtime.attendeeId] = value;\n\t\t\tthis.runtime.localUpdate(\n\t\t\t\t{ [key]: value },\n\t\t\t\t{\n\t\t\t\t\tallowableUpdateLatencyMs:\n\t\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 ensureContent<TSchemaAdditional extends StatesWorkspaceSchema>(\n\t\tcontent: TSchemaAdditional,\n\t\tcontrols: BroadcastControlSettings | undefined,\n\t): AnyWorkspace<TSchema & TSchemaAdditional> {\n\t\tif (controls?.allowableUpdateLatencyMs !== undefined) {\n\t\t\tthis.controls.allowableUpdateLatencyMs = controls.allowableUpdateLatencyMs;\n\t\t}\n\t\tfor (const [key, nodeFactory] of Object.entries(content)) {\n\t\t\tconst brandedIVM = this.nodes[key];\n\t\t\tif (brandedIVM === undefined) {\n\t\t\t\tthis.add(key, nodeFactory);\n\t\t\t} else {\n\t\t\t\tconst node = unbrandIVM(brandedIVM);\n\t\t\t\tif (!(node instanceof nodeFactory.instanceBase)) {\n\t\t\t\t\tthrow new TypeError(`State \"${key}\" previously created by different State object.`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this as AnyWorkspace<TSchema & TSchemaAdditional>;\n\t}\n\n\tpublic processUpdate(\n\t\treceived: number,\n\t\ttimeModifier: number,\n\t\tremoteDatastore: ValueUpdateRecord,\n\t): PostUpdateAction[] {\n\t\tconst postUpdateActions: PostUpdateAction[] = [];\n\t\tfor (const [key, remoteAllKnownState] of Object.entries(remoteDatastore)) {\n\t\t\tconst brandedIVM = this.nodes[key];\n\t\t\tif (brandedIVM === undefined) {\n\t\t\t\t// Assume all broadcast state is meant to be kept even if not currently registered.\n\t\t\t\tmergeUntrackedDatastore(key, remoteAllKnownState, this.datastore, timeModifier);\n\t\t\t} else {\n\t\t\t\tconst node = unbrandIVM(brandedIVM);\n\t\t\t\tfor (const [attendeeId, value] of objectEntries(remoteAllKnownState)) {\n\t\t\t\t\tconst client = this.runtime.presence.attendees.getAttendee(attendeeId);\n\t\t\t\t\tpostUpdateActions.push(...node.update(client, received, value));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn postUpdateActions;\n\t}\n}\n\n/**\n * Create a new Workspace using the DataStoreRuntime provided.\n * @param initialContent - The initial State objects to register.\n */\nexport function createPresenceStates<TSchema extends StatesWorkspaceSchema>(\n\truntime: PresenceRuntime,\n\tdatastore: ValueElementMap<StatesWorkspaceSchema>,\n\tinitialContent: TSchema,\n\tcontrols: BroadcastControlSettings | undefined,\n): { public: AnyWorkspace<TSchema>; internal: PresenceStatesInternal } {\n\tconst impl = new PresenceStatesImpl<TSchema>(runtime, datastore, initialContent, controls);\n\n\treturn {\n\t\tpublic: impl,\n\t\tinternal: impl,\n\t};\n}\n"]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
import type { ExtensionHost as ContainerExtensionHost } from "@fluidframework/container-runtime-definitions/internal";
|
|
6
|
+
import type { OutboundPresenceMessage, SignalMessages } from "./protocol.js";
|
|
7
|
+
/**
|
|
8
|
+
* Presence {@link ContainerExtension} version of {@link @fluidframework/container-runtime-definitions#ExtensionRuntimeProperties}
|
|
9
|
+
*/
|
|
10
|
+
export interface ExtensionRuntimeProperties {
|
|
11
|
+
SignalMessages: SignalMessages;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Presence specific ExtensionHost
|
|
15
|
+
*/
|
|
16
|
+
export type ExtensionHost = ContainerExtensionHost<ExtensionRuntimeProperties>;
|
|
17
|
+
/**
|
|
18
|
+
* This interface is a subset of ExtensionHost that is needed by the Presence States.
|
|
19
|
+
*/
|
|
20
|
+
export type IEphemeralRuntime = Omit<ExtensionHost, "submitAddressedSignal"> & {
|
|
21
|
+
/**
|
|
22
|
+
* Submits the signal to be sent to other clients.
|
|
23
|
+
*/
|
|
24
|
+
submitSignal: (message: OutboundPresenceMessage) => void;
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=runtimeTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtimeTypes.d.ts","sourceRoot":"","sources":["../src/runtimeTypes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,IAAI,sBAAsB,EAAE,MAAM,wDAAwD,CAAC;AAEtH,OAAO,KAAK,EAAE,uBAAuB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE7E;;GAEG;AACH,MAAM,WAAW,0BAA0B;IAC1C,cAAc,EAAE,cAAc,CAAC;CAC/B;AACD;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,sBAAsB,CAAC,0BAA0B,CAAC,CAAC;AAE/E;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,aAAa,EAAE,uBAAuB,CAAC,GAAG;IAC9E;;OAEG;IACH,YAAY,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,IAAI,CAAC;CACzD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtimeTypes.js","sourceRoot":"","sources":["../src/runtimeTypes.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { ExtensionHost as ContainerExtensionHost } from \"@fluidframework/container-runtime-definitions/internal\";\n\nimport type { OutboundPresenceMessage, SignalMessages } from \"./protocol.js\";\n\n/**\n * Presence {@link ContainerExtension} version of {@link @fluidframework/container-runtime-definitions#ExtensionRuntimeProperties}\n */\nexport interface ExtensionRuntimeProperties {\n\tSignalMessages: SignalMessages;\n}\n/**\n * Presence specific ExtensionHost\n */\nexport type ExtensionHost = ContainerExtensionHost<ExtensionRuntimeProperties>;\n\n/**\n * This interface is a subset of ExtensionHost that is needed by the Presence States.\n */\nexport type IEphemeralRuntime = Omit<ExtensionHost, \"submitAddressedSignal\"> & {\n\t/**\n\t * Submits the signal to be sent to other clients.\n\t */\n\tsubmitSignal: (message: OutboundPresenceMessage) => void;\n};\n"]}
|
package/lib/stateDatastore.d.ts
CHANGED
|
@@ -4,8 +4,17 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import type { ClientConnectionId } from "./baseTypes.js";
|
|
6
6
|
import type { InternalTypes } from "./exposedInternalTypes.js";
|
|
7
|
-
import type { ClientRecord, ValidatableValueDirectoryOrState, ValidatableValueStructure } from "./internalTypes.js";
|
|
8
7
|
import type { AttendeeId, PresenceWithNotifications as Presence } from "./presence.js";
|
|
8
|
+
import type { ValidatableValueDirectoryOrState, ValidatableValueStructure } from "./validatableTypes.js";
|
|
9
|
+
/**
|
|
10
|
+
* Basic structure of set of {@link Attendee} records within Presence datastore
|
|
11
|
+
*
|
|
12
|
+
* @remarks
|
|
13
|
+
* This is commonly exists per named state in State Managers.
|
|
14
|
+
*/
|
|
15
|
+
export interface ClientRecord<TValue extends ValidatableValueDirectoryOrState<unknown>> {
|
|
16
|
+
[AttendeeId: AttendeeId]: TValue;
|
|
17
|
+
}
|
|
9
18
|
/**
|
|
10
19
|
* Miscellaneous options for local state updates
|
|
11
20
|
*/
|
|
@@ -43,5 +52,5 @@ export declare function handleFromDatastore<TKey extends string, TValue extends
|
|
|
43
52
|
/**
|
|
44
53
|
* Helper to get the datastore back from its handle.
|
|
45
54
|
*/
|
|
46
|
-
export declare function datastoreFromHandle<TKey extends string, TValue extends InternalTypes.ValueDirectoryOrState<
|
|
55
|
+
export declare function datastoreFromHandle<TKey extends string, TValue extends InternalTypes.ValueDirectoryOrState<unknown>>(handle: InternalTypes.StateDatastoreHandle<TKey, TValue>): StateDatastore<TKey, TValue>;
|
|
47
56
|
//# sourceMappingURL=stateDatastore.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stateDatastore.d.ts","sourceRoot":"","sources":["../src/stateDatastore.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"stateDatastore.d.ts","sourceRoot":"","sources":["../src/stateDatastore.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,yBAAyB,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AACvF,OAAO,KAAK,EACX,gCAAgC,EAChC,yBAAyB,EACzB,MAAM,uBAAuB,CAAC;AAE/B;;;;;GAKG;AACH,MAAM,WAAW,YAAY,CAAC,MAAM,SAAS,gCAAgC,CAAC,OAAO,CAAC;IAIrF,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAAC;CACjC;AAcD;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACvC;;;;OAIG;IACH,wBAAwB,EAAE,MAAM,GAAG,SAAS,CAAC;IAE7C;;OAEG;IACH,cAAc,CAAC,EAAE,kBAAkB,CAAC;CACpC;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc,CAC9B,IAAI,SAAS,MAAM,EACnB,iBAAiB,SAAS,aAAa,CAAC,qBAAqB,CAAC,OAAO,CAAC,EACtE,YAAY,SACX,gCAAgC,CAAC,OAAO,CAAC,GAAG,yBAAyB,CAAC,iBAAiB,CAAC;IAEzF,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,WAAW,CACV,GAAG,EAAE,IAAI,EACT,KAAK,EAAE,iBAAiB,GAAG;QAC1B,iBAAiB,CAAC,EAAE,IAAI,CAAC;KACzB,EACD,OAAO,EAAE,uBAAuB,GAC9B,IAAI,CAAC;IACR,MAAM,CAAC,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IACrE,WAAW,CAAC,GAAG,EAAE,IAAI,GAAG;QACvB,IAAI,EAAE,UAAU,GAAG,SAAS,CAAC;QAC7B,MAAM,EAAE,YAAY,CAAC,YAAY,CAAC,CAAC;KACnC,CAAC;CACF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAIlC,IAAI,SAAS,MAAM,EACnB,MAAM,SAAS,aAAa,CAAC,qBAAqB,CAAC,OAAO,CAAC,EAE3D,SAAS,EAAE,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,GACrC,aAAa,CAAC,oBAAoB,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAKtE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAClC,IAAI,SAAS,MAAM,EACnB,MAAM,SAAS,aAAa,CAAC,qBAAqB,CAAC,OAAO,CAAC,EAC1D,MAAM,EAAE,aAAa,CAAC,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,CAExF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stateDatastore.js","sourceRoot":"","sources":["../src/stateDatastore.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"stateDatastore.js","sourceRoot":"","sources":["../src/stateDatastore.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA6EH;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAOlC,SAAuC;IAEvC,OAAO,SAGN,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAGjC,MAAwD;IACzD,OAAO,MAAiD,CAAC;AAC1D,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { ClientConnectionId } from \"./baseTypes.js\";\nimport type { InternalTypes } from \"./exposedInternalTypes.js\";\nimport type { AttendeeId, PresenceWithNotifications as Presence } from \"./presence.js\";\nimport type {\n\tValidatableValueDirectoryOrState,\n\tValidatableValueStructure,\n} from \"./validatableTypes.js\";\n\n/**\n * Basic structure of set of {@link Attendee} records within Presence datastore\n *\n * @remarks\n * This is commonly exists per named state in State Managers.\n */\nexport interface ClientRecord<TValue extends ValidatableValueDirectoryOrState<unknown>> {\n\t// Caution: any particular item may or may not exist\n\t// Typescript does not support absent keys without forcing type to also be undefined.\n\t// See https://github.com/microsoft/TypeScript/issues/42810.\n\t[AttendeeId: AttendeeId]: TValue;\n}\n\n// type StateDatastoreSchemaNode<\n// \tTValue extends InternalTypes.ValueDirectoryOrState<any> = InternalTypes.ValueDirectoryOrState<unknown>,\n// > = TValue extends InternalTypes.ValueDirectoryOrState<infer T> ? InternalTypes.ValueDirectoryOrState<T> : never;\n\n// export interface StateDatastoreSchema {\n// \t// This type is not precise. It may\n// \t// need to be replaced with StatesWorkspace schema pattern\n// \t// similar to what is commented out.\n// \t[key: string]: InternalTypes.ValueDirectoryOrState<unknown>;\n// \t// [key: string]: StateDatastoreSchemaNode;\n// }\n\n/**\n * Miscellaneous options for local state updates\n */\nexport interface LocalStateUpdateOptions {\n\t/**\n\t * When defined, this is the maximum time in milliseconds that this\n\t * update is allowed to be delayed before it must be sent to service.\n\t * When `undefined`, the callee may determine maximum delay.\n\t */\n\tallowableUpdateLatencyMs: number | undefined;\n\n\t/**\n\t * Special option allowed for unicast notifications.\n\t */\n\ttargetClientId?: ClientConnectionId;\n}\n\n/**\n * Contract for States Workspace to support State Manager access to\n * datastore and general internal presence knowledge.\n */\nexport interface StateDatastore<\n\tTKey extends string,\n\tTLocalUpdateValue extends InternalTypes.ValueDirectoryOrState<unknown>,\n\tTStoredValue extends\n\t\tValidatableValueDirectoryOrState<unknown> = ValidatableValueStructure<TLocalUpdateValue>,\n> {\n\treadonly presence: Presence;\n\tlocalUpdate(\n\t\tkey: TKey,\n\t\tvalue: TLocalUpdateValue & {\n\t\t\tignoreUnmonitored?: true;\n\t\t},\n\t\toptions: LocalStateUpdateOptions,\n\t): void;\n\tupdate(key: TKey, attendeeId: AttendeeId, value: TStoredValue): void;\n\tknownValues(key: TKey): {\n\t\tself: AttendeeId | undefined;\n\t\tstates: ClientRecord<TStoredValue>;\n\t};\n}\n\n/**\n * Helper to get a handle from a datastore.\n */\nexport function handleFromDatastore<\n\t// Constraining TSchema would be great, but it seems nested types (at least with undefined) cause trouble.\n\t// TSchema as `unknown` still provides some type safety.\n\t// TSchema extends StateDatastoreSchema,\n\tTKey extends string /* & keyof TSchema */,\n\tTValue extends InternalTypes.ValueDirectoryOrState<unknown>,\n>(\n\tdatastore: StateDatastore<TKey, TValue>,\n): InternalTypes.StateDatastoreHandle<TKey, Exclude<TValue, undefined>> {\n\treturn datastore as unknown as InternalTypes.StateDatastoreHandle<\n\t\tTKey,\n\t\tExclude<TValue, undefined>\n\t>;\n}\n\n/**\n * Helper to get the datastore back from its handle.\n */\nexport function datastoreFromHandle<\n\tTKey extends string,\n\tTValue extends InternalTypes.ValueDirectoryOrState<unknown>,\n>(handle: InternalTypes.StateDatastoreHandle<TKey, TValue>): StateDatastore<TKey, TValue> {\n\treturn handle as unknown as StateDatastore<TKey, TValue>;\n}\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
import type { InternalTypes } from "./exposedInternalTypes.js";
|
|
6
|
+
import type { Attendee } from "./presence.js";
|
|
7
|
+
/**
|
|
8
|
+
* A function to be called at the end of an update frame
|
|
9
|
+
*/
|
|
10
|
+
export type PostUpdateAction = () => void;
|
|
11
|
+
/**
|
|
12
|
+
* Contract for State Managers as used by a States Workspace (`PresenceStatesImpl`)
|
|
13
|
+
*
|
|
14
|
+
* @remarks
|
|
15
|
+
* See uses of `unbrandIVM`.
|
|
16
|
+
*/
|
|
17
|
+
export interface ValueManager<TValue, TValueState extends InternalTypes.ValueDirectoryOrState<TValue> = InternalTypes.ValueDirectoryOrState<TValue>> {
|
|
18
|
+
readonly value?: TValueState;
|
|
19
|
+
/**
|
|
20
|
+
* Process an update of `value` for remote attendee.
|
|
21
|
+
* @param attendee - The attendee whose `value` is being updated
|
|
22
|
+
* @param received - The revision number received
|
|
23
|
+
* @param value - The new `value` state
|
|
24
|
+
*/
|
|
25
|
+
update(attendee: Attendee, received: number, value: TValueState): PostUpdateAction[];
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=statesManagerTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"statesManagerTypes.d.ts","sourceRoot":"","sources":["../src/statesManagerTypes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC;AAE1C;;;;;GAKG;AACH,MAAM,WAAW,YAAY,CAC5B,MAAM,EACN,WAAW,SACV,aAAa,CAAC,qBAAqB,CAAC,MAAM,CAAC,GAAG,aAAa,CAAC,qBAAqB,CAAC,MAAM,CAAC;IAG1F,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC;IAE7B;;;;;OAKG;IACH,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,gBAAgB,EAAE,CAAC;CACrF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"statesManagerTypes.js","sourceRoot":"","sources":["../src/statesManagerTypes.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { InternalTypes } from \"./exposedInternalTypes.js\";\nimport type { Attendee } from \"./presence.js\";\n\n/**\n * A function to be called at the end of an update frame\n */\nexport type PostUpdateAction = () => void;\n\n/**\n * Contract for State Managers as used by a States Workspace (`PresenceStatesImpl`)\n *\n * @remarks\n * See uses of `unbrandIVM`.\n */\nexport interface ValueManager<\n\tTValue,\n\tTValueState extends\n\t\tInternalTypes.ValueDirectoryOrState<TValue> = InternalTypes.ValueDirectoryOrState<TValue>,\n> {\n\t// State objects should provide value - implement Required<ValueManager<...>>\n\treadonly value?: TValueState;\n\n\t/**\n\t * Process an update of `value` for remote attendee.\n\t * @param attendee - The attendee whose `value` is being updated\n\t * @param received - The revision number received\n\t * @param value - The new `value` state\n\t */\n\tupdate(attendee: Attendee, received: number, value: TValueState): PostUpdateAction[];\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"systemWorkspace.d.ts","sourceRoot":"","sources":["../src/systemWorkspace.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uCAAuC,CAAC;AACvE,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAGrF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"systemWorkspace.d.ts","sourceRoot":"","sources":["../src/systemWorkspace.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uCAAuC,CAAC;AACvE,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAGrF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE/D,OAAO,KAAK,EAAY,eAAe,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAErF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAGlE,OAAO,KAAK,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEtE;;;;;GAKG;AACH,UAAU,oBAAqB,SAAQ,aAAa,CAAC,kBAAkB;IACtE,KAAK,EAAE,UAAU,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACxC,iBAAiB,EAAE;QAClB,CAAC,YAAY,EAAE,kBAAkB,GAAG,oBAAoB,CAAC;KACzD,CAAC;CACF;AAmCD;;GAEG;AACH,MAAM,WAAW,eAGhB,SAAQ,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,KAAK,CAAC;IAC7C;;;;;OAKG;IACH,iBAAiB,CAAC,kBAAkB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,OAAO,GAAG,IAAI,CAAC;IAE5F;;;;OAIG;IACH,wBAAwB,CAAC,kBAAkB,EAAE,kBAAkB,GAAG,IAAI,CAAC;CACvE;AAsRD;;GAEG;AACH,wBAAgB,qBAAqB,CACpC,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,wBAAwB,EACnC,MAAM,EAAE,UAAU,CAAC,eAAe,CAAC,GAAG,QAAQ,CAAC,eAAe,CAAC,EAC/D,QAAQ,EAAE,SAAS,GACjB;IACF,SAAS,EAAE,eAAe,CAAC;IAC3B,WAAW,EAAE;QACZ,QAAQ,EAAE,sBAAsB,CAAC;QACjC,MAAM,EAAE,YAAY,CAAC,qBAAqB,CAAC,CAAC;KAC5C,CAAC;CACF,CASA"}
|
package/lib/systemWorkspace.js
CHANGED
|
@@ -126,8 +126,7 @@ class SystemWorkspaceImpl {
|
|
|
126
126
|
}
|
|
127
127
|
this.staleConnectionTimer.setTimeout(this.resolveStaleConnections.bind(this), 30_000);
|
|
128
128
|
this.selfAttendee.setConnected();
|
|
129
|
-
|
|
130
|
-
// this.events.emit("attendeeConnected", this.selfAttendee);
|
|
129
|
+
this.events.emit("attendeeConnected", this.selfAttendee);
|
|
131
130
|
}
|
|
132
131
|
}
|
|
133
132
|
resolveStaleConnections() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"systemWorkspace.js","sourceRoot":"","sources":["../src/systemWorkspace.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 type { IAudience } from \"@fluidframework/container-definitions\";\nimport type { IEmitter, Listenable } from \"@fluidframework/core-interfaces/internal\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\n\nimport type { ClientConnectionId } from \"./baseTypes.js\";\nimport type { InternalTypes } from \"./exposedInternalTypes.js\";\nimport type { PostUpdateAction } from \"./internalTypes.js\";\nimport { revealOpaqueJson } from \"./internalUtils.js\";\nimport type { Attendee, AttendeesEvents, AttendeeId, Presence } from \"./presence.js\";\nimport { AttendeeStatus } from \"./presence.js\";\nimport type { PresenceStatesInternal } from \"./presenceStates.js\";\nimport { TimerManager } from \"./timerManager.js\";\nimport type { AnyWorkspace, StatesWorkspaceSchema } from \"./types.js\";\n\n/**\n * `ConnectionValueState` is known value state for `clientToSessionId` data.\n *\n * @remarks\n * It is {@link InternalTypes.ValueRequiredState} with a known value type.\n */\ninterface ConnectionValueState extends InternalTypes.ValueStateMetadata {\n\tvalue: AttendeeId;\n}\n\n/**\n * The system workspace's datastore structure.\n */\nexport interface SystemWorkspaceDatastore {\n\tclientToSessionId: {\n\t\t[ConnectionId: ClientConnectionId]: ConnectionValueState;\n\t};\n}\n\nclass SessionClient implements Attendee {\n\tprivate connectionStatus: AttendeeStatus = AttendeeStatus.Disconnected;\n\n\tpublic constructor(\n\t\tpublic readonly attendeeId: AttendeeId,\n\t\t/**\n\t\t * Order is used to track the most recent client connection\n\t\t * during a session.\n\t\t */\n\t\tpublic order: number = 0,\n\t\tpublic connectionId: ClientConnectionId | undefined = undefined,\n\t) {}\n\n\tpublic getConnectionId(): ClientConnectionId {\n\t\tif (this.connectionId === undefined) {\n\t\t\tthrow new Error(\"Client has never been connected\");\n\t\t}\n\t\treturn this.connectionId;\n\t}\n\n\tpublic getConnectionStatus(): AttendeeStatus {\n\t\treturn this.connectionStatus;\n\t}\n\n\tpublic setConnected(): void {\n\t\tthis.connectionStatus = AttendeeStatus.Connected;\n\t}\n\n\tpublic setDisconnected(): void {\n\t\tthis.connectionStatus = AttendeeStatus.Disconnected;\n\t}\n}\n\n/**\n * Internal workspace that manages metadata for session attendees.\n */\nexport interface SystemWorkspace\n\t// Portion of Presence that is handled by SystemWorkspace along with\n\t// responsibility for emitting \"attendeeConnected\" events.\n\textends Exclude<Presence[\"attendees\"], never> {\n\t/**\n\t * Must be called when the current client acquires a new connection.\n\t *\n\t * @param clientConnectionId - The new client connection ID.\n\t * @param audienceOutOfDate - When true, audience cannot be used as authoritative.\n\t */\n\tonConnectionAdded(clientConnectionId: ClientConnectionId, audienceOutOfDate: boolean): void;\n\n\t/**\n\t * Removes the client connection ID from the system workspace.\n\t *\n\t * @param clientConnectionId - The client connection ID to remove.\n\t */\n\tremoveClientConnectionId(clientConnectionId: ClientConnectionId): void;\n}\n\nclass SystemWorkspaceImpl implements PresenceStatesInternal, SystemWorkspace {\n\tprivate readonly selfAttendee: SessionClient;\n\t/**\n\t * `attendees` is this client's understanding of the attendees in the\n\t * session. The map covers entries for both session ids and connection\n\t * ids, which are never expected to collide, but if they did for same\n\t * client that would be fine.\n\t * An entry is for session ID if the value's `attendeeId` matches the key.\n\t */\n\tprivate readonly attendees = new Map<ClientConnectionId | AttendeeId, SessionClient>();\n\n\t// When local client disconnects, we lose the connectivity status updates for remote attendees in the session.\n\t// Upon reconnect, we mark all other attendees connections as stale and update their status to disconnected after 30 seconds of inactivity.\n\tprivate readonly staleConnectionClients = new Set<SessionClient>();\n\n\tprivate readonly staleConnectionTimer = new TimerManager();\n\n\tpublic constructor(\n\t\tattendeeId: AttendeeId,\n\t\tprivate readonly datastore: SystemWorkspaceDatastore,\n\t\tpublic readonly events: Listenable<AttendeesEvents> & IEmitter<AttendeesEvents>,\n\t\tprivate readonly audience: IAudience,\n\t) {\n\t\tthis.selfAttendee = new SessionClient(attendeeId);\n\t\tthis.attendees.set(attendeeId, this.selfAttendee);\n\t}\n\n\tpublic ensureContent<TSchemaAdditional extends StatesWorkspaceSchema>(\n\t\t_content: TSchemaAdditional,\n\t): never {\n\t\tthrow new Error(\"Method not implemented.\");\n\t}\n\n\tpublic processUpdate(\n\t\t_received: number,\n\t\t_timeModifier: number,\n\t\t/**\n\t\t * Remote datastore typed to match {@link PresenceStatesInternal.processUpdate}'s\n\t\t * `ValueUpdateRecord` type that uses {@link InternalTypes.ValueRequiredState}\n\t\t * and expects an Opaque JSON type. (We get away with a non-`unknown` value type\n\t\t * per TypeScript's method parameter bivariance.) Proper type would be\n\t\t * {@link ConnectionValueState} directly.\n\t\t * {@link ClientConnectionId} use for index is also a deviation, but conveniently\n\t\t * the accurate {@link AttendeeId} type is just a branded string, and\n\t\t * {@link ClientConnectionId} is just `string`.\n\t\t */\n\t\tremoteDatastore: {\n\t\t\tclientToSessionId: {\n\t\t\t\t[ConnectionId: ClientConnectionId]: InternalTypes.ValueRequiredState<\n\t\t\t\t\tConnectionValueState[\"value\"]\n\t\t\t\t>;\n\t\t\t};\n\t\t},\n\t\tsenderConnectionId: ClientConnectionId,\n\t): PostUpdateAction[] {\n\t\tconst audienceMembers = this.audience.getMembers();\n\t\tconst postUpdateActions: PostUpdateAction[] = [];\n\t\tfor (const [clientConnectionId, value] of Object.entries(\n\t\t\trevealOpaqueJson(remoteDatastore.clientToSessionId),\n\t\t)) {\n\t\t\tconst attendeeId = value.value;\n\t\t\tconst { attendee, isJoining } = this.ensureAttendee({\n\t\t\t\tattendeeId,\n\t\t\t\tclientConnectionId,\n\t\t\t\torder: value.rev,\n\t\t\t\tisSender: senderConnectionId === clientConnectionId,\n\t\t\t\tisInAudience: audienceMembers.has(clientConnectionId),\n\t\t\t});\n\t\t\t// If the attendee is joining the session, add them to the list of joining attendees to be announced later.\n\t\t\tif (isJoining) {\n\t\t\t\tpostUpdateActions.push(() => this.events.emit(\"attendeeConnected\", attendee));\n\t\t\t}\n\n\t\t\tconst knownSessionId = this.datastore.clientToSessionId[clientConnectionId];\n\t\t\tif (knownSessionId === undefined) {\n\t\t\t\tthis.datastore.clientToSessionId[clientConnectionId] = value;\n\t\t\t} else {\n\t\t\t\tassert(knownSessionId.value === value.value, 0xa5a /* Mismatched SessionId */);\n\t\t\t}\n\t\t}\n\n\t\treturn postUpdateActions;\n\t}\n\n\tpublic onConnectionAdded(\n\t\tclientConnectionId: ClientConnectionId,\n\t\taudienceOutOfDate: boolean,\n\t): void {\n\t\tassert(\n\t\t\tthis.selfAttendee.getConnectionStatus() === AttendeeStatus.Disconnected,\n\t\t\t0xaad /* Local client should be 'Disconnected' before adding new connection. */,\n\t\t);\n\n\t\tconst selfInAudience = this.audience.getMember(clientConnectionId) !== undefined;\n\t\tassert(\n\t\t\tselfInAudience || audienceOutOfDate,\n\t\t\t0xcc0 /* Local client must be in audience for presence to handle added connection. */,\n\t\t);\n\n\t\tif (!(clientConnectionId in this.datastore.clientToSessionId)) {\n\t\t\tthis.datastore.clientToSessionId[clientConnectionId] = {\n\t\t\t\trev: this.selfAttendee.order++,\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t\tvalue: this.selfAttendee.attendeeId,\n\t\t\t};\n\t\t}\n\n\t\t// Update the self attendee connection information, but not connection\n\t\t// status yet. Connection status is updated once self is in audience -\n\t\t// see later. It is only once our connection is known to audience that\n\t\t// audience can be used to track other attendees' connection statuses\n\t\t// and we seek to present a consistent view locally.\n\t\tthis.selfAttendee.connectionId = clientConnectionId;\n\t\tthis.attendees.set(clientConnectionId, this.selfAttendee);\n\n\t\tif (selfInAudience) {\n\t\t\t// Mark 'Connected' remote attendees connections as stale\n\t\t\t// Performance note: This will visit attendees multiple times as the\n\t\t\t// attendee map has attendeeIds and connectionIds entries that point to\n\t\t\t// the same attendee. But the getConnectionStatus check is cheap and\n\t\t\t// staleConnectionClients.add will handle duplicates.\n\t\t\tthis.staleConnectionClients.clear();\n\t\t\tfor (const staleConnectionClient of this.attendees.values()) {\n\t\t\t\tif (staleConnectionClient.getConnectionStatus() === AttendeeStatus.Connected) {\n\t\t\t\t\tthis.staleConnectionClients.add(staleConnectionClient);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.staleConnectionTimer.setTimeout(this.resolveStaleConnections.bind(this), 30_000);\n\n\t\t\tthis.selfAttendee.setConnected();\n\t\t\t// TODO: AB#56686: self-Attendee never announced as Connected - Emit this event once there are tests in place\n\t\t\t// this.events.emit(\"attendeeConnected\", this.selfAttendee);\n\t\t}\n\t}\n\n\tprivate resolveStaleConnections(): void {\n\t\tconst consideredDisconnected = [];\n\t\tfor (const client of this.staleConnectionClients) {\n\t\t\t// Confirm that audience no longer has connection. It is possible\n\t\t\t// but unlikely that no one mentioned the attendee in this period\n\t\t\t// and that they were never disconnected.\n\t\t\tif (this.audience.getMember(client.getConnectionId()) === undefined) {\n\t\t\t\tconsideredDisconnected.push(client);\n\t\t\t\tclient.setDisconnected();\n\t\t\t}\n\t\t}\n\t\tfor (const client of consideredDisconnected) {\n\t\t\tthis.events.emit(\"attendeeDisconnected\", client);\n\t\t}\n\t\tthis.staleConnectionClients.clear();\n\t}\n\n\tpublic removeClientConnectionId(clientConnectionId: ClientConnectionId): void {\n\t\tconst attendee = this.attendees.get(clientConnectionId);\n\t\tif (!attendee) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If the local connection is being removed, clear the stale connection timer\n\t\tif (attendee === this.selfAttendee) {\n\t\t\tthis.staleConnectionTimer.clearTimeout();\n\t\t} else {\n\t\t\t// When self is not connected, audience may go through a refresh that\n\t\t\t// removes members and adds them back. Defer any removals until self\n\t\t\t// is connected implying audience is stable.\n\t\t\tif (this.selfAttendee.getConnectionStatus() !== AttendeeStatus.Connected) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// If the last known connectionID is different from the connection ID being removed, the attendee has reconnected,\n\t\t// therefore we should not change the attendee connection status or emit a disconnect event.\n\t\tconst attendeeReconnected = attendee.getConnectionId() !== clientConnectionId;\n\t\tconst connected = attendee.getConnectionStatus() === AttendeeStatus.Connected;\n\t\tif (!attendeeReconnected && connected) {\n\t\t\tattendee.setDisconnected();\n\t\t\tthis.events.emit(\"attendeeDisconnected\", attendee);\n\t\t\tthis.staleConnectionClients.delete(attendee);\n\t\t}\n\t}\n\n\tpublic getAttendees(): ReadonlySet<Attendee> {\n\t\treturn new Set(this.attendees.values());\n\t}\n\n\tpublic getAttendee(clientId: ClientConnectionId | AttendeeId): Attendee {\n\t\tconst attendee = this.attendees.get(clientId);\n\t\tif (attendee) {\n\t\t\treturn attendee;\n\t\t}\n\n\t\t// TODO: Restore option to add attendee on demand to handle internal\n\t\t// lookup cases that must come from internal data.\n\t\t// There aren't any resiliency mechanisms in place to handle a missed\n\t\t// ClientJoin right now.\n\t\tthrow new Error(\"Attendee not found\");\n\t}\n\n\tpublic getMyself(): Attendee {\n\t\treturn this.selfAttendee;\n\t}\n\n\t/**\n\t * Make sure the given client session and connection ID pair are represented\n\t * in the attendee map. If not present, SessionClient is created and added\n\t * to map. If present, make sure the current connection ID is updated.\n\t */\n\tprivate ensureAttendee({\n\t\tattendeeId,\n\t\tclientConnectionId,\n\t\torder,\n\t\tisSender,\n\t\tisInAudience,\n\t}: {\n\t\tattendeeId: AttendeeId;\n\t\tclientConnectionId: ClientConnectionId;\n\t\torder: number;\n\t\tisSender: boolean;\n\t\tisInAudience: boolean;\n\t}): { attendee: SessionClient; isJoining: boolean } {\n\t\tlet attendee = this.attendees.get(attendeeId);\n\t\tlet isConnected = false;\n\t\tlet isJoining = false;\n\n\t\tif (attendee === undefined) {\n\t\t\t// New attendee. Create SessionClient and add session ID based\n\t\t\t// entry to map.\n\t\t\tattendee = new SessionClient(attendeeId, order, clientConnectionId);\n\t\t\tthis.attendees.set(attendeeId, attendee);\n\t\t\t// If the attendee update is from the sending remote client itself\n\t\t\t// OR if the attendee is present in audience,\n\t\t\t// then the attendee is considered connected. (Otherwise, leave\n\t\t\t// state as disconnected - default.)\n\t\t\tif (isSender || isInAudience) {\n\t\t\t\tisConnected = true;\n\t\t\t\tattendee.setConnected();\n\t\t\t\tisJoining = true;\n\t\t\t}\n\t\t} else {\n\t\t\t// Known attendee is considered connected if\n\t\t\tisConnected =\n\t\t\t\t// this information is at least up to date with current knowledge\n\t\t\t\torder >= attendee.order &&\n\t\t\t\t// AND in the audience OR\n\t\t\t\t(isInAudience ||\n\t\t\t\t\t// not in audience, but client is the sender and has newer\n\t\t\t\t\t// info. (Assume that audience is out of date and attendee\n\t\t\t\t\t// is joining.)\n\t\t\t\t\t(isSender && order > attendee.order));\n\n\t\t\tif (order > attendee.order) {\n\t\t\t\t// The given association is newer than the one we have.\n\t\t\t\t// Update the order and current connection ID.\n\t\t\t\tattendee.order = order;\n\t\t\t\tattendee.connectionId = clientConnectionId;\n\t\t\t}\n\n\t\t\t// Known attendee is joining the session if they are currently disconnected.\n\t\t\tif (isConnected && attendee.getConnectionStatus() === AttendeeStatus.Disconnected) {\n\t\t\t\tattendee.setConnected();\n\t\t\t\tisJoining = true;\n\t\t\t}\n\t\t}\n\n\t\tif (isConnected) {\n\t\t\t// If the attendee is connected, remove them from the stale connection set\n\t\t\tthis.staleConnectionClients.delete(attendee);\n\t\t}\n\n\t\t// Always update entry for the connection ID. (Okay if already set.)\n\t\tthis.attendees.set(clientConnectionId, attendee);\n\n\t\treturn { attendee, isJoining };\n\t}\n}\n\n/**\n * Instantiates the system workspace.\n */\nexport function createSystemWorkspace(\n\tattendeeId: AttendeeId,\n\tdatastore: SystemWorkspaceDatastore,\n\tevents: Listenable<AttendeesEvents> & IEmitter<AttendeesEvents>,\n\taudience: IAudience,\n): {\n\tworkspace: SystemWorkspace;\n\tstatesEntry: {\n\t\tinternal: PresenceStatesInternal;\n\t\tpublic: AnyWorkspace<StatesWorkspaceSchema>;\n\t};\n} {\n\tconst workspace = new SystemWorkspaceImpl(attendeeId, datastore, events, audience);\n\treturn {\n\t\tworkspace,\n\t\tstatesEntry: {\n\t\t\tinternal: workspace,\n\t\t\tpublic: undefined as unknown as AnyWorkspace<StatesWorkspaceSchema>,\n\t\t},\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"systemWorkspace.js","sourceRoot":"","sources":["../src/systemWorkspace.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 type { IAudience } from \"@fluidframework/container-definitions\";\nimport type { IEmitter, Listenable } from \"@fluidframework/core-interfaces/internal\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\n\nimport type { ClientConnectionId } from \"./baseTypes.js\";\nimport type { InternalTypes } from \"./exposedInternalTypes.js\";\nimport { revealOpaqueJson } from \"./internalUtils.js\";\nimport type { Attendee, AttendeesEvents, AttendeeId, Presence } from \"./presence.js\";\nimport { AttendeeStatus } from \"./presence.js\";\nimport type { PresenceStatesInternal } from \"./presenceStates.js\";\nimport type { PostUpdateAction } from \"./statesManagerTypes.js\";\nimport { TimerManager } from \"./timerManager.js\";\nimport type { AnyWorkspace, StatesWorkspaceSchema } from \"./types.js\";\n\n/**\n * `ConnectionValueState` is known value state for `clientToSessionId` data.\n *\n * @remarks\n * It is {@link InternalTypes.ValueRequiredState} with a known value type.\n */\ninterface ConnectionValueState extends InternalTypes.ValueStateMetadata {\n\tvalue: AttendeeId;\n}\n\n/**\n * The system workspace's datastore structure.\n */\nexport interface SystemWorkspaceDatastore {\n\tclientToSessionId: {\n\t\t[ConnectionId: ClientConnectionId]: ConnectionValueState;\n\t};\n}\n\nclass SessionClient implements Attendee {\n\tprivate connectionStatus: AttendeeStatus = AttendeeStatus.Disconnected;\n\n\tpublic constructor(\n\t\tpublic readonly attendeeId: AttendeeId,\n\t\t/**\n\t\t * Order is used to track the most recent client connection\n\t\t * during a session.\n\t\t */\n\t\tpublic order: number = 0,\n\t\tpublic connectionId: ClientConnectionId | undefined = undefined,\n\t) {}\n\n\tpublic getConnectionId(): ClientConnectionId {\n\t\tif (this.connectionId === undefined) {\n\t\t\tthrow new Error(\"Client has never been connected\");\n\t\t}\n\t\treturn this.connectionId;\n\t}\n\n\tpublic getConnectionStatus(): AttendeeStatus {\n\t\treturn this.connectionStatus;\n\t}\n\n\tpublic setConnected(): void {\n\t\tthis.connectionStatus = AttendeeStatus.Connected;\n\t}\n\n\tpublic setDisconnected(): void {\n\t\tthis.connectionStatus = AttendeeStatus.Disconnected;\n\t}\n}\n\n/**\n * Internal workspace that manages metadata for session attendees.\n */\nexport interface SystemWorkspace\n\t// Portion of Presence that is handled by SystemWorkspace along with\n\t// responsibility for emitting \"attendeeConnected\" events.\n\textends Exclude<Presence[\"attendees\"], never> {\n\t/**\n\t * Must be called when the current client acquires a new connection.\n\t *\n\t * @param clientConnectionId - The new client connection ID.\n\t * @param audienceOutOfDate - When true, audience cannot be used as authoritative.\n\t */\n\tonConnectionAdded(clientConnectionId: ClientConnectionId, audienceOutOfDate: boolean): void;\n\n\t/**\n\t * Removes the client connection ID from the system workspace.\n\t *\n\t * @param clientConnectionId - The client connection ID to remove.\n\t */\n\tremoveClientConnectionId(clientConnectionId: ClientConnectionId): void;\n}\n\nclass SystemWorkspaceImpl implements PresenceStatesInternal, SystemWorkspace {\n\tprivate readonly selfAttendee: SessionClient;\n\t/**\n\t * `attendees` is this client's understanding of the attendees in the\n\t * session. The map covers entries for both session ids and connection\n\t * ids, which are never expected to collide, but if they did for same\n\t * client that would be fine.\n\t * An entry is for session ID if the value's `attendeeId` matches the key.\n\t */\n\tprivate readonly attendees = new Map<ClientConnectionId | AttendeeId, SessionClient>();\n\n\t// When local client disconnects, we lose the connectivity status updates for remote attendees in the session.\n\t// Upon reconnect, we mark all other attendees connections as stale and update their status to disconnected after 30 seconds of inactivity.\n\tprivate readonly staleConnectionClients = new Set<SessionClient>();\n\n\tprivate readonly staleConnectionTimer = new TimerManager();\n\n\tpublic constructor(\n\t\tattendeeId: AttendeeId,\n\t\tprivate readonly datastore: SystemWorkspaceDatastore,\n\t\tpublic readonly events: Listenable<AttendeesEvents> & IEmitter<AttendeesEvents>,\n\t\tprivate readonly audience: IAudience,\n\t) {\n\t\tthis.selfAttendee = new SessionClient(attendeeId);\n\t\tthis.attendees.set(attendeeId, this.selfAttendee);\n\t}\n\n\tpublic ensureContent<TSchemaAdditional extends StatesWorkspaceSchema>(\n\t\t_content: TSchemaAdditional,\n\t): never {\n\t\tthrow new Error(\"Method not implemented.\");\n\t}\n\n\tpublic processUpdate(\n\t\t_received: number,\n\t\t_timeModifier: number,\n\t\t/**\n\t\t * Remote datastore typed to match {@link PresenceStatesInternal.processUpdate}'s\n\t\t * `ValueUpdateRecord` type that uses {@link InternalTypes.ValueRequiredState}\n\t\t * and expects an Opaque JSON type. (We get away with a non-`unknown` value type\n\t\t * per TypeScript's method parameter bivariance.) Proper type would be\n\t\t * {@link ConnectionValueState} directly.\n\t\t * {@link ClientConnectionId} use for index is also a deviation, but conveniently\n\t\t * the accurate {@link AttendeeId} type is just a branded string, and\n\t\t * {@link ClientConnectionId} is just `string`.\n\t\t */\n\t\tremoteDatastore: {\n\t\t\tclientToSessionId: {\n\t\t\t\t[ConnectionId: ClientConnectionId]: InternalTypes.ValueRequiredState<\n\t\t\t\t\tConnectionValueState[\"value\"]\n\t\t\t\t>;\n\t\t\t};\n\t\t},\n\t\tsenderConnectionId: ClientConnectionId,\n\t): PostUpdateAction[] {\n\t\tconst audienceMembers = this.audience.getMembers();\n\t\tconst postUpdateActions: PostUpdateAction[] = [];\n\t\tfor (const [clientConnectionId, value] of Object.entries(\n\t\t\trevealOpaqueJson(remoteDatastore.clientToSessionId),\n\t\t)) {\n\t\t\tconst attendeeId = value.value;\n\t\t\tconst { attendee, isJoining } = this.ensureAttendee({\n\t\t\t\tattendeeId,\n\t\t\t\tclientConnectionId,\n\t\t\t\torder: value.rev,\n\t\t\t\tisSender: senderConnectionId === clientConnectionId,\n\t\t\t\tisInAudience: audienceMembers.has(clientConnectionId),\n\t\t\t});\n\t\t\t// If the attendee is joining the session, add them to the list of joining attendees to be announced later.\n\t\t\tif (isJoining) {\n\t\t\t\tpostUpdateActions.push(() => this.events.emit(\"attendeeConnected\", attendee));\n\t\t\t}\n\n\t\t\tconst knownSessionId = this.datastore.clientToSessionId[clientConnectionId];\n\t\t\tif (knownSessionId === undefined) {\n\t\t\t\tthis.datastore.clientToSessionId[clientConnectionId] = value;\n\t\t\t} else {\n\t\t\t\tassert(knownSessionId.value === value.value, 0xa5a /* Mismatched SessionId */);\n\t\t\t}\n\t\t}\n\n\t\treturn postUpdateActions;\n\t}\n\n\tpublic onConnectionAdded(\n\t\tclientConnectionId: ClientConnectionId,\n\t\taudienceOutOfDate: boolean,\n\t): void {\n\t\tassert(\n\t\t\tthis.selfAttendee.getConnectionStatus() === AttendeeStatus.Disconnected,\n\t\t\t0xaad /* Local client should be 'Disconnected' before adding new connection. */,\n\t\t);\n\n\t\tconst selfInAudience = this.audience.getMember(clientConnectionId) !== undefined;\n\t\tassert(\n\t\t\tselfInAudience || audienceOutOfDate,\n\t\t\t0xcc0 /* Local client must be in audience for presence to handle added connection. */,\n\t\t);\n\n\t\tif (!(clientConnectionId in this.datastore.clientToSessionId)) {\n\t\t\tthis.datastore.clientToSessionId[clientConnectionId] = {\n\t\t\t\trev: this.selfAttendee.order++,\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t\tvalue: this.selfAttendee.attendeeId,\n\t\t\t};\n\t\t}\n\n\t\t// Update the self attendee connection information, but not connection\n\t\t// status yet. Connection status is updated once self is in audience -\n\t\t// see later. It is only once our connection is known to audience that\n\t\t// audience can be used to track other attendees' connection statuses\n\t\t// and we seek to present a consistent view locally.\n\t\tthis.selfAttendee.connectionId = clientConnectionId;\n\t\tthis.attendees.set(clientConnectionId, this.selfAttendee);\n\n\t\tif (selfInAudience) {\n\t\t\t// Mark 'Connected' remote attendees connections as stale\n\t\t\t// Performance note: This will visit attendees multiple times as the\n\t\t\t// attendee map has attendeeIds and connectionIds entries that point to\n\t\t\t// the same attendee. But the getConnectionStatus check is cheap and\n\t\t\t// staleConnectionClients.add will handle duplicates.\n\t\t\tthis.staleConnectionClients.clear();\n\t\t\tfor (const staleConnectionClient of this.attendees.values()) {\n\t\t\t\tif (staleConnectionClient.getConnectionStatus() === AttendeeStatus.Connected) {\n\t\t\t\t\tthis.staleConnectionClients.add(staleConnectionClient);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.staleConnectionTimer.setTimeout(this.resolveStaleConnections.bind(this), 30_000);\n\n\t\t\tthis.selfAttendee.setConnected();\n\t\t\tthis.events.emit(\"attendeeConnected\", this.selfAttendee);\n\t\t}\n\t}\n\n\tprivate resolveStaleConnections(): void {\n\t\tconst consideredDisconnected = [];\n\t\tfor (const client of this.staleConnectionClients) {\n\t\t\t// Confirm that audience no longer has connection. It is possible\n\t\t\t// but unlikely that no one mentioned the attendee in this period\n\t\t\t// and that they were never disconnected.\n\t\t\tif (this.audience.getMember(client.getConnectionId()) === undefined) {\n\t\t\t\tconsideredDisconnected.push(client);\n\t\t\t\tclient.setDisconnected();\n\t\t\t}\n\t\t}\n\t\tfor (const client of consideredDisconnected) {\n\t\t\tthis.events.emit(\"attendeeDisconnected\", client);\n\t\t}\n\t\tthis.staleConnectionClients.clear();\n\t}\n\n\tpublic removeClientConnectionId(clientConnectionId: ClientConnectionId): void {\n\t\tconst attendee = this.attendees.get(clientConnectionId);\n\t\tif (!attendee) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If the local connection is being removed, clear the stale connection timer\n\t\tif (attendee === this.selfAttendee) {\n\t\t\tthis.staleConnectionTimer.clearTimeout();\n\t\t} else {\n\t\t\t// When self is not connected, audience may go through a refresh that\n\t\t\t// removes members and adds them back. Defer any removals until self\n\t\t\t// is connected implying audience is stable.\n\t\t\tif (this.selfAttendee.getConnectionStatus() !== AttendeeStatus.Connected) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// If the last known connectionID is different from the connection ID being removed, the attendee has reconnected,\n\t\t// therefore we should not change the attendee connection status or emit a disconnect event.\n\t\tconst attendeeReconnected = attendee.getConnectionId() !== clientConnectionId;\n\t\tconst connected = attendee.getConnectionStatus() === AttendeeStatus.Connected;\n\t\tif (!attendeeReconnected && connected) {\n\t\t\tattendee.setDisconnected();\n\t\t\tthis.events.emit(\"attendeeDisconnected\", attendee);\n\t\t\tthis.staleConnectionClients.delete(attendee);\n\t\t}\n\t}\n\n\tpublic getAttendees(): ReadonlySet<Attendee> {\n\t\treturn new Set(this.attendees.values());\n\t}\n\n\tpublic getAttendee(clientId: ClientConnectionId | AttendeeId): Attendee {\n\t\tconst attendee = this.attendees.get(clientId);\n\t\tif (attendee) {\n\t\t\treturn attendee;\n\t\t}\n\n\t\t// TODO: Restore option to add attendee on demand to handle internal\n\t\t// lookup cases that must come from internal data.\n\t\t// There aren't any resiliency mechanisms in place to handle a missed\n\t\t// ClientJoin right now.\n\t\tthrow new Error(\"Attendee not found\");\n\t}\n\n\tpublic getMyself(): Attendee {\n\t\treturn this.selfAttendee;\n\t}\n\n\t/**\n\t * Make sure the given client session and connection ID pair are represented\n\t * in the attendee map. If not present, SessionClient is created and added\n\t * to map. If present, make sure the current connection ID is updated.\n\t */\n\tprivate ensureAttendee({\n\t\tattendeeId,\n\t\tclientConnectionId,\n\t\torder,\n\t\tisSender,\n\t\tisInAudience,\n\t}: {\n\t\tattendeeId: AttendeeId;\n\t\tclientConnectionId: ClientConnectionId;\n\t\torder: number;\n\t\tisSender: boolean;\n\t\tisInAudience: boolean;\n\t}): { attendee: SessionClient; isJoining: boolean } {\n\t\tlet attendee = this.attendees.get(attendeeId);\n\t\tlet isConnected = false;\n\t\tlet isJoining = false;\n\n\t\tif (attendee === undefined) {\n\t\t\t// New attendee. Create SessionClient and add session ID based\n\t\t\t// entry to map.\n\t\t\tattendee = new SessionClient(attendeeId, order, clientConnectionId);\n\t\t\tthis.attendees.set(attendeeId, attendee);\n\t\t\t// If the attendee update is from the sending remote client itself\n\t\t\t// OR if the attendee is present in audience,\n\t\t\t// then the attendee is considered connected. (Otherwise, leave\n\t\t\t// state as disconnected - default.)\n\t\t\tif (isSender || isInAudience) {\n\t\t\t\tisConnected = true;\n\t\t\t\tattendee.setConnected();\n\t\t\t\tisJoining = true;\n\t\t\t}\n\t\t} else {\n\t\t\t// Known attendee is considered connected if\n\t\t\tisConnected =\n\t\t\t\t// this information is at least up to date with current knowledge\n\t\t\t\torder >= attendee.order &&\n\t\t\t\t// AND in the audience OR\n\t\t\t\t(isInAudience ||\n\t\t\t\t\t// not in audience, but client is the sender and has newer\n\t\t\t\t\t// info. (Assume that audience is out of date and attendee\n\t\t\t\t\t// is joining.)\n\t\t\t\t\t(isSender && order > attendee.order));\n\n\t\t\tif (order > attendee.order) {\n\t\t\t\t// The given association is newer than the one we have.\n\t\t\t\t// Update the order and current connection ID.\n\t\t\t\tattendee.order = order;\n\t\t\t\tattendee.connectionId = clientConnectionId;\n\t\t\t}\n\n\t\t\t// Known attendee is joining the session if they are currently disconnected.\n\t\t\tif (isConnected && attendee.getConnectionStatus() === AttendeeStatus.Disconnected) {\n\t\t\t\tattendee.setConnected();\n\t\t\t\tisJoining = true;\n\t\t\t}\n\t\t}\n\n\t\tif (isConnected) {\n\t\t\t// If the attendee is connected, remove them from the stale connection set\n\t\t\tthis.staleConnectionClients.delete(attendee);\n\t\t}\n\n\t\t// Always update entry for the connection ID. (Okay if already set.)\n\t\tthis.attendees.set(clientConnectionId, attendee);\n\n\t\treturn { attendee, isJoining };\n\t}\n}\n\n/**\n * Instantiates the system workspace.\n */\nexport function createSystemWorkspace(\n\tattendeeId: AttendeeId,\n\tdatastore: SystemWorkspaceDatastore,\n\tevents: Listenable<AttendeesEvents> & IEmitter<AttendeesEvents>,\n\taudience: IAudience,\n): {\n\tworkspace: SystemWorkspace;\n\tstatesEntry: {\n\t\tinternal: PresenceStatesInternal;\n\t\tpublic: AnyWorkspace<StatesWorkspaceSchema>;\n\t};\n} {\n\tconst workspace = new SystemWorkspaceImpl(attendeeId, datastore, events, audience);\n\treturn {\n\t\tworkspace,\n\t\tstatesEntry: {\n\t\t\tinternal: workspace,\n\t\t\tpublic: undefined as unknown as AnyWorkspace<StatesWorkspaceSchema>,\n\t\t},\n\t};\n}\n"]}
|
package/lib/types.d.ts
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
import type { BroadcastControls } from "./
|
|
5
|
+
import type { BroadcastControls } from "./broadcastControlsTypes.js";
|
|
6
6
|
import type { InternalTypes } from "./exposedInternalTypes.js";
|
|
7
|
-
import type {
|
|
7
|
+
import type { InternalUtilityTypes } from "./exposedUtilityTypes.js";
|
|
8
|
+
import type { NotificationsManager } from "./notificationsManagerTypes.js";
|
|
8
9
|
import type { Presence, PresenceWithNotifications } from "./presence.js";
|
|
9
10
|
/**
|
|
10
11
|
* Unique address within a session.
|
|
@@ -40,7 +41,7 @@ export interface StatesWorkspaceSchema {
|
|
|
40
41
|
/**
|
|
41
42
|
* Key-value pairs of State objects registered with the {@link StatesWorkspace}.
|
|
42
43
|
*/
|
|
43
|
-
[key: string]: StatesWorkspaceEntry<typeof key, InternalTypes.ValueDirectoryOrState<
|
|
44
|
+
[key: string]: StatesWorkspaceEntry<typeof key, InternalTypes.ValueDirectoryOrState<unknown>>;
|
|
44
45
|
}
|
|
45
46
|
/**
|
|
46
47
|
* Map of State objects registered with {@link StatesWorkspace}.
|
|
@@ -70,7 +71,7 @@ export interface StatesWorkspace<TSchema extends StatesWorkspaceSchema, TManager
|
|
|
70
71
|
* @param key - new unique key for the State object within the workspace
|
|
71
72
|
* @param manager - factory for creating a State object
|
|
72
73
|
*/
|
|
73
|
-
add<TKey extends string, TValue extends InternalTypes.ValueDirectoryOrState<
|
|
74
|
+
add<TKey extends string, TValue extends InternalTypes.ValueDirectoryOrState<unknown>, TManager extends TManagerConstraints>(key: TKey, manager: InternalTypes.ManagerFactory<TKey, TValue, TManager>): asserts this is StatesWorkspace<TSchema & Record<TKey, InternalTypes.ManagerFactory<TKey, TValue, TManager>>, TManagerConstraints>;
|
|
74
75
|
/**
|
|
75
76
|
* Registry of State objects.
|
|
76
77
|
*/
|
|
@@ -92,7 +93,7 @@ export interface StatesWorkspace<TSchema extends StatesWorkspaceSchema, TManager
|
|
|
92
93
|
* @alpha
|
|
93
94
|
*/
|
|
94
95
|
export interface NotificationsWorkspaceSchema {
|
|
95
|
-
[key: string]: InternalTypes.ManagerFactory<typeof key, InternalTypes.ValueRequiredState<InternalTypes.NotificationType>, NotificationsManager<
|
|
96
|
+
[key: string]: InternalTypes.ManagerFactory<typeof key, InternalTypes.ValueRequiredState<InternalTypes.NotificationType>, NotificationsManager<InternalUtilityTypes.NotificationListeners<unknown>>>;
|
|
96
97
|
}
|
|
97
98
|
/**
|
|
98
99
|
* `NotificationsWorkspace` maintains a registry of {@link NotificationsManager}s
|
|
@@ -113,7 +114,7 @@ export interface NotificationsWorkspace<TSchema extends NotificationsWorkspaceSc
|
|
|
113
114
|
* @param key - new unique key for the `NotificationsManager` within the workspace
|
|
114
115
|
* @param manager - factory for creating a `NotificationsManager`
|
|
115
116
|
*/
|
|
116
|
-
add<TKey extends string, TValue extends InternalTypes.ValueDirectoryOrState<
|
|
117
|
+
add<TKey extends string, TValue extends InternalTypes.ValueDirectoryOrState<unknown>, TManager extends NotificationsManager<InternalUtilityTypes.NotificationListeners<unknown>>>(key: TKey, manager: InternalTypes.ManagerFactory<TKey, TValue, TManager>): asserts this is NotificationsWorkspace<TSchema & Record<TKey, InternalTypes.ManagerFactory<TKey, TValue, TManager>>>;
|
|
117
118
|
/**
|
|
118
119
|
* Registry of `NotificationsManager`s.
|
|
119
120
|
*/
|
package/lib/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/lib/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { BroadcastControls } from \"./
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { BroadcastControls } from \"./broadcastControlsTypes.js\";\nimport type { InternalTypes } from \"./exposedInternalTypes.js\";\nimport type { InternalUtilityTypes } from \"./exposedUtilityTypes.js\";\nimport type { NotificationsManager } from \"./notificationsManagerTypes.js\";\nimport type { Presence, PresenceWithNotifications } from \"./presence.js\";\n\n/**\n * Unique address within a session.\n *\n * @remarks\n * A string known to all clients working with a certain Workspace and unique\n * among Workspaces. Recommend using specifying concatenation of: type of\n * unique identifier, `:` (required), and unique identifier.\n *\n * @example Examples\n * ```typescript\n * \"guid:g0fl001d-1415-5000-c00l-g0fa54g0b1g1\"\n * \"address:object0/sub-object2:pointers\"\n * ```\n *\n * @beta\n */\nexport type WorkspaceAddress = `${string}:${string}`;\n\n/**\n * Single entry in {@link StatesWorkspaceSchema} or {@link NotificationsWorkspaceSchema}.\n *\n * @beta\n */\nexport type StatesWorkspaceEntry<\n\tTKey extends string,\n\tTValue extends InternalTypes.ValueDirectoryOrState<unknown>,\n\tTManager = unknown,\n> = InternalTypes.ManagerFactory<TKey, TValue, TManager>;\n\n// #region StatesWorkspace\n\n/**\n * Schema for a {@link StatesWorkspace} workspace.\n *\n * Keys of schema are the keys of the {@link StatesWorkspace} providing access to State objects.\n *\n * @beta\n */\nexport interface StatesWorkspaceSchema {\n\t/**\n\t * Key-value pairs of State objects registered with the {@link StatesWorkspace}.\n\t */\n\t[key: string]: StatesWorkspaceEntry<\n\t\ttypeof key,\n\t\tInternalTypes.ValueDirectoryOrState<unknown>\n\t>;\n}\n\n/**\n * Map of State objects registered with {@link StatesWorkspace}.\n *\n * @sealed\n * @beta\n */\nexport type StatesWorkspaceEntries<TSchema extends StatesWorkspaceSchema> = {\n\t/**\n\t * Registered State objects.\n\t */\n\treadonly [Key in keyof TSchema]: ReturnType<\n\t\tTSchema[Key]\n\t>[\"manager\"] extends InternalTypes.StateValue<infer TManager>\n\t\t? TManager\n\t\t: never;\n};\n\n/**\n * `StatesWorkspace` maintains a registry of State objects that all share and provide access to\n * presence state values across client members in a session.\n *\n * State objects offer variations on how to manage states, but all share same principle that\n * each client's state is independent and may only be updated by originating client.\n *\n * @sealed\n * @beta\n */\nexport interface StatesWorkspace<\n\tTSchema extends StatesWorkspaceSchema,\n\tTManagerConstraints = unknown,\n> {\n\t/**\n\t * Registers a new State object with the {@link StatesWorkspace}.\n\t * @param key - new unique key for the State object within the workspace\n\t * @param manager - factory for creating a State object\n\t */\n\tadd<\n\t\tTKey extends string,\n\t\tTValue extends InternalTypes.ValueDirectoryOrState<unknown>,\n\t\tTManager extends TManagerConstraints,\n\t>(\n\t\tkey: TKey,\n\t\tmanager: InternalTypes.ManagerFactory<TKey, TValue, TManager>,\n\t): asserts this is StatesWorkspace<\n\t\tTSchema & Record<TKey, InternalTypes.ManagerFactory<TKey, TValue, TManager>>,\n\t\tTManagerConstraints\n\t>;\n\n\t/**\n\t * Registry of State objects.\n\t */\n\treadonly states: StatesWorkspaceEntries<TSchema>;\n\n\t/**\n\t * Default controls for management of broadcast updates.\n\t */\n\treadonly controls: BroadcastControls;\n\n\t/**\n\t * Containing {@link Presence}\n\t */\n\treadonly presence: Presence;\n}\n\n// #endregion StatesWorkspace\n\n// #region NotificationsWorkspace\n\n/**\n * Schema for a {@link NotificationsWorkspace} workspace.\n *\n * Keys of schema are the keys of the {@link NotificationsWorkspace} providing access to {@link NotificationsManager}s.\n *\n * @alpha\n */\nexport interface NotificationsWorkspaceSchema {\n\t[key: string]: InternalTypes.ManagerFactory<\n\t\ttypeof key,\n\t\tInternalTypes.ValueRequiredState<InternalTypes.NotificationType>,\n\t\tNotificationsManager<InternalUtilityTypes.NotificationListeners<unknown>>\n\t>;\n}\n\n/**\n * `NotificationsWorkspace` maintains a registry of {@link NotificationsManager}s\n * that facilitate messages across client members in a session.\n *\n * @privateRemarks\n * This should be kept mostly in sync with {@link StatesWorkspace}. Notably the\n * return type of `add` is limited here and the `controls` property is omitted.\n * The `PresenceStatesImpl` class implements `AnyWorkspace` and therefore\n * `NotificationsWorkspace`, so long as this is proper subset.\n *\n * @sealed\n * @alpha\n */\nexport interface NotificationsWorkspace<TSchema extends NotificationsWorkspaceSchema> {\n\t/**\n\t * Registers a new `NotificationsManager` with the {@link NotificationsWorkspace}.\n\t * @param key - new unique key for the `NotificationsManager` within the workspace\n\t * @param manager - factory for creating a `NotificationsManager`\n\t */\n\tadd<\n\t\tTKey extends string,\n\t\tTValue extends InternalTypes.ValueDirectoryOrState<unknown>,\n\t\tTManager extends NotificationsManager<InternalUtilityTypes.NotificationListeners<unknown>>,\n\t>(\n\t\tkey: TKey,\n\t\tmanager: InternalTypes.ManagerFactory<TKey, TValue, TManager>,\n\t): asserts this is NotificationsWorkspace<\n\t\tTSchema & Record<TKey, InternalTypes.ManagerFactory<TKey, TValue, TManager>>\n\t>;\n\n\t/**\n\t * Registry of `NotificationsManager`s.\n\t */\n\treadonly notifications: StatesWorkspaceEntries<TSchema>;\n\n\t/**\n\t * Containing {@link PresenceWithNotifications}\n\t */\n\treadonly presence: PresenceWithNotifications;\n}\n\n// #endregion NotificationsWorkspace\n\n/**\n * `AnyWorkspace` is a superset of {@link StatesWorkspace} and {@link NotificationsWorkspace}.\n */\nexport interface AnyWorkspace<\n\tTSchema extends StatesWorkspaceSchema,\n\tTManagerConstraints = unknown,\n> extends StatesWorkspace<TSchema, TManagerConstraints> {\n\treadonly notifications: StatesWorkspaceEntries<TSchema>;\n\t// TO be removed if/when notifications are fully supported\n\treadonly presence: PresenceWithNotifications;\n}\n"]}
|
|
@@ -2,66 +2,8 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
import type { ExtensionHost as ContainerExtensionHost } from "@fluidframework/container-runtime-definitions/internal";
|
|
6
5
|
import type { InternalUtilityTypes, OpaqueJsonDeserialized } from "@fluidframework/core-interfaces/internal";
|
|
7
6
|
import type { InternalTypes } from "./exposedInternalTypes.js";
|
|
8
|
-
import type { AttendeeId, Attendee } from "./presence.js";
|
|
9
|
-
import type { OutboundAcknowledgementMessage, OutboundClientJoinMessage, OutboundDatastoreUpdateMessage, SignalMessages } from "./protocol.js";
|
|
10
|
-
/**
|
|
11
|
-
* Presence {@link ContainerExtension} version of {@link @fluidframework/container-runtime-definitions#ExtensionRuntimeProperties}
|
|
12
|
-
*/
|
|
13
|
-
export interface ExtensionRuntimeProperties {
|
|
14
|
-
SignalMessages: SignalMessages;
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Presence specific ExtensionHost
|
|
18
|
-
*/
|
|
19
|
-
export type ExtensionHost = ContainerExtensionHost<ExtensionRuntimeProperties>;
|
|
20
|
-
/**
|
|
21
|
-
* Basic structure of set of {@link Attendee} records within Presence datastore
|
|
22
|
-
*
|
|
23
|
-
* @remarks
|
|
24
|
-
* This is commonly exists per named state in State Managers.
|
|
25
|
-
*/
|
|
26
|
-
export interface ClientRecord<TValue extends ValidatableValueDirectoryOrState<unknown>> {
|
|
27
|
-
[AttendeeId: AttendeeId]: TValue;
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* This interface is a subset of ExtensionHost (and mostly of
|
|
31
|
-
* FluidDataStoreRuntime) that is needed by the Presence States.
|
|
32
|
-
*
|
|
33
|
-
* @privateRemarks
|
|
34
|
-
* Replace with non-DataStore based interface.
|
|
35
|
-
*/
|
|
36
|
-
export type IEphemeralRuntime = Omit<ExtensionHost, "logger" | "submitAddressedSignal"> & Partial<Pick<ExtensionHost, "logger">> & {
|
|
37
|
-
/**
|
|
38
|
-
* Submits the signal to be sent to other clients.
|
|
39
|
-
* @param type - Type of the signal.
|
|
40
|
-
* @param content - Content of the signal. Should be a JSON serializable object or primitive.
|
|
41
|
-
* @param targetClientId - When specified, the signal is only sent to the provided client id.
|
|
42
|
-
*/
|
|
43
|
-
submitSignal: (message: OutboundAcknowledgementMessage | OutboundClientJoinMessage | OutboundDatastoreUpdateMessage) => void;
|
|
44
|
-
};
|
|
45
|
-
/**
|
|
46
|
-
* Contract for State Managers as used by a States Workspace (`PresenceStatesImpl`)
|
|
47
|
-
*
|
|
48
|
-
* @remarks
|
|
49
|
-
* See uses of `unbrandIVM`.
|
|
50
|
-
*/
|
|
51
|
-
export interface ValueManager<TValue, TValueState extends InternalTypes.ValueDirectoryOrState<TValue> = InternalTypes.ValueDirectoryOrState<TValue>> {
|
|
52
|
-
readonly value?: TValueState;
|
|
53
|
-
/**
|
|
54
|
-
* Process an update of `value` for remote attendee.
|
|
55
|
-
* @param attendee - The attendee whose `value` is being updated
|
|
56
|
-
* @param received - The revision number received
|
|
57
|
-
* @param value - The new `value` state
|
|
58
|
-
*/
|
|
59
|
-
update(attendee: Attendee, received: number, value: TValueState): PostUpdateAction[];
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* A function to be called at the end of an update frame
|
|
63
|
-
*/
|
|
64
|
-
export type PostUpdateAction = () => void;
|
|
65
7
|
/**
|
|
66
8
|
* Metadata for a value that may have been validated by a {@link StateSchemaValidator} function.
|
|
67
9
|
*/
|
|
@@ -124,4 +66,4 @@ export type ValidatableValueStructure<T extends InternalTypes.ValueDirectory<unk
|
|
|
124
66
|
};
|
|
125
67
|
}>> : T extends InternalTypes.ValueRequiredState<infer TValue> | InternalTypes.ValueOptionalState<infer TValue> ? InternalUtilityTypes.FlattenIntersection<Omit<T, keyof ValidatableMetadata<TValue>> & ValidatableMetadata<TValue>> : never;
|
|
126
68
|
export {};
|
|
127
|
-
//# sourceMappingURL=
|
|
69
|
+
//# sourceMappingURL=validatableTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validatableTypes.d.ts","sourceRoot":"","sources":["../src/validatableTypes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACX,oBAAoB,EACpB,sBAAsB,EACtB,MAAM,0CAA0C,CAAC;AAElD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE/D;;GAEG;AACH,UAAU,mBAAmB,CAAC,MAAM;IACnC;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,sBAAsB,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;CAE5D;AAED;;;GAGG;AACH,MAAM,WAAW,wBAAwB,CAAC,MAAM,CAC/C,SAAQ,IAAI,CAAC,aAAa,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,MAAM,mBAAmB,CAAC,MAAM,CAAC,CAAC,EACxF,mBAAmB,CAAC,MAAM,CAAC;CAAG;AAEhC;;;GAGG;AACH,MAAM,WAAW,wBAAwB,CAAC,MAAM,CAC/C,SAAQ,IAAI,CAAC,aAAa,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,MAAM,mBAAmB,CAAC,MAAM,CAAC,CAAC,EACxF,mBAAmB,CAAC,MAAM,CAAC;CAAG;AAEhC;;;;;;GAMG;AACH,MAAM,WAAW,yBAAyB,CAAC,CAAC;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE;QAIN,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,wBAAwB,CAAC,CAAC,CAAC,GAAG,yBAAyB,CAAC,CAAC,CAAC,CAAC;KACpF,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,MAAM,gCAAgC,CAAC,CAAC,IAC3C,wBAAwB,CAAC,CAAC,CAAC,GAC3B,yBAAyB,CAAC,CAAC,CAAC,CAAC;AAEhC;;;;;;;;;;GAUG;AACH,MAAM,MAAM,yBAAyB,CACpC,CAAC,SACE,aAAa,CAAC,cAAc,CAAC,OAAO,CAAC,GACrC,aAAa,CAAC,kBAAkB,CAAC,OAAO,CAAC,GACzC,aAAa,CAAC,kBAAkB,CAAC,OAAO,CAAC,IACzC,CAAC,SAAS,aAAa,CAAC,cAAc,CAAC,MAAM,MAAM,CAAC,GACrD,oBAAoB,CAAC,UAAU,CAC/B,CAAC,EACD,aAAa,CAAC,cAAc,CAAC,CAAC,CAAC,EAE/B,yBAAyB,CAAC,MAAM,CAAC,EAEjC,oBAAoB,CAAC,mBAAmB,CACvC,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG;IAClB,KAAK,EAAE;SACL,MAAM,IAAI,MAAM,CAAC,CAAC,OAAO,CAAC,GAAG,yBAAyB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC;KAC3E,CAAC;CACF,CACD,CACD,GACA,CAAC,SACE,aAAa,CAAC,kBAAkB,CAAC,MAAM,MAAM,CAAC,GAC9C,aAAa,CAAC,kBAAkB,CAAC,MAAM,MAAM,CAAC,GAChD,oBAAoB,CAAC,mBAAmB,CACxC,IAAI,CAAC,CAAC,EAAE,MAAM,mBAAmB,CAAC,MAAM,CAAC,CAAC,GAAG,mBAAmB,CAAC,MAAM,CAAC,CACxE,GACA,KAAK,CAAC"}
|