@fluidframework/container-loader 2.0.0-rc.1.0.6 → 2.0.0-rc.2.0.1

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 (298) hide show
  1. package/{.eslintrc.js → .eslintrc.cjs} +5 -6
  2. package/{.mocharc.js → .mocharc.cjs} +1 -1
  3. package/CHANGELOG.md +48 -0
  4. package/README.md +3 -3
  5. package/{api-extractor-esm.json → api-extractor-cjs.json} +5 -1
  6. package/api-extractor-lint.json +1 -1
  7. package/api-extractor.json +1 -1
  8. package/api-report/container-loader.api.md +2 -2
  9. package/dist/attachment.d.ts +115 -0
  10. package/dist/attachment.d.ts.map +1 -0
  11. package/dist/attachment.js +83 -0
  12. package/dist/attachment.js.map +1 -0
  13. package/dist/audience.d.ts +9 -4
  14. package/dist/audience.d.ts.map +1 -1
  15. package/dist/audience.js +10 -4
  16. package/dist/audience.js.map +1 -1
  17. package/dist/connectionManager.d.ts +3 -3
  18. package/dist/connectionManager.d.ts.map +1 -1
  19. package/dist/connectionManager.js +17 -18
  20. package/dist/connectionManager.js.map +1 -1
  21. package/dist/connectionState.d.ts +1 -0
  22. package/dist/connectionState.d.ts.map +1 -1
  23. package/dist/connectionState.js +1 -0
  24. package/dist/connectionState.js.map +1 -1
  25. package/dist/connectionStateHandler.d.ts +7 -7
  26. package/dist/connectionStateHandler.d.ts.map +1 -1
  27. package/dist/connectionStateHandler.js +32 -32
  28. package/dist/connectionStateHandler.js.map +1 -1
  29. package/dist/container-loader-alpha.d.ts +2 -1
  30. package/dist/container-loader-beta.d.ts +3 -0
  31. package/dist/container-loader-public.d.ts +3 -0
  32. package/dist/container-loader-untrimmed.d.ts +5 -5
  33. package/dist/container.d.ts +29 -27
  34. package/dist/container.d.ts.map +1 -1
  35. package/dist/container.js +215 -284
  36. package/dist/container.js.map +1 -1
  37. package/dist/containerContext.d.ts +3 -2
  38. package/dist/containerContext.d.ts.map +1 -1
  39. package/dist/containerContext.js +2 -1
  40. package/dist/containerContext.js.map +1 -1
  41. package/dist/containerStorageAdapter.d.ts +5 -6
  42. package/dist/containerStorageAdapter.d.ts.map +1 -1
  43. package/dist/containerStorageAdapter.js +14 -21
  44. package/dist/containerStorageAdapter.js.map +1 -1
  45. package/dist/contracts.d.ts +3 -3
  46. package/dist/contracts.d.ts.map +1 -1
  47. package/dist/contracts.js.map +1 -1
  48. package/dist/debugLogger.js.map +1 -1
  49. package/dist/deltaManager.d.ts +5 -5
  50. package/dist/deltaManager.d.ts.map +1 -1
  51. package/dist/deltaManager.js +6 -6
  52. package/dist/deltaManager.js.map +1 -1
  53. package/dist/error.d.ts.map +1 -1
  54. package/dist/error.js.map +1 -1
  55. package/dist/index.d.ts +6 -6
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +11 -11
  58. package/dist/index.js.map +1 -1
  59. package/dist/loader.d.ts +3 -3
  60. package/dist/loader.d.ts.map +1 -1
  61. package/dist/loader.js +13 -17
  62. package/dist/loader.js.map +1 -1
  63. package/dist/location-redirection-utilities/index.d.ts +1 -1
  64. package/dist/location-redirection-utilities/index.d.ts.map +1 -1
  65. package/dist/location-redirection-utilities/index.js +3 -3
  66. package/dist/location-redirection-utilities/index.js.map +1 -1
  67. package/dist/package.json +3 -0
  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/protocolTreeDocumentStorageService.d.ts +1 -1
  72. package/dist/protocolTreeDocumentStorageService.d.ts.map +1 -1
  73. package/dist/protocolTreeDocumentStorageService.js +1 -3
  74. package/dist/protocolTreeDocumentStorageService.js.map +1 -1
  75. package/dist/retriableDocumentStorageService.d.ts +2 -2
  76. package/dist/retriableDocumentStorageService.d.ts.map +1 -1
  77. package/dist/retriableDocumentStorageService.js +8 -6
  78. package/dist/retriableDocumentStorageService.js.map +1 -1
  79. package/dist/serializedStateManager.d.ts +44 -0
  80. package/dist/serializedStateManager.d.ts.map +1 -0
  81. package/dist/serializedStateManager.js +149 -0
  82. package/dist/serializedStateManager.js.map +1 -0
  83. package/dist/tsdoc-metadata.json +1 -1
  84. package/dist/utils.d.ts +16 -11
  85. package/dist/utils.d.ts.map +1 -1
  86. package/dist/utils.js +107 -32
  87. package/dist/utils.js.map +1 -1
  88. package/lib/attachment.d.ts +115 -0
  89. package/lib/attachment.d.ts.map +1 -0
  90. package/lib/attachment.js +79 -0
  91. package/lib/attachment.js.map +1 -0
  92. package/lib/{audience.d.mts → audience.d.ts} +14 -5
  93. package/lib/audience.d.ts.map +1 -0
  94. package/lib/{audience.mjs → audience.js} +14 -4
  95. package/lib/audience.js.map +1 -0
  96. package/lib/{catchUpMonitor.d.mts → catchUpMonitor.d.ts} +1 -1
  97. package/lib/catchUpMonitor.d.ts.map +1 -0
  98. package/lib/{catchUpMonitor.mjs → catchUpMonitor.js} +1 -1
  99. package/lib/catchUpMonitor.js.map +1 -0
  100. package/lib/{connectionManager.d.mts → connectionManager.d.ts} +4 -4
  101. package/lib/connectionManager.d.ts.map +1 -0
  102. package/lib/{connectionManager.mjs → connectionManager.js} +7 -10
  103. package/lib/connectionManager.js.map +1 -0
  104. package/lib/{connectionState.d.mts → connectionState.d.ts} +2 -1
  105. package/lib/connectionState.d.ts.map +1 -0
  106. package/lib/{connectionState.mjs → connectionState.js} +2 -1
  107. package/lib/connectionState.js.map +1 -0
  108. package/lib/{connectionStateHandler.d.mts → connectionStateHandler.d.ts} +8 -8
  109. package/lib/connectionStateHandler.d.ts.map +1 -0
  110. package/lib/{connectionStateHandler.mjs → connectionStateHandler.js} +3 -3
  111. package/lib/connectionStateHandler.js.map +1 -0
  112. package/lib/{container-loader-alpha.d.mts → container-loader-alpha.d.ts} +2 -1
  113. package/lib/{container-loader-beta.d.mts → container-loader-beta.d.ts} +3 -0
  114. package/lib/{container-loader-public.d.mts → container-loader-public.d.ts} +3 -0
  115. package/lib/{container-loader-untrimmed.d.mts → container-loader-untrimmed.d.ts} +5 -5
  116. package/lib/{container.d.mts → container.d.ts} +30 -28
  117. package/lib/container.d.ts.map +1 -0
  118. package/lib/{container.mjs → container.js} +178 -247
  119. package/lib/container.js.map +1 -0
  120. package/lib/{containerContext.d.mts → containerContext.d.ts} +4 -3
  121. package/lib/containerContext.d.ts.map +1 -0
  122. package/lib/{containerContext.mjs → containerContext.js} +3 -2
  123. package/lib/containerContext.js.map +1 -0
  124. package/lib/{containerStorageAdapter.d.mts → containerStorageAdapter.d.ts} +6 -7
  125. package/lib/containerStorageAdapter.d.ts.map +1 -0
  126. package/lib/{containerStorageAdapter.mjs → containerStorageAdapter.js} +13 -20
  127. package/lib/containerStorageAdapter.js.map +1 -0
  128. package/lib/{contracts.d.mts → contracts.d.ts} +4 -4
  129. package/lib/contracts.d.ts.map +1 -0
  130. package/lib/{contracts.mjs → contracts.js} +1 -1
  131. package/lib/contracts.js.map +1 -0
  132. package/lib/{debugLogger.d.mts → debugLogger.d.ts} +1 -1
  133. package/lib/debugLogger.d.ts.map +1 -0
  134. package/lib/{debugLogger.mjs → debugLogger.js} +2 -1
  135. package/lib/debugLogger.js.map +1 -0
  136. package/lib/{deltaManager.d.mts → deltaManager.d.ts} +6 -6
  137. package/lib/deltaManager.d.ts.map +1 -0
  138. package/lib/{deltaManager.mjs → deltaManager.js} +4 -4
  139. package/lib/deltaManager.js.map +1 -0
  140. package/lib/{deltaQueue.d.mts → deltaQueue.d.ts} +1 -1
  141. package/lib/deltaQueue.d.ts.map +1 -0
  142. package/lib/{deltaQueue.mjs → deltaQueue.js} +1 -1
  143. package/lib/deltaQueue.js.map +1 -0
  144. package/lib/{disposal.d.mts → disposal.d.ts} +1 -1
  145. package/lib/disposal.d.ts.map +1 -0
  146. package/lib/{disposal.mjs → disposal.js} +1 -1
  147. package/lib/disposal.js.map +1 -0
  148. package/lib/{error.d.mts → error.d.ts} +1 -1
  149. package/lib/error.d.ts.map +1 -0
  150. package/lib/{error.mjs → error.js} +1 -1
  151. package/lib/error.js.map +1 -0
  152. package/lib/{index.d.mts → index.d.ts} +7 -7
  153. package/lib/index.d.ts.map +1 -0
  154. package/lib/index.js +10 -0
  155. package/lib/index.js.map +1 -0
  156. package/lib/{loader.d.mts → loader.d.ts} +4 -4
  157. package/lib/loader.d.ts.map +1 -0
  158. package/lib/{loader.mjs → loader.js} +7 -11
  159. package/lib/loader.js.map +1 -0
  160. package/lib/location-redirection-utilities/{index.mjs → index.d.ts} +2 -2
  161. package/lib/location-redirection-utilities/index.d.ts.map +1 -0
  162. package/lib/location-redirection-utilities/{index.d.mts → index.js} +2 -2
  163. package/lib/location-redirection-utilities/index.js.map +1 -0
  164. package/lib/location-redirection-utilities/{resolveWithLocationRedirection.d.mts → resolveWithLocationRedirection.d.ts} +1 -1
  165. package/lib/location-redirection-utilities/resolveWithLocationRedirection.d.ts.map +1 -0
  166. package/lib/location-redirection-utilities/{resolveWithLocationRedirection.mjs → resolveWithLocationRedirection.js} +1 -1
  167. package/lib/location-redirection-utilities/resolveWithLocationRedirection.js.map +1 -0
  168. package/lib/{noopHeuristic.d.mts → noopHeuristic.d.ts} +1 -1
  169. package/lib/noopHeuristic.d.ts.map +1 -0
  170. package/lib/{noopHeuristic.mjs → noopHeuristic.js} +1 -1
  171. package/lib/noopHeuristic.js.map +1 -0
  172. package/lib/{packageVersion.d.mts → packageVersion.d.ts} +2 -2
  173. package/lib/packageVersion.d.ts.map +1 -0
  174. package/lib/{packageVersion.mjs → packageVersion.js} +2 -2
  175. package/lib/packageVersion.js.map +1 -0
  176. package/lib/{protocol.d.mts → protocol.d.ts} +1 -1
  177. package/lib/protocol.d.ts.map +1 -0
  178. package/lib/{protocol.mjs → protocol.js} +1 -1
  179. package/lib/protocol.js.map +1 -0
  180. package/lib/{protocolTreeDocumentStorageService.d.mts → protocolTreeDocumentStorageService.d.ts} +2 -2
  181. package/lib/protocolTreeDocumentStorageService.d.ts.map +1 -0
  182. package/lib/{protocolTreeDocumentStorageService.mjs → protocolTreeDocumentStorageService.js} +2 -4
  183. package/lib/protocolTreeDocumentStorageService.js.map +1 -0
  184. package/lib/{quorum.d.mts → quorum.d.ts} +5 -1
  185. package/lib/quorum.d.ts.map +1 -0
  186. package/lib/{quorum.mjs → quorum.js} +1 -1
  187. package/lib/quorum.js.map +1 -0
  188. package/lib/{retriableDocumentStorageService.d.mts → retriableDocumentStorageService.d.ts} +3 -3
  189. package/lib/retriableDocumentStorageService.d.ts.map +1 -0
  190. package/lib/{retriableDocumentStorageService.mjs → retriableDocumentStorageService.js} +10 -8
  191. package/lib/retriableDocumentStorageService.js.map +1 -0
  192. package/lib/serializedStateManager.d.ts +44 -0
  193. package/lib/serializedStateManager.d.ts.map +1 -0
  194. package/lib/serializedStateManager.js +145 -0
  195. package/lib/serializedStateManager.js.map +1 -0
  196. package/lib/test/attachment.spec.js +380 -0
  197. package/lib/test/attachment.spec.js.map +1 -0
  198. package/lib/test/catchUpMonitor.spec.js +88 -0
  199. package/lib/test/catchUpMonitor.spec.js.map +1 -0
  200. package/lib/test/connectionManager.spec.js +201 -0
  201. package/lib/test/connectionManager.spec.js.map +1 -0
  202. package/lib/test/connectionStateHandler.spec.js +555 -0
  203. package/lib/test/connectionStateHandler.spec.js.map +1 -0
  204. package/lib/test/container.spec.js +64 -0
  205. package/lib/test/container.spec.js.map +1 -0
  206. package/lib/test/deltaManager.spec.js +405 -0
  207. package/lib/test/deltaManager.spec.js.map +1 -0
  208. package/lib/test/loader.spec.js +212 -0
  209. package/lib/test/loader.spec.js.map +1 -0
  210. package/lib/test/locationRedirectionTests.spec.js +44 -0
  211. package/lib/test/locationRedirectionTests.spec.js.map +1 -0
  212. package/lib/test/serializedStateManager.spec.js +148 -0
  213. package/lib/test/serializedStateManager.spec.js.map +1 -0
  214. package/lib/test/snapshotConversionTest.spec.js +79 -0
  215. package/lib/test/snapshotConversionTest.spec.js.map +1 -0
  216. package/lib/test/types/validateContainerLoaderPrevious.generated.js +38 -0
  217. package/lib/test/types/validateContainerLoaderPrevious.generated.js.map +1 -0
  218. package/lib/test/utils.spec.js +31 -0
  219. package/lib/test/utils.spec.js.map +1 -0
  220. package/lib/{utils.d.mts → utils.d.ts} +17 -12
  221. package/lib/utils.d.ts.map +1 -0
  222. package/lib/utils.js +206 -0
  223. package/lib/utils.js.map +1 -0
  224. package/package.json +61 -63
  225. package/src/attachment.ts +222 -0
  226. package/src/audience.ts +9 -3
  227. package/src/connectionManager.ts +9 -11
  228. package/src/connectionState.ts +1 -0
  229. package/src/connectionStateHandler.ts +8 -7
  230. package/src/container.ts +296 -323
  231. package/src/containerContext.ts +2 -1
  232. package/src/containerStorageAdapter.ts +21 -26
  233. package/src/contracts.ts +3 -3
  234. package/src/debugLogger.ts +2 -2
  235. package/src/deltaManager.ts +8 -8
  236. package/src/error.ts +2 -2
  237. package/src/index.ts +6 -6
  238. package/src/loader.ts +9 -13
  239. package/src/location-redirection-utilities/index.ts +1 -1
  240. package/src/packageVersion.ts +1 -1
  241. package/src/protocolTreeDocumentStorageService.ts +1 -3
  242. package/src/retriableDocumentStorageService.ts +18 -8
  243. package/src/serializedStateManager.ts +217 -0
  244. package/src/utils.ts +140 -43
  245. package/tsconfig.cjs.json +7 -0
  246. package/tsconfig.json +2 -5
  247. package/lib/audience.d.mts.map +0 -1
  248. package/lib/audience.mjs.map +0 -1
  249. package/lib/catchUpMonitor.d.mts.map +0 -1
  250. package/lib/catchUpMonitor.mjs.map +0 -1
  251. package/lib/connectionManager.d.mts.map +0 -1
  252. package/lib/connectionManager.mjs.map +0 -1
  253. package/lib/connectionState.d.mts.map +0 -1
  254. package/lib/connectionState.mjs.map +0 -1
  255. package/lib/connectionStateHandler.d.mts.map +0 -1
  256. package/lib/connectionStateHandler.mjs.map +0 -1
  257. package/lib/container.d.mts.map +0 -1
  258. package/lib/container.mjs.map +0 -1
  259. package/lib/containerContext.d.mts.map +0 -1
  260. package/lib/containerContext.mjs.map +0 -1
  261. package/lib/containerStorageAdapter.d.mts.map +0 -1
  262. package/lib/containerStorageAdapter.mjs.map +0 -1
  263. package/lib/contracts.d.mts.map +0 -1
  264. package/lib/contracts.mjs.map +0 -1
  265. package/lib/debugLogger.d.mts.map +0 -1
  266. package/lib/debugLogger.mjs.map +0 -1
  267. package/lib/deltaManager.d.mts.map +0 -1
  268. package/lib/deltaManager.mjs.map +0 -1
  269. package/lib/deltaQueue.d.mts.map +0 -1
  270. package/lib/deltaQueue.mjs.map +0 -1
  271. package/lib/disposal.d.mts.map +0 -1
  272. package/lib/disposal.mjs.map +0 -1
  273. package/lib/error.d.mts.map +0 -1
  274. package/lib/error.mjs.map +0 -1
  275. package/lib/index.d.mts.map +0 -1
  276. package/lib/index.mjs +0 -10
  277. package/lib/index.mjs.map +0 -1
  278. package/lib/loader.d.mts.map +0 -1
  279. package/lib/loader.mjs.map +0 -1
  280. package/lib/location-redirection-utilities/index.d.mts.map +0 -1
  281. package/lib/location-redirection-utilities/index.mjs.map +0 -1
  282. package/lib/location-redirection-utilities/resolveWithLocationRedirection.d.mts.map +0 -1
  283. package/lib/location-redirection-utilities/resolveWithLocationRedirection.mjs.map +0 -1
  284. package/lib/noopHeuristic.d.mts.map +0 -1
  285. package/lib/noopHeuristic.mjs.map +0 -1
  286. package/lib/packageVersion.d.mts.map +0 -1
  287. package/lib/packageVersion.mjs.map +0 -1
  288. package/lib/protocol.d.mts.map +0 -1
  289. package/lib/protocol.mjs.map +0 -1
  290. package/lib/protocolTreeDocumentStorageService.d.mts.map +0 -1
  291. package/lib/protocolTreeDocumentStorageService.mjs.map +0 -1
  292. package/lib/quorum.d.mts.map +0 -1
  293. package/lib/quorum.mjs.map +0 -1
  294. package/lib/retriableDocumentStorageService.d.mts.map +0 -1
  295. package/lib/retriableDocumentStorageService.mjs.map +0 -1
  296. package/lib/utils.d.mts.map +0 -1
  297. package/lib/utils.mjs +0 -133
  298. package/lib/utils.mjs.map +0 -1
