@fluidframework/presence 2.70.0 → 2.71.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.
@@ -3,6 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  import type { IFluidContainer } from "@fluidframework/fluid-static";
6
+ import type { IFluidDataStoreContext } from "@fluidframework/runtime-definitions/internal";
6
7
  import type { Presence, PresenceWithNotifications } from "./presence.js";
7
8
  /**
8
9
  * Acquire a {@link Presence} from a Fluid Container
@@ -20,4 +21,10 @@ export declare const getPresence: (fluidContainer: IFluidContainer) => Presence;
20
21
  * @alpha
21
22
  */
22
23
  export declare function getPresenceAlpha(fluidContainer: IFluidContainer): PresenceWithNotifications;
24
+ /**
25
+ * Get {@link Presence} from a Fluid Data Store Context
26
+ *
27
+ * @legacy @alpha
28
+ */
29
+ export declare function getPresenceFromDataStoreContext(context: IFluidDataStoreContext): Presence;
23
30
  //# sourceMappingURL=getPresence.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"getPresence.d.ts","sourceRoot":"","sources":["../src/getPresence.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAIpE,OAAO,KAAK,EAAE,QAAQ,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AA6CzE;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,EAAE,CAAC,cAAc,EAAE,eAAe,KAAK,QAA2B,CAAC;AAE3F;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,eAAe,GAAG,yBAAyB,CAW3F"}
