@fluidframework/container-loader 2.0.0-rc.2.0.2 → 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 (246) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/api-report/container-loader.api.md +13 -13
  3. package/dist/attachment.d.ts +6 -9
  4. package/dist/attachment.d.ts.map +1 -1
  5. package/dist/attachment.js +5 -5
  6. package/dist/attachment.js.map +1 -1
  7. package/dist/audience.d.ts +1 -1
  8. package/dist/audience.d.ts.map +1 -1
  9. package/dist/audience.js +4 -4
  10. package/dist/audience.js.map +1 -1
  11. package/dist/catchUpMonitor.d.ts +1 -1
  12. package/dist/catchUpMonitor.d.ts.map +1 -1
  13. package/dist/catchUpMonitor.js +2 -2
  14. package/dist/catchUpMonitor.js.map +1 -1
  15. package/dist/connectionManager.d.ts +4 -4
  16. package/dist/connectionManager.d.ts.map +1 -1
  17. package/dist/connectionManager.js +48 -43
  18. package/dist/connectionManager.js.map +1 -1
  19. package/dist/connectionStateHandler.d.ts +3 -3
  20. package/dist/connectionStateHandler.d.ts.map +1 -1
  21. package/dist/connectionStateHandler.js +27 -27
  22. package/dist/connectionStateHandler.js.map +1 -1
  23. package/dist/container.d.ts +9 -46
  24. package/dist/container.d.ts.map +1 -1
  25. package/dist/container.js +105 -116
  26. package/dist/container.js.map +1 -1
  27. package/dist/containerContext.d.ts +19 -7
  28. package/dist/containerContext.d.ts.map +1 -1
  29. package/dist/containerContext.js +7 -2
  30. package/dist/containerContext.js.map +1 -1
  31. package/dist/containerStorageAdapter.d.ts +3 -3
  32. package/dist/containerStorageAdapter.d.ts.map +1 -1
  33. package/dist/containerStorageAdapter.js +6 -6
  34. package/dist/containerStorageAdapter.js.map +1 -1
  35. package/dist/contracts.d.ts +4 -3
  36. package/dist/contracts.d.ts.map +1 -1
  37. package/dist/contracts.js +2 -2
  38. package/dist/contracts.js.map +1 -1
  39. package/dist/debugLogger.d.ts +2 -1
  40. package/dist/debugLogger.d.ts.map +1 -1
  41. package/dist/debugLogger.js +4 -4
  42. package/dist/debugLogger.js.map +1 -1
  43. package/dist/deltaManager.d.ts +11 -7
  44. package/dist/deltaManager.d.ts.map +1 -1
  45. package/dist/deltaManager.js +53 -50
  46. package/dist/deltaManager.js.map +1 -1
  47. package/dist/deltaQueue.d.ts +1 -1
  48. package/dist/deltaQueue.d.ts.map +1 -1
  49. package/dist/deltaQueue.js +5 -5
  50. package/dist/deltaQueue.js.map +1 -1
  51. package/dist/error.d.ts +3 -2
  52. package/dist/error.d.ts.map +1 -1
  53. package/dist/error.js +5 -5
  54. package/dist/error.js.map +1 -1
  55. package/dist/legacy.d.ts +29 -0
  56. package/dist/loader.d.ts +4 -4
  57. package/dist/loader.d.ts.map +1 -1
  58. package/dist/loader.js +23 -23
  59. package/dist/loader.js.map +1 -1
  60. package/dist/location-redirection-utilities/resolveWithLocationRedirection.d.ts +2 -2
  61. package/dist/location-redirection-utilities/resolveWithLocationRedirection.d.ts.map +1 -1
  62. package/dist/location-redirection-utilities/resolveWithLocationRedirection.js +2 -2
  63. package/dist/location-redirection-utilities/resolveWithLocationRedirection.js.map +1 -1
  64. package/dist/noopHeuristic.d.ts +1 -1
  65. package/dist/noopHeuristic.d.ts.map +1 -1
  66. package/dist/noopHeuristic.js +6 -6
  67. package/dist/noopHeuristic.js.map +1 -1
  68. package/dist/packageVersion.d.ts +1 -1
  69. package/dist/packageVersion.js +1 -1
  70. package/dist/packageVersion.js.map +1 -1
  71. package/dist/protocol.d.ts +1 -1
  72. package/dist/protocol.d.ts.map +1 -1
  73. package/dist/protocol.js +2 -2
  74. package/dist/protocol.js.map +1 -1
  75. package/dist/protocolTreeDocumentStorageService.d.ts +4 -4
  76. package/dist/protocolTreeDocumentStorageService.d.ts.map +1 -1
  77. package/dist/protocolTreeDocumentStorageService.js.map +1 -1
  78. package/dist/public.d.ts +14 -0
  79. package/dist/quorum.d.ts +1 -1
  80. package/dist/quorum.d.ts.map +1 -1
  81. package/dist/quorum.js +4 -0
  82. package/dist/quorum.js.map +1 -1
  83. package/dist/retriableDocumentStorageService.d.ts +2 -2
  84. package/dist/retriableDocumentStorageService.d.ts.map +1 -1
  85. package/dist/retriableDocumentStorageService.js +7 -7
  86. package/dist/retriableDocumentStorageService.js.map +1 -1
  87. package/dist/serializedStateManager.d.ts +86 -16
  88. package/dist/serializedStateManager.d.ts.map +1 -1
  89. package/dist/serializedStateManager.js +182 -82
  90. package/dist/serializedStateManager.js.map +1 -1
  91. package/dist/utils.d.ts +24 -9
  92. package/dist/utils.d.ts.map +1 -1
  93. package/dist/utils.js +82 -25
  94. package/dist/utils.js.map +1 -1
  95. package/internal.d.ts +11 -0
  96. package/legacy.d.ts +11 -0
  97. package/lib/attachment.d.ts +6 -9
  98. package/lib/attachment.d.ts.map +1 -1
  99. package/lib/attachment.js +1 -1
  100. package/lib/attachment.js.map +1 -1
  101. package/lib/audience.d.ts +1 -1
  102. package/lib/audience.d.ts.map +1 -1
  103. package/lib/audience.js +1 -1
  104. package/lib/audience.js.map +1 -1
  105. package/lib/catchUpMonitor.d.ts +1 -1
  106. package/lib/catchUpMonitor.d.ts.map +1 -1
  107. package/lib/catchUpMonitor.js +1 -1
  108. package/lib/catchUpMonitor.js.map +1 -1
  109. package/lib/connectionManager.d.ts +4 -4
  110. package/lib/connectionManager.d.ts.map +1 -1
  111. package/lib/connectionManager.js +11 -6
  112. package/lib/connectionManager.js.map +1 -1
  113. package/lib/connectionStateHandler.d.ts +3 -3
  114. package/lib/connectionStateHandler.d.ts.map +1 -1
  115. package/lib/connectionStateHandler.js +2 -2
  116. package/lib/connectionStateHandler.js.map +1 -1
  117. package/lib/container.d.ts +9 -46
  118. package/lib/container.d.ts.map +1 -1
  119. package/lib/container.js +37 -48
  120. package/lib/container.js.map +1 -1
  121. package/lib/containerContext.d.ts +19 -7
  122. package/lib/containerContext.d.ts.map +1 -1
  123. package/lib/containerContext.js +7 -2
  124. package/lib/containerContext.js.map +1 -1
  125. package/lib/containerStorageAdapter.d.ts +3 -3
  126. package/lib/containerStorageAdapter.d.ts.map +1 -1
  127. package/lib/containerStorageAdapter.js +2 -2
  128. package/lib/containerStorageAdapter.js.map +1 -1
  129. package/lib/contracts.d.ts +4 -3
  130. package/lib/contracts.d.ts.map +1 -1
  131. package/lib/contracts.js +1 -1
  132. package/lib/contracts.js.map +1 -1
  133. package/lib/debugLogger.d.ts +2 -1
  134. package/lib/debugLogger.d.ts.map +1 -1
  135. package/lib/debugLogger.js +1 -1
  136. package/lib/debugLogger.js.map +1 -1
  137. package/lib/deltaManager.d.ts +11 -7
  138. package/lib/deltaManager.d.ts.map +1 -1
  139. package/lib/deltaManager.js +13 -10
  140. package/lib/deltaManager.js.map +1 -1
  141. package/lib/deltaQueue.d.ts +1 -1
  142. package/lib/deltaQueue.d.ts.map +1 -1
  143. package/lib/deltaQueue.js +2 -2
  144. package/lib/deltaQueue.js.map +1 -1
  145. package/lib/error.d.ts +3 -2
  146. package/lib/error.d.ts.map +1 -1
  147. package/lib/error.js +2 -2
  148. package/lib/error.js.map +1 -1
  149. package/lib/legacy.d.ts +29 -0
  150. package/lib/loader.d.ts +4 -4
  151. package/lib/loader.d.ts.map +1 -1
  152. package/lib/loader.js +4 -4
  153. package/lib/loader.js.map +1 -1
  154. package/lib/location-redirection-utilities/resolveWithLocationRedirection.d.ts +2 -2
  155. package/lib/location-redirection-utilities/resolveWithLocationRedirection.d.ts.map +1 -1
  156. package/lib/location-redirection-utilities/resolveWithLocationRedirection.js +2 -2
  157. package/lib/location-redirection-utilities/resolveWithLocationRedirection.js.map +1 -1
  158. package/lib/noopHeuristic.d.ts +1 -1
  159. package/lib/noopHeuristic.d.ts.map +1 -1
  160. package/lib/noopHeuristic.js +2 -2
  161. package/lib/noopHeuristic.js.map +1 -1
  162. package/lib/packageVersion.d.ts +1 -1
  163. package/lib/packageVersion.js +1 -1
  164. package/lib/packageVersion.js.map +1 -1
  165. package/lib/protocol.d.ts +1 -1
  166. package/lib/protocol.d.ts.map +1 -1
  167. package/lib/protocol.js +1 -1
  168. package/lib/protocol.js.map +1 -1
  169. package/lib/protocolTreeDocumentStorageService.d.ts +4 -4
  170. package/lib/protocolTreeDocumentStorageService.d.ts.map +1 -1
  171. package/lib/protocolTreeDocumentStorageService.js.map +1 -1
  172. package/lib/public.d.ts +14 -0
  173. package/lib/quorum.d.ts +1 -1
  174. package/lib/quorum.d.ts.map +1 -1
  175. package/lib/quorum.js +4 -0
  176. package/lib/quorum.js.map +1 -1
  177. package/lib/retriableDocumentStorageService.d.ts +2 -2
  178. package/lib/retriableDocumentStorageService.d.ts.map +1 -1
  179. package/lib/retriableDocumentStorageService.js +3 -3
  180. package/lib/retriableDocumentStorageService.js.map +1 -1
  181. package/lib/serializedStateManager.d.ts +86 -16
  182. package/lib/serializedStateManager.d.ts.map +1 -1
  183. package/lib/serializedStateManager.js +174 -77
  184. package/lib/serializedStateManager.js.map +1 -1
  185. package/lib/utils.d.ts +24 -9
  186. package/lib/utils.d.ts.map +1 -1
  187. package/lib/utils.js +69 -15
  188. package/lib/utils.js.map +1 -1
  189. package/package.json +37 -58
  190. package/src/attachment.ts +10 -8
  191. package/src/audience.ts +3 -2
  192. package/src/catchUpMonitor.ts +2 -2
  193. package/src/connectionManager.ts +27 -20
  194. package/src/connectionStateHandler.ts +7 -7
  195. package/src/container.ts +90 -143
  196. package/src/containerContext.ts +22 -12
  197. package/src/containerStorageAdapter.ts +7 -6
  198. package/src/contracts.ts +4 -5
  199. package/src/debugLogger.ts +3 -4
  200. package/src/deltaManager.ts +40 -30
  201. package/src/deltaQueue.ts +2 -2
  202. package/src/error.ts +5 -4
  203. package/src/loader.ts +25 -23
  204. package/src/location-redirection-utilities/resolveWithLocationRedirection.ts +4 -4
  205. package/src/noopHeuristic.ts +3 -3
  206. package/src/packageVersion.ts +1 -1
  207. package/src/protocol.ts +2 -2
  208. package/src/protocolTreeDocumentStorageService.ts +4 -1
  209. package/src/quorum.ts +2 -1
  210. package/src/retriableDocumentStorageService.ts +6 -5
  211. package/src/serializedStateManager.ts +299 -111
  212. package/src/utils.ts +103 -24
  213. package/api-extractor-cjs.json +0 -8
  214. package/dist/container-loader-alpha.d.ts +0 -275
  215. package/dist/container-loader-beta.d.ts +0 -101
  216. package/dist/container-loader-public.d.ts +0 -101
  217. package/dist/container-loader-untrimmed.d.ts +0 -331
  218. package/lib/container-loader-alpha.d.ts +0 -275
  219. package/lib/container-loader-beta.d.ts +0 -101
  220. package/lib/container-loader-public.d.ts +0 -101
  221. package/lib/container-loader-untrimmed.d.ts +0 -331
  222. package/lib/test/attachment.spec.js +0 -380
  223. package/lib/test/attachment.spec.js.map +0 -1
  224. package/lib/test/catchUpMonitor.spec.js +0 -88
  225. package/lib/test/catchUpMonitor.spec.js.map +0 -1
  226. package/lib/test/connectionManager.spec.js +0 -201
  227. package/lib/test/connectionManager.spec.js.map +0 -1
  228. package/lib/test/connectionStateHandler.spec.js +0 -555
  229. package/lib/test/connectionStateHandler.spec.js.map +0 -1
  230. package/lib/test/container.spec.js +0 -64
  231. package/lib/test/container.spec.js.map +0 -1
  232. package/lib/test/deltaManager.spec.js +0 -405
  233. package/lib/test/deltaManager.spec.js.map +0 -1
  234. package/lib/test/loader.spec.js +0 -212
  235. package/lib/test/loader.spec.js.map +0 -1
  236. package/lib/test/locationRedirectionTests.spec.js +0 -44
  237. package/lib/test/locationRedirectionTests.spec.js.map +0 -1
  238. package/lib/test/serializedStateManager.spec.js +0 -148
  239. package/lib/test/serializedStateManager.spec.js.map +0 -1
  240. package/lib/test/snapshotConversionTest.spec.js +0 -79
  241. package/lib/test/snapshotConversionTest.spec.js.map +0 -1
  242. package/lib/test/types/validateContainerLoaderPrevious.generated.js +0 -38
  243. package/lib/test/types/validateContainerLoaderPrevious.generated.js.map +0 -1
  244. package/lib/test/utils.spec.js +0 -31
  245. package/lib/test/utils.spec.js.map +0 -1
  246. /package/{dist → lib}/tsdoc-metadata.json +0 -0
