@fluidframework/shared-object-base 2.0.0-rc.2.0.1 → 2.0.0-rc.3.0.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 (87) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/api-report/shared-object-base.api.md +8 -1
  3. package/dist/handle.d.ts +1 -1
  4. package/dist/handle.d.ts.map +1 -1
  5. package/dist/handle.js +2 -2
  6. package/dist/handle.js.map +1 -1
  7. package/dist/index.d.ts +1 -1
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js.map +1 -1
  10. package/dist/legacy.d.ts +23 -0
  11. package/dist/packageVersion.d.ts +1 -1
  12. package/dist/packageVersion.js +1 -1
  13. package/dist/packageVersion.js.map +1 -1
  14. package/dist/public.d.ts +17 -0
  15. package/dist/remoteObjectHandle.d.ts.map +1 -1
  16. package/dist/remoteObjectHandle.js +6 -6
  17. package/dist/remoteObjectHandle.js.map +1 -1
  18. package/dist/serializer.d.ts.map +1 -1
  19. package/dist/serializer.js +3 -5
  20. package/dist/serializer.js.map +1 -1
  21. package/dist/sharedObject.d.ts +52 -4
  22. package/dist/sharedObject.d.ts.map +1 -1
  23. package/dist/sharedObject.js +22 -22
  24. package/dist/sharedObject.js.map +1 -1
  25. package/dist/summarySerializer.d.ts.map +1 -1
  26. package/dist/summarySerializer.js.map +1 -1
  27. package/dist/utils.d.ts.map +1 -1
  28. package/dist/utils.js +2 -2
  29. package/dist/utils.js.map +1 -1
  30. package/internal.d.ts +11 -0
  31. package/legacy.d.ts +11 -0
  32. package/lib/handle.d.ts +1 -1
  33. package/lib/handle.d.ts.map +1 -1
  34. package/lib/handle.js +1 -1
  35. package/lib/handle.js.map +1 -1
  36. package/lib/index.d.ts +1 -1
  37. package/lib/index.d.ts.map +1 -1
  38. package/lib/index.js.map +1 -1
  39. package/lib/legacy.d.ts +23 -0
  40. package/lib/packageVersion.d.ts +1 -1
  41. package/lib/packageVersion.js +1 -1
  42. package/lib/packageVersion.js.map +1 -1
  43. package/lib/public.d.ts +17 -0
  44. package/lib/remoteObjectHandle.d.ts.map +1 -1
  45. package/lib/remoteObjectHandle.js +3 -3
  46. package/lib/remoteObjectHandle.js.map +1 -1
  47. package/lib/serializer.d.ts.map +1 -1
  48. package/lib/serializer.js +1 -3
  49. package/lib/serializer.js.map +1 -1
  50. package/lib/sharedObject.d.ts +52 -4
  51. package/lib/sharedObject.d.ts.map +1 -1
  52. package/lib/sharedObject.js +5 -5
  53. package/lib/sharedObject.js.map +1 -1
  54. package/lib/summarySerializer.d.ts.map +1 -1
  55. package/lib/summarySerializer.js.map +1 -1
  56. package/lib/utils.d.ts.map +1 -1
  57. package/lib/utils.js +1 -1
  58. package/lib/utils.js.map +1 -1
  59. package/package.json +36 -57
  60. package/src/handle.ts +2 -1
  61. package/src/index.ts +1 -1
  62. package/src/packageVersion.ts +1 -1
  63. package/src/remoteObjectHandle.ts +4 -4
  64. package/src/serializer.ts +5 -1
  65. package/src/sharedObject.ts +71 -18
  66. package/src/summarySerializer.ts +1 -0
  67. package/src/utils.ts +2 -1
  68. package/api-extractor-cjs.json +0 -8
  69. package/dist/shared-object-base-alpha.d.ts +0 -427
  70. package/dist/shared-object-base-beta.d.ts +0 -118
  71. package/dist/shared-object-base-public.d.ts +0 -118
  72. package/dist/shared-object-base-untrimmed.d.ts +0 -513
  73. package/lib/shared-object-base-alpha.d.ts +0 -427
  74. package/lib/shared-object-base-beta.d.ts +0 -118
  75. package/lib/shared-object-base-public.d.ts +0 -118
  76. package/lib/shared-object-base-untrimmed.d.ts +0 -513
  77. package/lib/test/attachingBindingAndConnecting.spec.js +0 -334
  78. package/lib/test/attachingBindingAndConnecting.spec.js.map +0 -1
  79. package/lib/test/serializer.spec.js +0 -166
  80. package/lib/test/serializer.spec.js.map +0 -1
  81. package/lib/test/sharedObject.spec.js +0 -72
  82. package/lib/test/sharedObject.spec.js.map +0 -1
  83. package/lib/test/types/validateSharedObjectBasePrevious.generated.js +0 -26
  84. package/lib/test/types/validateSharedObjectBasePrevious.generated.js.map +0 -1
  85. package/lib/test/utils.js +0 -37
  86. package/lib/test/utils.js.map +0 -1
  87. /package/{dist → lib}/tsdoc-metadata.json +0 -0
