@fluid-internal/presence-runtime 2.102.0 → 2.103.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/dist/packageVersion.d.ts +1 -1
  2. package/dist/packageVersion.js +1 -1
  3. package/dist/packageVersion.js.map +1 -1
  4. package/dist/runtime/extension/containerPresence.d.ts +1 -1
  5. package/dist/runtime/presenceDatastoreManager.d.ts +2 -2
  6. package/dist/runtime/presenceDatastoreManager.d.ts.map +1 -1
  7. package/dist/runtime/presenceDatastoreManager.js.map +1 -1
  8. package/dist/runtime/presenceManager.js.map +1 -1
  9. package/lib/packageVersion.d.ts +1 -1
  10. package/lib/packageVersion.js +1 -1
  11. package/lib/packageVersion.js.map +1 -1
  12. package/lib/runtime/extension/containerPresence.d.ts +1 -1
  13. package/lib/runtime/presenceDatastoreManager.d.ts +2 -2
  14. package/lib/runtime/presenceDatastoreManager.d.ts.map +1 -1
  15. package/lib/runtime/presenceDatastoreManager.js.map +1 -1
  16. package/lib/runtime/presenceManager.js.map +1 -1
  17. package/package.json +14 -14
  18. package/dist/runtime/test/presenceDatastoreManager.spec.js +0 -618
  19. package/dist/runtime/test/presenceDatastoreManager.spec.js.map +0 -1
  20. package/dist/runtime/test/presenceManager.spec.js +0 -651
  21. package/dist/runtime/test/presenceManager.spec.js.map +0 -1
  22. package/dist/states/test/batching.spec.js +0 -843
  23. package/dist/states/test/batching.spec.js.map +0 -1
  24. package/dist/states/test/broadcastControlsTests.js +0 -60
  25. package/dist/states/test/broadcastControlsTests.js.map +0 -1
  26. package/dist/states/test/eventing.spec.js +0 -576
  27. package/dist/states/test/eventing.spec.js.map +0 -1
  28. package/dist/states/test/latestMapValueManager.spec.js +0 -210
  29. package/dist/states/test/latestMapValueManager.spec.js.map +0 -1
  30. package/dist/states/test/latestValueManager.spec.js +0 -193
  31. package/dist/states/test/latestValueManager.spec.js.map +0 -1
  32. package/dist/states/test/mockEphemeralRuntime.js +0 -11
  33. package/dist/states/test/mockEphemeralRuntime.js.map +0 -1
  34. package/dist/states/test/notificationsManager.spec.js +0 -460
  35. package/dist/states/test/notificationsManager.spec.js.map +0 -1
  36. package/dist/states/test/presenceStates.spec.js +0 -73
  37. package/dist/states/test/presenceStates.spec.js.map +0 -1
  38. package/dist/states/test/schemaValidation/protocol.spec.js +0 -246
  39. package/dist/states/test/schemaValidation/protocol.spec.js.map +0 -1
  40. package/dist/states/test/schemaValidation/valueManagers.spec.js +0 -784
  41. package/dist/states/test/schemaValidation/valueManagers.spec.js.map +0 -1
  42. package/dist/states/test/testUtils.js +0 -21
  43. package/dist/states/test/testUtils.js.map +0 -1
  44. package/dist/test/mockEphemeralRuntime.js +0 -175
  45. package/dist/test/mockEphemeralRuntime.js.map +0 -1
  46. package/dist/test/testUtils.js +0 -262
  47. package/dist/test/testUtils.js.map +0 -1
  48. package/dist/test/utils/index.js +0 -27
  49. package/dist/test/utils/index.js.map +0 -1
  50. package/dist/utils/test/timerManager.spec.js +0 -93
  51. package/dist/utils/test/timerManager.spec.js.map +0 -1
  52. package/lib/runtime/test/presenceDatastoreManager.spec.js +0 -616
  53. package/lib/runtime/test/presenceDatastoreManager.spec.js.map +0 -1
  54. package/lib/runtime/test/presenceManager.spec.js +0 -649
  55. package/lib/runtime/test/presenceManager.spec.js.map +0 -1
  56. package/lib/states/test/batching.spec.js +0 -841
  57. package/lib/states/test/batching.spec.js.map +0 -1
  58. package/lib/states/test/broadcastControlsTests.js +0 -56
  59. package/lib/states/test/broadcastControlsTests.js.map +0 -1
  60. package/lib/states/test/eventing.spec.js +0 -574
  61. package/lib/states/test/eventing.spec.js.map +0 -1
  62. package/lib/states/test/latestMapValueManager.spec.js +0 -206
  63. package/lib/states/test/latestMapValueManager.spec.js.map +0 -1
  64. package/lib/states/test/latestValueManager.spec.js +0 -189
  65. package/lib/states/test/latestValueManager.spec.js.map +0 -1
  66. package/lib/states/test/mockEphemeralRuntime.js +0 -6
  67. package/lib/states/test/mockEphemeralRuntime.js.map +0 -1
  68. package/lib/states/test/notificationsManager.spec.js +0 -456
  69. package/lib/states/test/notificationsManager.spec.js.map +0 -1
  70. package/lib/states/test/presenceStates.spec.js +0 -69
  71. package/lib/states/test/presenceStates.spec.js.map +0 -1
  72. package/lib/states/test/schemaValidation/protocol.spec.js +0 -244
  73. package/lib/states/test/schemaValidation/protocol.spec.js.map +0 -1
  74. package/lib/states/test/schemaValidation/valueManagers.spec.js +0 -782
  75. package/lib/states/test/schemaValidation/valueManagers.spec.js.map +0 -1
  76. package/lib/states/test/testUtils.js +0 -6
  77. package/lib/states/test/testUtils.js.map +0 -1
  78. package/lib/test/mockEphemeralRuntime.js +0 -171
  79. package/lib/test/mockEphemeralRuntime.js.map +0 -1
  80. package/lib/test/testUtils.js +0 -251
  81. package/lib/test/testUtils.js.map +0 -1
  82. package/lib/test/utils/index.js +0 -8
  83. package/lib/test/utils/index.js.map +0 -1
  84. package/lib/utils/test/timerManager.spec.js +0 -91
  85. package/lib/utils/test/timerManager.spec.js.map +0 -1