package/lib/utils.js CHANGED
@@ -2,13 +2,13 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import { v4 as uuid } from "uuid";
6
- import { Uint8ArrayToString, stringToBuffer } from "@fluid-internal/client-utils";
7
- import { assert, compareArrays, unreachableCase } from "@fluidframework/core-utils";
8
- import { SummaryType } from "@fluidframework/protocol-definitions";
9
- import { LoggingError, UsageError } from "@fluidframework/telemetry-utils";
10
- import { isCombinedAppAndProtocolSummary, } from "@fluidframework/driver-utils";
5
+ import { Uint8ArrayToString, bufferToString, stringToBuffer } from "@fluid-internal/client-utils";
6
+ import { assert, compareArrays, unreachableCase } from "@fluidframework/core-utils/internal";
11
7
  import { DriverErrorTypes } from "@fluidframework/driver-definitions";
8
+ import { isCombinedAppAndProtocolSummary, readAndParse, } from "@fluidframework/driver-utils/internal";
9
+ import { SummaryType, } from "@fluidframework/protocol-definitions";
10
+ import { LoggingError, UsageError } from "@fluidframework/telemetry-utils/internal";
11
+ import { v4 as uuid } from "uuid";
12
12
  /**
13
13
  * Utility api to parse the IResolvedUrl.url into specific parts like querystring, path to get
14
14
  * deep link info etc.
@@ -16,7 +16,7 @@ import { DriverErrorTypes } from "@fluidframework/driver-definitions";
16
16
  * with urls of type: protocol://<string>/.../..?<querystring>
17
17
  * @param url - This is the IResolvedUrl.url part of the resolved url.
18
18
  * @returns The IParsedUrl representing the input URL, or undefined if the format was not supported
19
- * @internal
19
+ * @alpha
20
20
  */
21
21
  export function tryParseCompatibleResolvedUrl(url) {
22
22
  const parsed = new URL(url);
@@ -73,9 +73,9 @@ function convertSummaryToSnapshotAndBlobs(summary) {
73
73
  const summaryObject = summary.tree[key];
74
74
  switch (summaryObject.type) {
75
75
  case SummaryType.Tree: {
76
- const { tree, blobs } = convertSummaryToSnapshotAndBlobs(summaryObject);
77
- treeNode.trees[key] = tree;
78
- blobContents = { ...blobContents, ...blobs };
76
+ const innerSnapshot = convertSummaryToSnapshotAndBlobs(summaryObject);
77
+ treeNode.trees[key] = innerSnapshot.baseSnapshot;
78
+ blobContents = { ...blobContents, ...innerSnapshot.snapshotBlobs };
79
79
  break;
80
80
  }
81
81
  case SummaryType.Attachment:
@@ -92,13 +92,53 @@ function convertSummaryToSnapshotAndBlobs(summary) {
92
92
  }
93
93
  case SummaryType.Handle:
94
94
  throw new LoggingError("No handles should be there in summary in detached container!!");
95
- break;
96
95
  default: {
97
96
  unreachableCase(summaryObject, `Unknown tree type ${summaryObject.type}`);
98
97
  }
99
98
  }
100
99
  }
101
- return { tree: treeNode, blobs: blobContents };
100
+ const pendingSnapshot = { baseSnapshot: treeNode, snapshotBlobs: blobContents };
101
+ return pendingSnapshot;
102
+ }
103
+ /**
104
+ * Converts a snapshot to snapshotInfo with its blob contents
105
+ * to align detached container format with IPendingContainerState
106
+ *
107
+ * Note, this assumes the ISnapshot sequence number is defined. Otherwise an assert will be thrown
108
+ * @param snapshot - ISnapshot
109
+ */
110
+ export function convertSnapshotToSnapshotInfo(snapshot) {
111
+ assert(snapshot.sequenceNumber !== undefined, 0x93a /* Snapshot sequence number is missing */);
112
+ const snapshotBlobs = {};
113
+ for (const [blobId, arrayBufferLike] of snapshot.blobContents.entries()) {
114
+ snapshotBlobs[blobId] = bufferToString(arrayBufferLike, "utf8");
115
+ }
116
+ return {
117
+ baseSnapshot: snapshot.snapshotTree,
118
+ snapshotBlobs,
119
+ snapshotSequenceNumber: snapshot.sequenceNumber,
120
+ };
121
+ }
122
+ /**
123
+ * Converts a snapshot to snapshotInfo with its blob contents
124
+ * to align detached container format with IPendingContainerState
125
+ *
126
+ * Note, this assumes the ISnapshot sequence number is defined. Otherwise an assert will be thrown
127
+ * @param snapshot - ISnapshot
128
+ */
129
+ export function convertSnapshotInfoToSnapshot(snapshotInfo, snapshotSequenceNumber) {
130
+ const blobContents = new Map();
131
+ for (const [blobId, serializedContent] of Object.entries(snapshotInfo.snapshotBlobs)) {
132
+ blobContents.set(blobId, stringToBuffer(serializedContent, "utf8"));
133
+ }
134
+ return {
135
+ snapshotTree: snapshotInfo.baseSnapshot,
136
+ blobContents,
137
+ ops: [],
138
+ sequenceNumber: snapshotSequenceNumber,
139
+ latestSequenceNumber: undefined,
140
+ snapshotFormatV: 1,
141
+ };
102
142
  }
