@fluidframework/presence 2.32.0 → 2.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -24
- package/dist/alpha.d.ts +29 -25
- package/dist/baseTypes.d.ts +3 -3
- package/dist/baseTypes.js.map +1 -1
- package/dist/broadcastControls.d.ts +1 -1
- package/dist/broadcastControls.js.map +1 -1
- package/dist/datastorePresenceManagerFactory.d.ts +5 -5
- package/dist/datastorePresenceManagerFactory.d.ts.map +1 -1
- package/dist/datastorePresenceManagerFactory.js +6 -6
- package/dist/datastorePresenceManagerFactory.js.map +1 -1
- package/dist/experimentalAccess.d.ts +4 -4
- package/dist/experimentalAccess.d.ts.map +1 -1
- package/dist/experimentalAccess.js +6 -6
- package/dist/experimentalAccess.js.map +1 -1
- package/dist/exposedInternalTypes.d.ts +1 -1
- package/dist/exposedInternalTypes.js.map +1 -1
- package/dist/exposedUtilityTypes.d.ts +0 -8
- package/dist/exposedUtilityTypes.d.ts.map +1 -1
- package/dist/exposedUtilityTypes.js.map +1 -1
- package/dist/index.d.ts +8 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -8
- package/dist/index.js.map +1 -1
- package/dist/internalTypes.d.ts +3 -3
- package/dist/internalTypes.d.ts.map +1 -1
- package/dist/internalTypes.js.map +1 -1
- package/dist/internalUtils.d.ts +5 -0
- package/dist/internalUtils.d.ts.map +1 -1
- package/dist/internalUtils.js +8 -1
- package/dist/internalUtils.js.map +1 -1
- package/dist/latestMapValueManager.d.ts +57 -39
- package/dist/latestMapValueManager.d.ts.map +1 -1
- package/dist/latestMapValueManager.js +48 -39
- package/dist/latestMapValueManager.js.map +1 -1
- package/dist/latestValueManager.d.ts +38 -20
- package/dist/latestValueManager.d.ts.map +1 -1
- package/dist/latestValueManager.js +32 -28
- package/dist/latestValueManager.js.map +1 -1
- package/dist/latestValueTypes.d.ts +9 -10
- package/dist/latestValueTypes.d.ts.map +1 -1
- package/dist/latestValueTypes.js.map +1 -1
- package/dist/notificationsManager.d.ts +15 -10
- package/dist/notificationsManager.d.ts.map +1 -1
- package/dist/notificationsManager.js +8 -5
- package/dist/notificationsManager.js.map +1 -1
- package/dist/presence.d.ts +82 -66
- package/dist/presence.d.ts.map +1 -1
- package/dist/presence.js +5 -5
- package/dist/presence.js.map +1 -1
- package/dist/presenceDatastoreManager.d.ts +12 -10
- package/dist/presenceDatastoreManager.d.ts.map +1 -1
- package/dist/presenceDatastoreManager.js +10 -8
- package/dist/presenceDatastoreManager.js.map +1 -1
- package/dist/presenceManager.d.ts +2 -2
- package/dist/presenceManager.d.ts.map +1 -1
- package/dist/presenceManager.js +14 -22
- package/dist/presenceManager.js.map +1 -1
- package/dist/presenceStates.d.ts +14 -13
- package/dist/presenceStates.d.ts.map +1 -1
- package/dist/presenceStates.js +22 -15
- package/dist/presenceStates.js.map +1 -1
- package/dist/stateDatastore.d.ts +5 -4
- package/dist/stateDatastore.d.ts.map +1 -1
- package/dist/stateDatastore.js.map +1 -1
- package/dist/stateFactory.d.ts +22 -0
- package/dist/stateFactory.d.ts.map +1 -0
- package/dist/stateFactory.js +25 -0
- package/dist/stateFactory.js.map +1 -0
- package/dist/systemWorkspace.d.ts +7 -7
- package/dist/systemWorkspace.d.ts.map +1 -1
- package/dist/systemWorkspace.js +23 -23
- package/dist/systemWorkspace.js.map +1 -1
- package/dist/types.d.ts +50 -33
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +0 -1
- package/dist/types.js.map +1 -1
- package/lib/alpha.d.ts +29 -25
- package/lib/baseTypes.d.ts +3 -3
- package/lib/baseTypes.js.map +1 -1
- package/lib/broadcastControls.d.ts +1 -1
- package/lib/broadcastControls.js.map +1 -1
- package/lib/datastorePresenceManagerFactory.d.ts +5 -5
- package/lib/datastorePresenceManagerFactory.d.ts.map +1 -1
- package/lib/datastorePresenceManagerFactory.js +4 -4
- package/lib/datastorePresenceManagerFactory.js.map +1 -1
- package/lib/experimentalAccess.d.ts +4 -4
- package/lib/experimentalAccess.d.ts.map +1 -1
- package/lib/experimentalAccess.js +4 -4
- package/lib/experimentalAccess.js.map +1 -1
- package/lib/exposedInternalTypes.d.ts +1 -1
- package/lib/exposedInternalTypes.js.map +1 -1
- package/lib/exposedUtilityTypes.d.ts +0 -8
- package/lib/exposedUtilityTypes.d.ts.map +1 -1
- package/lib/exposedUtilityTypes.js.map +1 -1
- package/lib/index.d.ts +8 -7
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +4 -5
- package/lib/index.js.map +1 -1
- package/lib/internalTypes.d.ts +3 -3
- package/lib/internalTypes.d.ts.map +1 -1
- package/lib/internalTypes.js.map +1 -1
- package/lib/internalUtils.d.ts +5 -0
- package/lib/internalUtils.d.ts.map +1 -1
- package/lib/internalUtils.js +6 -0
- package/lib/internalUtils.js.map +1 -1
- package/lib/latestMapValueManager.d.ts +57 -39
- package/lib/latestMapValueManager.d.ts.map +1 -1
- package/lib/latestMapValueManager.js +47 -38
- package/lib/latestMapValueManager.js.map +1 -1
- package/lib/latestValueManager.d.ts +38 -20
- package/lib/latestValueManager.d.ts.map +1 -1
- package/lib/latestValueManager.js +31 -27
- package/lib/latestValueManager.js.map +1 -1
- package/lib/latestValueTypes.d.ts +9 -10
- package/lib/latestValueTypes.d.ts.map +1 -1
- package/lib/latestValueTypes.js.map +1 -1
- package/lib/notificationsManager.d.ts +15 -10
- package/lib/notificationsManager.d.ts.map +1 -1
- package/lib/notificationsManager.js +8 -5
- package/lib/notificationsManager.js.map +1 -1
- package/lib/presence.d.ts +82 -66
- package/lib/presence.d.ts.map +1 -1
- package/lib/presence.js +4 -4
- package/lib/presence.js.map +1 -1
- package/lib/presenceDatastoreManager.d.ts +12 -10
- package/lib/presenceDatastoreManager.d.ts.map +1 -1
- package/lib/presenceDatastoreManager.js +10 -8
- package/lib/presenceDatastoreManager.js.map +1 -1
- package/lib/presenceManager.d.ts +2 -2
- package/lib/presenceManager.d.ts.map +1 -1
- package/lib/presenceManager.js +14 -22
- package/lib/presenceManager.js.map +1 -1
- package/lib/presenceStates.d.ts +14 -13
- package/lib/presenceStates.d.ts.map +1 -1
- package/lib/presenceStates.js +22 -15
- package/lib/presenceStates.js.map +1 -1
- package/lib/stateDatastore.d.ts +5 -4
- package/lib/stateDatastore.d.ts.map +1 -1
- package/lib/stateDatastore.js.map +1 -1
- package/lib/stateFactory.d.ts +22 -0
- package/lib/stateFactory.d.ts.map +1 -0
- package/lib/stateFactory.js +22 -0
- package/lib/stateFactory.js.map +1 -0
- package/lib/systemWorkspace.d.ts +7 -7
- package/lib/systemWorkspace.d.ts.map +1 -1
- package/lib/systemWorkspace.js +24 -24
- package/lib/systemWorkspace.js.map +1 -1
- package/lib/tsdoc-metadata.json +1 -1
- package/lib/types.d.ts +50 -33
- package/lib/types.d.ts.map +1 -1
- package/lib/types.js +0 -1
- package/lib/types.js.map +1 -1
- package/package.json +19 -19
package/dist/stateDatastore.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import type { ClientConnectionId } from "./baseTypes.js";
|
|
6
6
|
import type { InternalTypes } from "./exposedInternalTypes.js";
|
|
7
7
|
import type { ClientRecord } from "./internalTypes.js";
|
|
8
|
-
import type {
|
|
8
|
+
import type { Attendee, AttendeeId, Presence } from "./presence.js";
|
|
9
9
|
/**
|
|
10
10
|
* @internal
|
|
11
11
|
*/
|
|
@@ -20,15 +20,16 @@ export interface LocalStateUpdateOptions {
|
|
|
20
20
|
* @internal
|
|
21
21
|
*/
|
|
22
22
|
export interface StateDatastore<TKey extends string, TValue extends InternalTypes.ValueDirectoryOrState<any>> {
|
|
23
|
+
readonly presence: Presence;
|
|
23
24
|
localUpdate(key: TKey, value: TValue & {
|
|
24
25
|
ignoreUnmonitored?: true;
|
|
25
26
|
}, options: LocalStateUpdateOptions): void;
|
|
26
|
-
update(key: TKey,
|
|
27
|
+
update(key: TKey, attendeeId: AttendeeId, value: TValue): void;
|
|
27
28
|
knownValues(key: TKey): {
|
|
28
|
-
self:
|
|
29
|
+
self: AttendeeId | undefined;
|
|
29
30
|
states: ClientRecord<TValue>;
|
|
30
31
|
};
|
|
31
|
-
lookupClient(clientId: ClientConnectionId):
|
|
32
|
+
lookupClient(clientId: ClientConnectionId): Attendee;
|
|
32
33
|
}
|
|
33
34
|
/**
|
|
34
35
|
* Helper to get a handle from a datastore.
|
|
@@ -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,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,
|
|
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,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAiBpE;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACvC,wBAAwB,EAAE,MAAM,GAAG,SAAS,CAAC;IAE7C;;OAEG;IACH,cAAc,CAAC,EAAE,kBAAkB,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,cAAc,CAC9B,IAAI,SAAS,MAAM,EACnB,MAAM,SAAS,aAAa,CAAC,qBAAqB,CAAC,GAAG,CAAC;IAEvD,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,WAAW,CACV,GAAG,EAAE,IAAI,EACT,KAAK,EAAE,MAAM,GAAG;QACf,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,MAAM,GAAG,IAAI,CAAC;IAC/D,WAAW,CAAC,GAAG,EAAE,IAAI,GAAG;QACvB,IAAI,EAAE,UAAU,GAAG,SAAS,CAAC;QAC7B,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;KAC7B,CAAC;IACF,YAAY,CAAC,QAAQ,EAAE,kBAAkB,GAAG,QAAQ,CAAC;CACrD;AAED;;;;GAIG;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;;;;GAIG;AACH,wBAAgB,mBAAmB,CAClC,IAAI,SAAS,MAAM,EACnB,MAAM,SAAS,aAAa,CAAC,qBAAqB,CAAC,GAAG,CAAC,EACtD,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;;;AAyDH;;;;GAIG;AACH,SAAgB,mBAAmB,CAOlC,SAAuC;IAEvC,OAAO,SAGN,CAAC;AACH,CAAC;AAbD,kDAaC;AAED;;;;GAIG;AACH,SAAgB,mBAAmB,CAGjC,MAAwD;IACzD,OAAO,MAAiD,CAAC;AAC1D,CAAC;AALD,kDAKC","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 { ClientRecord } from \"./internalTypes.js\";\nimport type { Attendee, AttendeeId, Presence } from \"./presence.js\";\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// /**\n// * @internal\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 * @internal\n */\nexport interface LocalStateUpdateOptions {\n\tallowableUpdateLatencyMs: number | undefined;\n\n\t/**\n\t * Special option allowed for unicast notifications.\n\t */\n\ttargetClientId?: ClientConnectionId;\n}\n\n/**\n * @internal\n */\nexport interface StateDatastore<\n\tTKey extends string,\n\tTValue extends InternalTypes.ValueDirectoryOrState<any>,\n> {\n\treadonly presence: Presence;\n\tlocalUpdate(\n\t\tkey: TKey,\n\t\tvalue: TValue & {\n\t\t\tignoreUnmonitored?: true;\n\t\t},\n\t\toptions: LocalStateUpdateOptions,\n\t): void;\n\tupdate(key: TKey, attendeeId: AttendeeId, value: TValue): void;\n\tknownValues(key: TKey): {\n\t\tself: AttendeeId | undefined;\n\t\tstates: ClientRecord<TValue>;\n\t};\n\tlookupClient(clientId: ClientConnectionId): Attendee;\n}\n\n/**\n * Helper to get a handle from a datastore.\n *\n * @internal\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 *\n * @internal\n */\nexport function datastoreFromHandle<\n\tTKey extends string,\n\tTValue extends InternalTypes.ValueDirectoryOrState<any>,\n>(handle: InternalTypes.StateDatastoreHandle<TKey, TValue>): StateDatastore<TKey, TValue> {\n\treturn handle as unknown as StateDatastore<TKey, TValue>;\n}\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
import { latestMap } from "./latestMapValueManager.js";
|
|
6
|
+
import { latest } from "./latestValueManager.js";
|
|
7
|
+
/**
|
|
8
|
+
* Factory for creating presence State objects.
|
|
9
|
+
*
|
|
10
|
+
* @alpha
|
|
11
|
+
*/
|
|
12
|
+
export declare const StateFactory: {
|
|
13
|
+
/**
|
|
14
|
+
* {@inheritdoc latest}
|
|
15
|
+
*/
|
|
16
|
+
latest: typeof latest;
|
|
17
|
+
/**
|
|
18
|
+
* {@inheritdoc latestMap}
|
|
19
|
+
*/
|
|
20
|
+
latestMap: typeof latestMap;
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=stateFactory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stateFactory.d.ts","sourceRoot":"","sources":["../src/stateFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEjD;;;;GAIG;AACH,eAAO,MAAM,YAAY;IACxB;;OAEG;;IAEH;;OAEG;;CAEH,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*!
|
|
3
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
4
|
+
* Licensed under the MIT License.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.StateFactory = void 0;
|
|
8
|
+
const latestMapValueManager_js_1 = require("./latestMapValueManager.js");
|
|
9
|
+
const latestValueManager_js_1 = require("./latestValueManager.js");
|
|
10
|
+
/**
|
|
11
|
+
* Factory for creating presence State objects.
|
|
12
|
+
*
|
|
13
|
+
* @alpha
|
|
14
|
+
*/
|
|
15
|
+
exports.StateFactory = {
|
|
16
|
+
/**
|
|
17
|
+
* {@inheritdoc latest}
|
|
18
|
+
*/
|
|
19
|
+
latest: latestValueManager_js_1.latest,
|
|
20
|
+
/**
|
|
21
|
+
* {@inheritdoc latestMap}
|
|
22
|
+
*/
|
|
23
|
+
latestMap: latestMapValueManager_js_1.latestMap,
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=stateFactory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stateFactory.js","sourceRoot":"","sources":["../src/stateFactory.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,yEAAuD;AACvD,mEAAiD;AAEjD;;;;GAIG;AACU,QAAA,YAAY,GAAG;IAC3B;;OAEG;IACH,MAAM,EAAN,8BAAM;IACN;;OAEG;IACH,SAAS,EAAT,oCAAS;CACT,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { latestMap } from \"./latestMapValueManager.js\";\nimport { latest } from \"./latestValueManager.js\";\n\n/**\n * Factory for creating presence State objects.\n *\n * @alpha\n */\nexport const StateFactory = {\n\t/**\n\t * {@inheritdoc latest}\n\t */\n\tlatest,\n\t/**\n\t * {@inheritdoc latestMap}\n\t */\n\tlatestMap,\n};\n"]}
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
import type { IAudience } from "@fluidframework/container-definitions";
|
|
6
|
-
import type { IEmitter } from "@fluidframework/core-interfaces/internal";
|
|
6
|
+
import type { IEmitter, Listenable } from "@fluidframework/core-interfaces/internal";
|
|
7
7
|
import type { ClientConnectionId } from "./baseTypes.js";
|
|
8
8
|
import type { InternalTypes } from "./exposedInternalTypes.js";
|
|
9
|
-
import type {
|
|
9
|
+
import type { AttendeesEvents, AttendeeId, Presence } from "./presence.js";
|
|
10
10
|
import type { PresenceStatesInternal } from "./presenceStates.js";
|
|
11
|
-
import type {
|
|
11
|
+
import type { AnyWorkspace, StatesWorkspaceSchema } from "./types.js";
|
|
12
12
|
/**
|
|
13
13
|
* The system workspace's datastore structure.
|
|
14
14
|
*
|
|
@@ -16,13 +16,13 @@ import type { PresenceStates, PresenceStatesSchema } from "./types.js";
|
|
|
16
16
|
*/
|
|
17
17
|
export interface SystemWorkspaceDatastore {
|
|
18
18
|
clientToSessionId: {
|
|
19
|
-
[ConnectionId: ClientConnectionId]: InternalTypes.ValueRequiredState<
|
|
19
|
+
[ConnectionId: ClientConnectionId]: InternalTypes.ValueRequiredState<AttendeeId>;
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
22
|
/**
|
|
23
23
|
* @internal
|
|
24
24
|
*/
|
|
25
|
-
export interface SystemWorkspace extends
|
|
25
|
+
export interface SystemWorkspace extends Exclude<Presence["attendees"], never> {
|
|
26
26
|
/**
|
|
27
27
|
* Must be called when the current client acquires a new connection.
|
|
28
28
|
*
|
|
@@ -41,11 +41,11 @@ export interface SystemWorkspace extends Pick<IPresence, "getAttendees" | "getAt
|
|
|
41
41
|
*
|
|
42
42
|
* @internal
|
|
43
43
|
*/
|
|
44
|
-
export declare function createSystemWorkspace(
|
|
44
|
+
export declare function createSystemWorkspace(attendeeId: AttendeeId, datastore: SystemWorkspaceDatastore, events: Listenable<AttendeesEvents> & IEmitter<AttendeesEvents>, audience: IAudience): {
|
|
45
45
|
workspace: SystemWorkspace;
|
|
46
46
|
statesEntry: {
|
|
47
47
|
internal: PresenceStatesInternal;
|
|
48
|
-
public:
|
|
48
|
+
public: AnyWorkspace<StatesWorkspaceSchema>;
|
|
49
49
|
};
|
|
50
50
|
};
|
|
51
51
|
//# sourceMappingURL=systemWorkspace.d.ts.map
|
|
@@ -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,MAAM,0CAA0C,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;AAElE,OAAO,KAAK,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEtE;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACxC,iBAAiB,EAAE;QAClB,CAAC,YAAY,EAAE,kBAAkB,GAAG,aAAa,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC;KACjF,CAAC;CACF;AAoCD;;GAEG;AACH,MAAM,WAAW,eAGhB,SAAQ,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,KAAK,CAAC;IAC7C;;;;OAIG;IACH,iBAAiB,CAAC,kBAAkB,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAEhE;;;;OAIG;IACH,wBAAwB,CAAC,kBAAkB,EAAE,kBAAkB,GAAG,IAAI,CAAC;CACvE;AA4MD;;;;GAIG;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/dist/systemWorkspace.js
CHANGED
|
@@ -9,15 +9,15 @@ const internal_1 = require("@fluidframework/core-utils/internal");
|
|
|
9
9
|
const presence_js_1 = require("./presence.js");
|
|
10
10
|
const timerManager_js_1 = require("./timerManager.js");
|
|
11
11
|
class SessionClient {
|
|
12
|
-
constructor(
|
|
13
|
-
this.
|
|
12
|
+
constructor(attendeeId, connectionId = undefined) {
|
|
13
|
+
this.attendeeId = attendeeId;
|
|
14
14
|
this.connectionId = connectionId;
|
|
15
15
|
/**
|
|
16
16
|
* Order is used to track the most recent client connection
|
|
17
17
|
* during a session.
|
|
18
18
|
*/
|
|
19
19
|
this.order = 0;
|
|
20
|
-
this.connectionStatus = presence_js_1.
|
|
20
|
+
this.connectionStatus = presence_js_1.AttendeeStatus.Disconnected;
|
|
21
21
|
}
|
|
22
22
|
getConnectionId() {
|
|
23
23
|
if (this.connectionId === undefined) {
|
|
@@ -29,14 +29,14 @@ class SessionClient {
|
|
|
29
29
|
return this.connectionStatus;
|
|
30
30
|
}
|
|
31
31
|
setConnected() {
|
|
32
|
-
this.connectionStatus = presence_js_1.
|
|
32
|
+
this.connectionStatus = presence_js_1.AttendeeStatus.Connected;
|
|
33
33
|
}
|
|
34
34
|
setDisconnected() {
|
|
35
|
-
this.connectionStatus = presence_js_1.
|
|
35
|
+
this.connectionStatus = presence_js_1.AttendeeStatus.Disconnected;
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
class SystemWorkspaceImpl {
|
|
39
|
-
constructor(
|
|
39
|
+
constructor(attendeeId, datastore, events, audience) {
|
|
40
40
|
this.datastore = datastore;
|
|
41
41
|
this.events = events;
|
|
42
42
|
this.audience = audience;
|
|
@@ -45,15 +45,15 @@ class SystemWorkspaceImpl {
|
|
|
45
45
|
* session. The map covers entries for both session ids and connection
|
|
46
46
|
* ids, which are never expected to collide, but if they did for same
|
|
47
47
|
* client that would be fine.
|
|
48
|
-
* An entry is for session ID if the value's `
|
|
48
|
+
* An entry is for session ID if the value's `attendeeId` matches the key.
|
|
49
49
|
*/
|
|
50
50
|
this.attendees = new Map();
|
|
51
51
|
// When local client disconnects, we lose the connectivity status updates for remote attendees in the session.
|
|
52
52
|
// Upon reconnect, we mark all other attendees connections as stale and update their status to disconnected after 30 seconds of inactivity.
|
|
53
53
|
this.staleConnectionClients = new Set();
|
|
54
54
|
this.staleConnectionTimer = new timerManager_js_1.TimerManager();
|
|
55
|
-
this.selfAttendee = new SessionClient(
|
|
56
|
-
this.attendees.set(
|
|
55
|
+
this.selfAttendee = new SessionClient(attendeeId);
|
|
56
|
+
this.attendees.set(attendeeId, this.selfAttendee);
|
|
57
57
|
}
|
|
58
58
|
ensureContent(_content) {
|
|
59
59
|
throw new Error("Method not implemented.");
|
|
@@ -62,8 +62,8 @@ class SystemWorkspaceImpl {
|
|
|
62
62
|
const audienceMembers = this.audience.getMembers();
|
|
63
63
|
const postUpdateActions = [];
|
|
64
64
|
for (const [clientConnectionId, value] of Object.entries(remoteDatastore.clientToSessionId)) {
|
|
65
|
-
const
|
|
66
|
-
const { attendee, isJoining } = this.ensureAttendee(
|
|
65
|
+
const attendeeId = value.value;
|
|
66
|
+
const { attendee, isJoining } = this.ensureAttendee(attendeeId, clientConnectionId,
|
|
67
67
|
/* order */ value.rev,
|
|
68
68
|
// If the attendee is present in audience OR if the attendee update is from the sending remote client itself,
|
|
69
69
|
// then the attendee is considered connected.
|
|
@@ -71,7 +71,7 @@ class SystemWorkspaceImpl {
|
|
|
71
71
|
audienceMembers.has(clientConnectionId));
|
|
72
72
|
// If the attendee is joining the session, add them to the list of joining attendees to be announced later.
|
|
73
73
|
if (isJoining) {
|
|
74
|
-
postUpdateActions.push(() => this.events.emit("
|
|
74
|
+
postUpdateActions.push(() => this.events.emit("attendeeConnected", attendee));
|
|
75
75
|
}
|
|
76
76
|
const knownSessionId = this.datastore.clientToSessionId[clientConnectionId];
|
|
77
77
|
if (knownSessionId === undefined) {
|
|
@@ -84,15 +84,15 @@ class SystemWorkspaceImpl {
|
|
|
84
84
|
return postUpdateActions;
|
|
85
85
|
}
|
|
86
86
|
onConnectionAdded(clientConnectionId) {
|
|
87
|
-
(0, internal_1.assert)(this.selfAttendee.getConnectionStatus() === presence_js_1.
|
|
87
|
+
(0, internal_1.assert)(this.selfAttendee.getConnectionStatus() === presence_js_1.AttendeeStatus.Disconnected, 0xaad /* Local client should be 'Disconnected' before adding new connection. */);
|
|
88
88
|
this.datastore.clientToSessionId[clientConnectionId] = {
|
|
89
89
|
rev: this.selfAttendee.order++,
|
|
90
90
|
timestamp: Date.now(),
|
|
91
|
-
value: this.selfAttendee.
|
|
91
|
+
value: this.selfAttendee.attendeeId,
|
|
92
92
|
};
|
|
93
93
|
// Mark 'Connected' remote attendees connections as stale
|
|
94
94
|
for (const staleConnectionClient of this.attendees.values()) {
|
|
95
|
-
if (staleConnectionClient.getConnectionStatus() === presence_js_1.
|
|
95
|
+
if (staleConnectionClient.getConnectionStatus() === presence_js_1.AttendeeStatus.Connected) {
|
|
96
96
|
this.staleConnectionClients.add(staleConnectionClient);
|
|
97
97
|
}
|
|
98
98
|
}
|
|
@@ -122,7 +122,7 @@ class SystemWorkspaceImpl {
|
|
|
122
122
|
// If the last known connectionID is different from the connection ID being removed, the attendee has reconnected,
|
|
123
123
|
// therefore we should not change the attendee connection status or emit a disconnect event.
|
|
124
124
|
const attendeeReconnected = attendee.getConnectionId() !== clientConnectionId;
|
|
125
|
-
const connected = attendee.getConnectionStatus() === presence_js_1.
|
|
125
|
+
const connected = attendee.getConnectionStatus() === presence_js_1.AttendeeStatus.Connected;
|
|
126
126
|
if (!attendeeReconnected && connected) {
|
|
127
127
|
attendee.setDisconnected();
|
|
128
128
|
this.events.emit("attendeeDisconnected", attendee);
|
|
@@ -151,14 +151,14 @@ class SystemWorkspaceImpl {
|
|
|
151
151
|
* in the attendee map. If not present, SessionClient is created and added
|
|
152
152
|
* to map. If present, make sure the current connection ID is updated.
|
|
153
153
|
*/
|
|
154
|
-
ensureAttendee(
|
|
155
|
-
let attendee = this.attendees.get(
|
|
154
|
+
ensureAttendee(attendeeId, clientConnectionId, order, isConnected) {
|
|
155
|
+
let attendee = this.attendees.get(attendeeId);
|
|
156
156
|
let isJoining = false;
|
|
157
157
|
if (attendee === undefined) {
|
|
158
158
|
// New attendee. Create SessionClient and add session ID based
|
|
159
159
|
// entry to map.
|
|
160
|
-
attendee = new SessionClient(
|
|
161
|
-
this.attendees.set(
|
|
160
|
+
attendee = new SessionClient(attendeeId, clientConnectionId);
|
|
161
|
+
this.attendees.set(attendeeId, attendee);
|
|
162
162
|
if (isConnected) {
|
|
163
163
|
attendee.setConnected();
|
|
164
164
|
isJoining = true;
|
|
@@ -169,7 +169,7 @@ class SystemWorkspaceImpl {
|
|
|
169
169
|
// Update the order and current connection ID.
|
|
170
170
|
attendee.order = order;
|
|
171
171
|
// Known attendee is joining the session if they are currently disconnected
|
|
172
|
-
if (attendee.getConnectionStatus() === presence_js_1.
|
|
172
|
+
if (attendee.getConnectionStatus() === presence_js_1.AttendeeStatus.Disconnected && isConnected) {
|
|
173
173
|
attendee.setConnected();
|
|
174
174
|
isJoining = true;
|
|
175
175
|
}
|
|
@@ -189,8 +189,8 @@ class SystemWorkspaceImpl {
|
|
|
189
189
|
*
|
|
190
190
|
* @internal
|
|
191
191
|
*/
|
|
192
|
-
function createSystemWorkspace(
|
|
193
|
-
const workspace = new SystemWorkspaceImpl(
|
|
192
|
+
function createSystemWorkspace(attendeeId, datastore, events, audience) {
|
|
193
|
+
const workspace = new SystemWorkspaceImpl(attendeeId, datastore, events, audience);
|
|
194
194
|
return {
|
|
195
195
|
workspace,
|
|
196
196
|
statesEntry: {
|
|
@@ -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 } 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 type {\n\tClientSessionId,\n\tIPresence,\n\tISessionClient,\n\tPresenceEvents,\n} from \"./presence.js\";\nimport { SessionClientStatus } from \"./presence.js\";\nimport type { PresenceStatesInternal } from \"./presenceStates.js\";\nimport { TimerManager } from \"./timerManager.js\";\nimport type { PresenceStates, PresenceStatesSchema } from \"./types.js\";\n\n/**\n * The system workspace's datastore structure.\n *\n * @internal\n */\nexport interface SystemWorkspaceDatastore {\n\tclientToSessionId: {\n\t\t[ConnectionId: ClientConnectionId]: InternalTypes.ValueRequiredState<ClientSessionId>;\n\t};\n}\n\nclass SessionClient implements ISessionClient {\n\t/**\n\t * Order is used to track the most recent client connection\n\t * during a session.\n\t */\n\tpublic order: number = 0;\n\n\tprivate connectionStatus: SessionClientStatus = SessionClientStatus.Disconnected;\n\n\tpublic constructor(\n\t\tpublic readonly sessionId: ClientSessionId,\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(): SessionClientStatus {\n\t\treturn this.connectionStatus;\n\t}\n\n\tpublic setConnected(): void {\n\t\tthis.connectionStatus = SessionClientStatus.Connected;\n\t}\n\n\tpublic setDisconnected(): void {\n\t\tthis.connectionStatus = SessionClientStatus.Disconnected;\n\t}\n}\n\n/**\n * @internal\n */\nexport interface SystemWorkspace\n\t// Portion of IPresence that is handled by SystemWorkspace along with\n\t// responsiblity for emitting \"attendeeJoined\" events.\n\textends Pick<IPresence, \"getAttendees\" | \"getAttendee\" | \"getMyself\"> {\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 */\n\tonConnectionAdded(clientConnectionId: ClientConnectionId): 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 `sessionId` matches the key.\n\t */\n\tprivate readonly attendees = new Map<ClientConnectionId | ClientSessionId, 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\tclientSessionId: ClientSessionId,\n\t\tprivate readonly datastore: SystemWorkspaceDatastore,\n\t\tprivate readonly events: IEmitter<\n\t\t\tPick<PresenceEvents, \"attendeeJoined\" | \"attendeeDisconnected\">\n\t\t>,\n\t\tprivate readonly audience: IAudience,\n\t) {\n\t\tthis.selfAttendee = new SessionClient(clientSessionId);\n\t\tthis.attendees.set(clientSessionId, this.selfAttendee);\n\t}\n\n\tpublic ensureContent<TSchemaAdditional extends PresenceStatesSchema>(\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\tremoteDatastore: {\n\t\t\tclientToSessionId: {\n\t\t\t\t[\n\t\t\t\t\tConnectionId: ClientConnectionId\n\t\t\t\t]: InternalTypes.ValueRequiredState<ClientSessionId> & {\n\t\t\t\t\tignoreUnmonitored?: true;\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\tremoteDatastore.clientToSessionId,\n\t\t)) {\n\t\t\tconst clientSessionId = value.value;\n\t\t\tconst { attendee, isJoining } = this.ensureAttendee(\n\t\t\t\tclientSessionId,\n\t\t\t\tclientConnectionId,\n\t\t\t\t/* order */ value.rev,\n\t\t\t\t// If the attendee is present in audience OR if the attendee update is from the sending remote client itself,\n\t\t\t\t// then the attendee is considered connected.\n\t\t\t\t/* isConnected */ senderConnectionId === clientConnectionId ||\n\t\t\t\t\taudienceMembers.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(\"attendeeJoined\", attendee));\n\t\t\t}\n\n\t\t\tconst knownSessionId: InternalTypes.ValueRequiredState<ClientSessionId> | undefined =\n\t\t\t\tthis.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(clientConnectionId: ClientConnectionId): void {\n\t\tassert(\n\t\t\tthis.selfAttendee.getConnectionStatus() === SessionClientStatus.Disconnected,\n\t\t\t0xaad /* Local client should be 'Disconnected' before adding new connection. */,\n\t\t);\n\n\t\tthis.datastore.clientToSessionId[clientConnectionId] = {\n\t\t\trev: this.selfAttendee.order++,\n\t\t\ttimestamp: Date.now(),\n\t\t\tvalue: this.selfAttendee.sessionId,\n\t\t};\n\n\t\t// Mark 'Connected' remote attendees connections as stale\n\t\tfor (const staleConnectionClient of this.attendees.values()) {\n\t\t\tif (staleConnectionClient.getConnectionStatus() === SessionClientStatus.Connected) {\n\t\t\t\tthis.staleConnectionClients.add(staleConnectionClient);\n\t\t\t}\n\t\t}\n\n\t\t// Update the self attendee\n\t\tthis.selfAttendee.connectionId = clientConnectionId;\n\t\tthis.selfAttendee.setConnected();\n\t\tthis.attendees.set(clientConnectionId, this.selfAttendee);\n\n\t\tthis.staleConnectionTimer.setTimeout(() => {\n\t\t\tfor (const client of this.staleConnectionClients) {\n\t\t\t\tclient.setDisconnected();\n\t\t\t}\n\t\t\tfor (const client of this.staleConnectionClients) {\n\t\t\t\tthis.events.emit(\"attendeeDisconnected\", client);\n\t\t\t}\n\t\t\tthis.staleConnectionClients.clear();\n\t\t}, 30_000);\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}\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() === SessionClientStatus.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<ISessionClient> {\n\t\treturn new Set(this.attendees.values());\n\t}\n\n\tpublic getAttendee(clientId: ClientConnectionId | ClientSessionId): ISessionClient {\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(): ISessionClient {\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\tclientSessionId: ClientSessionId,\n\t\tclientConnectionId: ClientConnectionId,\n\t\torder: number,\n\t\tisConnected: boolean,\n\t): { attendee: SessionClient; isJoining: boolean } {\n\t\tlet attendee = this.attendees.get(clientSessionId);\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(clientSessionId, clientConnectionId);\n\t\t\tthis.attendees.set(clientSessionId, attendee);\n\t\t\tif (isConnected) {\n\t\t\t\tattendee.setConnected();\n\t\t\t\tisJoining = true;\n\t\t\t}\n\t\t} else if (order > attendee.order) {\n\t\t\t// The given association is newer than the one we have.\n\t\t\t// Update the order and current connection ID.\n\t\t\tattendee.order = order;\n\t\t\t// Known attendee is joining the session if they are currently disconnected\n\t\t\tif (attendee.getConnectionStatus() === SessionClientStatus.Disconnected && isConnected) {\n\t\t\t\tattendee.setConnected();\n\t\t\t\tisJoining = true;\n\t\t\t}\n\t\t\tattendee.connectionId = clientConnectionId;\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 *\n * @internal\n */\nexport function createSystemWorkspace(\n\tclientSessionId: ClientSessionId,\n\tdatastore: SystemWorkspaceDatastore,\n\tevents: IEmitter<Pick<PresenceEvents, \"attendeeJoined\">>,\n\taudience: IAudience,\n): {\n\tworkspace: SystemWorkspace;\n\tstatesEntry: {\n\t\tinternal: PresenceStatesInternal;\n\t\tpublic: PresenceStates<PresenceStatesSchema>;\n\t};\n} {\n\tconst workspace = new SystemWorkspaceImpl(clientSessionId, datastore, events, audience);\n\treturn {\n\t\tworkspace,\n\t\tstatesEntry: {\n\t\t\tinternal: workspace,\n\t\t\tpublic: undefined as unknown as PresenceStates<PresenceStatesSchema>,\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 type { PostUpdateAction } from \"./internalTypes.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 * The system workspace's datastore structure.\n *\n * @internal\n */\nexport interface SystemWorkspaceDatastore {\n\tclientToSessionId: {\n\t\t[ConnectionId: ClientConnectionId]: InternalTypes.ValueRequiredState<AttendeeId>;\n\t};\n}\n\nclass SessionClient implements Attendee {\n\t/**\n\t * Order is used to track the most recent client connection\n\t * during a session.\n\t */\n\tpublic order: number = 0;\n\n\tprivate connectionStatus: AttendeeStatus = AttendeeStatus.Disconnected;\n\n\tpublic constructor(\n\t\tpublic readonly attendeeId: AttendeeId,\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\n */\nexport interface SystemWorkspace\n\t// Portion of Presence that is handled by SystemWorkspace along with\n\t// responsiblity 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 */\n\tonConnectionAdded(clientConnectionId: ClientConnectionId): 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\tremoteDatastore: {\n\t\t\tclientToSessionId: {\n\t\t\t\t[ConnectionId: ClientConnectionId]: InternalTypes.ValueRequiredState<AttendeeId> & {\n\t\t\t\t\tignoreUnmonitored?: true;\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\tremoteDatastore.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\t/* order */ value.rev,\n\t\t\t\t// If the attendee is present in audience OR if the attendee update is from the sending remote client itself,\n\t\t\t\t// then the attendee is considered connected.\n\t\t\t\t/* isConnected */ senderConnectionId === clientConnectionId ||\n\t\t\t\t\taudienceMembers.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: InternalTypes.ValueRequiredState<AttendeeId> | undefined =\n\t\t\t\tthis.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(clientConnectionId: ClientConnectionId): 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\tthis.datastore.clientToSessionId[clientConnectionId] = {\n\t\t\trev: this.selfAttendee.order++,\n\t\t\ttimestamp: Date.now(),\n\t\t\tvalue: this.selfAttendee.attendeeId,\n\t\t};\n\n\t\t// Mark 'Connected' remote attendees connections as stale\n\t\tfor (const staleConnectionClient of this.attendees.values()) {\n\t\t\tif (staleConnectionClient.getConnectionStatus() === AttendeeStatus.Connected) {\n\t\t\t\tthis.staleConnectionClients.add(staleConnectionClient);\n\t\t\t}\n\t\t}\n\n\t\t// Update the self attendee\n\t\tthis.selfAttendee.connectionId = clientConnectionId;\n\t\tthis.selfAttendee.setConnected();\n\t\tthis.attendees.set(clientConnectionId, this.selfAttendee);\n\n\t\tthis.staleConnectionTimer.setTimeout(() => {\n\t\t\tfor (const client of this.staleConnectionClients) {\n\t\t\t\tclient.setDisconnected();\n\t\t\t}\n\t\t\tfor (const client of this.staleConnectionClients) {\n\t\t\t\tthis.events.emit(\"attendeeDisconnected\", client);\n\t\t\t}\n\t\t\tthis.staleConnectionClients.clear();\n\t\t}, 30_000);\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}\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: AttendeeId,\n\t\tclientConnectionId: ClientConnectionId,\n\t\torder: number,\n\t\tisConnected: boolean,\n\t): { attendee: SessionClient; isJoining: boolean } {\n\t\tlet attendee = this.attendees.get(attendeeId);\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, clientConnectionId);\n\t\t\tthis.attendees.set(attendeeId, attendee);\n\t\t\tif (isConnected) {\n\t\t\t\tattendee.setConnected();\n\t\t\t\tisJoining = true;\n\t\t\t}\n\t\t} else if (order > attendee.order) {\n\t\t\t// The given association is newer than the one we have.\n\t\t\t// Update the order and current connection ID.\n\t\t\tattendee.order = order;\n\t\t\t// Known attendee is joining the session if they are currently disconnected\n\t\t\tif (attendee.getConnectionStatus() === AttendeeStatus.Disconnected && isConnected) {\n\t\t\t\tattendee.setConnected();\n\t\t\t\tisJoining = true;\n\t\t\t}\n\t\t\tattendee.connectionId = clientConnectionId;\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 *\n * @internal\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/dist/types.d.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import type { BroadcastControls } from "./broadcastControls.js";
|
|
6
6
|
import type { InternalTypes } from "./exposedInternalTypes.js";
|
|
7
7
|
import type { NotificationsManager } from "./notificationsManager.js";
|
|
8
|
+
import type { Presence } from "./presence.js";
|
|
8
9
|
/**
|
|
9
10
|
* Unique address within a session.
|
|
10
11
|
*
|
|
@@ -21,94 +22,110 @@ import type { NotificationsManager } from "./notificationsManager.js";
|
|
|
21
22
|
*
|
|
22
23
|
* @alpha
|
|
23
24
|
*/
|
|
24
|
-
export type
|
|
25
|
+
export type WorkspaceAddress = `${string}:${string}`;
|
|
25
26
|
/**
|
|
26
|
-
* Single entry in {@link
|
|
27
|
+
* Single entry in {@link StatesWorkspaceSchema} or {@link NotificationsWorkspaceSchema}.
|
|
27
28
|
*
|
|
28
29
|
* @alpha
|
|
29
30
|
*/
|
|
30
|
-
export type
|
|
31
|
+
export type StatesWorkspaceEntry<TKey extends string, TValue extends InternalTypes.ValueDirectoryOrState<unknown>, TManager = unknown> = InternalTypes.ManagerFactory<TKey, TValue, TManager>;
|
|
31
32
|
/**
|
|
32
|
-
* Schema for a {@link
|
|
33
|
+
* Schema for a {@link StatesWorkspace} workspace.
|
|
33
34
|
*
|
|
34
|
-
* Keys of schema are the keys of the {@link
|
|
35
|
+
* Keys of schema are the keys of the {@link StatesWorkspace} providing access to State objects.
|
|
35
36
|
*
|
|
36
37
|
* @alpha
|
|
37
38
|
*/
|
|
38
|
-
export interface
|
|
39
|
-
[key: string]:
|
|
39
|
+
export interface StatesWorkspaceSchema {
|
|
40
|
+
[key: string]: StatesWorkspaceEntry<typeof key, InternalTypes.ValueDirectoryOrState<any>>;
|
|
40
41
|
}
|
|
41
42
|
/**
|
|
42
|
-
* Map of
|
|
43
|
+
* Map of State objects registered with {@link StatesWorkspace}.
|
|
43
44
|
*
|
|
44
45
|
* @sealed
|
|
45
46
|
* @alpha
|
|
46
47
|
*/
|
|
47
|
-
export type
|
|
48
|
+
export type StatesWorkspaceEntries<TSchema extends StatesWorkspaceSchema> = {
|
|
48
49
|
/**
|
|
49
|
-
* Registered
|
|
50
|
+
* Registered State objects.
|
|
50
51
|
*/
|
|
51
52
|
readonly [Key in keyof TSchema]: ReturnType<TSchema[Key]>["manager"] extends InternalTypes.StateValue<infer TManager> ? TManager : never;
|
|
52
53
|
};
|
|
53
54
|
/**
|
|
54
|
-
* `
|
|
55
|
+
* `StatesWorkspace` maintains a registry of State objects that all share and provide access to
|
|
55
56
|
* presence state values across client members in a session.
|
|
56
57
|
*
|
|
57
|
-
*
|
|
58
|
+
* State objects offer variations on how to manage states, but all share same principle that
|
|
58
59
|
* each client's state is independent and may only be updated by originating client.
|
|
59
60
|
*
|
|
60
61
|
* @sealed
|
|
61
62
|
* @alpha
|
|
62
63
|
*/
|
|
63
|
-
export interface
|
|
64
|
+
export interface StatesWorkspace<TSchema extends StatesWorkspaceSchema, TManagerConstraints = unknown> {
|
|
64
65
|
/**
|
|
65
|
-
* Registers a new
|
|
66
|
-
* @param key - new unique key for the
|
|
67
|
-
* @param manager - factory for creating a
|
|
66
|
+
* Registers a new State object with the {@link StatesWorkspace}.
|
|
67
|
+
* @param key - new unique key for the State object within the workspace
|
|
68
|
+
* @param manager - factory for creating a State object
|
|
68
69
|
*/
|
|
69
|
-
add<TKey extends string, TValue extends InternalTypes.ValueDirectoryOrState<any>, TManager extends TManagerConstraints>(key: TKey, manager: InternalTypes.ManagerFactory<TKey, TValue, TManager>): asserts this is
|
|
70
|
+
add<TKey extends string, TValue extends InternalTypes.ValueDirectoryOrState<any>, TManager extends TManagerConstraints>(key: TKey, manager: InternalTypes.ManagerFactory<TKey, TValue, TManager>): asserts this is StatesWorkspace<TSchema & Record<TKey, InternalTypes.ManagerFactory<TKey, TValue, TManager>>, TManagerConstraints>;
|
|
70
71
|
/**
|
|
71
|
-
* Registry of
|
|
72
|
+
* Registry of State objects.
|
|
72
73
|
*/
|
|
73
|
-
readonly
|
|
74
|
+
readonly states: StatesWorkspaceEntries<TSchema>;
|
|
74
75
|
/**
|
|
75
76
|
* Default controls for management of broadcast updates.
|
|
76
77
|
*/
|
|
77
78
|
readonly controls: BroadcastControls;
|
|
79
|
+
/**
|
|
80
|
+
* Containing {@link Presence}
|
|
81
|
+
*/
|
|
82
|
+
readonly presence: Presence;
|
|
78
83
|
}
|
|
79
84
|
/**
|
|
80
|
-
* Schema for a {@link
|
|
85
|
+
* Schema for a {@link NotificationsWorkspace} workspace.
|
|
81
86
|
*
|
|
82
|
-
* Keys of schema are the keys of the {@link
|
|
87
|
+
* Keys of schema are the keys of the {@link NotificationsWorkspace} providing access to {@link NotificationsManager}s.
|
|
83
88
|
*
|
|
84
89
|
* @alpha
|
|
85
90
|
*/
|
|
86
|
-
export interface
|
|
91
|
+
export interface NotificationsWorkspaceSchema {
|
|
87
92
|
[key: string]: InternalTypes.ManagerFactory<typeof key, InternalTypes.ValueRequiredState<InternalTypes.NotificationType>, NotificationsManager<any>>;
|
|
88
93
|
}
|
|
89
94
|
/**
|
|
90
|
-
* `
|
|
95
|
+
* `NotificationsWorkspace` maintains a registry of {@link NotificationsManager}s
|
|
91
96
|
* that facilitate messages across client members in a session.
|
|
92
97
|
*
|
|
93
98
|
* @privateRemarks
|
|
94
|
-
* This should be kept mostly in sync with {@link
|
|
99
|
+
* This should be kept mostly in sync with {@link StatesWorkspace}. Notably the
|
|
95
100
|
* return type of `add` is limited here and the `controls` property is omitted.
|
|
96
|
-
* The `PresenceStatesImpl` class implements `
|
|
97
|
-
* `
|
|
101
|
+
* The `PresenceStatesImpl` class implements `AnyWorkspace` and therefore
|
|
102
|
+
* `NotificationsWorkspace`, so long as this is proper subset.
|
|
98
103
|
*
|
|
99
104
|
* @sealed
|
|
100
105
|
* @alpha
|
|
101
106
|
*/
|
|
102
|
-
export interface
|
|
107
|
+
export interface NotificationsWorkspace<TSchema extends NotificationsWorkspaceSchema> {
|
|
108
|
+
/**
|
|
109
|
+
* Registers a new `NotificationsManager` with the {@link NotificationsWorkspace}.
|
|
110
|
+
* @param key - new unique key for the `NotificationsManager` within the workspace
|
|
111
|
+
* @param manager - factory for creating a `NotificationsManager`
|
|
112
|
+
*/
|
|
113
|
+
add<TKey extends string, TValue extends InternalTypes.ValueDirectoryOrState<any>, TManager extends NotificationsManager<any>>(key: TKey, manager: InternalTypes.ManagerFactory<TKey, TValue, TManager>): asserts this is NotificationsWorkspace<TSchema & Record<TKey, InternalTypes.ManagerFactory<TKey, TValue, TManager>>>;
|
|
103
114
|
/**
|
|
104
|
-
*
|
|
105
|
-
* @param key - new unique key for the `Value Manager` within the workspace
|
|
106
|
-
* @param manager - factory for creating a `Value Manager`
|
|
115
|
+
* Registry of `NotificationsManager`s.
|
|
107
116
|
*/
|
|
108
|
-
|
|
117
|
+
readonly notifications: StatesWorkspaceEntries<TSchema>;
|
|
109
118
|
/**
|
|
110
|
-
*
|
|
119
|
+
* Containing {@link Presence}
|
|
111
120
|
*/
|
|
112
|
-
readonly
|
|
121
|
+
readonly presence: Presence;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* `AnyWorkspace` is a superset of {@link StatesWorkspace} and {@link NotificationsWorkspace}.
|
|
125
|
+
*
|
|
126
|
+
* @internal
|
|
127
|
+
*/
|
|
128
|
+
export interface AnyWorkspace<TSchema extends StatesWorkspaceSchema, TManagerConstraints = unknown> extends StatesWorkspace<TSchema, TManagerConstraints> {
|
|
129
|
+
readonly notifications: StatesWorkspaceEntries<TSchema>;
|
|
113
130
|
}
|
|
114
131
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/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,wBAAwB,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
CHANGED
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;;GAGG
|
|
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 \"./broadcastControls.js\";\nimport type { InternalTypes } from \"./exposedInternalTypes.js\";\nimport type { NotificationsManager } from \"./notificationsManager.js\";\nimport type { Presence } 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 * @alpha\n */\nexport type WorkspaceAddress = `${string}:${string}`;\n\n/**\n * Single entry in {@link StatesWorkspaceSchema} or {@link NotificationsWorkspaceSchema}.\n *\n * @alpha\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 * @alpha\n */\nexport interface StatesWorkspaceSchema {\n\t[key: string]: StatesWorkspaceEntry<typeof key, InternalTypes.ValueDirectoryOrState<any>>;\n}\n\n/**\n * Map of State objects registered with {@link StatesWorkspace}.\n *\n * @sealed\n * @alpha\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 * @alpha\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<any>,\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<any>\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<any>,\n\t\tTManager extends NotificationsManager<any>,\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 Presence}\n\t */\n\treadonly presence: Presence;\n}\n\n// #endregion NotificationsWorkspace\n\n/**\n * `AnyWorkspace` is a superset of {@link StatesWorkspace} and {@link NotificationsWorkspace}.\n *\n * @internal\n */\nexport interface AnyWorkspace<\n\tTSchema extends StatesWorkspaceSchema,\n\tTManagerConstraints = unknown,\n> extends StatesWorkspace<TSchema, TManagerConstraints> {\n\treadonly notifications: StatesWorkspaceEntries<TSchema>;\n}\n"]}
|