@fluid-internal/presence-runtime 2.101.1 → 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 +0,0 @@
1
- {"version":3,"file":"eventing.spec.js","sourceRoot":"","sources":["../../../src/states/test/eventing.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 {\n\tAttendee,\n\tLatestMapRaw,\n\tLatestRaw,\n\tNotificationsManager,\n\tPresenceWithNotifications,\n\tWorkspaceAddress,\n} from \"@fluid-internal/presence-definitions\";\nimport { EventAndErrorTrackingLogger } from \"@fluidframework/test-utils/internal\";\nimport type { SinonFakeTimers, SinonSpy } from \"sinon\";\nimport { useFakeTimers, spy } from \"sinon\";\n\nimport type {\n\tGeneralDatastoreMessageContent,\n\tInternalWorkspaceAddress,\n} from \"@fluid-internal/presence-runtime/internal/test\";\nimport { Notifications, 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\tprepareConnectedPresence,\n\tattendeeId1,\n\tlocalAttendeeId,\n\tinitialLocalClientConnectionId,\n} from \"./testUtils.js\";\n\nconst datastoreUpdateType = \"Pres:DatastoreUpdate\";\n\ntype StatesObjectUpdateContent = GeneralDatastoreMessageContent[InternalWorkspaceAddress];\n/**\n * Workspace updates\n */\nconst attendeeUpdate = {\n\t\"clientToSessionId\": {\n\t\t\"client1\": {\n\t\t\t\"rev\": 0,\n\t\t\t\"timestamp\": 0,\n\t\t\t\"value\": attendeeId1,\n\t\t},\n\t},\n} as const;\nconst latestUpdate = {\n\t\"latest\": {\n\t\t[attendeeId1]: {\n\t\t\t\"rev\": 1,\n\t\t\t\"timestamp\": 0,\n\t\t\t\"value\": toOpaqueJson({ x: 1, y: 1, z: 1 }),\n\t\t},\n\t},\n} as const satisfies StatesObjectUpdateContent;\nconst latestMapUpdate = {\n\t\"latestMap\": {\n\t\t[attendeeId1]: {\n\t\t\t\"rev\": 1,\n\t\t\t\"items\": {\n\t\t\t\t\"key1\": {\n\t\t\t\t\t\"rev\": 1,\n\t\t\t\t\t\"timestamp\": 0,\n\t\t\t\t\t\"value\": toOpaqueJson({ a: 1, b: 1 }),\n\t\t\t\t},\n\t\t\t\t\"key2\": {\n\t\t\t\t\t\"rev\": 1,\n\t\t\t\t\t\"timestamp\": 0,\n\t\t\t\t\t\"value\": toOpaqueJson({ c: 1, d: 1 }),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t},\n} as const satisfies StatesObjectUpdateContent;\nconst latestUpdateRev2 = {\n\t\"latest\": {\n\t\t[attendeeId1]: {\n\t\t\t\"rev\": 2,\n\t\t\t\"timestamp\": 50,\n\t\t\t\"value\": toOpaqueJson({ x: 2, y: 2, z: 2 }),\n\t\t},\n\t},\n} as const satisfies StatesObjectUpdateContent;\nconst itemRemovedMapUpdate = {\n\t\"latestMap\": {\n\t\t[attendeeId1]: {\n\t\t\t\"rev\": 2,\n\t\t\t\"items\": {\n\t\t\t\t\"key2\": {\n\t\t\t\t\t\"rev\": 2,\n\t\t\t\t\t\"timestamp\": 50,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t},\n} as const satisfies StatesObjectUpdateContent;\nconst itemRemovedAndItemUpdatedMapUpdate = {\n\t\"latestMap\": {\n\t\t[attendeeId1]: {\n\t\t\t\"rev\": 2,\n\t\t\t\"items\": {\n\t\t\t\t\"key2\": {\n\t\t\t\t\t\"rev\": 2,\n\t\t\t\t\t\"timestamp\": 50,\n\t\t\t\t},\n\t\t\t\t\"key1\": {\n\t\t\t\t\t\"rev\": 2,\n\t\t\t\t\t\"timestamp\": 50,\n\t\t\t\t\t\"value\": toOpaqueJson({ a: 2, b: 2 }),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t},\n} as const satisfies StatesObjectUpdateContent;\nconst itemUpdatedAndItemRemovedMapUpdate = {\n\t\"latestMap\": {\n\t\t[attendeeId1]: {\n\t\t\t\"rev\": 2,\n\t\t\t\"items\": {\n\t\t\t\t\"key1\": {\n\t\t\t\t\t\"rev\": 2,\n\t\t\t\t\t\"timestamp\": 50,\n\t\t\t\t\t\"value\": toOpaqueJson({ a: 2, b: 2 }),\n\t\t\t\t},\n\t\t\t\t\"key2\": {\n\t\t\t\t\t\"rev\": 2,\n\t\t\t\t\t\"timestamp\": 50,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t},\n} as const satisfies StatesObjectUpdateContent;\nconst notificationsUpdate = {\n\t\"testEvents\": {\n\t\t[attendeeId1]: {\n\t\t\t\"rev\": 0,\n\t\t\t\"timestamp\": 0,\n\t\t\t\"value\": toOpaqueJson({ \"name\": \"newId\", \"args\": [42] }),\n\t\t\t\"ignoreUnmonitored\": true,\n\t\t},\n\t},\n} as const satisfies StatesObjectUpdateContent;\n\ndescribe(\"Presence/States\", () => {\n\tdescribe(\"events are fired with consistent and final state when\", () => {\n\t\tlet runtime: MockEphemeralRuntime;\n\t\tlet logger: EventAndErrorTrackingLogger;\n\t\tlet clock: SinonFakeTimers;\n\t\tlet presence: PresenceWithNotifications;\n\t\tlet processSignal: ProcessSignalFunction;\n\t\tlet latest: LatestRaw<{ x: number; y: number; z: number }>;\n\t\tlet latestMap: LatestMapRaw<{ a: number; b: number } | { c: number; d: number }>;\n\t\tlet notificationManager: NotificationsManager<{ newId: (id: number) => void }>;\n\n\t\tinterface LatestMapValueExpected {\n\t\t\tkey1: { a: number; b: number } | undefined;\n\t\t\tkey2: { c: number; d: number } | undefined;\n\t\t}\n\t\tinterface LatestValueExpected {\n\t\t\tx: number;\n\t\t\ty: number;\n\t\t\tz: number;\n\t\t}\n\t\ttype StateVerification =\n\t\t\t| {\n\t\t\t\t\tmanager: \"latest\";\n\t\t\t\t\texpectedValue: LatestValueExpected;\n\t\t\t }\n\t\t\t| {\n\t\t\t\t\tmanager: \"latestMap\";\n\t\t\t\t\texpectedValue: LatestMapValueExpected;\n\t\t\t };\n\n\t\tfunction verifyState(attendee: Attendee, verifications: StateVerification[]): void {\n\t\t\tassert(attendee !== undefined, \"Eventing does not reflect new attendee\");\n\t\t\tassert.strictEqual(\n\t\t\t\tattendee.attendeeId,\n\t\t\t\t\"attendeeId-1\",\n\t\t\t\t\"Eventing does not reflect new attendee's attendeeId\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\tattendee.getConnectionId(),\n\t\t\t\t\"client1\",\n\t\t\t\t\"Eventing does not reflect new attendee's connection id\",\n\t\t\t);\n\n\t\t\tfor (const { manager, expectedValue } of verifications) {\n\t\t\t\tswitch (manager) {\n\t\t\t\t\tcase \"latest\": {\n\t\t\t\t\t\tassert.deepEqual(\n\t\t\t\t\t\t\tlatest.getRemote(attendee).value,\n\t\t\t\t\t\t\texpectedValue,\n\t\t\t\t\t\t\t\"Eventing does not reflect latest value\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"latestMap\": {\n\t\t\t\t\t\tassert.deepEqual(\n\t\t\t\t\t\t\tlatestMap.getRemote(attendee).get(\"key1\")?.value,\n\t\t\t\t\t\t\texpectedValue.key1,\n\t\t\t\t\t\t\t\"Eventing does not reflect latest map value\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\tassert.deepEqual(\n\t\t\t\t\t\t\tlatestMap.getRemote(attendee).get(\"key2\")?.value,\n\t\t\t\t\t\t\texpectedValue.key2,\n\t\t\t\t\t\t\t\"Eventing does not reflect latest map value\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbefore(() => {\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\t({ presence, processSignal } = 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\t\t});\n\n\t\tafterEach(function (done: Mocha.Done) {\n\t\t\tclock.reset();\n\t\t\tif (this.currentTest?.state === \"passed\") {\n\t\t\t\tassertFinalExpectations(runtime, logger);\n\t\t\t}\n\t\t\tdone();\n\t\t});\n\n\t\tafter(() => {\n\t\t\tclock.restore();\n\t\t});\n\n\t\tfunction setupSharedStatesWorkspace({\n\t\t\tnotifications,\n\t\t}: {\n\t\t\tnotifications?: true;\n\t\t} = {}): void {\n\t\t\tconst statesWorkspace = presence.states.getWorkspace(\"name:testWorkspace\", {\n\t\t\t\tlatest: StateFactory.latest({ local: { x: 0, y: 0, z: 0 } }),\n\t\t\t\tlatestMap: StateFactory.latestMap({\n\t\t\t\t\tlocal: { key1: { a: 0, b: 0 }, key2: { c: 0, d: 0 } },\n\t\t\t\t}),\n\t\t\t});\n\t\t\tlatest = statesWorkspace.states.latest;\n\t\t\tlatestMap = statesWorkspace.states.latestMap;\n\t\t\tif (notifications) {\n\t\t\t\tconst workspace: typeof statesWorkspace = statesWorkspace;\n\t\t\t\tworkspace.add(\n\t\t\t\t\t\"testEvents\",\n\t\t\t\t\tNotifications<{ newId: (id: number) => void }>({\n\t\t\t\t\t\tnewId: (_attendee: Attendee, _id: number) => {},\n\t\t\t\t\t}),\n\t\t\t\t);\n\n\t\t\t\tnotificationManager = workspace.states.testEvents;\n\t\t\t}\n\t\t}\n\n\t\tfunction setupMultipleStatesWorkspaces(): void {\n\t\t\tconst latestsStates = presence.states.getWorkspace(\"name:testWorkspace1\", {\n\t\t\t\tlatest: StateFactory.latest({ local: { x: 0, y: 0, z: 0 } }),\n\t\t\t});\n\t\t\tconst latesetMapStates = presence.states.getWorkspace(\"name:testWorkspace2\", {\n\t\t\t\tlatestMap: StateFactory.latestMap({\n\t\t\t\t\tlocal: { key1: { a: 0, b: 0 }, key2: { c: 0, d: 0 } },\n\t\t\t\t}),\n\t\t\t});\n\t\t\tlatest = latestsStates.states.latest;\n\t\t\tlatestMap = latesetMapStates.states.latestMap;\n\t\t}\n\n\t\tfunction setupNotificationsWorkspace(): void {\n\t\t\tconst notificationsWorkspace = presence.notifications.getWorkspace(\n\t\t\t\t\"name:testWorkspace\",\n\t\t\t\t{\n\t\t\t\t\ttestEvents: Notifications<{ newId: (id: number) => void }>({\n\t\t\t\t\t\tnewId: (_attendee: Attendee, _id: number) => {},\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t);\n\t\t\tnotificationManager = notificationsWorkspace.notifications.testEvents;\n\t\t}\n\n\t\tfunction processUpdates(valueManagerUpdates: GeneralDatastoreMessageContent): void {\n\t\t\tconst updates = { \"system:presence\": attendeeUpdate, ...valueManagerUpdates };\n\n\t\t\tprocessSignal(\n\t\t\t\t[],\n\t\t\t\t{\n\t\t\t\t\ttype: datastoreUpdateType,\n\t\t\t\t\tcontent: {\n\t\t\t\t\t\tsendTimestamp: clock.now - 10,\n\t\t\t\t\t\tavgLatency: 20,\n\t\t\t\t\t\tdata: updates,\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\t\t}\n\n\t\tfunction getTestAttendee(): Attendee {\n\t\t\treturn presence.attendees.getAttendee(\"attendeeId-1\");\n\t\t}\n\n\t\tdescribe(\"states workspace\", () => {\n\t\t\tlet latestUpdatedEventSpy: SinonSpy;\n\t\t\tlet latestMapUpdatedEventSpy: SinonSpy;\n\t\t\tlet itemUpdatedEventSpy: SinonSpy;\n\n\t\t\tdescribe(\"value is updated where\", () => {\n\t\t\t\tlet atteendeeEventSpy: SinonSpy;\n\n\t\t\t\tfunction verify(): void {\n\t\t\t\t\tverifyState(getTestAttendee(), [\n\t\t\t\t\t\t{ manager: \"latest\", expectedValue: { x: 1, y: 1, z: 1 } },\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmanager: \"latestMap\",\n\t\t\t\t\t\t\texpectedValue: { key1: { a: 1, b: 1 }, key2: { c: 1, d: 1 } },\n\t\t\t\t\t\t},\n\t\t\t\t\t]);\n\t\t\t\t}\n\n\t\t\t\tfunction assertSpies(): void {\n\t\t\t\t\tassert.ok(atteendeeEventSpy.calledOnce, \"attendee event not fired exactly once\");\n\t\t\t\t\tassert.ok(\n\t\t\t\t\t\tlatestUpdatedEventSpy.calledOnce,\n\t\t\t\t\t\t\"latest update event not fired exactly once\",\n\t\t\t\t\t);\n\t\t\t\t\tassert.ok(\n\t\t\t\t\t\tlatestMapUpdatedEventSpy.calledOnce,\n\t\t\t\t\t\t\"latestMap update event not fired exactly once\",\n\t\t\t\t\t);\n\t\t\t\t\tassert.ok(\n\t\t\t\t\t\titemUpdatedEventSpy.calledTwice,\n\t\t\t\t\t\t\"latestMap item update event not fired exactly twice\",\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tfunction setupSpiesAndListeners(): void {\n\t\t\t\t\tlatestUpdatedEventSpy = spy(verify);\n\t\t\t\t\tlatestMapUpdatedEventSpy = spy(verify);\n\t\t\t\t\titemUpdatedEventSpy = spy(verify);\n\t\t\t\t\tatteendeeEventSpy = spy(verify);\n\n\t\t\t\t\tlatest.events.on(\"remoteUpdated\", latestUpdatedEventSpy);\n\t\t\t\t\tlatestMap.events.on(\"remoteUpdated\", latestMapUpdatedEventSpy);\n\t\t\t\t\tlatestMap.events.on(\"remoteItemUpdated\", itemUpdatedEventSpy);\n\t\t\t\t\tpresence.attendees.events.on(\"attendeeConnected\", atteendeeEventSpy);\n\t\t\t\t}\n\n\t\t\t\tit(\"'latest' update comes before 'latestMap' update in single workspace\", async () => {\n\t\t\t\t\t// Setup\n\t\t\t\t\tsetupSharedStatesWorkspace();\n\t\t\t\t\tsetupSpiesAndListeners();\n\t\t\t\t\tconst workspace = {\n\t\t\t\t\t\t\"s:name:testWorkspace\": { ...latestUpdate, ...latestMapUpdate },\n\t\t\t\t\t};\n\t\t\t\t\t// Act\n\t\t\t\t\tprocessUpdates(workspace);\n\t\t\t\t\t// Verify\n\t\t\t\t\tassertSpies();\n\t\t\t\t});\n\n\t\t\t\tit(\"'latestMap' update comes before 'latest' update in single workspace\", async () => {\n\t\t\t\t\t// Setup\n\t\t\t\t\tsetupSharedStatesWorkspace();\n\t\t\t\t\tsetupSpiesAndListeners();\n\t\t\t\t\tconst workspace = {\n\t\t\t\t\t\t\"s:name:testWorkspace\": { ...latestMapUpdate, ...latestUpdate },\n\t\t\t\t\t};\n\t\t\t\t\t// Act\n\t\t\t\t\tprocessUpdates(workspace);\n\t\t\t\t\t// Verify\n\t\t\t\t\tassertSpies();\n\t\t\t\t});\n\n\t\t\t\tit(\"workspace 1 update comes before workspace 2 update in multiple workspaces\", async () => {\n\t\t\t\t\t// Setup\n\t\t\t\t\tsetupMultipleStatesWorkspaces();\n\t\t\t\t\tsetupSpiesAndListeners();\n\t\t\t\t\tconst workspace = {\n\t\t\t\t\t\t\"s:name:testWorkspace1\": latestUpdate,\n\t\t\t\t\t\t\"s:name:testWorkspace2\": latestMapUpdate,\n\t\t\t\t\t};\n\t\t\t\t\t// Act\n\t\t\t\t\tprocessUpdates(workspace);\n\t\t\t\t\t// Verify\n\t\t\t\t\tassertSpies();\n\t\t\t\t});\n\n\t\t\t\tit(\"workspace 2 update comes before workspace 1 update in multiple workspaces\", async () => {\n\t\t\t\t\t// Setup\n\t\t\t\t\tsetupMultipleStatesWorkspaces();\n\t\t\t\t\tsetupSpiesAndListeners();\n\t\t\t\t\tconst workspace = {\n\t\t\t\t\t\t\"s:name:testWorkspace2\": latestMapUpdate,\n\t\t\t\t\t\t\"s:name:testWorkspace1\": latestUpdate,\n\t\t\t\t\t};\n\t\t\t\t\t// Act\n\t\t\t\t\tprocessUpdates(workspace);\n\t\t\t\t\t// Verify\n\t\t\t\t\tassertSpies();\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tdescribe(\"map item is removed\", () => {\n\t\t\t\tlet itemRemovedEventSpy: SinonSpy;\n\n\t\t\t\tdescribe(\"and 'latest' value updated\", () => {\n\t\t\t\t\tfunction verify(): void {\n\t\t\t\t\t\tverifyState(getTestAttendee(), [\n\t\t\t\t\t\t\t{ manager: \"latest\", expectedValue: { x: 2, y: 2, z: 2 } },\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tmanager: \"latestMap\",\n\t\t\t\t\t\t\t\texpectedValue: { key1: { a: 1, b: 1 }, key2: undefined },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t]);\n\t\t\t\t\t}\n\n\t\t\t\t\tfunction setupSpiesAndListeners(): void {\n\t\t\t\t\t\titemRemovedEventSpy = spy(verify);\n\t\t\t\t\t\tlatestUpdatedEventSpy = spy(verify);\n\t\t\t\t\t\tlatestMapUpdatedEventSpy = spy(verify);\n\t\t\t\t\t\tlatest.events.on(\"remoteUpdated\", latestUpdatedEventSpy);\n\t\t\t\t\t\tlatestMap.events.on(\"remoteUpdated\", latestMapUpdatedEventSpy);\n\t\t\t\t\t\tlatestMap.events.on(\"remoteItemRemoved\", itemRemovedEventSpy);\n\t\t\t\t\t}\n\n\t\t\t\t\tfunction assertSpies(): void {\n\t\t\t\t\t\tassert.ok(\n\t\t\t\t\t\t\tlatestUpdatedEventSpy.calledOnce,\n\t\t\t\t\t\t\t`latest update event not fired exactly once`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tassert.ok(\n\t\t\t\t\t\t\tlatestMapUpdatedEventSpy.calledOnce,\n\t\t\t\t\t\t\t\"latestMap update event not fired exactly once\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\tassert.ok(\n\t\t\t\t\t\t\titemRemovedEventSpy.calledOnce,\n\t\t\t\t\t\t\t\"latestMap item remove event not fired exactly once\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tit(\"in a single workspace\", async () => {\n\t\t\t\t\t\t// Setup\n\t\t\t\t\t\tsetupSharedStatesWorkspace();\n\t\t\t\t\t\tconst workspace = {\n\t\t\t\t\t\t\t\"s:name:testWorkspace\": { ...latestMapUpdate, ...latestUpdate },\n\t\t\t\t\t\t};\n\t\t\t\t\t\tprocessUpdates(workspace);\n\t\t\t\t\t\tsetupSpiesAndListeners();\n\t\t\t\t\t\tconst itemRemovedUpdate = {\n\t\t\t\t\t\t\t\"s:name:testWorkspace\": { ...latestUpdateRev2, ...itemRemovedMapUpdate },\n\t\t\t\t\t\t};\n\t\t\t\t\t\t// Act\n\t\t\t\t\t\tprocessUpdates(itemRemovedUpdate);\n\t\t\t\t\t\t// Verify\n\t\t\t\t\t\tassertSpies();\n\t\t\t\t\t});\n\n\t\t\t\t\tit(\"in multiple workspaces\", async () => {\n\t\t\t\t\t\t// Setup\n\t\t\t\t\t\tsetupMultipleStatesWorkspaces();\n\t\t\t\t\t\tconst workspace = {\n\t\t\t\t\t\t\t\"s:name:testWorkspace2\": latestMapUpdate,\n\t\t\t\t\t\t\t\"s:name:testWorkspace1\": latestUpdate,\n\t\t\t\t\t\t};\n\t\t\t\t\t\tprocessUpdates(workspace);\n\t\t\t\t\t\tsetupSpiesAndListeners();\n\t\t\t\t\t\tconst itemRemovedUpdate = {\n\t\t\t\t\t\t\t\"s:name:testWorkspace1\": latestUpdateRev2,\n\t\t\t\t\t\t\t\"s:name:testWorkspace2\": itemRemovedMapUpdate,\n\t\t\t\t\t\t};\n\t\t\t\t\t\t// Act\n\t\t\t\t\t\tprocessUpdates(itemRemovedUpdate);\n\t\t\t\t\t\t// Verify\n\t\t\t\t\t\tassertSpies();\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t\tdescribe(\"and map item is updated\", () => {\n\t\t\t\t\tfunction verify(): void {\n\t\t\t\t\t\tverifyState(getTestAttendee(), [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tmanager: \"latestMap\",\n\t\t\t\t\t\t\t\texpectedValue: { key1: { a: 2, b: 2 }, key2: undefined },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t]);\n\t\t\t\t\t}\n\n\t\t\t\t\tfunction setupSpiesAndListeners(): void {\n\t\t\t\t\t\titemRemovedEventSpy = spy(verify);\n\t\t\t\t\t\tlatestMapUpdatedEventSpy = spy(verify);\n\t\t\t\t\t\titemUpdatedEventSpy = spy(verify);\n\n\t\t\t\t\t\tlatestMap.events.on(\"remoteUpdated\", latestMapUpdatedEventSpy);\n\t\t\t\t\t\tlatestMap.events.on(\"remoteItemUpdated\", itemUpdatedEventSpy);\n\t\t\t\t\t\tlatestMap.events.on(\"remoteItemRemoved\", itemRemovedEventSpy);\n\t\t\t\t\t}\n\n\t\t\t\t\tfunction assertSpies(): void {\n\t\t\t\t\t\tassert.ok(\n\t\t\t\t\t\t\titemUpdatedEventSpy.calledOnce,\n\t\t\t\t\t\t\t`latest update event not fired exactly once`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tassert.ok(\n\t\t\t\t\t\t\tlatestMapUpdatedEventSpy.calledOnce,\n\t\t\t\t\t\t\t\"latestMap update event not fired exactly once\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\tassert.ok(\n\t\t\t\t\t\t\titemRemovedEventSpy.calledOnce,\n\t\t\t\t\t\t\t\"latestMap item remove event not fired exactly once\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tit(\"with removal first\", () => {\n\t\t\t\t\t\t// Setup\n\t\t\t\t\t\tsetupSharedStatesWorkspace();\n\t\t\t\t\t\tconst workspace = {\n\t\t\t\t\t\t\t\"s:name:testWorkspace\": latestMapUpdate,\n\t\t\t\t\t\t};\n\t\t\t\t\t\tprocessUpdates(workspace);\n\t\t\t\t\t\tsetupSpiesAndListeners();\n\t\t\t\t\t\tconst itemRemovedAndItemUpdatedUpdate = {\n\t\t\t\t\t\t\t\"s:name:testWorkspace\": itemRemovedAndItemUpdatedMapUpdate,\n\t\t\t\t\t\t} as const satisfies GeneralDatastoreMessageContent;\n\t\t\t\t\t\t// Act\n\t\t\t\t\t\tprocessUpdates(itemRemovedAndItemUpdatedUpdate);\n\t\t\t\t\t\t// Verify\n\t\t\t\t\t\tassertSpies();\n\t\t\t\t\t});\n\n\t\t\t\t\tit(\"with update first\", () => {\n\t\t\t\t\t\t// Setup\n\t\t\t\t\t\tsetupSharedStatesWorkspace();\n\t\t\t\t\t\tconst workspace = {\n\t\t\t\t\t\t\t\"s:name:testWorkspace\": latestMapUpdate,\n\t\t\t\t\t\t};\n\t\t\t\t\t\tprocessUpdates(workspace);\n\t\t\t\t\t\tsetupSpiesAndListeners();\n\t\t\t\t\t\tconst itemUpdatedAndItemRemovedUpdate = {\n\t\t\t\t\t\t\t\"s:name:testWorkspace\": itemUpdatedAndItemRemovedMapUpdate,\n\t\t\t\t\t\t};\n\t\t\t\t\t\t// Act\n\t\t\t\t\t\tprocessUpdates(itemUpdatedAndItemRemovedUpdate);\n\t\t\t\t\t\t// Verify\n\t\t\t\t\t\tassertSpies();\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\n\t\tdescribe(\"Notifications update\", () => {\n\t\t\tlet notificationSpy: SinonSpy;\n\t\t\tlet latestSpy: SinonSpy;\n\t\t\tlet attendeeSpy: SinonSpy;\n\t\t\tlet latestMapSpy: SinonSpy;\n\n\t\t\tfunction verify(): void {\n\t\t\t\tverifyState(getTestAttendee(), [\n\t\t\t\t\t{ manager: \"latest\", expectedValue: { x: 1, y: 1, z: 1 } },\n\t\t\t\t\t{\n\t\t\t\t\t\tmanager: \"latestMap\",\n\t\t\t\t\t\texpectedValue: { key1: { a: 1, b: 1 }, key2: { c: 1, d: 1 } },\n\t\t\t\t\t},\n\t\t\t\t]);\n\t\t\t}\n\n\t\t\tfunction setupSpiesAndListeners(): void {\n\t\t\t\tnotificationSpy = spy(verify);\n\t\t\t\tlatestSpy = spy(verify);\n\t\t\t\tattendeeSpy = spy(verify);\n\t\t\t\tlatestMapSpy = spy(verify);\n\n\t\t\t\tnotificationManager.notifications.on(\"newId\", notificationSpy);\n\t\t\t\tlatest.events.on(\"remoteUpdated\", latestSpy);\n\t\t\t\tlatestMap.events.on(\"remoteUpdated\", latestMapSpy);\n\t\t\t\tpresence.attendees.events.on(\"attendeeConnected\", attendeeSpy);\n\t\t\t}\n\n\t\t\tfunction assertSpies(): void {\n\t\t\t\tassert.ok(notificationSpy.calledOnce, \"notification event not fired exactly once\");\n\t\t\t\tassert.ok(latestMapSpy.calledOnce, \"latestMap update event not fired exactly once\");\n\t\t\t\tassert.ok(latestSpy.calledOnce, \"latest update event not fired exactly once\");\n\t\t\t\tassert.ok(attendeeSpy.calledOnce, \"attendee event not fired exactly once\");\n\t\t\t}\n\n\t\t\tit(\"comes before states workspace update\", async () => {\n\t\t\t\t// Setup\n\t\t\t\tsetupSharedStatesWorkspace();\n\t\t\t\tsetupNotificationsWorkspace();\n\t\t\t\tsetupSpiesAndListeners();\n\t\t\t\tconst workspace = {\n\t\t\t\t\t\"n:name:testWorkspace\": notificationsUpdate,\n\t\t\t\t\t\"s:name:testWorkspace\": { ...latestUpdate, ...latestMapUpdate },\n\t\t\t\t};\n\t\t\t\t// Act\n\t\t\t\tprocessUpdates(workspace);\n\t\t\t\t// Verify\n\t\t\t\tassertSpies();\n\t\t\t});\n\n\t\t\tit(\"comes after states workspace update\", async () => {\n\t\t\t\t// Setup\n\t\t\t\tsetupSharedStatesWorkspace();\n\t\t\t\tsetupNotificationsWorkspace();\n\t\t\t\tsetupSpiesAndListeners();\n\t\t\t\tconst workspace = {\n\t\t\t\t\t\"s:name:testWorkspace\": { ...latestUpdate, ...latestMapUpdate },\n\t\t\t\t\t\"n:name:testWorkspace\": notificationsUpdate,\n\t\t\t\t};\n\t\t\t\t// Act\n\t\t\t\tprocessUpdates(workspace);\n\t\t\t\t// Verify\n\t\t\t\tassertSpies();\n\t\t\t});\n\n\t\t\tit(\"comes in between states workspaces\", async () => {\n\t\t\t\t// Setup\n\t\t\t\tsetupMultipleStatesWorkspaces();\n\t\t\t\tsetupNotificationsWorkspace();\n\t\t\t\tsetupSpiesAndListeners();\n\t\t\t\tconst workspace = {\n\t\t\t\t\t\"s:name:testWorkspace1\": latestUpdate,\n\t\t\t\t\t\"n:name:testWorkspace\": notificationsUpdate,\n\t\t\t\t\t\"s:name:testWorkspace2\": latestMapUpdate,\n\t\t\t\t};\n\t\t\t\t// Act\n\t\t\t\tprocessUpdates(workspace);\n\t\t\t\t// Verify\n\t\t\t\tassertSpies();\n\t\t\t});\n\n\t\t\tit(\"within a states workspace\", async () => {\n\t\t\t\t// Setup\n\t\t\t\tsetupSharedStatesWorkspace({ notifications: true });\n\t\t\t\tsetupSpiesAndListeners();\n\t\t\t\tconst workspace = {\n\t\t\t\t\t\"s:name:testWorkspace\": {\n\t\t\t\t\t\t...latestUpdate,\n\t\t\t\t\t\t...notificationsUpdate,\n\t\t\t\t\t\t...latestMapUpdate,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t\t// Act\n\t\t\t\tprocessUpdates(workspace);\n\t\t\t\t// Verify\n\t\t\t\tassertSpies();\n\t\t\t});\n\n\t\t\tit(\"from unregistered workspace triggers 'workspaceActivated' event\", async () => {\n\t\t\t\t// Setup\n\t\t\t\tnotificationSpy = spy();\n\t\t\t\tconst workspaceActivatedEventSpy = spy((workspaceAddress: WorkspaceAddress) => {\n\t\t\t\t\t// Once activated, register the notifications workspace and listener for it's event\n\t\t\t\t\tconst notificationsWorkspace = presence.notifications.getWorkspace(\n\t\t\t\t\t\tworkspaceAddress,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttestEvents: Notifications<{ newId: (id: number) => void }>({\n\t\t\t\t\t\t\t\tnewId: (_attendee: Attendee, _id: number) => {},\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\tnotificationsWorkspace.notifications.testEvents.notifications.on(\n\t\t\t\t\t\t\"newId\",\n\t\t\t\t\t\tnotificationSpy,\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t\t\tpresence.events.on(\"workspaceActivated\", (workspaceAddress, type) => {\n\t\t\t\t\tif (workspaceAddress === \"name:testWorkspace\" && type === \"Notifications\") {\n\t\t\t\t\t\tworkspaceActivatedEventSpy(workspaceAddress);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tconst workspace = {\n\t\t\t\t\t\"n:name:testWorkspace\": notificationsUpdate,\n\t\t\t\t};\n\t\t\t\t// Act\n\t\t\t\tprocessUpdates(workspace);\n\n\t\t\t\t// Verify\n\t\t\t\tassert.ok(\n\t\t\t\t\tworkspaceActivatedEventSpy.calledOnce,\n\t\t\t\t\t\"workspace activated event not fired\",\n\t\t\t\t);\n\t\t\t\tassert.ok(\n\t\t\t\t\tnotificationSpy.calledOnce,\n\t\t\t\t\t`notification event not fired exactly once ${notificationSpy.callCount}`,\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tit(\"from an unregistered workspace arrives with state updates\", async () => {\n\t\t\t\tsetupMultipleStatesWorkspaces();\n\n\t\t\t\tconst initialWorkspaceUpdate = {\n\t\t\t\t\t\"s:name:testWorkspace1\": latestUpdate,\n\t\t\t\t\t\"s:name:testWorkspace2\": latestMapUpdate,\n\t\t\t\t};\n\t\t\t\tconst secondWorkspaceUpdate = {\n\t\t\t\t\t\"s:name:testWorkspace1\": latestUpdateRev2,\n\t\t\t\t\t\"n:name:testWorkspace\": notificationsUpdate,\n\t\t\t\t\t\"s:name:testWorkspace2\": itemUpdatedAndItemRemovedMapUpdate,\n\t\t\t\t};\n\n\t\t\t\tpresence.events.on(\"workspaceActivated\", (_, type) => {\n\t\t\t\t\tif (type === \"Notifications\") {\n\t\t\t\t\t\t// Verify initial state maintains consistency\n\t\t\t\t\t\tverifyState(getTestAttendee(), [\n\t\t\t\t\t\t\t{ manager: \"latest\", expectedValue: { x: 1, y: 1, z: 1 } },\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tmanager: \"latestMap\",\n\t\t\t\t\t\t\t\texpectedValue: { key1: { a: 1, b: 1 }, key2: { c: 1, d: 1 } },\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});\n\n\t\t\t\t// Act\n\t\t\t\tprocessUpdates(initialWorkspaceUpdate);\n\t\t\t\tprocessUpdates(secondWorkspaceUpdate);\n\n\t\t\t\t// Verify\n\t\t\t\tverifyState(getTestAttendee(), [\n\t\t\t\t\t{ manager: \"latest\", expectedValue: { x: 2, y: 2, z: 2 } },\n\t\t\t\t\t{\n\t\t\t\t\t\tmanager: \"latestMap\",\n\t\t\t\t\t\texpectedValue: { key1: { a: 2, b: 2 }, key2: undefined },\n\t\t\t\t\t},\n\t\t\t\t]);\n\t\t\t});\n\t\t});\n\t});\n});\n"]}
@@ -1,206 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
- import { strict as assert } from "node:assert";
6
- import { createPresenceManager } from "@fluid-internal/presence-runtime/internal/test";
7
- import { StateFactory } from "@fluid-internal/presence-runtime/states";
8
- import { addControlsTests } from "./broadcastControlsTests.js";
9
- import { MockEphemeralRuntime } from "./mockEphemeralRuntime.js";
10
- import { assertIdenticalTypes, createInstanceOf } from "./testUtils.js";
11
- const testWorkspaceName = "name:testWorkspaceA";
12
- // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
13
- function createLatestMapManager(presence, valueControlSettings) {
14
- const workspace = presence.states.getWorkspace(testWorkspaceName, {
15
- fixedMap: StateFactory.latestMap({
16
- local: { key1: { x: 0, y: 0 }, key2: { ref: "default", someId: 0 } },
17
- settings: valueControlSettings,
18
- }),
19
- });
20
- return workspace.states.fixedMap;
21
- }
22
- describe("Presence/States", () => {
23
- describe("LatestMap", () => {
24
- /**
25
- * See {@link checkCompiles} below
26
- */
27
- it("API use compiles", () => { });
28
- addControlsTests(createLatestMapManager);
29
- function setupMapValueManager() {
30
- const presence = createPresenceManager(new MockEphemeralRuntime());
31
- const workspace = presence.states.getWorkspace(testWorkspaceName, {
32
- fixedMap: StateFactory.latestMap({ local: { key1: { x: 0, y: 0 } } }),
33
- });
34
- return workspace.states.fixedMap;
35
- }
36
- it("localItemUpdated event is fired with new value when local value is updated", () => {
37
- // Setup
38
- const mapVM = setupMapValueManager();
39
- let localUpdateCount = 0;
40
- mapVM.events.on("localItemUpdated", (update) => {
41
- localUpdateCount++;
42
- assert.strictEqual(update.key, "key1");
43
- assert.deepStrictEqual(update.value, { x: 1, y: 2 });
44
- });
45
- // Act & Verify
46
- mapVM.local.set("key1", { x: 1, y: 2 });
47
- assert.strictEqual(localUpdateCount, 1);
48
- });
49
- it("localItemRemoved event is fired with new value when local value is deleted", () => {
50
- // Setup
51
- const mapVM = setupMapValueManager();
52
- let localRemovalCount = 0;
53
- mapVM.events.on("localItemRemoved", (update) => {
54
- localRemovalCount++;
55
- assert.strictEqual(update.key, "key1");
56
- });
57
- // Act & Verify
58
- mapVM.local.delete("key1");
59
- assert.strictEqual(localRemovalCount, 1);
60
- });
61
- it(".presence provides Presence it was created under", () => {
62
- const presence = createPresenceManager(new MockEphemeralRuntime());
63
- const workspace = presence.states.getWorkspace(testWorkspaceName, {
64
- fixedMap: StateFactory.latestMap({ local: { key1: { x: 0, y: 0 } } }),
65
- });
66
- assert.strictEqual(workspace.states.fixedMap.presence, presence);
67
- });
68
- });
69
- });
70
- /**
71
- * Check that the code compiles.
72
- */
73
- export function checkCompiles() {
74
- const fixedMapAnyKeyConfiguration = StateFactory.latestMap();
75
- const validatedMapSpecificKeyConfiguration = StateFactory.latestMap({
76
- local: {
77
- key1: { x: 0, y: 0 },
78
- key2: { ref: "default", someId: 0 },
79
- },
80
- validator: (data) => data,
81
- });
82
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
83
- const presence = {};
84
- const statesWorkspace = presence.states.getWorkspace("name:testStatesWorkspaceWithLatestMap", {
85
- fixedMap: StateFactory.latestMap({
86
- local: {
87
- key1: { x: 0, y: 0 },
88
- key2: { ref: "default", someId: 0 },
89
- },
90
- }),
91
- validatedMap: StateFactory.latestMap({
92
- local: {
93
- key1: { x: 0, y: 0 },
94
- key2: { ref: "default", someId: 0 },
95
- },
96
- validator: (data) => data,
97
- }),
98
- otherMap: fixedMapAnyKeyConfiguration,
99
- anotherMap: fixedMapAnyKeyConfiguration,
100
- specificValidatedMap: validatedMapSpecificKeyConfiguration,
101
- });
102
- // Workaround ts(2775): Assertions require every name in the call target to be declared with an explicit type annotation.
103
- const workspace = statesWorkspace;
104
- const props = workspace.states;
105
- props.fixedMap.local.get("key1");
106
- // @ts-expect-error with inferred keys only those named it init are accessible
107
- props.fixedMap.local.get("key3");
108
- props.fixedMap.local.set("key2", { x: 0, y: 2 });
109
- props.fixedMap.local.set("key2", { ref: "string", someId: -1 });
110
- // @ts-expect-error with inferred type `undefined` optional values are errors
111
- props.fixedMap.local.set("key2", { x: undefined, y: undefined, ref: "string", someId: -1 });
112
- // @ts-expect-error with inferred type partial values are errors
113
- props.fixedMap.local.set("key2", { x: 0 });
114
- // @ts-expect-error with inferred heterogenous type mixed type values are errors
115
- props.fixedMap.local.set("key2", { x: 0, y: 2, ref: "a", someId: 3 });
116
- for (const key of props.fixedMap.local.keys()) {
117
- const value = props.fixedMap.local.get(key);
118
- console.log(key, value);
119
- }
120
- assertIdenticalTypes(props.validatedMap, createInstanceOf());
121
- assertIdenticalTypes(props.fixedMap, createInstanceOf());
122
- // Get a reference to one of the remote attendees
123
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
124
- const attendee2 = [...props.validatedMap.getStateAttendees()].find((attendee) => attendee !== presence.attendees.getMyself());
125
- // Get a remote validated value
126
- const latestMapData = props.validatedMap.getRemote(attendee2);
127
- // Get a value from the validated map
128
- const keyValue = latestMapData.get("key2");
129
- if (keyValue === undefined) {
130
- throw new Error("'key2' not found in LatestMap");
131
- }
132
- const validatedKeyValue = keyValue.value;
133
- // @ts-expect-error because validatedKeyValue is an accessor, not a value
134
- // Type '() =>
135
- // { readonly x: number; readonly y: number; readonly ref?: never; readonly someId?: never; } | { readonly ref:
136
- // string; readonly someId: number; readonly x?: never; readonly y?: never; } | undefined'
137
- // is not assignable to type 'TestMapData | undefined'.
138
- assertIdenticalTypes(validatedKeyValue, createInstanceOf());
139
- // The key value should be a function that returns a value.
140
- const validatedValue = validatedKeyValue?.();
141
- if (validatedValue === undefined) {
142
- throw new Error("Value is not valid according to the validator function.");
143
- }
144
- logClientValue({ attendee: attendee2, key: "key2", value: validatedValue });
145
- workspace.add("pointers", StateFactory.latestMap({ local: {} }));
146
- const pointers = workspace.states.pointers;
147
- const localPointers = pointers.local;
148
- function logClientValue({ attendee, key, value, }) {
149
- console.log(attendee.attendeeId, key, value);
150
- }
151
- localPointers.set("pen", { x: 1, y: 2 });
152
- const pointerItemUpdatedOff = pointers.events.on("remoteItemUpdated", logClientValue);
153
- pointerItemUpdatedOff();
154
- for (const attendee of pointers.getStateAttendees()) {
155
- const items = pointers.getRemote(attendee);
156
- for (const [key, { value }] of items.entries()) {
157
- logClientValue({ attendee, key, value });
158
- }
159
- }
160
- for (const { attendee, items } of pointers.getRemotes()) {
161
- for (const [key, { value }] of items.entries()) {
162
- logClientValue({ attendee, key, value });
163
- }
164
- }
165
- pointers.events.on("remoteItemRemoved", ({ attendee, key }) => logClientValue({ attendee, key, value: "<removed>" }));
166
- pointers.events.on("remoteUpdated", ({ attendee, items }) => {
167
- for (const [key, { value }] of items.entries()) {
168
- logClientValue({ attendee, key, value });
169
- }
170
- });
171
- // ----------------------------------
172
- // primitive and null value support
173
- workspace.add("primitiveMap", StateFactory.latestMap({
174
- local: {
175
- // eslint-disable-next-line unicorn/no-null
176
- null: null,
177
- string: "string",
178
- number: 0,
179
- boolean: true,
180
- },
181
- }));
182
- const localPrimitiveMap = workspace.states.primitiveMap.local;
183
- // map value types are not matched to specific key
184
- localPrimitiveMap.set("string", 1);
185
- // latestMap should infer that `true` or `false` is a valid value
186
- // without use of `true as const` or explicit specification.
187
- // That happened under PR #24752 unexpectedly. Presumably from some
188
- // additional inference complication where `& JsonDeserialized<T>`
189
- // was used in `LatestMapArguments` that was relaxed in PR #247??. !!! <- to fill in
190
- // Caller can always use explicit generic specification to be
191
- // completely clear about the types.
192
- localPrimitiveMap.set("number", false);
193
- // eslint-disable-next-line unicorn/no-null
194
- localPrimitiveMap.set("boolean", null);
195
- localPrimitiveMap.set("null", "null");
196
- // @ts-expect-error with inferred keys only those named in init are accessible
197
- localPrimitiveMap.set("key3", "value");
198
- // @ts-expect-error value of type value is not assignable
199
- localPrimitiveMap.set("null", { value: "value" });
200
- // Adding captured LatestMapConfigurations's to workspace
201
- workspace.add("otherMap", fixedMapAnyKeyConfiguration);
202
- workspace.add("specificValidatedMap", validatedMapSpecificKeyConfiguration);
203
- // @ts-expect-error Argument of type '"yetAnotherMap"' is not assignable to parameter of type '"specificValidatedMap"'
204
- workspace.add("yetAnotherMap", validatedMapSpecificKeyConfiguration);
205
- }
206
- //# sourceMappingURL=latestMapValueManager.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"latestMapValueManager.spec.js","sourceRoot":"","sources":["../../../src/states/test/latestMapValueManager.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 {\n\tBroadcastControlSettings,\n\tLatestMapRaw,\n\tLatestMapItemUpdatedClientData,\n\tPresence,\n\tRawValueAccessor,\n\tLatestMap,\n\tLatestMapConfiguration,\n} from \"@fluid-internal/presence-definitions\";\n\nimport { createPresenceManager } from \"@fluid-internal/presence-runtime/internal/test\";\nimport { StateFactory } from \"@fluid-internal/presence-runtime/states\";\n\nimport { addControlsTests } from \"./broadcastControlsTests.js\";\nimport { MockEphemeralRuntime } from \"./mockEphemeralRuntime.js\";\nimport { assertIdenticalTypes, createInstanceOf } from \"./testUtils.js\";\n\nconst testWorkspaceName = \"name:testWorkspaceA\";\n\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nfunction createLatestMapManager(\n\tpresence: Presence,\n\tvalueControlSettings?: BroadcastControlSettings,\n) {\n\tconst workspace = presence.states.getWorkspace(testWorkspaceName, {\n\t\tfixedMap: StateFactory.latestMap({\n\t\t\tlocal: { key1: { x: 0, y: 0 }, key2: { ref: \"default\", someId: 0 } },\n\t\t\tsettings: valueControlSettings,\n\t\t}),\n\t});\n\treturn workspace.states.fixedMap;\n}\n\ndescribe(\"Presence/States\", () => {\n\tdescribe(\"LatestMap\", () => {\n\t\t/**\n\t\t * See {@link checkCompiles} below\n\t\t */\n\t\tit(\"API use compiles\", () => {});\n\n\t\taddControlsTests(createLatestMapManager);\n\n\t\tfunction setupMapValueManager(): LatestMapRaw<\n\t\t\t{\n\t\t\t\tx: number;\n\t\t\t\ty: number;\n\t\t\t},\n\t\t\t`key${number}`\n\t\t> {\n\t\t\tconst presence = createPresenceManager(new MockEphemeralRuntime());\n\t\t\tconst workspace = presence.states.getWorkspace(testWorkspaceName, {\n\t\t\t\tfixedMap: StateFactory.latestMap({ local: { key1: { x: 0, y: 0 } } }),\n\t\t\t});\n\t\t\treturn workspace.states.fixedMap;\n\t\t}\n\n\t\tit(\"localItemUpdated event is fired with new value when local value is updated\", () => {\n\t\t\t// Setup\n\t\t\tconst mapVM = setupMapValueManager();\n\n\t\t\tlet localUpdateCount = 0;\n\t\t\tmapVM.events.on(\"localItemUpdated\", (update) => {\n\t\t\t\tlocalUpdateCount++;\n\t\t\t\tassert.strictEqual(update.key, \"key1\");\n\t\t\t\tassert.deepStrictEqual(update.value, { x: 1, y: 2 });\n\t\t\t});\n\n\t\t\t// Act & Verify\n\t\t\tmapVM.local.set(\"key1\", { x: 1, y: 2 });\n\t\t\tassert.strictEqual(localUpdateCount, 1);\n\t\t});\n\n\t\tit(\"localItemRemoved event is fired with new value when local value is deleted\", () => {\n\t\t\t// Setup\n\t\t\tconst mapVM = setupMapValueManager();\n\n\t\t\tlet localRemovalCount = 0;\n\t\t\tmapVM.events.on(\"localItemRemoved\", (update) => {\n\t\t\t\tlocalRemovalCount++;\n\t\t\t\tassert.strictEqual(update.key, \"key1\");\n\t\t\t});\n\n\t\t\t// Act & Verify\n\t\t\tmapVM.local.delete(\"key1\");\n\t\t\tassert.strictEqual(localRemovalCount, 1);\n\t\t});\n\n\t\tit(\".presence provides Presence it was created under\", () => {\n\t\t\tconst presence = createPresenceManager(new MockEphemeralRuntime());\n\t\t\tconst workspace = presence.states.getWorkspace(testWorkspaceName, {\n\t\t\t\tfixedMap: StateFactory.latestMap({ local: { key1: { x: 0, y: 0 } } }),\n\t\t\t});\n\n\t\t\tassert.strictEqual(workspace.states.fixedMap.presence, presence);\n\t\t});\n\t});\n});\n\n// ---- test (example) code ----\n\ntype TestMapData =\n\t| { x: number; y: number; ref?: never; someId?: never }\n\t| { ref: string; someId: number; x?: never; y?: never };\n\n/**\n * Check that the code compiles.\n */\nexport function checkCompiles(): void {\n\tconst fixedMapAnyKeyConfiguration = StateFactory.latestMap<TestMapData>();\n\tconst validatedMapSpecificKeyConfiguration: LatestMapConfiguration<\n\t\tTestMapData,\n\t\t\"key1\" | \"key2\",\n\t\t// May only be set to specific workspace key \"specificValidatedMap\"\n\t\t\"specificValidatedMap\"\n\t> = StateFactory.latestMap({\n\t\tlocal: {\n\t\t\tkey1: { x: 0, y: 0 },\n\t\t\tkey2: { ref: \"default\", someId: 0 },\n\t\t},\n\t\tvalidator: (data) => data as TestMapData,\n\t});\n\n\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\tconst presence = {} as Presence;\n\tconst statesWorkspace = presence.states.getWorkspace(\n\t\t\"name:testStatesWorkspaceWithLatestMap\",\n\t\t{\n\t\t\tfixedMap: StateFactory.latestMap({\n\t\t\t\tlocal: {\n\t\t\t\t\tkey1: { x: 0, y: 0 },\n\t\t\t\t\tkey2: { ref: \"default\", someId: 0 },\n\t\t\t\t},\n\t\t\t}),\n\t\t\tvalidatedMap: StateFactory.latestMap({\n\t\t\t\tlocal: {\n\t\t\t\t\tkey1: { x: 0, y: 0 },\n\t\t\t\t\tkey2: { ref: \"default\", someId: 0 },\n\t\t\t\t},\n\t\t\t\tvalidator: (data) => data as TestMapData,\n\t\t\t}),\n\t\t\totherMap: fixedMapAnyKeyConfiguration,\n\t\t\tanotherMap: fixedMapAnyKeyConfiguration,\n\t\t\tspecificValidatedMap: validatedMapSpecificKeyConfiguration,\n\t\t},\n\t);\n\t// Workaround ts(2775): Assertions require every name in the call target to be declared with an explicit type annotation.\n\tconst workspace: typeof statesWorkspace = statesWorkspace;\n\tconst props = workspace.states;\n\n\tprops.fixedMap.local.get(\"key1\");\n\t// @ts-expect-error with inferred keys only those named it init are accessible\n\tprops.fixedMap.local.get(\"key3\");\n\n\tprops.fixedMap.local.set(\"key2\", { x: 0, y: 2 });\n\tprops.fixedMap.local.set(\"key2\", { ref: \"string\", someId: -1 });\n\t// @ts-expect-error with inferred type `undefined` optional values are errors\n\tprops.fixedMap.local.set(\"key2\", { x: undefined, y: undefined, ref: \"string\", someId: -1 });\n\t// @ts-expect-error with inferred type partial values are errors\n\tprops.fixedMap.local.set(\"key2\", { x: 0 });\n\t// @ts-expect-error with inferred heterogenous type mixed type values are errors\n\tprops.fixedMap.local.set(\"key2\", { x: 0, y: 2, ref: \"a\", someId: 3 });\n\n\tfor (const key of props.fixedMap.local.keys()) {\n\t\tconst value = props.fixedMap.local.get(key);\n\t\tconsole.log(key, value);\n\t}\n\n\tassertIdenticalTypes(\n\t\tprops.validatedMap,\n\t\tcreateInstanceOf<LatestMap<TestMapData, \"key1\" | \"key2\">>(),\n\t);\n\n\tassertIdenticalTypes(\n\t\tprops.fixedMap,\n\t\tcreateInstanceOf<LatestMapRaw<TestMapData, \"key1\" | \"key2\">>(),\n\t);\n\n\t// Get a reference to one of the remote attendees\n\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\tconst attendee2 = [...props.validatedMap.getStateAttendees()].find(\n\t\t(attendee) => attendee !== presence.attendees.getMyself(),\n\t)!;\n\n\t// Get a remote validated value\n\tconst latestMapData = props.validatedMap.getRemote(attendee2);\n\n\t// Get a value from the validated map\n\tconst keyValue = latestMapData.get(\"key2\");\n\tif (keyValue === undefined) {\n\t\tthrow new Error(\"'key2' not found in LatestMap\");\n\t}\n\n\tconst validatedKeyValue = keyValue.value;\n\n\t// @ts-expect-error because validatedKeyValue is an accessor, not a value\n\t// Type '() =>\n\t// { readonly x: number; readonly y: number; readonly ref?: never; readonly someId?: never; } | { readonly ref:\n\t// string; readonly someId: number; readonly x?: never; readonly y?: never; } | undefined'\n\t// is not assignable to type 'TestMapData | undefined'.\n\tassertIdenticalTypes(validatedKeyValue, createInstanceOf<TestMapData | undefined>());\n\n\t// The key value should be a function that returns a value.\n\tconst validatedValue: TestMapData | undefined = validatedKeyValue?.();\n\n\tif (validatedValue === undefined) {\n\t\tthrow new Error(\"Value is not valid according to the validator function.\");\n\t}\n\tlogClientValue({ attendee: attendee2, key: \"key2\", value: validatedValue });\n\n\t// ----------------------------------\n\t// pointers data\n\n\tinterface PointerData {\n\t\tx: number;\n\t\ty: number;\n\t\tpressure?: number;\n\t\ttilt?: number;\n\t}\n\n\tworkspace.add(\"pointers\", StateFactory.latestMap<PointerData>({ local: {} }));\n\n\tconst pointers = workspace.states.pointers;\n\tconst localPointers = pointers.local;\n\n\tfunction logClientValue<T>({\n\t\tattendee,\n\t\tkey,\n\t\tvalue,\n\t}: Pick<\n\t\tLatestMapItemUpdatedClientData<T, string, RawValueAccessor<T>>,\n\t\t\"attendee\" | \"key\" | \"value\"\n\t>): void {\n\t\tconsole.log(attendee.attendeeId, key, value);\n\t}\n\n\tlocalPointers.set(\"pen\", { x: 1, y: 2 });\n\n\tconst pointerItemUpdatedOff = pointers.events.on(\"remoteItemUpdated\", logClientValue);\n\tpointerItemUpdatedOff();\n\n\tfor (const attendee of pointers.getStateAttendees()) {\n\t\tconst items = pointers.getRemote(attendee);\n\t\tfor (const [key, { value }] of items.entries()) {\n\t\t\tlogClientValue({ attendee, key, value });\n\t\t}\n\t}\n\n\tfor (const { attendee, items } of pointers.getRemotes()) {\n\t\tfor (const [key, { value }] of items.entries()) {\n\t\t\tlogClientValue({ attendee, key, value });\n\t\t}\n\t}\n\n\tpointers.events.on(\"remoteItemRemoved\", ({ attendee, key }) =>\n\t\tlogClientValue<string>({ attendee, key, value: \"<removed>\" }),\n\t);\n\n\tpointers.events.on(\"remoteUpdated\", ({ attendee, items }) => {\n\t\tfor (const [key, { value }] of items.entries()) {\n\t\t\tlogClientValue({ attendee, key, value });\n\t\t}\n\t});\n\n\t// ----------------------------------\n\t// primitive and null value support\n\n\tworkspace.add(\n\t\t\"primitiveMap\",\n\t\tStateFactory.latestMap({\n\t\t\tlocal: {\n\t\t\t\t// eslint-disable-next-line unicorn/no-null\n\t\t\t\tnull: null,\n\t\t\t\tstring: \"string\",\n\t\t\t\tnumber: 0,\n\t\t\t\tboolean: true,\n\t\t\t},\n\t\t}),\n\t);\n\n\tconst localPrimitiveMap = workspace.states.primitiveMap.local;\n\n\t// map value types are not matched to specific key\n\tlocalPrimitiveMap.set(\"string\", 1);\n\t// latestMap should infer that `true` or `false` is a valid value\n\t// without use of `true as const` or explicit specification.\n\t// That happened under PR #24752 unexpectedly. Presumably from some\n\t// additional inference complication where `& JsonDeserialized<T>`\n\t// was used in `LatestMapArguments` that was relaxed in PR #247??. !!! <- to fill in\n\t// Caller can always use explicit generic specification to be\n\t// completely clear about the types.\n\tlocalPrimitiveMap.set(\"number\", false);\n\t// eslint-disable-next-line unicorn/no-null\n\tlocalPrimitiveMap.set(\"boolean\", null);\n\tlocalPrimitiveMap.set(\"null\", \"null\");\n\n\t// @ts-expect-error with inferred keys only those named in init are accessible\n\tlocalPrimitiveMap.set(\"key3\", \"value\");\n\t// @ts-expect-error value of type value is not assignable\n\tlocalPrimitiveMap.set(\"null\", { value: \"value\" });\n\n\t// Adding captured LatestMapConfigurations's to workspace\n\tworkspace.add(\"otherMap\", fixedMapAnyKeyConfiguration);\n\tworkspace.add(\"specificValidatedMap\", validatedMapSpecificKeyConfiguration);\n\t// @ts-expect-error Argument of type '\"yetAnotherMap\"' is not assignable to parameter of type '\"specificValidatedMap\"'\n\tworkspace.add(\"yetAnotherMap\", validatedMapSpecificKeyConfiguration);\n}\n"]}
@@ -1,189 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
- import { strict as assert } from "node:assert";
6
- import { createPresenceManager } from "@fluid-internal/presence-runtime/internal/test";
7
- import { StateFactory } from "@fluid-internal/presence-runtime/states";
8
- import { addControlsTests } from "./broadcastControlsTests.js";
9
- import { MockEphemeralRuntime } from "./mockEphemeralRuntime.js";
10
- import { assertIdenticalTypes, createInstanceOf } from "./testUtils.js";
11
- const testWorkspaceName = "name:testWorkspaceA";
12
- /* eslint-disable unicorn/no-null -- API null support must be tested */
13
- // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
14
- function createLatestManager(presence, valueControlSettings) {
15
- const workspace = presence.states.getWorkspace(testWorkspaceName, {
16
- camera: StateFactory.latest({
17
- local: { x: 0, y: 0, z: 0 },
18
- settings: valueControlSettings,
19
- }),
20
- });
21
- return workspace.states.camera;
22
- }
23
- describe("Presence/States", () => {
24
- describe("Latest", () => {
25
- /**
26
- * See {@link checkCompiles} below
27
- */
28
- it("API use compiles", () => { });
29
- describe("when initialized", () => {
30
- let presence;
31
- beforeEach(() => {
32
- presence = createPresenceManager(new MockEphemeralRuntime());
33
- });
34
- it("can set and get empty object as initial value", () => {
35
- const workspace = presence.states.getWorkspace(testWorkspaceName, {
36
- obj: StateFactory.latest({ local: {} }),
37
- });
38
- assert.deepStrictEqual(workspace.states.obj.local, {});
39
- });
40
- it("can set and get object with properties as initial value", () => {
41
- const workspace = presence.states.getWorkspace(testWorkspaceName, {
42
- obj: StateFactory.latest({ local: { x: 0, y: 0, z: 0 } }),
43
- });
44
- assert.deepStrictEqual(workspace.states.obj.local, { x: 0, y: 0, z: 0 });
45
- });
46
- it("can set and get empty array as initial value", () => {
47
- const workspace = presence.states.getWorkspace(testWorkspaceName, {
48
- arr: StateFactory.latest({ local: [] }),
49
- });
50
- assert.deepStrictEqual(workspace.states.arr.local, []);
51
- });
52
- it("can set and get array with elements as initial value", () => {
53
- const workspace = presence.states.getWorkspace(testWorkspaceName, {
54
- arr: StateFactory.latest({ local: [1, 2, 3] }),
55
- });
56
- assert.deepStrictEqual(workspace.states.arr.local, [1, 2, 3]);
57
- });
58
- it("can set and get null as initial value", () => {
59
- const workspace = presence.states.getWorkspace(testWorkspaceName, {
60
- nullable: StateFactory.latest({ local: null }),
61
- });
62
- assert.deepStrictEqual(workspace.states.nullable.local, null);
63
- });
64
- it("can set and get inferred nullable type as initial value", () => {
65
- // Setup
66
- // Use a function to generate the initial value so that TypeScript
67
- // can't statically infer the type as exactly null.
68
- function generateInitialValue() {
69
- return { x: 0, y: 0 };
70
- }
71
- const initialValue = generateInitialValue();
72
- // Act
73
- const workspace = presence.states.getWorkspace(testWorkspaceName, {
74
- nullable: StateFactory.latest({ local: initialValue }),
75
- });
76
- // Verify
77
- assert.deepStrictEqual(workspace.states.nullable.local, initialValue);
78
- });
79
- it(".presence provides Presence it was created under", () => {
80
- const workspace = presence.states.getWorkspace(testWorkspaceName, {
81
- camera: StateFactory.latest({ local: { x: 0, y: 0, z: 0 } }),
82
- });
83
- assert.strictEqual(workspace.states.camera.presence, presence);
84
- });
85
- it("can set and get null as modified local value", () => {
86
- // Setup
87
- const workspace = presence.states.getWorkspace(testWorkspaceName, {
88
- nullable: StateFactory.latest({
89
- local: { x: 0, y: 0 },
90
- }),
91
- });
92
- // Act and Verify
93
- workspace.states.nullable.local = null;
94
- assert.deepStrictEqual(workspace.states.nullable.local, null);
95
- });
96
- });
97
- addControlsTests(createLatestManager);
98
- it("localUpdate event is fired with new value when local value is updated", () => {
99
- // Setup
100
- const presence = createPresenceManager(new MockEphemeralRuntime());
101
- const workspace = presence.states.getWorkspace(testWorkspaceName, {
102
- camera: StateFactory.latest({ local: { x: 0, y: 0, z: 0 } }),
103
- });
104
- const camera = workspace.states.camera;
105
- let localUpdateCount = 0;
106
- camera.events.on("localUpdated", (update) => {
107
- localUpdateCount++;
108
- assert.deepStrictEqual(update.value, { x: 1, y: 2, z: 3 });
109
- });
110
- // Act & Verify
111
- camera.local = { x: 1, y: 2, z: 3 };
112
- assert.strictEqual(localUpdateCount, 1);
113
- });
114
- });
115
- });
116
- // ---- test (example) code ----
117
- /**
118
- * Check that the code compiles.
119
- */
120
- export function checkCompiles() {
121
- const latestCountAnyKeyConfiguration = StateFactory.latest({ local: { count: 0 } });
122
- const latestCountSpecificKeyConfiguration = StateFactory.latest({ local: { count: 0 } });
123
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
124
- const presence = {};
125
- const statesWorkspace = presence.states.getWorkspace("name:testStatesWorkspaceWithLatest", {
126
- cursor: StateFactory.latest({ local: { x: 0, y: 0 } }),
127
- camera: StateFactory.latest({ local: { x: 0, y: 0, z: 0 } }),
128
- nullablePoint: StateFactory.latest({ local: null }),
129
- validated: StateFactory.latest({
130
- local: { num: 22 },
131
- validator: (data) => data,
132
- }),
133
- count0: latestCountAnyKeyConfiguration,
134
- count1: latestCountAnyKeyConfiguration,
135
- myCount: latestCountSpecificKeyConfiguration,
136
- });
137
- // Workaround ts(2775): Assertions require every name in the call target to be declared with an explicit type annotation.
138
- const workspace = statesWorkspace;
139
- const props = workspace.states;
140
- workspace.add("caret", StateFactory.latest({ local: { id: "", pos: 0 } }));
141
- const fakeAdd = workspace.states.caret.local.pos + props.camera.local.z + props.cursor.local.x;
142
- console.log(fakeAdd);
143
- // @ts-expect-error local may be set wholly, but partially it is readonly
144
- workspace.states.caret.local.pos = 0;
145
- function logClientValue({ attendee, value, }) {
146
- console.log(attendee.attendeeId, value);
147
- }
148
- function logRemoteValue({ attendee, value, }) {
149
- console.log(attendee.attendeeId, value());
150
- }
151
- // Create new cursor state
152
- const cursor = props.cursor;
153
- // Update our cursor position
154
- cursor.local = { x: 1, y: 2 };
155
- // Set nullable point to non-null value
156
- props.nullablePoint.local = { x: 10, y: -2 };
157
- // Listen to others cursor updates
158
- const cursorUpdatedOff = cursor.events.on("remoteUpdated", ({ attendee, value }) => console.log(`attendee ${attendee.attendeeId}'s cursor is now at (${value.x},${value.y})`));
159
- cursorUpdatedOff();
160
- for (const attendee of cursor.getStateAttendees()) {
161
- logClientValue({ attendee, ...cursor.getRemote(attendee) });
162
- }
163
- // Enumerate all cursor values
164
- for (const { attendee, value } of cursor.getRemotes()) {
165
- logClientValue({ attendee, value });
166
- }
167
- // Get a reference to one of the remote attendees
168
- const attendee2 = [...cursor.getStateAttendees()].find((attendee) => attendee !== presence.attendees.getMyself());
169
- assert(attendee2 !== undefined);
170
- // Get a remote raw value
171
- const remoteCursor = cursor.getRemote(attendee2);
172
- logClientValue({ attendee: attendee2, value: remoteCursor.value });
173
- assertIdenticalTypes(props.cursor, createInstanceOf());
174
- assertIdenticalTypes(props.validated, createInstanceOf());
175
- // Get a remote validated value
176
- const latestData = props.validated.getRemote(attendee2);
177
- // The next line correctly does not compile because the value argument must be a RawValueAccessor
178
- // @ts-expect-error Type '() => { readonly num: number; } | undefined' is not assignable to type 'never'.
179
- logClientValue({ attendee: attendee2, value: latestData.value });
180
- // This line correctly compiles because logRemoteValue expects a ProxiedValueAccessor
181
- logRemoteValue({ attendee: attendee2, value: latestData.value });
182
- // Adding captured LatestConfigurations's to workspace
183
- workspace.add("myCount", latestCountAnyKeyConfiguration);
184
- workspace.add("otherCount", latestCountAnyKeyConfiguration);
185
- // @ts-expect-error Argument of type '"otherCount"' is not assignable to parameter of type '"myCount"'
186
- workspace.add("otherCount", latestCountSpecificKeyConfiguration);
187
- }
188
- /* eslint-enable unicorn/no-null */
189
- //# sourceMappingURL=latestValueManager.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"latestValueManager.spec.js","sourceRoot":"","sources":["../../../src/states/test/latestValueManager.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 {\n\tBroadcastControlSettings,\n\tLatest,\n\tLatestClientData,\n\tLatestRaw,\n\tLatestRawConfiguration,\n\tPresence,\n\tRawValueAccessor,\n} from \"@fluid-internal/presence-definitions\";\n\nimport { createPresenceManager } from \"@fluid-internal/presence-runtime/internal/test\";\nimport { StateFactory } from \"@fluid-internal/presence-runtime/states\";\n\nimport { addControlsTests } from \"./broadcastControlsTests.js\";\nimport { MockEphemeralRuntime } from \"./mockEphemeralRuntime.js\";\nimport { assertIdenticalTypes, createInstanceOf } from \"./testUtils.js\";\n\nconst testWorkspaceName = \"name:testWorkspaceA\";\n\n/* eslint-disable unicorn/no-null -- API null support must be tested */\n\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nfunction createLatestManager(\n\tpresence: Presence,\n\tvalueControlSettings?: BroadcastControlSettings,\n) {\n\tconst workspace = presence.states.getWorkspace(testWorkspaceName, {\n\t\tcamera: StateFactory.latest({\n\t\t\tlocal: { x: 0, y: 0, z: 0 },\n\t\t\tsettings: valueControlSettings,\n\t\t}),\n\t});\n\treturn workspace.states.camera;\n}\n\ndescribe(\"Presence/States\", () => {\n\tdescribe(\"Latest\", () => {\n\t\t/**\n\t\t * See {@link checkCompiles} below\n\t\t */\n\t\tit(\"API use compiles\", () => {});\n\n\t\tdescribe(\"when initialized\", () => {\n\t\t\tlet presence: Presence;\n\n\t\t\tbeforeEach(() => {\n\t\t\t\tpresence = createPresenceManager(new MockEphemeralRuntime());\n\t\t\t});\n\n\t\t\tit(\"can set and get empty object as initial value\", () => {\n\t\t\t\tconst workspace = presence.states.getWorkspace(testWorkspaceName, {\n\t\t\t\t\tobj: StateFactory.latest({ local: {} }),\n\t\t\t\t});\n\t\t\t\tassert.deepStrictEqual(workspace.states.obj.local, {});\n\t\t\t});\n\n\t\t\tit(\"can set and get object with properties as initial value\", () => {\n\t\t\t\tconst workspace = presence.states.getWorkspace(testWorkspaceName, {\n\t\t\t\t\tobj: StateFactory.latest({ local: { x: 0, y: 0, z: 0 } }),\n\t\t\t\t});\n\t\t\t\tassert.deepStrictEqual(workspace.states.obj.local, { x: 0, y: 0, z: 0 });\n\t\t\t});\n\n\t\t\tit(\"can set and get empty array as initial value\", () => {\n\t\t\t\tconst workspace = presence.states.getWorkspace(testWorkspaceName, {\n\t\t\t\t\tarr: StateFactory.latest({ local: [] }),\n\t\t\t\t});\n\t\t\t\tassert.deepStrictEqual(workspace.states.arr.local, []);\n\t\t\t});\n\n\t\t\tit(\"can set and get array with elements as initial value\", () => {\n\t\t\t\tconst workspace = presence.states.getWorkspace(testWorkspaceName, {\n\t\t\t\t\tarr: StateFactory.latest({ local: [1, 2, 3] }),\n\t\t\t\t});\n\t\t\t\tassert.deepStrictEqual(workspace.states.arr.local, [1, 2, 3]);\n\t\t\t});\n\n\t\t\tit(\"can set and get null as initial value\", () => {\n\t\t\t\tconst workspace = presence.states.getWorkspace(testWorkspaceName, {\n\t\t\t\t\tnullable: StateFactory.latest({ local: null }),\n\t\t\t\t});\n\t\t\t\tassert.deepStrictEqual(workspace.states.nullable.local, null);\n\t\t\t});\n\n\t\t\tit(\"can set and get inferred nullable type as initial value\", () => {\n\t\t\t\t// Setup\n\t\t\t\t// Use a function to generate the initial value so that TypeScript\n\t\t\t\t// can't statically infer the type as exactly null.\n\t\t\t\tfunction generateInitialValue(): { x: number; y: number } | null {\n\t\t\t\t\treturn { x: 0, y: 0 };\n\t\t\t\t}\n\t\t\t\tconst initialValue = generateInitialValue();\n\t\t\t\t// Act\n\t\t\t\tconst workspace = presence.states.getWorkspace(testWorkspaceName, {\n\t\t\t\t\tnullable: StateFactory.latest({ local: initialValue }),\n\t\t\t\t});\n\t\t\t\t// Verify\n\t\t\t\tassert.deepStrictEqual(workspace.states.nullable.local, initialValue);\n\t\t\t});\n\n\t\t\tit(\".presence provides Presence it was created under\", () => {\n\t\t\t\tconst workspace = presence.states.getWorkspace(testWorkspaceName, {\n\t\t\t\t\tcamera: StateFactory.latest({ local: { x: 0, y: 0, z: 0 } }),\n\t\t\t\t});\n\n\t\t\t\tassert.strictEqual(workspace.states.camera.presence, presence);\n\t\t\t});\n\n\t\t\tit(\"can set and get null as modified local value\", () => {\n\t\t\t\t// Setup\n\t\t\t\tconst workspace = presence.states.getWorkspace(testWorkspaceName, {\n\t\t\t\t\tnullable: StateFactory.latest<{ x: number; y: number } | null>({\n\t\t\t\t\t\tlocal: { x: 0, y: 0 },\n\t\t\t\t\t}),\n\t\t\t\t});\n\n\t\t\t\t// Act and Verify\n\t\t\t\tworkspace.states.nullable.local = null;\n\t\t\t\tassert.deepStrictEqual(workspace.states.nullable.local, null);\n\t\t\t});\n\t\t});\n\n\t\taddControlsTests(createLatestManager);\n\n\t\tit(\"localUpdate event is fired with new value when local value is updated\", () => {\n\t\t\t// Setup\n\t\t\tconst presence = createPresenceManager(new MockEphemeralRuntime());\n\t\t\tconst workspace = presence.states.getWorkspace(testWorkspaceName, {\n\t\t\t\tcamera: StateFactory.latest({ local: { x: 0, y: 0, z: 0 } }),\n\t\t\t});\n\t\t\tconst camera = workspace.states.camera;\n\n\t\t\tlet localUpdateCount = 0;\n\t\t\tcamera.events.on(\"localUpdated\", (update) => {\n\t\t\t\tlocalUpdateCount++;\n\t\t\t\tassert.deepStrictEqual(update.value, { x: 1, y: 2, z: 3 });\n\t\t\t});\n\n\t\t\t// Act & Verify\n\t\t\tcamera.local = { x: 1, y: 2, z: 3 };\n\t\t\tassert.strictEqual(localUpdateCount, 1);\n\t\t});\n\t});\n});\n\n// ---- test (example) code ----\n\n/**\n * Check that the code compiles.\n */\nexport function checkCompiles(): void {\n\tconst latestCountAnyKeyConfiguration = StateFactory.latest({ local: { count: 0 } });\n\tconst latestCountSpecificKeyConfiguration: LatestRawConfiguration<\n\t\t{\n\t\t\tcount: number;\n\t\t},\n\t\t// May only be set to specific workspace key \"myCount\"\n\t\t\"myCount\"\n\t> = StateFactory.latest({ local: { count: 0 } });\n\n\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\tconst presence = {} as Presence;\n\tconst statesWorkspace = presence.states.getWorkspace(\"name:testStatesWorkspaceWithLatest\", {\n\t\tcursor: StateFactory.latest({ local: { x: 0, y: 0 } }),\n\t\tcamera: StateFactory.latest({ local: { x: 0, y: 0, z: 0 } }),\n\t\tnullablePoint: StateFactory.latest<null | { x: number; y: number }>({ local: null }),\n\t\tvalidated: StateFactory.latest({\n\t\t\tlocal: { num: 22 },\n\t\t\tvalidator: (data: unknown) => data as { num: number },\n\t\t}),\n\t\tcount0: latestCountAnyKeyConfiguration,\n\t\tcount1: latestCountAnyKeyConfiguration,\n\t\tmyCount: latestCountSpecificKeyConfiguration,\n\t});\n\t// Workaround ts(2775): Assertions require every name in the call target to be declared with an explicit type annotation.\n\tconst workspace: typeof statesWorkspace = statesWorkspace;\n\tconst props = workspace.states;\n\n\tworkspace.add(\"caret\", StateFactory.latest({ local: { id: \"\", pos: 0 } }));\n\n\tconst fakeAdd =\n\t\tworkspace.states.caret.local.pos + props.camera.local.z + props.cursor.local.x;\n\tconsole.log(fakeAdd);\n\n\t// @ts-expect-error local may be set wholly, but partially it is readonly\n\tworkspace.states.caret.local.pos = 0;\n\n\tfunction logClientValue<T>({\n\t\tattendee,\n\t\tvalue,\n\t}: Pick<LatestClientData<T, RawValueAccessor<T>>, \"attendee\" | \"value\">): void {\n\t\tconsole.log(attendee.attendeeId, value);\n\t}\n\n\tfunction logRemoteValue<T>({\n\t\tattendee,\n\t\tvalue,\n\t}: Pick<LatestClientData<T>, \"attendee\" | \"value\">): void {\n\t\tconsole.log(attendee.attendeeId, value());\n\t}\n\n\t// Create new cursor state\n\tconst cursor = props.cursor;\n\n\t// Update our cursor position\n\tcursor.local = { x: 1, y: 2 };\n\n\t// Set nullable point to non-null value\n\tprops.nullablePoint.local = { x: 10, y: -2 };\n\n\t// Listen to others cursor updates\n\tconst cursorUpdatedOff = cursor.events.on(\"remoteUpdated\", ({ attendee, value }) =>\n\t\tconsole.log(`attendee ${attendee.attendeeId}'s cursor is now at (${value.x},${value.y})`),\n\t);\n\tcursorUpdatedOff();\n\n\tfor (const attendee of cursor.getStateAttendees()) {\n\t\tlogClientValue({ attendee, ...cursor.getRemote(attendee) });\n\t}\n\n\t// Enumerate all cursor values\n\tfor (const { attendee, value } of cursor.getRemotes()) {\n\t\tlogClientValue({ attendee, value });\n\t}\n\n\t// Get a reference to one of the remote attendees\n\tconst attendee2 = [...cursor.getStateAttendees()].find(\n\t\t(attendee) => attendee !== presence.attendees.getMyself(),\n\t);\n\tassert(attendee2 !== undefined);\n\n\t// Get a remote raw value\n\tconst remoteCursor = cursor.getRemote(attendee2);\n\tlogClientValue({ attendee: attendee2, value: remoteCursor.value });\n\n\tassertIdenticalTypes(props.cursor, createInstanceOf<LatestRaw<{ x: number; y: number }>>());\n\tassertIdenticalTypes(props.validated, createInstanceOf<Latest<{ num: number }>>());\n\n\t// Get a remote validated value\n\tconst latestData = props.validated.getRemote(attendee2);\n\n\t// The next line correctly does not compile because the value argument must be a RawValueAccessor\n\t// @ts-expect-error Type '() => { readonly num: number; } | undefined' is not assignable to type 'never'.\n\tlogClientValue({ attendee: attendee2, value: latestData.value });\n\n\t// This line correctly compiles because logRemoteValue expects a ProxiedValueAccessor\n\tlogRemoteValue({ attendee: attendee2, value: latestData.value });\n\n\t// Adding captured LatestConfigurations's to workspace\n\tworkspace.add(\"myCount\", latestCountAnyKeyConfiguration);\n\tworkspace.add(\"otherCount\", latestCountAnyKeyConfiguration);\n\t// @ts-expect-error Argument of type '\"otherCount\"' is not assignable to parameter of type '\"myCount\"'\n\tworkspace.add(\"otherCount\", latestCountSpecificKeyConfiguration);\n}\n\n/* eslint-enable unicorn/no-null */\n"]}
@@ -1,6 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
- export { initialLocalClientConnectionId, MockEphemeralRuntime, } from "@fluid-internal/presence-runtime/internal/test-utils";
6
- //# sourceMappingURL=mockEphemeralRuntime.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mockEphemeralRuntime.js","sourceRoot":"","sources":["../../../src/states/test/mockEphemeralRuntime.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,8BAA8B,EAC9B,oBAAoB,GACpB,MAAM,sDAAsD,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport {\n\tinitialLocalClientConnectionId,\n\tMockEphemeralRuntime,\n} from \"@fluid-internal/presence-runtime/internal/test-utils\";\n"]}