@fluidframework/container-loader 2.0.0-dev-rc.4.0.0.261659 → 2.0.0-dev-rc.5.0.0.265721

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 (146) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/attachment.d.ts +3 -2
  3. package/dist/attachment.d.ts.map +1 -1
  4. package/dist/attachment.js +5 -5
  5. package/dist/attachment.js.map +1 -1
  6. package/dist/audience.d.ts +2 -1
  7. package/dist/audience.d.ts.map +1 -1
  8. package/dist/audience.js.map +1 -1
  9. package/dist/catchUpMonitor.d.ts +1 -1
  10. package/dist/catchUpMonitor.d.ts.map +1 -1
  11. package/dist/catchUpMonitor.js.map +1 -1
  12. package/dist/connectionManager.d.ts +2 -1
  13. package/dist/connectionManager.d.ts.map +1 -1
  14. package/dist/connectionManager.js +28 -28
  15. package/dist/connectionManager.js.map +1 -1
  16. package/dist/connectionStateHandler.d.ts +2 -2
  17. package/dist/connectionStateHandler.d.ts.map +1 -1
  18. package/dist/connectionStateHandler.js +7 -3
  19. package/dist/connectionStateHandler.js.map +1 -1
  20. package/dist/container.d.ts +16 -3
  21. package/dist/container.d.ts.map +1 -1
  22. package/dist/container.js +28 -13
  23. package/dist/container.js.map +1 -1
  24. package/dist/containerContext.d.ts +2 -2
  25. package/dist/containerContext.d.ts.map +1 -1
  26. package/dist/containerContext.js.map +1 -1
  27. package/dist/containerStorageAdapter.d.ts.map +1 -1
  28. package/dist/containerStorageAdapter.js +2 -2
  29. package/dist/containerStorageAdapter.js.map +1 -1
  30. package/dist/contracts.d.ts +2 -2
  31. package/dist/contracts.d.ts.map +1 -1
  32. package/dist/contracts.js.map +1 -1
  33. package/dist/debugLogger.js.map +1 -1
  34. package/dist/deltaManager.d.ts +3 -2
  35. package/dist/deltaManager.d.ts.map +1 -1
  36. package/dist/deltaManager.js +30 -30
  37. package/dist/deltaManager.js.map +1 -1
  38. package/dist/deltaQueue.d.ts +1 -1
  39. package/dist/deltaQueue.d.ts.map +1 -1
  40. package/dist/deltaQueue.js.map +1 -1
  41. package/dist/disposal.js.map +1 -1
  42. package/dist/loadPaused.js.map +1 -1
  43. package/dist/loader.d.ts.map +1 -1
  44. package/dist/loader.js +1 -1
  45. package/dist/loader.js.map +1 -1
  46. package/dist/location-redirection-utilities/resolveWithLocationRedirection.d.ts.map +1 -1
  47. package/dist/location-redirection-utilities/resolveWithLocationRedirection.js +4 -4
  48. package/dist/location-redirection-utilities/resolveWithLocationRedirection.js.map +1 -1
  49. package/dist/noopHeuristic.js.map +1 -1
  50. package/dist/packageVersion.d.ts +1 -1
  51. package/dist/packageVersion.js +1 -1
  52. package/dist/packageVersion.js.map +1 -1
  53. package/dist/protocol.d.ts +2 -2
  54. package/dist/protocol.d.ts.map +1 -1
  55. package/dist/protocol.js.map +1 -1
  56. package/dist/retriableDocumentStorageService.js.map +1 -1
  57. package/dist/serializedStateManager.d.ts +70 -8
  58. package/dist/serializedStateManager.d.ts.map +1 -1
  59. package/dist/serializedStateManager.js +98 -28
  60. package/dist/serializedStateManager.js.map +1 -1
  61. package/dist/utils.d.ts +11 -1
  62. package/dist/utils.d.ts.map +1 -1
  63. package/dist/utils.js +29 -14
  64. package/dist/utils.js.map +1 -1
  65. package/lib/attachment.d.ts +3 -2
  66. package/lib/attachment.d.ts.map +1 -1
  67. package/lib/attachment.js +5 -5
  68. package/lib/attachment.js.map +1 -1
  69. package/lib/audience.d.ts +2 -1
  70. package/lib/audience.d.ts.map +1 -1
  71. package/lib/audience.js.map +1 -1
  72. package/lib/catchUpMonitor.d.ts +1 -1
  73. package/lib/catchUpMonitor.d.ts.map +1 -1
  74. package/lib/catchUpMonitor.js.map +1 -1
  75. package/lib/connectionManager.d.ts +2 -1
  76. package/lib/connectionManager.d.ts.map +1 -1
  77. package/lib/connectionManager.js +5 -5
  78. package/lib/connectionManager.js.map +1 -1
  79. package/lib/connectionStateHandler.d.ts +2 -2
  80. package/lib/connectionStateHandler.d.ts.map +1 -1
  81. package/lib/connectionStateHandler.js +7 -3
  82. package/lib/connectionStateHandler.js.map +1 -1
  83. package/lib/container.d.ts +16 -3
  84. package/lib/container.d.ts.map +1 -1
  85. package/lib/container.js +29 -14
  86. package/lib/container.js.map +1 -1
  87. package/lib/containerContext.d.ts +2 -2
  88. package/lib/containerContext.d.ts.map +1 -1
  89. package/lib/containerContext.js.map +1 -1
  90. package/lib/containerStorageAdapter.d.ts.map +1 -1
  91. package/lib/containerStorageAdapter.js +2 -2
  92. package/lib/containerStorageAdapter.js.map +1 -1
  93. package/lib/contracts.d.ts +2 -2
  94. package/lib/contracts.d.ts.map +1 -1
  95. package/lib/contracts.js +1 -1
  96. package/lib/contracts.js.map +1 -1
  97. package/lib/debugLogger.js.map +1 -1
  98. package/lib/deltaManager.d.ts +3 -2
  99. package/lib/deltaManager.d.ts.map +1 -1
  100. package/lib/deltaManager.js +8 -8
  101. package/lib/deltaManager.js.map +1 -1
  102. package/lib/deltaQueue.d.ts +1 -1
  103. package/lib/deltaQueue.d.ts.map +1 -1
  104. package/lib/deltaQueue.js.map +1 -1
  105. package/lib/disposal.js.map +1 -1
  106. package/lib/loadPaused.js.map +1 -1
  107. package/lib/loader.d.ts.map +1 -1
  108. package/lib/loader.js +2 -2
  109. package/lib/loader.js.map +1 -1
  110. package/lib/location-redirection-utilities/resolveWithLocationRedirection.d.ts.map +1 -1
  111. package/lib/location-redirection-utilities/resolveWithLocationRedirection.js +1 -1
  112. package/lib/location-redirection-utilities/resolveWithLocationRedirection.js.map +1 -1
  113. package/lib/noopHeuristic.js.map +1 -1
  114. package/lib/packageVersion.d.ts +1 -1
  115. package/lib/packageVersion.js +1 -1
  116. package/lib/packageVersion.js.map +1 -1
  117. package/lib/protocol.d.ts +2 -2
  118. package/lib/protocol.d.ts.map +1 -1
  119. package/lib/protocol.js.map +1 -1
  120. package/lib/retriableDocumentStorageService.js.map +1 -1
  121. package/lib/serializedStateManager.d.ts +70 -8
  122. package/lib/serializedStateManager.d.ts.map +1 -1
  123. package/lib/serializedStateManager.js +99 -29
  124. package/lib/serializedStateManager.js.map +1 -1
  125. package/lib/tsdoc-metadata.json +1 -1
  126. package/lib/utils.d.ts +11 -1
  127. package/lib/utils.d.ts.map +1 -1
  128. package/lib/utils.js +15 -1
  129. package/lib/utils.js.map +1 -1
  130. package/package.json +19 -27
  131. package/src/attachment.ts +12 -13
  132. package/src/audience.ts +2 -5
  133. package/src/catchUpMonitor.ts +1 -1
  134. package/src/connectionManager.ts +4 -6
  135. package/src/connectionStateHandler.ts +10 -6
  136. package/src/container.ts +38 -14
  137. package/src/containerContext.ts +1 -1
  138. package/src/containerStorageAdapter.ts +5 -2
  139. package/src/contracts.ts +5 -4
  140. package/src/deltaManager.ts +3 -3
  141. package/src/deltaQueue.ts +1 -1
  142. package/src/loader.ts +5 -2
  143. package/src/location-redirection-utilities/resolveWithLocationRedirection.ts +1 -1
  144. package/src/packageVersion.ts +1 -1
  145. package/src/serializedStateManager.ts +137 -36
  146. package/src/utils.ts +19 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/container-loader",
