@fluidframework/map 2.0.0-internal.2.2.1 → 2.0.0-internal.2.3.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 (59) hide show
  1. package/.eslintrc.js +4 -1
  2. package/dist/directory.d.ts +5 -4
  3. package/dist/directory.d.ts.map +1 -1
  4. package/dist/directory.js +26 -11
  5. package/dist/directory.js.map +1 -1
  6. package/dist/interfaces.d.ts +3 -4
  7. package/dist/interfaces.d.ts.map +1 -1
  8. package/dist/interfaces.js.map +1 -1
  9. package/dist/internalInterfaces.d.ts +39 -0
  10. package/dist/internalInterfaces.d.ts.map +1 -1
  11. package/dist/internalInterfaces.js.map +1 -1
  12. package/dist/localValues.d.ts +12 -3
  13. package/dist/localValues.d.ts.map +1 -1
  14. package/dist/localValues.js +10 -0
  15. package/dist/localValues.js.map +1 -1
  16. package/dist/map.d.ts +4 -4
  17. package/dist/map.d.ts.map +1 -1
  18. package/dist/map.js +11 -0
  19. package/dist/map.js.map +1 -1
  20. package/dist/mapKernel.d.ts +5 -5
  21. package/dist/mapKernel.d.ts.map +1 -1
  22. package/dist/mapKernel.js +25 -11
  23. package/dist/mapKernel.js.map +1 -1
  24. package/dist/packageVersion.d.ts +1 -1
  25. package/dist/packageVersion.js +1 -1
  26. package/dist/packageVersion.js.map +1 -1
  27. package/lib/directory.d.ts +5 -4
  28. package/lib/directory.d.ts.map +1 -1
  29. package/lib/directory.js +26 -11
  30. package/lib/directory.js.map +1 -1
  31. package/lib/interfaces.d.ts +3 -4
  32. package/lib/interfaces.d.ts.map +1 -1
  33. package/lib/interfaces.js.map +1 -1
  34. package/lib/internalInterfaces.d.ts +39 -0
  35. package/lib/internalInterfaces.d.ts.map +1 -1
  36. package/lib/internalInterfaces.js.map +1 -1
  37. package/lib/localValues.d.ts +12 -3
  38. package/lib/localValues.d.ts.map +1 -1
  39. package/lib/localValues.js +10 -0
  40. package/lib/localValues.js.map +1 -1
  41. package/lib/map.d.ts +4 -4
  42. package/lib/map.d.ts.map +1 -1
  43. package/lib/map.js +11 -0
  44. package/lib/map.js.map +1 -1
  45. package/lib/mapKernel.d.ts +5 -5
  46. package/lib/mapKernel.d.ts.map +1 -1
  47. package/lib/mapKernel.js +25 -11
  48. package/lib/mapKernel.js.map +1 -1
  49. package/lib/packageVersion.d.ts +1 -1
  50. package/lib/packageVersion.js +1 -1
  51. package/lib/packageVersion.js.map +1 -1
  52. package/package.json +16 -14
  53. package/src/directory.ts +85 -54
  54. package/src/interfaces.ts +19 -9
  55. package/src/internalInterfaces.ts +45 -0
  56. package/src/localValues.ts +18 -7
  57. package/src/map.ts +28 -17
  58. package/src/mapKernel.ts +50 -32
  59. package/src/packageVersion.ts +1 -1
package/src/directory.ts CHANGED
@@ -40,7 +40,7 @@ import { pkgVersion } from "./packageVersion";
40
40
 
41
41
  // We use path-browserify since this code can run safely on the server or the browser.
42
42
  // We standardize on using posix slashes everywhere.
43
- const posix: typeof import("path").posix = path.posix;
43
+ const posix = path.posix;
44
44
 
45
45
  const snapshotFileName = "header";
46
46
 