@@ -16,7 +16,7 @@ import {
16
16
  IBatchMessage,
17
17
  } from "@fluidframework/container-definitions";
18
18
  import { FluidObject } from "@fluidframework/core-interfaces";
19
- import { IDocumentStorageService } from "@fluidframework/driver-definitions";
19
+ import { IDocumentStorageService, ISnapshot } from "@fluidframework/driver-definitions";
20
20
  import {
21
21
  IClientDetails,
22
22
  IDocumentMessage,
@@ -99,6 +99,7 @@ export class ContainerContext implements IContainerContext {
99
99
  public readonly existing: boolean,
100
100
  public readonly taggedLogger: ITelemetryLoggerExt,
101
101
  public readonly pendingLocalState?: unknown,
102
+ public readonly snapshotWithContents?: ISnapshot,
102
103
  ) {}
103
104
 
104
105
  public getLoadedFromVersion(): IVersion | undefined {
@@ -13,6 +13,8 @@ import {
13
13
  IDocumentService,
14
14
  IDocumentStorageService,
15
15
  IDocumentStorageServicePolicies,
16
+ ISnapshot,
17
+ ISnapshotFetchOptions,
16
18
  ISummaryContext,
17
19
  } from "@fluidframework/driver-definitions";
18
20
  import { UsageError } from "@fluidframework/driver-utils";
@@ -23,9 +25,9 @@ import {
23
25
  ISummaryTree,
24
26
  IVersion,
25
27
  } from "@fluidframework/protocol-definitions";
26
- import { IDetachedBlobStorage } from "./loader";
27
- import { ProtocolTreeStorageService } from "./protocolTreeDocumentStorageService";
28
- import { RetriableDocumentStorageService } from "./retriableDocumentStorageService";
28
+ import { IDetachedBlobStorage } from "./loader.js";
29
+ import { ProtocolTreeStorageService } from "./protocolTreeDocumentStorageService.js";
30
+ import { RetriableDocumentStorageService } from "./retriableDocumentStorageService.js";
29
31
 
30
32
  /**
31
33
  * Stringified blobs from a summary/snapshot tree.
@@ -101,18 +103,9 @@ export class ContainerStorageAdapter implements IDocumentStorageService, IDispos
101
103
  }
102
104
  }
103
105
 
104
- public loadSnapshotForRehydratingContainer(snapshotTree: ISnapshotTreeWithBlobContents) {
105
- this.getBlobContents(snapshotTree);
106
- }
107
-
108
- private getBlobContents(snapshotTree: ISnapshotTreeWithBlobContents) {
109
- if (snapshotTree.blobsContents !== undefined) {
110
- for (const [id, value] of Object.entries(snapshotTree.blobsContents ?? {})) {
111
- this.blobContents[id] = value;
112
- }
113
- }
114
- for (const [_, tree] of Object.entries(snapshotTree.trees)) {
115
- this.getBlobContents(tree);
106
+ public loadSnapshotFromSnapshotBlobs(snapshotBlobs: ISerializableBlobContents) {
107
+ for (const [id, value] of Object.entries(snapshotBlobs)) {
108
+ this.blobContents[id] = value;
116
109
  }
117
110
  }
118
111
 
@@ -125,10 +118,6 @@ export class ContainerStorageAdapter implements IDocumentStorageService, IDispos
125
118
  return undefined;
126
119
  }
127
120
 
128
- public get repositoryUrl(): string {
129
- return this._storageService.repositoryUrl;
130
- }
131
-
132
121
  public async getSnapshotTree(
133
122
  version?: IVersion,
134
123
  scenarioName?: string,
@@ -136,6 +125,15 @@ export class ContainerStorageAdapter implements IDocumentStorageService, IDispos
136
125
  return this._storageService.getSnapshotTree(version, scenarioName);
137
126
  }
138
127
 
128
+ public async getSnapshot(snapshotFetchOptions?: ISnapshotFetchOptions): Promise<ISnapshot> {
129
+ if (this._storageService.getSnapshot !== undefined) {
130
+ return this._storageService.getSnapshot(snapshotFetchOptions);
131
+ }
132
+ throw new UsageError(
133
+ "getSnapshot api should exist in internal storage in ContainerStorageAdapter",
134
+ );
135
+ }
136
+
139
137
  public async readBlob(id: string): Promise<ArrayBufferLike> {
140
138
  const maybeBlob = this.blobContents[id];
141
139
  if (maybeBlob !== undefined) {
@@ -202,12 +200,9 @@ class BlobOnlyStorage implements IDocumentStorageService {
202
200
  return this.notCalled();
203
201
  }
204
202
 
205
- public get repositoryUrl(): string {
206
- return this.notCalled();
207
- }
208
-
209
203
  /* eslint-disable @typescript-eslint/unbound-method */
210
204
  public getSnapshotTree: () => Promise<ISnapshotTree | null> = this.notCalled;
205
+ public getSnapshot: () => Promise<ISnapshot> = this.notCalled;
211
206
  public getVersions: () => Promise<IVersion[]> = this.notCalled;
212
207
  public write: () => Promise<IVersion> = this.notCalled;
213
208
  public uploadSummaryWithContext: () => Promise<string> = this.notCalled;
@@ -239,7 +234,7 @@ const redirectTableBlobName = ".redirectTable";
239
234
  */
240
235
  export async function getBlobContentsFromTree(
241
236
  snapshot: ISnapshotTree,
242
- storage: IDocumentStorageService,
237
+ storage: Pick<IDocumentStorageService, "readBlob">,
243
238
  ): Promise<ISerializableBlobContents> {
244
239
  const blobs = {};
245
240
  await getBlobContentsFromTreeCore(snapshot, blobs, storage);
@@ -249,7 +244,7 @@ export async function getBlobContentsFromTree(
249
244
  async function getBlobContentsFromTreeCore(
250
245
  tree: ISnapshotTree,
251
246
  blobs: ISerializableBlobContents,
252
- storage: IDocumentStorageService,
247
+ storage: Pick<IDocumentStorageService, "readBlob">,
253
248
  root = true,
254
249
  ) {
255
250
  const treePs: Promise<any>[] = [];
@@ -272,7 +267,7 @@ async function getBlobContentsFromTreeCore(
272
267
  async function getBlobManagerTreeFromTree(
273
268
  tree: ISnapshotTree,
274
269
  blobs: ISerializableBlobContents,
275
- storage: IDocumentStorageService,
270
+ storage: Pick<IDocumentStorageService, "readBlob">,
276
271
  ) {
277
272
  const id = tree.blobs[redirectTableBlobName];
278
273
  const blob = await storage.readBlob(id);
package/src/contracts.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { IErrorBase, ITelemetryProperties } from "@fluidframework/core-interfaces";
6
+ import { IErrorBase, ITelemetryBaseProperties } from "@fluidframework/core-interfaces";
7
7
  import {
8
8
  IConnectionDetails,
9
9
  ICriticalContainerError,
@@ -73,12 +73,12 @@ export interface IConnectionManager {
73
73
  // Various connectivity properties for telemetry describing type of current connection
74
74
  // Things like connection mode, service info, etc.
75
75
  // Called when connection state changes (connect / disconnect)
76
- readonly connectionProps: ITelemetryProperties;
76
+ readonly connectionProps: ITelemetryBaseProperties;
77
77
 
78
78
  // Verbose information about connection logged to telemetry in case of issues with
79
79
  // maintaining healthy connection, including op gaps, not receiving join op in time, etc.
80
80
  // Contains details information, like sequence numbers at connection time, initial ops info, etc.
81
- readonly connectionVerboseProps: ITelemetryProperties;
81
+ readonly connectionVerboseProps: ITelemetryBaseProperties;
82
82
 
83
83
  /**
84
84
  * Prepares message to be sent. Fills in clientSequenceNumber.
@@ -6,7 +6,7 @@
6
6
  import {
7
7
  ITelemetryBaseEvent,
8
8
  ITelemetryBaseLogger,
9
- ITelemetryProperties,
9
+ ITelemetryBaseProperties,
10
10
  } from "@fluidframework/core-interfaces";
11
11
  import { performance } from "@fluid-internal/client-utils";
12
12
 
@@ -77,7 +77,7 @@ export class DebugLogger implements ITelemetryBaseLogger {
77
77
  * @param event - the event to send
78
78
  */
79
79
  public send(event: ITelemetryBaseEvent): void {
80
- const newEvent: ITelemetryProperties = { ...event };
80
+ const newEvent: ITelemetryBaseProperties = { ...event };
81
81
  const isError = newEvent.category === "error";
82
82
  let logger = isError ? this.debugErr : this.debug;
83
83
 
@@ -7,8 +7,7 @@ import { v4 as uuid } from "uuid";
7
7
  import {
8
8
  IThrottlingWarning,
9
9
  IEventProvider,
10
- ITelemetryProperties,
11
- ITelemetryErrorEvent,
10
+ ITelemetryBaseProperties,
12
11
  type ITelemetryBaseEvent,
13
12
  } from "@fluidframework/core-interfaces";
14
13
  import {
@@ -29,6 +28,7 @@ import {
29
28
  DataCorruptionError,
30
29
  UsageError,
31
30
  type ITelemetryGenericEventExt,
31
+ type ITelemetryErrorEventExt,
32
32
  } from "@fluidframework/telemetry-utils";
33
33
  import {
34
34
  IDocumentDeltaStorageService,
@@ -49,9 +49,9 @@ import {
49
49
  IConnectionManager,
50
50
  IConnectionManagerFactoryArgs,
51
51
  IConnectionStateChangeReason,
52
- } from "./contracts";
53
- import { DeltaQueue } from "./deltaQueue";
54
- import { ThrottlingWarning } from "./error";
52
+ } from "./contracts.js";
53
+ import { DeltaQueue } from "./deltaQueue.js";
54
+ import { ThrottlingWarning } from "./error.js";
55
55
 
56
56
  export interface IConnectionArgs {
57
57
  mode?: ConnectionMode;
@@ -361,7 +361,7 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
361
361
  assert(this.messageBuffer.length === 0, 0x3cc /* reentrancy */);
362
362
  }
363
363
 
364
- public get connectionProps(): ITelemetryProperties {
364
+ public get connectionProps(): ITelemetryBaseProperties {
365
365
  return {
366
366
  sequenceNumber: this.lastSequenceNumber,
367
367
  opsSize: this.opsSize > 0 ? this.opsSize : undefined,
@@ -376,7 +376,7 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
376
376
  * we stop processing ops that results in no processing join op and thus moving to connected state)
377
377
  * @param event - Event to log.
378
378
  */
379
- public logConnectionIssue(event: ITelemetryErrorEvent) {
379
+ public logConnectionIssue(event: ITelemetryErrorEventExt) {
380
380
  assert(this.connectionManager.connected, 0x238 /* "called only in connected state" */);
381
381
 
382
382
  const pendingSorted = this.pending.sort((a, b) => a.sequenceNumber - b.sequenceNumber);
@@ -797,7 +797,7 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
797
797
 
798
798
  private disconnectHandler(reason: IConnectionStateChangeReason) {
799
799
  this.messageBuffer.length = 0;
800
- this.emit("disconnect", reason);
800
+ this.emit("disconnect", reason.text, reason.error);
801
801
  }
802
802
 
803
803
  /**
package/src/error.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { ITelemetryProperties, IThrottlingWarning } from "@fluidframework/core-interfaces";
6
+ import { ITelemetryBaseProperties, IThrottlingWarning } from "@fluidframework/core-interfaces";
7
7
  import { ContainerErrorTypes } from "@fluidframework/container-definitions";
8
8
  import {
9
9
  IFluidErrorBase,
@@ -24,7 +24,7 @@ export class ThrottlingWarning extends LoggingError implements IThrottlingWarnin
24
24
  private constructor(
25
25
  message: string,
26
26
  readonly retryAfterSeconds: number,
27
- props?: ITelemetryProperties,
27
+ props?: ITelemetryBaseProperties,
28
28
  ) {
29
29
  super(message, props);
30
30
  }
package/src/index.ts CHANGED
@@ -3,8 +3,8 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- export { ConnectionState } from "./connectionState";
7
- export { IContainerExperimental, waitContainerToCatchUp } from "./container";
6
+ export { ConnectionState } from "./connectionState.js";
7
+ export { IContainerExperimental, waitContainerToCatchUp } from "./container.js";
8
8
  export {
9
9
  ICodeDetailsLoader,
10
10
  IDetachedBlobStorage,
@@ -13,10 +13,10 @@ export {
13
13
  ILoaderProps,
14
14
  ILoaderServices,
15
15
  Loader,
16
- } from "./loader";
16
+ } from "./loader.js";
17
17
  export {
18
18
  isLocationRedirectionError,
19
19
  resolveWithLocationRedirectionHandling,
20
- } from "./location-redirection-utilities";
21
- export { IProtocolHandler, ProtocolHandlerBuilder } from "./protocol";
22
- export { tryParseCompatibleResolvedUrl, IParsedUrl } from "./utils";
20
+ } from "./location-redirection-utilities/index.js";
21
+ export { IProtocolHandler, ProtocolHandlerBuilder } from "./protocol.js";
22
+ export { tryParseCompatibleResolvedUrl, IParsedUrl } from "./utils.js";
package/src/loader.ts CHANGED
@@ -36,11 +36,11 @@ import {
36
36
  IUrlResolver,
37
37
  } from "@fluidframework/driver-definitions";
38
38
  import { IClientDetails } from "@fluidframework/protocol-definitions";
39
- import { Container, IPendingContainerState } from "./container";
40
- import { IParsedUrl, tryParseCompatibleResolvedUrl } from "./utils";
41
- import { pkgVersion } from "./packageVersion";
42
- import { ProtocolHandlerBuilder } from "./protocol";
43
- import { DebugLogger } from "./debugLogger";
39
+ import { Container, IPendingContainerState } from "./container.js";
40
+ import { tryParseCompatibleResolvedUrl } from "./utils.js";
41
+ import { pkgVersion } from "./packageVersion.js";
42
+ import { ProtocolHandlerBuilder } from "./protocol.js";
43
+ import { DebugLogger } from "./debugLogger.js";
44
44
 
45
45
  function ensureResolvedUrlDefined(
46
46
  resolved: IResolvedUrl | undefined,
@@ -108,7 +108,7 @@ export interface IFluidModuleWithDetails {
108
108
  }
109
109
 
110
110
  /**
111
- * @deprecated ICodeDetailsLoader interface is moved to {@link @fluidframework/container-definition#ICodeDetailsLoader}
111
+ * @deprecated ICodeDetailsLoader interface is moved to {@link @fluidframework/container-definitions#ICodeDetailsLoader}
112
112
  * to have code loading modules in one package. #8193
113
113
  * Fluid code loader resolves a code module matching the document schema, i.e. code details, such as
114
114
  * a package name and package version range.
@@ -332,18 +332,17 @@ export class Loader implements IHostLoader {
332
332
  public async resolve(request: IRequest, pendingLocalState?: string): Promise<IContainer> {
333
333
  const eventName = pendingLocalState === undefined ? "Resolve" : "ResolveWithPendingState";
334
334
  return PerformanceEvent.timedExecAsync(this.mc.logger, { eventName }, async () => {
335
- const resolved = await this.resolveCore(
335
+ return this.resolveCore(
336
336
  request,
337
337
  pendingLocalState !== undefined ? JSON.parse(pendingLocalState) : undefined,
338
338
  );
339
- return resolved.container;
340
339
  });
341
340
  }
342
341
 
343
342
  private async resolveCore(
344
343
  request: IRequest,
345
344
  pendingLocalState?: IPendingContainerState,
346
- ): Promise<{ container: Container; parsed: IParsedUrl }> {
345
+ ): Promise<Container> {
347
346
  const resolvedAsFluid = await this.services.urlResolver.resolve(request);
348
347
  ensureResolvedUrlDefined(resolvedAsFluid);
349
348
 
@@ -387,10 +386,7 @@ export class Loader implements IHostLoader {
387
386
  throw new UsageError('opsBeforeReturn must be set to "sequenceNumber"');
388
387
  }
389
388
 
390
- return {
391
- container: await this.loadContainer(request, resolvedAsFluid, pendingLocalState),
392
- parsed,
393
- };
389
+ return this.loadContainer(request, resolvedAsFluid, pendingLocalState);
394
390
  }
395
391
 
396
392
  private async loadContainer(
@@ -6,4 +6,4 @@
6
6
  export {
7
7
  isLocationRedirectionError,
8
8
  resolveWithLocationRedirectionHandling,
9
- } from "./resolveWithLocationRedirection";
9
+ } from "./resolveWithLocationRedirection.js";
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/container-loader";
9
- export const pkgVersion = "2.0.0-rc.1.0.6";
9
+ export const pkgVersion = "2.0.0-rc.2.0.1";
@@ -19,14 +19,12 @@ export class ProtocolTreeStorageService implements IDocumentStorageService, IDis
19
19
  public get policies() {
20
20
  return this.internalStorageService.policies;
21
21
  }
22
- public get repositoryUrl() {
23
- return this.internalStorageService.repositoryUrl;
24
- }
25
22
  public get disposed() {
26
23
  return this.internalStorageService.disposed;
27
24
  }
28
25
 
29
26
  getSnapshotTree = this.internalStorageService.getSnapshotTree.bind(this.internalStorageService);
27
+ getSnapshot = this.internalStorageService.getSnapshot?.bind(this.internalStorageService);
30
28
  getVersions = this.internalStorageService.getVersions.bind(this.internalStorageService);
31
29
  createBlob = this.internalStorageService.createBlob.bind(this.internalStorageService);
32
30
  readBlob = this.internalStorageService.readBlob.bind(this.internalStorageService);
@@ -8,6 +8,8 @@ import {
8
8
  FetchSource,
9
9
  IDocumentStorageService,
10
10
  IDocumentStorageServicePolicies,
11
+ ISnapshot,
12
+ ISnapshotFetchOptions,
11
13
  ISummaryContext,
12
14
  } from "@fluidframework/driver-definitions";
13
15
  import {
@@ -18,7 +20,7 @@ import {
18
20
  IVersion,
19
21
  } from "@fluidframework/protocol-definitions";
20
22
  import { IDisposable } from "@fluidframework/core-interfaces";
21
- import { GenericError, ITelemetryLoggerExt } from "@fluidframework/telemetry-utils";
23
+ import { GenericError, ITelemetryLoggerExt, UsageError } from "@fluidframework/telemetry-utils";
22
24
  import { runWithRetry } from "@fluidframework/driver-utils";
23
25
 
24
26
  export class RetriableDocumentStorageService implements IDocumentStorageService, IDisposable {
@@ -44,13 +46,6 @@ export class RetriableDocumentStorageService implements IDocumentStorageService,
44
46
  this._disposed = true;
45
47
  }
46
48
 
47
- public get repositoryUrl(): string {
48
- if (this.internalStorageService) {
49
- return this.internalStorageService.repositoryUrl;
50
- }
51
- throw new Error("storage service not yet instantiated");
52
- }
53
-
54
49
  public async getSnapshotTree(
55
50
  version?: IVersion,
56
51
  scenarioName?: string,
@@ -64,6 +59,21 @@ export class RetriableDocumentStorageService implements IDocumentStorageService,
64
59
  );
65
60
  }
66
61
 
62
+ public async getSnapshot(snapshotFetchOptions?: ISnapshotFetchOptions): Promise<ISnapshot> {
63
+ return this.runWithRetry(
64
+ async () =>
65
+ this.internalStorageServiceP.then(async (s) => {
66
+ if (s.getSnapshot !== undefined) {
67
+ return s.getSnapshot(snapshotFetchOptions);
68
+ }
69
+ throw new UsageError(
70
+ "getSnapshot api should exist on internal storage in RetriableDocStorageService class",
71
+ );
72
+ }),
73
+ "storage_getSnapshot",
74
+ );
75
+ }
76
+
67
77
  public async readBlob(id: string): Promise<ArrayBufferLike> {
68
78
  return this.runWithRetry(
69
79
  async () => this.internalStorageServiceP.then(async (s) => s.readBlob(id)),
@@ -0,0 +1,217 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import {
7
+ ISequencedDocumentMessage,
8
+ ISnapshotTree,
9
+ IVersion,
10
+ } from "@fluidframework/protocol-definitions";
11
+ import { IGetPendingLocalStateProps, IRuntime } from "@fluidframework/container-definitions";
12
+ import {
13
+ ITelemetryLoggerExt,
14
+ MonitoringContext,
15
+ PerformanceEvent,
16
+ UsageError,
17
+ createChildMonitoringContext,
18
+ } from "@fluidframework/telemetry-utils";
19
+ import { assert } from "@fluidframework/core-utils";
20
+ import {
21
+ IDocumentStorageService,
22
+ IResolvedUrl,
23
+ ISnapshot,
24
+ } from "@fluidframework/driver-definitions";
25
+ import { isInstanceOfISnapshot } from "@fluidframework/driver-utils";
26
+ import { ISerializableBlobContents, getBlobContentsFromTree } from "./containerStorageAdapter.js";
27
+ import { IPendingContainerState } from "./container.js";
28
+
29
+ export class SerializedStateManager {
30
+ private readonly processedOps: ISequencedDocumentMessage[] = [];
31
+ private snapshot:
32
+ | {
33
+ tree: ISnapshotTree;
34
+ blobs: ISerializableBlobContents;
35
+ }
36
+ | undefined;
37
+ private readonly mc: MonitoringContext;
38
+
39
+ constructor(
40
+ private readonly pendingLocalState: IPendingContainerState | undefined,
41
+ subLogger: ITelemetryLoggerExt,
42
+ private readonly storageAdapter: Pick<
43
+ IDocumentStorageService,
44
+ "readBlob" | "getSnapshotTree" | "getSnapshot" | "getVersions"
45
+ >,
46
+ private readonly _offlineLoadEnabled: boolean,
47
+ ) {
48
+ this.mc = createChildMonitoringContext({
49
+ logger: subLogger,
50
+ namespace: "serializedStateManager",
51
+ });
52
+ }
53
+
54
+ public get offlineLoadEnabled(): boolean {
55
+ return this._offlineLoadEnabled;
56
+ }
57
+
58
+ public addProcessedOp(message: ISequencedDocumentMessage) {
59
+ if (this.offlineLoadEnabled) {
60
+ this.processedOps.push(message);
61
+ }
62
+ }
63
+
64
+ private async getVersion(version: string | null): Promise<IVersion | undefined> {
65
+ const versions = await this.storageAdapter.getVersions(version, 1);
66
+ return versions[0];
67
+ }
68
+
69
+ public async fetchSnapshot(
70
+ specifiedVersion: string | undefined,
71
+ supportGetSnapshotApi: boolean | undefined,
72
+ ) {
73
+ const { snapshot, version } =
74
+ this.pendingLocalState === undefined
75
+ ? await this.fetchSnapshotCore(specifiedVersion, supportGetSnapshotApi)
76
+ : { snapshot: this.pendingLocalState.baseSnapshot, version: undefined };
77
+ const snapshotTree: ISnapshotTree | undefined = isInstanceOfISnapshot(snapshot)
78
+ ? snapshot.snapshotTree
79
+ : snapshot;
80
+ if (this.pendingLocalState) {
81
+ this.snapshot = {
82
+ tree: this.pendingLocalState.baseSnapshot,
83
+ blobs: this.pendingLocalState.snapshotBlobs,
84
+ };
85
+ } else {
86
+ assert(snapshotTree !== undefined, 0x8e4 /* Snapshot should exist */);
87
+ // non-interactive clients will not have any pending state we want to save
88
+ if (this.offlineLoadEnabled) {
89
+ const blobs = await getBlobContentsFromTree(snapshotTree, this.storageAdapter);
90
+ this.snapshot = { tree: snapshotTree, blobs };
91
+ }
92
+ }
93
+ return { snapshotTree, version };
94
+ }
95
+
96
+ private async fetchSnapshotCore(
97
+ specifiedVersion: string | undefined,
98
+ supportGetSnapshotApi: boolean | undefined,
99
+ ): Promise<{ snapshot?: ISnapshot | ISnapshotTree; version?: IVersion }> {
100
+ if (
101
+ this.mc.config.getBoolean("Fluid.Container.UseLoadingGroupIdForSnapshotFetch") ===
102
+ true &&
103
+ supportGetSnapshotApi === true
104
+ ) {
105
+ const snapshot =
106
+ (await this.storageAdapter.getSnapshot?.({
107
+ versionId: specifiedVersion,
108
+ })) ?? undefined;
109
+ const version: IVersion | undefined =
110
+ snapshot?.snapshotTree.id === undefined
111
+ ? undefined
112
+ : {
113
+ id: snapshot.snapshotTree.id,
114
+ treeId: snapshot.snapshotTree.id,
115
+ };
116
+
117
+ if (snapshot === undefined && specifiedVersion !== undefined) {
118
+ this.mc.logger.sendErrorEvent({
119
+ eventName: "getSnapshotTreeFailed",
120
+ id: specifiedVersion,
121
+ });
122
+ // Not sure if this should be here actually
123
+ } else if (snapshot !== undefined && version?.id === undefined) {
124
+ this.mc.logger.sendErrorEvent({
125
+ eventName: "getSnapshotFetchedTreeWithoutVersionId",
126
+ hasVersion: version !== undefined, // if hasVersion is true, this means that the contract with the service was broken.
127
+ });
128
+ }
129
+ return { snapshot, version };
130
+ }
131
+ return this.fetchSnapshotTree(specifiedVersion);
132
+ }
133
+
134
+ /**
135
+ * Get the most recent snapshot, or a specific version.
136
+ * @param specifiedVersion - The specific version of the snapshot to retrieve
137
+ * @returns The snapshot requested, or the latest snapshot if no version was specified, plus version ID
138
+ */
139
+ private async fetchSnapshotTree(
140
+ specifiedVersion: string | undefined,
141
+ ): Promise<{ snapshot?: ISnapshotTree; version?: IVersion | undefined }> {
142
+ const version = await this.getVersion(specifiedVersion ?? null);
143
+
144
+ if (version === undefined && specifiedVersion !== undefined) {
145
+ // We should have a defined version to load from if specified version requested
146
+ this.mc.logger.sendErrorEvent({
147
+ eventName: "NoVersionFoundWhenSpecified",
148
+ id: specifiedVersion,
149
+ });
150
+ }
151
+ const snapshot = (await this.storageAdapter.getSnapshotTree(version)) ?? undefined;
152
+
153
+ if (snapshot === undefined && version !== undefined) {
154
+ this.mc.logger.sendErrorEvent({ eventName: "getSnapshotTreeFailed", id: version.id });
155
+ } else if (snapshot !== undefined && version?.id === undefined) {
156
+ this.mc.logger.sendErrorEvent({
157
+ eventName: "getSnapshotFetchedTreeWithoutVersionId",
158
+ hasVersion: version !== undefined, // if hasVersion is true, this means that the contract with the service was broken.
159
+ });
160
+ }
161
+ return { snapshot, version };
162
+ }
163
+
164
+ /**
165
+ * This method is only meant to be used by Container.attach() to set the initial
166
+ * base snapshot when attaching.
167
+ * @param snapshot - snapshot and blobs collected while attaching
168
+ */
169
+ public setSnapshot(
170
+ snapshot:
171
+ | {
172
+ tree: ISnapshotTree;
173
+ blobs: ISerializableBlobContents;
174
+ }
175
+ | undefined,
176
+ ) {
177
+ this.snapshot = snapshot;
178
+ }
179
+
180
+ public async getPendingLocalStateCore(
181
+ props: IGetPendingLocalStateProps,
182
+ clientId: string | undefined,
183
+ runtime: Pick<IRuntime, "getPendingLocalState">,
184
+ resolvedUrl: IResolvedUrl,
185
+ ) {
186
+ return PerformanceEvent.timedExecAsync(
187
+ this.mc.logger,
188
+ {
189
+ eventName: "getPendingLocalState",
190
+ notifyImminentClosure: props.notifyImminentClosure,
191
+ processedOpsSize: this.processedOps.length,
192
+ clientId,
193
+ },
194
+ async () => {
195
+ if (!this.offlineLoadEnabled) {
196
+ throw new UsageError(
197
+ "Can't get pending local state unless offline load is enabled",
198
+ );
199
+ }
200
+ assert(this.snapshot !== undefined, 0x8e5 /* no base data */);
201
+ const pendingRuntimeState = await runtime.getPendingLocalState(props);
202
+ const pendingState: IPendingContainerState = {
203
+ attached: true,
204
+ pendingRuntimeState,
205
+ baseSnapshot: this.snapshot.tree,
206
+ snapshotBlobs: this.snapshot.blobs,
207
+ savedOps: this.processedOps,
208
+ url: resolvedUrl.url,
209
+ // no need to save this if there is no pending runtime state
210
+ clientId: pendingRuntimeState !== undefined ? clientId : undefined,
211
+ };
212
+
213
+ return JSON.stringify(pendingState);
214
+ },
215
+ );
216
+ }
217
+ }