@fluidframework/container-loader 2.0.0-internal.5.4.0 → 2.0.0-internal.6.1.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 (102) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/dist/connectionManager.d.ts +4 -4
  3. package/dist/connectionManager.d.ts.map +1 -1
  4. package/dist/connectionManager.js +57 -49
  5. package/dist/connectionManager.js.map +1 -1
  6. package/dist/connectionStateHandler.d.ts +15 -14
  7. package/dist/connectionStateHandler.d.ts.map +1 -1
  8. package/dist/connectionStateHandler.js +26 -28
  9. package/dist/connectionStateHandler.js.map +1 -1
  10. package/dist/container.d.ts +10 -5
  11. package/dist/container.d.ts.map +1 -1
  12. package/dist/container.js +183 -134
  13. package/dist/container.js.map +1 -1
  14. package/dist/containerContext.d.ts +2 -12
  15. package/dist/containerContext.d.ts.map +1 -1
  16. package/dist/containerContext.js +1 -20
  17. package/dist/containerContext.js.map +1 -1
  18. package/dist/containerStorageAdapter.js +3 -5
  19. package/dist/containerStorageAdapter.js.map +1 -1
  20. package/dist/contracts.d.ts +20 -7
  21. package/dist/contracts.d.ts.map +1 -1
  22. package/dist/contracts.js +3 -3
  23. package/dist/contracts.js.map +1 -1
  24. package/dist/debugLogger.js +2 -3
  25. package/dist/debugLogger.js.map +1 -1
  26. package/dist/deltaManager.d.ts +19 -6
  27. package/dist/deltaManager.d.ts.map +1 -1
  28. package/dist/deltaManager.js +67 -28
  29. package/dist/deltaManager.js.map +1 -1
  30. package/dist/deltaQueue.js +1 -2
  31. package/dist/deltaQueue.js.map +1 -1
  32. package/dist/loader.d.ts +12 -0
  33. package/dist/loader.d.ts.map +1 -1
  34. package/dist/loader.js +57 -42
  35. package/dist/loader.js.map +1 -1
  36. package/dist/packageVersion.d.ts +1 -1
  37. package/dist/packageVersion.js +1 -1
  38. package/dist/packageVersion.js.map +1 -1
  39. package/dist/protocol.d.ts +4 -2
  40. package/dist/protocol.d.ts.map +1 -1
  41. package/dist/protocol.js +25 -4
  42. package/dist/protocol.js.map +1 -1
  43. package/dist/utils.d.ts +8 -1
  44. package/dist/utils.d.ts.map +1 -1
  45. package/dist/utils.js +24 -6
  46. package/dist/utils.js.map +1 -1
  47. package/lib/connectionManager.d.ts +4 -4
  48. package/lib/connectionManager.d.ts.map +1 -1
  49. package/lib/connectionManager.js +58 -50
  50. package/lib/connectionManager.js.map +1 -1
  51. package/lib/connectionStateHandler.d.ts +15 -14
  52. package/lib/connectionStateHandler.d.ts.map +1 -1
  53. package/lib/connectionStateHandler.js +26 -28
  54. package/lib/connectionStateHandler.js.map +1 -1
  55. package/lib/container.d.ts +10 -5
  56. package/lib/container.d.ts.map +1 -1
  57. package/lib/container.js +182 -133
  58. package/lib/container.js.map +1 -1
  59. package/lib/containerContext.d.ts +2 -12
  60. package/lib/containerContext.d.ts.map +1 -1
  61. package/lib/containerContext.js +1 -20
  62. package/lib/containerContext.js.map +1 -1
  63. package/lib/containerStorageAdapter.js +3 -5
  64. package/lib/containerStorageAdapter.js.map +1 -1
  65. package/lib/contracts.d.ts +20 -7
  66. package/lib/contracts.d.ts.map +1 -1
  67. package/lib/contracts.js +3 -3
  68. package/lib/contracts.js.map +1 -1
  69. package/lib/debugLogger.js +2 -3
  70. package/lib/debugLogger.js.map +1 -1
  71. package/lib/deltaManager.d.ts +19 -6
  72. package/lib/deltaManager.d.ts.map +1 -1
  73. package/lib/deltaManager.js +67 -28
  74. package/lib/deltaManager.js.map +1 -1
  75. package/lib/deltaQueue.js +1 -2
  76. package/lib/deltaQueue.js.map +1 -1
  77. package/lib/loader.d.ts +12 -0
  78. package/lib/loader.d.ts.map +1 -1
  79. package/lib/loader.js +57 -42
  80. package/lib/loader.js.map +1 -1
  81. package/lib/packageVersion.d.ts +1 -1
  82. package/lib/packageVersion.js +1 -1
  83. package/lib/packageVersion.js.map +1 -1
  84. package/lib/protocol.d.ts +4 -2
  85. package/lib/protocol.d.ts.map +1 -1
  86. package/lib/protocol.js +25 -4
  87. package/lib/protocol.js.map +1 -1
  88. package/lib/utils.d.ts +8 -1
  89. package/lib/utils.d.ts.map +1 -1
  90. package/lib/utils.js +22 -5
  91. package/lib/utils.js.map +1 -1
  92. package/package.json +15 -19
  93. package/src/connectionManager.ts +53 -34
  94. package/src/connectionStateHandler.ts +30 -37
  95. package/src/container.ts +156 -76
  96. package/src/containerContext.ts +0 -24
  97. package/src/contracts.ts +27 -10
  98. package/src/deltaManager.ts +41 -18
  99. package/src/loader.ts +37 -23
  100. package/src/packageVersion.ts +1 -1
  101. package/src/protocol.ts +33 -2
  102. package/src/utils.ts +29 -0
@@ -1 +1 @@
1
- {"version":3,"file":"deltaQueue.js","sourceRoot":"","sources":["../src/deltaQueue.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 { IDeltaQueue, IDeltaQueueEvents } from \"@fluidframework/container-definitions\";\nimport { assert, performance, TypedEventEmitter } from \"@fluidframework/common-utils\";\nimport Deque from \"double-ended-queue\";\n\nexport interface IDeltaQueueWriter<T> {\n\tpush(task: T): void;\n\tclear(): void;\n}\n\nexport class DeltaQueue<T>\n\textends TypedEventEmitter<IDeltaQueueEvents<T>>\n\timplements IDeltaQueue<T>, IDeltaQueueWriter<T>\n{\n\tprivate isDisposed: boolean = false;\n\tprivate readonly q = new Deque<T>();\n\n\t/**\n\t * Tracks the number of pause requests for the queue.\n\t * The DeltaQueue is created initially paused.\n\t */\n\tprivate pauseCount = 1;\n\n\tprivate error: any | undefined;\n\n\t/**\n\t * When processing is ongoing, holds a deferred that will resolve once processing stops.\n\t * Undefined when not processing.\n\t */\n\tprivate processingPromise: Promise<{ count: number; duration: number }> | undefined;\n\n\tpublic get disposed(): boolean {\n\t\treturn this.isDisposed;\n\t}\n\n\t/**\n\t * @returns True if the queue is paused, false if not.\n\t */\n\tpublic get paused(): boolean {\n\t\treturn this.pauseCount !== 0;\n\t}\n\n\tpublic get length(): number {\n\t\treturn this.q.length;\n\t}\n\n\tpublic get idle(): boolean {\n\t\treturn this.processingPromise === undefined && this.q.length === 0;\n\t}\n\n\tpublic async waitTillProcessingDone() {\n\t\treturn this.processingPromise ?? { count: 0, duration: 0 };\n\t}\n\n\t/**\n\t * @param worker - A callback to process a delta.\n\t */\n\tconstructor(private readonly worker: (delta: T) => void) {\n\t\tsuper();\n\t}\n\n\tpublic dispose() {\n\t\tthrow new Error(\"Not implemented.\");\n\t\tthis.isDisposed = true;\n\t}\n\n\tpublic clear(): void {\n\t\tthis.q.clear();\n\t}\n\n\tpublic peek(): T | undefined {\n\t\treturn this.q.peekFront();\n\t}\n\n\tpublic toArray(): T[] {\n\t\treturn this.q.toArray();\n\t}\n\n\tpublic push(task: T) {\n\t\ttry {\n\t\t\tthis.q.push(task);\n\t\t\tthis.emit(\"push\", task);\n\t\t\tthis.ensureProcessing();\n\t\t} catch (error) {\n\t\t\tthis.emit(\"error\", error);\n\t\t}\n\t}\n\n\tpublic async pause(): Promise<void> {\n\t\tthis.pauseCount++;\n\t\t// If called from within the processing loop, we are in the middle of processing an op. Return a promise\n\t\t// that will resolve when processing has actually stopped.\n\t\tawait this.waitTillProcessingDone();\n\t}\n\n\tpublic resume(): void {\n\t\tassert(this.pauseCount > 0, 0x0f4 /* \"Nonzero pause-count on resume()\" */);\n\t\tthis.pauseCount--;\n\t\tthis.ensureProcessing();\n\t}\n\n\t/**\n\t * There are several actions that may need to kick off delta processing, so we want to guard against\n\t * accidental reentrancy. ensureProcessing can be called safely to start the processing loop if it is\n\t * not already started.\n\t */\n\tprivate ensureProcessing() {\n\t\tif (this.anythingToProcess() && this.processingPromise === undefined) {\n\t\t\t// Use a resolved promise to start the processing on a separate stack.\n\t\t\tthis.processingPromise = Promise.resolve()\n\t\t\t\t.then(() => {\n\t\t\t\t\tassert(this.processingPromise !== undefined, 0x37f /* reentrancy? */);\n\t\t\t\t\tconst result = this.processDeltas();\n\t\t\t\t\tassert(this.processingPromise !== undefined, 0x380 /* reentrancy? */);\n\t\t\t\t\t// WARNING: Do not move next line to .finally() clause!\n\t\t\t\t\t// It runs async and creates a race condition where incoming ensureProcessing() call observes\n\t\t\t\t\t// from previous run while previous run is over (but finally clause was not scheduled yet)\n\t\t\t\t\tthis.processingPromise = undefined;\n\t\t\t\t\treturn result;\n\t\t\t\t})\n\t\t\t\t.catch((error) => {\n\t\t\t\t\tthis.error = error;\n\t\t\t\t\tthis.processingPromise = undefined;\n\t\t\t\t\tthis.emit(\"error\", error);\n\t\t\t\t\treturn { count: 0, duration: 0 };\n\t\t\t\t});\n\t\t\tassert(\n\t\t\t\tthis.processingPromise !== undefined,\n\t\t\t\t0x381 /* processDeltas() should run async */,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate anythingToProcess() {\n\t\treturn this.q.length !== 0 && !this.paused && this.error === undefined;\n\t}\n\n\t/**\n\t * Executes the delta processing loop until a stop condition is reached.\n\t */\n\tprivate processDeltas() {\n\t\tconst start = performance.now();\n\t\tlet count = 0;\n\n\t\t// For grouping to work we must process all local messages immediately and in the single turn.\n\t\t// So loop over them until no messages to process, we have become paused, or hit an error.\n\t\twhile (this.anythingToProcess()) {\n\t\t\t// Get the next message in the queue\n\t\t\tconst next = this.q.shift();\n\t\t\tcount++;\n\t\t\t// Process the message.\n\t\t\t// We know next is defined since we did a length check just prior to shifting.\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tthis.worker(next!);\n\t\t\tthis.emit(\"op\", next);\n\t\t}\n\n\t\tconst duration = performance.now() - start;\n\t\tif (this.q.length === 0) {\n\t\t\tthis.emit(\"idle\", count, duration);\n\t\t}\n\t\treturn { count, duration };\n\t}\n}\n"]}
1
+ {"version":3,"file":"deltaQueue.js","sourceRoot":"","sources":["../src/deltaQueue.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 { IDeltaQueue, IDeltaQueueEvents } from \"@fluidframework/container-definitions\";\nimport { assert, performance, TypedEventEmitter } from \"@fluidframework/common-utils\";\nimport Deque from \"double-ended-queue\";\n\nexport interface IDeltaQueueWriter<T> {\n\tpush(task: T): void;\n\tclear(): void;\n}\n\nexport class DeltaQueue<T>\n\textends TypedEventEmitter<IDeltaQueueEvents<T>>\n\timplements IDeltaQueue<T>, IDeltaQueueWriter<T>\n{\n\tprivate isDisposed: boolean = false;\n\tprivate readonly q = new Deque<T>();\n\n\t/**\n\t * Tracks the number of pause requests for the queue.\n\t * The DeltaQueue is created initially paused.\n\t */\n\tprivate pauseCount = 1;\n\n\tprivate error: any | undefined;\n\n\t/**\n\t * When processing is ongoing, holds a deferred that will resolve once processing stops.\n\t * Undefined when not processing.\n\t */\n\tprivate processingPromise: Promise<{ count: number; duration: number }> | undefined;\n\n\tpublic get disposed(): boolean {\n\t\treturn this.isDisposed;\n\t}\n\n\t/**\n\t * @returns True if the queue is paused, false if not.\n\t */\n\tpublic get paused(): boolean {\n\t\treturn this.pauseCount !== 0;\n\t}\n\n\tpublic get length(): number {\n\t\treturn this.q.length;\n\t}\n\n\tpublic get idle(): boolean {\n\t\treturn this.processingPromise === undefined && this.q.length === 0;\n\t}\n\n\tpublic async waitTillProcessingDone() {\n\t\treturn this.processingPromise ?? { count: 0, duration: 0 };\n\t}\n\n\t/**\n\t * @param worker - A callback to process a delta.\n\t */\n\tconstructor(private readonly worker: (delta: T) => void) {\n\t\tsuper();\n\t}\n\n\tpublic dispose() {\n\t\tthrow new Error(\"Not implemented.\");\n\t\tthis.isDisposed = true;\n\t}\n\n\tpublic clear(): void {\n\t\tthis.q.clear();\n\t}\n\n\tpublic peek(): T | undefined {\n\t\treturn this.q.peekFront();\n\t}\n\n\tpublic toArray(): T[] {\n\t\treturn this.q.toArray();\n\t}\n\n\tpublic push(task: T) {\n\t\ttry {\n\t\t\tthis.q.push(task);\n\t\t\tthis.emit(\"push\", task);\n\t\t\tthis.ensureProcessing();\n\t\t} catch (error) {\n\t\t\tthis.emit(\"error\", error);\n\t\t}\n\t}\n\n\tpublic async pause(): Promise<void> {\n\t\tthis.pauseCount++;\n\t\t// If called from within the processing loop, we are in the middle of processing an op. Return a promise\n\t\t// that will resolve when processing has actually stopped.\n\t\tawait this.waitTillProcessingDone();\n\t}\n\n\tpublic resume(): void {\n\t\tassert(this.pauseCount > 0, 0x0f4 /* \"Nonzero pause-count on resume()\" */);\n\t\tthis.pauseCount--;\n\t\tthis.ensureProcessing();\n\t}\n\n\t/**\n\t * There are several actions that may need to kick off delta processing, so we want to guard against\n\t * accidental reentrancy. ensureProcessing can be called safely to start the processing loop if it is\n\t * not already started.\n\t */\n\tprivate ensureProcessing() {\n\t\tif (this.anythingToProcess() && this.processingPromise === undefined) {\n\t\t\t// Use a resolved promise to start the processing on a separate stack.\n\t\t\tthis.processingPromise = Promise.resolve()\n\t\t\t\t.then(() => {\n\t\t\t\t\tassert(this.processingPromise !== undefined, 0x37f /* reentrancy? */);\n\t\t\t\t\tconst result = this.processDeltas();\n\t\t\t\t\tassert(this.processingPromise !== undefined, 0x380 /* reentrancy? */);\n\t\t\t\t\t// WARNING: Do not move next line to .finally() clause!\n\t\t\t\t\t// It runs async and creates a race condition where incoming ensureProcessing() call observes\n\t\t\t\t\t// from previous run while previous run is over (but finally clause was not scheduled yet)\n\t\t\t\t\tthis.processingPromise = undefined;\n\t\t\t\t\treturn result;\n\t\t\t\t})\n\t\t\t\t.catch((error) => {\n\t\t\t\t\tthis.error = error;\n\t\t\t\t\tthis.processingPromise = undefined;\n\t\t\t\t\tthis.emit(\"error\", error);\n\t\t\t\t\treturn { count: 0, duration: 0 };\n\t\t\t\t});\n\t\t\tassert(\n\t\t\t\tthis.processingPromise !== undefined,\n\t\t\t\t0x381 /* processDeltas() should run async */,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate anythingToProcess() {\n\t\treturn this.q.length !== 0 && !this.paused && this.error === undefined;\n\t}\n\n\t/**\n\t * Executes the delta processing loop until a stop condition is reached.\n\t */\n\tprivate processDeltas() {\n\t\tconst start = performance.now();\n\t\tlet count = 0;\n\n\t\t// For grouping to work we must process all local messages immediately and in the single turn.\n\t\t// So loop over them until no messages to process, we have become paused, or hit an error.\n\t\twhile (this.anythingToProcess()) {\n\t\t\t// Get the next message in the queue\n\t\t\tconst next = this.q.shift();\n\t\t\tcount++;\n\t\t\t// Process the message.\n\t\t\t// We know next is defined since we did a length check just prior to shifting.\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tthis.worker(next!);\n\t\t\tthis.emit(\"op\", next);\n\t\t}\n\n\t\tconst duration = performance.now() - start;\n\t\tif (this.q.length === 0) {\n\t\t\tthis.emit(\"idle\", count, duration);\n\t\t}\n\t\treturn { count, duration };\n\t}\n}\n"]}
package/dist/loader.d.ts CHANGED
@@ -15,8 +15,14 @@ export declare class RelativeLoader implements ILoader {
15
15
  private readonly container;
16
16
  private readonly loader;
17
17
  constructor(container: Container, loader: ILoader | undefined);
18
+ /**
19
+ * @deprecated - Will be removed in future major release. Migrate all usage of IFluidRouter to the Container's IFluidRouter/request.
20
+ */
18
21
  get IFluidRouter(): IFluidRouter;
19
22
  resolve(request: IRequest): Promise<IContainer>;
23
+ /**
24
+ * @deprecated - Will be removed in future major release. Migrate all usage of IFluidRouter to the Container's IFluidRouter/request.
25
+ */
20
26
  request(request: IRequest): Promise<IResponse>;
21
27
  }
