@fluidframework/container-loader 2.0.0-internal.1.1.1 → 2.0.0-internal.1.2.0.93071

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 (67) hide show
  1. package/dist/collabWindowTracker.d.ts +1 -1
  2. package/dist/collabWindowTracker.d.ts.map +1 -1
  3. package/dist/collabWindowTracker.js +2 -1
  4. package/dist/collabWindowTracker.js.map +1 -1
  5. package/dist/connectionManager.d.ts +1 -1
  6. package/dist/connectionManager.d.ts.map +1 -1
  7. package/dist/connectionManager.js +5 -5
  8. package/dist/connectionManager.js.map +1 -1
  9. package/dist/container.d.ts +10 -0
  10. package/dist/container.d.ts.map +1 -1
  11. package/dist/container.js +54 -42
  12. package/dist/container.js.map +1 -1
  13. package/dist/containerContext.d.ts +18 -7
  14. package/dist/containerContext.d.ts.map +1 -1
  15. package/dist/containerContext.js +18 -8
  16. package/dist/containerContext.js.map +1 -1
  17. package/dist/deltaManager.d.ts +1 -1
  18. package/dist/deltaManager.d.ts.map +1 -1
  19. package/dist/deltaManager.js +18 -6
  20. package/dist/deltaManager.js.map +1 -1
  21. package/dist/loader.d.ts +1 -1
  22. package/dist/loader.js.map +1 -1
  23. package/dist/packageVersion.d.ts +1 -1
  24. package/dist/packageVersion.d.ts.map +1 -1
  25. package/dist/packageVersion.js +1 -1
  26. package/dist/packageVersion.js.map +1 -1
  27. package/dist/protocol.d.ts.map +1 -1
  28. package/dist/protocol.js +2 -1
  29. package/dist/protocol.js.map +1 -1
  30. package/lib/collabWindowTracker.d.ts +1 -1
  31. package/lib/collabWindowTracker.d.ts.map +1 -1
  32. package/lib/collabWindowTracker.js +3 -2
  33. package/lib/collabWindowTracker.js.map +1 -1
  34. package/lib/connectionManager.d.ts +1 -1
  35. package/lib/connectionManager.d.ts.map +1 -1
  36. package/lib/connectionManager.js +6 -8
  37. package/lib/connectionManager.js.map +1 -1
  38. package/lib/container.d.ts +10 -0
  39. package/lib/container.d.ts.map +1 -1
  40. package/lib/container.js +56 -44
  41. package/lib/container.js.map +1 -1
  42. package/lib/containerContext.d.ts +18 -7
  43. package/lib/containerContext.d.ts.map +1 -1
  44. package/lib/containerContext.js +19 -9
  45. package/lib/containerContext.js.map +1 -1
  46. package/lib/deltaManager.d.ts +1 -1
  47. package/lib/deltaManager.d.ts.map +1 -1
  48. package/lib/deltaManager.js +18 -6
  49. package/lib/deltaManager.js.map +1 -1
  50. package/lib/loader.d.ts +1 -1
  51. package/lib/loader.js.map +1 -1
  52. package/lib/packageVersion.d.ts +1 -1
  53. package/lib/packageVersion.d.ts.map +1 -1
  54. package/lib/packageVersion.js +1 -1
  55. package/lib/packageVersion.js.map +1 -1
  56. package/lib/protocol.d.ts.map +1 -1
  57. package/lib/protocol.js +2 -1
  58. package/lib/protocol.js.map +1 -1
  59. package/package.json +12 -12
  60. package/src/collabWindowTracker.ts +4 -3
  61. package/src/connectionManager.ts +6 -6
  62. package/src/container.ts +67 -50
  63. package/src/containerContext.ts +22 -8
  64. package/src/deltaManager.ts +20 -7
  65. package/src/loader.ts +1 -1
  66. package/src/packageVersion.ts +1 -1
  67. package/src/protocol.ts +2 -1
package/lib/container.js CHANGED
@@ -7,8 +7,8 @@ import merge from "lodash/merge";
7
7
  import { v4 as uuid } from "uuid";