1
+ {"version":3,"file":"getPresence.d.ts","sourceRoot":"","sources":["../src/getPresence.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE,OAAO,KAAK,EAGX,sBAAsB,EACtB,MAAM,8CAA8C,CAAC;AAItD,OAAO,KAAK,EAAE,QAAQ,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAuIzE;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,EAAE,CAAC,cAAc,EAAE,eAAe,KAAK,QAA2B,CAAC;AAE3F;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,eAAe,GAAG,yBAAyB,CAO3F;AAWD;;;;GAIG;AACH,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,sBAAsB,GAAG,QAAQ,CAGzF"}
@@ -4,15 +4,33 @@
4
4
  * Licensed under the MIT License.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.getPresenceAlpha = exports.getPresence = void 0;
7
+ exports.getPresenceFromDataStoreContext = exports.getPresenceAlpha = exports.getPresence = void 0;
8
8
  const internal_1 = require("@fluidframework/core-utils/internal");
9
9
  const internal_2 = require("@fluidframework/fluid-static/internal");
10
+ const packageVersion_js_1 = require("./packageVersion.js");
10
11
  const presenceManager_js_1 = require("./presenceManager.js");
12
+ const presenceCompatibility = {
13
+ generation: 1,
14
+ version: packageVersion_js_1.pkgVersion,
15
+ capabilities: new Set([]),
16
+ };
17
+ // Compatibility infrastructure was added in 2.71.0. Once version is bumped,
18
+ // this can be used to accept instances from 2.71.0 and newer (up to current).
19
+ // const minimalCompatiblePackageVersion = "2.71.0-0";
20
+ function assertCompatibilityInvariants(compatibility) {
21
+ (0, internal_1.assert)(compatibility.generation === presenceCompatibility.generation, 0xc97 /* Presence compatibility generation mismatch. */);
22
+ (0, internal_1.assert)(compatibility.version.startsWith("2."), 0xc98 /* Registered version is not major version 2. */);
23
+ (0, internal_1.assert)(Number.parseFloat(compatibility.version.slice(2)) <
24
+ Number.parseFloat(presenceCompatibility.version.slice(2)), 0xc99 /* Registered version is not less than the current version. */);
25
+ (0, internal_1.assert)(presenceCompatibility.capabilities.size === 0, 0xc9a /* Presence capabilities should be empty. */);
26
+ }
11
27
  /**
12
28
  * Common Presence manager for a container
13
29
  */
14
30
  class ContainerPresenceManager {
15
31
  constructor(host) {
32
+ // ContainerExtensionFactory return elements
33
+ this.compatibility = presenceCompatibility;
16
34
  this.extension = this;
17
35
  this.interface = this.manager = (0, presenceManager_js_1.createPresenceManager)({
18
36
  ...host,
@@ -21,6 +39,13 @@ class ContainerPresenceManager {
21
39
  },
22
40
  });
23
41
  }
42
+ handleVersionOrCapabilitiesMismatch(ourExistingInstantiation, newCompatibilityRequest) {
43
+ (0, internal_1.assert)(ourExistingInstantiation.compatibility === presenceCompatibility, 0xc9b /* Presence extension called without own compatibility details */);
44
+ assertCompatibilityInvariants(newCompatibilityRequest);
45
+ // There have not yet been any changes that would require action to upgrade.
46
+ // But also mixed runtime versions are not yet expected.
47
+ (0, internal_1.fail)("Presence is only expected to be accessed with a single version.");
48
+ }
24
49
  onNewUse() {
25
50
  // No-op
26
51
  }
@@ -28,7 +53,32 @@ class ContainerPresenceManager {
28
53
  this.manager.processSignal(addressChain, message, local);
29
54
  }
30
55
  }
31
- ContainerPresenceManager.extensionId = "dis:bb89f4c0-80fd-4f0c-8469-4f2848ee7f4a";
56
+ const extensionId = "dis:bb89f4c0-80fd-4f0c-8469-4f2848ee7f4a";
57
+ const ContainerPresenceFactory = {
58
+ hostRequirements: {
59
+ minSupportedGeneration: 1,
60
+ requiredFeatures: [],
61
+ },
62
+ instanceExpectations: presenceCompatibility,
63
+ resolvePriorInstantiation(existingInstantiation) {
64
+ // Validate assumptions about existing instance
65
+ assertCompatibilityInvariants(existingInstantiation.compatibility);
66
+ // There have not yet been any changes that would require action to upgrade.
67
+ // But also mixed runtime versions are not yet expected.
68
+ (0, internal_1.fail)("Presence is only expected to be accessed with a single version.");
69
+ },
70
+ instantiateExtension(host) {
71
+ return new ContainerPresenceManager(host);
72
+ },
73
+ [Symbol.hasInstance]: (instance) => {
74
+ return (instance instanceof ContainerPresenceManager
75
+ // typeof instance === "object" &&
76
+ // instance !== null &&
77
+ // "extension" in instance &&
78
+ // instance.extension instanceof ContainerPresenceManager
79
+ );
80
+ },
81
+ };
32
82
  /**
33
83
  * Acquire a {@link Presence} from a Fluid Container
34
84
  * @param fluidContainer - Fluid Container to acquire the map from
@@ -46,8 +96,21 @@ exports.getPresence = getPresenceAlpha;
46
96
  */
47
97
  function getPresenceAlpha(fluidContainer) {
48
98
  (0, internal_1.assert)((0, internal_2.isInternalFluidContainer)(fluidContainer), 0xa2f /* IFluidContainer was not recognized. Only Containers generated by the Fluid Framework are supported. */);
49
- const presence = fluidContainer.acquireExtension(ContainerPresenceManager.extensionId, ContainerPresenceManager);
99
+ const presence = fluidContainer.acquireExtension(extensionId, ContainerPresenceFactory);
50
100
  return presence;
51
101
  }
52
102
  exports.getPresenceAlpha = getPresenceAlpha;
103
+ function assertContextHasExtensionProvider(context) {
104
+ (0, internal_1.assert)("getExtension" in context, 0xc9c /* Data store context does not implement ContainerExtensionProvider */);
105
+ }
106
+ /**
107
+ * Get {@link Presence} from a Fluid Data Store Context
108
+ *
109
+ * @legacy @alpha
110
+ */
111
+ function getPresenceFromDataStoreContext(context) {
112
+ assertContextHasExtensionProvider(context);
113
+ return context.getExtension(extensionId, ContainerPresenceFactory);
114
+ }
115
+ exports.getPresenceFromDataStoreContext = getPresenceFromDataStoreContext;
53
116
  //# sourceMappingURL=getPresence.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"getPresence.js","sourceRoot":"","sources":["../src/getPresence.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAOH,kEAA6D;AAE7D,oEAAiF;AAKjF,6DAA6D;AAG7D;;GAEG;AACH,MAAM,wBAAwB;IAa7B,YAAmB,IAAmB;QAJtB,cAAS,GAAG,IAAI,CAAC;QAKhC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,OAAO,GAAG,IAAA,0CAAqB,EAAC;YACrD,GAAG,IAAI;YACP,YAAY,EAAE,CAAC,OAAO,EAAE,EAAE;gBACzB,IAAI,CAAC,qBAAqB,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;YACzC,CAAC;SACD,CAAC,CAAC;IACJ,CAAC;IAEM,QAAQ;QACd,QAAQ;IACT,CAAC;IAIM,aAAa,CACnB,YAAsB,EACtB,OAAgD,EAChD,KAAc;QAEd,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,YAAY,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IAC1D,CAAC;;AARsB,oCAAW,GAAG,0CAA0C,AAA7C,CAA8C;AAWjF;;;;;;GAMG;AACU,QAAA,WAAW,GAAkD,gBAAgB,CAAC;AAE3F;;;;;;GAMG;AACH,SAAgB,gBAAgB,CAAC,cAA+B;IAC/D,IAAA,iBAAM,EACL,IAAA,mCAAwB,EAAC,cAAc,CAAC,EACxC,KAAK,CAAC,yGAAyG,CAC/G,CAAC;IAEF,MAAM,QAAQ,GAAG,cAAc,CAAC,gBAAgB,CAC/C,wBAAwB,CAAC,WAAW,EACpC,wBAAwB,CACxB,CAAC;IACF,OAAO,QAAQ,CAAC;AACjB,CAAC;AAXD,4CAWC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type {\n\tContainerExtension,\n\tContainerExtensionFactory,\n\tInboundExtensionMessage,\n} from \"@fluidframework/container-runtime-definitions/internal\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport type { IFluidContainer } from \"@fluidframework/fluid-static\";\nimport { isInternalFluidContainer } from \"@fluidframework/fluid-static/internal\";\n\nimport type { ExtensionHost, ExtensionRuntimeProperties } from \"./internalTypes.js\";\nimport type { Presence, PresenceWithNotifications } from \"./presence.js\";\nimport type { PresenceExtensionInterface } from \"./presenceManager.js\";\nimport { createPresenceManager } from \"./presenceManager.js\";\nimport type { SignalMessages } from \"./protocol.js\";\n\n/**\n * Common Presence manager for a container\n */\nclass ContainerPresenceManager\n\timplements\n\t\tContainerExtension<ExtensionRuntimeProperties>,\n\t\tInstanceType<\n\t\t\tContainerExtensionFactory<PresenceWithNotifications, ExtensionRuntimeProperties>\n\t\t>\n{\n\t// ContainerExtensionFactory return elements\n\tpublic readonly interface: PresenceWithNotifications;\n\tpublic readonly extension = this;\n\n\tprivate readonly manager: PresenceExtensionInterface;\n\n\tpublic constructor(host: ExtensionHost) {\n\t\tthis.interface = this.manager = createPresenceManager({\n\t\t\t...host,\n\t\t\tsubmitSignal: (message) => {\n\t\t\t\thost.submitAddressedSignal([], message);\n\t\t\t},\n\t\t});\n\t}\n\n\tpublic onNewUse(): void {\n\t\t// No-op\n\t}\n\n\tpublic static readonly extensionId = \"dis:bb89f4c0-80fd-4f0c-8469-4f2848ee7f4a\";\n\n\tpublic processSignal(\n\t\taddressChain: string[],\n\t\tmessage: InboundExtensionMessage<SignalMessages>,\n\t\tlocal: boolean,\n\t): void {\n\t\tthis.manager.processSignal(addressChain, message, local);\n\t}\n}\n\n/**\n * Acquire a {@link Presence} from a Fluid Container\n * @param fluidContainer - Fluid Container to acquire the map from\n * @returns the {@link Presence}\n *\n * @beta\n */\nexport const getPresence: (fluidContainer: IFluidContainer) => Presence = getPresenceAlpha;\n\n/**\n * Acquire a {@link PresenceWithNotifications} from a Fluid Container\n * @param fluidContainer - Fluid Container to acquire the map from\n * @returns the {@link PresenceWithNotifications}\n *\n * @alpha\n */\nexport function getPresenceAlpha(fluidContainer: IFluidContainer): PresenceWithNotifications {\n\tassert(\n\t\tisInternalFluidContainer(fluidContainer),\n\t\t0xa2f /* IFluidContainer was not recognized. Only Containers generated by the Fluid Framework are supported. */,\n\t);\n\n\tconst presence = fluidContainer.acquireExtension(\n\t\tContainerPresenceManager.extensionId,\n\t\tContainerPresenceManager,\n\t);\n\treturn presence;\n}\n"]}
1
+ {"version":3,"file":"getPresence.js","sourceRoot":"","sources":["../src/getPresence.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 { ILayerCompatSupportRequirements } from \"@fluid-internal/client-utils\";\nimport type {\n\tContainerExtension,\n\tContainerExtensionFactory,\n\tExtensionInstantiationResult,\n\tExtensionRuntimeProperties as GenericExtensionRuntimeProperties,\n\tInboundExtensionMessage,\n} from \"@fluidframework/container-runtime-definitions/internal\";\nimport { assert, fail } from \"@fluidframework/core-utils/internal\";\nimport type { IFluidContainer } from \"@fluidframework/fluid-static\";\nimport { isInternalFluidContainer } from \"@fluidframework/fluid-static/internal\";\nimport type {\n\tExtensionCompatibilityDetails,\n\tFluidDataStoreContextInternal,\n\tIFluidDataStoreContext,\n} from \"@fluidframework/runtime-definitions/internal\";\n\nimport type { ExtensionHost, ExtensionRuntimeProperties } from \"./internalTypes.js\";\nimport { pkgVersion } from \"./packageVersion.js\";\nimport type { Presence, PresenceWithNotifications } from \"./presence.js\";\nimport type { PresenceExtensionInterface } from \"./presenceManager.js\";\nimport { createPresenceManager } from \"./presenceManager.js\";\nimport type { SignalMessages } from \"./protocol.js\";\n\nconst presenceCompatibility = {\n\tgeneration: 1,\n\tversion: pkgVersion,\n\tcapabilities: new Set([]),\n} as const satisfies ExtensionCompatibilityDetails;\n\n// Compatibility infrastructure was added in 2.71.0. Once version is bumped,\n// this can be used to accept instances from 2.71.0 and newer (up to current).\n// const minimalCompatiblePackageVersion = \"2.71.0-0\";\n\nfunction assertCompatibilityInvariants(compatibility: ExtensionCompatibilityDetails): void {\n\tassert(\n\t\tcompatibility.generation === presenceCompatibility.generation,\n\t\t0xc97 /* Presence compatibility generation mismatch. */,\n\t);\n\tassert(\n\t\tcompatibility.version.startsWith(\"2.\"),\n\t\t0xc98 /* Registered version is not major version 2. */,\n\t);\n\tassert(\n\t\tNumber.parseFloat(compatibility.version.slice(2)) <\n\t\t\tNumber.parseFloat(presenceCompatibility.version.slice(2)),\n\t\t0xc99 /* Registered version is not less than the current version. */,\n\t);\n\tassert(\n\t\tpresenceCompatibility.capabilities.size === 0,\n\t\t0xc9a /* Presence capabilities should be empty. */,\n\t);\n}\n\n/**\n * Common Presence manager for a container\n */\nclass ContainerPresenceManager\n\timplements\n\t\tContainerExtension<ExtensionRuntimeProperties>,\n\t\tReturnType<\n\t\t\tContainerExtensionFactory<\n\t\t\t\tPresenceWithNotifications,\n\t\t\t\tExtensionRuntimeProperties\n\t\t\t>[\"instantiateExtension\"]\n\t\t>\n{\n\t// ContainerExtensionFactory return elements\n\tpublic readonly compatibility = presenceCompatibility;\n\tpublic readonly interface: PresenceWithNotifications;\n\tpublic readonly extension = this;\n\n\tprivate readonly manager: PresenceExtensionInterface;\n\n\tpublic constructor(host: ExtensionHost) {\n\t\tthis.interface = this.manager = createPresenceManager({\n\t\t\t...host,\n\t\t\tsubmitSignal: (message) => {\n\t\t\t\thost.submitAddressedSignal([], message);\n\t\t\t},\n\t\t});\n\t}\n\n\tpublic handleVersionOrCapabilitiesMismatch<_TRequestedInterface>(\n\t\tourExistingInstantiation: Readonly<\n\t\t\tExtensionInstantiationResult<PresenceWithNotifications, ExtensionRuntimeProperties, []>\n\t\t>,\n\t\tnewCompatibilityRequest: ExtensionCompatibilityDetails,\n\t): never {\n\t\tassert(\n\t\t\tourExistingInstantiation.compatibility === presenceCompatibility,\n\t\t\t0xc9b /* Presence extension called without own compatibility details */,\n\t\t);\n\t\tassertCompatibilityInvariants(newCompatibilityRequest);\n\t\t// There have not yet been any changes that would require action to upgrade.\n\t\t// But also mixed runtime versions are not yet expected.\n\t\tfail(\"Presence is only expected to be accessed with a single version.\");\n\t}\n\n\tpublic onNewUse(): void {\n\t\t// No-op\n\t}\n\n\tpublic processSignal(\n\t\taddressChain: string[],\n\t\tmessage: InboundExtensionMessage<SignalMessages>,\n\t\tlocal: boolean,\n\t): void {\n\t\tthis.manager.processSignal(addressChain, message, local);\n\t}\n}\n\nconst extensionId = \"dis:bb89f4c0-80fd-4f0c-8469-4f2848ee7f4a\";\n\nconst ContainerPresenceFactory = {\n\thostRequirements: {\n\t\tminSupportedGeneration: 1,\n\t\trequiredFeatures: [],\n\t} as const satisfies ILayerCompatSupportRequirements,\n\n\tinstanceExpectations: presenceCompatibility,\n\n\tresolvePriorInstantiation(\n\t\texistingInstantiation: ExtensionInstantiationResult<\n\t\t\tunknown,\n\t\t\tGenericExtensionRuntimeProperties,\n\t\t\tunknown[]\n\t\t>,\n\t): never {\n\t\t// Validate assumptions about existing instance\n\t\tassertCompatibilityInvariants(existingInstantiation.compatibility);\n\t\t// There have not yet been any changes that would require action to upgrade.\n\t\t// But also mixed runtime versions are not yet expected.\n\t\tfail(\"Presence is only expected to be accessed with a single version.\");\n\t},\n\n\tinstantiateExtension(host: ExtensionHost): ContainerPresenceManager {\n\t\treturn new ContainerPresenceManager(host);\n\t},\n\n\t[Symbol.hasInstance]: (instance: unknown): instance is ContainerPresenceManager => {\n\t\treturn (\n\t\t\tinstance instanceof ContainerPresenceManager\n\t\t\t// typeof instance === \"object\" &&\n\t\t\t// instance !== null &&\n\t\t\t// \"extension\" in instance &&\n\t\t\t// instance.extension instanceof ContainerPresenceManager\n\t\t);\n\t},\n} as const satisfies ContainerExtensionFactory<\n\tPresenceWithNotifications,\n\tExtensionRuntimeProperties\n>;\n\n/**\n * Acquire a {@link Presence} from a Fluid Container\n * @param fluidContainer - Fluid Container to acquire the map from\n * @returns the {@link Presence}\n *\n * @beta\n */\nexport const getPresence: (fluidContainer: IFluidContainer) => Presence = getPresenceAlpha;\n\n/**\n * Acquire a {@link PresenceWithNotifications} from a Fluid Container\n * @param fluidContainer - Fluid Container to acquire the map from\n * @returns the {@link PresenceWithNotifications}\n *\n * @alpha\n */\nexport function getPresenceAlpha(fluidContainer: IFluidContainer): PresenceWithNotifications {\n\tassert(\n\t\tisInternalFluidContainer(fluidContainer),\n\t\t0xa2f /* IFluidContainer was not recognized. Only Containers generated by the Fluid Framework are supported. */,\n\t);\n\tconst presence = fluidContainer.acquireExtension(extensionId, ContainerPresenceFactory);\n\treturn presence;\n}\n\nfunction assertContextHasExtensionProvider(\n\tcontext: IFluidDataStoreContext,\n): asserts context is FluidDataStoreContextInternal {\n\tassert(\n\t\t\"getExtension\" in context,\n\t\t0xc9c /* Data store context does not implement ContainerExtensionProvider */,\n\t);\n}\n\n/**\n * Get {@link Presence} from a Fluid Data Store Context\n *\n * @legacy @alpha\n */\nexport function getPresenceFromDataStoreContext(context: IFluidDataStoreContext): Presence {\n\tassertContextHasExtensionProvider(context);\n\treturn context.getExtension(extensionId, ContainerPresenceFactory);\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -13,7 +13,7 @@ export type { ClientConnectionId } from "./baseTypes.js";
13
13
  export type { NotificationsWorkspace, NotificationsWorkspaceSchema, StatesWorkspace, StatesWorkspaceEntries, StatesWorkspaceSchema, StatesWorkspaceEntry, WorkspaceAddress, } from "./types.js";
14
14
  export { type Attendee, type AttendeesEvents, type AttendeeId, AttendeeStatus, type Presence, type PresenceEvents, type PresenceWithNotifications, } from "./presence.js";
15
15
  export type { BroadcastControls, BroadcastControlSettings, } from "./broadcastControls.js";
16
- export { getPresence, getPresenceAlpha } from "./getPresence.js";
16
+ export { getPresence, getPresenceAlpha, getPresenceFromDataStoreContext, } from "./getPresence.js";
17
17
  export { getPresenceViaDataObject, type ExperimentalPresenceDO, ExperimentalPresenceManager, } from "./datastorePresenceManagerFactory.js";
18
18
  export type { LatestMap, LatestMapArguments, LatestMapArgumentsRaw, LatestMapClientData, LatestMapEvents, LatestMapFactory, LatestMapItemRemovedClientData, LatestMapItemUpdatedClientData, LatestMapRaw, LatestMapRawEvents, StateMap, } from "./latestMapValueManager.js";
19
19
  export type { Latest, LatestArguments, LatestArgumentsRaw, LatestEvents, LatestFactory, LatestRaw, LatestRawEvents, } from "./latestValueManager.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;GAMG;AAEH,YAAY,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEzD,YAAY,EACX,sBAAsB,EACtB,4BAA4B,EAC5B,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACN,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,cAAc,EACd,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,yBAAyB,GAC9B,MAAM,eAAe,CAAC;AAEvB,YAAY,EACX,iBAAiB,EACjB,wBAAwB,GACxB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEjE,OAAO,EACN,wBAAwB,EACxB,KAAK,sBAAsB,EAC3B,2BAA2B,GAC3B,MAAM,sCAAsC,CAAC;AAE9C,YAAY,EACX,SAAS,EACT,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,8BAA8B,EAC9B,8BAA8B,EAC9B,YAAY,EACZ,kBAAkB,EAClB,QAAQ,GACR,MAAM,4BAA4B,CAAC;AACpC,YAAY,EACX,MAAM,EACN,eAAe,EACf,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,SAAS,EACT,eAAe,GACf,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACX,QAAQ,EACR,gBAAgB,EAChB,UAAU,EACV,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,GACb,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACN,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,yBAAyB,EAC9B,aAAa,EACb,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,GAC/B,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,YAAY,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,YAAY,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;GAMG;AAEH,YAAY,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEzD,YAAY,EACX,sBAAsB,EACtB,4BAA4B,EAC5B,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACN,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,cAAc,EACd,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,yBAAyB,GAC9B,MAAM,eAAe,CAAC;AAEvB,YAAY,EACX,iBAAiB,EACjB,wBAAwB,GACxB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACN,WAAW,EACX,gBAAgB,EAChB,+BAA+B,GAC/B,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACN,wBAAwB,EACxB,KAAK,sBAAsB,EAC3B,2BAA2B,GAC3B,MAAM,sCAAsC,CAAC;AAE9C,YAAY,EACX,SAAS,EACT,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,8BAA8B,EAC9B,8BAA8B,EAC9B,YAAY,EACZ,kBAAkB,EAClB,QAAQ,GACR,MAAM,4BAA4B,CAAC;AACpC,YAAY,EACX,MAAM,EACN,eAAe,EACf,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,SAAS,EACT,eAAe,GACf,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACX,QAAQ,EACR,gBAAgB,EAChB,UAAU,EACV,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,GACb,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACN,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,yBAAyB,EAC9B,aAAa,EACb,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,GAC/B,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,YAAY,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,YAAY,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC"}
package/dist/index.js CHANGED
@@ -4,12 +4,13 @@
4
4
  * Licensed under the MIT License.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.StateFactory = exports.Notifications = exports.ExperimentalPresenceManager = exports.getPresenceViaDataObject = exports.getPresenceAlpha = exports.getPresence = exports.AttendeeStatus = void 0;
7
+ exports.StateFactory = exports.Notifications = exports.ExperimentalPresenceManager = exports.getPresenceViaDataObject = exports.getPresenceFromDataStoreContext = exports.getPresenceAlpha = exports.getPresence = exports.AttendeeStatus = void 0;
8
8
  var presence_js_1 = require("./presence.js");
9
9
  Object.defineProperty(exports, "AttendeeStatus", { enumerable: true, get: function () { return presence_js_1.AttendeeStatus; } });
10
10
  var getPresence_js_1 = require("./getPresence.js");
11
11
  Object.defineProperty(exports, "getPresence", { enumerable: true, get: function () { return getPresence_js_1.getPresence; } });
12
12
  Object.defineProperty(exports, "getPresenceAlpha", { enumerable: true, get: function () { return getPresence_js_1.getPresenceAlpha; } });
13
+ Object.defineProperty(exports, "getPresenceFromDataStoreContext", { enumerable: true, get: function () { return getPresence_js_1.getPresenceFromDataStoreContext; } });
13
14
  var datastorePresenceManagerFactory_js_1 = require("./datastorePresenceManagerFactory.js");
14
15
  Object.defineProperty(exports, "getPresenceViaDataObject", { enumerable: true, get: function () { return datastorePresenceManagerFactory_js_1.getPresenceViaDataObject; } });
15
16
  Object.defineProperty(exports, "ExperimentalPresenceManager", { enumerable: true, get: function () { return datastorePresenceManagerFactory_js_1.ExperimentalPresenceManager; } });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAsBH,6CAQuB;AAJtB,6GAAA,cAAc,OAAA;AAWf,mDAAiE;AAAxD,6GAAA,WAAW,OAAA;AAAE,kHAAA,gBAAgB,OAAA;AAEtC,2FAI8C;AAH7C,8IAAA,wBAAwB,OAAA;AAExB,iJAAA,2BAA2B,OAAA;AAoC5B,qEAOmC;AAHlC,wHAAA,aAAa,OAAA;AAKd,qDAAiD;AAAxC,+GAAA,YAAY,OAAA","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * Package for client presence within a connected session.\n *\n * See {@link https://github.com/microsoft/FluidFramework/tree/main/packages/framework/presence#readme | README.md } for an overview of the package.\n *\n * @packageDocumentation\n */\n\nexport type { ClientConnectionId } from \"./baseTypes.js\";\n\nexport type {\n\tNotificationsWorkspace,\n\tNotificationsWorkspaceSchema,\n\tStatesWorkspace,\n\tStatesWorkspaceEntries,\n\tStatesWorkspaceSchema,\n\tStatesWorkspaceEntry,\n\tWorkspaceAddress,\n} from \"./types.js\";\n\nexport {\n\ttype Attendee,\n\ttype AttendeesEvents,\n\ttype AttendeeId,\n\tAttendeeStatus,\n\ttype Presence,\n\ttype PresenceEvents,\n\ttype PresenceWithNotifications,\n} from \"./presence.js\";\n\nexport type {\n\tBroadcastControls,\n\tBroadcastControlSettings,\n} from \"./broadcastControls.js\";\n\nexport { getPresence, getPresenceAlpha } from \"./getPresence.js\";\n\nexport {\n\tgetPresenceViaDataObject,\n\ttype ExperimentalPresenceDO,\n\tExperimentalPresenceManager,\n} from \"./datastorePresenceManagerFactory.js\";\n\nexport type {\n\tLatestMap,\n\tLatestMapArguments,\n\tLatestMapArgumentsRaw,\n\tLatestMapClientData,\n\tLatestMapEvents,\n\tLatestMapFactory,\n\tLatestMapItemRemovedClientData,\n\tLatestMapItemUpdatedClientData,\n\tLatestMapRaw,\n\tLatestMapRawEvents,\n\tStateMap,\n} from \"./latestMapValueManager.js\";\nexport type {\n\tLatest,\n\tLatestArguments,\n\tLatestArgumentsRaw,\n\tLatestEvents,\n\tLatestFactory,\n\tLatestRaw,\n\tLatestRawEvents,\n} from \"./latestValueManager.js\";\nexport type {\n\tAccessor,\n\tLatestClientData,\n\tLatestData,\n\tLatestMetadata,\n\tProxiedValueAccessor,\n\tRawValueAccessor,\n\tStateSchemaValidator,\n\tValueAccessor,\n} from \"./latestValueTypes.js\";\n\nexport {\n\ttype NotificationEmitter,\n\ttype NotificationListenable,\n\ttype NotificationSubscriptions,\n\tNotifications,\n\ttype NotificationsManager,\n\ttype NotificationsManagerEvents,\n} from \"./notificationsManager.js\";\n\nexport { StateFactory } from \"./stateFactory.js\";\n\nexport type { InternalTypes } from \"./exposedInternalTypes.js\";\nexport type { InternalUtilityTypes } from \"./exposedUtilityTypes.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAsBH,6CAQuB;AAJtB,6GAAA,cAAc,OAAA;AAWf,mDAI0B;AAHzB,6GAAA,WAAW,OAAA;AACX,kHAAA,gBAAgB,OAAA;AAChB,iIAAA,+BAA+B,OAAA;AAGhC,2FAI8C;AAH7C,8IAAA,wBAAwB,OAAA;AAExB,iJAAA,2BAA2B,OAAA;AAoC5B,qEAOmC;AAHlC,wHAAA,aAAa,OAAA;AAKd,qDAAiD;AAAxC,+GAAA,YAAY,OAAA","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * Package for client presence within a connected session.\n *\n * See {@link https://github.com/microsoft/FluidFramework/tree/main/packages/framework/presence#readme | README.md } for an overview of the package.\n *\n * @packageDocumentation\n */\n\nexport type { ClientConnectionId } from \"./baseTypes.js\";\n\nexport type {\n\tNotificationsWorkspace,\n\tNotificationsWorkspaceSchema,\n\tStatesWorkspace,\n\tStatesWorkspaceEntries,\n\tStatesWorkspaceSchema,\n\tStatesWorkspaceEntry,\n\tWorkspaceAddress,\n} from \"./types.js\";\n\nexport {\n\ttype Attendee,\n\ttype AttendeesEvents,\n\ttype AttendeeId,\n\tAttendeeStatus,\n\ttype Presence,\n\ttype PresenceEvents,\n\ttype PresenceWithNotifications,\n} from \"./presence.js\";\n\nexport type {\n\tBroadcastControls,\n\tBroadcastControlSettings,\n} from \"./broadcastControls.js\";\n\nexport {\n\tgetPresence,\n\tgetPresenceAlpha,\n\tgetPresenceFromDataStoreContext,\n} from \"./getPresence.js\";\n\nexport {\n\tgetPresenceViaDataObject,\n\ttype ExperimentalPresenceDO,\n\tExperimentalPresenceManager,\n} from \"./datastorePresenceManagerFactory.js\";\n\nexport type {\n\tLatestMap,\n\tLatestMapArguments,\n\tLatestMapArgumentsRaw,\n\tLatestMapClientData,\n\tLatestMapEvents,\n\tLatestMapFactory,\n\tLatestMapItemRemovedClientData,\n\tLatestMapItemUpdatedClientData,\n\tLatestMapRaw,\n\tLatestMapRawEvents,\n\tStateMap,\n} from \"./latestMapValueManager.js\";\nexport type {\n\tLatest,\n\tLatestArguments,\n\tLatestArgumentsRaw,\n\tLatestEvents,\n\tLatestFactory,\n\tLatestRaw,\n\tLatestRawEvents,\n} from \"./latestValueManager.js\";\nexport type {\n\tAccessor,\n\tLatestClientData,\n\tLatestData,\n\tLatestMetadata,\n\tProxiedValueAccessor,\n\tRawValueAccessor,\n\tStateSchemaValidator,\n\tValueAccessor,\n} from \"./latestValueTypes.js\";\n\nexport {\n\ttype NotificationEmitter,\n\ttype NotificationListenable,\n\ttype NotificationSubscriptions,\n\tNotifications,\n\ttype NotificationsManager,\n\ttype NotificationsManagerEvents,\n} from \"./notificationsManager.js\";\n\nexport { StateFactory } from \"./stateFactory.js\";\n\nexport type { InternalTypes } from \"./exposedInternalTypes.js\";\nexport type { InternalUtilityTypes } from \"./exposedUtilityTypes.js\";\n"]}
@@ -0,0 +1,86 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ /*
7
+ * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
8
+ * Generated by "flub generate entrypoints" in @fluid-tools/build-cli.
9
+ */
10
+
11
+ /**
12
+ * Package for client presence within a connected session.
13
+ *
14
+ * See {@link https://github.com/microsoft/FluidFramework/tree/main/packages/framework/presence#readme | README.md } for an overview of the package.
15
+ *
16
+ * @packageDocumentation
17
+ */
18
+
19
+ export {
20
+ // #region @beta APIs
21
+ Accessor,
22
+ Attendee,
23
+ AttendeeId,
24
+ AttendeeStatus,
25
+ AttendeesEvents,
26
+ BroadcastControlSettings,
27
+ BroadcastControls,
28
+ ClientConnectionId,
29
+ InternalTypes,
30
+ Latest,
31
+ LatestArguments,
32
+ LatestArgumentsRaw,
33
+ LatestClientData,
34
+ LatestData,
35
+ LatestEvents,
36
+ LatestFactory,
37
+ LatestMap,
38
+ LatestMapArguments,
39
+ LatestMapArgumentsRaw,
40
+ LatestMapClientData,
41
+ LatestMapEvents,
42
+ LatestMapFactory,
43
+ LatestMapItemRemovedClientData,
44
+ LatestMapItemUpdatedClientData,
45
+ LatestMapRaw,
46
+ LatestMapRawEvents,
47
+ LatestMetadata,
48
+ LatestRaw,
49
+ LatestRawEvents,
50
+ Presence,
51
+ PresenceEvents,
52
+ ProxiedValueAccessor,
53
+ RawValueAccessor,
54
+ StateFactory,
55
+ StateMap,
56
+ StateSchemaValidator,
57
+ StatesWorkspace,
58
+ StatesWorkspaceEntries,
59
+ StatesWorkspaceEntry,
60
+ StatesWorkspaceSchema,
61
+ ValueAccessor,
62
+ WorkspaceAddress,
63
+ getPresence,
64
+ // #endregion
65
+
66
+ // #region @alpha APIs
67
+ ExperimentalPresenceDO,
68
+ ExperimentalPresenceManager,
69
+ InternalUtilityTypes,
70
+ NotificationEmitter,
71
+ NotificationListenable,
72
+ NotificationSubscriptions,
73
+ Notifications,
74
+ NotificationsManager,
75
+ NotificationsManagerEvents,
76
+ NotificationsWorkspace,
77
+ NotificationsWorkspaceSchema,
78
+ PresenceWithNotifications,
79
+ getPresenceAlpha,
80
+ getPresenceViaDataObject,
81
+ // #endregion
82
+
83
+ // #region @legacyAlpha APIs
84
+ getPresenceFromDataStoreContext
85
+ // #endregion
86
+ } from "./index.js";
package/dist/package.json CHANGED
@@ -9,6 +9,10 @@
9
9
  "./alpha": {
10
10
  "types": "./alpha.d.ts",
11
11
  "default": "./index.js"
12
+ },
13
+ "./legacy/alpha": {
14
+ "types": "./legacy.alpha.d.ts",
15
+ "default": "./index.js"
12
16
  }
13
17
  }
14
18
  }
@@ -0,0 +1,9 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ *
5
+ * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
+ */
7
+ export declare const pkgName = "@fluidframework/presence";
8
+ export declare const pkgVersion = "2.71.0";
9
+ //# sourceMappingURL=packageVersion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,6BAA6B,CAAC;AAClD,eAAO,MAAM,UAAU,WAAW,CAAC"}
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ /*!
3
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
4
+ * Licensed under the MIT License.
5
+ *
6
+ * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.pkgVersion = exports.pkgName = void 0;
10
+ exports.pkgName = "@fluidframework/presence";
11
+ exports.pkgVersion = "2.71.0";
12
+ //# sourceMappingURL=packageVersion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,0BAA0B,CAAC;AACrC,QAAA,UAAU,GAAG,QAAQ,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/presence\";\nexport const pkgVersion = \"2.71.0\";\n"]}
@@ -71,6 +71,12 @@ export declare class PresenceDatastoreManagerImpl implements PresenceDatastoreMa
71
71
  private readonly sendMessageTimer;
72
72
  private readonly workspaces;
73
73
  private readonly targetedSignalSupport;
74
+ /**
75
+ * When defined, this client is not recognized in the session.
76
+ * Call when no longer caring about that condition. That way listeners are
77
+ * cleaned up.
78
+ */
79
+ private stopWaitingForSelfInAudience;
74
80
  /**
75
81
  * Tracks whether this client has complete snapshot level knowledge and
76
82
  * how that determination was reached.
@@ -102,8 +108,10 @@ export declare class PresenceDatastoreManagerImpl implements PresenceDatastoreMa
102
108
  */
103
109
  private readonly broadcastRequestsTimer;
104
110
  constructor(attendeeId: AttendeeId, runtime: IEphemeralRuntime, logger: ITelemetryLoggerExt | undefined, events: IEmitter<PresenceEvents>, presence: Presence, systemWorkspaceDatastore: SystemWorkspaceDatastore, systemWorkspace: AnyWorkspaceEntry<StatesWorkspaceSchema>);
105
- private getInteractiveMembersExcludingSelf;
106
- joinSession(selfClientId: ClientConnectionId): void;
111
+ private getAudienceInformation;
112
+ joinSession(selfClientId: ClientConnectionId, alternateProvider?: ClientConnectionId | undefined): void;
113
+ private listenForSelfInAudience;
114
+ private stopWaitingAndJoin;
107
115
  onDisconnected(): void;
108
116
  getWorkspace<TSchema extends StatesWorkspaceSchema>(internalWorkspaceAddress: InternalWorkspaceAddress, requestedContent: TSchema, controls?: BroadcastControlSettings): AnyWorkspace<TSchema>;
109
117
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"presenceDatastoreManager.d.ts","sourceRoot":"","sources":["../src/presenceDatastoreManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"presenceDatastoreManager.d.ts","sourceRoot":"","sources":["../src/presenceDatastoreManager.ts"],"names":[],"mappings":"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"}
@@ -134,13 +134,16 @@ class PresenceDatastoreManagerImpl {
134
134
  this.broadcastRequests.delete(clientId);
135
135
  });
136
136
  }
