@fluidframework/datastore 2.41.0-338186 → 2.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/.eslintrc.cjs +1 -4
  2. package/CHANGELOG.md +4 -0
  3. package/dist/channelContext.d.ts +7 -5
  4. package/dist/channelContext.d.ts.map +1 -1
  5. package/dist/channelContext.js +3 -1
  6. package/dist/channelContext.js.map +1 -1
  7. package/dist/channelDeltaConnection.d.ts +5 -5
  8. package/dist/channelDeltaConnection.d.ts.map +1 -1
  9. package/dist/channelDeltaConnection.js +7 -6
  10. package/dist/channelDeltaConnection.js.map +1 -1
  11. package/dist/channelStorageService.js +2 -2
  12. package/dist/channelStorageService.js.map +1 -1
  13. package/dist/dataStoreRuntime.d.ts.map +1 -1
  14. package/dist/dataStoreRuntime.js +65 -37
  15. package/dist/dataStoreRuntime.js.map +1 -1
  16. package/dist/fluidHandle.d.ts.map +1 -1
  17. package/dist/fluidHandle.js +6 -2
  18. package/dist/fluidHandle.js.map +1 -1
  19. package/dist/localChannelContext.d.ts +8 -6
  20. package/dist/localChannelContext.d.ts.map +1 -1
  21. package/dist/localChannelContext.js +8 -6
  22. package/dist/localChannelContext.js.map +1 -1
  23. package/dist/localChannelStorageService.d.ts.map +1 -1
  24. package/dist/localChannelStorageService.js +6 -4
  25. package/dist/localChannelStorageService.js.map +1 -1
  26. package/dist/packageVersion.d.ts +1 -1
  27. package/dist/packageVersion.d.ts.map +1 -1
  28. package/dist/packageVersion.js +1 -1
  29. package/dist/packageVersion.js.map +1 -1
  30. package/dist/remoteChannelContext.d.ts +7 -5
  31. package/dist/remoteChannelContext.d.ts.map +1 -1
  32. package/dist/remoteChannelContext.js +5 -4
  33. package/dist/remoteChannelContext.js.map +1 -1
  34. package/lib/channelContext.d.ts +7 -5
  35. package/lib/channelContext.d.ts.map +1 -1
  36. package/lib/channelContext.js +3 -1
  37. package/lib/channelContext.js.map +1 -1
  38. package/lib/channelDeltaConnection.d.ts +5 -5
  39. package/lib/channelDeltaConnection.d.ts.map +1 -1
  40. package/lib/channelDeltaConnection.js +7 -6
  41. package/lib/channelDeltaConnection.js.map +1 -1
  42. package/lib/channelStorageService.js +2 -2
  43. package/lib/channelStorageService.js.map +1 -1
  44. package/lib/dataStoreRuntime.d.ts.map +1 -1
  45. package/lib/dataStoreRuntime.js +65 -37
  46. package/lib/dataStoreRuntime.js.map +1 -1
  47. package/lib/fluidHandle.d.ts.map +1 -1
  48. package/lib/fluidHandle.js +6 -2
  49. package/lib/fluidHandle.js.map +1 -1
  50. package/lib/localChannelContext.d.ts +8 -6
  51. package/lib/localChannelContext.d.ts.map +1 -1
  52. package/lib/localChannelContext.js +8 -6
  53. package/lib/localChannelContext.js.map +1 -1
  54. package/lib/localChannelStorageService.d.ts.map +1 -1
  55. package/lib/localChannelStorageService.js +6 -4
  56. package/lib/localChannelStorageService.js.map +1 -1
  57. package/lib/packageVersion.d.ts +1 -1
  58. package/lib/packageVersion.d.ts.map +1 -1
  59. package/lib/packageVersion.js +1 -1
  60. package/lib/packageVersion.js.map +1 -1
  61. package/lib/remoteChannelContext.d.ts +7 -5
  62. package/lib/remoteChannelContext.d.ts.map +1 -1
  63. package/lib/remoteChannelContext.js +5 -4
  64. package/lib/remoteChannelContext.js.map +1 -1
  65. package/package.json +15 -15
  66. package/src/channelContext.ts +7 -5
  67. package/src/channelDeltaConnection.ts +19 -19
  68. package/src/channelStorageService.ts +3 -3
  69. package/src/dataStoreRuntime.ts +100 -64
  70. package/src/fluidHandle.ts +7 -3
  71. package/src/localChannelContext.ts +18 -16
  72. package/src/localChannelStorageService.ts +6 -4
  73. package/src/packageVersion.ts +1 -1
  74. package/src/remoteChannelContext.ts +19 -19
@@ -201,22 +201,25 @@ export class FluidDataStoreRuntime
201
201
  return this.dataStoreContext.idCompressor;