8
8
  import { assert, performance, unreachableCase } from "@fluidframework/common-utils";
9
9
  import { AttachState, isFluidCodeDetails, } from "@fluidframework/container-definitions";
10
- import { DataCorruptionError, extractSafePropertiesFromMessage, GenericError, UsageError, } from "@fluidframework/container-utils";
11
- import { readAndParse, OnlineStatus, isOnline, ensureFluidResolvedUrl, combineAppAndProtocolSummary, runWithRetry, isFluidResolvedUrl, isRuntimeMessage, isUnpackedRuntimeMessage, } from "@fluidframework/driver-utils";
10
+ import { GenericError, UsageError, } from "@fluidframework/container-utils";
11
+ import { readAndParse, OnlineStatus, isOnline, ensureFluidResolvedUrl, combineAppAndProtocolSummary, runWithRetry, isFluidResolvedUrl, } from "@fluidframework/driver-utils";
12
12
  import { MessageType, SummaryType, } from "@fluidframework/protocol-definitions";
13
13
  import { ChildLogger, EventEmitterWithErrorHandling, PerformanceEvent, raiseConnectedEvent, TelemetryLogger, connectedEventName, disconnectedEventName, normalizeError, loggerToMonitoringContext, wrapError, } from "@fluidframework/telemetry-utils";
14
14
  import { Audience } from "./audience";