103
143
  /**
104
144
  * Converts summary parts into a SnapshotTree and its blob contents.
@@ -170,11 +210,11 @@ export function getDetachedContainerStateFromSerializedContainer(serializedConta
170
210
  return parsedContainerState;
171
211
  }
172
212
  else if (isCombinedAppAndProtocolSummary(parsedContainerState)) {
173
- const { tree, blobs } = getSnapshotTreeAndBlobsFromSerializedContainer(parsedContainerState);
213
+ const { baseSnapshot, snapshotBlobs } = getSnapshotTreeAndBlobsFromSerializedContainer(parsedContainerState);
174
214
  const detachedContainerState = {
175
215
  attached: false,
176
- baseSnapshot: tree,
177
- snapshotBlobs: blobs,
216
+ baseSnapshot,
217
+ snapshotBlobs,
178
218
  hasAttachmentBlobs: parsedContainerState.tree[hasBlobsSummaryTree] !== undefined,
179
219
  };
180
220
  return detachedContainerState;
@@ -203,4 +243,18 @@ export const runSingle = (func) => {
203
243
  return running.result;
204
244
  };
205
245
  };
246
+ export async function getDocumentAttributes(storage, tree) {
247
+ if (tree === undefined) {
248
+ return {
249
+ minimumSequenceNumber: 0,
250
+ sequenceNumber: 0,
251
+ };
252
+ }
253
+ // Backward compatibility: old docs would have ".attributes" instead of "attributes"
254
+ const attributesHash = ".protocol" in tree.trees
255
+ ? tree.trees[".protocol"].blobs.attributes
256
+ : tree.blobs[".attributes"];
257
+ const attributes = await readAndParse(storage, attributesHash);
258
+ return attributes;
259
+ }
206
260
  //# sourceMappingURL=utils.js.map
package/lib/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.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 { Uint8ArrayToString, stringToBuffer } from \"@fluid-internal/client-utils\";\nimport { assert, compareArrays, unreachableCase } from \"@fluidframework/core-utils\";\nimport { ISummaryTree, ISnapshotTree, SummaryType } from \"@fluidframework/protocol-definitions\";\nimport { LoggingError, UsageError } from \"@fluidframework/telemetry-utils\";\nimport {\n\tCombinedAppAndProtocolSummary,\n\tDeltaStreamConnectionForbiddenError,\n\tisCombinedAppAndProtocolSummary,\n} from \"@fluidframework/driver-utils\";\nimport { DriverErrorTypes } from \"@fluidframework/driver-definitions\";\nimport { ISerializableBlobContents } from \"./containerStorageAdapter.js\";\nimport { IPendingDetachedContainerState } from \"./container.js\";\n\n// This is used when we rehydrate a container from the snapshot. Here we put the blob contents\n// in separate property: blobContents.\nexport interface ISnapshotTreeWithBlobContents extends ISnapshotTree {\n\tblobsContents: { [path: string]: ArrayBufferLike };\n\ttrees: { [path: string]: ISnapshotTreeWithBlobContents };\n}\n\n/**\n * Interface to represent the parsed parts of IResolvedUrl.url to help\n * in getting info about different parts of the url.\n * May not be compatible or relevant for any Url Resolver\n * @internal\n */\nexport interface IParsedUrl {\n\t/**\n\t * It is combination of tenantid/docId part of the url.\n\t */\n\tid: string;\n\t/**\n\t * It is the deep link path in the url.\n\t */\n\tpath: string;\n\t/**\n\t * Query string part of the url.\n\t */\n\tquery: string;\n\t/**\n\t * Undefined means load latest snapshot, otherwise it's version ID passed to IDocumentStorageService.getVersions()\n\t * to figure out what snapshot to use.\n\t */\n\tversion: string | undefined;\n}\n\n/**\n * Utility api to parse the IResolvedUrl.url into specific parts like querystring, path to get\n * deep link info etc.\n * Warning - This function may not be compatible with any Url Resolver's resolved url. It works\n * with urls of type: protocol://<string>/.../..?<querystring>\n * @param url - This is the IResolvedUrl.url part of the resolved url.\n * @returns The IParsedUrl representing the input URL, or undefined if the format was not supported\n * @internal\n */\nexport function tryParseCompatibleResolvedUrl(url: string): IParsedUrl | undefined {\n\tconst parsed = new URL(url);\n\tif (typeof parsed.pathname !== \"string\") {\n\t\tthrow new LoggingError(\"Failed to parse pathname\");\n\t}\n\tconst query = parsed.search ?? \"\";\n\tconst regex = /^\\/([^/]*\\/[^/]*)(\\/?.*)$/;\n\tconst match = regex.exec(parsed.pathname);\n\treturn match?.length === 3\n\t\t? {\n\t\t\t\tid: match[1],\n\t\t\t\tpath: match[2],\n\t\t\t\tquery,\n\t\t\t\t// URLSearchParams returns null if the param is not provided.\n\t\t\t\tversion: parsed.searchParams.get(\"version\") ?? undefined,\n\t\t }\n\t\t: undefined;\n}\n\n/**\n * Combine the app summary and protocol summary in 1 tree.\n * @param appSummary - Summary of the app.\n * @param protocolSummary - Summary of the protocol.\n * @internal\n */\nexport function combineAppAndProtocolSummary(\n\tappSummary: ISummaryTree,\n\tprotocolSummary: ISummaryTree,\n): CombinedAppAndProtocolSummary {\n\tassert(\n\t\t!isCombinedAppAndProtocolSummary(appSummary),\n\t\t0x5a8 /* app summary is already a combined tree! */,\n\t);\n\tassert(\n\t\t!isCombinedAppAndProtocolSummary(protocolSummary),\n\t\t0x5a9 /* protocol summary is already a combined tree! */,\n\t);\n\tconst createNewSummary: CombinedAppAndProtocolSummary = {\n\t\ttype: SummaryType.Tree,\n\t\ttree: {\n\t\t\t\".protocol\": protocolSummary,\n\t\t\t\".app\": appSummary,\n\t\t},\n\t};\n\treturn createNewSummary;\n}\n\n/**\n * Converts a summary to snapshot tree and separate its blob contents\n * to align detached container format with IPendingContainerState\n * @param summary - ISummaryTree\n */\nfunction convertSummaryToSnapshotAndBlobs(summary: ISummaryTree): {\n\ttree: ISnapshotTree;\n\tblobs: ISerializableBlobContents;\n} {\n\tlet blobContents: ISerializableBlobContents = {};\n\tconst treeNode: ISnapshotTree = {\n\t\tblobs: {},\n\t\ttrees: {},\n\t\tid: uuid(),\n\t\tunreferenced: summary.unreferenced,\n\t\tgroupId: summary.groupId,\n\t};\n\tconst keys = Object.keys(summary.tree);\n\tfor (const key of keys) {\n\t\tconst summaryObject = summary.tree[key];\n\n\t\tswitch (summaryObject.type) {\n\t\t\tcase SummaryType.Tree: {\n\t\t\t\tconst { tree, blobs } = convertSummaryToSnapshotAndBlobs(summaryObject);\n\t\t\t\ttreeNode.trees[key] = tree;\n\t\t\t\tblobContents = { ...blobContents, ...blobs };\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SummaryType.Attachment:\n\t\t\t\ttreeNode.blobs[key] = summaryObject.id;\n\t\t\t\tbreak;\n\t\t\tcase SummaryType.Blob: {\n\t\t\t\tconst blobId = uuid();\n\t\t\t\ttreeNode.blobs[key] = blobId;\n\t\t\t\tconst contentString: string =\n\t\t\t\t\tsummaryObject.content instanceof Uint8Array\n\t\t\t\t\t\t? Uint8ArrayToString(summaryObject.content)\n\t\t\t\t\t\t: summaryObject.content;\n\t\t\t\tblobContents[blobId] = contentString;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SummaryType.Handle:\n\t\t\t\tthrow new LoggingError(\n\t\t\t\t\t\"No handles should be there in summary in detached container!!\",\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tdefault: {\n\t\t\t\tunreachableCase(summaryObject, `Unknown tree type ${(summaryObject as any).type}`);\n\t\t\t}\n\t\t}\n\t}\n\treturn { tree: treeNode, blobs: blobContents };\n}\n\n/**\n * Converts summary parts into a SnapshotTree and its blob contents.\n * @param protocolSummaryTree - Protocol Summary Tree\n * @param appSummaryTree - App Summary Tree\n */\nfunction convertProtocolAndAppSummaryToSnapshotAndBlobs(\n\tprotocolSummaryTree: ISummaryTree,\n\tappSummaryTree: ISummaryTree,\n): { tree: ISnapshotTree; blobs: ISerializableBlobContents } {\n\tconst combinedSummary: ISummaryTree = {\n\t\ttype: SummaryType.Tree,\n\t\ttree: { ...appSummaryTree.tree },\n\t};\n\n\tcombinedSummary.tree[\".protocol\"] = protocolSummaryTree;\n\tconst snapshotTreeWithBlobContents = convertSummaryToSnapshotAndBlobs(combinedSummary);\n\treturn snapshotTreeWithBlobContents;\n}\n\nexport const getSnapshotTreeAndBlobsFromSerializedContainer = (\n\tdetachedContainerSnapshot: ISummaryTree,\n): { tree: ISnapshotTree; blobs: ISerializableBlobContents } => {\n\tassert(\n\t\tisCombinedAppAndProtocolSummary(detachedContainerSnapshot),\n\t\t0x8e6 /* Protocol and App summary trees should be present */,\n\t);\n\tconst protocolSummaryTree = detachedContainerSnapshot.tree[\".protocol\"];\n\tconst appSummaryTree = detachedContainerSnapshot.tree[\".app\"];\n\tconst snapshotTreeWithBlobContents = convertProtocolAndAppSummaryToSnapshotAndBlobs(\n\t\tprotocolSummaryTree,\n\t\tappSummaryTree,\n\t);\n\treturn snapshotTreeWithBlobContents;\n};\n\nexport function getProtocolSnapshotTree(snapshot: ISnapshotTree): ISnapshotTree {\n\treturn \".protocol\" in snapshot.trees ? snapshot.trees[\".protocol\"] : snapshot;\n}\n\nexport const combineSnapshotTreeAndSnapshotBlobs = (\n\tbaseSnapshot: ISnapshotTree,\n\tsnapshotBlobs: ISerializableBlobContents,\n): ISnapshotTreeWithBlobContents => {\n\tconst blobsContents: { [path: string]: ArrayBufferLike } = {};\n\n\t// Process blobs in the current level\n\tfor (const [, id] of Object.entries(baseSnapshot.blobs)) {\n\t\tif (snapshotBlobs[id]) {\n\t\t\tblobsContents[id] = stringToBuffer(snapshotBlobs[id], \"utf8\");\n\t\t}\n\t}\n\n\t// Recursively process trees in the current level\n\tconst trees: { [path: string]: ISnapshotTreeWithBlobContents } = {};\n\tfor (const [path, tree] of Object.entries(baseSnapshot.trees)) {\n\t\ttrees[path] = combineSnapshotTreeAndSnapshotBlobs(tree, snapshotBlobs);\n\t}\n\n\t// Create a new snapshot tree with blob contents and processed trees\n\tconst snapshotTreeWithBlobContents: ISnapshotTreeWithBlobContents = {\n\t\t...baseSnapshot,\n\t\tblobsContents,\n\t\ttrees,\n\t};\n\n\treturn snapshotTreeWithBlobContents;\n};\n\nexport function isDeltaStreamConnectionForbiddenError(\n\terror: any,\n): error is DeltaStreamConnectionForbiddenError {\n\treturn (\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\terror?.errorType === DriverErrorTypes.deltaStreamConnectionForbidden\n\t);\n}\n\n/**\n * Validates format in parsed string get from detached container\n * serialization using IPendingDetachedContainerState format.\n */\nfunction isPendingDetachedContainerState(\n\tdetachedContainerState: IPendingDetachedContainerState,\n): detachedContainerState is IPendingDetachedContainerState {\n\tif (\n\t\tdetachedContainerState?.attached === undefined ||\n\t\tdetachedContainerState?.baseSnapshot === undefined ||\n\t\tdetachedContainerState?.snapshotBlobs === undefined ||\n\t\tdetachedContainerState?.hasAttachmentBlobs === undefined\n\t) {\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nexport function getDetachedContainerStateFromSerializedContainer(\n\tserializedContainer: string,\n): IPendingDetachedContainerState {\n\tconst hasBlobsSummaryTree = \".hasAttachmentBlobs\";\n\tconst parsedContainerState = JSON.parse(serializedContainer);\n\tif (isPendingDetachedContainerState(parsedContainerState)) {\n\t\treturn parsedContainerState;\n\t} else if (isCombinedAppAndProtocolSummary(parsedContainerState)) {\n\t\tconst { tree, blobs } =\n\t\t\tgetSnapshotTreeAndBlobsFromSerializedContainer(parsedContainerState);\n\t\tconst detachedContainerState: IPendingDetachedContainerState = {\n\t\t\tattached: false,\n\t\t\tbaseSnapshot: tree,\n\t\t\tsnapshotBlobs: blobs,\n\t\t\thasAttachmentBlobs: parsedContainerState.tree[hasBlobsSummaryTree] !== undefined,\n\t\t};\n\t\treturn detachedContainerState;\n\t} else {\n\t\tthrow new UsageError(\"Cannot rehydrate detached container. Incorrect format\");\n\t}\n}\n\n/**\n * Ensures only a single instance of the provided async function is running.\n * If there are multiple calls they will all get the same promise to wait on.\n */\nexport const runSingle = <A extends any[], R>(func: (...args: A) => Promise<R>) => {\n\tlet running:\n\t\t| {\n\t\t\t\targs: A;\n\t\t\t\tresult: Promise<R>;\n\t\t }\n\t\t| undefined;\n\t// don't mark this function async, so we return the same promise,\n\t// rather than one that is wrapped due to async\n\t// eslint-disable-next-line @typescript-eslint/promise-function-async\n\treturn (...args: A) => {\n\t\tif (running !== undefined) {\n\t\t\tif (!compareArrays(running.args, args)) {\n\t\t\t\treturn Promise.reject(\n\t\t\t\t\tnew UsageError(\"Subsequent calls cannot use different arguments.\"),\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn running.result;\n\t\t}\n\t\trunning = { args, result: func(...args).finally(() => (running = undefined)) };\n\t\treturn running.result;\n\t};\n};\n"]}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAClG,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAC7F,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAKtE,OAAO,EAGN,+BAA+B,EAC/B,YAAY,GACZ,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAIN,WAAW,GACX,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AACpF,OAAO,EAAE,EAAE,IAAI,IAAI,EAAE,MAAM,MAAM,CAAC;AA0ClC;;;;;;;;GAQG;AACH,MAAM,UAAU,6BAA6B,CAAC,GAAW;IACxD,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IAC5B,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE;QACxC,MAAM,IAAI,YAAY,CAAC,0BAA0B,CAAC,CAAC;KACnD;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;IAClC,MAAM,KAAK,GAAG,2BAA2B,CAAC;IAC1C,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC1C,OAAO,KAAK,EAAE,MAAM,KAAK,CAAC;QACzB,CAAC,CAAC;YACA,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;YACZ,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;YACd,KAAK;YACL,6DAA6D;YAC7D,OAAO,EAAE,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,SAAS;SACvD;QACH,CAAC,CAAC,SAAS,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,4BAA4B,CAC3C,UAAwB,EACxB,eAA6B;IAE7B,MAAM,CACL,CAAC,+BAA+B,CAAC,UAAU,CAAC,EAC5C,KAAK,CAAC,6CAA6C,CACnD,CAAC;IACF,MAAM,CACL,CAAC,+BAA+B,CAAC,eAAe,CAAC,EACjD,KAAK,CAAC,kDAAkD,CACxD,CAAC;IACF,MAAM,gBAAgB,GAAkC;QACvD,IAAI,EAAE,WAAW,CAAC,IAAI;QACtB,IAAI,EAAE;YACL,WAAW,EAAE,eAAe;YAC5B,MAAM,EAAE,UAAU;SAClB;KACD,CAAC;IACF,OAAO,gBAAgB,CAAC;AACzB,CAAC;AAED;;;;GAIG;AACH,SAAS,gCAAgC,CAAC,OAAqB;IAC9D,IAAI,YAAY,GAA8B,EAAE,CAAC;IACjD,MAAM,QAAQ,GAAkB;QAC/B,KAAK,EAAE,EAAE;QACT,KAAK,EAAE,EAAE;QACT,EAAE,EAAE,IAAI,EAAE;QACV,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,OAAO,EAAE,OAAO,CAAC,OAAO;KACxB,CAAC;IACF,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE;QACvB,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAExC,QAAQ,aAAa,CAAC,IAAI,EAAE;YAC3B,KAAK,WAAW,CAAC,IAAI,CAAC,CAAC;gBACtB,MAAM,aAAa,GAAG,gCAAgC,CAAC,aAAa,CAAC,CAAC;gBACtE,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC,YAAY,CAAC;gBACjD,YAAY,GAAG,EAAE,GAAG,YAAY,EAAE,GAAG,aAAa,CAAC,aAAa,EAAE,CAAC;gBACnE,MAAM;aACN;YACD,KAAK,WAAW,CAAC,UAAU;gBAC1B,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC,EAAE,CAAC;gBACvC,MAAM;YACP,KAAK,WAAW,CAAC,IAAI,CAAC,CAAC;gBACtB,MAAM,MAAM,GAAG,IAAI,EAAE,CAAC;gBACtB,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;gBAC7B,MAAM,aAAa,GAClB,aAAa,CAAC,OAAO,YAAY,UAAU;oBAC1C,CAAC,CAAC,kBAAkB,CAAC,aAAa,CAAC,OAAO,CAAC;oBAC3C,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC;gBAC1B,YAAY,CAAC,MAAM,CAAC,GAAG,aAAa,CAAC;gBACrC,MAAM;aACN;YACD,KAAK,WAAW,CAAC,MAAM;gBACtB,MAAM,IAAI,YAAY,CACrB,+DAA+D,CAC/D,CAAC;YACH,OAAO,CAAC,CAAC;gBACR,eAAe,CAAC,aAAa,EAAE,qBAAsB,aAAqB,CAAC,IAAI,EAAE,CAAC,CAAC;aACnF;SACD;KACD;IACD,MAAM,eAAe,GAAG,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,YAAY,EAAE,CAAC;IAChF,OAAO,eAAe,CAAC;AACxB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,6BAA6B,CAAC,QAAmB;IAChE,MAAM,CAAC,QAAQ,CAAC,cAAc,KAAK,SAAS,EAAE,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC/F,MAAM,aAAa,GAA8B,EAAE,CAAC;IACpD,KAAK,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,IAAI,QAAQ,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE;QACxE,aAAa,CAAC,MAAM,CAAC,GAAG,cAAc,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;KAChE;IACD,OAAO;QACN,YAAY,EAAE,QAAQ,CAAC,YAAY;QACnC,aAAa;QACb,sBAAsB,EAAE,QAAQ,CAAC,cAAc;KAC/C,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,6BAA6B,CAC5C,YAA2B,EAC3B,sBAA8B;IAE9B,MAAM,YAAY,GAAG,IAAI,GAAG,EAA2B,CAAC;IACxD,KAAK,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,aAAa,CAAC,EAAE;QACrF,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC,CAAC;KACpE;IACD,OAAO;QACN,YAAY,EAAE,YAAY,CAAC,YAAY;QACvC,YAAY;QACZ,GAAG,EAAE,EAAE;QACP,cAAc,EAAE,sBAAsB;QACtC,oBAAoB,EAAE,SAAS;QAC/B,eAAe,EAAE,CAAC;KAClB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,8CAA8C,CACtD,mBAAiC,EACjC,cAA4B;IAE5B,MAAM,eAAe,GAAiB;QACrC,IAAI,EAAE,WAAW,CAAC,IAAI;QACtB,IAAI,EAAE,EAAE,GAAG,cAAc,CAAC,IAAI,EAAE;KAChC,CAAC;IAEF,eAAe,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,mBAAmB,CAAC;IACxD,MAAM,4BAA4B,GAAG,gCAAgC,CAAC,eAAe,CAAC,CAAC;IACvF,OAAO,4BAA4B,CAAC;AACrC,CAAC;AAED,MAAM,CAAC,MAAM,8CAA8C,GAAG,CAC7D,yBAAuC,EACnB,EAAE;IACtB,MAAM,CACL,+BAA+B,CAAC,yBAAyB,CAAC,EAC1D,KAAK,CAAC,sDAAsD,CAC5D,CAAC;IACF,MAAM,mBAAmB,GAAG,yBAAyB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACxE,MAAM,cAAc,GAAG,yBAAyB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC9D,MAAM,4BAA4B,GAAG,8CAA8C,CAClF,mBAAmB,EACnB,cAAc,CACd,CAAC;IACF,OAAO,4BAA4B,CAAC;AACrC,CAAC,CAAC;AAEF,MAAM,UAAU,uBAAuB,CAAC,QAAuB;IAC9D,OAAO,WAAW,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC/E,CAAC;AAED,MAAM,CAAC,MAAM,mCAAmC,GAAG,CAClD,YAA2B,EAC3B,aAAwC,EACR,EAAE;IAClC,MAAM,aAAa,GAAwC,EAAE,CAAC;IAE9D,qCAAqC;IACrC,KAAK,MAAM,CAAC,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE;QACxD,IAAI,aAAa,CAAC,EAAE,CAAC,EAAE;YACtB,aAAa,CAAC,EAAE,CAAC,GAAG,cAAc,CAAC,aAAa,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;SAC9D;KACD;IAED,iDAAiD;IACjD,MAAM,KAAK,GAAsD,EAAE,CAAC;IACpE,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE;QAC9D,KAAK,CAAC,IAAI,CAAC,GAAG,mCAAmC,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;KACvE;IAED,oEAAoE;IACpE,MAAM,4BAA4B,GAAkC;QACnE,GAAG,YAAY;QACf,aAAa;QACb,KAAK;KACL,CAAC;IAEF,OAAO,4BAA4B,CAAC;AACrC,CAAC,CAAC;AAEF,MAAM,UAAU,qCAAqC,CACpD,KAAU;IAEV,OAAO,CACN,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,KAAK,EAAE,SAAS,KAAK,gBAAgB,CAAC,8BAA8B,CACpE,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,+BAA+B,CACvC,sBAAsD;IAEtD,IACC,sBAAsB,EAAE,QAAQ,KAAK,SAAS;QAC9C,sBAAsB,EAAE,YAAY,KAAK,SAAS;QAClD,sBAAsB,EAAE,aAAa,KAAK,SAAS;QACnD,sBAAsB,EAAE,kBAAkB,KAAK,SAAS,EACvD;QACD,OAAO,KAAK,CAAC;KACb;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,MAAM,UAAU,gDAAgD,CAC/D,mBAA2B;IAE3B,MAAM,mBAAmB,GAAG,qBAAqB,CAAC;IAClD,MAAM,oBAAoB,GAAG,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;IAC7D,IAAI,+BAA+B,CAAC,oBAAoB,CAAC,EAAE;QAC1D,OAAO,oBAAoB,CAAC;KAC5B;SAAM,IAAI,+BAA+B,CAAC,oBAAoB,CAAC,EAAE;QACjE,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,GACpC,8CAA8C,CAAC,oBAAoB,CAAC,CAAC;QACtE,MAAM,sBAAsB,GAAmC;YAC9D,QAAQ,EAAE,KAAK;YACf,YAAY;YACZ,aAAa;YACb,kBAAkB,EAAE,oBAAoB,CAAC,IAAI,CAAC,mBAAmB,CAAC,KAAK,SAAS;SAChF,CAAC;QACF,OAAO,sBAAsB,CAAC;KAC9B;SAAM;QACN,MAAM,IAAI,UAAU,CAAC,uDAAuD,CAAC,CAAC;KAC9E;AACF,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAqB,IAAgC,EAAE,EAAE;IACjF,IAAI,OAKQ,CAAC;IACb,iEAAiE;IACjE,+CAA+C;IAC/C,qEAAqE;IACrE,OAAO,CAAC,GAAG,IAAO,EAAE,EAAE;QACrB,IAAI,OAAO,KAAK,SAAS,EAAE;YAC1B,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE;gBACvC,OAAO,OAAO,CAAC,MAAM,CACpB,IAAI,UAAU,CAAC,kDAAkD,CAAC,CAClE,CAAC;aACF;YACD,OAAO,OAAO,CAAC,MAAM,CAAC;SACtB;QACD,OAAO,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC,EAAE,CAAC;QAC/E,OAAO,OAAO,CAAC,MAAM,CAAC;IACvB,CAAC,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAC1C,OAAkD,EAClD,IAA+B;IAE/B,IAAI,IAAI,KAAK,SAAS,EAAE;QACvB,OAAO;YACN,qBAAqB,EAAE,CAAC;YACxB,cAAc,EAAE,CAAC;SACjB,CAAC;KACF;IAED,oFAAoF;IACpF,MAAM,cAAc,GACnB,WAAW,IAAI,IAAI,CAAC,KAAK;QACxB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,UAAU;QAC1C,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IAE9B,MAAM,UAAU,GAAG,MAAM,YAAY,CAAsB,OAAO,EAAE,cAAc,CAAC,CAAC;IAEpF,OAAO,UAAU,CAAC;AACnB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { Uint8ArrayToString, bufferToString, stringToBuffer } from \"@fluid-internal/client-utils\";\nimport { assert, compareArrays, unreachableCase } from \"@fluidframework/core-utils/internal\";\nimport { DriverErrorTypes } from \"@fluidframework/driver-definitions\";\nimport {\n\tIDocumentStorageService,\n\ttype ISnapshot,\n} from \"@fluidframework/driver-definitions/internal\";\nimport {\n\tCombinedAppAndProtocolSummary,\n\tDeltaStreamConnectionForbiddenError,\n\tisCombinedAppAndProtocolSummary,\n\treadAndParse,\n} from \"@fluidframework/driver-utils/internal\";\nimport {\n\tIDocumentAttributes,\n\tISnapshotTree,\n\tISummaryTree,\n\tSummaryType,\n} from \"@fluidframework/protocol-definitions\";\nimport { LoggingError, UsageError } from \"@fluidframework/telemetry-utils/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport { ISerializableBlobContents } from \"./containerStorageAdapter.js\";\nimport type {\n\tIPendingDetachedContainerState,\n\tISnapshotInfo,\n\tSnapshotWithBlobs,\n} from \"./serializedStateManager.js\";\n\n// This is used when we rehydrate a container from the snapshot. Here we put the blob contents\n// in separate property: blobContents.\nexport interface ISnapshotTreeWithBlobContents extends ISnapshotTree {\n\tblobsContents: { [path: string]: ArrayBufferLike };\n\ttrees: { [path: string]: ISnapshotTreeWithBlobContents };\n}\n\n/**\n * Interface to represent the parsed parts of IResolvedUrl.url to help\n * in getting info about different parts of the url.\n * May not be compatible or relevant for any Url Resolver\n * @alpha\n */\nexport interface IParsedUrl {\n\t/**\n\t * It is combination of tenantid/docId part of the url.\n\t */\n\tid: string;\n\t/**\n\t * It is the deep link path in the url.\n\t */\n\tpath: string;\n\t/**\n\t * Query string part of the url.\n\t */\n\tquery: string;\n\t/**\n\t * Undefined means load latest snapshot, otherwise it's version ID passed to IDocumentStorageService.getVersions()\n\t * to figure out what snapshot to use.\n\t */\n\tversion: string | undefined;\n}\n\n/**\n * Utility api to parse the IResolvedUrl.url into specific parts like querystring, path to get\n * deep link info etc.\n * Warning - This function may not be compatible with any Url Resolver's resolved url. It works\n * with urls of type: protocol://<string>/.../..?<querystring>\n * @param url - This is the IResolvedUrl.url part of the resolved url.\n * @returns The IParsedUrl representing the input URL, or undefined if the format was not supported\n * @alpha\n */\nexport function tryParseCompatibleResolvedUrl(url: string): IParsedUrl | undefined {\n\tconst parsed = new URL(url);\n\tif (typeof parsed.pathname !== \"string\") {\n\t\tthrow new LoggingError(\"Failed to parse pathname\");\n\t}\n\tconst query = parsed.search ?? \"\";\n\tconst regex = /^\\/([^/]*\\/[^/]*)(\\/?.*)$/;\n\tconst match = regex.exec(parsed.pathname);\n\treturn match?.length === 3\n\t\t? {\n\t\t\t\tid: match[1],\n\t\t\t\tpath: match[2],\n\t\t\t\tquery,\n\t\t\t\t// URLSearchParams returns null if the param is not provided.\n\t\t\t\tversion: parsed.searchParams.get(\"version\") ?? undefined,\n\t\t }\n\t\t: undefined;\n}\n\n/**\n * Combine the app summary and protocol summary in 1 tree.\n * @param appSummary - Summary of the app.\n * @param protocolSummary - Summary of the protocol.\n * @internal\n */\nexport function combineAppAndProtocolSummary(\n\tappSummary: ISummaryTree,\n\tprotocolSummary: ISummaryTree,\n): CombinedAppAndProtocolSummary {\n\tassert(\n\t\t!isCombinedAppAndProtocolSummary(appSummary),\n\t\t0x5a8 /* app summary is already a combined tree! */,\n\t);\n\tassert(\n\t\t!isCombinedAppAndProtocolSummary(protocolSummary),\n\t\t0x5a9 /* protocol summary is already a combined tree! */,\n\t);\n\tconst createNewSummary: CombinedAppAndProtocolSummary = {\n\t\ttype: SummaryType.Tree,\n\t\ttree: {\n\t\t\t\".protocol\": protocolSummary,\n\t\t\t\".app\": appSummary,\n\t\t},\n\t};\n\treturn createNewSummary;\n}\n\n/**\n * Converts a summary to snapshot tree and separate its blob contents\n * to align detached container format with IPendingContainerState\n * @param summary - ISummaryTree\n */\nfunction convertSummaryToSnapshotAndBlobs(summary: ISummaryTree): SnapshotWithBlobs {\n\tlet blobContents: ISerializableBlobContents = {};\n\tconst treeNode: ISnapshotTree = {\n\t\tblobs: {},\n\t\ttrees: {},\n\t\tid: uuid(),\n\t\tunreferenced: summary.unreferenced,\n\t\tgroupId: summary.groupId,\n\t};\n\tconst keys = Object.keys(summary.tree);\n\tfor (const key of keys) {\n\t\tconst summaryObject = summary.tree[key];\n\n\t\tswitch (summaryObject.type) {\n\t\t\tcase SummaryType.Tree: {\n\t\t\t\tconst innerSnapshot = convertSummaryToSnapshotAndBlobs(summaryObject);\n\t\t\t\ttreeNode.trees[key] = innerSnapshot.baseSnapshot;\n\t\t\t\tblobContents = { ...blobContents, ...innerSnapshot.snapshotBlobs };\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SummaryType.Attachment:\n\t\t\t\ttreeNode.blobs[key] = summaryObject.id;\n\t\t\t\tbreak;\n\t\t\tcase SummaryType.Blob: {\n\t\t\t\tconst blobId = uuid();\n\t\t\t\ttreeNode.blobs[key] = blobId;\n\t\t\t\tconst contentString: string =\n\t\t\t\t\tsummaryObject.content instanceof Uint8Array\n\t\t\t\t\t\t? Uint8ArrayToString(summaryObject.content)\n\t\t\t\t\t\t: summaryObject.content;\n\t\t\t\tblobContents[blobId] = contentString;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SummaryType.Handle:\n\t\t\t\tthrow new LoggingError(\n\t\t\t\t\t\"No handles should be there in summary in detached container!!\",\n\t\t\t\t);\n\t\t\tdefault: {\n\t\t\t\tunreachableCase(summaryObject, `Unknown tree type ${(summaryObject as any).type}`);\n\t\t\t}\n\t\t}\n\t}\n\tconst pendingSnapshot = { baseSnapshot: treeNode, snapshotBlobs: blobContents };\n\treturn pendingSnapshot;\n}\n\n/**\n * Converts a snapshot to snapshotInfo with its blob contents\n * to align detached container format with IPendingContainerState\n *\n * Note, this assumes the ISnapshot sequence number is defined. Otherwise an assert will be thrown\n * @param snapshot - ISnapshot\n */\nexport function convertSnapshotToSnapshotInfo(snapshot: ISnapshot): ISnapshotInfo {\n\tassert(snapshot.sequenceNumber !== undefined, 0x93a /* Snapshot sequence number is missing */);\n\tconst snapshotBlobs: ISerializableBlobContents = {};\n\tfor (const [blobId, arrayBufferLike] of snapshot.blobContents.entries()) {\n\t\tsnapshotBlobs[blobId] = bufferToString(arrayBufferLike, \"utf8\");\n\t}\n\treturn {\n\t\tbaseSnapshot: snapshot.snapshotTree,\n\t\tsnapshotBlobs,\n\t\tsnapshotSequenceNumber: snapshot.sequenceNumber,\n\t};\n}\n\n/**\n * Converts a snapshot to snapshotInfo with its blob contents\n * to align detached container format with IPendingContainerState\n *\n * Note, this assumes the ISnapshot sequence number is defined. Otherwise an assert will be thrown\n * @param snapshot - ISnapshot\n */\nexport function convertSnapshotInfoToSnapshot(\n\tsnapshotInfo: ISnapshotInfo,\n\tsnapshotSequenceNumber: number,\n): ISnapshot {\n\tconst blobContents = new Map<string, ArrayBufferLike>();\n\tfor (const [blobId, serializedContent] of Object.entries(snapshotInfo.snapshotBlobs)) {\n\t\tblobContents.set(blobId, stringToBuffer(serializedContent, \"utf8\"));\n\t}\n\treturn {\n\t\tsnapshotTree: snapshotInfo.baseSnapshot,\n\t\tblobContents,\n\t\tops: [],\n\t\tsequenceNumber: snapshotSequenceNumber,\n\t\tlatestSequenceNumber: undefined,\n\t\tsnapshotFormatV: 1,\n\t};\n}\n\n/**\n * Converts summary parts into a SnapshotTree and its blob contents.\n * @param protocolSummaryTree - Protocol Summary Tree\n * @param appSummaryTree - App Summary Tree\n */\nfunction convertProtocolAndAppSummaryToSnapshotAndBlobs(\n\tprotocolSummaryTree: ISummaryTree,\n\tappSummaryTree: ISummaryTree,\n): SnapshotWithBlobs {\n\tconst combinedSummary: ISummaryTree = {\n\t\ttype: SummaryType.Tree,\n\t\ttree: { ...appSummaryTree.tree },\n\t};\n\n\tcombinedSummary.tree[\".protocol\"] = protocolSummaryTree;\n\tconst snapshotTreeWithBlobContents = convertSummaryToSnapshotAndBlobs(combinedSummary);\n\treturn snapshotTreeWithBlobContents;\n}\n\nexport const getSnapshotTreeAndBlobsFromSerializedContainer = (\n\tdetachedContainerSnapshot: ISummaryTree,\n): SnapshotWithBlobs => {\n\tassert(\n\t\tisCombinedAppAndProtocolSummary(detachedContainerSnapshot),\n\t\t0x8e6 /* Protocol and App summary trees should be present */,\n\t);\n\tconst protocolSummaryTree = detachedContainerSnapshot.tree[\".protocol\"];\n\tconst appSummaryTree = detachedContainerSnapshot.tree[\".app\"];\n\tconst snapshotTreeWithBlobContents = convertProtocolAndAppSummaryToSnapshotAndBlobs(\n\t\tprotocolSummaryTree,\n\t\tappSummaryTree,\n\t);\n\treturn snapshotTreeWithBlobContents;\n};\n\nexport function getProtocolSnapshotTree(snapshot: ISnapshotTree): ISnapshotTree {\n\treturn \".protocol\" in snapshot.trees ? snapshot.trees[\".protocol\"] : snapshot;\n}\n\nexport const combineSnapshotTreeAndSnapshotBlobs = (\n\tbaseSnapshot: ISnapshotTree,\n\tsnapshotBlobs: ISerializableBlobContents,\n): ISnapshotTreeWithBlobContents => {\n\tconst blobsContents: { [path: string]: ArrayBufferLike } = {};\n\n\t// Process blobs in the current level\n\tfor (const [, id] of Object.entries(baseSnapshot.blobs)) {\n\t\tif (snapshotBlobs[id]) {\n\t\t\tblobsContents[id] = stringToBuffer(snapshotBlobs[id], \"utf8\");\n\t\t}\n\t}\n\n\t// Recursively process trees in the current level\n\tconst trees: { [path: string]: ISnapshotTreeWithBlobContents } = {};\n\tfor (const [path, tree] of Object.entries(baseSnapshot.trees)) {\n\t\ttrees[path] = combineSnapshotTreeAndSnapshotBlobs(tree, snapshotBlobs);\n\t}\n\n\t// Create a new snapshot tree with blob contents and processed trees\n\tconst snapshotTreeWithBlobContents: ISnapshotTreeWithBlobContents = {\n\t\t...baseSnapshot,\n\t\tblobsContents,\n\t\ttrees,\n\t};\n\n\treturn snapshotTreeWithBlobContents;\n};\n\nexport function isDeltaStreamConnectionForbiddenError(\n\terror: any,\n): error is DeltaStreamConnectionForbiddenError {\n\treturn (\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\terror?.errorType === DriverErrorTypes.deltaStreamConnectionForbidden\n\t);\n}\n\n/**\n * Validates format in parsed string get from detached container\n * serialization using IPendingDetachedContainerState format.\n */\nfunction isPendingDetachedContainerState(\n\tdetachedContainerState: IPendingDetachedContainerState,\n): detachedContainerState is IPendingDetachedContainerState {\n\tif (\n\t\tdetachedContainerState?.attached === undefined ||\n\t\tdetachedContainerState?.baseSnapshot === undefined ||\n\t\tdetachedContainerState?.snapshotBlobs === undefined ||\n\t\tdetachedContainerState?.hasAttachmentBlobs === undefined\n\t) {\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nexport function getDetachedContainerStateFromSerializedContainer(\n\tserializedContainer: string,\n): IPendingDetachedContainerState {\n\tconst hasBlobsSummaryTree = \".hasAttachmentBlobs\";\n\tconst parsedContainerState = JSON.parse(serializedContainer);\n\tif (isPendingDetachedContainerState(parsedContainerState)) {\n\t\treturn parsedContainerState;\n\t} else if (isCombinedAppAndProtocolSummary(parsedContainerState)) {\n\t\tconst { baseSnapshot, snapshotBlobs } =\n\t\t\tgetSnapshotTreeAndBlobsFromSerializedContainer(parsedContainerState);\n\t\tconst detachedContainerState: IPendingDetachedContainerState = {\n\t\t\tattached: false,\n\t\t\tbaseSnapshot,\n\t\t\tsnapshotBlobs,\n\t\t\thasAttachmentBlobs: parsedContainerState.tree[hasBlobsSummaryTree] !== undefined,\n\t\t};\n\t\treturn detachedContainerState;\n\t} else {\n\t\tthrow new UsageError(\"Cannot rehydrate detached container. Incorrect format\");\n\t}\n}\n\n/**\n * Ensures only a single instance of the provided async function is running.\n * If there are multiple calls they will all get the same promise to wait on.\n */\nexport const runSingle = <A extends any[], R>(func: (...args: A) => Promise<R>) => {\n\tlet running:\n\t\t| {\n\t\t\t\targs: A;\n\t\t\t\tresult: Promise<R>;\n\t\t }\n\t\t| undefined;\n\t// don't mark this function async, so we return the same promise,\n\t// rather than one that is wrapped due to async\n\t// eslint-disable-next-line @typescript-eslint/promise-function-async\n\treturn (...args: A) => {\n\t\tif (running !== undefined) {\n\t\t\tif (!compareArrays(running.args, args)) {\n\t\t\t\treturn Promise.reject(\n\t\t\t\t\tnew UsageError(\"Subsequent calls cannot use different arguments.\"),\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn running.result;\n\t\t}\n\t\trunning = { args, result: func(...args).finally(() => (running = undefined)) };\n\t\treturn running.result;\n\t};\n};\n\nexport async function getDocumentAttributes(\n\tstorage: Pick<IDocumentStorageService, \"readBlob\">,\n\ttree: ISnapshotTree | undefined,\n): Promise<IDocumentAttributes> {\n\tif (tree === undefined) {\n\t\treturn {\n\t\t\tminimumSequenceNumber: 0,\n\t\t\tsequenceNumber: 0,\n\t\t};\n\t}\n\n\t// Backward compatibility: old docs would have \".attributes\" instead of \"attributes\"\n\tconst attributesHash =\n\t\t\".protocol\" in tree.trees\n\t\t\t? tree.trees[\".protocol\"].blobs.attributes\n\t\t\t: tree.blobs[\".attributes\"];\n\n\tconst attributes = await readAndParse<IDocumentAttributes>(storage, attributesHash);\n\n\treturn attributes;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/container-loader",
3
- "version": "2.0.0-rc.2.0.2",
3
+ "version": "2.0.0-rc.3.0.0",
4
4
  "description": "Fluid container loader",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -15,15 +15,15 @@