202
202
  }
203
203
 
204
- public get IFluidHandleContext() {
204
+ // TODO: the methods below should have more specific return typing, per the interfaces they are implementing.
205
+ // Doing so would be a breaking change.
206
+
207
+ public get IFluidHandleContext(): this {
205
208
  return this;
206
209
  }
207
210
 
208
- public get rootRoutingContext() {
211
+ public get rootRoutingContext(): this {
209
212
  return this;
210
213
  }
211
- public get channelsRoutingContext() {
214
+ public get channelsRoutingContext(): this {
212
215
  return this;
213
216
  }
214
- public get objectsRoutingContext() {
217
+ public get objectsRoutingContext(): this {
215
218
  return this;
216
219
  }
217
220
 
218
221
  private _disposed = false;
219
- public get disposed() {
222
+ public get disposed(): boolean {
220
223
  return this._disposed;
221
224
  }
222
225
 
@@ -234,6 +237,8 @@ export class FluidDataStoreRuntime
234
237
 
235
238
  public readonly id: string;
236
239
 
240
+ // TODO: use something other than `any` here (breaking change)
241
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
237
242
  public readonly options: Record<string | number, any>;
238
243
  public readonly deltaManagerInternal: IDeltaManager<
239
244
  ISequencedDocumentMessage,
@@ -337,10 +342,10 @@ export class FluidDataStoreRuntime
337
342
 
338
343
  // Must always receive the data store type inside of the attributes
339
344
  if (tree?.trees !== undefined) {
340
- Object.entries(tree.trees).forEach(([path, subtree]) => {
345
+ for (const [path, subtree] of Object.entries(tree.trees)) {
341
346
  // Issue #4414
342
347
  if (path === "_search") {
343
- return;
348
+ continue;
344
349
  }
345
350
 
346
351
  let channelContext: RemoteChannelContext | RehydratedLocalChannelContext;
@@ -353,10 +358,10 @@ export class FluidDataStoreRuntime
353
358
  // data store, if the data store is loaded after the container is attached, then we missed making
354
359
  // the channel visible. So do it now. Otherwise, add it to local channel context queue, so
355
360
  // that it can be make it visible later with the data store.
356
- if (dataStoreContext.attachState !== AttachState.Detached) {
357
- channelContext.makeVisible();
358
- } else {
361
+ if (dataStoreContext.attachState === AttachState.Detached) {
359
362
  this.localChannelContextQueue.set(path, channelContext);
363
+ } else {
364
+ channelContext.makeVisible();
360
365
  }
361
366
  } else {
362
367
  channelContext = new RemoteChannelContext(
@@ -376,7 +381,7 @@ export class FluidDataStoreRuntime
376
381
  }
377
382
 
378
383
  this.contexts.set(path, channelContext);
379
- });
384
+ }
380
385
  }
381
386
 
382
387
  this.entryPoint = new FluidObjectHandle<FluidObject>(
@@ -508,7 +513,7 @@ export class FluidDataStoreRuntime
508
513
  * IDs cannot start with "_" as it could result in collision of IDs with auto-assigned (by FF) short IDs.
509
514
  * @param id - channel ID.
510
515
  */
511
- protected validateChannelId(id: string) {
516
+ protected validateChannelId(id: string): void {
512
517
  if (id.includes("/")) {
513
518
  throw new UsageError(`Id cannot contain slashes: ${id}`);
514
519
  }
@@ -546,10 +551,7 @@ export class FluidDataStoreRuntime
546
551
  public createChannel(idArg: string | undefined, type: string): IChannel {
547
552
  let id: string;
548
553
 
549
- if (idArg !== undefined) {
550
- id = idArg;
551
- this.validateChannelId(id);
552
- } else {
554
+ if (idArg === undefined) {
553
555
  /**
554
556
  * Return uuid if short-ids are explicitly disabled via feature flags.
555
557
  */
@@ -562,18 +564,21 @@ export class FluidDataStoreRuntime
562
564
  // - uuids
563
565
  // In first two cases we will encode result as strings in more compact form, with leading underscore,
564
566
  // to ensure no overlap with user-provided DDS names (see validateChannelId())
565
- if (this.visibilityState !== VisibilityState.GloballyVisible) {
566
- // container is detached, only one client observes content, no way to hit collisions with other clients.
567
- id = encodeCompactIdToString(2 * this.contexts.size, "_");
568
- } else {
567
+ if (this.visibilityState === VisibilityState.GloballyVisible) {
569
568
  // Due to back-compat, we could not depend yet on generateDocumentUniqueId() being there.
570
569
  // We can remove the need to leverage uuid() as fall-back in couple releases.
571
570
  const res =
572
571
  this.dataStoreContext.containerRuntime.generateDocumentUniqueId?.() ?? uuid();
573
572
  id = typeof res === "number" ? encodeCompactIdToString(2 * res + 1, "_") : res;
573
+ } else {
574
+ // container is detached, only one client observes content, no way to hit collisions with other clients.
575
+ id = encodeCompactIdToString(2 * this.contexts.size, "_");
574
576
  }
575
577
  }
576
578
  assert(!id.includes("/"), 0x8fc /* slash */);
579
+ } else {
580
+ id = idArg;
581
+ this.validateChannelId(id);
577
582
  }
578
583
 
579
584
  this.verifyNotClosed();
@@ -592,7 +597,7 @@ export class FluidDataStoreRuntime
592
597
  return channel;
593
598
  }
594
599
 
595
- private createChannelContext(channel: IChannel) {
600
+ private createChannelContext(channel: IChannel): void {
596
601
  this.notBoundedChannelContextSet.add(channel.id);
597
602
  const context = new LocalChannelContext(
598
603
  channel,
@@ -610,7 +615,7 @@ export class FluidDataStoreRuntime
610
615
  id: string,
611
616
  tree: ISnapshotTree,
612
617
  flatBlobs?: Map<string, ArrayBufferLike>,
613
- ) {
618
+ ): RehydratedLocalChannelContext {
614
619
  return new RehydratedLocalChannelContext(
615
620
  id,
616
621
  this.sharedObjectRegistry,
@@ -672,15 +677,15 @@ export class FluidDataStoreRuntime
672
677
  * visible, it will mark us globally visible. Otherwise, it will mark us globally visible when it becomes
673
678
  * globally visible.
674
679
  */
675
- public makeVisibleAndAttachGraph() {
680
+ public makeVisibleAndAttachGraph(): void {
676
681
  if (this.visibilityState !== VisibilityState.NotVisible) {
677
682
  return;
678
683
  }
679
684
  this.visibilityState = VisibilityState.LocallyVisible;
680
685
 
681
- this.pendingHandlesToMakeVisible.forEach((handle) => {
686
+ for (const handle of this.pendingHandlesToMakeVisible) {
682
687
  handle.attachGraph();
683
- });
688
+ }
684
689
  this.pendingHandlesToMakeVisible.clear();
685
690
  this.dataStoreContext.makeLocallyVisible();
686
691
  }
@@ -688,7 +693,7 @@ export class FluidDataStoreRuntime
688
693
  /**
689
694
  * This function is called when a handle to this data store is added to a visible DDS.
690
695
  */
691
- public attachGraph() {
696
+ public attachGraph(): void {
692
697
  this.makeVisibleAndAttachGraph();
693
698
  }
694
699
 
@@ -701,7 +706,7 @@ export class FluidDataStoreRuntime
701
706
  this.pendingHandlesToMakeVisible.add(toFluidHandleInternal(handle));
702
707
  }
703
708
 
704
- public setConnectionState(connected: boolean, clientId?: string) {
709
+ public setConnectionState(connected: boolean, clientId?: string): void {
705
710
  this.verifyNotClosed();
706
711
 
707
712
  for (const [, object] of this.contexts) {
@@ -745,7 +750,7 @@ export class FluidDataStoreRuntime
745
750
  private createRemoteChannelContext(
746
751
  attachMessage: IAttachMessage,
747
752
  summarizerNodeParams: CreateChildSummarizerNodeParam,
748
- ) {
753
+ ): RemoteChannelContext {
749
754
  const flatBlobs = new Map<string, ArrayBufferLike>();
750
755
  const snapshotTree = buildSnapshotTree(attachMessage.snapshot.entries, flatBlobs);
751
756
 
@@ -773,7 +778,7 @@ export class FluidDataStoreRuntime
773
778
  * store.
774
779
  * @param messageCollection - The collection of messages to process.
775
780
  */
776
- private processChannelMessages(messageCollection: IRuntimeMessageCollection) {
781
+ private processChannelMessages(messageCollection: IRuntimeMessageCollection): void {
777
782
  this.verifyNotClosed();
778
783
 
779
784
  /*
@@ -783,9 +788,9 @@ export class FluidDataStoreRuntime
783
788
  */
784
789
  let currentAddress: string | undefined;
785
790
  let currentMessagesContent: IRuntimeMessagesContent[] = [];
786
- const { messagesContent, local } = messageCollection;
791
+ const { messagesContent, local, envelope } = messageCollection;
787
792
 
788
- const sendBunchedMessages = () => {
793
+ const sendBunchedMessages = (): void => {
789
794
  // Current address will be undefined for the first message in the list.
790
795
  if (currentAddress === undefined) {
791
796
  return;
@@ -796,7 +801,7 @@ export class FluidDataStoreRuntime
796
801
  assert(!!channelContext, 0xa6b /* Channel context not found */);
797
802
 
798
803
  channelContext.processMessages({
799
- envelope: messageCollection.envelope,
804
+ envelope,
800
805
  messagesContent: currentMessagesContent,
801
806
  local,
802
807
  });
@@ -823,7 +828,7 @@ export class FluidDataStoreRuntime
823
828
  sendBunchedMessages();
824
829
  }
825
830
 
826
- private processAttachMessages(messageCollection: IRuntimeMessageCollection) {
831
+ private processAttachMessages(messageCollection: IRuntimeMessageCollection): void {
827
832
  const { envelope, messagesContent, local } = messageCollection;
828
833
  for (const { contents } of messagesContent) {
829
834
  const attachMessage = contents as IAttachMessage;
@@ -871,12 +876,14 @@ export class FluidDataStoreRuntime
871
876
  const { envelope, messagesContent } = messageCollection;
872
877
  try {
873
878
  switch (envelope.type) {
874
- case DataStoreMessageType.ChannelOp:
879
+ case DataStoreMessageType.ChannelOp: {
875
880
  this.processChannelMessages(messageCollection);
876
881
  break;
877
- case DataStoreMessageType.Attach:
882
+ }
883
+ case DataStoreMessageType.Attach: {
878
884
  this.processAttachMessages(messageCollection);
879
885
  break;
886
+ }
880
887
  default:
881
888
  }
882
889
  } catch (error) {
@@ -892,7 +899,7 @@ export class FluidDataStoreRuntime
892
899
  }
893
900
  }
894
901
 
895
- public processSignal(message: IInboundSignalMessage, local: boolean) {
902
+ public processSignal(message: IInboundSignalMessage, local: boolean): void {
896
903
  this.emit("signal", message, local);
897
904
  }
898
905
 
@@ -929,7 +936,7 @@ export class FluidDataStoreRuntime
929
936
  * - Adds a node for this channel.
930
937
  * @param builder - The builder that contains the GC nodes for this channel's children.
931
938
  */
932
- private updateGCNodes(builder: GCDataBuilder) {
939
+ private updateGCNodes(builder: GCDataBuilder): void {
933
940
  // Add a back route to self in each child's GC nodes. If any child is referenced, then its parent should
934
941
  // be considered referenced as well.
935
942
  builder.addRouteToAllNodes(this.absolutePath);
@@ -993,7 +1000,7 @@ export class FluidDataStoreRuntime
993
1000
  * update their used routes.
994
1001
  * @param usedRoutes - The routes that are used in all contexts in this channel.
995
1002
  */
996
- public updateUsedRoutes(usedRoutes: string[]) {
1003
+ public updateUsedRoutes(usedRoutes: string[]): void {
997
1004
  // Get a map of channel ids to routes used in it.
998
1005
  const usedContextRoutes = unpackChildNodesUsedRoutes(usedRoutes);
999
1006
 
@@ -1132,7 +1139,13 @@ export class FluidDataStoreRuntime
1132
1139
  }
1133
1140
  }
1134
1141
 
1135
- public submitMessage(type: DataStoreMessageType, content: any, localOpMetadata: unknown) {
1142
+ public submitMessage(
1143
+ type: DataStoreMessageType,
1144
+ // TODO: use something other than `any` here (breaking change)
1145
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
1146
+ content: any,
1147
+ localOpMetadata: unknown,
1148
+ ): void {
1136
1149
  this.submit(type, content, localOpMetadata);
1137
1150
  }
1138
1151
 
@@ -1142,9 +1155,9 @@ export class FluidDataStoreRuntime
1142
1155
  * @param content - Content of the signal. Should be a JSON serializable object or primitive.
1143
1156
  * @param targetClientId - When specified, the signal is only sent to the provided client id.
1144
1157
  */
1145
- public submitSignal(type: string, content: unknown, targetClientId?: string) {
1158
+ public submitSignal(type: string, content: unknown, targetClientId?: string): void {
1146
1159
  this.verifyNotClosed();
1147
- return this.dataStoreContext.submitSignal(type, content, targetClientId);
1160
+ this.dataStoreContext.submitSignal(type, content, targetClientId);
1148
1161
  }
1149
1162
 
1150
1163
  /**
@@ -1201,14 +1214,14 @@ export class FluidDataStoreRuntime
1201
1214
  context.makeVisible();
1202
1215
  }
1203
1216
 
1204
- private submitChannelOp(address: string, contents: any, localOpMetadata: unknown) {
1217
+ private submitChannelOp(address: string, contents: unknown, localOpMetadata: unknown): void {
1205
1218
  const envelope: IEnvelope = { address, contents };
1206
1219
  this.submit(DataStoreMessageType.ChannelOp, envelope, localOpMetadata);
1207
1220
  }
1208
1221
 
1209
1222
  private submit(
1210
1223
  type: DataStoreMessageType,
1211
- content: any,
1224
+ content: unknown,
1212
1225
  localOpMetadata: unknown = undefined,
1213
1226
  ): void {
1214
1227
  this.verifyNotClosed();
@@ -1224,10 +1237,12 @@ export class FluidDataStoreRuntime
1224
1237
  */
1225
1238
  public reSubmit(
1226
1239
  type: DataStoreMessageType,
1240
+ // TODO: use something other than `any` here (breaking change)
1241
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
1227
1242
  content: any,
1228
1243
  localOpMetadata: unknown,
1229
1244
  squash?: boolean,
1230
- ) {
1245
+ ): void {
1231
1246
  this.verifyNotClosed();
1232
1247
 
1233
1248
  switch (type) {
@@ -1239,12 +1254,14 @@ export class FluidDataStoreRuntime
1239
1254
  channelContext.reSubmit(envelope.contents, localOpMetadata, squash);
1240
1255
  break;
1241
1256
  }
1242
- case DataStoreMessageType.Attach:
1257
+ case DataStoreMessageType.Attach: {
1243
1258
  // For Attach messages, just submit them again.
1244
1259
  this.submit(type, content, localOpMetadata);
1245
1260
  break;
1246
- default:
1261
+ }
1262
+ default: {
1247
1263
  unreachableCase(type);
1264
+ }
1248
1265
  }
1249
1266
  }
1250
1267
 
@@ -1253,7 +1270,13 @@ export class FluidDataStoreRuntime
1253
1270
  * @param content - The content of the original message.
1254
1271
  * @param localOpMetadata - The local metadata associated with the original message.
1255
1272
  */
1256
- public rollback?(type: DataStoreMessageType, content: any, localOpMetadata: unknown) {
1273
+ public rollback?(
1274
+ type: DataStoreMessageType,
1275
+ // TODO: use something other than `any` here (breaking change)
1276
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
1277
+ content: any,
1278
+ localOpMetadata: unknown,
1279
+ ): void {
1257
1280
  this.verifyNotClosed();
1258
1281
 
1259
1282
  switch (type) {
@@ -1265,15 +1288,20 @@ export class FluidDataStoreRuntime
1265
1288
  channelContext.rollback(envelope.contents, localOpMetadata);
1266
1289
  break;
1267
1290
  }
1268
- default:
1291
+ default: {
1269
1292
  throw new LoggingError(`Can't rollback ${type} message`);
1293
+ }
1270
1294
  }
1271
1295
  }
1272
1296
 
1297
+ // TODO: use something other than `any` here
1298
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
1273
1299
  public async applyStashedOp(content: any): Promise<unknown> {
1300
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
1274
1301
  const type = content?.type as DataStoreMessageType;
1275
1302
  switch (type) {
1276
1303
  case DataStoreMessageType.Attach: {
1304
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
1277
1305
  const attachMessage = content.content as IAttachMessage;
1278
1306
 
1279
1307
  const flatBlobs = new Map<string, ArrayBufferLike>();
@@ -1295,14 +1323,16 @@ export class FluidDataStoreRuntime
1295
1323
  return;
1296
1324
  }
1297
1325
  case DataStoreMessageType.ChannelOp: {
1326
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
1298
1327
  const envelope = content.content as IEnvelope;
1299
1328
  const channelContext = this.contexts.get(envelope.address);
1300
1329
  assert(!!channelContext, 0x184 /* "There should be a channel context for the op" */);
1301
1330
  await channelContext.getChannel();
1302
1331
  return channelContext.applyStashedOp(envelope.contents);
1303
1332
  }
1304
- default:
1333
+ default: {
1305
1334
  unreachableCase(type);
1335
+ }
1306
1336
  }
1307
1337
  }
1308
1338
 
@@ -1311,23 +1341,25 @@ export class FluidDataStoreRuntime
1311
1341
  this.dataStoreContext.setChannelDirty(address);
1312
1342
  }
1313
1343
 
1314
- private attachListener() {
1344
+ private attachListener(): void {
1315
1345
  this.setMaxListeners(Number.MAX_SAFE_INTEGER);
1316
1346
 
1317
1347
  // back-compat, to be removed in the future.
1318
1348
  // Added in "2.0.0-rc.2.0.0" timeframe.
1349
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-explicit-any
1319
1350
  (this.dataStoreContext as any).once?.("attaching", () => {
1320
1351
  this.setAttachState(AttachState.Attaching);
1321
1352
  });
1322
1353
 
1323
1354
  // back-compat, to be removed in the future.
1324
1355
  // Added in "2.0.0-rc.2.0.0" timeframe.
1356
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-explicit-any
1325
1357
  (this.dataStoreContext as any).once?.("attached", () => {
1326
1358
  this.setAttachState(AttachState.Attached);
1327
1359
  });
1328
1360
  }
1329
1361
 
1330
- private verifyNotClosed() {
1362
+ private verifyNotClosed(): void {
1331
1363
  if (this._disposed) {
1332
1364
  throw new LoggingError("Runtime is closed");
1333
1365
  }
@@ -1342,7 +1374,7 @@ export class FluidDataStoreRuntime
1342
1374
  eventName: string,
1343
1375
  channelId: string,
1344
1376
  channelType: string,
1345
- ) {
1377
+ ): void {
1346
1378
  if (this.clientDetails.type !== "summarizer" || this.localChangesTelemetryCount <= 0) {
1347
1379
  return;
1348
1380
  }
@@ -1365,7 +1397,7 @@ export class FluidDataStoreRuntime
1365
1397
 
1366
1398
  public setAttachState(attachState: AttachState.Attaching | AttachState.Attached): void {
1367
1399
  switch (attachState) {
1368
- case AttachState.Attaching:
1400
+ case AttachState.Attaching: {
1369
1401
  /**
1370
1402
  * back-compat 0.59.1000 - Ideally, attachGraph() should have already been called making the data store
1371
1403
  * locally visible. However, before visibility state was added, this may not have been the case and data
@@ -1386,16 +1418,17 @@ export class FluidDataStoreRuntime
1386
1418
 
1387
1419
  // Mark the data store globally visible and make its child channels visible as well.
1388
1420
  this.visibilityState = VisibilityState.GloballyVisible;
1389
- this.localChannelContextQueue.forEach((channel) => {
1421
+ for (const [, channel] of this.localChannelContextQueue) {
1390
1422
  channel.makeVisible();
1391
- });
1423
+ }
1392
1424
  this.localChannelContextQueue.clear();
1393
1425
 
1394
1426
  // This promise resolution will be moved to attached event once we fix the scheduler.
1395
1427
  this.deferredAttached.resolve();
1396
1428
  this.emit("attaching");
1397
1429
  break;
1398
- case AttachState.Attached:
1430
+ }
1431
+ case AttachState.Attached: {
1399
1432
  assert(
1400
1433
  this.visibilityState === VisibilityState.GloballyVisible,
1401
1434
  0x2d2 /* "Data store should be globally visible when its attached." */,
@@ -1403,8 +1436,10 @@ export class FluidDataStoreRuntime
1403
1436
  this._attachState = AttachState.Attached;
1404
1437
  this.emit("attached");
1405
1438
  break;
1406
- default:
1439
+ }
1440
+ default: {
1407
1441
  unreachableCase(attachState, "unreached");
1442
+ }
1408
1443
  }
1409
1444
  }
1410
1445
  }
@@ -1420,9 +1455,9 @@ export class FluidDataStoreRuntime
1420
1455
  export const mixinRequestHandler = (
1421
1456
  requestHandler: (request: IRequest, runtime: FluidDataStoreRuntime) => Promise<IResponse>,
1422
1457
  Base: typeof FluidDataStoreRuntime = FluidDataStoreRuntime,
1423
- ) =>
1458
+ ): typeof FluidDataStoreRuntime =>
1424
1459
  class RuntimeWithRequestHandler extends Base {
1425
- public async request(request: IRequest) {
1460
+ public async request(request: IRequest): Promise<IResponse> {
1426
1461
  const response = await super.request(request);
1427
1462
  if (response.status === 404) {
1428
1463
  return requestHandler(request, this);
@@ -1444,9 +1479,9 @@ export const mixinSummaryHandler = (
1444
1479
  runtime: FluidDataStoreRuntime,
1445
1480
  ) => Promise<{ path: string[]; content: string } | undefined>,
1446
1481
  Base: typeof FluidDataStoreRuntime = FluidDataStoreRuntime,
1447
- ) =>
1482
+ ): typeof FluidDataStoreRuntime =>
1448
1483
  class RuntimeWithSummarizerHandler extends Base {
1449
- private addBlob(summary: ISummaryTreeWithStats, path: string[], content: string) {
1484
+ private addBlob(summary: ISummaryTreeWithStats, path: string[], content: string): void {
1450
1485
  const firstName = path.shift();
1451
1486
  if (firstName === undefined) {
1452
1487
  throw new LoggingError("Path can't be empty");
@@ -1469,7 +1504,8 @@ export const mixinSummaryHandler = (
1469
1504
  summary.summary.tree[firstName] = blob;
1470
1505
  }
1471
1506
 
1472
- async summarize(...args: any[]) {
1507
+ async summarize(...args: any[]): Promise<ISummaryTreeWithStats> {
1508
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
1473
1509
  const summary = await super.summarize(...args);
1474
1510
 
1475
1511
  try {
@@ -1477,9 +1513,9 @@ export const mixinSummaryHandler = (
1477
1513
  if (content !== undefined) {
1478
1514
  this.addBlob(summary, content.path, content.content);
1479
1515
  }
1480
- } catch (e) {
1516
+ } catch (error) {
1481
1517
  // Any error coming from app-provided handler should be marked as DataProcessingError
1482
- throw DataProcessingError.wrapIfUnrecognized(e, "mixinSummaryHandler");
1518
+ throw DataProcessingError.wrapIfUnrecognized(error, "mixinSummaryHandler");
1483
1519
  }
1484
1520
 
1485
1521
  return summary;
@@ -77,6 +77,9 @@ export class FluidObjectHandle<
77
77
  /**
78
78
  * {@inheritDoc @fluidframework/core-interfaces#IFluidHandle.get}
79
79
  */
80
+ // TODO: Return `Promise<T>` instead of `Promise<any>`.
81
+ // This was clearly the intended typing of this API, but fixing it would be a breaking change.
82
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
80
83
  public async get(): Promise<any> {
81
84
  // Note that this return works whether we received a T or a Promise<T> for this.value in the constructor.
82
85
  return this.value;
@@ -91,18 +94,19 @@ export class FluidObjectHandle<
91
94
  }
92
95
 
93
96
  this.locallyVisible = true;
94
- this.pendingHandlesToMakeVisible.forEach((handle) => {
97
+ for (const handle of this.pendingHandlesToMakeVisible) {
95
98
  handle.attachGraph();
96
- });
99
+ }
97
100
  this.pendingHandlesToMakeVisible.clear();
98
101
  this.routeContext.attachGraph();
99
102
  }
100
103
 
104
+ // eslint-disable-next-line jsdoc/require-description
101
105
  /**
102
106
  * @deprecated No replacement provided. Arbitrary handles may not serve as a bind source.
103
107
  * @privateRemarks This implementation will be moved to SharedObjectHandle once this is removed.
104
108
  */
105
- public bind(handle: IFluidHandleInternal) {
109
+ public bind(handle: IFluidHandleInternal): void {
106
110
  // If this handle is visible, attach the graph of the incoming handle as well.
107
111
  if (this.visible) {
108
112
  handle.attachGraph();
@@ -42,7 +42,9 @@ import { ISharedObjectRegistry } from "./dataStoreRuntime.js";
42
42
  */
43
43
  export abstract class LocalChannelContextBase implements IChannelContext {
44
44
  private globallyVisible = false;
45
- /** Tracks the messages for this channel that are sent while it's not loaded */
45
+ /**
46
+ * Tracks the messages for this channel that are sent while it's not loaded
47
+ */
46
48
  protected pendingMessagesState: IPendingMessagesState = {
47
49
  messageCollections: [],
48
50
  pendingCount: 0,
@@ -57,7 +59,7 @@ export abstract class LocalChannelContextBase implements IChannelContext {
57
59
  assert(!this.id.includes("/"), 0x30f /* Channel context ID cannot contain slashes */);
58
60
  }
59
61
 
60
- protected get isGloballyVisible() {
62
+ protected get isGloballyVisible(): boolean {
61
63
  return this.globallyVisible;
62
64
  }
63
65
 
@@ -72,7 +74,7 @@ export abstract class LocalChannelContextBase implements IChannelContext {
72
74
  return this._channel !== undefined;
73
75
  }
74
76
 
75
- public setConnectionState(connected: boolean, clientId?: string) {
77
+ public setConnectionState(connected: boolean, clientId?: string): void {
76
78
  // Connection events are ignored if the data store is not yet globallyVisible or loaded
77
79
  if (this.globallyVisible && this.isLoaded) {
78
80
  this.services.value.deltaConnection.setConnectionState(connected);
@@ -101,13 +103,13 @@ export abstract class LocalChannelContextBase implements IChannelContext {
101
103
  );
102
104
  const propsCopy = {
103
105
  ...messageCollection,
104
- messagesContent: Array.from(messageCollection.messagesContent),
106
+ messagesContent: [...messageCollection.messagesContent],
105
107
  };
106
108
  this.pendingMessagesState.messageCollections.push(propsCopy);
107
109
  }
108
110
  }
109
111
 
110
- public reSubmit(content: any, localOpMetadata: unknown, squash: boolean) {
112
+ public reSubmit(content: unknown, localOpMetadata: unknown, squash: boolean): void {
111
113
  assert(this.isLoaded, 0x18a /* "Channel should be loaded to resubmit ops" */);
112
114
  assert(
113
115
  this.globallyVisible,
@@ -115,7 +117,7 @@ export abstract class LocalChannelContextBase implements IChannelContext {
115
117
  );
116
118
  this.services.value.deltaConnection.reSubmit(content, localOpMetadata, squash);
117
119
  }
118
- public rollback(content: any, localOpMetadata: unknown) {
120
+ public rollback(content: unknown, localOpMetadata: unknown): void {
119
121
  assert(this.isLoaded, 0x2ee /* "Channel should be loaded to rollback ops" */);
120
122
  assert(
121
123
  this.globallyVisible,
@@ -198,7 +200,7 @@ export abstract class LocalChannelContextBase implements IChannelContext {
198
200
  return channel.getGCData(fullGC);
199
201
  }
200
202
 
201
- public updateUsedRoutes(usedRoutes: string[]) {
203
+ public updateUsedRoutes(usedRoutes: string[]): void {
202
204
  /**
203
205
  * Currently, DDSes are always considered referenced and are not garbage collected.
204
206
  * Once we have GC at DDS level, this channel context's used routes will be updated as per the passed
@@ -216,7 +218,7 @@ export class RehydratedLocalChannelContext extends LocalChannelContextBase {
216
218
  dataStoreContext: IFluidDataStoreContext,
217
219
  storageService: IDocumentStorageService,
218
220
  logger: ITelemetryLoggerExt,
219
- submitFn: (content: any, localOpMetadata: unknown) => void,
221
+ submitFn: (content: unknown, localOpMetadata: unknown) => void,
220
222
  dirtyFn: (address: string) => void,
221
223
  private readonly snapshotTree: ISnapshotTree,
222
224
  extraBlob?: Map<string, ArrayBufferLike>,
@@ -267,9 +269,9 @@ export class RehydratedLocalChannelContext extends LocalChannelContextBase {
267
269
  this.services.value.deltaConnection.processMessages(messageCollection);
268
270
  }
269
271
  return channel;
270
- } catch (err) {
272
+ } catch (error) {
271
273
  throw DataProcessingError.wrapIfUnrecognized(
272
- err,
274
+ error,
273
275
  "rehydratedLocalChannelContextFailedToLoadChannel",
274
276
  undefined,
275
277
  );
@@ -282,7 +284,7 @@ export class RehydratedLocalChannelContext extends LocalChannelContextBase {
282
284
  };
283
285
  }
284
286
 
285
- public override applyStashedOp(content) {
287
+ public override applyStashedOp(content: unknown): unknown {
286
288
  return this.services.value.deltaConnection.applyStashedOp(content);
287
289
  }
288
290
 
@@ -293,12 +295,12 @@ export class RehydratedLocalChannelContext extends LocalChannelContextBase {
293
295
  let sanitize = false;
294
296
  const blobsContents = snapshotTree.blobsContents;
295
297
  if (blobsContents !== undefined) {
296
- Object.entries(blobsContents).forEach(([key, value]) => {
298
+ for (const [key, value] of Object.entries(blobsContents)) {
297
299
  blobMap.set(key, value);
298
300
  if (snapshotTree.blobs[key] !== undefined) {
299
301
  sanitize = true;
300
302
  }
301
- });
303
+ }
302
304
  }
303
305
  for (const value of Object.values(snapshotTree.trees)) {
304
306
  sanitize = sanitize || this.isSnapshotInOldFormatAndCollectBlobs(value, blobMap);
@@ -306,7 +308,7 @@ export class RehydratedLocalChannelContext extends LocalChannelContextBase {
306
308
  return sanitize;
307
309
  }
308
310
 
309
- private sanitizeSnapshot(snapshotTree: ISnapshotTree) {
311
+ private sanitizeSnapshot(snapshotTree: ISnapshotTree): void {
310
312
  const blobMapInitial = new Map(Object.entries(snapshotTree.blobs));
311
313
  for (const [blobName, blobId] of blobMapInitial.entries()) {
312
314
  const blobValue = blobMapInitial.get(blobId);
@@ -329,7 +331,7 @@ export class LocalChannelContext extends LocalChannelContextBase {
329
331
  dataStoreContext: IFluidDataStoreContext,
330
332
  storageService: IDocumentStorageService,
331
333
  logger: ITelemetryLoggerExt,
332
- submitFn: (content: any, localOpMetadata: unknown) => void,
334
+ submitFn: (content: unknown, localOpMetadata: unknown) => void,
333
335
  dirtyFn: (address: string) => void,
334
336
  ) {
335
337
  super(
@@ -355,7 +357,7 @@ export class LocalChannelContext extends LocalChannelContextBase {
355
357
  };
356
358
  }
357
359
 
358
- public applyStashedOp() {
360
+ public applyStashedOp(): void {
359
361
  throw new Error("no stashed ops on local channel");
360
362
  }
361
363
  }