@@ -954,7 +954,7 @@ export class Container extends EventEmitterWithErrorHandling {
954
954
  async initializeProtocolState(attributes, quorumSnapshot) {
955
955
  var _a, _b;
956
956
  const protocolHandlerBuilder = (_a = this.protocolHandlerBuilder) !== null && _a !== void 0 ? _a : ((...args) => new ProtocolHandler(...args, new Audience()));
957
- const protocol = protocolHandlerBuilder(attributes, quorumSnapshot, (key, value) => this.submitMessage(MessageType.Propose, { key, value }), (_b = this._initialClients) !== null && _b !== void 0 ? _b : []);
957
+ const protocol = protocolHandlerBuilder(attributes, quorumSnapshot, (key, value) => this.submitMessage(MessageType.Propose, JSON.stringify({ key, value })), (_b = this._initialClients) !== null && _b !== void 0 ? _b : []);
958
958
  this._initialClients = undefined;
959
959
  const protocolLogger = ChildLogger.create(this.subLogger, "ProtocolHandler");
960
960
  protocol.quorum.on("error", (error) => {
@@ -1084,6 +1084,7 @@ export class Container extends EventEmitterWithErrorHandling {
1084
1084
  this.emit("warning", warn);
1085
1085
  });
1086
1086
  deltaManager.on("readonly", (readonly) => {
1087
+ this.setContextConnectedState(this.connectionState === ConnectionState.Connected, readonly);
1087
1088
  this.emit("readonly", readonly);
1088
1089
  });
1089
1090
  deltaManager.on("closed", (error) => {
@@ -1152,39 +1153,46 @@ export class Container extends EventEmitterWithErrorHandling {
1152
1153
  }
1153
1154
  const state = this.connectionState === ConnectionState.Connected;
1154
1155
  // Both protocol and context should not be undefined if we got so far.
1155
- if (((_a = this._context) === null || _a === void 0 ? void 0 : _a.disposed) === false) {
1156
- this.context.setConnectionState(state, this.clientId);
1157
- }
1156
+ this.setContextConnectedState(state, (_a = this._deltaManager.connectionManager.readOnlyInfo.readonly) !== null && _a !== void 0 ? _a : false);
1158
1157
  this.protocolHandler.setConnectionState(state, this.clientId);
1159
1158
  raiseConnectedEvent(this.mc.logger, this, state, this.clientId);
1160
1159
  if (logOpsOnReconnect) {
1161
1160
  this.mc.logger.sendTelemetryEvent({ eventName: "OpsSentOnReconnect", count: this.messageCountAfterDisconnection });
1162
1161
  }
1163
1162
  }
1163
+ // back-compat: ADO #1385: Remove in the future, summary op should come through submitSummaryMessage()
1164
1164
  submitContainerMessage(type, contents, batch, metadata) {
1165
- const outboundMessageType = type;
1166
- switch (outboundMessageType) {
1165
+ switch (type) {
1167
1166
  case MessageType.Operation:
1168
- case MessageType.RemoteHelp:
1169
- break;
1170
- case MessageType.Summarize: {
1171
- // github #6451: this is only needed for staging so the server
1172
- // know when the protocol tree is included
1173
- // this can be removed once all clients send
1174
- // protocol tree by default
1175
- const summary = contents;
1176
- if (summary.details === undefined) {
1177
- summary.details = {};
1178
- }
1179
- summary.details.includesProtocolTree =
1180
- this.options.summarizeProtocolTree === true;
1181
- break;
1182
- }
1167
+ return this.submitMessage(type, JSON.stringify(contents), batch, metadata);
1168
+ case MessageType.Summarize:
1169
+ return this.submitSummaryMessage(contents);
1183
1170
  default:
1184
1171
  this.close(new GenericError("invalidContainerSubmitOpType", undefined /* error */, { messageType: type }));
1185
1172
  return -1;
1186
1173
  }
1187
- return this.submitMessage(type, contents, batch, metadata);
1174
+ }
1175
+ /** @returns clientSequenceNumber of last message in a batch */
1176
+ submitBatch(batch) {
1177
+ let clientSequenceNumber = -1;
1178
+ for (const message of batch) {
1179
+ clientSequenceNumber = this.submitMessage(MessageType.Operation, message.contents, true, // batch
1180
+ message.metadata);
1181
+ }
1182
+ this._deltaManager.flush();
1183
+ return clientSequenceNumber;
1184
+ }
1185
+ submitSummaryMessage(summary) {
1186
+ // github #6451: this is only needed for staging so the server
1187
+ // know when the protocol tree is included
1188
+ // this can be removed once all clients send
1189
+ // protocol tree by default
1190
+ if (summary.details === undefined) {
1191
+ summary.details = {};
1192
+ }
1193
+ summary.details.includesProtocolTree =
1194
+ this.options.summarizeProtocolTree === true;
1195
+ return this.submitMessage(MessageType.Summarize, JSON.stringify(summary), false /* batch */);
1188
1196
  }
1189
1197
  submitMessage(type, contents, batch, metadata) {
1190
1198
  var _a;
@@ -1199,22 +1207,9 @@ export class Container extends EventEmitterWithErrorHandling {
1199
1207
  processRemoteMessage(message) {
1200
1208
  const local = this.clientId === message.clientId;
1201
1209
  // Allow the protocol handler to process the message
1202
- let result = { immediateNoOp: false };
1203
- try {
1204
- result = this.protocolHandler.processMessage(message, local);
1205
- }
1206
- catch (error) {
1207
- this.close(wrapError(error, (errorMessage) => new DataCorruptionError(errorMessage, extractSafePropertiesFromMessage(message))));
1208
- }
1209
- // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
1210
- if (isUnpackedRuntimeMessage(message) && !isRuntimeMessage(message)) {
1211
- this.mc.logger.sendTelemetryEvent({ eventName: "UnpackedRuntimeMessage", type: message.type });
1212
- }
1213
- // Forward non system messages to the loaded runtime for processing
1214
- // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
1215
- if (isRuntimeMessage(message) || isUnpackedRuntimeMessage(message)) {
1216
- this.context.process(message, local, undefined);
1217
- }
1210
+ const result = this.protocolHandler.processMessage(message, local);
1211
+ // Forward messages to the loaded runtime for processing
1212
+ this.context.process(message, local, undefined);
1218
1213
  // Inactive (not in quorum or not writers) clients don't take part in the minimum sequence number calculation.
1219
1214
  if (this.activeConnection()) {
1220
1215
  if (this.collabWindowTracker === undefined) {
@@ -1223,15 +1218,14 @@ export class Container extends EventEmitterWithErrorHandling {
1223
1218
  // clients.
1224
1219
  // All existing will continue to use settings they got earlier.
1225
1220
  assert(this.serviceConfiguration !== undefined, 0x2e4 /* "there should be service config for active connection" */);
1226
- this.collabWindowTracker = new CollabWindowTracker((type, contents) => {
1221
+ this.collabWindowTracker = new CollabWindowTracker((type) => {
1227
1222
  assert(this.activeConnection(), 0x241 /* "disconnect should result in stopSequenceNumberUpdate() call" */);
1228
- this.submitMessage(type, contents);
1223
+ this.submitMessage(type);
1229
1224
  }, this.serviceConfiguration.noopTimeFrequency, this.serviceConfiguration.noopCountFrequency);
1230
1225
  }
1231
1226
  this.collabWindowTracker.scheduleSequenceNumberUpdate(message, result.immediateNoOp === true);
1232
1227
  }
1233
1228
  this.emit("op", message);
1234
- return result;
1235
1229
  }
1236
1230
  submitSignal(message) {
1237
1231
  this._deltaManager.submitSignal(JSON.stringify(message));
@@ -1278,7 +1272,7 @@ export class Container extends EventEmitterWithErrorHandling {
1278
1272
  // The relative loader will proxy requests to '/' to the loader itself assuming no non-cache flags
1279
1273
  // are set. Global requests will still go directly to the loader
1280
1274
  const loader = new RelativeLoader(this, this.loader);
1281
- this._context = await ContainerContext.createOrLoad(this, this.scope, this.codeLoader, codeDetails, snapshot, new DeltaManagerProxy(this._deltaManager), new QuorumProxy(this.protocolHandler.quorum), loader, (type, contents, batch, metadata) => this.submitContainerMessage(type, contents, batch, metadata), (message) => this.submitSignal(message), (error) => this.close(error), Container.version, (dirty) => this.updateDirtyContainerState(dirty), existing, pendingLocalState);
1275
+ this._context = await ContainerContext.createOrLoad(this, this.scope, this.codeLoader, codeDetails, snapshot, new DeltaManagerProxy(this._deltaManager), new QuorumProxy(this.protocolHandler.quorum), loader, (type, contents, batch, metadata) => this.submitContainerMessage(type, contents, batch, metadata), (summaryOp) => this.submitSummaryMessage(summaryOp), (batch) => this.submitBatch(batch), (message) => this.submitSignal(message), (error) => this.close(error), Container.version, (dirty) => this.updateDirtyContainerState(dirty), existing, pendingLocalState);
1282
1276
  this.emit("contextChanged", codeDetails);
1283
1277
  }
1284
1278
  updateDirtyContainerState(dirty) {
@@ -1291,6 +1285,24 @@ export class Container extends EventEmitterWithErrorHandling {
1291
1285
  logContainerError(warning) {
1292
1286
  this.mc.logger.sendErrorEvent({ eventName: "ContainerWarning" }, warning);
1293
1287
  }
1288
+ /**
1289
+ * Set the connected state of the ContainerContext
1290
+ * This controls the "connected" state of the ContainerRuntime as well
1291
+ * @param state - Is the container currently connected?
1292
+ * @param readonly - Is the container in readonly mode?
1293
+ */
1294
+ setContextConnectedState(state, readonly) {
1295
+ var _a;
1296
+ if (((_a = this._context) === null || _a === void 0 ? void 0 : _a.disposed) === false) {
1297
+ /**
1298
+ * We want to lie to the ContainerRuntime when we are in readonly mode to prevent issues with pending
1299
+ * ops getting through to the DeltaManager.
1300
+ * The ContainerRuntime's "connected" state simply means it is ok to send ops
1301
+ * See https://dev.azure.com/fluidframework/internal/_workitems/edit/1246
1302
+ */
1303
+ this.context.setConnectionState(state && !readonly, this.clientId);
1304
+ }
1305
+ }
1294
1306
  }
1295
1307
  Container.version = "^0.1.0";
1296
1308
  //# sourceMappingURL=container.js.map