@fluidframework/datastore 2.41.0 → 2.43.0-343119

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/datastore",
3
- "version": "2.41.0",
3
+ "version": "2.43.0-343119",
4
4
  "description": "Fluid data store implementation",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -69,29 +69,29 @@
69
69
  "temp-directory": "nyc/.nyc_output"
70
70
  },
71
71
  "dependencies": {
72
- "@fluid-internal/client-utils": "~2.41.0",
73
- "@fluidframework/container-definitions": "~2.41.0",
74
- "@fluidframework/core-interfaces": "~2.41.0",
75
- "@fluidframework/core-utils": "~2.41.0",
76
- "@fluidframework/datastore-definitions": "~2.41.0",
77
- "@fluidframework/driver-definitions": "~2.41.0",
78
- "@fluidframework/driver-utils": "~2.41.0",
79
- "@fluidframework/id-compressor": "~2.41.0",
80
- "@fluidframework/runtime-definitions": "~2.41.0",
81
- "@fluidframework/runtime-utils": "~2.41.0",
82
- "@fluidframework/telemetry-utils": "~2.41.0",
72
+ "@fluid-internal/client-utils": "2.43.0-343119",
73
+ "@fluidframework/container-definitions": "2.43.0-343119",
74
+ "@fluidframework/core-interfaces": "2.43.0-343119",
75
+ "@fluidframework/core-utils": "2.43.0-343119",
76
+ "@fluidframework/datastore-definitions": "2.43.0-343119",
77
+ "@fluidframework/driver-definitions": "2.43.0-343119",
78
+ "@fluidframework/driver-utils": "2.43.0-343119",
79
+ "@fluidframework/id-compressor": "2.43.0-343119",
80
+ "@fluidframework/runtime-definitions": "2.43.0-343119",
81
+ "@fluidframework/runtime-utils": "2.43.0-343119",
82
+ "@fluidframework/telemetry-utils": "2.43.0-343119",
83
83
  "uuid": "^9.0.0"
84
84
  },