15
15
  "exports": {
16
16
  ".": {
17
17
  "import": {
18
- "types": "./lib/index.d.ts",
18
+ "types": "./lib/public.d.ts",
19
19
  "default": "./lib/index.js"
20
20
  },
21
21
  "require": {
22
- "types": "./dist/index.d.ts",
22
+ "types": "./dist/public.d.ts",
23
23
  "default": "./dist/index.js"
24
24
  }
25
25
  },
26
- "./test/container": {
26
+ "./internal/test/container": {
27
27
  "import": {
28
28
  "types": "./lib/container.d.ts",
29
29
  "default": "./lib/container.js"
@@ -33,7 +33,7 @@
33
33
  "default": "./dist/container.js"
34
34
  }
35
35
  },
36
- "./test/contracts": {
36
+ "./internal/test/contracts": {
37
37
  "import": {
38
38
  "types": "./lib/contracts.d.ts",
39
39
  "default": "./lib/contracts.js"
@@ -43,7 +43,7 @@
43
43
  "default": "./dist/contracts.js"
44
44
  }
45
45
  },
46
- "./test/connectionManager": {
46
+ "./internal/test/connectionManager": {
47
47
  "import": {
48
48
  "types": "./lib/connectionManager.d.ts",
49
49
  "default": "./lib/connectionManager.js"
@@ -53,7 +53,7 @@
53
53
  "default": "./dist/connectionManager.js"
54
54
  }
55
55
  },
56
- "./test/deltaManager": {
56
+ "./internal/test/deltaManager": {
57
57
  "import": {
58
58
  "types": "./lib/deltaManager.d.ts",
59
59
  "default": "./lib/deltaManager.js"
@@ -63,7 +63,7 @@
63
63
  "default": "./dist/deltaManager.js"
64
64
  }
65
65
  },
66
- "./test/utils": {
66
+ "./internal/test/utils": {
67
67
  "import": {
68
68
  "types": "./lib/utils.d.ts",
69
69
  "default": "./lib/utils.js"
@@ -73,23 +73,13 @@
73
73
  "default": "./dist/utils.js"
74
74
  }
75
75
  },
76
- "./public": {
77
- "import": {
78
- "types": "./lib/container-loader-public.d.ts",
79
- "default": "./lib/index.js"
80
- },
81
- "require": {
82
- "types": "./dist/container-loader-public.d.ts",
83
- "default": "./dist/index.js"
84
- }
85
- },
86
- "./alpha": {
76
+ "./legacy": {
87
77
  "import": {
88
- "types": "./lib/container-loader-alpha.d.ts",
78
+ "types": "./lib/legacy.d.ts",
89
79
  "default": "./lib/index.js"
90
80
  },
91
81
  "require": {
92
- "types": "./dist/container-loader-alpha.d.ts",
82
+ "types": "./dist/legacy.d.ts",
93
83
  "default": "./dist/index.js"
94
84
  }
95
85
  },
@@ -104,8 +94,8 @@
104
94
  }
105
95
  }
106
96
  },
107
- "main": "dist/index.js",
108
- "types": "dist/index.d.ts",
97
+ "main": "lib/index.js",
98
+ "types": "lib/public.d.ts",
109
99
  "c8": {
110
100
  "all": true,
111
101
  "cache-dir": "nyc/.cache",
@@ -127,29 +117,30 @@
127
117
  "temp-directory": "nyc/.nyc_output"
128
118
  },
129
119
  "dependencies": {
130
- "@fluid-internal/client-utils": ">=2.0.0-rc.2.0.2 <2.0.0-rc.2.1.0",
131
- "@fluidframework/container-definitions": ">=2.0.0-rc.2.0.2 <2.0.0-rc.2.1.0",
132
- "@fluidframework/core-interfaces": ">=2.0.0-rc.2.0.2 <2.0.0-rc.2.1.0",
133
- "@fluidframework/core-utils": ">=2.0.0-rc.2.0.2 <2.0.0-rc.2.1.0",
134
- "@fluidframework/driver-definitions": ">=2.0.0-rc.2.0.2 <2.0.0-rc.2.1.0",
135
- "@fluidframework/driver-utils": ">=2.0.0-rc.2.0.2 <2.0.0-rc.2.1.0",
120
+ "@fluid-internal/client-utils": ">=2.0.0-rc.3.0.0 <2.0.0-rc.3.1.0",
121
+ "@fluidframework/container-definitions": ">=2.0.0-rc.3.0.0 <2.0.0-rc.3.1.0",
122
+ "@fluidframework/core-interfaces": ">=2.0.0-rc.3.0.0 <2.0.0-rc.3.1.0",
123
+ "@fluidframework/core-utils": ">=2.0.0-rc.3.0.0 <2.0.0-rc.3.1.0",
124
+ "@fluidframework/driver-definitions": ">=2.0.0-rc.3.0.0 <2.0.0-rc.3.1.0",
125
+ "@fluidframework/driver-utils": ">=2.0.0-rc.3.0.0 <2.0.0-rc.3.1.0",
136
126
  "@fluidframework/protocol-base": "^4.0.0",
137
127
  "@fluidframework/protocol-definitions": "^3.2.0",
138
- "@fluidframework/telemetry-utils": ">=2.0.0-rc.2.0.2 <2.0.0-rc.2.1.0",
128
+ "@fluidframework/telemetry-utils": ">=2.0.0-rc.3.0.0 <2.0.0-rc.3.1.0",
139
129
  "@ungap/structured-clone": "^1.2.0",
140
130
  "debug": "^4.3.4",
141
131
  "double-ended-queue": "^2.1.0-0",
142
132
  "uuid": "^9.0.0"
143
133
  },
144
134
  "devDependencies": {
145
- "@arethetypeswrong/cli": "^0.13.3",
146
- "@fluid-internal/mocha-test-setup": ">=2.0.0-rc.2.0.2 <2.0.0-rc.2.1.0",
147
- "@fluid-private/test-loader-utils": ">=2.0.0-rc.2.0.2 <2.0.0-rc.2.1.0",
148
- "@fluid-tools/build-cli": "^0.34.0",
135
+ "@arethetypeswrong/cli": "^0.15.2",
136
+ "@biomejs/biome": "^1.6.2",
137
+ "@fluid-internal/mocha-test-setup": ">=2.0.0-rc.3.0.0 <2.0.0-rc.3.1.0",
138
+ "@fluid-private/test-loader-utils": ">=2.0.0-rc.3.0.0 <2.0.0-rc.3.1.0",
139
+ "@fluid-tools/build-cli": "^0.37.0",
149
140
  "@fluidframework/build-common": "^2.0.3",
150
- "@fluidframework/build-tools": "^0.34.0",
141
+ "@fluidframework/build-tools": "^0.37.0",
151
142
  "@fluidframework/container-loader-previous": "npm:@fluidframework/container-loader@2.0.0-internal.8.0.0",
152
- "@fluidframework/eslint-config-fluid": "^4.0.0",
143
+ "@fluidframework/eslint-config-fluid": "^5.1.0",
153
144
  "@microsoft/api-extractor": "^7.42.3",
154
145
  "@types/debug": "^4.1.5",
155
146
  "@types/double-ended-queue": "^2.1.0",
@@ -171,18 +162,6 @@
171
162
  "sinon": "^17.0.1",
172
163
  "typescript": "~5.1.6"
173
164
  },
174
- "fluidBuild": {
175
- "tasks": {
176
- "build:docs": {
177
- "dependsOn": [
178
- "...",
179
- "api-extractor:commonjs",
180
- "api-extractor:esnext"
181
- ],
182
- "script": false
183
- }
184
- }
185
- },
186
165
  "typeValidation": {
187
166
  "broken": {
188
167
  "InterfaceDeclaration_IContainerExperimental": {
@@ -195,28 +174,28 @@
195
174
  },
196
175
  "scripts": {
197
176
  "api": "fluid-build . --task api",
198
- "api-extractor:commonjs": "api-extractor run --config ./api-extractor-cjs.json",
199
- "api-extractor:esnext": "api-extractor run --local",
177
+ "api-extractor:commonjs": "flub generate entrypoints --outFileAlpha legacy --outDir ./dist",
178
+ "api-extractor:esnext": "flub generate entrypoints --outFileAlpha legacy --outDir ./lib --node10TypeCompat",
200
179
  "build": "fluid-build . --task build",
201
180
  "build:commonjs": "fluid-build . --task commonjs",
202
181
  "build:compile": "fluid-build . --task compile",
203
- "build:docs": "fluid-build . --task api",
182
+ "build:docs": "api-extractor run --local",
204
183
  "build:esnext": "tsc --project ./tsconfig.json",
205
184
  "build:genver": "gen-version",
206
185
  "build:test": "npm run build:test:esm && npm run build:test:cjs",
207
186
  "build:test:cjs": "fluid-tsc commonjs --project ./src/test/tsconfig.cjs.json",
208
187
  "build:test:esm": "tsc --project ./src/test/tsconfig.json",
209
- "check:are-the-types-wrong": "attw --pack . --entrypoints .",
188
+ "check:are-the-types-wrong": "attw --pack . --exclude-entrypoints ./internal/test/container ./internal/test/contracts ./internal/test/connectionManager ./internal/test/deltaManager ./internal/test/utils",
189
+ "check:prettier": "prettier --check . --cache --ignore-path ../../../.prettierignore",
210
190
  "check:release-tags": "api-extractor run --local --config ./api-extractor-lint.json",
211
191
  "ci:build:docs": "api-extractor run",
212
- "clean": "rimraf --glob dist lib \"**/*.tsbuildinfo\" \"**/*.build.log\" _api-extractor-temp nyc",
192
+ "clean": "rimraf --glob dist lib \"*.d.ts\" \"**/*.tsbuildinfo\" \"**/*.build.log\" _api-extractor-temp nyc",
213
193
  "eslint": "eslint --format stylish src",
214
194
  "eslint:fix": "eslint --format stylish src --fix --fix-type problem,suggestion,layout",
215
- "format": "npm run prettier:fix",
216
- "lint": "npm run prettier && npm run check:release-tags && npm run eslint",
217
- "lint:fix": "npm run prettier:fix && npm run eslint:fix",
218
- "prettier": "prettier --check . --cache --ignore-path ../../../.prettierignore",
219
- "prettier:fix": "prettier --write . --cache --ignore-path ../../../.prettierignore",
195
+ "format": "fluid-build --task format .",
196
+ "format:prettier": "prettier --write . --cache --ignore-path ../../../.prettierignore",
197
+ "lint": "fluid-build . --task lint",
198
+ "lint:fix": "fluid-build . --task eslint:fix --task format",
220
199
  "test": "npm run test:mocha",
221
200
  "test:coverage": "c8 npm test",
222
201
  "test:mocha": "npm run test:mocha:esm && echo skipping cjs to avoid overhead - npm run test:mocha:cjs",
package/src/attachment.ts CHANGED
@@ -2,14 +2,16 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
+
5
6
  import { AttachState } from "@fluidframework/container-definitions";
6
- import { CombinedAppAndProtocolSummary } from "@fluidframework/driver-utils";
7
- import { ISnapshotTree, ISummaryTree } from "@fluidframework/protocol-definitions";
8
- import { assert } from "@fluidframework/core-utils";
9
- import { IDocumentStorageService } from "@fluidframework/driver-definitions";
7
+ import { assert } from "@fluidframework/core-utils/internal";
8
+ import { IDocumentStorageService } from "@fluidframework/driver-definitions/internal";
9
+ import { CombinedAppAndProtocolSummary } from "@fluidframework/driver-utils/internal";
10
+ import { ISummaryTree } from "@fluidframework/protocol-definitions";
11
+
12
+ import { IDetachedBlobStorage } from "./loader.js";
13
+ import type { SnapshotWithBlobs } from "./serializedStateManager.js";
10
14
  import { getSnapshotTreeAndBlobsFromSerializedContainer } from "./utils.js";
11
- import { ISerializableBlobContents } from "./containerStorageAdapter.js";
12
- import { IDetachedBlobStorage } from "./index.js";
13
15
 
14
16
  /**
15
17
  * The default state a newly created detached container will have.
@@ -134,7 +136,7 @@ export interface AttachProcessProps {
134
136
  */
135
137
  export const runRetriableAttachProcess = async (
136
138
  props: AttachProcessProps,
137
- ): Promise<{ tree: ISnapshotTree; blobs: ISerializableBlobContents } | undefined> => {
139
+ ): Promise<SnapshotWithBlobs | undefined> => {
138
140
  const {
139
141
  detachedBlobStorage,
140
142
  createOrGetStorageService,
@@ -209,7 +211,7 @@ export const runRetriableAttachProcess = async (
209
211
  });
210
212
  }
211
213
 
212
- const snapshot = offlineLoadEnabled
214
+ const snapshot: SnapshotWithBlobs | undefined = offlineLoadEnabled
213
215
  ? getSnapshotTreeAndBlobsFromSerializedContainer(currentData.summary)
214
216
  : undefined;
215
217
 
package/src/audience.ts CHANGED
@@ -2,9 +2,10 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
+
5
6
  import { EventEmitter } from "@fluid-internal/client-utils";
6
- import { assert } from "@fluidframework/core-utils";
7
- import { IAudienceOwner } from "@fluidframework/container-definitions";
7
+ import { IAudienceOwner } from "@fluidframework/container-definitions/internal";
8
+ import { assert } from "@fluidframework/core-utils/internal";
8
9
  import { IClient } from "@fluidframework/protocol-definitions";
9
10
 
10
11
  /**
@@ -3,9 +3,9 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { IDisposable } from "@fluidframework/core-interfaces";
7
- import { assert } from "@fluidframework/core-utils";
8
6
  import { IDeltaManager } from "@fluidframework/container-definitions";
7
+ import { IDisposable } from "@fluidframework/core-interfaces";
8
+ import { assert } from "@fluidframework/core-utils/internal";
9
9
  import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
10
10
 
11
11
  /** @see CatchUpMonitor for usage */
@@ -3,30 +3,29 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { IDisposable, ITelemetryBaseProperties, LogLevel } from "@fluidframework/core-interfaces";
7
- import { assert } from "@fluidframework/core-utils";
8
- import { performance, TypedEventEmitter } from "@fluid-internal/client-utils";
6
+ import { TypedEventEmitter, performance } from "@fluid-internal/client-utils";
9
7
  import {
10
8
  ICriticalContainerError,
11
9
  IDeltaQueue,
12
10
  ReadOnlyInfo,
13
11
  } from "@fluidframework/container-definitions";
12
+ import { IDisposable, ITelemetryBaseProperties, LogLevel } from "@fluidframework/core-interfaces";
13
+ import { assert } from "@fluidframework/core-utils/internal";
14
+ import { DriverErrorTypes, IAnyDriverError } from "@fluidframework/driver-definitions";
14
15
  import {
15
- IAnyDriverError,
16
- IDocumentService,
17
16
  IDocumentDeltaConnection,
18
17
  IDocumentDeltaConnectionEvents,
19
- DriverErrorTypes,
20
- } from "@fluidframework/driver-definitions";
18
+ IDocumentService,
19
+ } from "@fluidframework/driver-definitions/internal";
21
20
  import {
21
+ calculateMaxWaitTime,
22
22
  canRetryOnError,
23
- createWriteError,
24
23
  createGenericNetworkError,
24
+ createWriteError,
25
25
  getRetryDelayFromError,
26
- logNetworkFailure,
27
26
  isRuntimeMessage,
28
- calculateMaxWaitTime,
29
- } from "@fluidframework/driver-utils";
27
+ logNetworkFailure,
28
+ } from "@fluidframework/driver-utils/internal";
30
29
  import {
31
30
  ConnectionMode,
32
31
  IClient,
@@ -36,27 +35,28 @@ import {
36
35
  INack,
37
36
  INackContent,
38
37
  ISequencedDocumentMessage,
38
+ ISequencedDocumentSystemMessage,
39
39
  ISignalClient,
40
40
  ISignalMessage,
41
41
  ITokenClaims,
42
42
  MessageType,
43
43
  ScopeType,
44
- ISequencedDocumentSystemMessage,
45
44
  } from "@fluidframework/protocol-definitions";
45
+ import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils";
46
46
  import {
47
- formatTick,
48
47
  GenericError,
48
+ UsageError,
49
+ formatTick,
49
50
  isFluidError,
50
- ITelemetryLoggerExt,
51
51
  normalizeError,
52
- UsageError,
53
- } from "@fluidframework/telemetry-utils";
52
+ } from "@fluidframework/telemetry-utils/internal";
53
+
54
54
  import {
55
- ReconnectMode,
55
+ IConnectionDetailsInternal,
56
56
  IConnectionManager,
57
57
  IConnectionManagerFactoryArgs,
58
- IConnectionDetailsInternal,
59
58
  IConnectionStateChangeReason,
59
+ ReconnectMode,
60
60
  } from "./contracts.js";
61
61
  import { DeltaQueue } from "./deltaQueue.js";
62
62
  import { SignalType } from "./protocol.js";
@@ -533,6 +533,8 @@ export class ConnectionManager implements IConnectionManager {
533
533
  const docService = this.serviceProvider();
534
534
  assert(docService !== undefined, 0x2a7 /* "Container is not attached" */);
535
535
 
536
+ this.props.establishConnectionHandler(reason);
537
+
536
538
  let connection: IDocumentDeltaConnection | undefined;
537
539
 
538
540
  if (docService.policies?.storageOnly === true) {
@@ -556,7 +558,6 @@ export class ConnectionManager implements IConnectionManager {
556
558
  connectionMode: requestedMode,
557
559
  };
558
560
 
559
- this.props.establishConnectionHandler(reason);
560
561
  // This loop will keep trying to connect until successful, with a delay between each iteration.
561
562
  while (connection === undefined) {
562
563
  if (this._disposed) {
@@ -644,6 +645,12 @@ export class ConnectionManager implements IConnectionManager {
644
645
 
645
646
  lastError = origError;
646
647
 
648
+ // We will not perform retries if the container disconnected and the ReconnectMode is set to Disabled or Never
649
+ // so break out of the re-connecting while-loop after first attempt
650
+ if (this.reconnectMode !== ReconnectMode.Enabled) {
651
+ return;
652
+ }
653
+
647
654
  const waitStartTime = performance.now();
648
655
  const retryDelayFromError = getRetryDelayFromError(origError);
649
656
  // If the error told us to wait or browser signals us that we are offline, then calculate the time we
@@ -1069,7 +1076,7 @@ export class ConnectionManager implements IConnectionManager {
1069
1076
  };
1070
1077
  }
1071
1078
 
1072
- public submitSignal(content: any, targetClientId?: string) {
1079
+ public submitSignal(content: string, targetClientId?: string) {
1073
1080
  if (this.connection !== undefined) {
1074
1081
  this.connection.submitSignal(content, targetClientId);
1075
1082
  } else {
@@ -3,17 +3,17 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { ITelemetryBaseProperties } from "@fluidframework/core-interfaces";
7
- import { assert, Timer } from "@fluidframework/core-utils";
8
6
  import { IDeltaManager } from "@fluidframework/container-definitions";
9
- import { ISequencedClient, IClient } from "@fluidframework/protocol-definitions";
7
+ import { ITelemetryBaseProperties } from "@fluidframework/core-interfaces";
8
+ import { assert, Timer } from "@fluidframework/core-utils/internal";
9
+ import { IAnyDriverError } from "@fluidframework/driver-definitions";
10
+ import { IClient, ISequencedClient } from "@fluidframework/protocol-definitions";
11
+ import { ITelemetryLoggerExt, type TelemetryEventCategory } from "@fluidframework/telemetry-utils";
10
12
  import {
11
- ITelemetryLoggerExt,
12
13
  PerformanceEvent,
13
14
  loggerToMonitoringContext,
14
- type TelemetryEventCategory,
15
- } from "@fluidframework/telemetry-utils";
16
- import { IAnyDriverError } from "@fluidframework/driver-definitions";
15
+ } from "@fluidframework/telemetry-utils/internal";
16
+
17
17
  import { CatchUpMonitor, ICatchUpMonitor } from "./catchUpMonitor.js";
18
18
  import { ConnectionState } from "./connectionState.js";
19
19
  import { IConnectionDetailsInternal, IConnectionStateChangeReason } from "./contracts.js";