22
28
  export interface ILoaderOptions extends ILoaderOptions1 {
@@ -172,10 +178,16 @@ export declare class Loader implements IHostLoader {
172
178
  readonly services: ILoaderServices;
173
179
  private readonly mc;
174
180
  constructor(loaderProps: ILoaderProps);
181
+ /**
182
+ * @deprecated - Will be removed in future major release. Migrate all usage of IFluidRouter to the Container's IFluidRouter/request.
183
+ */
175
184
  get IFluidRouter(): IFluidRouter;
176
185
  createDetachedContainer(codeDetails: IFluidCodeDetails): Promise<IContainer>;
177
186
  rehydrateDetachedContainerFromSnapshot(snapshot: string): Promise<IContainer>;
178
187
  resolve(request: IRequest, pendingLocalState?: string): Promise<IContainer>;
188
+ /**
189
+ * @deprecated - Will be removed in future major release. Migrate all usage of IFluidRouter to the Container's IFluidRouter/request.
190
+ */
179
191
  request(request: IRequest): Promise<IResponse>;
180
192
  private getKeyForContainerCache;
181
193
  private addToContainerCache;
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"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"}
package/dist/loader.js CHANGED
@@ -8,15 +8,13 @@ exports.Loader = exports.requestResolvedObjectFromContainer = exports.RelativeLo
8
8
  const uuid_1 = require("uuid");
9
9
  const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
10
10
  const container_definitions_1 = require("@fluidframework/container-definitions");
11
+ const container_utils_1 = require("@fluidframework/container-utils");
11
12
  const container_1 = require("./container");
12
13
  const utils_1 = require("./utils");
13
14
  const packageVersion_1 = require("./packageVersion");
14
15
  const debugLogger_1 = require("./debugLogger");
15
16
  function canUseCache(request) {
16
- if (request.headers === undefined) {
17
- return true;
18
- }
19
- return request.headers[container_definitions_1.LoaderHeader.cache] !== false;
17
+ return request.headers?.[container_definitions_1.LoaderHeader.cache] === true;
20
18
  }
21
19
  function ensureResolvedUrlDefined(resolved) {
22
20
  if (resolved === undefined) {
@@ -31,11 +29,13 @@ class RelativeLoader {
31
29
  this.container = container;
32
30
  this.loader = loader;
33
31
  }
32
+ /**
33
+ * @deprecated - Will be removed in future major release. Migrate all usage of IFluidRouter to the Container's IFluidRouter/request.
34
+ */
34
35
  get IFluidRouter() {
35
36
  return this;
36
37
  }
37
38
  async resolve(request) {
38
- var _a, _b, _c, _d, _e;
39
39
  if (request.url.startsWith("/")) {
40
40
  if (canUseCache(request)) {
41
41
  return this.container;
@@ -43,12 +43,12 @@ class RelativeLoader {
43
43
  else {
44
44
  ensureResolvedUrlDefined(this.container.resolvedUrl);
45
45
  const container = await this.container.clone({
46
- resolvedUrl: Object.assign({}, this.container.resolvedUrl),
47
- version: (_b = (_a = request.headers) === null || _a === void 0 ? void 0 : _a[container_definitions_1.LoaderHeader.version]) !== null && _b !== void 0 ? _b : undefined,
48
- loadMode: (_c = request.headers) === null || _c === void 0 ? void 0 : _c[container_definitions_1.LoaderHeader.loadMode],
46
+ resolvedUrl: { ...this.container.resolvedUrl },
47
+ version: request.headers?.[container_definitions_1.LoaderHeader.version] ?? undefined,
48
+ loadMode: request.headers?.[container_definitions_1.LoaderHeader.loadMode],
49
49
  }, {
50
- canReconnect: (_d = request.headers) === null || _d === void 0 ? void 0 : _d[container_definitions_1.LoaderHeader.reconnect],
51
- clientDetailsOverride: (_e = request.headers) === null || _e === void 0 ? void 0 : _e[container_definitions_1.LoaderHeader.clientDetails],
50
+ canReconnect: request.headers?.[container_definitions_1.LoaderHeader.reconnect],
51
+ clientDetailsOverride: request.headers?.[container_definitions_1.LoaderHeader.clientDetails],
52
52
  });
53
53
  return container;
54
54
  }
@@ -58,6 +58,9 @@ class RelativeLoader {
58
58
  }
59
59
  return this.loader.resolve(request);
60
60
  }
61
+ /**
62
+ * @deprecated - Will be removed in future major release. Migrate all usage of IFluidRouter to the Container's IFluidRouter/request.
63
+ */
61
64
  async request(request) {
62
65
  if (request.url.startsWith("/")) {
63
66
  const container = await this.resolve(request);
@@ -80,14 +83,13 @@ exports.RelativeLoader = RelativeLoader;
80
83
  * @returns component on the container
81
84
  */
82
85
  async function requestResolvedObjectFromContainer(container, headers) {
83
- var _a, _b;
84
86
  ensureResolvedUrlDefined(container.resolvedUrl);
85
87
  const parsedUrl = (0, utils_1.parseUrl)(container.resolvedUrl.url);
86
88
  if (parsedUrl === undefined) {
87
89
  throw new Error(`Invalid URL ${container.resolvedUrl.url}`);
88
90
  }
89
- const entryPoint = await ((_a = container.getEntryPoint) === null || _a === void 0 ? void 0 : _a.call(container));
90
- const router = (_b = entryPoint === null || entryPoint === void 0 ? void 0 : entryPoint.IFluidRouter) !== null && _b !== void 0 ? _b : container.IFluidRouter;
91
+ const entryPoint = await container.getEntryPoint?.();
92
+ const router = entryPoint?.IFluidRouter ?? container.IFluidRouter;
91
93
  return router.request({
92
94
  url: `${parsedUrl.path}${parsedUrl.query}`,
93
95
  headers,
@@ -112,8 +114,8 @@ class Loader {
112
114
  urlResolver,
113
115
  documentServiceFactory,
114
116
  codeLoader,
115
- options: options !== null && options !== void 0 ? options : {},
116
- scope: (options === null || options === void 0 ? void 0 : options.provideScopeLoader) !== false ? Object.assign(Object.assign({}, scope), { ILoader: this }) : Object.assign({}, scope),
117
+ options: options ?? {},
118
+ scope: options?.provideScopeLoader !== false ? { ...scope, ILoader: this } : { ...scope },
117
119
  detachedBlobStorage,
118
120
  protocolHandlerBuilder,
119
121
  subLogger: subMc.logger,
@@ -123,6 +125,9 @@ class Loader {
123
125
  namespace: "Loader",
124
126
  });
125
127
  }
128
+ /**
129
+ * @deprecated - Will be removed in future major release. Migrate all usage of IFluidRouter to the Container's IFluidRouter/request.
130
+ */
126
131
  get IFluidRouter() {
127
132
  return this;
128
133
  }
@@ -149,15 +154,20 @@ class Loader {
149
154
  return resolved.container;
150
155
  });
151
156
  }
157
+ /**
158
+ * @deprecated - Will be removed in future major release. Migrate all usage of IFluidRouter to the Container's IFluidRouter/request.
159
+ */
152
160
  async request(request) {
153
161
  return telemetry_utils_1.PerformanceEvent.timedExecAsync(this.mc.logger, { eventName: "Request" }, async () => {
154
162
  const resolved = await this.resolveCore(request);
155
- return resolved.container.request(Object.assign(Object.assign({}, request), { url: `${resolved.parsed.path}${resolved.parsed.query}` }));
163
+ return resolved.container.request({
164
+ ...request,
165
+ url: `${resolved.parsed.path}${resolved.parsed.query}`,
166
+ });
156
167
  });
157
168
  }
158
169
  getKeyForContainerCache(request, parsedUrl) {
159
- var _a;
160
- const key = ((_a = request.headers) === null || _a === void 0 ? void 0 : _a[container_definitions_1.LoaderHeader.version]) !== undefined
170
+ const key = request.headers?.[container_definitions_1.LoaderHeader.version] !== undefined
161
171
  ? `${parsedUrl.id}@${request.headers[container_definitions_1.LoaderHeader.version]}`
162
172
  : parsedUrl.id;
163
173
  return key;
@@ -186,7 +196,6 @@ class Loader {
186
196
  });
187
197
  }
188
198
  async resolveCore(request, pendingLocalState) {
189
- var _a, _b, _c;
190
199
  const resolvedAsFluid = await this.services.urlResolver.resolve(request);
191
200
  ensureResolvedUrlDefined(resolvedAsFluid);
192
201
  // Parse URL into data stores
@@ -196,20 +205,33 @@ class Loader {
196
205
  }
197
206
  if (pendingLocalState !== undefined) {
198
207
  const parsedPendingUrl = (0, utils_1.parseUrl)(pendingLocalState.url);
199
- if ((parsedPendingUrl === null || parsedPendingUrl === void 0 ? void 0 : parsedPendingUrl.id) !== parsed.id ||
200
- (parsedPendingUrl === null || parsedPendingUrl === void 0 ? void 0 : parsedPendingUrl.path.replace(/\/$/, "")) !== parsed.path.replace(/\/$/, "")) {
208
+ if (parsedPendingUrl?.id !== parsed.id ||
209
+ parsedPendingUrl?.path.replace(/\/$/, "") !== parsed.path.replace(/\/$/, "")) {
201
210
  const message = `URL ${resolvedAsFluid.url} does not match pending state URL ${pendingLocalState.url}`;
202
211
  throw new Error(message);
203
212
  }
204
213
  }
205
- (_a = request.headers) !== null && _a !== void 0 ? _a : (request.headers = {});
214
+ request.headers ?? (request.headers = {});
206
215
  // If set in both query string and headers, use query string. Also write the value from the query string into the header either way.
207
216
  request.headers[container_definitions_1.LoaderHeader.version] =
208
- (_b = parsed.version) !== null && _b !== void 0 ? _b : request.headers[container_definitions_1.LoaderHeader.version];
209
- const canCache = this.cachingEnabled &&
210
- request.headers[container_definitions_1.LoaderHeader.cache] !== false &&
217
+ parsed.version ?? request.headers[container_definitions_1.LoaderHeader.version];
218
+ const cacheHeader = request.headers[container_definitions_1.LoaderHeader.cache];
219
+ const canCache =
220
+ // Take header value if present, else use ILoaderOptions.cache value
221
+ (cacheHeader !== undefined ? cacheHeader === true : this.cachingEnabled) &&
211
222
  pendingLocalState === undefined;
212
- const fromSequenceNumber = (_c = request.headers[container_definitions_1.LoaderHeader.sequenceNumber]) !== null && _c !== void 0 ? _c : -1;
223
+ const fromSequenceNumber = request.headers[container_definitions_1.LoaderHeader.sequenceNumber];
224
+ const opsBeforeReturn = request.headers[container_definitions_1.LoaderHeader.loadMode]?.opsBeforeReturn;
225
+ if (opsBeforeReturn === "sequenceNumber" &&
226
+ (fromSequenceNumber === undefined || fromSequenceNumber < 0)) {
227
+ // If opsBeforeReturn is set to "sequenceNumber", then fromSequenceNumber should be set to a non-negative integer.
228
+ throw new container_utils_1.UsageError("sequenceNumber must be set to a non-negative integer");
229
+ }
230
+ else if (opsBeforeReturn !== "sequenceNumber" && fromSequenceNumber !== undefined) {
231
+ // If opsBeforeReturn is not set to "sequenceNumber", then fromSequenceNumber should be undefined (default value).
232
+ // In this case, we should throw an error since opsBeforeReturn is not explicitly set to "sequenceNumber".
233
+ throw new container_utils_1.UsageError('opsBeforeReturn must be set to "sequenceNumber"');
234
+ }
213
235
  let container;
214
236
  if (canCache) {
215
237
  const key = this.getKeyForContainerCache(request, parsed);
@@ -226,30 +248,23 @@ class Loader {
226
248
  else {
227
249
  container = await this.loadContainer(request, resolvedAsFluid, pendingLocalState);
228
250
  }
229
- if (container.deltaManager.lastSequenceNumber <= fromSequenceNumber) {
230
- await new Promise((resolve, reject) => {
231
- function opHandler(message) {
232
- if (message.sequenceNumber > fromSequenceNumber) {
233
- resolve();
234
- container.removeListener("op", opHandler);
235
- }
236
- }
237
- container.on("op", opHandler);
238
- });
239
- }
240
251
  return { container, parsed };
241
252
  }
242
253
  get cachingEnabled() {
243
- return this.services.options.cache !== false;
254
+ return this.services.options.cache === true;
244
255
  }
245
256
  async loadContainer(request, resolvedUrl, pendingLocalState) {
246
- var _a, _b, _c, _d, _e;
247
257
  return container_1.Container.load({
248
258
  resolvedUrl,
249
- version: (_b = (_a = request.headers) === null || _a === void 0 ? void 0 : _a[container_definitions_1.LoaderHeader.version]) !== null && _b !== void 0 ? _b : undefined,
250
- loadMode: (_c = request.headers) === null || _c === void 0 ? void 0 : _c[container_definitions_1.LoaderHeader.loadMode],
259
+ version: request.headers?.[container_definitions_1.LoaderHeader.version] ?? undefined,
260
+ loadMode: request.headers?.[container_definitions_1.LoaderHeader.loadMode],
251
261
  pendingLocalState,
252
- }, Object.assign({ canReconnect: (_d = request.headers) === null || _d === void 0 ? void 0 : _d[container_definitions_1.LoaderHeader.reconnect], clientDetailsOverride: (_e = request.headers) === null || _e === void 0 ? void 0 : _e[container_definitions_1.LoaderHeader.clientDetails] }, this.services));
262
+ loadToSequenceNumber: request.headers?.[container_definitions_1.LoaderHeader.sequenceNumber],
263
+ }, {
264
+ canReconnect: request.headers?.[container_definitions_1.LoaderHeader.reconnect],
265
+ clientDetailsOverride: request.headers?.[container_definitions_1.LoaderHeader.clientDetails],
266
+ ...this.services,
267
+ });
253
268
  }
254
269
  }
255
270
  exports.Loader = Loader;
@@ -1 +1 @@
1
- {"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.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 { v4 as uuid } from \"uuid\";\nimport {\n\tITelemetryLoggerExt,\n\tIConfigProviderBase,\n\tmixinMonitoringContext,\n\tMonitoringContext,\n\tPerformanceEvent,\n\tsessionStorageConfigProvider,\n\tcreateChildMonitoringContext,\n} from \"@fluidframework/telemetry-utils\";\nimport {\n\tITelemetryBaseLogger,\n\tFluidObject,\n\tIFluidRouter,\n\tIRequest,\n\tIRequestHeader,\n\tIResponse,\n} from \"@fluidframework/core-interfaces\";\nimport {\n\tIContainer,\n\tIFluidModule,\n\tIHostLoader,\n\tILoader,\n\tILoaderOptions as ILoaderOptions1,\n\tLoaderHeader,\n\tIProvideFluidCodeDetailsComparer,\n\tIFluidCodeDetails,\n} from \"@fluidframework/container-definitions\";\nimport {\n\tIDocumentServiceFactory,\n\tIDocumentStorageService,\n\tIResolvedUrl,\n\tIUrlResolver,\n} from \"@fluidframework/driver-definitions\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport { Container, IPendingContainerState } from \"./container\";\nimport { IParsedUrl, parseUrl } from \"./utils\";\nimport { pkgVersion } from \"./packageVersion\";\nimport { ProtocolHandlerBuilder } from \"./protocol\";\nimport { DebugLogger } from \"./debugLogger\";\n\nfunction canUseCache(request: IRequest): boolean {\n\tif (request.headers === undefined) {\n\t\treturn true;\n\t}\n\n\treturn request.headers[LoaderHeader.cache] !== false;\n}\n\nfunction ensureResolvedUrlDefined(\n\tresolved: IResolvedUrl | undefined,\n): asserts resolved is IResolvedUrl {\n\tif (resolved === undefined) {\n\t\tthrow new Error(`Object is not a IResolveUrl.`);\n\t}\n}\n/**\n * @internal\n */\nexport class RelativeLoader implements ILoader {\n\tconstructor(\n\t\tprivate readonly container: Container,\n\t\tprivate readonly loader: ILoader | undefined,\n\t) {}\n\n\tpublic get IFluidRouter(): IFluidRouter {\n\t\treturn this;\n\t}\n\n\tpublic async resolve(request: IRequest): Promise<IContainer> {\n\t\tif (request.url.startsWith(\"/\")) {\n\t\t\tif (canUseCache(request)) {\n\t\t\t\treturn this.container;\n\t\t\t} else {\n\t\t\t\tensureResolvedUrlDefined(this.container.resolvedUrl);\n\t\t\t\tconst container = await this.container.clone(\n\t\t\t\t\t{\n\t\t\t\t\t\tresolvedUrl: { ...this.container.resolvedUrl },\n\t\t\t\t\t\tversion: request.headers?.[LoaderHeader.version] ?? undefined,\n\t\t\t\t\t\tloadMode: request.headers?.[LoaderHeader.loadMode],\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tcanReconnect: request.headers?.[LoaderHeader.reconnect],\n\t\t\t\t\t\tclientDetailsOverride: request.headers?.[LoaderHeader.clientDetails],\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\treturn container;\n\t\t\t}\n\t\t}\n\n\t\tif (this.loader === undefined) {\n\t\t\tthrow new Error(\"Cannot resolve external containers\");\n\t\t}\n\t\treturn this.loader.resolve(request);\n\t}\n\n\tpublic async request(request: IRequest): Promise<IResponse> {\n\t\tif (request.url.startsWith(\"/\")) {\n\t\t\tconst container = await this.resolve(request);\n\t\t\treturn container.request(request);\n\t\t}\n\n\t\tif (this.loader === undefined) {\n\t\t\treturn {\n\t\t\t\tstatus: 404,\n\t\t\t\tvalue: \"Cannot request external containers\",\n\t\t\t\tmimeType: \"plain/text\",\n\t\t\t};\n\t\t}\n\t\treturn this.loader.request(request);\n\t}\n}\n\nexport interface ILoaderOptions extends ILoaderOptions1 {\n\tsummarizeProtocolTree?: boolean;\n}\n\n/**\n * @deprecated IFluidModuleWithDetails interface is moved to\n * {@link @fluidframework/container-definitions#IFluidModuleWithDetails}\n * to have all the code loading modules in one package. #8193\n * Encapsulates a module entry point with corresponding code details.\n */\nexport interface IFluidModuleWithDetails {\n\t/** Fluid code module that implements the runtime factory needed to instantiate the container runtime. */\n\tmodule: IFluidModule;\n\t/**\n\t * Code details associated with the module. Represents a document schema this module supports.\n\t * If the code loader implements the {@link @fluidframework/core-interfaces#IFluidCodeDetailsComparer} interface,\n\t * it'll be called to determine whether the module code details satisfy the new code proposal in the quorum.\n\t */\n\tdetails: IFluidCodeDetails;\n}\n\n/**\n * @deprecated ICodeDetailsLoader interface is moved to {@link @fluidframework/container-definition#ICodeDetailsLoader}\n * to have code loading modules in one package. #8193\n * Fluid code loader resolves a code module matching the document schema, i.e. code details, such as\n * a package name and package version range.\n */\nexport interface ICodeDetailsLoader extends Partial<IProvideFluidCodeDetailsComparer> {\n\t/**\n\t * Load the code module (package) that is capable to interact with the document.\n\t *\n\t * @param source - Code proposal that articulates the current schema the document is written in.\n\t * @returns - Code module entry point along with the code details associated with it.\n\t */\n\tload(source: IFluidCodeDetails): Promise<IFluidModuleWithDetails>;\n}\n\n/**\n * Services and properties necessary for creating a loader\n */\nexport interface ILoaderProps {\n\t/**\n\t * The url resolver used by the loader for resolving external urls\n\t * into Fluid urls such that the container specified by the\n\t * external url can be loaded.\n\t */\n\treadonly urlResolver: IUrlResolver;\n\t/**\n\t * The document service factory take the Fluid url provided\n\t * by the resolved url and constructs all the necessary services\n\t * for communication with the container's server.\n\t */\n\treadonly documentServiceFactory: IDocumentServiceFactory;\n\t/**\n\t * The code loader handles loading the necessary code\n\t * for running a container once it is loaded.\n\t */\n\treadonly codeLoader: ICodeDetailsLoader;\n\n\t/**\n\t * A property bag of options used by various layers\n\t * to control features\n\t */\n\treadonly options?: ILoaderOptions;\n\n\t/**\n\t * Scope is provided to all container and is a set of shared\n\t * services for container's to integrate with their host environment.\n\t */\n\treadonly scope?: FluidObject;\n\n\t/**\n\t * The logger that all telemetry should be pushed to.\n\t */\n\treadonly logger?: ITelemetryBaseLogger;\n\n\t/**\n\t * Blobs storage for detached containers.\n\t */\n\treadonly detachedBlobStorage?: IDetachedBlobStorage;\n\n\t/**\n\t * The configuration provider which may be used to control features.\n\t */\n\treadonly configProvider?: IConfigProviderBase;\n\n\t/**\n\t * Optional property for allowing the container to use a custom\n\t * protocol implementation for handling the quorum and/or the audience.\n\t */\n\treadonly protocolHandlerBuilder?: ProtocolHandlerBuilder;\n}\n\n/**\n * Services and properties used by and exposed by the loader\n */\nexport interface ILoaderServices {\n\t/**\n\t * The url resolver used by the loader for resolving external urls\n\t * into Fluid urls such that the container specified by the\n\t * external url can be loaded.\n\t */\n\treadonly urlResolver: IUrlResolver;\n\t/**\n\t * The document service factory take the Fluid url provided\n\t * by the resolved url and constructs all the necessary services\n\t * for communication with the container's server.\n\t */\n\treadonly documentServiceFactory: IDocumentServiceFactory;\n\t/**\n\t * The code loader handles loading the necessary code\n\t * for running a container once it is loaded.\n\t */\n\treadonly codeLoader: ICodeDetailsLoader;\n\n\t/**\n\t * A property bag of options used by various layers\n\t * to control features\n\t */\n\treadonly options: ILoaderOptions;\n\n\t/**\n\t * Scope is provided to all container and is a set of shared\n\t * services for container's to integrate with their host environment.\n\t */\n\treadonly scope: FluidObject;\n\n\t/**\n\t * The logger downstream consumers should construct their loggers from\n\t */\n\treadonly subLogger: ITelemetryLoggerExt;\n\n\t/**\n\t * Blobs storage for detached containers.\n\t */\n\treadonly detachedBlobStorage?: IDetachedBlobStorage;\n\n\t/**\n\t * Optional property for allowing the container to use a custom\n\t * protocol implementation for handling the quorum and/or the audience.\n\t */\n\treadonly protocolHandlerBuilder?: ProtocolHandlerBuilder;\n}\n\n/**\n * Subset of IDocumentStorageService which only supports createBlob() and readBlob(). This is used to support\n * blobs in detached containers.\n */\nexport type IDetachedBlobStorage = Pick<IDocumentStorageService, \"createBlob\" | \"readBlob\"> & {\n\tsize: number;\n\t/**\n\t * Return an array of all blob IDs present in storage\n\t */\n\tgetBlobIds(): string[];\n};\n\n/**\n * With an already-resolved container, we can request a component directly, without loading the container again\n * @param container - a resolved container\n * @returns component on the container\n */\nexport async function requestResolvedObjectFromContainer(\n\tcontainer: IContainer,\n\theaders?: IRequestHeader,\n): Promise<IResponse> {\n\tensureResolvedUrlDefined(container.resolvedUrl);\n\tconst parsedUrl = parseUrl(container.resolvedUrl.url);\n\n\tif (parsedUrl === undefined) {\n\t\tthrow new Error(`Invalid URL ${container.resolvedUrl.url}`);\n\t}\n\n\tconst entryPoint: FluidObject<IFluidRouter> | undefined = await container.getEntryPoint?.();\n\tconst router = entryPoint?.IFluidRouter ?? container.IFluidRouter;\n\n\treturn router.request({\n\t\turl: `${parsedUrl.path}${parsedUrl.query}`,\n\t\theaders,\n\t});\n}\n\n/**\n * Manages Fluid resource loading\n */\nexport class Loader implements IHostLoader {\n\tprivate readonly containers = new Map<string, Promise<Container>>();\n\tpublic readonly services: ILoaderServices;\n\tprivate readonly mc: MonitoringContext;\n\n\tconstructor(loaderProps: ILoaderProps) {\n\t\tconst {\n\t\t\turlResolver,\n\t\t\tdocumentServiceFactory,\n\t\t\tcodeLoader,\n\t\t\toptions,\n\t\t\tscope,\n\t\t\tlogger,\n\t\t\tdetachedBlobStorage,\n\t\t\tconfigProvider,\n\t\t\tprotocolHandlerBuilder,\n\t\t} = loaderProps;\n\n\t\tconst telemetryProps = {\n\t\t\tloaderId: uuid(),\n\t\t\tloaderVersion: pkgVersion,\n\t\t};\n\n\t\tconst subMc = mixinMonitoringContext(\n\t\t\tDebugLogger.mixinDebugLogger(\"fluid:telemetry\", logger, {\n\t\t\t\tall: telemetryProps,\n\t\t\t}),\n\t\t\tsessionStorageConfigProvider.value,\n\t\t\tconfigProvider,\n\t\t);\n\n\t\tthis.services = {\n\t\t\turlResolver,\n\t\t\tdocumentServiceFactory,\n\t\t\tcodeLoader,\n\t\t\toptions: options ?? {},\n\t\t\tscope:\n\t\t\t\toptions?.provideScopeLoader !== false ? { ...scope, ILoader: this } : { ...scope },\n\t\t\tdetachedBlobStorage,\n\t\t\tprotocolHandlerBuilder,\n\t\t\tsubLogger: subMc.logger,\n\t\t};\n\t\tthis.mc = createChildMonitoringContext({\n\t\t\tlogger: this.services.subLogger,\n\t\t\tnamespace: \"Loader\",\n\t\t});\n\t}\n\n\tpublic get IFluidRouter(): IFluidRouter {\n\t\treturn this;\n\t}\n\n\tpublic async createDetachedContainer(codeDetails: IFluidCodeDetails): Promise<IContainer> {\n\t\tconst container = await Container.createDetached(this.services, codeDetails);\n\n\t\tif (this.cachingEnabled) {\n\t\t\tcontainer.once(\"attached\", () => {\n\t\t\t\tensureResolvedUrlDefined(container.resolvedUrl);\n\t\t\t\tconst parsedUrl = parseUrl(container.resolvedUrl.url);\n\t\t\t\tif (parsedUrl !== undefined) {\n\t\t\t\t\tthis.addToContainerCache(parsedUrl.id, Promise.resolve(container));\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\treturn container;\n\t}\n\n\tpublic async rehydrateDetachedContainerFromSnapshot(snapshot: string): Promise<IContainer> {\n\t\treturn Container.rehydrateDetachedFromSnapshot(this.services, snapshot);\n\t}\n\n\tpublic async resolve(request: IRequest, pendingLocalState?: string): Promise<IContainer> {\n\t\tconst eventName = pendingLocalState === undefined ? \"Resolve\" : \"ResolveWithPendingState\";\n\t\treturn PerformanceEvent.timedExecAsync(this.mc.logger, { eventName }, async () => {\n\t\t\tconst resolved = await this.resolveCore(\n\t\t\t\trequest,\n\t\t\t\tpendingLocalState !== undefined ? JSON.parse(pendingLocalState) : undefined,\n\t\t\t);\n\t\t\treturn resolved.container;\n\t\t});\n\t}\n\n\tpublic async request(request: IRequest): Promise<IResponse> {\n\t\treturn PerformanceEvent.timedExecAsync(\n\t\t\tthis.mc.logger,\n\t\t\t{ eventName: \"Request\" },\n\t\t\tasync () => {\n\t\t\t\tconst resolved = await this.resolveCore(request);\n\t\t\t\treturn resolved.container.request({\n\t\t\t\t\t...request,\n\t\t\t\t\turl: `${resolved.parsed.path}${resolved.parsed.query}`,\n\t\t\t\t});\n\t\t\t},\n\t\t);\n\t}\n\n\tprivate getKeyForContainerCache(request: IRequest, parsedUrl: IParsedUrl): string {\n\t\tconst key =\n\t\t\trequest.headers?.[LoaderHeader.version] !== undefined\n\t\t\t\t? `${parsedUrl.id}@${request.headers[LoaderHeader.version]}`\n\t\t\t\t: parsedUrl.id;\n\t\treturn key;\n\t}\n\n\tprivate addToContainerCache(key: string, containerP: Promise<Container>) {\n\t\tthis.containers.set(key, containerP);\n\t\tcontainerP\n\t\t\t.then((container) => {\n\t\t\t\t// If the container is closed/disposed or becomes closed/disposed after we resolve it,\n\t\t\t\t// remove it from the cache.\n\t\t\t\tif (container.closed || container.disposed) {\n\t\t\t\t\tthis.containers.delete(key);\n\t\t\t\t} else {\n\t\t\t\t\tcontainer.once(\"closed\", () => {\n\t\t\t\t\t\tthis.containers.delete(key);\n\t\t\t\t\t});\n\t\t\t\t\tcontainer.once(\"disposed\", () => {\n\t\t\t\t\t\tthis.containers.delete(key);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\t// If an error occured while resolving the container request, then remove it from the cache.\n\t\t\t\tthis.containers.delete(key);\n\t\t\t});\n\t}\n\n\tprivate async resolveCore(\n\t\trequest: IRequest,\n\t\tpendingLocalState?: IPendingContainerState,\n\t): Promise<{ container: Container; parsed: IParsedUrl }> {\n\t\tconst resolvedAsFluid = await this.services.urlResolver.resolve(request);\n\t\tensureResolvedUrlDefined(resolvedAsFluid);\n\n\t\t// Parse URL into data stores\n\t\tconst parsed = parseUrl(resolvedAsFluid.url);\n\t\tif (parsed === undefined) {\n\t\t\tthrow new Error(`Invalid URL ${resolvedAsFluid.url}`);\n\t\t}\n\n\t\tif (pendingLocalState !== undefined) {\n\t\t\tconst parsedPendingUrl = parseUrl(pendingLocalState.url);\n\t\t\tif (\n\t\t\t\tparsedPendingUrl?.id !== parsed.id ||\n\t\t\t\tparsedPendingUrl?.path.replace(/\\/$/, \"\") !== parsed.path.replace(/\\/$/, \"\")\n\t\t\t) {\n\t\t\t\tconst message = `URL ${resolvedAsFluid.url} does not match pending state URL ${pendingLocalState.url}`;\n\t\t\t\tthrow new Error(message);\n\t\t\t}\n\t\t}\n\n\t\trequest.headers ??= {};\n\t\t// If set in both query string and headers, use query string. Also write the value from the query string into the header either way.\n\t\trequest.headers[LoaderHeader.version] =\n\t\t\tparsed.version ?? request.headers[LoaderHeader.version];\n\t\tconst canCache =\n\t\t\tthis.cachingEnabled &&\n\t\t\trequest.headers[LoaderHeader.cache] !== false &&\n\t\t\tpendingLocalState === undefined;\n\t\tconst fromSequenceNumber = request.headers[LoaderHeader.sequenceNumber] ?? -1;\n\n\t\tlet container: Container;\n\t\tif (canCache) {\n\t\t\tconst key = this.getKeyForContainerCache(request, parsed);\n\t\t\tconst maybeContainer = await this.containers.get(key);\n\t\t\tif (maybeContainer !== undefined) {\n\t\t\t\tcontainer = maybeContainer;\n\t\t\t} else {\n\t\t\t\tconst containerP = this.loadContainer(request, resolvedAsFluid);\n\t\t\t\tthis.addToContainerCache(key, containerP);\n\t\t\t\tcontainer = await containerP;\n\t\t\t}\n\t\t} else {\n\t\t\tcontainer = await this.loadContainer(request, resolvedAsFluid, pendingLocalState);\n\t\t}\n\n\t\tif (container.deltaManager.lastSequenceNumber <= fromSequenceNumber) {\n\t\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\t\tfunction opHandler(message: ISequencedDocumentMessage) {\n\t\t\t\t\tif (message.sequenceNumber > fromSequenceNumber) {\n\t\t\t\t\t\tresolve();\n\t\t\t\t\t\tcontainer.removeListener(\"op\", opHandler);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcontainer.on(\"op\", opHandler);\n\t\t\t});\n\t\t}\n\n\t\treturn { container, parsed };\n\t}\n\n\tprivate get cachingEnabled() {\n\t\treturn this.services.options.cache !== false;\n\t}\n\n\tprivate async loadContainer(\n\t\trequest: IRequest,\n\t\tresolvedUrl: IResolvedUrl,\n\t\tpendingLocalState?: IPendingContainerState,\n\t): Promise<Container> {\n\t\treturn Container.load(\n\t\t\t{\n\t\t\t\tresolvedUrl,\n\t\t\t\tversion: request.headers?.[LoaderHeader.version] ?? undefined,\n\t\t\t\tloadMode: request.headers?.[LoaderHeader.loadMode],\n\t\t\t\tpendingLocalState,\n\t\t\t},\n\t\t\t{\n\t\t\t\tcanReconnect: request.headers?.[LoaderHeader.reconnect],\n\t\t\t\tclientDetailsOverride: request.headers?.[LoaderHeader.clientDetails],\n\t\t\t\t...this.services,\n\t\t\t},\n\t\t);\n\t}\n}\n"]}
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.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 { v4 as uuid } from \"uuid\";\nimport {\n\tITelemetryLoggerExt,\n\tIConfigProviderBase,\n\tmixinMonitoringContext,\n\tMonitoringContext,\n\tPerformanceEvent,\n\tsessionStorageConfigProvider,\n\tcreateChildMonitoringContext,\n} from \"@fluidframework/telemetry-utils\";\nimport {\n\tITelemetryBaseLogger,\n\tFluidObject,\n\tIFluidRouter,\n\tIRequest,\n\tIRequestHeader,\n\tIResponse,\n} from \"@fluidframework/core-interfaces\";\nimport {\n\tIContainer,\n\tIFluidModule,\n\tIHostLoader,\n\tILoader,\n\tILoaderOptions as ILoaderOptions1,\n\tLoaderHeader,\n\tIProvideFluidCodeDetailsComparer,\n\tIFluidCodeDetails,\n} from \"@fluidframework/container-definitions\";\nimport {\n\tIDocumentServiceFactory,\n\tIDocumentStorageService,\n\tIResolvedUrl,\n\tIUrlResolver,\n} from \"@fluidframework/driver-definitions\";\nimport { UsageError } from \"@fluidframework/container-utils\";\nimport { Container, IPendingContainerState } from \"./container\";\nimport { IParsedUrl, parseUrl } from \"./utils\";\nimport { pkgVersion } from \"./packageVersion\";\nimport { ProtocolHandlerBuilder } from \"./protocol\";\nimport { DebugLogger } from \"./debugLogger\";\n\nfunction canUseCache(request: IRequest): boolean {\n\treturn request.headers?.[LoaderHeader.cache] === true;\n}\n\nfunction ensureResolvedUrlDefined(\n\tresolved: IResolvedUrl | undefined,\n): asserts resolved is IResolvedUrl {\n\tif (resolved === undefined) {\n\t\tthrow new Error(`Object is not a IResolveUrl.`);\n\t}\n}\n/**\n * @internal\n */\nexport class RelativeLoader implements ILoader {\n\tconstructor(\n\t\tprivate readonly container: Container,\n\t\tprivate readonly loader: ILoader | undefined,\n\t) {}\n\n\t/**\n\t * @deprecated - Will be removed in future major release. Migrate all usage of IFluidRouter to the Container's IFluidRouter/request.\n\t */\n\tpublic get IFluidRouter(): IFluidRouter {\n\t\treturn this;\n\t}\n\n\tpublic async resolve(request: IRequest): Promise<IContainer> {\n\t\tif (request.url.startsWith(\"/\")) {\n\t\t\tif (canUseCache(request)) {\n\t\t\t\treturn this.container;\n\t\t\t} else {\n\t\t\t\tensureResolvedUrlDefined(this.container.resolvedUrl);\n\t\t\t\tconst container = await this.container.clone(\n\t\t\t\t\t{\n\t\t\t\t\t\tresolvedUrl: { ...this.container.resolvedUrl },\n\t\t\t\t\t\tversion: request.headers?.[LoaderHeader.version] ?? undefined,\n\t\t\t\t\t\tloadMode: request.headers?.[LoaderHeader.loadMode],\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tcanReconnect: request.headers?.[LoaderHeader.reconnect],\n\t\t\t\t\t\tclientDetailsOverride: request.headers?.[LoaderHeader.clientDetails],\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\treturn container;\n\t\t\t}\n\t\t}\n\n\t\tif (this.loader === undefined) {\n\t\t\tthrow new Error(\"Cannot resolve external containers\");\n\t\t}\n\t\treturn this.loader.resolve(request);\n\t}\n\n\t/**\n\t * @deprecated - Will be removed in future major release. Migrate all usage of IFluidRouter to the Container's IFluidRouter/request.\n\t */\n\tpublic async request(request: IRequest): Promise<IResponse> {\n\t\tif (request.url.startsWith(\"/\")) {\n\t\t\tconst container = await this.resolve(request);\n\t\t\treturn container.request(request);\n\t\t}\n\n\t\tif (this.loader === undefined) {\n\t\t\treturn {\n\t\t\t\tstatus: 404,\n\t\t\t\tvalue: \"Cannot request external containers\",\n\t\t\t\tmimeType: \"plain/text\",\n\t\t\t};\n\t\t}\n\t\treturn this.loader.request(request);\n\t}\n}\n\nexport interface ILoaderOptions extends ILoaderOptions1 {\n\tsummarizeProtocolTree?: boolean;\n}\n\n/**\n * @deprecated IFluidModuleWithDetails interface is moved to\n * {@link @fluidframework/container-definitions#IFluidModuleWithDetails}\n * to have all the code loading modules in one package. #8193\n * Encapsulates a module entry point with corresponding code details.\n */\nexport interface IFluidModuleWithDetails {\n\t/** Fluid code module that implements the runtime factory needed to instantiate the container runtime. */\n\tmodule: IFluidModule;\n\t/**\n\t * Code details associated with the module. Represents a document schema this module supports.\n\t * If the code loader implements the {@link @fluidframework/core-interfaces#IFluidCodeDetailsComparer} interface,\n\t * it'll be called to determine whether the module code details satisfy the new code proposal in the quorum.\n\t */\n\tdetails: IFluidCodeDetails;\n}\n\n/**\n * @deprecated ICodeDetailsLoader interface is moved to {@link @fluidframework/container-definition#ICodeDetailsLoader}\n * to have code loading modules in one package. #8193\n * Fluid code loader resolves a code module matching the document schema, i.e. code details, such as\n * a package name and package version range.\n */\nexport interface ICodeDetailsLoader extends Partial<IProvideFluidCodeDetailsComparer> {\n\t/**\n\t * Load the code module (package) that is capable to interact with the document.\n\t *\n\t * @param source - Code proposal that articulates the current schema the document is written in.\n\t * @returns - Code module entry point along with the code details associated with it.\n\t */\n\tload(source: IFluidCodeDetails): Promise<IFluidModuleWithDetails>;\n}\n\n/**\n * Services and properties necessary for creating a loader\n */\nexport interface ILoaderProps {\n\t/**\n\t * The url resolver used by the loader for resolving external urls\n\t * into Fluid urls such that the container specified by the\n\t * external url can be loaded.\n\t */\n\treadonly urlResolver: IUrlResolver;\n\t/**\n\t * The document service factory take the Fluid url provided\n\t * by the resolved url and constructs all the necessary services\n\t * for communication with the container's server.\n\t */\n\treadonly documentServiceFactory: IDocumentServiceFactory;\n\t/**\n\t * The code loader handles loading the necessary code\n\t * for running a container once it is loaded.\n\t */\n\treadonly codeLoader: ICodeDetailsLoader;\n\n\t/**\n\t * A property bag of options used by various layers\n\t * to control features\n\t */\n\treadonly options?: ILoaderOptions;\n\n\t/**\n\t * Scope is provided to all container and is a set of shared\n\t * services for container's to integrate with their host environment.\n\t */\n\treadonly scope?: FluidObject;\n\n\t/**\n\t * The logger that all telemetry should be pushed to.\n\t */\n\treadonly logger?: ITelemetryBaseLogger;\n\n\t/**\n\t * Blobs storage for detached containers.\n\t */\n\treadonly detachedBlobStorage?: IDetachedBlobStorage;\n\n\t/**\n\t * The configuration provider which may be used to control features.\n\t */\n\treadonly configProvider?: IConfigProviderBase;\n\n\t/**\n\t * Optional property for allowing the container to use a custom\n\t * protocol implementation for handling the quorum and/or the audience.\n\t */\n\treadonly protocolHandlerBuilder?: ProtocolHandlerBuilder;\n}\n\n/**\n * Services and properties used by and exposed by the loader\n */\nexport interface ILoaderServices {\n\t/**\n\t * The url resolver used by the loader for resolving external urls\n\t * into Fluid urls such that the container specified by the\n\t * external url can be loaded.\n\t */\n\treadonly urlResolver: IUrlResolver;\n\t/**\n\t * The document service factory take the Fluid url provided\n\t * by the resolved url and constructs all the necessary services\n\t * for communication with the container's server.\n\t */\n\treadonly documentServiceFactory: IDocumentServiceFactory;\n\t/**\n\t * The code loader handles loading the necessary code\n\t * for running a container once it is loaded.\n\t */\n\treadonly codeLoader: ICodeDetailsLoader;\n\n\t/**\n\t * A property bag of options used by various layers\n\t * to control features\n\t */\n\treadonly options: ILoaderOptions;\n\n\t/**\n\t * Scope is provided to all container and is a set of shared\n\t * services for container's to integrate with their host environment.\n\t */\n\treadonly scope: FluidObject;\n\n\t/**\n\t * The logger downstream consumers should construct their loggers from\n\t */\n\treadonly subLogger: ITelemetryLoggerExt;\n\n\t/**\n\t * Blobs storage for detached containers.\n\t */\n\treadonly detachedBlobStorage?: IDetachedBlobStorage;\n\n\t/**\n\t * Optional property for allowing the container to use a custom\n\t * protocol implementation for handling the quorum and/or the audience.\n\t */\n\treadonly protocolHandlerBuilder?: ProtocolHandlerBuilder;\n}\n\n/**\n * Subset of IDocumentStorageService which only supports createBlob() and readBlob(). This is used to support\n * blobs in detached containers.\n */\nexport type IDetachedBlobStorage = Pick<IDocumentStorageService, \"createBlob\" | \"readBlob\"> & {\n\tsize: number;\n\t/**\n\t * Return an array of all blob IDs present in storage\n\t */\n\tgetBlobIds(): string[];\n};\n\n/**\n * With an already-resolved container, we can request a component directly, without loading the container again\n * @param container - a resolved container\n * @returns component on the container\n */\nexport async function requestResolvedObjectFromContainer(\n\tcontainer: IContainer,\n\theaders?: IRequestHeader,\n): Promise<IResponse> {\n\tensureResolvedUrlDefined(container.resolvedUrl);\n\tconst parsedUrl = parseUrl(container.resolvedUrl.url);\n\n\tif (parsedUrl === undefined) {\n\t\tthrow new Error(`Invalid URL ${container.resolvedUrl.url}`);\n\t}\n\n\tconst entryPoint: FluidObject<IFluidRouter> | undefined = await container.getEntryPoint?.();\n\tconst router = entryPoint?.IFluidRouter ?? container.IFluidRouter;\n\n\treturn router.request({\n\t\turl: `${parsedUrl.path}${parsedUrl.query}`,\n\t\theaders,\n\t});\n}\n\n/**\n * Manages Fluid resource loading\n */\nexport class Loader implements IHostLoader {\n\tprivate readonly containers = new Map<string, Promise<Container>>();\n\tpublic readonly services: ILoaderServices;\n\tprivate readonly mc: MonitoringContext;\n\n\tconstructor(loaderProps: ILoaderProps) {\n\t\tconst {\n\t\t\turlResolver,\n\t\t\tdocumentServiceFactory,\n\t\t\tcodeLoader,\n\t\t\toptions,\n\t\t\tscope,\n\t\t\tlogger,\n\t\t\tdetachedBlobStorage,\n\t\t\tconfigProvider,\n\t\t\tprotocolHandlerBuilder,\n\t\t} = loaderProps;\n\n\t\tconst telemetryProps = {\n\t\t\tloaderId: uuid(),\n\t\t\tloaderVersion: pkgVersion,\n\t\t};\n\n\t\tconst subMc = mixinMonitoringContext(\n\t\t\tDebugLogger.mixinDebugLogger(\"fluid:telemetry\", logger, {\n\t\t\t\tall: telemetryProps,\n\t\t\t}),\n\t\t\tsessionStorageConfigProvider.value,\n\t\t\tconfigProvider,\n\t\t);\n\n\t\tthis.services = {\n\t\t\turlResolver,\n\t\t\tdocumentServiceFactory,\n\t\t\tcodeLoader,\n\t\t\toptions: options ?? {},\n\t\t\tscope:\n\t\t\t\toptions?.provideScopeLoader !== false ? { ...scope, ILoader: this } : { ...scope },\n\t\t\tdetachedBlobStorage,\n\t\t\tprotocolHandlerBuilder,\n\t\t\tsubLogger: subMc.logger,\n\t\t};\n\t\tthis.mc = createChildMonitoringContext({\n\t\t\tlogger: this.services.subLogger,\n\t\t\tnamespace: \"Loader\",\n\t\t});\n\t}\n\n\t/**\n\t * @deprecated - Will be removed in future major release. Migrate all usage of IFluidRouter to the Container's IFluidRouter/request.\n\t */\n\tpublic get IFluidRouter(): IFluidRouter {\n\t\treturn this;\n\t}\n\n\tpublic async createDetachedContainer(codeDetails: IFluidCodeDetails): Promise<IContainer> {\n\t\tconst container = await Container.createDetached(this.services, codeDetails);\n\n\t\tif (this.cachingEnabled) {\n\t\t\tcontainer.once(\"attached\", () => {\n\t\t\t\tensureResolvedUrlDefined(container.resolvedUrl);\n\t\t\t\tconst parsedUrl = parseUrl(container.resolvedUrl.url);\n\t\t\t\tif (parsedUrl !== undefined) {\n\t\t\t\t\tthis.addToContainerCache(parsedUrl.id, Promise.resolve(container));\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\treturn container;\n\t}\n\n\tpublic async rehydrateDetachedContainerFromSnapshot(snapshot: string): Promise<IContainer> {\n\t\treturn Container.rehydrateDetachedFromSnapshot(this.services, snapshot);\n\t}\n\n\tpublic async resolve(request: IRequest, pendingLocalState?: string): Promise<IContainer> {\n\t\tconst eventName = pendingLocalState === undefined ? \"Resolve\" : \"ResolveWithPendingState\";\n\t\treturn PerformanceEvent.timedExecAsync(this.mc.logger, { eventName }, async () => {\n\t\t\tconst resolved = await this.resolveCore(\n\t\t\t\trequest,\n\t\t\t\tpendingLocalState !== undefined ? JSON.parse(pendingLocalState) : undefined,\n\t\t\t);\n\t\t\treturn resolved.container;\n\t\t});\n\t}\n\n\t/**\n\t * @deprecated - Will be removed in future major release. Migrate all usage of IFluidRouter to the Container's IFluidRouter/request.\n\t */\n\tpublic async request(request: IRequest): Promise<IResponse> {\n\t\treturn PerformanceEvent.timedExecAsync(\n\t\t\tthis.mc.logger,\n\t\t\t{ eventName: \"Request\" },\n\t\t\tasync () => {\n\t\t\t\tconst resolved = await this.resolveCore(request);\n\t\t\t\treturn resolved.container.request({\n\t\t\t\t\t...request,\n\t\t\t\t\turl: `${resolved.parsed.path}${resolved.parsed.query}`,\n\t\t\t\t});\n\t\t\t},\n\t\t);\n\t}\n\n\tprivate getKeyForContainerCache(request: IRequest, parsedUrl: IParsedUrl): string {\n\t\tconst key =\n\t\t\trequest.headers?.[LoaderHeader.version] !== undefined\n\t\t\t\t? `${parsedUrl.id}@${request.headers[LoaderHeader.version]}`\n\t\t\t\t: parsedUrl.id;\n\t\treturn key;\n\t}\n\n\tprivate addToContainerCache(key: string, containerP: Promise<Container>) {\n\t\tthis.containers.set(key, containerP);\n\t\tcontainerP\n\t\t\t.then((container) => {\n\t\t\t\t// If the container is closed/disposed or becomes closed/disposed after we resolve it,\n\t\t\t\t// remove it from the cache.\n\t\t\t\tif (container.closed || container.disposed) {\n\t\t\t\t\tthis.containers.delete(key);\n\t\t\t\t} else {\n\t\t\t\t\tcontainer.once(\"closed\", () => {\n\t\t\t\t\t\tthis.containers.delete(key);\n\t\t\t\t\t});\n\t\t\t\t\tcontainer.once(\"disposed\", () => {\n\t\t\t\t\t\tthis.containers.delete(key);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\t// If an error occured while resolving the container request, then remove it from the cache.\n\t\t\t\tthis.containers.delete(key);\n\t\t\t});\n\t}\n\n\tprivate async resolveCore(\n\t\trequest: IRequest,\n\t\tpendingLocalState?: IPendingContainerState,\n\t): Promise<{ container: Container; parsed: IParsedUrl }> {\n\t\tconst resolvedAsFluid = await this.services.urlResolver.resolve(request);\n\t\tensureResolvedUrlDefined(resolvedAsFluid);\n\n\t\t// Parse URL into data stores\n\t\tconst parsed = parseUrl(resolvedAsFluid.url);\n\t\tif (parsed === undefined) {\n\t\t\tthrow new Error(`Invalid URL ${resolvedAsFluid.url}`);\n\t\t}\n\n\t\tif (pendingLocalState !== undefined) {\n\t\t\tconst parsedPendingUrl = parseUrl(pendingLocalState.url);\n\t\t\tif (\n\t\t\t\tparsedPendingUrl?.id !== parsed.id ||\n\t\t\t\tparsedPendingUrl?.path.replace(/\\/$/, \"\") !== parsed.path.replace(/\\/$/, \"\")\n\t\t\t) {\n\t\t\t\tconst message = `URL ${resolvedAsFluid.url} does not match pending state URL ${pendingLocalState.url}`;\n\t\t\t\tthrow new Error(message);\n\t\t\t}\n\t\t}\n\n\t\trequest.headers ??= {};\n\t\t// If set in both query string and headers, use query string. Also write the value from the query string into the header either way.\n\t\trequest.headers[LoaderHeader.version] =\n\t\t\tparsed.version ?? request.headers[LoaderHeader.version];\n\t\tconst cacheHeader = request.headers[LoaderHeader.cache];\n\t\tconst canCache =\n\t\t\t// Take header value if present, else use ILoaderOptions.cache value\n\t\t\t(cacheHeader !== undefined ? cacheHeader === true : this.cachingEnabled) &&\n\t\t\tpendingLocalState === undefined;\n\t\tconst fromSequenceNumber = request.headers[LoaderHeader.sequenceNumber] as\n\t\t\t| number\n\t\t\t| undefined;\n\t\tconst opsBeforeReturn = request.headers[LoaderHeader.loadMode]?.opsBeforeReturn as\n\t\t\t| string\n\t\t\t| undefined;\n\n\t\tif (\n\t\t\topsBeforeReturn === \"sequenceNumber\" &&\n\t\t\t(fromSequenceNumber === undefined || fromSequenceNumber < 0)\n\t\t) {\n\t\t\t// If opsBeforeReturn is set to \"sequenceNumber\", then fromSequenceNumber should be set to a non-negative integer.\n\t\t\tthrow new UsageError(\"sequenceNumber must be set to a non-negative integer\");\n\t\t} else if (opsBeforeReturn !== \"sequenceNumber\" && fromSequenceNumber !== undefined) {\n\t\t\t// If opsBeforeReturn is not set to \"sequenceNumber\", then fromSequenceNumber should be undefined (default value).\n\t\t\t// In this case, we should throw an error since opsBeforeReturn is not explicitly set to \"sequenceNumber\".\n\t\t\tthrow new UsageError('opsBeforeReturn must be set to \"sequenceNumber\"');\n\t\t}\n\n\t\tlet container: Container;\n\t\tif (canCache) {\n\t\t\tconst key = this.getKeyForContainerCache(request, parsed);\n\t\t\tconst maybeContainer = await this.containers.get(key);\n\t\t\tif (maybeContainer !== undefined) {\n\t\t\t\tcontainer = maybeContainer;\n\t\t\t} else {\n\t\t\t\tconst containerP = this.loadContainer(request, resolvedAsFluid);\n\t\t\t\tthis.addToContainerCache(key, containerP);\n\t\t\t\tcontainer = await containerP;\n\t\t\t}\n\t\t} else {\n\t\t\tcontainer = await this.loadContainer(request, resolvedAsFluid, pendingLocalState);\n\t\t}\n\n\t\treturn { container, parsed };\n\t}\n\n\tprivate get cachingEnabled() {\n\t\treturn this.services.options.cache === true;\n\t}\n\n\tprivate async loadContainer(\n\t\trequest: IRequest,\n\t\tresolvedUrl: IResolvedUrl,\n\t\tpendingLocalState?: IPendingContainerState,\n\t): Promise<Container> {\n\t\treturn Container.load(\n\t\t\t{\n\t\t\t\tresolvedUrl,\n\t\t\t\tversion: request.headers?.[LoaderHeader.version] ?? undefined,\n\t\t\t\tloadMode: request.headers?.[LoaderHeader.loadMode],\n\t\t\t\tpendingLocalState,\n\t\t\t\tloadToSequenceNumber: request.headers?.[LoaderHeader.sequenceNumber],\n\t\t\t},\n\t\t\t{\n\t\t\t\tcanReconnect: request.headers?.[LoaderHeader.reconnect],\n\t\t\t\tclientDetailsOverride: request.headers?.[LoaderHeader.clientDetails],\n\t\t\t\t...this.services,\n\t\t\t},\n\t\t);\n\t}\n}\n"]}
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export declare const pkgName = "@fluidframework/container-loader";
8
- export declare const pkgVersion = "2.0.0-internal.5.4.0";
8
+ export declare const pkgVersion = "2.0.0-internal.6.1.0";
9
9
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -8,5 +8,5 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.pkgVersion = exports.pkgName = void 0;
10
10
  exports.pkgName = "@fluidframework/container-loader";
11
- exports.pkgVersion = "2.0.0-internal.5.4.0";
11
+ exports.pkgVersion = "2.0.0-internal.6.1.0";
12
12
  //# sourceMappingURL=packageVersion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,kCAAkC,CAAC;AAC7C,QAAA,UAAU,GAAG,sBAAsB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/container-loader\";\nexport const pkgVersion = \"2.0.0-internal.5.4.0\";\n"]}
1
+ {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,kCAAkC,CAAC;AAC7C,QAAA,UAAU,GAAG,sBAAsB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/container-loader\";\nexport const pkgVersion = \"2.0.0-internal.6.1.0\";\n"]}
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import { IAudienceOwner } from "@fluidframework/container-definitions";
6
6
  import { IProtocolHandler as IBaseProtocolHandler, IQuorumSnapshot, ProtocolOpHandler } from "@fluidframework/protocol-base";
7
- import { IDocumentAttributes, ISignalMessage } from "@fluidframework/protocol-definitions";
7
+ import { IDocumentAttributes, IProcessMessageResult, ISequencedDocumentMessage, ISignalMessage } from "@fluidframework/protocol-definitions";
8
8
  export declare const OnlyValidTermValue: 1;
9
9
  export declare enum SignalType {
10
10
  ClientJoin = "join",
@@ -21,7 +21,9 @@ export interface IProtocolHandler extends IBaseProtocolHandler {
21
21
  }
22
22
  export declare class ProtocolHandler extends ProtocolOpHandler implements IProtocolHandler {
23
23
  readonly audience: IAudienceOwner;
24
- constructor(attributes: IDocumentAttributes, quorumSnapshot: IQuorumSnapshot, sendProposal: (key: string, value: any) => number, audience: IAudienceOwner);
24
+ private readonly shouldClientHaveLeft;
25
+ constructor(attributes: IDocumentAttributes, quorumSnapshot: IQuorumSnapshot, sendProposal: (key: string, value: any) => number, audience: IAudienceOwner, shouldClientHaveLeft: (clientId: string) => boolean);
26
+ processMessage(message: ISequencedDocumentMessage, local: boolean): IProcessMessageResult;
25
27
  processSignal(message: ISignalMessage): void;
26
28
  }
27
29
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AACvE,OAAO,EACN,gBAAgB,IAAI,oBAAoB,EACxC,eAAe,EACf,iBAAiB,EACjB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACN,mBAAmB,EAEnB,cAAc,EACd,MAAM,sCAAsC,CAAC;AAG9C,eAAO,MAAM,kBAAkB,GAAa,CAAC;AAG7C,oBAAY,UAAU;IACrB,UAAU,SAAS;IACnB,WAAW,UAAU;IACrB,KAAK,UAAU;CACf;AAED;;GAEG;AACH,oBAAY,sBAAsB,GAAG,CACpC,UAAU,EAAE,mBAAmB,EAC/B,QAAQ,EAAE,eAAe,EACzB,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,MAAM,KAC7C,gBAAgB,CAAC;AAEtB,MAAM,WAAW,gBAAiB,SAAQ,oBAAoB;IAC7D,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,aAAa,CAAC,OAAO,EAAE,cAAc,OAAE;CACvC;AAED,qBAAa,eAAgB,SAAQ,iBAAkB,YAAW,gBAAgB;IAKhF,QAAQ,CAAC,QAAQ,EAAE,cAAc;gBAHjC,UAAU,EAAE,mBAAmB,EAC/B,cAAc,EAAE,eAAe,EAC/B,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,MAAM,EACxC,QAAQ,EAAE,cAAc;IAsB3B,aAAa,CAAC,OAAO,EAAE,cAAc;CAgC5C;AAED;;;;GAIG;AACH,wBAAgB,kCAAkC,CAAC,OAAO,EAAE,cAAc,WAWzE"}
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAEvE,OAAO,EACN,gBAAgB,IAAI,oBAAoB,EACxC,eAAe,EACf,iBAAiB,EACjB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACN,mBAAmB,EACnB,qBAAqB,EAErB,yBAAyB,EAEzB,cAAc,EAEd,MAAM,sCAAsC,CAAC;AAG9C,eAAO,MAAM,kBAAkB,GAAa,CAAC;AAG7C,oBAAY,UAAU;IACrB,UAAU,SAAS;IACnB,WAAW,UAAU;IACrB,KAAK,UAAU;CACf;AAED;;GAEG;AACH,oBAAY,sBAAsB,GAAG,CACpC,UAAU,EAAE,mBAAmB,EAC/B,QAAQ,EAAE,eAAe,EACzB,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,MAAM,KAC7C,gBAAgB,CAAC;AAEtB,MAAM,WAAW,gBAAiB,SAAQ,oBAAoB;IAC7D,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,aAAa,CAAC,OAAO,EAAE,cAAc,OAAE;CACvC;AAED,qBAAa,eAAgB,SAAQ,iBAAkB,YAAW,gBAAgB;aAKhE,QAAQ,EAAE,cAAc;IACxC,OAAO,CAAC,QAAQ,CAAC,oBAAoB;gBAJrC,UAAU,EAAE,mBAAmB,EAC/B,cAAc,EAAE,eAAe,EAC/B,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,MAAM,EACjC,QAAQ,EAAE,cAAc,EACvB,oBAAoB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO;IAqB9D,cAAc,CACpB,OAAO,EAAE,yBAAyB,EAClC,KAAK,EAAE,OAAO,GACZ,qBAAqB;IAuBjB,aAAa,CAAC,OAAO,EAAE,cAAc;CAgC5C;AAED;;;;GAIG;AACH,wBAAgB,kCAAkC,CAAC,OAAO,EAAE,cAAc,WAWzE"}
package/dist/protocol.js CHANGED
@@ -5,7 +5,9 @@
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.protocolHandlerShouldProcessSignal = exports.ProtocolHandler = exports.SignalType = exports.OnlyValidTermValue = void 0;
8
+ const driver_utils_1 = require("@fluidframework/driver-utils");
8
9
  const protocol_base_1 = require("@fluidframework/protocol-base");
10
+ const protocol_definitions_1 = require("@fluidframework/protocol-definitions");
9
11
  // "term" was an experimental feature that is being removed. The only safe value to use is 1.
10
12
  exports.OnlyValidTermValue = 1;
11
13
  // ADO: #1986: Start using enum from protocol-base.
@@ -16,9 +18,10 @@ var SignalType;
16
18
  SignalType["Clear"] = "clear";
17
19
  })(SignalType = exports.SignalType || (exports.SignalType = {}));
18
20
  class ProtocolHandler extends protocol_base_1.ProtocolOpHandler {
19
- constructor(attributes, quorumSnapshot, sendProposal, audience) {
20
- super(attributes.minimumSequenceNumber, attributes.sequenceNumber, exports.OnlyValidTermValue, quorumSnapshot.members, quorumSnapshot.proposals, quorumSnapshot.values, sendProposal);
21
+ constructor(attributes, quorumSnapshot, sendProposal, audience, shouldClientHaveLeft) {
22
+ super(attributes.minimumSequenceNumber, attributes.sequenceNumber, quorumSnapshot.members, quorumSnapshot.proposals, quorumSnapshot.values, sendProposal);
21
23
  this.audience = audience;
24
+ this.shouldClientHaveLeft = shouldClientHaveLeft;
22
25
  // Join / leave signals are ignored for "write" clients in favor of join / leave ops
23
26
  this.quorum.on("addMember", (clientId, details) => audience.addMember(clientId, details.client));
24
27
  this.quorum.on("removeMember", (clientId) => audience.removeMember(clientId));
@@ -26,8 +29,26 @@ class ProtocolHandler extends protocol_base_1.ProtocolOpHandler {
26
29
  this.audience.addMember(clientId, details.client);
27
30
  }
28
31
  }
32
+ processMessage(message, local) {
33
+ const client = this.quorum.getMember(message.clientId);
34
+ // Check and report if we're getting messages from a clientId that we previously
35
+ // flagged as shouldHaveLeft, or from a client that's not in the quorum but should be
36
+ if (message.clientId != null) {
37
+ if (client === undefined && message.type !== protocol_definitions_1.MessageType.ClientJoin) {
38
+ // pre-0.58 error message: messageClientIdMissingFromQuorum
39
+ throw new Error("Remote message's clientId is missing from the quorum");
40
+ }
41
+ // Here checking canBeCoalescedByService is used as an approximation of "is benign to process despite being unexpected".
42
+ // It's still not good to see these messages from unexpected clientIds, but since they don't harm the integrity of the
43
+ // document we don't need to blow up aggressively.
44
+ if (this.shouldClientHaveLeft(message.clientId) && !(0, driver_utils_1.canBeCoalescedByService)(message)) {
45
+ // pre-0.58 error message: messageClientIdShouldHaveLeft
46
+ throw new Error("Remote message's clientId already should have left");
47
+ }
48
+ }
49
+ return super.processMessage(message, local);
50
+ }
29
51
  processSignal(message) {
30
- var _a;
31
52
  const innerContent = message.content;
32
53
  switch (innerContent.type) {
33
54
  case SignalType.Clear: {
@@ -50,7 +71,7 @@ class ProtocolHandler extends protocol_base_1.ProtocolOpHandler {
50
71
  case SignalType.ClientLeave: {
51
72
  const leftClientId = innerContent.content;
52
73
  // Ignore write clients - quorum will control such clients.
53
- if (((_a = this.audience.getMember(leftClientId)) === null || _a === void 0 ? void 0 : _a.mode) === "read") {
74
+ if (this.audience.getMember(leftClientId)?.mode === "read") {
54
75
  this.audience.removeMember(leftClientId);
55
76
  }
56
77
  break;
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.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 { IAudienceOwner } from \"@fluidframework/container-definitions\";\nimport {\n\tIProtocolHandler as IBaseProtocolHandler,\n\tIQuorumSnapshot,\n\tProtocolOpHandler,\n} from \"@fluidframework/protocol-base\";\nimport {\n\tIDocumentAttributes,\n\tISignalClient,\n\tISignalMessage,\n} from \"@fluidframework/protocol-definitions\";\n\n// \"term\" was an experimental feature that is being removed. The only safe value to use is 1.\nexport const OnlyValidTermValue = 1 as const;\n\n// ADO: #1986: Start using enum from protocol-base.\nexport enum SignalType {\n\tClientJoin = \"join\", // same value as MessageType.ClientJoin,\n\tClientLeave = \"leave\", // same value as MessageType.ClientLeave,\n\tClear = \"clear\", // used only by client for synthetic signals\n}\n\n/**\n * Function to be used for creating a protocol handler.\n */\nexport type ProtocolHandlerBuilder = (\n\tattributes: IDocumentAttributes,\n\tsnapshot: IQuorumSnapshot,\n\tsendProposal: (key: string, value: any) => number,\n) => IProtocolHandler;\n\nexport interface IProtocolHandler extends IBaseProtocolHandler {\n\treadonly audience: IAudienceOwner;\n\tprocessSignal(message: ISignalMessage);\n}\n\nexport class ProtocolHandler extends ProtocolOpHandler implements IProtocolHandler {\n\tconstructor(\n\t\tattributes: IDocumentAttributes,\n\t\tquorumSnapshot: IQuorumSnapshot,\n\t\tsendProposal: (key: string, value: any) => number,\n\t\treadonly audience: IAudienceOwner,\n\t) {\n\t\tsuper(\n\t\t\tattributes.minimumSequenceNumber,\n\t\t\tattributes.sequenceNumber,\n\t\t\tOnlyValidTermValue,\n\t\t\tquorumSnapshot.members,\n\t\t\tquorumSnapshot.proposals,\n\t\t\tquorumSnapshot.values,\n\t\t\tsendProposal,\n\t\t);\n\n\t\t// Join / leave signals are ignored for \"write\" clients in favor of join / leave ops\n\t\tthis.quorum.on(\"addMember\", (clientId, details) =>\n\t\t\taudience.addMember(clientId, details.client),\n\t\t);\n\t\tthis.quorum.on(\"removeMember\", (clientId) => audience.removeMember(clientId));\n\t\tfor (const [clientId, details] of this.quorum.getMembers()) {\n\t\t\tthis.audience.addMember(clientId, details.client);\n\t\t}\n\t}\n\n\tpublic processSignal(message: ISignalMessage) {\n\t\tconst innerContent = message.content as { content: any; type: string };\n\t\tswitch (innerContent.type) {\n\t\t\tcase SignalType.Clear: {\n\t\t\t\tconst members = this.audience.getMembers();\n\t\t\t\tfor (const [clientId, client] of members) {\n\t\t\t\t\tif (client.mode === \"read\") {\n\t\t\t\t\t\tthis.audience.removeMember(clientId);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SignalType.ClientJoin: {\n\t\t\t\tconst newClient = innerContent.content as ISignalClient;\n\t\t\t\t// Ignore write clients - quorum will control such clients.\n\t\t\t\tif (newClient.client.mode === \"read\") {\n\t\t\t\t\tthis.audience.addMember(newClient.clientId, newClient.client);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SignalType.ClientLeave: {\n\t\t\t\tconst leftClientId = innerContent.content as string;\n\t\t\t\t// Ignore write clients - quorum will control such clients.\n\t\t\t\tif (this.audience.getMember(leftClientId)?.mode === \"read\") {\n\t\t\t\t\tthis.audience.removeMember(leftClientId);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/**\n * Function to check whether the protocol handler should process the Signal.\n * The protocol handler should strictly handle only ClientJoin, ClientLeave\n * and Clear signal types.\n */\nexport function protocolHandlerShouldProcessSignal(message: ISignalMessage) {\n\t// Signal originates from server\n\tif (message.clientId === null) {\n\t\tconst innerContent = message.content as { content: unknown; type: string };\n\t\treturn (\n\t\t\tinnerContent.type === SignalType.Clear ||\n\t\t\tinnerContent.type === SignalType.ClientJoin ||\n\t\t\tinnerContent.type === SignalType.ClientLeave\n\t\t);\n\t}\n\treturn false;\n}\n"]}
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,+DAAuE;AACvE,iEAIuC;AACvC,+EAQ8C;AAE9C,8FAA8F;AACjF,QAAA,kBAAkB,GAAG,CAAU,CAAC;AAE7C,mDAAmD;AACnD,IAAY,UAIX;AAJD,WAAY,UAAU;IACrB,iCAAmB,CAAA;IACnB,mCAAqB,CAAA;IACrB,6BAAe,CAAA;AAChB,CAAC,EAJW,UAAU,GAAV,kBAAU,KAAV,kBAAU,QAIrB;AAgBD,MAAa,eAAgB,SAAQ,iCAAiB;IACrD,YACC,UAA+B,EAC/B,cAA+B,EAC/B,YAAiD,EACjC,QAAwB,EACvB,oBAAmD;QAEpE,KAAK,CACJ,UAAU,CAAC,qBAAqB,EAChC,UAAU,CAAC,cAAc,EACzB,cAAc,CAAC,OAAO,EACtB,cAAc,CAAC,SAAS,EACxB,cAAc,CAAC,MAAM,EACrB,YAAY,CACZ,CAAC;QAVc,aAAQ,GAAR,QAAQ,CAAgB;QACvB,yBAAoB,GAApB,oBAAoB,CAA+B;QAWpE,oFAAoF;QACpF,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,CACjD,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAC5C,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC9E,KAAK,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE;YAC3D,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;SAClD;IACF,CAAC;IAEM,cAAc,CACpB,OAAkC,EAClC,KAAc;QAEd,MAAM,MAAM,GAAiC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAErF,gFAAgF;QAChF,qFAAqF;QACrF,IAAI,OAAO,CAAC,QAAQ,IAAI,IAAI,EAAE;YAC7B,IAAI,MAAM,KAAK,SAAS,IAAI,OAAO,CAAC,IAAI,KAAK,kCAAW,CAAC,UAAU,EAAE;gBACpE,2DAA2D;gBAC3D,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;aACxE;YAED,wHAAwH;YACxH,sHAAsH;YACtH,kDAAkD;YAClD,IAAI,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAA,sCAAuB,EAAC,OAAO,CAAC,EAAE;gBACrF,wDAAwD;gBACxD,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;aACtE;SACD;QAED,OAAO,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC7C,CAAC;IAEM,aAAa,CAAC,OAAuB;QAC3C,MAAM,YAAY,GAAG,OAAO,CAAC,OAAyC,CAAC;QACvE,QAAQ,YAAY,CAAC,IAAI,EAAE;YAC1B,KAAK,UAAU,CAAC,KAAK,CAAC,CAAC;gBACtB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;gBAC3C,KAAK,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,OAAO,EAAE;oBACzC,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE;wBAC3B,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;qBACrC;iBACD;gBACD,MAAM;aACN;YACD,KAAK,UAAU,CAAC,UAAU,CAAC,CAAC;gBAC3B,MAAM,SAAS,GAAG,YAAY,CAAC,OAAwB,CAAC;gBACxD,2DAA2D;gBAC3D,IAAI,SAAS,CAAC,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE;oBACrC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;iBAC9D;gBACD,MAAM;aACN;YACD,KAAK,UAAU,CAAC,WAAW,CAAC,CAAC;gBAC5B,MAAM,YAAY,GAAG,YAAY,CAAC,OAAiB,CAAC;gBACpD,2DAA2D;gBAC3D,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,IAAI,KAAK,MAAM,EAAE;oBAC3D,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;iBACzC;gBACD,MAAM;aACN;YACD;gBACC,MAAM;SACP;IACF,CAAC;CACD;AArFD,0CAqFC;AAED;;;;GAIG;AACH,SAAgB,kCAAkC,CAAC,OAAuB;IACzE,gCAAgC;IAChC,IAAI,OAAO,CAAC,QAAQ,KAAK,IAAI,EAAE;QAC9B,MAAM,YAAY,GAAG,OAAO,CAAC,OAA6C,CAAC;QAC3E,OAAO,CACN,YAAY,CAAC,IAAI,KAAK,UAAU,CAAC,KAAK;YACtC,YAAY,CAAC,IAAI,KAAK,UAAU,CAAC,UAAU;YAC3C,YAAY,CAAC,IAAI,KAAK,UAAU,CAAC,WAAW,CAC5C,CAAC;KACF;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAXD,gFAWC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IAudienceOwner } from \"@fluidframework/container-definitions\";\nimport { canBeCoalescedByService } from \"@fluidframework/driver-utils\";\nimport {\n\tIProtocolHandler as IBaseProtocolHandler,\n\tIQuorumSnapshot,\n\tProtocolOpHandler,\n} from \"@fluidframework/protocol-base\";\nimport {\n\tIDocumentAttributes,\n\tIProcessMessageResult,\n\tISequencedClient,\n\tISequencedDocumentMessage,\n\tISignalClient,\n\tISignalMessage,\n\tMessageType,\n} from \"@fluidframework/protocol-definitions\";\n\n// \"term\" was an experimental feature that is being removed. The only safe value to use is 1.\nexport const OnlyValidTermValue = 1 as const;\n\n// ADO: #1986: Start using enum from protocol-base.\nexport enum SignalType {\n\tClientJoin = \"join\", // same value as MessageType.ClientJoin,\n\tClientLeave = \"leave\", // same value as MessageType.ClientLeave,\n\tClear = \"clear\", // used only by client for synthetic signals\n}\n\n/**\n * Function to be used for creating a protocol handler.\n */\nexport type ProtocolHandlerBuilder = (\n\tattributes: IDocumentAttributes,\n\tsnapshot: IQuorumSnapshot,\n\tsendProposal: (key: string, value: any) => number,\n) => IProtocolHandler;\n\nexport interface IProtocolHandler extends IBaseProtocolHandler {\n\treadonly audience: IAudienceOwner;\n\tprocessSignal(message: ISignalMessage);\n}\n\nexport class ProtocolHandler extends ProtocolOpHandler implements IProtocolHandler {\n\tconstructor(\n\t\tattributes: IDocumentAttributes,\n\t\tquorumSnapshot: IQuorumSnapshot,\n\t\tsendProposal: (key: string, value: any) => number,\n\t\tpublic readonly audience: IAudienceOwner,\n\t\tprivate readonly shouldClientHaveLeft: (clientId: string) => boolean,\n\t) {\n\t\tsuper(\n\t\t\tattributes.minimumSequenceNumber,\n\t\t\tattributes.sequenceNumber,\n\t\t\tquorumSnapshot.members,\n\t\t\tquorumSnapshot.proposals,\n\t\t\tquorumSnapshot.values,\n\t\t\tsendProposal,\n\t\t);\n\n\t\t// Join / leave signals are ignored for \"write\" clients in favor of join / leave ops\n\t\tthis.quorum.on(\"addMember\", (clientId, details) =>\n\t\t\taudience.addMember(clientId, details.client),\n\t\t);\n\t\tthis.quorum.on(\"removeMember\", (clientId) => audience.removeMember(clientId));\n\t\tfor (const [clientId, details] of this.quorum.getMembers()) {\n\t\t\tthis.audience.addMember(clientId, details.client);\n\t\t}\n\t}\n\n\tpublic processMessage(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tlocal: boolean,\n\t): IProcessMessageResult {\n\t\tconst client: ISequencedClient | undefined = this.quorum.getMember(message.clientId);\n\n\t\t// Check and report if we're getting messages from a clientId that we previously\n\t\t// flagged as shouldHaveLeft, or from a client that's not in the quorum but should be\n\t\tif (message.clientId != null) {\n\t\t\tif (client === undefined && message.type !== MessageType.ClientJoin) {\n\t\t\t\t// pre-0.58 error message: messageClientIdMissingFromQuorum\n\t\t\t\tthrow new Error(\"Remote message's clientId is missing from the quorum\");\n\t\t\t}\n\n\t\t\t// Here checking canBeCoalescedByService is used as an approximation of \"is benign to process despite being unexpected\".\n\t\t\t// It's still not good to see these messages from unexpected clientIds, but since they don't harm the integrity of the\n\t\t\t// document we don't need to blow up aggressively.\n\t\t\tif (this.shouldClientHaveLeft(message.clientId) && !canBeCoalescedByService(message)) {\n\t\t\t\t// pre-0.58 error message: messageClientIdShouldHaveLeft\n\t\t\t\tthrow new Error(\"Remote message's clientId already should have left\");\n\t\t\t}\n\t\t}\n\n\t\treturn super.processMessage(message, local);\n\t}\n\n\tpublic processSignal(message: ISignalMessage) {\n\t\tconst innerContent = message.content as { content: any; type: string };\n\t\tswitch (innerContent.type) {\n\t\t\tcase SignalType.Clear: {\n\t\t\t\tconst members = this.audience.getMembers();\n\t\t\t\tfor (const [clientId, client] of members) {\n\t\t\t\t\tif (client.mode === \"read\") {\n\t\t\t\t\t\tthis.audience.removeMember(clientId);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SignalType.ClientJoin: {\n\t\t\t\tconst newClient = innerContent.content as ISignalClient;\n\t\t\t\t// Ignore write clients - quorum will control such clients.\n\t\t\t\tif (newClient.client.mode === \"read\") {\n\t\t\t\t\tthis.audience.addMember(newClient.clientId, newClient.client);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SignalType.ClientLeave: {\n\t\t\t\tconst leftClientId = innerContent.content as string;\n\t\t\t\t// Ignore write clients - quorum will control such clients.\n\t\t\t\tif (this.audience.getMember(leftClientId)?.mode === \"read\") {\n\t\t\t\t\tthis.audience.removeMember(leftClientId);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/**\n * Function to check whether the protocol handler should process the Signal.\n * The protocol handler should strictly handle only ClientJoin, ClientLeave\n * and Clear signal types.\n */\nexport function protocolHandlerShouldProcessSignal(message: ISignalMessage) {\n\t// Signal originates from server\n\tif (message.clientId === null) {\n\t\tconst innerContent = message.content as { content: unknown; type: string };\n\t\treturn (\n\t\t\tinnerContent.type === SignalType.Clear ||\n\t\t\tinnerContent.type === SignalType.ClientJoin ||\n\t\t\tinnerContent.type === SignalType.ClientLeave\n\t\t);\n\t}\n\treturn false;\n}\n"]}
package/dist/utils.d.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  import { ISummaryTree, ISnapshotTree } from "@fluidframework/protocol-definitions";
6
- import { DeltaStreamConnectionForbiddenError } from "@fluidframework/driver-utils";
6
+ import { CombinedAppAndProtocolSummary, DeltaStreamConnectionForbiddenError } from "@fluidframework/driver-utils";
7
7
  export interface ISnapshotTreeWithBlobContents extends ISnapshotTree {
8
8
  blobsContents: {
9
9
  [path: string]: ArrayBufferLike;
@@ -24,6 +24,13 @@ export interface IParsedUrl {
24
24
  version: string | null | undefined;
25
25
  }
26
26
  export declare function parseUrl(url: string): IParsedUrl | undefined;
27
+ /**
28
+ * Combine the app summary and protocol summary in 1 tree.
29
+ * @param appSummary - Summary of the app.
30
+ * @param protocolSummary - Summary of the protocol.
31
+ * @internal
32
+ */
33
+ export declare function combineAppAndProtocolSummary(appSummary: ISummaryTree, protocolSummary: ISummaryTree): CombinedAppAndProtocolSummary;
27
34
  /**
28
35
  * Combine and convert protocol and app summary tree to format which is readable by container while rehydrating.
29
36
  * @param protocolSummaryTree - Protocol Summary Tree
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAe,MAAM,sCAAsC,CAAC;AAEhG,OAAO,EACN,mCAAmC,EAEnC,MAAM,8BAA8B,CAAC;AAKtC,MAAM,WAAW,6BAA8B,SAAQ,aAAa;IACnE,aAAa,EAAE;QAAE,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAAA;KAAE,CAAC;IACnD,KAAK,EAAE;QAAE,CAAC,IAAI,EAAE,MAAM,GAAG,6BAA6B,CAAA;KAAE,CAAC;CACzD;AAED,MAAM,WAAW,UAAU;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACnC;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAW5D;AA0DD;;;;GAIG;AACH,wBAAgB,0CAA0C,CACzD,mBAAmB,EAAE,YAAY,EACjC,cAAc,EAAE,YAAY,GAC1B,6BAA6B,CAW/B;AAID,eAAO,MAAM,sCAAsC,8BACvB,YAAY,KACrC,6BAYF,CAAC;AAEF,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,aAAa,GAAG,aAAa,CAE9E;AAED,wBAAgB,qCAAqC,CACpD,KAAK,EAAE,GAAG,GACR,KAAK,IAAI,mCAAmC,CAM9C"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAe,MAAM,sCAAsC,CAAC;AAEhG,OAAO,EACN,6BAA6B,EAC7B,mCAAmC,EAEnC,MAAM,8BAA8B,CAAC;AAKtC,MAAM,WAAW,6BAA8B,SAAQ,aAAa;IACnE,aAAa,EAAE;QAAE,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAAA;KAAE,CAAC;IACnD,KAAK,EAAE;QAAE,CAAC,IAAI,EAAE,MAAM,GAAG,6BAA6B,CAAA;KAAE,CAAC;CACzD;AAED,MAAM,WAAW,UAAU;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACnC;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAW5D;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC3C,UAAU,EAAE,YAAY,EACxB,eAAe,EAAE,YAAY,GAC3B,6BAA6B,CAiB/B;AA0DD;;;;GAIG;AACH,wBAAgB,0CAA0C,CACzD,mBAAmB,EAAE,YAAY,EACjC,cAAc,EAAE,YAAY,GAC1B,6BAA6B,CAW/B;AAID,eAAO,MAAM,sCAAsC,8BACvB,YAAY,KACrC,6BAYF,CAAC;AAEF,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,aAAa,GAAG,aAAa,CAE9E;AAED,wBAAgB,qCAAqC,CACpD,KAAK,EAAE,GAAG,GACR,KAAK,IAAI,mCAAmC,CAM9C"}