137
- getInteractiveMembersExcludingSelf(selfClientId) {
137
+ getAudienceInformation(selfClientId) {
138
138
  const audience = this.runtime.getAudience();
139
139
  const members = audience.getMembers();
140
140
  const all = new Set();
141
141
  const writers = new Set();
142
- // Remove self (if present)
143
- members.delete(selfClientId);
142
+ const selfPresent = members.has(selfClientId);
143
+ if (selfPresent) {
144
+ // Remove self
145
+ members.delete(selfClientId);
146
+ }
144
147
  // Gather interactive client IDs
145
148
  for (const [id, client] of members) {
146
149
  if (client.details.capabilities.interactive) {
@@ -151,22 +154,42 @@ class PresenceDatastoreManagerImpl {
151
154
  }
152
155
  }
153
156
  return {
154
- all,
155
- writers,
157
+ audience,
158
+ selfPresent,
159
+ interactiveMembersExcludingSelf: {
160
+ all,
161
+ writers,
162
+ },
156
163
  };
157
164
  }
158
- joinSession(selfClientId) {
159
- const interactiveMembersExcludingSelf = this.getInteractiveMembersExcludingSelf(selfClientId);
160
- // If there aren't any others connected, then this client must have
161
- // complete information.
162
- if (interactiveMembersExcludingSelf.all.size === 0) {
163
- this.reasonForCompleteSnapshot = "alone";
164
- // It would be possible to return at this time and skip ClientJoin
165
- // signal. Instead continue in case audience information is
166
- // inaccurate. This client might temporarily erroneously believe it
167
- // has complete information, but the other(s) should respond to
168
- // ClientJoin soon rectifying that and covering for bad incomplete
169
- // responses this client sent in the meantime.
165
+ joinSession(selfClientId, alternateProvider = undefined) {
166
+ // Before broadcasting the join message, check that there is at least
167
+ // one audience member present (self or another). This is useful to
168
+ // optimize join messages while not using targeted join responses.
169
+ // (We need at least one other to be able to elect them as update
170
+ // provider.)
171
+ // Lack of anyone likely means that this client is very freshly joined
172
+ // and has not received any Join Signals (type="join") from the service
173
+ // yet.
174
+ const { audience, selfPresent, interactiveMembersExcludingSelf } = this.getAudienceInformation(selfClientId);
175
+ if (interactiveMembersExcludingSelf.all.size === 0 && alternateProvider !== undefined) {
176
+ if (selfPresent) {
177
+ // If there aren't any members connected except self, then this client
178
+ // must have complete information.
179
+ this.reasonForCompleteSnapshot = "alone";
180
+ // It would be possible to return at this time and skip ClientJoin
181
+ // signal. Instead continue in case audience information is
182
+ // inaccurate. This client might temporarily erroneously believe it
183
+ // has complete information, but the other(s) should respond to
184
+ // ClientJoin soon rectifying that and covering for bad incomplete
185
+ // responses this client sent in the meantime.
186
+ }
187
+ else {
188
+ // No one is known. Not even self. Defer judgement on
189
+ // complete snapshot until at least self is known to be present.
190
+ this.listenForSelfInAudience(selfClientId, audience);
191
+ return;
192
+ }
170
193
  }
171
194
  // Broadcast join message to all clients
172
195
  // Select primary update providers
@@ -181,6 +204,9 @@ class PresenceDatastoreManagerImpl {
181
204
  if (updateProviders.length > 3) {
182
205
  updateProviders.length = 3;
183
206
  }
207
+ else if (updateProviders.length === 0 && alternateProvider !== undefined) {
208
+ updateProviders.push(alternateProvider);
209
+ }
184
210
  this.runtime.submitSignal({
185
211
  type: protocol_js_1.joinMessageType,
186
212
  content: {
@@ -197,11 +223,51 @@ class PresenceDatastoreManagerImpl {
197
223
  connectionId: selfClientId,
198
224
  // Empty updateProviders is indicative of join when alone.
199
225
  updateProviders: JSON.stringify(updateProviders),
226
+ // If false and providers is single entry, then join was probably forced.
227
+ selfPresent,
200
228
  },
201
229
  });
202
230
  }
231
+ listenForSelfInAudience(selfClientId, audience) {
232
+ this.logger?.sendTelemetryEvent({
233
+ eventName: "JoinDeferred",
234
+ details: {
235
+ attendeeId: this.attendeeId,
236
+ connectionId: selfClientId,
237
+ },
238
+ });
239
+ // Prepare to join once self audience member joins.
240
+ // Alternatively, processSignal may force a join when a presence
241
+ // signal is received even without audience members (assumes
242
+ // audience signals were lost).
243
+ const joinWhenSelfAudienceMemberAdded = (addedClientId) => {
244
+ if (addedClientId !== selfClientId) {
245
+ // Keep listening
246
+ return;
247
+ }
248
+ // No need to force here by providing alternate provider as self is
249
+ // now present.
250
+ // Do avoid forcing so that reasonForCompleteSnapshot is set correctly
251
+ // if no others have been added.
252
+ this.stopWaitingAndJoin(selfClientId, /* alternateProvider */ undefined);
253
+ };
254
+ audience.on("addMember", joinWhenSelfAudienceMemberAdded);
255
+ this.stopWaitingForSelfInAudience = () => {
256
+ audience.off("addMember", joinWhenSelfAudienceMemberAdded);
257
+ };
258
+ }
259
+ stopWaitingAndJoin(selfClientId, alternateProvider) {
260
+ this.stopWaitingForSelfInAudience?.();
261
+ this.stopWaitingForSelfInAudience = undefined;
262
+ // Confirm not currently disconnected
263
+ if (this.runtime.getJoinedStatus() !== "disconnected") {
264
+ this.joinSession(selfClientId, alternateProvider);
265
+ }
266
+ }
203
267
  onDisconnected() {
204
268
  delete this.reasonForCompleteSnapshot;
269
+ this.stopWaitingForSelfInAudience?.();
270
+ this.stopWaitingForSelfInAudience = undefined;
205
271
  }
206
272
  getWorkspace(internalWorkspaceAddress, requestedContent, controls) {
207
273
  const existing = this.workspaces.get(internalWorkspaceAddress);
@@ -435,6 +501,17 @@ class PresenceDatastoreManagerImpl {
435
501
  }
436
502
  const selfClientId = this.runtime.getClientId();
437
503
  (0, internal_1.assert)(selfClientId !== undefined, "Received signal without clientId");
504
+ // Check for undesired case of receiving a remote presence signal
505
+ // without having been alerted to self audience join. (Perhaps join
506
+ // signal was dropped.)
507
+ // In practice it is commonly observed that local signals can be
508
+ // returned ahead of audience join notification. So, it is reasonable
509
+ // to expect that audience join notification may be delayed until after
510
+ // other presence signals are received. One is enough to get things
511
+ // rolling.
512
+ if (this.stopWaitingForSelfInAudience !== undefined) {
513
+ this.stopWaitingAndJoin(selfClientId, /* alternateProvider */ message.clientId);
514
+ }
438
515
  const timeModifier = received -
439
516
  (this.averageLatency + message.content.avgLatency + message.content.sendTimestamp);
440
517
  const postUpdateActions = [];
@@ -605,8 +682,13 @@ class PresenceDatastoreManagerImpl {
605
682
  // Check if requestor count meets or exceeds count of other audience
606
683
  // members indicating that we effectively have a complete snapshot
607
684
  // (once the current message being processed is processed).
608
- const interactiveMembersExcludingSelf = this.getInteractiveMembersExcludingSelf(selfClientId);
609
- if (this.broadcastRequests.size >= interactiveMembersExcludingSelf.all.size) {
685
+ const { selfPresent, interactiveMembersExcludingSelf } = this.getAudienceInformation(selfClientId);
686
+ if (
687
+ // Self-present check is done to help ensure that audience
688
+ // information is accurate. If self is not present, audience
689
+ // information might be incomplete.
690
+ selfPresent &&
691
+ this.broadcastRequests.size >= interactiveMembersExcludingSelf.all.size) {
610
692
  // Note that no action is taken here specifically.
611
693
  // We want action to be queued so that it takes place after
612
694
  // current message is completely processed. All of the actions