@@ -1,334 +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 "assert";
6
- import { createChildLogger } from "@fluidframework/telemetry-utils";
7
- import { TypedEventEmitter } from "@fluid-internal/client-utils";
8
- import { AttachState } from "@fluidframework/container-definitions";
9
- import { generatePairwiseOptions } from "@fluid-private/test-pairwise-generator";
10
- import { SharedObject } from "../sharedObject.js";
11
- function createOverridableProxy(name, ...overrides) {
12
- return new Proxy({}, {
13
- get: (_, p, r) => {
14
- for (const override of overrides) {
15
- if (p in override) {
16
- return Reflect.get(override, p, r);
17
- }
18
- }
19
- assert.fail(`No override for ${name}.${p.toString()}`);
20
- },
21
- });
22
- }
23
- function createTestSharedObject(overrides) {
24
- class TestSharedObject extends SharedObject {
25
- constructor() {
26
- super(...arguments);
27
- this.summarizeCore = overrides?.summarizeCore?.bind(this);
28
- this.loadCore = overrides?.loadCore?.bind(this);
29
- this.processCore = overrides?.processCore?.bind(this);
30
- this.onDisconnect = overrides?.onDisconnect?.bind(this);
31
- this.applyStashedOp = overrides?.applyStashedOp?.bind(this);
32
- this.didAttach = overrides.didAttach?.bind(this) ?? (() => assert.fail("didAttach not set"));
33
- }
34
- }
35
- const runtime = overrides?.runtime ?? {};
36
- runtime.channelsRoutingContext ?? (runtime.channelsRoutingContext = {
37
- absolutePath: "/",
38
- attachGraph: () => { },
39
- get IFluidHandleContext() {
40
- return this;
41
- },
42
- isAttached: false,
43
- resolveHandle: async () => ({ status: 500, mimeType: "error", value: "error" }),
44
- });
45
- runtime.IFluidHandleContext ?? (runtime.IFluidHandleContext = runtime.channelsRoutingContext);
46
- runtime.logger ?? (runtime.logger = createChildLogger());
47
- const attributes = overrides?.attributes ?? {};
48
- attributes.type ?? (attributes.type = "TestSharedObject");
49
- return {
50
- overrides,
51
- sharedObject: new TestSharedObject(overrides?.id ?? "testSharedObject", createOverridableProxy("runtime", runtime, new TypedEventEmitter()), createOverridableProxy("attributes", attributes), overrides?.telemetryConfigPrefix ?? "testSharedObject"),
52
- };
53
- }
54
- /**
55
- * The attach state of a shared object is determined by two facts:
56
- *
57
- * * Is it bound to a context which means its handle is stored in an already bound dds
58
- * * Is the runtime attached
59
- *
60
- * If both of these are true, then the dds should be considered attached.
61
- *
62
- * Beyond attach, there is also the connected state, and the didAttach method.
63
- * The connected state should always be false while detached, and didAttach should only be called once when the dds transitions.
64
- *
65
- * These tests valid these properties across all the functions that can cause attach state transitions
66
- */
67
- describe("SharedObject attaching binding and connecting", () => {
68
- const runtimeAttachStateAndConnectedMatrix = generatePairwiseOptions({
69
- connected: [true, false],
70
- attachState: [AttachState.Detached, AttachState.Attaching, AttachState.Attached],
71
- });
72
- describe("shared object after creation", () => {
73
- runtimeAttachStateAndConnectedMatrix.forEach(({ connected, attachState }) => it(`!isAttached and !connected with runtime ${JSON.stringify({
74
- connected,
75
- attachState,
76
- })}`, () => {
77
- const { sharedObject } = createTestSharedObject({
78
- runtime: {
79
- attachState,
80
- connected,
81
- },
82
- });
83
- assert.strictEqual(sharedObject.isAttached(), false, "!isAttached");
84
- assert.strictEqual(sharedObject.connected, false, "!connected");
85
- }));
86
- it("!isAttached with detached transition to attach runtime", () => {
87
- const runtimeEvents = new TypedEventEmitter();
88
- let didAttach = 0;
89
- const { overrides, sharedObject } = createTestSharedObject({
90
- runtime: {
91
- ...runtimeEvents,
92
- attachState: AttachState.Detached,
93
- },
94
- didAttach: () => didAttach++,
95
- });
96
- assert.strictEqual(didAttach, 0, "!didAttach");
97
- assert.strictEqual(sharedObject.isAttached(), false, "!isAttached");
98
- assert(overrides.runtime);
99
- overrides.runtime.attachState = AttachState.Attaching;
100
- runtimeEvents.emit("attaching");
101
- overrides.runtime.attachState = AttachState.Attached;
102
- assert.strictEqual(sharedObject.isAttached(), false, "!isAttached");
103
- assert.strictEqual(didAttach, 0, "!didAttach");
104
- });
105
- });
106
- describe("shared object after load", () => {
107
- runtimeAttachStateAndConnectedMatrix.forEach(({ connected, attachState }) => it(`With runtime ${JSON.stringify({
108
- connected,
109
- attachState,
110
- })}`, async () => {
111
- let loaded = false;
112
- let didAttach = 0;
113
- const { sharedObject } = createTestSharedObject({
114
- runtime: {
115
- attachState,
116
- connected,
117
- },
118
- loadCore: async () => {
119
- loaded = true;
120
- },
121
- didAttach: () => didAttach++,
122
- });
123
- let attachCalled = false;
124
- await sharedObject.load(createOverridableProxy("services", {
125
- objectStorage: createOverridableProxy("objectStorage"),
126
- deltaConnection: createOverridableProxy("deltaConnection", {
127
- attach(handler) {
128
- attachCalled = true;
129
- },
130
- connected,
131
- }),
132
- }));
133
- assert.strictEqual(loaded, true, "loaded");
134
- assert.strictEqual(attachCalled, true, "attachCalled");
135
- assert.strictEqual(didAttach, sharedObject.isAttached() ? 1 : 0, "didAttach");
136
- assert.strictEqual(sharedObject.isAttached(), attachState !== AttachState.Detached, "isAttached");
137
- assert.strictEqual(sharedObject.connected, connected && sharedObject.isAttached(), "connected");
138
- }));
139
- it("isAttached with detached transition to attach runtime", async () => {
140
- const runtimeEvents = new TypedEventEmitter();
141
- let didAttach = 0;
142
- let loaded = false;
143
- const { overrides, sharedObject } = createTestSharedObject({
144
- runtime: {
145
- ...runtimeEvents,
146
- attachState: AttachState.Detached,
147
- connected: true,
148
- },
149
- didAttach: () => didAttach++,
150
- loadCore: async () => {
151
- loaded = true;
152
- },
153
- });
154
- await sharedObject.load(createOverridableProxy("services", {
155
- objectStorage: createOverridableProxy("objectStorage"),
156
- deltaConnection: createOverridableProxy("deltaConnection", {
157
- attach(handler) { },
158
- connected: overrides.runtime?.connected ?? false,
159
- }),
160
- }));
161
- assert.strictEqual(didAttach, 0, "!didAttach");
162
- assert.strictEqual(loaded, true, "loaded");
163
- assert.strictEqual(sharedObject.isAttached(), false, "!isAttached");
164
- assert(overrides.runtime);
165
- overrides.runtime.attachState = AttachState.Attaching;
166
- runtimeEvents.emit("attaching");
167
- overrides.runtime.attachState = AttachState.Attached;
168
- assert.strictEqual(sharedObject.isAttached(), true, "isAttached");
169
- assert.strictEqual(didAttach, 1, "didAttach");
170
- });
171
- });
172
- describe("shared object after connect", () => {
173
- runtimeAttachStateAndConnectedMatrix.forEach(({ connected, attachState }) => it(`With runtime ${JSON.stringify({
174
- connected,
175
- attachState,
176
- })}`, async () => {
177
- let didAttach = 0;
178
- const { sharedObject } = createTestSharedObject({
179
- runtime: {
180
- attachState,
181
- connected,
182
- },
183
- didAttach: () => didAttach++,
184
- });
185
- let attachCalled = false;
186
- sharedObject.connect(createOverridableProxy("services", {
187
- objectStorage: createOverridableProxy("objectStorage"),
188
- deltaConnection: createOverridableProxy("deltaConnection", {
189
- attach(handler) {
190
- attachCalled = true;
191
- },
192
- connected,
193
- }),
194
- }));
195
- assert.strictEqual(attachCalled, true, "attachCalled");
196
- assert.strictEqual(didAttach, sharedObject.isAttached() ? 1 : 0, "didAttach");
197
- assert.strictEqual(sharedObject.isAttached(), attachState !== AttachState.Detached, "isAttached");
198
- assert.strictEqual(sharedObject.connected, connected && sharedObject.isAttached(), "connected");
199
- }));
200
- it("isAttached with detached transition to attach runtime", async () => {
201
- const runtimeEvents = new TypedEventEmitter();
202
- let didAttach = 0;
203
- const { overrides, sharedObject } = createTestSharedObject({
204
- runtime: {
205
- ...runtimeEvents,
206
- attachState: AttachState.Detached,
207
- connected: true,
208
- },
209
- didAttach: () => didAttach++,
210
- });
211
- sharedObject.connect(createOverridableProxy("services", {
212
- objectStorage: createOverridableProxy("objectStorage"),
213
- deltaConnection: createOverridableProxy("deltaConnection", {
214
- attach(handler) { },
215
- connected: overrides.runtime?.connected ?? false,
216
- }),
217
- }));
218
- assert.strictEqual(didAttach, 0, "!didAttach");
219
- assert.strictEqual(sharedObject.isAttached(), false, "!isAttached");
220
- assert(overrides.runtime);
221
- overrides.runtime.attachState = AttachState.Attaching;
222
- runtimeEvents.emit("attaching");
223
- overrides.runtime.attachState = AttachState.Attached;
224
- assert.strictEqual(sharedObject.isAttached(), true, "isAttached");
225
- assert.strictEqual(didAttach, 1, "didAttach");
226
- });
227
- });
228
- describe("shared object after load and connect", () => {
229
- runtimeAttachStateAndConnectedMatrix.forEach(({ connected, attachState }) => it(`With runtime ${JSON.stringify({
230
- connected,
231
- attachState,
232
- })}`, async () => {
233
- let loaded = false;
234
- let didAttach = 0;
235
- const { sharedObject } = createTestSharedObject({
236
- runtime: {
237
- attachState,
238
- connected,
239
- },
240
- didAttach: () => didAttach++,
241
- loadCore: async () => {
242
- loaded = true;
243
- },
244
- });
245
- let attachCalled = false;
246
- await sharedObject.load(createOverridableProxy("services", {
247
- objectStorage: createOverridableProxy("objectStorage"),
248
- deltaConnection: createOverridableProxy("deltaConnection", {
249
- attach(handler) {
250
- attachCalled = true;
251
- },
252
- connected,
253
- }),
254
- }));
255
- assert.strictEqual(loaded, true, "loaded");
256
- assert.strictEqual(attachCalled, true, "attachCalled");
257
- assert.strictEqual(didAttach, sharedObject.isAttached() ? 1 : 0, "didAttach");
258
- sharedObject.connect(createOverridableProxy("services"));
259
- assert.strictEqual(sharedObject.isAttached(), attachState !== AttachState.Detached, "isAttached");
260
- assert.strictEqual(sharedObject.connected, connected && sharedObject.isAttached(), "connected");
261
- }));
262
- });
263
- describe("shared object after bindToContext", () => {
264
- runtimeAttachStateAndConnectedMatrix.forEach(({ connected, attachState }) => it(`With runtime ${JSON.stringify({
265
- connected,
266
- attachState,
267
- })}`, async () => {
268
- let didAttach = 0;
269
- let attachCalled = false;
270
- const { sharedObject } = createTestSharedObject({
271
- runtime: {
272
- attachState,
273
- connected,
274
- bindChannel: (channel) => {
275
- assert.strictEqual(channel, sharedObject, "channel");
276
- // real bind to context calls connect, so simulate here
277
- sharedObject.connect(createOverridableProxy("services", {
278
- objectStorage: createOverridableProxy("objectStorage"),
279
- deltaConnection: createOverridableProxy("deltaConnection", {
280
- attach(handler) {
281
- attachCalled = true;
282
- },
283
- connected,
284
- }),
285
- }));
286
- },
287
- },
288
- didAttach: () => didAttach++,
289
- });
290
- sharedObject.bindToContext();
291
- assert.strictEqual(didAttach, sharedObject.isAttached() ? 1 : 0, "didAttach");
292
- assert.strictEqual(attachCalled, true, "attachCalled");
293
- assert.strictEqual(sharedObject.isAttached(), attachState !== AttachState.Detached, "isAttached");
294
- assert.strictEqual(sharedObject.connected, connected && sharedObject.isAttached(), "connected");
295
- }));
296
- it("isAttached with detached transition to attach runtime", async () => {
297
- const runtimeEvents = new TypedEventEmitter();
298
- let didAttach = 0;
299
- let attachCalled = false;
300
- const { overrides, sharedObject } = createTestSharedObject({
301
- runtime: {
302
- ...runtimeEvents,
303
- attachState: AttachState.Detached,
304
- connected: false,
305
- bindChannel: (channel) => {
306
- assert.strictEqual(channel, sharedObject, "channel");
307
- // real bind to context calls connect, so simulate here
308
- sharedObject.connect(createOverridableProxy("services", {
309
- objectStorage: createOverridableProxy("objectStorage"),
310
- deltaConnection: createOverridableProxy("deltaConnection", {
311
- attach(handler) {
312
- attachCalled = true;
313
- },
314
- connected: false,
315
- }),
316
- }));
317
- },
318
- },
319
- didAttach: () => didAttach++,
320
- });
321
- sharedObject.bindToContext();
322
- assert.strictEqual(didAttach, 0, "!didAttach");
323
- assert.strictEqual(attachCalled, true, "attachCalled");
324
- assert.strictEqual(sharedObject.isAttached(), false, "!isAttached");
325
- assert(overrides.runtime);
326
- overrides.runtime.attachState = AttachState.Attaching;
327
- runtimeEvents.emit("attaching");
328
- overrides.runtime.attachState = AttachState.Attached;
329
- assert.strictEqual(didAttach, 1, "didAttach");
330
- assert.strictEqual(sharedObject.isAttached(), true, "isAttached");
331
- });
332
- });
333
- });
334
- //# sourceMappingURL=attachingBindingAndConnecting.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"attachingBindingAndConnecting.spec.js","sourceRoot":"","sources":["../../src/test/attachingBindingAndConnecting.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 \"assert\";\nimport {\n\tIChannelStorageService,\n\ttype IChannelAttributes,\n\ttype IFluidDataStoreRuntime,\n\ttype IFluidDataStoreRuntimeEvents,\n\tIChannelServices,\n\tIDeltaConnection,\n} from \"@fluidframework/datastore-definitions\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport {\n\tISummaryTreeWithStats,\n\ttype IExperimentalIncrementalSummaryContext,\n\ttype ITelemetryContext,\n} from \"@fluidframework/runtime-definitions\";\nimport { createChildLogger } from \"@fluidframework/telemetry-utils\";\nimport { TypedEventEmitter } from \"@fluid-internal/client-utils\";\nimport { AttachState } from \"@fluidframework/container-definitions\";\nimport { generatePairwiseOptions } from \"@fluid-private/test-pairwise-generator\";\nimport { IFluidSerializer } from \"../serializer.js\";\nimport { SharedObject } from \"../sharedObject.js\";\n\ntype Overridable<T> = T extends ((...args: any) => any) | string | number | undefined | []\n\t? T\n\t: {\n\t\t\t-readonly [P in keyof T]?: Overridable<T[P]>;\n\t };\n\nfunction createOverridableProxy<T extends object>(name: string, ...overrides: Overridable<T>[]) {\n\treturn new Proxy<T>({} as any as T, {\n\t\tget: (_, p, r) => {\n\t\t\tfor (const override of overrides) {\n\t\t\t\tif (p in override) {\n\t\t\t\t\treturn Reflect.get(override, p, r);\n\t\t\t\t}\n\t\t\t}\n\t\t\tassert.fail(`No override for ${name}.${p.toString()}`);\n\t\t},\n\t});\n}\n\nfunction createTestSharedObject(\n\toverrides: Overridable<{\n\t\tid: string;\n\t\truntime: IFluidDataStoreRuntime;\n\t\tattributes: IChannelAttributes;\n\t\ttelemetryConfigPrefix: string;\n\t\tsummarizeCore: (\n\t\t\tthis: SharedObject,\n\t\t\tserializer: IFluidSerializer,\n\t\t\ttelemetryContext?: ITelemetryContext | undefined,\n\t\t\tincrementalSummaryContext?: IExperimentalIncrementalSummaryContext | undefined,\n\t\t) => ISummaryTreeWithStats;\n\t\tloadCore: (this: SharedObject, services: IChannelStorageService) => Promise<void>;\n\t\tprocessCore: (\n\t\t\tthis: SharedObject,\n\n\t\t\tmessage: ISequencedDocumentMessage,\n\t\t\tlocal: boolean,\n\t\t\tlocalOpMetadata: unknown,\n\t\t) => void;\n\t\tonDisconnect: (this: SharedObject) => void;\n\t\tapplyStashedOp: (this: SharedObject, content: any) => unknown;\n\t\tdidAttach: () => void;\n\t}>,\n) {\n\tclass TestSharedObject extends SharedObject {\n\t\tprotected summarizeCore = overrides?.summarizeCore?.bind(this);\n\t\tprotected loadCore = overrides?.loadCore?.bind(this);\n\t\tprotected processCore = overrides?.processCore?.bind(this);\n\t\tprotected onDisconnect = overrides?.onDisconnect?.bind(this);\n\t\tprotected applyStashedOp = overrides?.applyStashedOp?.bind(this);\n\t\tprotected didAttach =\n\t\t\toverrides.didAttach?.bind(this) ?? (() => assert.fail(\"didAttach not set\"));\n\t}\n\n\tconst runtime = overrides?.runtime ?? {};\n\truntime.channelsRoutingContext ??= {\n\t\tabsolutePath: \"/\",\n\t\tattachGraph: () => {},\n\t\tget IFluidHandleContext() {\n\t\t\treturn this;\n\t\t},\n\t\tisAttached: false,\n\t\tresolveHandle: async () => ({ status: 500, mimeType: \"error\", value: \"error\" }),\n\t};\n\truntime.IFluidHandleContext ??= runtime.channelsRoutingContext;\n\n\truntime.logger ??= createChildLogger();\n\n\tconst attributes = overrides?.attributes ?? {};\n\n\tattributes.type ??= \"TestSharedObject\";\n\n\treturn {\n\t\toverrides,\n\t\tsharedObject: new TestSharedObject(\n\t\t\toverrides?.id ?? \"testSharedObject\",\n\t\t\tcreateOverridableProxy<IFluidDataStoreRuntime>(\n\t\t\t\t\"runtime\",\n\t\t\t\truntime,\n\t\t\t\tnew TypedEventEmitter<IFluidDataStoreRuntimeEvents>() as any as Overridable<IFluidDataStoreRuntime>,\n\t\t\t),\n\t\t\tcreateOverridableProxy<IChannelAttributes>(\"attributes\", attributes),\n\t\t\toverrides?.telemetryConfigPrefix ?? \"testSharedObject\",\n\t\t),\n\t};\n}\n\n/**\n * The attach state of a shared object is determined by two facts:\n *\n * * Is it bound to a context which means its handle is stored in an already bound dds\n * * Is the runtime attached\n *\n * If both of these are true, then the dds should be considered attached.\n *\n * Beyond attach, there is also the connected state, and the didAttach method.\n * The connected state should always be false while detached, and didAttach should only be called once when the dds transitions.\n *\n * These tests valid these properties across all the functions that can cause attach state transitions\n */\ndescribe(\"SharedObject attaching binding and connecting\", () => {\n\tconst runtimeAttachStateAndConnectedMatrix = generatePairwiseOptions({\n\t\tconnected: [true, false],\n\t\tattachState: [AttachState.Detached, AttachState.Attaching, AttachState.Attached],\n\t});\n\n\tdescribe(\"shared object after creation\", () => {\n\t\truntimeAttachStateAndConnectedMatrix.forEach(({ connected, attachState }) =>\n\t\t\tit(`!isAttached and !connected with runtime ${JSON.stringify({\n\t\t\t\tconnected,\n\t\t\t\tattachState,\n\t\t\t})}`, () => {\n\t\t\t\tconst { sharedObject } = createTestSharedObject({\n\t\t\t\t\truntime: {\n\t\t\t\t\t\tattachState,\n\t\t\t\t\t\tconnected,\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tassert.strictEqual(sharedObject.isAttached(), false, \"!isAttached\");\n\t\t\t\tassert.strictEqual(sharedObject.connected, false, \"!connected\");\n\t\t\t}),\n\t\t);\n\n\t\tit(\"!isAttached with detached transition to attach runtime\", () => {\n\t\t\tconst runtimeEvents = new TypedEventEmitter<IFluidDataStoreRuntimeEvents>();\n\n\t\t\tlet didAttach = 0;\n\t\t\tconst { overrides, sharedObject } = createTestSharedObject({\n\t\t\t\truntime: {\n\t\t\t\t\t...(runtimeEvents as any as Overridable<IFluidDataStoreRuntime>),\n\t\t\t\t\tattachState: AttachState.Detached,\n\t\t\t\t},\n\t\t\t\tdidAttach: () => didAttach++,\n\t\t\t});\n\n\t\t\tassert.strictEqual(didAttach, 0, \"!didAttach\");\n\t\t\tassert.strictEqual(sharedObject.isAttached(), false, \"!isAttached\");\n\n\t\t\tassert(overrides.runtime);\n\t\t\toverrides.runtime.attachState = AttachState.Attaching;\n\t\t\truntimeEvents.emit(\"attaching\");\n\t\t\toverrides.runtime.attachState = AttachState.Attached;\n\n\t\t\tassert.strictEqual(sharedObject.isAttached(), false, \"!isAttached\");\n\t\t\tassert.strictEqual(didAttach, 0, \"!didAttach\");\n\t\t});\n\t});\n\n\tdescribe(\"shared object after load\", () => {\n\t\truntimeAttachStateAndConnectedMatrix.forEach(({ connected, attachState }) =>\n\t\t\tit(`With runtime ${JSON.stringify({\n\t\t\t\tconnected,\n\t\t\t\tattachState,\n\t\t\t})}`, async () => {\n\t\t\t\tlet loaded = false;\n\t\t\t\tlet didAttach = 0;\n\t\t\t\tconst { sharedObject } = createTestSharedObject({\n\t\t\t\t\truntime: {\n\t\t\t\t\t\tattachState,\n\t\t\t\t\t\tconnected,\n\t\t\t\t\t},\n\t\t\t\t\tloadCore: async () => {\n\t\t\t\t\t\tloaded = true;\n\t\t\t\t\t},\n\t\t\t\t\tdidAttach: () => didAttach++,\n\t\t\t\t});\n\n\t\t\t\tlet attachCalled = false;\n\t\t\t\tawait sharedObject.load(\n\t\t\t\t\tcreateOverridableProxy<IChannelServices>(\"services\", {\n\t\t\t\t\t\tobjectStorage: createOverridableProxy(\"objectStorage\"),\n\t\t\t\t\t\tdeltaConnection: createOverridableProxy<IDeltaConnection>(\n\t\t\t\t\t\t\t\"deltaConnection\",\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tattach(handler) {\n\t\t\t\t\t\t\t\t\tattachCalled = true;\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tconnected,\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\tassert.strictEqual(loaded, true, \"loaded\");\n\t\t\t\tassert.strictEqual(attachCalled, true, \"attachCalled\");\n\t\t\t\tassert.strictEqual(didAttach, sharedObject.isAttached() ? 1 : 0, \"didAttach\");\n\n\t\t\t\tassert.strictEqual(\n\t\t\t\t\tsharedObject.isAttached(),\n\t\t\t\t\tattachState !== AttachState.Detached,\n\t\t\t\t\t\"isAttached\",\n\t\t\t\t);\n\t\t\t\tassert.strictEqual(\n\t\t\t\t\tsharedObject.connected,\n\t\t\t\t\tconnected && sharedObject.isAttached(),\n\t\t\t\t\t\"connected\",\n\t\t\t\t);\n\t\t\t}),\n\t\t);\n\n\t\tit(\"isAttached with detached transition to attach runtime\", async () => {\n\t\t\tconst runtimeEvents = new TypedEventEmitter<IFluidDataStoreRuntimeEvents>();\n\n\t\t\tlet didAttach = 0;\n\t\t\tlet loaded = false;\n\t\t\tconst { overrides, sharedObject } = createTestSharedObject({\n\t\t\t\truntime: {\n\t\t\t\t\t...(runtimeEvents as any as Overridable<IFluidDataStoreRuntime>),\n\t\t\t\t\tattachState: AttachState.Detached,\n\t\t\t\t\tconnected: true,\n\t\t\t\t},\n\t\t\t\tdidAttach: () => didAttach++,\n\t\t\t\tloadCore: async () => {\n\t\t\t\t\tloaded = true;\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tawait sharedObject.load(\n\t\t\t\tcreateOverridableProxy<IChannelServices>(\"services\", {\n\t\t\t\t\tobjectStorage: createOverridableProxy(\"objectStorage\"),\n\t\t\t\t\tdeltaConnection: createOverridableProxy<IDeltaConnection>(\"deltaConnection\", {\n\t\t\t\t\t\tattach(handler) {},\n\t\t\t\t\t\tconnected: overrides.runtime?.connected ?? false,\n\t\t\t\t\t}),\n\t\t\t\t}),\n\t\t\t);\n\n\t\t\tassert.strictEqual(didAttach, 0, \"!didAttach\");\n\t\t\tassert.strictEqual(loaded, true, \"loaded\");\n\t\t\tassert.strictEqual(sharedObject.isAttached(), false, \"!isAttached\");\n\n\t\t\tassert(overrides.runtime);\n\t\t\toverrides.runtime.attachState = AttachState.Attaching;\n\t\t\truntimeEvents.emit(\"attaching\");\n\t\t\toverrides.runtime.attachState = AttachState.Attached;\n\n\t\t\tassert.strictEqual(sharedObject.isAttached(), true, \"isAttached\");\n\t\t\tassert.strictEqual(didAttach, 1, \"didAttach\");\n\t\t});\n\t});\n\n\tdescribe(\"shared object after connect\", () => {\n\t\truntimeAttachStateAndConnectedMatrix.forEach(({ connected, attachState }) =>\n\t\t\tit(`With runtime ${JSON.stringify({\n\t\t\t\tconnected,\n\t\t\t\tattachState,\n\t\t\t})}`, async () => {\n\t\t\t\tlet didAttach = 0;\n\t\t\t\tconst { sharedObject } = createTestSharedObject({\n\t\t\t\t\truntime: {\n\t\t\t\t\t\tattachState,\n\t\t\t\t\t\tconnected,\n\t\t\t\t\t},\n\t\t\t\t\tdidAttach: () => didAttach++,\n\t\t\t\t});\n\n\t\t\t\tlet attachCalled = false;\n\t\t\t\tsharedObject.connect(\n\t\t\t\t\tcreateOverridableProxy<IChannelServices>(\"services\", {\n\t\t\t\t\t\tobjectStorage: createOverridableProxy(\"objectStorage\"),\n\t\t\t\t\t\tdeltaConnection: createOverridableProxy<IDeltaConnection>(\n\t\t\t\t\t\t\t\"deltaConnection\",\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tattach(handler) {\n\t\t\t\t\t\t\t\t\tattachCalled = true;\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tconnected,\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\tassert.strictEqual(attachCalled, true, \"attachCalled\");\n\t\t\t\tassert.strictEqual(didAttach, sharedObject.isAttached() ? 1 : 0, \"didAttach\");\n\n\t\t\t\tassert.strictEqual(\n\t\t\t\t\tsharedObject.isAttached(),\n\t\t\t\t\tattachState !== AttachState.Detached,\n\t\t\t\t\t\"isAttached\",\n\t\t\t\t);\n\t\t\t\tassert.strictEqual(\n\t\t\t\t\tsharedObject.connected,\n\t\t\t\t\tconnected && sharedObject.isAttached(),\n\t\t\t\t\t\"connected\",\n\t\t\t\t);\n\t\t\t}),\n\t\t);\n\n\t\tit(\"isAttached with detached transition to attach runtime\", async () => {\n\t\t\tconst runtimeEvents = new TypedEventEmitter<IFluidDataStoreRuntimeEvents>();\n\n\t\t\tlet didAttach = 0;\n\t\t\tconst { overrides, sharedObject } = createTestSharedObject({\n\t\t\t\truntime: {\n\t\t\t\t\t...(runtimeEvents as any as Overridable<IFluidDataStoreRuntime>),\n\t\t\t\t\tattachState: AttachState.Detached,\n\t\t\t\t\tconnected: true,\n\t\t\t\t},\n\t\t\t\tdidAttach: () => didAttach++,\n\t\t\t});\n\n\t\t\tsharedObject.connect(\n\t\t\t\tcreateOverridableProxy<IChannelServices>(\"services\", {\n\t\t\t\t\tobjectStorage: createOverridableProxy(\"objectStorage\"),\n\t\t\t\t\tdeltaConnection: createOverridableProxy<IDeltaConnection>(\"deltaConnection\", {\n\t\t\t\t\t\tattach(handler) {},\n\t\t\t\t\t\tconnected: overrides.runtime?.connected ?? false,\n\t\t\t\t\t}),\n\t\t\t\t}),\n\t\t\t);\n\n\t\t\tassert.strictEqual(didAttach, 0, \"!didAttach\");\n\n\t\t\tassert.strictEqual(sharedObject.isAttached(), false, \"!isAttached\");\n\n\t\t\tassert(overrides.runtime);\n\t\t\toverrides.runtime.attachState = AttachState.Attaching;\n\t\t\truntimeEvents.emit(\"attaching\");\n\t\t\toverrides.runtime.attachState = AttachState.Attached;\n\n\t\t\tassert.strictEqual(sharedObject.isAttached(), true, \"isAttached\");\n\t\t\tassert.strictEqual(didAttach, 1, \"didAttach\");\n\t\t});\n\t});\n\n\tdescribe(\"shared object after load and connect\", () => {\n\t\truntimeAttachStateAndConnectedMatrix.forEach(({ connected, attachState }) =>\n\t\t\tit(`With runtime ${JSON.stringify({\n\t\t\t\tconnected,\n\t\t\t\tattachState,\n\t\t\t})}`, async () => {\n\t\t\t\tlet loaded = false;\n\t\t\t\tlet didAttach = 0;\n\t\t\t\tconst { sharedObject } = createTestSharedObject({\n\t\t\t\t\truntime: {\n\t\t\t\t\t\tattachState,\n\t\t\t\t\t\tconnected,\n\t\t\t\t\t},\n\t\t\t\t\tdidAttach: () => didAttach++,\n\t\t\t\t\tloadCore: async () => {\n\t\t\t\t\t\tloaded = true;\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tlet attachCalled = false;\n\t\t\t\tawait sharedObject.load(\n\t\t\t\t\tcreateOverridableProxy<IChannelServices>(\"services\", {\n\t\t\t\t\t\tobjectStorage: createOverridableProxy(\"objectStorage\"),\n\t\t\t\t\t\tdeltaConnection: createOverridableProxy<IDeltaConnection>(\n\t\t\t\t\t\t\t\"deltaConnection\",\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tattach(handler) {\n\t\t\t\t\t\t\t\t\tattachCalled = true;\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tconnected,\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\tassert.strictEqual(loaded, true, \"loaded\");\n\t\t\t\tassert.strictEqual(attachCalled, true, \"attachCalled\");\n\t\t\t\tassert.strictEqual(didAttach, sharedObject.isAttached() ? 1 : 0, \"didAttach\");\n\n\t\t\t\tsharedObject.connect(createOverridableProxy<IChannelServices>(\"services\"));\n\n\t\t\t\tassert.strictEqual(\n\t\t\t\t\tsharedObject.isAttached(),\n\t\t\t\t\tattachState !== AttachState.Detached,\n\t\t\t\t\t\"isAttached\",\n\t\t\t\t);\n\t\t\t\tassert.strictEqual(\n\t\t\t\t\tsharedObject.connected,\n\t\t\t\t\tconnected && sharedObject.isAttached(),\n\t\t\t\t\t\"connected\",\n\t\t\t\t);\n\t\t\t}),\n\t\t);\n\t});\n\n\tdescribe(\"shared object after bindToContext\", () => {\n\t\truntimeAttachStateAndConnectedMatrix.forEach(({ connected, attachState }) =>\n\t\t\tit(`With runtime ${JSON.stringify({\n\t\t\t\tconnected,\n\t\t\t\tattachState,\n\t\t\t})}`, async () => {\n\t\t\t\tlet didAttach = 0;\n\t\t\t\tlet attachCalled = false;\n\t\t\t\tconst { sharedObject } = createTestSharedObject({\n\t\t\t\t\truntime: {\n\t\t\t\t\t\tattachState,\n\t\t\t\t\t\tconnected,\n\t\t\t\t\t\tbindChannel: (channel) => {\n\t\t\t\t\t\t\tassert.strictEqual(channel, sharedObject, \"channel\");\n\t\t\t\t\t\t\t// real bind to context calls connect, so simulate here\n\t\t\t\t\t\t\tsharedObject.connect(\n\t\t\t\t\t\t\t\tcreateOverridableProxy<IChannelServices>(\"services\", {\n\t\t\t\t\t\t\t\t\tobjectStorage: createOverridableProxy(\"objectStorage\"),\n\t\t\t\t\t\t\t\t\tdeltaConnection: createOverridableProxy<IDeltaConnection>(\n\t\t\t\t\t\t\t\t\t\t\"deltaConnection\",\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tattach(handler) {\n\t\t\t\t\t\t\t\t\t\t\t\tattachCalled = true;\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\tconnected,\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\tdidAttach: () => didAttach++,\n\t\t\t\t});\n\n\t\t\t\tsharedObject.bindToContext();\n\t\t\t\tassert.strictEqual(didAttach, sharedObject.isAttached() ? 1 : 0, \"didAttach\");\n\t\t\t\tassert.strictEqual(attachCalled, true, \"attachCalled\");\n\n\t\t\t\tassert.strictEqual(\n\t\t\t\t\tsharedObject.isAttached(),\n\t\t\t\t\tattachState !== AttachState.Detached,\n\t\t\t\t\t\"isAttached\",\n\t\t\t\t);\n\t\t\t\tassert.strictEqual(\n\t\t\t\t\tsharedObject.connected,\n\t\t\t\t\tconnected && sharedObject.isAttached(),\n\t\t\t\t\t\"connected\",\n\t\t\t\t);\n\t\t\t}),\n\t\t);\n\n\t\tit(\"isAttached with detached transition to attach runtime\", async () => {\n\t\t\tconst runtimeEvents = new TypedEventEmitter<IFluidDataStoreRuntimeEvents>();\n\t\t\tlet didAttach = 0;\n\t\t\tlet attachCalled = false;\n\t\t\tconst { overrides, sharedObject } = createTestSharedObject({\n\t\t\t\truntime: {\n\t\t\t\t\t...(runtimeEvents as any),\n\t\t\t\t\tattachState: AttachState.Detached,\n\t\t\t\t\tconnected: false,\n\t\t\t\t\tbindChannel: (channel) => {\n\t\t\t\t\t\tassert.strictEqual(channel, sharedObject, \"channel\");\n\t\t\t\t\t\t// real bind to context calls connect, so simulate here\n\t\t\t\t\t\tsharedObject.connect(\n\t\t\t\t\t\t\tcreateOverridableProxy<IChannelServices>(\"services\", {\n\t\t\t\t\t\t\t\tobjectStorage: createOverridableProxy(\"objectStorage\"),\n\t\t\t\t\t\t\t\tdeltaConnection: createOverridableProxy<IDeltaConnection>(\n\t\t\t\t\t\t\t\t\t\"deltaConnection\",\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tattach(handler) {\n\t\t\t\t\t\t\t\t\t\t\tattachCalled = true;\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tconnected: false,\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},\n\t\t\t\tdidAttach: () => didAttach++,\n\t\t\t});\n\n\t\t\tsharedObject.bindToContext();\n\n\t\t\tassert.strictEqual(didAttach, 0, \"!didAttach\");\n\t\t\tassert.strictEqual(attachCalled, true, \"attachCalled\");\n\t\t\tassert.strictEqual(sharedObject.isAttached(), false, \"!isAttached\");\n\n\t\t\tassert(overrides.runtime);\n\t\t\toverrides.runtime.attachState = AttachState.Attaching;\n\t\t\truntimeEvents.emit(\"attaching\");\n\t\t\toverrides.runtime.attachState = AttachState.Attached;\n\n\t\t\tassert.strictEqual(didAttach, 1, \"didAttach\");\n\t\t\tassert.strictEqual(sharedObject.isAttached(), true, \"isAttached\");\n\t\t});\n\t});\n});\n"]}
@@ -1,166 +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 "assert";
6
- import { RemoteFluidObjectHandle } from "../remoteObjectHandle.js";
7
- import { FluidSerializer } from "../serializer.js";
8
- import { makeJson, MockHandleContext } from "./utils.js";
9
- describe("FluidSerializer", () => {
10
- function printHandle(target) {
11
- return JSON.stringify(target, (key, value) => {
12
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
13
- return value?.IFluidHandle !== undefined ? "#HANDLE" : value;
14
- });
15
- }
16
- function createNestedCases(testCases) {
17
- // Add an object where each field references one of the JSON serializable types.
18
- testCases.push(testCases.reduce((o, value, index) => {
19
- o[`f${index}`] = value;
20
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
21
- return o;
22
- }, {}));
23
- // Add an array that contains each of our constructed test cases.
24
- testCases.push([...testCases]);
25
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
26
- return testCases;
27
- }
28
- describe("vanilla JSON", () => {
29
- const context = new MockHandleContext();
30
- const serializer = new FluidSerializer(context, (parsedHandle) => { });
31
- const handle = new RemoteFluidObjectHandle("/root", context);
32
- // Start with the various JSON-serializable types. A mix of "truthy" and "falsy" values
33
- // are of particular interest.
34
- const simple = createNestedCases([false, true, 0, 1, "", "x", null, [], {}]);
35
- // Add an object where each field references one of the JSON serializable types.
36
- simple.push(simple.reduce((o, value, index) => {
37
- o[`f${index}`] = value;
38
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
39
- return o;
40
- }, {}));
41
- // Add an array that contains each of our constructed test cases.
42
- simple.push([...simple]);
43
- // Verify that `encode` is a no-op for these simple cases.
44
- for (const input of simple) {
45
- it(`${printHandle(input)} -> ${JSON.stringify(input)}`, () => {
46
- const actual = serializer.encode(input, handle);
47
- assert.strictEqual(actual, input, "encode() on input with no handles must return original input.");
48
- const decoded = serializer.decode(actual);
49
- assert.strictEqual(decoded, input, "decode() on input with no handles must return original input.");
50
- assert.deepStrictEqual(decoded, input, "input must round-trip through decode(encode()).");
51
- const stringified = serializer.stringify(input, handle);
52
- // Paranoid check that serializer.stringify() and JSON.stringify() agree.
53
- assert.deepStrictEqual(stringified, JSON.stringify(input), "stringify() of input without handles must produce same result as JSON.stringify().");
54
- const parsed = serializer.parse(stringified);
55
- assert.deepStrictEqual(parsed, input, "input must round-trip through parse(stringify()).");
56
- // Paranoid check that serializer.parse() and JSON.parse() agree.
57
- assert.deepStrictEqual(parsed, JSON.parse(stringified), "parse() of input without handles must produce same result as JSON.parse().");
58
- });
59
- }
60
- // Non-finite numbers are coerced to null. Date is coerced to string.
61
- const tricky = createNestedCases([-Infinity, NaN, +Infinity, new Date()]);
62
- // Undefined is extra special in that it can't appear at the root, but can appear
63
- // embedded in the tree, in which case the key is elided (if an object) or it is
64
- // coerced to null (if in an array).
65
- tricky.push({ u: undefined }, [undefined]);
66
- for (const input of tricky) {
67
- it(`${printHandle(input)} -> ${JSON.stringify(input)}`, () => {
68
- const actual = serializer.encode(input, handle);
69
- assert.strictEqual(actual, input, "encode() on input with no handles must return original input.");
70
- const decoded = serializer.decode(actual);
71
- assert.strictEqual(decoded, input, "decode() on input with no handles must return original input.");
72
- assert.deepStrictEqual(decoded, input, "input must round-trip through decode(encode()).");
73
- const stringified = serializer.stringify(input, handle);
74
- // Check that serializer.stringify() and JSON.stringify() agree.
75
- assert.deepStrictEqual(stringified, JSON.stringify(input), "stringify() of input without handles must produce same result as JSON.stringify().");
76
- const parsed = serializer.parse(stringified);
77
- // Check that serializer.parse() and JSON.parse() agree.
78
- assert.deepStrictEqual(parsed, JSON.parse(stringified), "parse() of input without handles must produce same result as JSON.parse().");
79
- });
80
- }
81
- // Undefined is extra special in that it can't be stringified at the root of the tree.
82
- it("'undefined' must round-trip through decode(replaceHandes(...))", () => {
83
- assert.strictEqual(serializer.encode(undefined, handle), undefined);
84
- assert.strictEqual(serializer.decode(undefined), undefined);
85
- });
86
- });
87
- describe("JSON w/embedded handles", () => {
88
- const context = new MockHandleContext();
89
- const serializer = new FluidSerializer(context, (parsedHandle) => { });
90
- const handle = new RemoteFluidObjectHandle("/root", context);
91
- const serializedHandle = {
92
- type: "__fluid_handle__",
93
- url: "/root",
94
- };
95
- function check(input, expected) {
96
- it(`${printHandle(input)} -> ${JSON.stringify(expected)}`, () => {
97
- const replaced = serializer.encode(input, handle);
98
- assert.notStrictEqual(replaced, input, "encode() must shallow-clone rather than mutate original object.");
99
- assert.deepStrictEqual(replaced, expected, "encode() must return expected output.");
100
- const decoded = serializer.decode(replaced);
101
- assert.notStrictEqual(decoded, input, "decode() must shallow-clone rather than mutate original object.");
102
- assert.deepStrictEqual(decoded, input, "input must round-trip through encode()/decode().");
103
- const stringified = serializer.stringify(input, handle);
104
- // Note that we're using JSON.parse() in this test, so the handles remained serialized.
105
- assert.deepStrictEqual(JSON.parse(stringified), expected, "Round-trip through stringify()/JSON.parse() must produce the same output as encode()");
106
- const parsed = serializer.parse(stringified);
107
- assert.deepStrictEqual(parsed, input, "input must round-trip through stringify()/parse().");
108
- });
109
- }
110
- check(handle, serializedHandle);
111
- check([handle], [serializedHandle]);
112
- check({ handle }, { handle: serializedHandle });
113
- check([{ handle }, { handle }], [{ handle: serializedHandle }, { handle: serializedHandle }]);
114
- it(`sizable json tree`, () => {
115
- const input = makeJson(
116
- /* breadth: */ 4,
117
- /* depth: */ 4,
118
- /* createLeaf: */ () => ({
119
- a: 0,
120
- b: handle,
121
- c: [handle, handle],
122
- d: false,
123
- e: handle,
124
- }));
125
- // Add some handles to intermediate objects.
126
- input.h = handle;
127
- input.o1.h = handle;
128
- const replaced = serializer.encode(input, handle);
129
- assert.notStrictEqual(replaced, input, "encode() must shallow-clone rather than mutate original object.");
130
- const decoded = serializer.decode(replaced);
131
- assert.notStrictEqual(decoded, input, "decode() must shallow-clone rather than mutate original object.");
132
- assert.deepStrictEqual(decoded, input, "input must round-trip through encode()/decode().");
133
- const stringified = serializer.stringify(input, handle);
134
- const parsed = serializer.parse(stringified);
135
- assert.deepStrictEqual(parsed, input, "input must round-trip through stringify()/parse().");
136
- });
137
- });
138
- describe("Parse handles with absolute / relative paths", () => {
139
- const rootContext = new MockHandleContext("");
140
- const dsContext = new MockHandleContext("/default", rootContext);
141
- // Create serialized with a handle context whose parent is a root handle context.
142
- const serializer = new FluidSerializer(dsContext, (parsedHandle) => { });
143
- it("can parse handles with absolute path", () => {
144
- const serializedHandle = JSON.stringify({
145
- type: "__fluid_handle__",
146
- url: "/default/sharedDDS", // absolute path
147
- });
148
- // Parse a handle whose url is absolute path.
149
- const parsedHandle = serializer.parse(serializedHandle);
150
- assert.strictEqual(parsedHandle.absolutePath, "/default/sharedDDS", "Incorrect absolute path in parsed handle");
151
- assert.strictEqual(parsedHandle.routeContext.absolutePath, "", "Parsed handle's route context should be the root context");
152
- });
153
- it("can parse handles with relative path", () => {
154
- const serializedHandle = JSON.stringify({
155
- type: "__fluid_handle__",
156
- url: "sharedDDS", // relative path
157
- });
158
- // Parse a handle whose url is a path relative to its route context. The serializer will generate absolute
159
- // path for the handle and create a handle with it.
160
- const parsedHandle = serializer.parse(serializedHandle);
161
- assert.strictEqual(parsedHandle.absolutePath, "/default/sharedDDS", "Incorrect absolute path in parsed handle");
162
- assert.strictEqual(parsedHandle.routeContext.absolutePath, "", "Parsed handle's route context should be the root context");
163
- });
164
- });
165
- });
166
- //# sourceMappingURL=serializer.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"serializer.spec.js","sourceRoot":"","sources":["../../src/test/serializer.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 \"assert\";\nimport { IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport { RemoteFluidObjectHandle } from \"../remoteObjectHandle.js\";\nimport { FluidSerializer } from \"../serializer.js\";\nimport { makeJson, MockHandleContext } from \"./utils.js\";\n\ndescribe(\"FluidSerializer\", () => {\n\tfunction printHandle(target: any) {\n\t\treturn JSON.stringify(target, (key, value) => {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\t\treturn value?.IFluidHandle !== undefined ? \"#HANDLE\" : value;\n\t\t});\n\t}\n\n\tfunction createNestedCases(testCases: any[]) {\n\t\t// Add an object where each field references one of the JSON serializable types.\n\t\ttestCases.push(\n\t\t\ttestCases.reduce<any>((o, value, index) => {\n\t\t\t\to[`f${index}`] = value;\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\t\t\treturn o;\n\t\t\t}, {}),\n\t\t);\n\n\t\t// Add an array that contains each of our constructed test cases.\n\t\ttestCases.push([...testCases]);\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\treturn testCases;\n\t}\n\n\tdescribe(\"vanilla JSON\", () => {\n\t\tconst context = new MockHandleContext();\n\t\tconst serializer = new FluidSerializer(context, (parsedHandle: IFluidHandle) => {});\n\t\tconst handle = new RemoteFluidObjectHandle(\"/root\", context);\n\n\t\t// Start with the various JSON-serializable types. A mix of \"truthy\" and \"falsy\" values\n\t\t// are of particular interest.\n\t\tconst simple = createNestedCases([false, true, 0, 1, \"\", \"x\", null, [], {}]);\n\n\t\t// Add an object where each field references one of the JSON serializable types.\n\t\tsimple.push(\n\t\t\tsimple.reduce<any>((o, value, index) => {\n\t\t\t\to[`f${index}`] = value;\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\t\t\treturn o;\n\t\t\t}, {}),\n\t\t);\n\n\t\t// Add an array that contains each of our constructed test cases.\n\t\tsimple.push([...simple]);\n\n\t\t// Verify that `encode` is a no-op for these simple cases.\n\t\tfor (const input of simple) {\n\t\t\tit(`${printHandle(input)} -> ${JSON.stringify(input)}`, () => {\n\t\t\t\tconst actual = serializer.encode(input, handle);\n\t\t\t\tassert.strictEqual(\n\t\t\t\t\tactual,\n\t\t\t\t\tinput,\n\t\t\t\t\t\"encode() on input with no handles must return original input.\",\n\t\t\t\t);\n\n\t\t\t\tconst decoded = serializer.decode(actual);\n\t\t\t\tassert.strictEqual(\n\t\t\t\t\tdecoded,\n\t\t\t\t\tinput,\n\t\t\t\t\t\"decode() on input with no handles must return original input.\",\n\t\t\t\t);\n\t\t\t\tassert.deepStrictEqual(\n\t\t\t\t\tdecoded,\n\t\t\t\t\tinput,\n\t\t\t\t\t\"input must round-trip through decode(encode()).\",\n\t\t\t\t);\n\n\t\t\t\tconst stringified = serializer.stringify(input, handle);\n\t\t\t\t// Paranoid check that serializer.stringify() and JSON.stringify() agree.\n\t\t\t\tassert.deepStrictEqual(\n\t\t\t\t\tstringified,\n\t\t\t\t\tJSON.stringify(input),\n\t\t\t\t\t\"stringify() of input without handles must produce same result as JSON.stringify().\",\n\t\t\t\t);\n\n\t\t\t\tconst parsed = serializer.parse(stringified);\n\t\t\t\tassert.deepStrictEqual(\n\t\t\t\t\tparsed,\n\t\t\t\t\tinput,\n\t\t\t\t\t\"input must round-trip through parse(stringify()).\",\n\t\t\t\t);\n\n\t\t\t\t// Paranoid check that serializer.parse() and JSON.parse() agree.\n\t\t\t\tassert.deepStrictEqual(\n\t\t\t\t\tparsed,\n\t\t\t\t\tJSON.parse(stringified),\n\t\t\t\t\t\"parse() of input without handles must produce same result as JSON.parse().\",\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\n\t\t// Non-finite numbers are coerced to null. Date is coerced to string.\n\t\tconst tricky = createNestedCases([-Infinity, NaN, +Infinity, new Date()]);\n\n\t\t// Undefined is extra special in that it can't appear at the root, but can appear\n\t\t// embedded in the tree, in which case the key is elided (if an object) or it is\n\t\t// coerced to null (if in an array).\n\t\ttricky.push({ u: undefined }, [undefined]);\n\n\t\tfor (const input of tricky) {\n\t\t\tit(`${printHandle(input)} -> ${JSON.stringify(input)}`, () => {\n\t\t\t\tconst actual = serializer.encode(input, handle);\n\t\t\t\tassert.strictEqual(\n\t\t\t\t\tactual,\n\t\t\t\t\tinput,\n\t\t\t\t\t\"encode() on input with no handles must return original input.\",\n\t\t\t\t);\n\n\t\t\t\tconst decoded = serializer.decode(actual);\n\t\t\t\tassert.strictEqual(\n\t\t\t\t\tdecoded,\n\t\t\t\t\tinput,\n\t\t\t\t\t\"decode() on input with no handles must return original input.\",\n\t\t\t\t);\n\t\t\t\tassert.deepStrictEqual(\n\t\t\t\t\tdecoded,\n\t\t\t\t\tinput,\n\t\t\t\t\t\"input must round-trip through decode(encode()).\",\n\t\t\t\t);\n\n\t\t\t\tconst stringified = serializer.stringify(input, handle);\n\t\t\t\t// Check that serializer.stringify() and JSON.stringify() agree.\n\t\t\t\tassert.deepStrictEqual(\n\t\t\t\t\tstringified,\n\t\t\t\t\tJSON.stringify(input),\n\t\t\t\t\t\"stringify() of input without handles must produce same result as JSON.stringify().\",\n\t\t\t\t);\n\n\t\t\t\tconst parsed = serializer.parse(stringified);\n\t\t\t\t// Check that serializer.parse() and JSON.parse() agree.\n\t\t\t\tassert.deepStrictEqual(\n\t\t\t\t\tparsed,\n\t\t\t\t\tJSON.parse(stringified),\n\t\t\t\t\t\"parse() of input without handles must produce same result as JSON.parse().\",\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\n\t\t// Undefined is extra special in that it can't be stringified at the root of the tree.\n\t\tit(\"'undefined' must round-trip through decode(replaceHandes(...))\", () => {\n\t\t\tassert.strictEqual(serializer.encode(undefined, handle), undefined);\n\t\t\tassert.strictEqual(serializer.decode(undefined), undefined);\n\t\t});\n\t});\n\n\tdescribe(\"JSON w/embedded handles\", () => {\n\t\tconst context = new MockHandleContext();\n\t\tconst serializer = new FluidSerializer(context, (parsedHandle: IFluidHandle) => {});\n\t\tconst handle = new RemoteFluidObjectHandle(\"/root\", context);\n\t\tconst serializedHandle = {\n\t\t\ttype: \"__fluid_handle__\",\n\t\t\turl: \"/root\",\n\t\t};\n\n\t\tfunction check(input, expected) {\n\t\t\tit(`${printHandle(input)} -> ${JSON.stringify(expected)}`, () => {\n\t\t\t\tconst replaced = serializer.encode(input, handle);\n\t\t\t\tassert.notStrictEqual(\n\t\t\t\t\treplaced,\n\t\t\t\t\tinput,\n\t\t\t\t\t\"encode() must shallow-clone rather than mutate original object.\",\n\t\t\t\t);\n\t\t\t\tassert.deepStrictEqual(replaced, expected, \"encode() must return expected output.\");\n\n\t\t\t\tconst decoded = serializer.decode(replaced);\n\t\t\t\tassert.notStrictEqual(\n\t\t\t\t\tdecoded,\n\t\t\t\t\tinput,\n\t\t\t\t\t\"decode() must shallow-clone rather than mutate original object.\",\n\t\t\t\t);\n\t\t\t\tassert.deepStrictEqual(\n\t\t\t\t\tdecoded,\n\t\t\t\t\tinput,\n\t\t\t\t\t\"input must round-trip through encode()/decode().\",\n\t\t\t\t);\n\n\t\t\t\tconst stringified = serializer.stringify(input, handle);\n\n\t\t\t\t// Note that we're using JSON.parse() in this test, so the handles remained serialized.\n\t\t\t\tassert.deepStrictEqual(\n\t\t\t\t\tJSON.parse(stringified),\n\t\t\t\t\texpected,\n\t\t\t\t\t\"Round-trip through stringify()/JSON.parse() must produce the same output as encode()\",\n\t\t\t\t);\n\n\t\t\t\tconst parsed = serializer.parse(stringified);\n\t\t\t\tassert.deepStrictEqual(\n\t\t\t\t\tparsed,\n\t\t\t\t\tinput,\n\t\t\t\t\t\"input must round-trip through stringify()/parse().\",\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\n\t\tcheck(handle, serializedHandle);\n\t\tcheck([handle], [serializedHandle]);\n\t\tcheck({ handle }, { handle: serializedHandle });\n\t\tcheck(\n\t\t\t[{ handle }, { handle }],\n\t\t\t[{ handle: serializedHandle }, { handle: serializedHandle }],\n\t\t);\n\n\t\tit(`sizable json tree`, () => {\n\t\t\tconst input: any = makeJson(\n\t\t\t\t/* breadth: */ 4,\n\t\t\t\t/* depth: */ 4,\n\t\t\t\t/* createLeaf: */ () => ({\n\t\t\t\t\ta: 0,\n\t\t\t\t\tb: handle,\n\t\t\t\t\tc: [handle, handle],\n\t\t\t\t\td: false,\n\t\t\t\t\te: handle,\n\t\t\t\t}),\n\t\t\t);\n\n\t\t\t// Add some handles to intermediate objects.\n\t\t\tinput.h = handle;\n\t\t\tinput.o1.h = handle;\n\n\t\t\tconst replaced = serializer.encode(input, handle);\n\t\t\tassert.notStrictEqual(\n\t\t\t\treplaced,\n\t\t\t\tinput,\n\t\t\t\t\"encode() must shallow-clone rather than mutate original object.\",\n\t\t\t);\n\n\t\t\tconst decoded = serializer.decode(replaced);\n\t\t\tassert.notStrictEqual(\n\t\t\t\tdecoded,\n\t\t\t\tinput,\n\t\t\t\t\"decode() must shallow-clone rather than mutate original object.\",\n\t\t\t);\n\t\t\tassert.deepStrictEqual(\n\t\t\t\tdecoded,\n\t\t\t\tinput,\n\t\t\t\t\"input must round-trip through encode()/decode().\",\n\t\t\t);\n\n\t\t\tconst stringified = serializer.stringify(input, handle);\n\t\t\tconst parsed = serializer.parse(stringified);\n\t\t\tassert.deepStrictEqual(\n\t\t\t\tparsed,\n\t\t\t\tinput,\n\t\t\t\t\"input must round-trip through stringify()/parse().\",\n\t\t\t);\n\t\t});\n\t});\n\n\tdescribe(\"Parse handles with absolute / relative paths\", () => {\n\t\tconst rootContext = new MockHandleContext(\"\");\n\t\tconst dsContext = new MockHandleContext(\"/default\", rootContext);\n\t\t// Create serialized with a handle context whose parent is a root handle context.\n\t\tconst serializer = new FluidSerializer(dsContext, (parsedHandle: IFluidHandle) => {});\n\n\t\tit(\"can parse handles with absolute path\", () => {\n\t\t\tconst serializedHandle = JSON.stringify({\n\t\t\t\ttype: \"__fluid_handle__\",\n\t\t\t\turl: \"/default/sharedDDS\", // absolute path\n\t\t\t});\n\n\t\t\t// Parse a handle whose url is absolute path.\n\t\t\tconst parsedHandle: RemoteFluidObjectHandle = serializer.parse(serializedHandle);\n\t\t\tassert.strictEqual(\n\t\t\t\tparsedHandle.absolutePath,\n\t\t\t\t\"/default/sharedDDS\",\n\t\t\t\t\"Incorrect absolute path in parsed handle\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\tparsedHandle.routeContext.absolutePath,\n\t\t\t\t\"\",\n\t\t\t\t\"Parsed handle's route context should be the root context\",\n\t\t\t);\n\t\t});\n\n\t\tit(\"can parse handles with relative path\", () => {\n\t\t\tconst serializedHandle = JSON.stringify({\n\t\t\t\ttype: \"__fluid_handle__\",\n\t\t\t\turl: \"sharedDDS\", // relative path\n\t\t\t});\n\n\t\t\t// Parse a handle whose url is a path relative to its route context. The serializer will generate absolute\n\t\t\t// path for the handle and create a handle with it.\n\t\t\tconst parsedHandle: RemoteFluidObjectHandle = serializer.parse(serializedHandle);\n\t\t\tassert.strictEqual(\n\t\t\t\tparsedHandle.absolutePath,\n\t\t\t\t\"/default/sharedDDS\",\n\t\t\t\t\"Incorrect absolute path in parsed handle\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\tparsedHandle.routeContext.absolutePath,\n\t\t\t\t\"\",\n\t\t\t\t\"Parsed handle's route context should be the root context\",\n\t\t\t);\n\t\t});\n\t});\n});\n"]}