85
85
  "devDependencies": {
86
86
  "@arethetypeswrong/cli": "^0.17.1",
87
87
  "@biomejs/biome": "~1.9.3",
88
- "@fluid-internal/mocha-test-setup": "~2.41.0",
88
+ "@fluid-internal/mocha-test-setup": "2.43.0-343119",
89
89
  "@fluid-tools/build-cli": "^0.55.0",
90
90
  "@fluidframework/build-common": "^2.0.3",
91
91
  "@fluidframework/build-tools": "^0.55.0",
92
- "@fluidframework/datastore-previous": "npm:@fluidframework/datastore@2.40.0",
92
+ "@fluidframework/datastore-previous": "npm:@fluidframework/datastore@2.42.0",
93
93
  "@fluidframework/eslint-config-fluid": "^5.7.4",
94
- "@fluidframework/test-runtime-utils": "~2.41.0",
94
+ "@fluidframework/test-runtime-utils": "2.43.0-343119",
95
95
  "@microsoft/api-extractor": "7.52.8",
96
96
  "@types/lodash": "^4.14.118",
97
97
  "@types/mocha": "^10.0.10",
@@ -27,6 +27,8 @@ import {
27
27
  IFluidDataStoreRuntime,
28
28
  IFluidDataStoreRuntimeEvents,
29
29
  type IDeltaManagerErased,
30
+ // eslint-disable-next-line import/no-deprecated
31
+ type IFluidDataStoreRuntimeExperimental,
30
32
  } from "@fluidframework/datastore-definitions/internal";
31
33
  import {
32
34
  IClientDetails,
@@ -148,6 +150,22 @@ const defaultPolicies: IFluidDataStorePolicies = {
148
150
  readonlyInStagingMode: true,
149
151
  };
150
152
 
153
+ /**
154
+ * Set up the boxed pendingOpCount value.
155
+ */
156
+ function initializePendingOpCount(): { value: number } {
157
+ let value = 0;
158
+ return {
159
+ get value() {
160
+ return value;
161
+ },
162
+ set value(newValue: number) {
163
+ assert(newValue >= 0, 0xbbd /* pendingOpCount must be non-negative */);
164
+ value = newValue;
165
+ },
166
+ };
167
+ }
168
+
151
169
  /**
152
170
  * Base data store class
153
171
  * @legacy
@@ -421,17 +439,30 @@ export class FluidDataStoreRuntime
421
439
  this.localChangesTelemetryCount =
422
440
  this.mc.config.getNumber("Fluid.Telemetry.LocalChangesTelemetryCount") ?? 10;
423
441
 
424
- // eslint-disable-next-line import/no-deprecated
425
- const base: IContainerRuntimeBaseExperimental | undefined =
442
+ // Reference these properties to avoid unused private member errors.
443
+ // They're accessed via IFluidDataStoreRuntimeExperimental interface.
444
+ // eslint-disable-next-line no-void
445
+ void [this.inStagingMode, this.isDirty];
446
+ }
447
+
448
+ /**
449
+ * Implementation of IFluidDataStoreRuntimeExperimental.inStagingMode
450
+ */
451
+ // eslint-disable-next-line import/no-deprecated
452
+ private get inStagingMode(): IFluidDataStoreRuntimeExperimental["inStagingMode"] {
453
+ return (
426
454
  // eslint-disable-next-line import/no-deprecated
427
- this.dataStoreContext.containerRuntime satisfies IContainerRuntimeBaseExperimental;
428
- if (base !== undefined && "inStagingMode" in base) {
429
- Object.defineProperty(this, "inStagingMode", {
430
- get: () => {
431
- return base.inStagingMode;
432
- },
433
- });
434
- }
455
+ (this.dataStoreContext.containerRuntime as IContainerRuntimeBaseExperimental)
456
+ ?.inStagingMode
457
+ );
458
+ }
459
+
460
+ /**
461
+ * Implementation of IFluidDataStoreRuntimeExperimental.isDirty
462
+ */
463
+ // eslint-disable-next-line import/no-deprecated
464
+ private get isDirty(): IFluidDataStoreRuntimeExperimental["isDirty"] {
465
+ return this.pendingOpCount.value > 0;
435
466
  }
436
467
 
437
468
  get deltaManager(): IDeltaManagerErased {
@@ -873,7 +904,12 @@ export class FluidDataStoreRuntime
873
904
  public processMessages(messageCollection: IRuntimeMessageCollection): void {
874
905
  this.verifyNotClosed();
875
906
 
876
- const { envelope, messagesContent } = messageCollection;
907
+ const { envelope, local, messagesContent } = messageCollection;
908
+
909
+ if (local) {
910
+ this.pendingOpCount.value -= messagesContent.length;
911
+ }
912
+
877
913
  try {
878
914
  switch (envelope.type) {
879
915
  case DataStoreMessageType.ChannelOp: {
@@ -1219,6 +1255,12 @@ export class FluidDataStoreRuntime
1219
1255
  this.submit(DataStoreMessageType.ChannelOp, envelope, localOpMetadata);
1220
1256
  }
1221
1257
 
1258
+ /**
1259
+ * Count of pending ops that have been submitted but not yet ack'd.
1260
+ * Used to compute {@link FluidDataStoreRuntime.isDirty}
1261
+ */
1262
+ private readonly pendingOpCount: { value: number } = initializePendingOpCount();
1263
+
1222
1264
  private submit(
1223
1265
  type: DataStoreMessageType,
1224
1266
  content: unknown,
@@ -1226,6 +1268,7 @@ export class FluidDataStoreRuntime
1226
1268
  ): void {
1227
1269
  this.verifyNotClosed();
1228
1270
  this.dataStoreContext.submitMessage(type, content, localOpMetadata);
1271
+ ++this.pendingOpCount.value;
1229
1272
  }
1230
1273
 
1231
1274
  /**
@@ -1245,12 +1288,17 @@ export class FluidDataStoreRuntime
1245
1288
  ): void {
1246
1289
  this.verifyNotClosed();
1247
1290
 
1291
+ // The op being resubmitted was not / will not be submitted, so decrement the count.
1292
+ // The calls below may result in one or more ops submitted again, which will increment the count (or not if nothing needs to be submitted anymore).
1293
+ --this.pendingOpCount.value;
1294
+
1248
1295
  switch (type) {
1249
1296
  case DataStoreMessageType.ChannelOp: {
1250
1297
  // For Operations, find the right channel and trigger resubmission on it.
1251
1298
  const envelope = content as IEnvelope;
1252
1299
  const channelContext = this.contexts.get(envelope.address);
1253
1300
  assert(!!channelContext, 0x183 /* "There should be a channel context for the op" */);
1301
+
1254
1302
  channelContext.reSubmit(envelope.contents, localOpMetadata, squash);
1255
1303
  break;
1256
1304
  }
@@ -1279,12 +1327,16 @@ export class FluidDataStoreRuntime
1279
1327
  ): void {
1280
1328
  this.verifyNotClosed();
1281
1329
 
1330
+ // The op being rolled back was not/will not be submitted, so decrement the count.
1331
+ --this.pendingOpCount.value;
1332
+
1282
1333
  switch (type) {
1283
1334
  case DataStoreMessageType.ChannelOp: {
1284
1335
  // For Operations, find the right channel and trigger resubmission on it.
1285
1336
  const envelope = content as IEnvelope;
1286
1337
  const channelContext = this.contexts.get(envelope.address);
1287
1338
  assert(!!channelContext, 0x2ed /* "There should be a channel context for the op" */);
1339
+
1288
1340
  channelContext.rollback(envelope.contents, localOpMetadata);
1289
1341
  break;
1290
1342
  }
@@ -1297,6 +1349,10 @@ export class FluidDataStoreRuntime
1297
1349
  // TODO: use something other than `any` here
1298
1350
  // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
1299
1351
  public async applyStashedOp(content: any): Promise<unknown> {
1352
+ // The op being applied may have been submitted in a previous session, so we increment the count here.
1353
+ // Either the ack will arrive and be processed, or that previous session's connection will end, at which point the op will be resubmitted.
1354
+ ++this.pendingOpCount.value;
1355
+
1300
1356
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
1301
1357
  const type = content?.type as DataStoreMessageType;
1302
1358
  switch (type) {
@@ -1336,6 +1392,13 @@ export class FluidDataStoreRuntime
1336
1392
  }
1337
1393
  }
1338
1394
 
1395
+ /**
1396
+ * Indicates the given channel is dirty from Summarizer's point of view,
1397
+ * i.e. it has local changes that need to be included in the summary.
1398
+ *
1399
+ * @remarks - If a channel's changes are rolled back or rebased away, we won't
1400
+ * clear the dirty flag set here.
1401
+ */
1339
1402
  private setChannelDirty(address: string): void {
1340
1403
  this.verifyNotClosed();
1341
1404
  this.dataStoreContext.setChannelDirty(address);
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/datastore";
9
- export const pkgVersion = "2.41.0";
9
+ export const pkgVersion = "2.43.0-343119";