@@ -1,246 +0,0 @@
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
- const node_assert_1 = require("node:assert");
8
- const internal_1 = require("@fluidframework/test-utils/internal");
9
- const mocha_1 = require("mocha");
10
- const sinon_1 = require("sinon");
11
- const test_1 = require("@fluid-internal/presence-runtime/internal/test");
12
- const states_1 = require("@fluid-internal/presence-runtime/states");
13
- const utils_1 = require("@fluid-internal/presence-runtime/utils");
14
- const mockEphemeralRuntime_js_1 = require("../mockEphemeralRuntime.js");
15
- const testUtils_js_1 = require("../testUtils.js");
16
- (0, mocha_1.describe)("Presence/States", () => {
17
- (0, mocha_1.describe)("Runtime schema validation", () => {
18
- const afterCleanUp = [];
19
- const initialTime = 500;
20
- const attendee1ValueRevisionTimestamp = 600;
21
- const testStartTime = 1010;
22
- let localAttendee1ValueRevisionTimestamp;
23
- let clock;
24
- let logger;
25
- let presence;
26
- let processSignal;
27
- let runtime;
28
- (0, mocha_1.before)(async () => {
29
- clock = (0, sinon_1.useFakeTimers)();
30
- });
31
- (0, mocha_1.beforeEach)(() => {
32
- logger = new internal_1.EventAndErrorTrackingLogger();
33
- runtime = new mockEphemeralRuntime_js_1.MockEphemeralRuntime(logger);
34
- clock.setSystemTime(initialTime);
35
- let localAvgLatency;
36
- ({ presence, processSignal, localAvgLatency } = (0, testUtils_js_1.prepareConnectedPresence)(runtime, testUtils_js_1.localAttendeeId, testUtils_js_1.initialLocalClientConnectionId, clock, logger));
37
- // Note that while the initialTime was set to 500, the prepareConnectedPresence call advances
38
- // it. Set a consistent start time for all tests.
39
- const deltaToStart = testStartTime - clock.now;
40
- (0, node_assert_1.strict)(deltaToStart >= 10);
41
- clock.tick(deltaToStart - 10);
42
- // Process remote client update signal (attendeeId-1 is then part of local client's known session).
43
- const attendee1UpdateSendTimestamp = deltaToStart - 20;
44
- const attendee1AvgLatency = 20;
45
- const attendee1ToLocalTimeDelta = clock.now - (localAvgLatency + attendee1AvgLatency + attendee1UpdateSendTimestamp);
46
- localAttendee1ValueRevisionTimestamp =
47
- attendee1ValueRevisionTimestamp + attendee1ToLocalTimeDelta;
48
- processSignal([], {
49
- type: "Pres:DatastoreUpdate",
50
- content: {
51
- sendTimestamp: attendee1UpdateSendTimestamp,
52
- avgLatency: attendee1AvgLatency,
53
- data: {
54
- "system:presence": {
55
- "clientToSessionId": {
56
- "client1": {
57
- "rev": 0,
58
- "timestamp": initialTime + 40,
59
- "value": testUtils_js_1.attendeeId1,
60
- },
61
- },
62
- },
63
- "s:name:testWorkspace": {
64
- "latest": {
65
- [testUtils_js_1.attendeeId1]: {
66
- "rev": 1,
67
- "timestamp": attendee1ValueRevisionTimestamp,
68
- "value": (0, utils_1.toOpaqueJson)({ x: 1, y: 1, z: 1 }),
69
- },
70
- },
71
- "latestMap": {
72
- [testUtils_js_1.attendeeId1]: {
73
- "rev": 1,
74
- "items": {
75
- "key1": {
76
- "rev": 1,
77
- "timestamp": attendee1ValueRevisionTimestamp,
78
- "value": (0, utils_1.toOpaqueJson)({ a: 1, b: 1 }),
79
- },
80
- "key2": {
81
- "rev": 1,
82
- "timestamp": attendee1ValueRevisionTimestamp,
83
- // out of schema value
84
- "value": (0, utils_1.toOpaqueJson)({ b: 1, d: 1 }),
85
- },
86
- },
87
- },
88
- },
89
- },
90
- },
91
- },
92
- clientId: "client1",
93
- }, false);
94
- // Pass a little time (to mimic reality)
95
- clock.tick(10);
96
- });
97
- (0, mocha_1.afterEach)(function (done) {
98
- clock.reset();
99
- // If the test passed so far, check final expectations.
100
- if (this.currentTest?.state === "passed") {
101
- (0, testUtils_js_1.assertFinalExpectations)(runtime, logger);
102
- }
103
- for (const cleanUp of afterCleanUp) {
104
- cleanUp();
105
- }
106
- afterCleanUp.length = 0;
107
- done();
108
- });
109
- (0, mocha_1.after)(() => {
110
- clock.restore();
111
- });
112
- (0, mocha_1.describe)("response to Join signal", () => {
113
- (0, mocha_1.it)("does not contain validation metadata for remote clients", () => {
114
- // Setup
115
- // Check Join response without active validators
116
- const attendeeId4 = (0, testUtils_js_1.createSpecificAttendeeId)("attendeeId-4");
117
- const connectionId4 = "client4";
118
- const client4JoinTime = clock.now - 50;
119
- const newAttendeeSignal = (0, testUtils_js_1.generateBasicClientJoin)(client4JoinTime, {
120
- averageLatency: 50,
121
- attendeeId: attendeeId4,
122
- clientConnectionId: connectionId4,
123
- updateProviders: [testUtils_js_1.initialLocalClientConnectionId],
124
- });
125
- const expectedSetupJoinResponse = {
126
- type: "Pres:DatastoreUpdate",
127
- content: {
128
- "avgLatency": 10,
129
- "data": {
130
- "system:presence": {
131
- "clientToSessionId": {
132
- [testUtils_js_1.initialLocalClientConnectionId]: {
133
- "rev": 0,
134
- "timestamp": initialTime,
135
- "value": testUtils_js_1.localAttendeeId,
136
- },
137
- [testUtils_js_1.connectionId1]: {
138
- "rev": 0,
139
- "timestamp": initialTime + 40,
140
- "value": testUtils_js_1.attendeeId1,
141
- },
142
- [connectionId4]: {
143
- "rev": 0,
144
- "timestamp": client4JoinTime,
145
- "value": attendeeId4,
146
- },
147
- },
148
- },
149
- "s:name:testWorkspace": {
150
- "latest": {
151
- [testUtils_js_1.attendeeId1]: {
152
- "rev": 1,
153
- "timestamp": localAttendee1ValueRevisionTimestamp,
154
- "value": (0, utils_1.toOpaqueJson)({ x: 1, y: 1, z: 1 }),
155
- },
156
- },
157
- "latestMap": {
158
- [testUtils_js_1.attendeeId1]: {
159
- "rev": 1,
160
- "items": {
161
- "key1": {
162
- "rev": 1,
163
- "timestamp": localAttendee1ValueRevisionTimestamp,
164
- "value": (0, utils_1.toOpaqueJson)({ a: 1, b: 1 }),
165
- },
166
- "key2": {
167
- "rev": 1,
168
- "timestamp": localAttendee1ValueRevisionTimestamp,
169
- "value": (0, utils_1.toOpaqueJson)({ b: 1, d: 1 }),
170
- },
171
- },
172
- },
173
- },
174
- },
175
- },
176
- "isComplete": true,
177
- "joinResponseFor": [connectionId4],
178
- "sendTimestamp": clock.now + test_1.broadcastJoinResponseDelaysMs.namedResponder,
179
- },
180
- };
181
- {
182
- runtime.signalsExpected.push([expectedSetupJoinResponse]);
183
- processSignal([], newAttendeeSignal, false);
184
- clock.tick(test_1.broadcastJoinResponseDelaysMs.namedResponder);
185
- }
186
- // Pass a little time (to distinguish between signals)
187
- clock.tick(10);
188
- // Create State objects with validators
189
- const workspaceSetupTime = clock.now;
190
- const point3DValidatorFunction = (0, testUtils_js_1.createSpiedValidator)((d) => {
191
- return typeof d === "object" ? d : undefined;
192
- });
193
- const statesWorkspace = presence.states.getWorkspace("name:testWorkspace", {
194
- latest: states_1.StateFactory.latest({
195
- local: { x: 0, y: 0, z: 0 },
196
- validator: point3DValidatorFunction,
197
- settings: {
198
- // To prevent sending messages ahead of full broadcast from
199
- // join below, set the allowable latency to twice expected
200
- // join response time.
201
- allowableUpdateLatencyMs: 2 * test_1.broadcastJoinResponseDelaysMs.namedResponder,
202
- },
203
- }),
204
- });
205
- const latest = statesWorkspace.states.latest;
206
- const attendee1 = presence.attendees.getAttendee(testUtils_js_1.attendeeId1);
207
- latest.getRemote(attendee1)?.value();
208
- const originalJoinResponseData = expectedSetupJoinResponse.content.data;
209
- const expectedJoinResponse = {
210
- type: "Pres:DatastoreUpdate",
211
- content: {
212
- "avgLatency": 10,
213
- "data": {
214
- "system:presence": {
215
- "clientToSessionId": {
216
- ...originalJoinResponseData["system:presence"].clientToSessionId,
217
- },
218
- },
219
- "s:name:testWorkspace": {
220
- "latest": {
221
- ...originalJoinResponseData["s:name:testWorkspace"].latest,
222
- [testUtils_js_1.localAttendeeId]: {
223
- "rev": 0,
224
- "timestamp": workspaceSetupTime,
225
- "value": (0, utils_1.toOpaqueJson)({ x: 0, y: 0, z: 0 }),
226
- },
227
- },
228
- "latestMap": {
229
- ...originalJoinResponseData["s:name:testWorkspace"].latestMap,
230
- },
231
- },
232
- },
233
- "isComplete": true,
234
- "joinResponseFor": [connectionId4],
235
- "sendTimestamp": clock.now + test_1.broadcastJoinResponseDelaysMs.namedResponder,
236
- },
237
- };
238
- runtime.signalsExpected.push([expectedJoinResponse]);
239
- // Act & Verify - resend new attendee Join signal
240
- processSignal([], newAttendeeSignal, false);
241
- clock.tick(test_1.broadcastJoinResponseDelaysMs.namedResponder);
242
- });
243
- });
244
- });
245
- });
246
- //# sourceMappingURL=protocol.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"protocol.spec.js","sourceRoot":"","sources":["../../../../src/states/test/schemaValidation/protocol.spec.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 { strict as assert } from \"node:assert\";\n\nimport type { PresenceWithNotifications } from \"@fluid-internal/presence-definitions\";\nimport { EventAndErrorTrackingLogger } from \"@fluidframework/test-utils/internal\";\nimport { describe, it, after, afterEach, before, beforeEach } from \"mocha\";\nimport { useFakeTimers, type SinonFakeTimers } from \"sinon\";\n\nimport type { OutboundDatastoreUpdateMessage } from \"@fluid-internal/presence-runtime/internal/test\";\nimport { broadcastJoinResponseDelaysMs } from \"@fluid-internal/presence-runtime/internal/test\";\nimport { StateFactory } from \"@fluid-internal/presence-runtime/states\";\nimport { toOpaqueJson } from \"@fluid-internal/presence-runtime/utils\";\n\nimport { MockEphemeralRuntime } from \"../mockEphemeralRuntime.js\";\nimport type { ProcessSignalFunction } from \"../testUtils.js\";\nimport {\n\tassertFinalExpectations,\n\tattendeeId1,\n\tlocalAttendeeId,\n\tconnectionId1,\n\tinitialLocalClientConnectionId,\n\tcreateSpecificAttendeeId,\n\tcreateSpiedValidator,\n\tgenerateBasicClientJoin,\n\tprepareConnectedPresence,\n} from \"../testUtils.js\";\n\n/**\n * Workspace updates\n */\ninterface Point3D {\n\tx: number;\n\ty: number;\n\tz: number;\n}\n\ndescribe(\"Presence/States\", () => {\n\tdescribe(\"Runtime schema validation\", () => {\n\t\tconst afterCleanUp: (() => void)[] = [];\n\t\tconst initialTime = 500;\n\t\tconst attendee1ValueRevisionTimestamp = 600;\n\t\tconst testStartTime = 1010;\n\t\tlet localAttendee1ValueRevisionTimestamp: number;\n\n\t\tlet clock: SinonFakeTimers;\n\t\tlet logger: EventAndErrorTrackingLogger;\n\t\tlet presence: PresenceWithNotifications;\n\t\tlet processSignal: ProcessSignalFunction;\n\t\tlet runtime: MockEphemeralRuntime;\n\n\t\tbefore(async () => {\n\t\t\tclock = useFakeTimers();\n\t\t});\n\n\t\tbeforeEach(() => {\n\t\t\tlogger = new EventAndErrorTrackingLogger();\n\t\t\truntime = new MockEphemeralRuntime(logger);\n\t\t\tclock.setSystemTime(initialTime);\n\n\t\t\tlet localAvgLatency: number;\n\t\t\t({ presence, processSignal, localAvgLatency } = prepareConnectedPresence(\n\t\t\t\truntime,\n\t\t\t\tlocalAttendeeId,\n\t\t\t\tinitialLocalClientConnectionId,\n\t\t\t\tclock,\n\t\t\t\tlogger,\n\t\t\t));\n\n\t\t\t// Note that while the initialTime was set to 500, the prepareConnectedPresence call advances\n\t\t\t// it. Set a consistent start time for all tests.\n\t\t\tconst deltaToStart = testStartTime - clock.now;\n\t\t\tassert(deltaToStart >= 10);\n\t\t\tclock.tick(deltaToStart - 10);\n\n\t\t\t// Process remote client update signal (attendeeId-1 is then part of local client's known session).\n\t\t\tconst attendee1UpdateSendTimestamp = deltaToStart - 20;\n\t\t\tconst attendee1AvgLatency = 20;\n\t\t\tconst attendee1ToLocalTimeDelta =\n\t\t\t\tclock.now - (localAvgLatency + attendee1AvgLatency + attendee1UpdateSendTimestamp);\n\t\t\tlocalAttendee1ValueRevisionTimestamp =\n\t\t\t\tattendee1ValueRevisionTimestamp + attendee1ToLocalTimeDelta;\n\t\t\tprocessSignal(\n\t\t\t\t[],\n\t\t\t\t{\n\t\t\t\t\ttype: \"Pres:DatastoreUpdate\",\n\t\t\t\t\tcontent: {\n\t\t\t\t\t\tsendTimestamp: attendee1UpdateSendTimestamp,\n\t\t\t\t\t\tavgLatency: attendee1AvgLatency,\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\"system:presence\": {\n\t\t\t\t\t\t\t\t\"clientToSessionId\": {\n\t\t\t\t\t\t\t\t\t\"client1\": {\n\t\t\t\t\t\t\t\t\t\t\"rev\": 0,\n\t\t\t\t\t\t\t\t\t\t\"timestamp\": initialTime + 40,\n\t\t\t\t\t\t\t\t\t\t\"value\": attendeeId1,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"s:name:testWorkspace\": {\n\t\t\t\t\t\t\t\t\"latest\": {\n\t\t\t\t\t\t\t\t\t[attendeeId1]: {\n\t\t\t\t\t\t\t\t\t\t\"rev\": 1,\n\t\t\t\t\t\t\t\t\t\t\"timestamp\": attendee1ValueRevisionTimestamp,\n\t\t\t\t\t\t\t\t\t\t\"value\": toOpaqueJson({ x: 1, y: 1, z: 1 }),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"latestMap\": {\n\t\t\t\t\t\t\t\t\t[attendeeId1]: {\n\t\t\t\t\t\t\t\t\t\t\"rev\": 1,\n\t\t\t\t\t\t\t\t\t\t\"items\": {\n\t\t\t\t\t\t\t\t\t\t\t\"key1\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"rev\": 1,\n\t\t\t\t\t\t\t\t\t\t\t\t\"timestamp\": attendee1ValueRevisionTimestamp,\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": toOpaqueJson({ a: 1, b: 1 }),\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"key2\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"rev\": 1,\n\t\t\t\t\t\t\t\t\t\t\t\t\"timestamp\": attendee1ValueRevisionTimestamp,\n\t\t\t\t\t\t\t\t\t\t\t\t// out of schema value\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": toOpaqueJson({ b: 1, d: 1 }),\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tclientId: \"client1\",\n\t\t\t\t},\n\t\t\t\tfalse,\n\t\t\t);\n\n\t\t\t// Pass a little time (to mimic reality)\n\t\t\tclock.tick(10);\n\t\t});\n\n\t\tafterEach(function (done: Mocha.Done) {\n\t\t\tclock.reset();\n\n\t\t\t// If the test passed so far, check final expectations.\n\t\t\tif (this.currentTest?.state === \"passed\") {\n\t\t\t\tassertFinalExpectations(runtime, logger);\n\t\t\t}\n\n\t\t\tfor (const cleanUp of afterCleanUp) {\n\t\t\t\tcleanUp();\n\t\t\t}\n\t\t\tafterCleanUp.length = 0;\n\t\t\tdone();\n\t\t});\n\n\t\tafter(() => {\n\t\t\tclock.restore();\n\t\t});\n\n\t\tdescribe(\"response to Join signal\", () => {\n\t\t\tit(\"does not contain validation metadata for remote clients\", () => {\n\t\t\t\t// Setup\n\n\t\t\t\t// Check Join response without active validators\n\t\t\t\tconst attendeeId4 = createSpecificAttendeeId(\"attendeeId-4\");\n\t\t\t\tconst connectionId4 = \"client4\";\n\t\t\t\tconst client4JoinTime = clock.now - 50;\n\t\t\t\tconst newAttendeeSignal = generateBasicClientJoin(client4JoinTime, {\n\t\t\t\t\taverageLatency: 50,\n\t\t\t\t\tattendeeId: attendeeId4,\n\t\t\t\t\tclientConnectionId: connectionId4,\n\t\t\t\t\tupdateProviders: [initialLocalClientConnectionId],\n\t\t\t\t});\n\t\t\t\tconst expectedSetupJoinResponse = {\n\t\t\t\t\ttype: \"Pres:DatastoreUpdate\",\n\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\"avgLatency\": 10,\n\t\t\t\t\t\t\"data\": {\n\t\t\t\t\t\t\t\"system:presence\": {\n\t\t\t\t\t\t\t\t\"clientToSessionId\": {\n\t\t\t\t\t\t\t\t\t[initialLocalClientConnectionId]: {\n\t\t\t\t\t\t\t\t\t\t\"rev\": 0,\n\t\t\t\t\t\t\t\t\t\t\"timestamp\": initialTime,\n\t\t\t\t\t\t\t\t\t\t\"value\": localAttendeeId,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t[connectionId1]: {\n\t\t\t\t\t\t\t\t\t\t\"rev\": 0,\n\t\t\t\t\t\t\t\t\t\t\"timestamp\": initialTime + 40,\n\t\t\t\t\t\t\t\t\t\t\"value\": attendeeId1,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t[connectionId4]: {\n\t\t\t\t\t\t\t\t\t\t\"rev\": 0,\n\t\t\t\t\t\t\t\t\t\t\"timestamp\": client4JoinTime,\n\t\t\t\t\t\t\t\t\t\t\"value\": attendeeId4,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"s:name:testWorkspace\": {\n\t\t\t\t\t\t\t\t\"latest\": {\n\t\t\t\t\t\t\t\t\t[attendeeId1]: {\n\t\t\t\t\t\t\t\t\t\t\"rev\": 1,\n\t\t\t\t\t\t\t\t\t\t\"timestamp\": localAttendee1ValueRevisionTimestamp,\n\t\t\t\t\t\t\t\t\t\t\"value\": toOpaqueJson({ x: 1, y: 1, z: 1 }),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"latestMap\": {\n\t\t\t\t\t\t\t\t\t[attendeeId1]: {\n\t\t\t\t\t\t\t\t\t\t\"rev\": 1,\n\t\t\t\t\t\t\t\t\t\t\"items\": {\n\t\t\t\t\t\t\t\t\t\t\t\"key1\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"rev\": 1,\n\t\t\t\t\t\t\t\t\t\t\t\t\"timestamp\": localAttendee1ValueRevisionTimestamp,\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": toOpaqueJson({ a: 1, b: 1 }),\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"key2\": {\n\t\t\t\t\t\t\t\t\t\t\t\t\"rev\": 1,\n\t\t\t\t\t\t\t\t\t\t\t\t\"timestamp\": localAttendee1ValueRevisionTimestamp,\n\t\t\t\t\t\t\t\t\t\t\t\t\"value\": toOpaqueJson({ b: 1, d: 1 }),\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"isComplete\": true,\n\t\t\t\t\t\t\"joinResponseFor\": [connectionId4],\n\t\t\t\t\t\t\"sendTimestamp\": clock.now + broadcastJoinResponseDelaysMs.namedResponder,\n\t\t\t\t\t},\n\t\t\t\t} as const satisfies OutboundDatastoreUpdateMessage;\n\t\t\t\t{\n\t\t\t\t\truntime.signalsExpected.push([expectedSetupJoinResponse]);\n\t\t\t\t\tprocessSignal([], newAttendeeSignal, false);\n\t\t\t\t\tclock.tick(broadcastJoinResponseDelaysMs.namedResponder);\n\t\t\t\t}\n\t\t\t\t// Pass a little time (to distinguish between signals)\n\t\t\t\tclock.tick(10);\n\n\t\t\t\t// Create State objects with validators\n\t\t\t\tconst workspaceSetupTime = clock.now;\n\t\t\t\tconst point3DValidatorFunction = createSpiedValidator<Point3D>((d: unknown) => {\n\t\t\t\t\treturn typeof d === \"object\" ? (d as Point3D) : undefined;\n\t\t\t\t});\n\t\t\t\tconst statesWorkspace = presence.states.getWorkspace(\"name:testWorkspace\", {\n\t\t\t\t\tlatest: StateFactory.latest({\n\t\t\t\t\t\tlocal: { x: 0, y: 0, z: 0 },\n\t\t\t\t\t\tvalidator: point3DValidatorFunction,\n\t\t\t\t\t\tsettings: {\n\t\t\t\t\t\t\t// To prevent sending messages ahead of full broadcast from\n\t\t\t\t\t\t\t// join below, set the allowable latency to twice expected\n\t\t\t\t\t\t\t// join response time.\n\t\t\t\t\t\t\tallowableUpdateLatencyMs: 2 * broadcastJoinResponseDelaysMs.namedResponder,\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t\tconst latest = statesWorkspace.states.latest;\n\t\t\t\tconst attendee1 = presence.attendees.getAttendee(attendeeId1);\n\n\t\t\t\tlatest.getRemote(attendee1)?.value();\n\n\t\t\t\tconst originalJoinResponseData = expectedSetupJoinResponse.content.data;\n\t\t\t\tconst expectedJoinResponse = {\n\t\t\t\t\ttype: \"Pres:DatastoreUpdate\",\n\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\"avgLatency\": 10,\n\t\t\t\t\t\t\"data\": {\n\t\t\t\t\t\t\t\"system:presence\": {\n\t\t\t\t\t\t\t\t\"clientToSessionId\": {\n\t\t\t\t\t\t\t\t\t...originalJoinResponseData[\"system:presence\"].clientToSessionId,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"s:name:testWorkspace\": {\n\t\t\t\t\t\t\t\t\"latest\": {\n\t\t\t\t\t\t\t\t\t...originalJoinResponseData[\"s:name:testWorkspace\"].latest,\n\t\t\t\t\t\t\t\t\t[localAttendeeId]: {\n\t\t\t\t\t\t\t\t\t\t\"rev\": 0,\n\t\t\t\t\t\t\t\t\t\t\"timestamp\": workspaceSetupTime,\n\t\t\t\t\t\t\t\t\t\t\"value\": toOpaqueJson({ x: 0, y: 0, z: 0 }),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"latestMap\": {\n\t\t\t\t\t\t\t\t\t...originalJoinResponseData[\"s:name:testWorkspace\"].latestMap,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"isComplete\": true,\n\t\t\t\t\t\t\"joinResponseFor\": [connectionId4],\n\t\t\t\t\t\t\"sendTimestamp\": clock.now + broadcastJoinResponseDelaysMs.namedResponder,\n\t\t\t\t\t},\n\t\t\t\t} as const satisfies OutboundDatastoreUpdateMessage;\n\t\t\t\truntime.signalsExpected.push([expectedJoinResponse]);\n\n\t\t\t\t// Act & Verify - resend new attendee Join signal\n\t\t\t\tprocessSignal([], newAttendeeSignal, false);\n\t\t\t\tclock.tick(broadcastJoinResponseDelaysMs.namedResponder);\n\t\t\t});\n\t\t});\n\t});\n});\n"]}