@@ -252,14 +252,14 @@ export class DirectoryFactory implements IChannelFactory {
252
252
  /**
253
253
  * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory."type"}
254
254
  */
255
- public get type() {
255
+ public get type(): string {
256
256
  return DirectoryFactory.Type;
257
257
  }
258
258
 
259
259
  /**
260
260
  * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.attributes}
261
261
  */
262
- public get attributes() {
262
+ public get attributes(): IChannelAttributes {
263
263
  return DirectoryFactory.Attributes;
264
264
  }
265
265
 
@@ -355,7 +355,7 @@ export class SharedDirectory extends SharedObject<ISharedDirectoryEvents> implem
355
355
  * @param runtime - Data store runtime
356
356
  * @param type - Type identifier
357
357
  */
358
- constructor(
358
+ public constructor(
359
359
  id: string,
360
360
  runtime: IFluidDataStoreRuntime,
361
361
  attributes: IChannelAttributes,
@@ -387,6 +387,8 @@ export class SharedDirectory extends SharedObject<ISharedDirectoryEvents> implem
387
387
  /**
388
388
  * {@inheritDoc IDirectory.get}
389
389
  */
390
+ // TODO: Use `unknown` instead (breaking change).
391
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
390
392
  public get<T = any>(key: string): T | undefined {
391
393
  return this.root.get<T>(key);
392
394
  }
@@ -394,7 +396,7 @@ export class SharedDirectory extends SharedObject<ISharedDirectoryEvents> implem
394
396
  /**
395
397
  * {@inheritDoc IDirectory.set}
396
398
  */
397
- public set<T = any>(key: string, value: T): this {
399
+ public set<T = unknown>(key: string, value: T): this {
398
400
  this.root.set(key, value);
399
401
  return this;
400
402
  }
@@ -443,7 +445,10 @@ export class SharedDirectory extends SharedObject<ISharedDirectoryEvents> implem
443
445
  * Issue a callback on each entry under this IDirectory.
444
446
  * @param callback - Callback to issue
445
447
  */
448
+ // TODO: Use `unknown` instead (breaking change).
449
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
446
450
  public forEach(callback: (value: any, key: string, map: Map<string, any>) => void): void {
451
+ // eslint-disable-next-line unicorn/no-array-for-each, unicorn/no-array-callback-reference
447
452
  this.root.forEach(callback);
448
453
  }
449
454
 
@@ -451,6 +456,8 @@ export class SharedDirectory extends SharedObject<ISharedDirectoryEvents> implem
451
456
  * Get an iterator over the entries under this IDirectory.
452
457
  * @returns The iterator
453
458
  */
459
+ // TODO: Use `unknown` instead (breaking change).
460
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
454
461
  public [Symbol.iterator](): IterableIterator<[string, any]> {
455
462
  return this.root[Symbol.iterator]();
456
463
  }
@@ -459,6 +466,8 @@ export class SharedDirectory extends SharedObject<ISharedDirectoryEvents> implem
459
466
  * Get an iterator over the entries under this IDirectory.
460
467
  * @returns The iterator
461
468
  */
469
+ // TODO: Use `unknown` instead (breaking change).
470
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
462
471
  public entries(): IterableIterator<[string, any]> {
463
472
  return this.root.entries();
464
473
  }
@@ -482,6 +491,8 @@ export class SharedDirectory extends SharedObject<ISharedDirectoryEvents> implem
482
491
  * Get an iterator over the values under this IDirectory.
483
492
  * @returns The iterator
484
493
  */
494
+ // TODO: Use `unknown` instead (breaking change).
495
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
485
496
  public values(): IterableIterator<any> {
486
497
  return this.root.values();
487
498
  }
@@ -531,7 +542,7 @@ export class SharedDirectory extends SharedObject<ISharedDirectoryEvents> implem
531
542
  }
532
543
 
533
544
  let currentSubDir = this.root;
534
- const subdirs = absolutePath.substr(1).split(posix.sep);
545
+ const subdirs = absolutePath.slice(1).split(posix.sep);
535
546
  for (const subdir of subdirs) {
536
547
  currentSubDir = currentSubDir.getSubDirectory(subdir) as SubDirectory;
537
548
  if (!currentSubDir) {
@@ -559,7 +570,7 @@ export class SharedDirectory extends SharedObject<ISharedDirectoryEvents> implem
559
570
  * this op while it has not been ack'd. This will be sent when we receive this op back from the server.
560
571
  * @internal
561
572
  */
562
- public submitDirectoryMessage(op: IDirectoryOperation, localOpMetadata: unknown) {
573
+ public submitDirectoryMessage(op: IDirectoryOperation, localOpMetadata: unknown): void {
563
574
  this.submitLocalMessage(op, localOpMetadata);
564
575
  }
565
576
 
@@ -567,13 +578,13 @@ export class SharedDirectory extends SharedObject<ISharedDirectoryEvents> implem
567
578
  * {@inheritDoc @fluidframework/shared-object-base#SharedObject.onDisconnect}
568
579
  * @internal
569
580
  */
570
- protected onDisconnect() { }
581
+ protected onDisconnect(): void { }
571
582
 
572
583
  /**
573
584
  * {@inheritDoc @fluidframework/shared-object-base#SharedObject.reSubmitCore}
574
585
  * @internal
575
586
  */
576
- protected reSubmitCore(content: any, localOpMetadata: unknown) {
587
+ protected reSubmitCore(content: unknown, localOpMetadata: unknown): void {
577
588
  const message = content as IDirectoryOperation;
578
589
  const handler = this.messageHandlers.get(message.type);
579
590
  assert(handler !== undefined, 0x00d /* Missing message handler for message type */);
@@ -584,7 +595,7 @@ export class SharedDirectory extends SharedObject<ISharedDirectoryEvents> implem
584
595
  * {@inheritDoc @fluidframework/shared-object-base#SharedObject.loadCore}
585
596
  * @internal
586
597
  */
587
- protected async loadCore(storage: IChannelStorageService) {
598
+ protected async loadCore(storage: IChannelStorageService): Promise<void> {
588
599
  const data = await readAndParse(storage, snapshotFileName);
589
600
  const newFormat = data as IDirectoryNewStorageFormat;
590
601
  if (Array.isArray(newFormat.blobs)) {
@@ -605,7 +616,7 @@ export class SharedDirectory extends SharedObject<ISharedDirectoryEvents> implem
605
616
  * @param data - A JSON string containing serialized directory data
606
617
  * @internal
607
618
  */
608
- protected populate(data: IDirectoryDataObject) {
619
+ protected populate(data: IDirectoryDataObject): void {
609
620
  const stack: [SubDirectory, IDirectoryDataObject][] = [];
610
621
  stack.push([this.root, data]);
611
622
  while (stack.length > 0) {
@@ -657,7 +668,7 @@ export class SharedDirectory extends SharedObject<ISharedDirectoryEvents> implem
657
668
  * {@inheritDoc @fluidframework/shared-object-base#SharedObject.rollback}
658
669
  * @internal
659
670
  */
660
- protected rollback(content: any, localOpMetadata: unknown) {
671
+ protected rollback(content: unknown, localOpMetadata: unknown): void {
661
672
  const op: IDirectoryOperation = content as IDirectoryOperation;
662
673
  const subdir = this.getWorkingDirectory(op.path) as SubDirectory | undefined;
663
674
  if (subdir) {
@@ -787,7 +798,6 @@ export class SharedDirectory extends SharedObject<ISharedDirectoryEvents> implem
787
798
  parentSubdir.resubmitSubDirectoryMessage(op, localOpMetadata);
788
799
  }
789
800
  },
790
- // eslint-disable-next-line max-len
791
801
  applyStashedOp: (op: IDirectoryCreateSubDirectoryOperation): ICreateSubDirLocalOpMetadata | undefined => {
792
802
  const parentSubdir = this.getWorkingDirectory(op.path) as SubDirectory | undefined;
793
803
  if (parentSubdir) {
@@ -813,7 +823,6 @@ export class SharedDirectory extends SharedObject<ISharedDirectoryEvents> implem
813
823
  parentSubdir.resubmitSubDirectoryMessage(op, localOpMetadata);
814
824
  }
815
825
  },
816
- // eslint-disable-next-line max-len
817
826
  applyStashedOp: (op: IDirectoryDeleteSubDirectoryOperation): IDeleteSubDirLocalOpMetadata | undefined => {
818
827
  const parentSubdir = this.getWorkingDirectory(op.path) as SubDirectory | undefined;
819
828
  if (parentSubdir) {
@@ -825,10 +834,11 @@ export class SharedDirectory extends SharedObject<ISharedDirectoryEvents> implem
825
834
  }
826
835
 
827
836
  /**
837
+ * {@inheritDoc @fluidframework/shared-object-base#SharedObjectCore.applyStashedOp}
828
838
  * @internal
829
839
  */
830
- protected applyStashedOp(op) {
831
- const handler = this.messageHandlers.get(op.type);
840
+ protected applyStashedOp(op: unknown): unknown {
841
+ const handler = this.messageHandlers.get((op as IDirectoryOperation).type);
832
842
  if (handler === undefined) {
833
843
  throw new Error("no apply stashed op handler");
834
844
  }
@@ -859,14 +869,13 @@ export class SharedDirectory extends SharedObject<ISharedDirectoryEvents> implem
859
869
  }
860
870
  const result: ISerializableValue = {
861
871
  type: value.type,
862
- // eslint-disable-next-line @typescript-eslint/ban-types
863
872
  value: value.value && JSON.parse(value.value) as object,
864
873
  };
865
874
  if (value.value && value.value.length >= MinValueSizeSeparateSnapshotBlob) {
866
875
  const extraContent: IDirectoryDataObject = {};
867
876
  let largeContent = extraContent;
868
877
  if (currentSubDir.absolutePath !== posix.sep) {
869
- for (const dir of currentSubDir.absolutePath.substr(1).split(posix.sep)) {
878
+ for (const dir of currentSubDir.absolutePath.slice(1).split(posix.sep)) {
870
879
  const subDataObject: IDirectoryDataObject = {};
871
880
  largeContent.subdirectories = { [dir]: subDataObject };
872
881
  largeContent = subDataObject;
@@ -929,6 +938,9 @@ interface IDeleteSubDirLocalOpMetadata {
929
938
  type SubDirLocalOpMetadata = ICreateSubDirLocalOpMetadata | IDeleteSubDirLocalOpMetadata;
930
939
  type DirectoryLocalOpMetadata = IClearLocalOpMetadata | IKeyEditLocalOpMetadata | SubDirLocalOpMetadata;
931
940
 
941
+
942
+ /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */
943
+
932
944
  function isKeyEditLocalOpMetadata(metadata: any): metadata is IKeyEditLocalOpMetadata {
933
945
  return metadata !== undefined && typeof metadata.pendingMessageId === "number" && metadata.type === "edit";
934
946
  }
@@ -951,6 +963,8 @@ function isDirectoryLocalOpMetadata(metadata: any): metadata is DirectoryLocalOp
951
963
  (metadata.type === "createSubDir" && typeof metadata.previouslyExisted === "boolean"));
952
964
  }
953
965
 
966
+ /* eslint-enable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */
967
+
954
968
  /**
955
969
  * Node of the directory tree.
956
970
  * @sealed
@@ -1003,7 +1017,7 @@ class SubDirectory extends TypedEventEmitter<IDirectoryEvents> implements IDirec
1003
1017
  * @param serializer - The serializer to serialize / parse handles
1004
1018
  * @param absolutePath - The absolute path of this IDirectory
1005
1019
  */
1006
- constructor(
1020
+ public constructor(
1007
1021
  private readonly directory: SharedDirectory,
1008
1022
  private readonly runtime: IFluidDataStoreRuntime,
1009
1023
  private readonly serializer: IFluidSerializer,
@@ -1028,7 +1042,7 @@ class SubDirectory extends TypedEventEmitter<IDirectoryEvents> implements IDirec
1028
1042
  return this._deleted;
1029
1043
  }
1030
1044
 
1031
- private throwIfDisposed() {
1045
+ private throwIfDisposed(): void {
1032
1046
  if (this._deleted) {
1033
1047
  throw new UsageError("Cannot access Disposed subDirectory");
1034
1048
  }
@@ -1047,7 +1061,7 @@ class SubDirectory extends TypedEventEmitter<IDirectoryEvents> implements IDirec
1047
1061
  /**
1048
1062
  * {@inheritDoc IDirectory.get}
1049
1063
  */
1050
- public get<T = any>(key: string): T | undefined {
1064
+ public get<T = unknown>(key: string): T | undefined {
1051
1065
  this.throwIfDisposed();
1052
1066
  return this._storage.get(key)?.value as T | undefined;
1053
1067
  }
@@ -1055,7 +1069,7 @@ class SubDirectory extends TypedEventEmitter<IDirectoryEvents> implements IDirec
1055
1069
  /**
1056
1070
  * {@inheritDoc IDirectory.set}
1057
1071
  */
1058
- public set<T = any>(key: string, value: T): this {
1072
+ public set<T = unknown>(key: string, value: T): this {
1059
1073
  this.throwIfDisposed();
1060
1074
  // Undefined/null keys can't be serialized to JSON in the manner we currently snapshot.
1061
1075
  if (key === undefined || key === null) {
@@ -1238,8 +1252,9 @@ class SubDirectory extends TypedEventEmitter<IDirectoryEvents> implements IDirec
1238
1252
  * Issue a callback on each entry under this IDirectory.
1239
1253
  * @param callback - Callback to issue
1240
1254
  */
1241
- public forEach(callback: (value: any, key: string, map: Map<string, any>) => void): void {
1255
+ public forEach(callback: (value: unknown, key: string, map: Map<string, unknown>) => void): void {
1242
1256
  this.throwIfDisposed();
1257
+ // eslint-disable-next-line unicorn/no-array-for-each
1243
1258
  this._storage.forEach((localValue, key, map) => {
1244
1259
  callback(localValue.value, key, map);
1245
1260
  });
@@ -1257,17 +1272,17 @@ class SubDirectory extends TypedEventEmitter<IDirectoryEvents> implements IDirec
1257
1272
  * Get an iterator over the entries under this IDirectory.
1258
1273
  * @returns The iterator
1259
1274
  */
1260
- public entries(): IterableIterator<[string, any]> {
1275
+ public entries(): IterableIterator<[string, unknown]> {
1261
1276
  this.throwIfDisposed();
1262
1277
  const localEntriesIterator = this._storage.entries();
1263
1278
  const iterator = {
1264
- next(): IteratorResult<[string, any]> {
1279
+ next(): IteratorResult<[string, unknown]> {
1265
1280
  const nextVal = localEntriesIterator.next();
1266
1281
  return nextVal.done
1267
1282
  ? { value: undefined, done: true }
1268
1283
  : { value: [nextVal.value[0], nextVal.value[1].value], done: false };
1269
1284
  },
1270
- [Symbol.iterator]() {
1285
+ [Symbol.iterator](): IterableIterator<[string, unknown]> {
1271
1286
  return this;
1272
1287
  },
1273
1288
  };
@@ -1287,17 +1302,17 @@ class SubDirectory extends TypedEventEmitter<IDirectoryEvents> implements IDirec
1287
1302
  * Get an iterator over the values under this IDirectory.
1288
1303
  * @returns The iterator
1289
1304
  */
1290
- public values(): IterableIterator<any> {
1305
+ public values(): IterableIterator<unknown> {
1291
1306
  this.throwIfDisposed();
1292
1307
  const localValuesIterator = this._storage.values();
1293
1308
  const iterator = {
1294
- next(): IteratorResult<any> {
1309
+ next(): IteratorResult<unknown> {
1295
1310
  const nextVal = localValuesIterator.next();
1296
1311
  return nextVal.done
1297
1312
  ? { value: undefined, done: true }
1298
1313
  : { value: nextVal.value.value, done: false };
1299
1314
  },
1300
- [Symbol.iterator]() {
1315
+ [Symbol.iterator](): IterableIterator<unknown> {
1301
1316
  return this;
1302
1317
  },
1303
1318
  };
@@ -1308,7 +1323,7 @@ class SubDirectory extends TypedEventEmitter<IDirectoryEvents> implements IDirec
1308
1323
  * Get an iterator over the entries under this IDirectory.
1309
1324
  * @returns The iterator
1310
1325
  */
1311
- public [Symbol.iterator](): IterableIterator<[string, any]> {
1326
+ public [Symbol.iterator](): IterableIterator<[string, unknown]> {
1312
1327
  this.throwIfDisposed();
1313
1328
  return this.entries();
1314
1329
  }
@@ -1673,7 +1688,7 @@ class SubDirectory extends TypedEventEmitter<IDirectoryEvents> implements IDirec
1673
1688
  * @returns The JSONable string representing the storage of this subdirectory
1674
1689
  * @internal
1675
1690
  */
1676
- public *getSerializedStorage(serializer: IFluidSerializer) {
1691
+ public *getSerializedStorage(serializer: IFluidSerializer): Generator<[string, ISerializedValue], void> {
1677
1692
  this.throwIfDisposed();
1678
1693
  for (const [key, localValue] of this._storage) {
1679
1694
  const value = localValue.makeSerialized(serializer, this.directory.handle);
@@ -1721,7 +1736,7 @@ class SubDirectory extends TypedEventEmitter<IDirectoryEvents> implements IDirec
1721
1736
  * @param map - map tracking the pending messages
1722
1737
  * @param key - key of the edit in the op
1723
1738
  */
1724
- private rollbackPendingMessageId(map: Map<string, number[]>, key: string, pendingMessageId) {
1739
+ private rollbackPendingMessageId(map: Map<string, number[]>, key: string, pendingMessageId): void {
1725
1740
  const pendingMessageIds = map.get(key);
1726
1741
  const lastPendingMessageId = pendingMessageIds?.pop();
1727
1742
  if (!pendingMessageIds || lastPendingMessageId !== pendingMessageId) {
@@ -1732,20 +1747,23 @@ class SubDirectory extends TypedEventEmitter<IDirectoryEvents> implements IDirec
1732
1747
  }
1733
1748
  }
1734
1749
 
1750
+ /* eslint-disable @typescript-eslint/no-unsafe-member-access */
1751
+
1735
1752
  /**
1736
1753
  * Rollback a local op
1737
1754
  * @param op - The operation to rollback
1738
1755
  * @param localOpMetadata - The local metadata associated with the op.
1739
1756
  */
1740
- public rollback(op: any, localOpMetadata: unknown) {
1757
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1758
+ public rollback(op: any, localOpMetadata: unknown): void {
1741
1759
  if (!isDirectoryLocalOpMetadata(localOpMetadata)) {
1742
1760
  throw new Error("Invalid localOpMetadata");
1743
1761
  }
1744
1762
 
1745
1763
  if (op.type === "clear" && localOpMetadata.type === "clear") {
1746
- localOpMetadata.previousStorage.forEach((localValue, key) => {
1764
+ for (const [key, localValue] of localOpMetadata.previousStorage.entries()) {
1747
1765
  this.setCore(key, localValue, true);
1748
- });
1766
+ }
1749
1767
 
1750
1768
  const lastPendingClearId = this.pendingClearMessageIds.pop();
1751
1769
  if (lastPendingClearId === undefined || lastPendingClearId !== localOpMetadata.pendingMessageId) {
@@ -1753,32 +1771,42 @@ class SubDirectory extends TypedEventEmitter<IDirectoryEvents> implements IDirec
1753
1771
  }
1754
1772
  } else if ((op.type === "delete" || op.type === "set") && localOpMetadata.type === "edit") {
1755
1773
  if (localOpMetadata.previousValue === undefined) {
1756
- this.deleteCore(op.key, true);
1774
+ this.deleteCore(op.key as string, true);
1757
1775
  } else {
1758
- this.setCore(op.key, localOpMetadata.previousValue, true);
1776
+ this.setCore(op.key as string, localOpMetadata.previousValue, true);
1759
1777
  }
1760
1778
 
1761
- this.rollbackPendingMessageId(this.pendingKeys, op.key, localOpMetadata.pendingMessageId);
1779
+ this.rollbackPendingMessageId(this.pendingKeys, op.key as string, localOpMetadata.pendingMessageId);
1762
1780
  } else if (op.type === "createSubDirectory" && localOpMetadata.type === "createSubDir") {
1763
1781
  if (!localOpMetadata.previouslyExisted) {
1764
- this.deleteSubDirectoryCore(op.subdirName, true);
1782
+ this.deleteSubDirectoryCore(op.subdirName as string, true);
1765
1783
  }
1766
1784
 
1767
- this.rollbackPendingMessageId(this.pendingSubDirectories, op.subdirName, localOpMetadata.pendingMessageId);
1785
+ this.rollbackPendingMessageId(
1786
+ this.pendingSubDirectories,
1787
+ op.subdirName as string,
1788
+ localOpMetadata.pendingMessageId
1789
+ );
1768
1790
  } else if (op.type === "deleteSubDirectory" && localOpMetadata.type === "deleteSubDir") {
1769
1791
  if (localOpMetadata.subDirectory !== undefined) {
1770
1792
  this.undeleteSubDirectoryTree(localOpMetadata.subDirectory);
1771
1793
  // don't need to register events because deleting never unregistered
1772
- this._subdirectories.set(op.subdirName, localOpMetadata.subDirectory);
1794
+ this._subdirectories.set(op.subdirName as string, localOpMetadata.subDirectory);
1773
1795
  this.emit("subDirectoryCreated", op.subdirName, true, this);
1774
1796
  }
1775
1797
 
1776
- this.rollbackPendingMessageId(this.pendingSubDirectories, op.subdirName, localOpMetadata.pendingMessageId);
1798
+ this.rollbackPendingMessageId(
1799
+ this.pendingSubDirectories,
1800
+ op.subdirName as string,
1801
+ localOpMetadata.pendingMessageId
1802
+ );
1777
1803
  } else {
1778
1804
  throw new Error("Unsupported op for rollback");
1779
1805
  }
1780
1806
  }
1781
1807
 
1808
+ /* eslint-enable @typescript-eslint/no-unsafe-member-access */
1809
+
1782
1810
  /**
1783
1811
  * Converts the given relative path into an absolute path.
1784
1812
  * @param path - Relative path to convert
@@ -1871,25 +1899,28 @@ class SubDirectory extends TypedEventEmitter<IDirectoryEvents> implements IDirec
1871
1899
  /**
1872
1900
  * Clear all keys in memory in response to a remote clear, but retain keys we have modified but not yet been ack'd.
1873
1901
  */
1874
- private clearExceptPendingKeys(local: boolean) {
1902
+ private clearExceptPendingKeys(local: boolean): void {
1875
1903
  // Assuming the pendingKeys is small and the map is large
1876
1904
  // we will get the value for the pendingKeys and clear the map
1877
1905
  const temp = new Map<string, ILocalValue>();
1878
- this.pendingKeys.forEach((value, key, map) => {
1906
+
1907
+ for (const [key] of this.pendingKeys) {
1879
1908
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1880
1909
  temp.set(key, this._storage.get(key)!);
1881
- });
1910
+ }
1911
+
1882
1912
  this.clearCore(local);
1883
- temp.forEach((value, key, map) => {
1913
+
1914
+ for (const [key, value] of temp.entries()) {
1884
1915
  this.setCore(key, value, true);
1885
- });
1916
+ }
1886
1917
  }
1887
1918
 
1888
1919
  /**
1889
1920
  * Clear implementation used for both locally sourced clears as well as incoming remote clears.
1890
1921
  * @param local - Whether the message originated from the local client
1891
1922
  */
1892
- private clearCore(local: boolean) {
1923
+ private clearCore(local: boolean): void {
1893
1924
  this._storage.clear();
1894
1925
  this.directory.emit("clear", local, this.directory);
1895
1926
  }
@@ -1902,7 +1933,7 @@ class SubDirectory extends TypedEventEmitter<IDirectoryEvents> implements IDirec
1902
1933
  */
1903
1934
  private deleteCore(key: string, local: boolean): ILocalValue | undefined {
1904
1935
  const previousLocalValue = this._storage.get(key);
1905
- const previousValue = previousLocalValue?.value;
1936
+ const previousValue: unknown = previousLocalValue?.value;
1906
1937
  const successfullyRemoved = this._storage.delete(key);
1907
1938
  if (successfullyRemoved) {
1908
1939
  const event: IDirectoryValueChanged = { key, path: this.absolutePath, previousValue };
@@ -1922,7 +1953,7 @@ class SubDirectory extends TypedEventEmitter<IDirectoryEvents> implements IDirec
1922
1953
  */
1923
1954
  private setCore(key: string, value: ILocalValue, local: boolean): ILocalValue | undefined {
1924
1955
  const previousLocalValue = this._storage.get(key);
1925
- const previousValue = previousLocalValue?.value;
1956
+ const previousValue: unknown = previousLocalValue?.value;
1926
1957
  this._storage.set(key, value);
1927
1958
  const event: IDirectoryValueChanged = { key, path: this.absolutePath, previousValue };
1928
1959
  this.directory.emit("valueChanged", event, local, this.directory);
@@ -1949,7 +1980,7 @@ class SubDirectory extends TypedEventEmitter<IDirectoryEvents> implements IDirec
1949
1980
  return false;
1950
1981
  }
1951
1982
 
1952
- private registerEventsOnSubDirectory(subDirectory: SubDirectory, subDirName: string) {
1983
+ private registerEventsOnSubDirectory(subDirectory: SubDirectory, subDirName: string): void {
1953
1984
  subDirectory.on("subDirectoryCreated", (relativePath: string, local: boolean) => {
1954
1985
  this.emit("subDirectoryCreated", posix.join(subDirName, relativePath), local, this);
1955
1986
  });
@@ -1963,7 +1994,7 @@ class SubDirectory extends TypedEventEmitter<IDirectoryEvents> implements IDirec
1963
1994
  * @param subdirName - The name of the subdirectory being deleted
1964
1995
  * @param local - Whether the message originated from the local client
1965
1996
  */
1966
- private deleteSubDirectoryCore(subdirName: string, local: boolean) {
1997
+ private deleteSubDirectoryCore(subdirName: string, local: boolean): SubDirectory | undefined {
1967
1998
  const previousValue = this._subdirectories.get(subdirName);
1968
1999
  // This should make the subdirectory structure unreachable so it can be GC'd and won't appear in snapshots
1969
2000
  // Might want to consider cleaning out the structure more exhaustively though? But not when rollback.
@@ -1975,7 +2006,7 @@ class SubDirectory extends TypedEventEmitter<IDirectoryEvents> implements IDirec
1975
2006
  return previousValue;
1976
2007
  }
1977
2008
 
1978
- private disposeSubDirectoryTree(directory: IDirectory | undefined) {
2009
+ private disposeSubDirectoryTree(directory: IDirectory | undefined): void {
1979
2010
  if (!directory) {
1980
2011
  return;
1981
2012
  }
@@ -1989,7 +2020,7 @@ class SubDirectory extends TypedEventEmitter<IDirectoryEvents> implements IDirec
1989
2020
  }
1990
2021
  }
1991
2022
 
1992
- private undeleteSubDirectoryTree(directory: SubDirectory) {
2023
+ private undeleteSubDirectoryTree(directory: SubDirectory): void {
1993
2024
  // Restore deleted subdirectory tree. This will unmark "deleted" from the subdirectories from bottom to top.
1994
2025
  for (const [_, subDirectory] of this._subdirectories.entries()) {
1995
2026
  this.undeleteSubDirectoryTree(subDirectory);
package/src/interfaces.ts CHANGED
@@ -18,15 +18,18 @@ export interface IValueChanged {
18
18
  /**
19
19
  * The value that was stored at the key prior to the change.
20
20
  */
21
+ // TODO: Use `unknown` instead (breaking change).
22
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
21
23
  previousValue: any;
22
24
  }
23
25
 
24
26
  /**
25
27
  * Interface describing actions on a directory.
26
28
  *
27
- * @remarks
28
- * When used as a Map, operates on its keys.
29
+ * @remarks When used as a Map, operates on its keys.
29
30
  */
31
+ // TODO: Use `unknown` instead (breaking change).
32
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
30
33
  export interface IDirectory extends Map<string, any>, IEventProvider<IDirectoryEvents>, Partial<IDisposable> {
31
34
  /**
32
35
  * The absolute path of the directory.
@@ -38,6 +41,8 @@ export interface IDirectory extends Map<string, any>, IEventProvider<IDirectoryE
38
41
  * @param key - Key to retrieve from
39
42
  * @returns The stored value, or undefined if the key is not set
40
43
  */
44
+ // TODO: Use `unknown` instead (breaking change).
45
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
41
46
  get<T = any>(key: string): T | undefined;
42
47
 
43
48
  /**
@@ -46,7 +51,7 @@ export interface IDirectory extends Map<string, any>, IEventProvider<IDirectoryE
46
51
  * @param value - Value to set
47
52
  * @returns The IDirectory itself
48
53
  */
49
- set<T = any>(key: string, value: T): this;
54
+ set<T = unknown>(key: string, value: T): this;
50
55
 
51
56
  /**
52
57
  * Get the number of sub directory within the directory.
@@ -165,7 +170,6 @@ export interface ISharedDirectoryEvents extends ISharedObjectEvents {
165
170
  *
166
171
  * - `target` - The {@link ISharedDirectory} itself.
167
172
  */
168
- // eslint-disable-next-line @typescript-eslint/unified-signatures
169
173
  (event: "subDirectoryDeleted", listener: (
170
174
  path: string,
171
175
  local: boolean,
@@ -226,7 +230,6 @@ export interface IDirectoryEvents extends IEvent {
226
230
  *
227
231
  * - `target` - The {@link ISharedDirectory} itself.
228
232
  */
229
- // eslint-disable-next-line @typescript-eslint/unified-signatures
230
233
  (event: "subDirectoryDeleted", listener: (
231
234
  path: string,
232
235
  local: boolean,
@@ -250,11 +253,13 @@ export interface IDirectoryEvents extends IEvent {
250
253
  * The values stored within can be accessed like a map, and the hierarchy can be navigated using path syntax.
251
254
  * SubDirectories can be retrieved for use as working directories.
252
255
  */
253
- export interface ISharedDirectory extends
254
- ISharedObject<ISharedDirectoryEvents & IDirectoryEvents>,
255
- Omit<IDirectory, "on" | "once" | "off"> {
256
+ export interface ISharedDirectory
257
+ extends ISharedObject<ISharedDirectoryEvents & IDirectoryEvents>, Omit<IDirectory, "on" | "once" | "off">
258
+ {
256
259
  // The Omit type excludes symbols, which we don't want to exclude. Adding them back here manually.
257
260
  // https://github.com/microsoft/TypeScript/issues/31671
261
+ // TODO: Use `unknown` instead (breaking change).
262
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
258
263
  [Symbol.iterator](): IterableIterator<[string, any]>;
259
264
  readonly [Symbol.toStringTag]: string;
260
265
  }
@@ -312,12 +317,16 @@ export interface ISharedMapEvents extends ISharedObjectEvents {
312
317
  *
313
318
  * For more information, including example usages, see {@link https://fluidframework.com/docs/data-structures/map/}.
314
319
  */
320
+ // TODO: Use `unknown` instead (breaking change).
321
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
315
322
  export interface ISharedMap extends ISharedObject<ISharedMapEvents>, Map<string, any> {
316
323
  /**
317
324
  * Retrieves the given key from the map if it exists.
318
325
  * @param key - Key to retrieve from
319
326
  * @returns The stored value, or undefined if the key is not set
320
327
  */
328
+ // TODO: Use `unknown` instead (breaking change).
329
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
321
330
  get<T = any>(key: string): T | undefined;
322
331
 
323
332
  /**
@@ -326,7 +335,7 @@ export interface ISharedMap extends ISharedObject<ISharedMapEvents>, Map<string,
326
335
  * @param value - Value to set
327
336
  * @returns The {@link ISharedMap} itself
328
337
  */
329
- set<T = any>(key: string, value: T): this;
338
+ set<T = unknown>(key: string, value: T): this;
330
339
  }
331
340
 
332
341
  /**
@@ -361,6 +370,7 @@ export interface ISerializableValue {
361
370
  /**
362
371
  * The JSONable representation of the value.
363
372
  */
373
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
364
374
  value: any;
365
375
  }
366
376
 
@@ -51,22 +51,67 @@ import { ILocalValue } from "./localValues";
51
51
  key: string;
52
52
  }
53
53
 
54
+ /**
55
+ * Metadata for an local `edit` operation.
56
+ */
54
57
  export interface IMapKeyEditLocalOpMetadata {
58
+ /**
59
+ * String identifier of the operation type.
60
+ */
55
61
  type: "edit";
62
+
63
+ /**
64
+ * Unique identifier for the local operation.
65
+ */
56
66
  pendingMessageId: number;
67
+
68
+ /**
69
+ * Local value prior to the edit.
70
+ */
57
71
  previousValue: ILocalValue;
58
72
  }
59
73
 
74
+ /**
75
+ * Metadata for an local `add` operation.
76
+ */
60
77
  export interface IMapKeyAddLocalOpMetadata {
78
+ /**
79
+ * String identifier of the operation type.
80
+ */
61
81
  type: "add";
82
+
83
+ /**
84
+ * Unique identifier for the local operation.
85
+ */
62
86
  pendingMessageId: number;
63
87
  }
64
88
 
89
+ /**
90
+ * Metadata for an local `clear` operation.
91
+ */
65
92
  export interface IMapClearLocalOpMetadata {
93
+ /**
94
+ * String identifier of the operation type.
95
+ */
66
96
  type: "clear";
97
+
98
+ /**
99
+ * Unique identifier for the local operation.
100
+ */
67
101
  pendingMessageId: number;
102
+
103
+ /**
104
+ * Local map contents prior to clearing it.
105
+ */
68
106
  previousMap?: Map<string, ILocalValue>;
69
107
  }
70
108
 
109
+ /**
110
+ * Metadata for a local operation associated with a specific key entry in the map.
111
+ */
71
112
  export type MapKeyLocalOpMetadata = IMapKeyEditLocalOpMetadata | IMapKeyAddLocalOpMetadata;
113
+
114
+ /**
115
+ * Metadata for a local operation.
116
+ */
72
117
  export type MapLocalOpMetadata = IMapClearLocalOpMetadata | MapKeyLocalOpMetadata;