3
- "version": "2.0.0-dev-rc.4.0.0.261659",
3
+ "version": "2.0.0-dev-rc.5.0.0.265721",
4
4
  "description": "Fluid container loader",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -117,15 +117,15 @@
117
117
  "temp-directory": "nyc/.nyc_output"
118
118
  },
119
119
  "dependencies": {
120
- "@fluid-internal/client-utils": "2.0.0-dev-rc.4.0.0.261659",
121
- "@fluidframework/container-definitions": "2.0.0-dev-rc.4.0.0.261659",
122
- "@fluidframework/core-interfaces": "2.0.0-dev-rc.4.0.0.261659",
123
- "@fluidframework/core-utils": "2.0.0-dev-rc.4.0.0.261659",
124
- "@fluidframework/driver-definitions": "2.0.0-dev-rc.4.0.0.261659",
125
- "@fluidframework/driver-utils": "2.0.0-dev-rc.4.0.0.261659",
120
+ "@fluid-internal/client-utils": "2.0.0-dev-rc.5.0.0.265721",
121
+ "@fluidframework/container-definitions": "2.0.0-dev-rc.5.0.0.265721",
122
+ "@fluidframework/core-interfaces": "2.0.0-dev-rc.5.0.0.265721",
123
+ "@fluidframework/core-utils": "2.0.0-dev-rc.5.0.0.265721",
124
+ "@fluidframework/driver-definitions": "2.0.0-dev-rc.5.0.0.265721",
125
+ "@fluidframework/driver-utils": "2.0.0-dev-rc.5.0.0.265721",
126
126
  "@fluidframework/protocol-base": "^4.0.0",
127
127
  "@fluidframework/protocol-definitions": "^3.2.0",
128
- "@fluidframework/telemetry-utils": "2.0.0-dev-rc.4.0.0.261659",
128
+ "@fluidframework/telemetry-utils": "2.0.0-dev-rc.5.0.0.265721",
129
129
  "@ungap/structured-clone": "^1.2.0",
130
130
  "debug": "^4.3.4",
131
131
  "double-ended-queue": "^2.1.0-0",
@@ -134,14 +134,14 @@
134
134
  "devDependencies": {
135
135
  "@arethetypeswrong/cli": "^0.15.2",
136
136
  "@biomejs/biome": "^1.6.2",
137
- "@fluid-internal/mocha-test-setup": "2.0.0-dev-rc.4.0.0.261659",
138
- "@fluid-private/test-loader-utils": "2.0.0-dev-rc.4.0.0.261659",
139
- "@fluid-tools/build-cli": "0.38.0-259537",
137
+ "@fluid-internal/mocha-test-setup": "2.0.0-dev-rc.5.0.0.265721",
138
+ "@fluid-private/test-loader-utils": "2.0.0-dev-rc.5.0.0.265721",
139
+ "@fluid-tools/build-cli": "^0.39.0-264124",
140
140
  "@fluidframework/build-common": "^2.0.3",
141
- "@fluidframework/build-tools": "0.38.0-259537",
142
- "@fluidframework/container-loader-previous": "npm:@fluidframework/container-loader@2.0.0-rc.3.0.0",
141
+ "@fluidframework/build-tools": "^0.39.0-264124",
142
+ "@fluidframework/container-loader-previous": "npm:@fluidframework/container-loader@2.0.0-rc.4.0.0",
143
143
  "@fluidframework/eslint-config-fluid": "^5.1.0",
144
- "@microsoft/api-extractor": "^7.42.3",
144
+ "@microsoft/api-extractor": "^7.43.1",
145
145
  "@types/debug": "^4.1.5",
146
146
  "@types/double-ended-queue": "^2.1.0",
147
147
  "@types/mocha": "^9.1.1",
@@ -160,19 +160,10 @@
160
160
  "prettier": "~3.0.3",
161
161
  "rimraf": "^4.4.0",
162
162
  "sinon": "^17.0.1",
163
- "typescript": "~5.1.6"
163
+ "typescript": "~5.3.3"
164
164
  },
165
165
  "typeValidation": {
166
- "broken": {
167
- "InterfaceDeclaration_IProtocolHandler": {
168
- "forwardCompat": false,
169
- "backCompat": false
170
- },
171
- "InterfaceDeclaration_IContainerExperimental": {
172
- "forwardCompat": false,
173
- "backCompat": false
174
- }
175
- }
166
+ "broken": {}
176
167
  },
177
168
  "scripts": {
178
169
  "api": "fluid-build . --task api",
@@ -198,14 +189,15 @@
198
189
  "format:prettier": "prettier --write . --cache --ignore-path ../../../.prettierignore",
199
190
  "lint": "fluid-build . --task lint",
200
191
  "lint:fix": "fluid-build . --task eslint:fix --task format",
192
+ "place:cjs:package-stub": "copyfiles -f ../../../common/build/build-common/src/cjs/package.json ./dist",
201
193
  "test": "npm run test:mocha",
202
194
  "test:coverage": "c8 npm test",
203
195
  "test:mocha": "npm run test:mocha:esm && echo skipping cjs to avoid overhead - npm run test:mocha:cjs",
204
196
  "test:mocha:cjs": "mocha --recursive \"dist/test/**/*.spec.*js\" --exit",
205
197
  "test:mocha:esm": "mocha --recursive \"lib/test/**/*.spec.*js\" --exit",
206
198
  "test:mocha:verbose": "cross-env FLUID_TEST_VERBOSE=1 npm run test:mocha",
207
- "tsc": "fluid-tsc commonjs --project ./tsconfig.cjs.json && copyfiles -f ../../../common/build/build-common/src/cjs/package.json ./dist",
208
- "tsc:watch": "tsc --watch",
199
+ "tsc": "fluid-tsc commonjs --project ./tsconfig.cjs.json && npm run place:cjs:package-stub",
200
+ "tsc:watch": "npm run place:cjs:package-stub && fluid-tsc commonjs --project ./tsconfig.cjs.json --watch",
209
201
  "typetests:gen": "flub generate typetests --dir . -v --publicFallback",
210
202
  "typetests:prepare": "flub typetests --dir . --reset --previous --normalize"
211
203
  }
package/src/attachment.ts CHANGED
@@ -132,19 +132,18 @@ export interface AttachProcessProps {
132
132
  * This method is retriable on failure. Based on the provided initialAttachmentData
133
133
  * this method will resume the attachment process and attempt to complete it.
134
134
  *
135
- * @param props - The data and services necessary to run the attachment process
135
+ * @param AttachProcessProps - The data and services necessary to run the attachment process
136
+ * @returns - The attach summary (only if offline load is enabled), or undefined
136
137
  */
137
- export const runRetriableAttachProcess = async (
138
- props: AttachProcessProps,
139
- ): Promise<SnapshotWithBlobs | undefined> => {
140
- const {
141
- detachedBlobStorage,
142
- createOrGetStorageService,
143
- setAttachmentData,
144
- createAttachmentSummary,
145
- offlineLoadEnabled,
146
- } = props;
147
- let currentData: AttachmentData = props.initialAttachmentData;
138
+ export const runRetriableAttachProcess = async ({
139
+ detachedBlobStorage,
140
+ createOrGetStorageService,
141
+ setAttachmentData,
142
+ createAttachmentSummary,
143
+ offlineLoadEnabled,
144
+ initialAttachmentData,
145
+ }: AttachProcessProps): Promise<SnapshotWithBlobs | undefined> => {
146
+ let currentData: AttachmentData = initialAttachmentData;
148
147
 
149
148
  if (currentData.blobs === undefined) {
150
149
  // If attachment blobs were uploaded in detached state we will go through a different attach flow
@@ -161,7 +160,7 @@ export const runRetriableAttachProcess = async (
161
160
  }
162
161
  : {
163
162
  state: AttachState.Attaching,
164
- summary: props.createAttachmentSummary(),
163
+ summary: createAttachmentSummary(),
165
164
  blobs: "none",
166
165
  };
167
166
  setAttachmentData(currentData);
package/src/audience.ts CHANGED
@@ -4,11 +4,8 @@
4
4
  */
5
5
 
6
6
  import { TypedEventEmitter } from "@fluid-internal/client-utils";
7
- import {
8
- IAudienceEvents,
9
- IAudienceOwner,
10
- ISelf,
11
- } from "@fluidframework/container-definitions/internal";
7
+ import { IAudienceEvents, ISelf } from "@fluidframework/container-definitions";
8
+ import { IAudienceOwner } from "@fluidframework/container-definitions/internal";
12
9
  import { assert } from "@fluidframework/core-utils/internal";
13
10
  import { IClient } from "@fluidframework/protocol-definitions";
14
11
 
@@ -3,7 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { IDeltaManager } from "@fluidframework/container-definitions";
6
+ import { IDeltaManager } from "@fluidframework/container-definitions/internal";
7
7
  import { IDisposable } from "@fluidframework/core-interfaces";
8
8
  import { assert } from "@fluidframework/core-utils/internal";
9
9
  import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
@@ -4,18 +4,16 @@
4
4
  */
5
5
 
6
6
  import { TypedEventEmitter, performance } from "@fluid-internal/client-utils";
7
- import {
8
- ICriticalContainerError,
9
- IDeltaQueue,
10
- ReadOnlyInfo,
11
- } from "@fluidframework/container-definitions";
7
+ import { ICriticalContainerError } from "@fluidframework/container-definitions";
8
+ import { IDeltaQueue, ReadOnlyInfo } from "@fluidframework/container-definitions/internal";
12
9
  import { IDisposable, ITelemetryBaseProperties, LogLevel } from "@fluidframework/core-interfaces";
13
10
  import { assert } from "@fluidframework/core-utils/internal";
14
- import { DriverErrorTypes, IAnyDriverError } from "@fluidframework/driver-definitions";
15
11
  import {
16
12
  IDocumentDeltaConnection,
17
13
  IDocumentDeltaConnectionEvents,
18
14
  IDocumentService,
15
+ DriverErrorTypes,
16
+ IAnyDriverError,
19
17
  } from "@fluidframework/driver-definitions/internal";
20
18
  import {
21
19
  calculateMaxWaitTime,
@@ -3,10 +3,10 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { IDeltaManager } from "@fluidframework/container-definitions";
6
+ import { IDeltaManager } from "@fluidframework/container-definitions/internal";
7
7
  import { ITelemetryBaseProperties } from "@fluidframework/core-interfaces";
8
8
  import { assert, Timer } from "@fluidframework/core-utils/internal";
9
- import { IAnyDriverError } from "@fluidframework/driver-definitions";
9
+ import { IAnyDriverError } from "@fluidframework/driver-definitions/internal";
10
10
  import { IClient, ISequencedClient } from "@fluidframework/protocol-definitions";
11
11
  import {
12
12
  type TelemetryEventCategory,
@@ -660,9 +660,6 @@ class ConnectionStateHandler implements IConnectionStateHandler {
660
660
  }
661
661
  this._clientId = this.pendingClientId;
662
662
  } else if (value === ConnectionState.Disconnected) {
663
- // Clear pending state immediately to prepare for reconnect
664
- this._pendingClientId = undefined;
665
-
666
663
  if (this.joinTimer.hasTimer) {
667
664
  this.stopjoinTimer();
668
665
  }
@@ -691,8 +688,15 @@ class ConnectionStateHandler implements IConnectionStateHandler {
691
688
  }
692
689
  }
693
690
 
694
- // Report transition before we propagate event across layers
691
+ // Report transition
695
692
  this.handler.connectionStateChanged(this._connectionState, oldState, reason);
693
+
694
+ // Clear pending state immediately to prepare for reconnect
695
+ // Do it after calling connectionStateChanged() above, such that our telemetry contains pendingClientId on disconnect events
696
+ // and we can pair attempts to connect with disconnects (that's the only ID we have if connection did not move far enough before being disconnected)
697
+ if (value === ConnectionState.Disconnected) {
698
+ this._pendingClientId = undefined;
699
+ }
696
700
  }
697
701
 
698
702
  protected get membership(): IMembership | undefined {
package/src/container.ts CHANGED
@@ -8,8 +8,6 @@ import {
8
8
  AttachState,
9
9
  IAudience,
10
10
  ICriticalContainerError,
11
- IDeltaManager,
12
- ReadOnlyInfo,
13
11
  } from "@fluidframework/container-definitions";
14
12
  import {
15
13
  ContainerWarning,
@@ -27,6 +25,8 @@ import {
27
25
  IProvideRuntimeFactory,
28
26
  IRuntime,
29
27
  isFluidCodeDetails,
28
+ IDeltaManager,
29
+ ReadOnlyInfo,
30
30
  } from "@fluidframework/container-definitions/internal";
31
31
  import {
32
32
  FluidObject,
@@ -47,6 +47,7 @@ import {
47
47
  IUrlResolver,
48
48
  } from "@fluidframework/driver-definitions/internal";
49
49
  import {
50
+ getSnapshotTree,
50
51
  MessageType2,
51
52
  OnlineStatus,
52
53
  isCombinedAppAndProtocolSummary,
@@ -161,7 +162,7 @@ export interface IContainerLoadProps {
161
162
  readonly loadMode?: IContainerLoadMode;
162
163
 
163
164
  /**
164
- * The pending state serialized from a pervious container instance
165
+ * The pending state serialized from a previous container instance
165
166
  */
166
167
  readonly pendingLocalState?: IPendingContainerState;
167
168
  }
@@ -432,6 +433,8 @@ export class Container
432
433
  /**
433
434
  * Create a new container in a detached state that is initialized with a
434
435
  * snapshot from a previous detached container.
436
+ * @param createProps - Config options for this new container instance
437
+ * @param snapshot - A stringified {@link IPendingDetachedContainerState}, e.g. generated via {@link serialize}
435
438
  */
436
439
  public static async rehydrateDetachedFromSnapshot(
437
440
  createProps: IContainerCreateProps,
@@ -509,7 +512,10 @@ export class Container
509
512
  // This is done by holding ops and signals until the end of load sequence
510
513
  // (calling this.handleDeltaConnectionArg() after setLoaded() call)
511
514
  // If this assert fires, it means our logic managing connection flow is wrong, and the logic below is also wrong.
512
- assert(this.connectionState !== ConnectionState.Connected, "not connected yet");
515
+ assert(
516
+ this.connectionState !== ConnectionState.Connected,
517
+ 0x969 /* not connected yet */,
518
+ );
513
519
 
514
520
  // Propagate current connection state through the system.
515
521
  const readonly = this.readOnlyInfo.readonly ?? false;
@@ -521,7 +527,7 @@ export class Container
521
527
  const cm = this._deltaManager.connectionManager;
522
528
  if (cm.connected) {
523
529
  const details = cm.connectionDetails;
524
- assert(details !== undefined, "should have details if connected");
530
+ assert(details !== undefined, 0x96a /* should have details if connected */);
525
531
  this.connectionStateHandler.receivedConnectEvent(details);
526
532
  }
527
533
  }
@@ -895,7 +901,7 @@ export class Container
895
901
  // state. So we would have to do (in most cases) useless infinite reconnect loop while we are loading.
896
902
  assert(
897
903
  this.loaded,
898
- "connection issues can be raised only after container is loaded",
904
+ 0x96b /* connection issues can be raised only after container is loaded */,
899
905
  );
900
906
 
901
907
  // If this is "write" connection, it took too long to receive join op. But in most cases that's due
@@ -1134,6 +1140,11 @@ export class Container
1134
1140
  return pendingState;
1135
1141
  }
1136
1142
 
1143
+ /**
1144
+ * Serialize current container state required to rehydrate to the same position without dataloss.
1145
+ * Note: The container must already be attached. For detached containers use {@link serialize}
1146
+ * @returns stringified {@link IPendingContainerState} for the container
1147
+ */
1137
1148
  public async getPendingLocalState(): Promise<string> {
1138
1149
  return this.getPendingLocalStateCore({ notifyImminentClosure: false });
1139
1150
  }
@@ -1152,7 +1163,7 @@ export class Container
1152
1163
  this.resolvedUrl !== undefined && this.resolvedUrl.type === "fluid",
1153
1164
  0x0d2 /* "resolved url should be valid Fluid url" */,
1154
1165
  );
1155
- const pendingState = await this.serializedStateManager.getPendingLocalStateCore(
1166
+ const pendingState = await this.serializedStateManager.getPendingLocalState(
1156
1167
  props,
1157
1168
  this.clientId,
1158
1169
  this.runtime,
@@ -1165,6 +1176,12 @@ export class Container
1165
1176
  return this.attachmentData.state;
1166
1177
  }
1167
1178
 
1179
+ /**
1180
+ * Serialize current container state required to rehydrate to the same position without dataloss.
1181
+ * Note: The container must be detached and not closed. For attached containers use
1182
+ * {@link getPendingLocalState} or {@link closeAndGetPendingLocalState}
1183
+ * @returns stringified {@link IPendingDetachedContainerState} for the container
1184
+ */
1168
1185
  public serialize(): string {
1169
1186
  if (this.attachmentData.state === AttachState.Attached || this.closed) {
1170
1187
  throw new UsageError("Container must not be attached or closed.");
@@ -1305,8 +1322,11 @@ export class Container
1305
1322
  throw normalizeErrorAndClose(error);
1306
1323
  });
1307
1324
  }
1325
+
1326
+ // If offline load is enabled, attachP will return the attach summary (in Snapshot format) so we can initialize SerializedStateManager
1308
1327
  const snapshotWithBlobs = await attachP;
1309
1328
  this.serializedStateManager.setInitialSnapshot(snapshotWithBlobs);
1329
+
1310
1330
  if (!this.closed) {
1311
1331
  this.handleDeltaConnectionArg(attachProps?.deltaConnection, {
1312
1332
  fetchOpsFromStorage: false,
@@ -1397,7 +1417,7 @@ export class Container
1397
1417
  // container is not ready yet to receive them. We can hit it only if some internal code call into here,
1398
1418
  // as public API like Container.connect() can be only called when user got back container object, i.e.
1399
1419
  // it is already fully loaded.
1400
- assert(this.loaded, "connect() can be called only in fully loaded state");
1420
+ assert(this.loaded, 0x96c /* connect() can be called only in fully loaded state */);
1401
1421
 
1402
1422
  this.inboundQueuePausedFromInit = false;
1403
1423
  this._deltaManager.inbound.resume();
@@ -1580,10 +1600,11 @@ export class Container
1580
1600
  specifiedVersion,
1581
1601
  supportGetSnapshotApi,
1582
1602
  );
1603
+ const baseSnapshotTree: ISnapshotTree | undefined = getSnapshotTree(baseSnapshot);
1583
1604
  this._loadedFromVersion = version;
1584
1605
  const attributes: IDocumentAttributes = await getDocumentAttributes(
1585
1606
  this.storageAdapter,
1586
- baseSnapshot,
1607
+ baseSnapshotTree,
1587
1608
  );
1588
1609
 
1589
1610
  // If we saved ops, we will replay them and don't need DeltaManager to fetch them
@@ -1621,12 +1642,12 @@ export class Container
1621
1642
  await this.initializeProtocolStateFromSnapshot(
1622
1643
  attributes,
1623
1644
  this.storageAdapter,
1624
- baseSnapshot,
1645
+ baseSnapshotTree,
1625
1646
  );
1626
1647
 
1627
1648
  // If we are loading from pending state, we start with old clientId.
1628
1649
  // We switch to latest connection clientId only after setLoaded().
1629
- assert(this.clientId === undefined, "there should be no clientId yet");
1650
+ assert(this.clientId === undefined, 0x96d /* there should be no clientId yet */);
1630
1651
  if (pendingLocalState?.clientId !== undefined) {
1631
1652
  this.protocolHandler.audience.setCurrentClientId(pendingLocalState?.clientId);
1632
1653
  }
@@ -1635,7 +1656,7 @@ export class Container
1635
1656
  const codeDetails = this.getCodeDetailsFromQuorum();
1636
1657
  await this.instantiateRuntime(
1637
1658
  codeDetails,
1638
- baseSnapshot,
1659
+ baseSnapshotTree,
1639
1660
  // give runtime a dummy value so it knows we're loading from a stash blob
1640
1661
  pendingLocalState ? pendingLocalState?.pendingRuntimeState ?? {} : undefined,
1641
1662
  isInstanceOfISnapshot(baseSnapshot) ? baseSnapshot : undefined,
@@ -2127,7 +2148,7 @@ export class Container
2127
2148
 
2128
2149
  if (connected) {
2129
2150
  const clientId = this.connectionStateHandler.clientId;
2130
- assert(clientId !== undefined, "there has to be clientId");
2151
+ assert(clientId !== undefined, 0x96e /* there has to be clientId */);
2131
2152
  this.protocolHandler.audience.setCurrentClientId(clientId);
2132
2153
  }
2133
2154
 
@@ -2411,7 +2432,10 @@ export class Container
2411
2432
  // and we propagate such events to container runtime. All events prior to being loaded are ignored.
2412
2433
  // This means if we get here in non-loaded state, we might not deliver proper events to container runtime,
2413
2434
  // and runtime implementation may miss such events.
2414
- assert(this.loaded, "has to be called after container transitions to loaded state");
2435
+ assert(
2436
+ this.loaded,
2437
+ 0x96f /* has to be called after container transitions to loaded state */,
2438
+ );
2415
2439
 
2416
2440
  switch (deltaConnectionArg) {
2417
2441
  case undefined:
@@ -7,13 +7,13 @@ import {
7
7
  AttachState,
8
8
  IAudience,
9
9
  ICriticalContainerError,
10
- IDeltaManager,
11
10
  } from "@fluidframework/container-definitions";
12
11
  import {
13
12
  IBatchMessage,
14
13
  IContainerContext,
15
14
  ILoader,
16
15
  ILoaderOptions,
16
+ IDeltaManager,
17
17
  } from "@fluidframework/container-definitions/internal";
18
18
  import { type FluidObject } from "@fluidframework/core-interfaces";
19
19
  import { type ISignalEnvelope } from "@fluidframework/core-interfaces/internal";
@@ -157,7 +157,7 @@ export class ContainerStorageAdapter
157
157
  this.loadingGroupIdSnapshotsFromPendingState[
158
158
  snapshotFetchOptions.loadingGroupIds[0]
159
159
  ];
160
- assert(localSnapshot !== undefined, "Local snapshot must be present");
160
+ assert(localSnapshot !== undefined, 0x970 /* Local snapshot must be present */);
161
161
  const attributes = await getDocumentAttributes(this, localSnapshot.baseSnapshot);
162
162
  snapshot = convertSnapshotInfoToSnapshot(localSnapshot, attributes.sequenceNumber);
163
163
  } else {
@@ -171,7 +171,10 @@ export class ContainerStorageAdapter
171
171
 
172
172
  // Track the latest snapshot for each loading group id
173
173
  const loadingGroupIds = snapshotFetchOptions?.loadingGroupIds;
174
- assert(snapshot.sequenceNumber !== undefined, "Snapshot must have sequence number");
174
+ assert(
175
+ snapshot.sequenceNumber !== undefined,
176
+ 0x971 /* Snapshot must have sequence number */,
177
+ );
175
178
  if (loadingGroupIds !== undefined) {
176
179
  for (const loadingGroupId of loadingGroupIds) {
177
180
  // Do we actually want to update the stored snapshot?
package/src/contracts.ts CHANGED
@@ -3,13 +3,14 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
+ import { ICriticalContainerError } from "@fluidframework/container-definitions";
6
7
  import {
7
- IConnectionDetails,
8
- ICriticalContainerError,
9
8
  IDeltaQueue,
10
9
  ReadOnlyInfo,
11
- } from "@fluidframework/container-definitions";
12
- import { IFluidCodeDetails, isFluidPackage } from "@fluidframework/container-definitions/internal";
10
+ IFluidCodeDetails,
11
+ isFluidPackage,
12
+ IConnectionDetails,
13
+ } from "@fluidframework/container-definitions/internal";
13
14
  import { IErrorBase, ITelemetryBaseProperties } from "@fluidframework/core-interfaces";
14
15
  import { IContainerPackageInfo } from "@fluidframework/driver-definitions/internal";
15
16
  import {
@@ -3,12 +3,12 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
+ import { ICriticalContainerError } from "@fluidframework/container-definitions";
6
7
  import {
7
- ICriticalContainerError,
8
8
  IDeltaManager,
9
9
  IDeltaManagerEvents,
10
10
  IDeltaQueue,
11
- } from "@fluidframework/container-definitions";
11
+ } from "@fluidframework/container-definitions/internal";
12
12
  import {
13
13
  IEventProvider,
14
14
  type ITelemetryBaseEvent,
@@ -16,10 +16,10 @@ import {
16
16
  } from "@fluidframework/core-interfaces";
17
17
  import { IThrottlingWarning } from "@fluidframework/core-interfaces/internal";
18
18
  import { assert } from "@fluidframework/core-utils/internal";
19
- import { DriverErrorTypes } from "@fluidframework/driver-definitions";
20
19
  import {
21
20
  IDocumentDeltaStorageService,
22
21
  IDocumentService,
22
+ DriverErrorTypes,
23
23
  } from "@fluidframework/driver-definitions/internal";
24
24
  import {
25
25
  MessageType2,
package/src/deltaQueue.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { TypedEventEmitter, performance } from "@fluid-internal/client-utils";
7
- import { IDeltaQueue, IDeltaQueueEvents } from "@fluidframework/container-definitions";
7
+ import { IDeltaQueue, IDeltaQueueEvents } from "@fluidframework/container-definitions/internal";
8
8
  import { assert } from "@fluidframework/core-utils/internal";
9
9
  import Deque from "double-ended-queue";
10
10
 
package/src/loader.ts CHANGED
@@ -41,7 +41,10 @@ import { DebugLogger } from "./debugLogger.js";
41
41
  import { pkgVersion } from "./packageVersion.js";
42
42
  import { ProtocolHandlerBuilder } from "./protocol.js";
43
43
  import type { IPendingContainerState } from "./serializedStateManager.js";
44
- import { tryParseCompatibleResolvedUrl } from "./utils.js";
44
+ import {
45
+ getAttachedContainerStateFromSerializedContainer,
46
+ tryParseCompatibleResolvedUrl,
47
+ } from "./utils.js";
45
48
 
46
49
  function ensureResolvedUrlDefined(
47
50
  resolved: IResolvedUrl | undefined,
@@ -335,7 +338,7 @@ export class Loader implements IHostLoader {
335
338
  return PerformanceEvent.timedExecAsync(this.mc.logger, { eventName }, async () => {
336
339
  return this.resolveCore(
337
340
  request,
338
- pendingLocalState !== undefined ? JSON.parse(pendingLocalState) : undefined,
341
+ getAttachedContainerStateFromSerializedContainer(pendingLocalState),
339
342
  );
340
343
  });
341
344
  }
@@ -4,10 +4,10 @@
4
4
  */
5
5
 
6
6
  import { IRequest, ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
7
- import { DriverErrorTypes } from "@fluidframework/driver-definitions";
8
7
  import {
9
8
  ILocationRedirectionError,
10
9
  IUrlResolver,
10
+ DriverErrorTypes,
11
11
  } from "@fluidframework/driver-definitions/internal";
12
12
  import { createChildLogger } from "@fluidframework/telemetry-utils/internal";
13
13
 
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/container-loader";
9
- export const pkgVersion = "2.0.0-dev-rc.4.0.0.261659";
9
+ export const pkgVersion = "2.0.0-dev-rc.5.0.0.265721";