@fluidframework/map 2.0.0-dev.2.2.0.111723 → 2.0.0-dev.3.1.0.125672

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 (65) hide show
  1. package/.eslintrc.js +12 -14
  2. package/.mocharc.js +2 -2
  3. package/README.md +3 -3
  4. package/api-extractor.json +2 -2
  5. package/dist/directory.d.ts +6 -5
  6. package/dist/directory.d.ts.map +1 -1
  7. package/dist/directory.js +68 -30
  8. package/dist/directory.js.map +1 -1
  9. package/dist/interfaces.d.ts +27 -17
  10. package/dist/interfaces.d.ts.map +1 -1
  11. package/dist/interfaces.js.map +1 -1
  12. package/dist/internalInterfaces.d.ts +39 -0
  13. package/dist/internalInterfaces.d.ts.map +1 -1
  14. package/dist/internalInterfaces.js.map +1 -1
  15. package/dist/localValues.d.ts +12 -3
  16. package/dist/localValues.d.ts.map +1 -1
  17. package/dist/localValues.js +10 -0
  18. package/dist/localValues.js.map +1 -1
  19. package/dist/map.d.ts +5 -5
  20. package/dist/map.d.ts.map +1 -1
  21. package/dist/map.js +15 -2
  22. package/dist/map.js.map +1 -1
  23. package/dist/mapKernel.d.ts +5 -5
  24. package/dist/mapKernel.d.ts.map +1 -1
  25. package/dist/mapKernel.js +58 -33
  26. package/dist/mapKernel.js.map +1 -1
  27. package/dist/packageVersion.d.ts +1 -1
  28. package/dist/packageVersion.js +1 -1
  29. package/dist/packageVersion.js.map +1 -1
  30. package/lib/directory.d.ts +6 -5
  31. package/lib/directory.d.ts.map +1 -1
  32. package/lib/directory.js +70 -32
  33. package/lib/directory.js.map +1 -1
  34. package/lib/interfaces.d.ts +27 -17
  35. package/lib/interfaces.d.ts.map +1 -1
  36. package/lib/interfaces.js.map +1 -1
  37. package/lib/internalInterfaces.d.ts +39 -0
  38. package/lib/internalInterfaces.d.ts.map +1 -1
  39. package/lib/internalInterfaces.js.map +1 -1
  40. package/lib/localValues.d.ts +12 -3
  41. package/lib/localValues.d.ts.map +1 -1
  42. package/lib/localValues.js +10 -0
  43. package/lib/localValues.js.map +1 -1
  44. package/lib/map.d.ts +5 -5
  45. package/lib/map.d.ts.map +1 -1
  46. package/lib/map.js +16 -3
  47. package/lib/map.js.map +1 -1
  48. package/lib/mapKernel.d.ts +5 -5
  49. package/lib/mapKernel.d.ts.map +1 -1
  50. package/lib/mapKernel.js +59 -34
  51. package/lib/mapKernel.js.map +1 -1
  52. package/lib/packageVersion.d.ts +1 -1
  53. package/lib/packageVersion.js +1 -1
  54. package/lib/packageVersion.js.map +1 -1
  55. package/package.json +25 -22
  56. package/prettier.config.cjs +1 -1
  57. package/src/directory.ts +1957 -1848
  58. package/src/interfaces.ts +309 -288
  59. package/src/internalInterfaces.ts +83 -38
  60. package/src/localValues.ts +95 -93
  61. package/src/map.ts +364 -345
  62. package/src/mapKernel.ts +729 -676
  63. package/src/packageVersion.ts +1 -1
  64. package/tsconfig.esnext.json +5 -5
  65. package/tsconfig.json +9 -15
package/lib/directory.js CHANGED
@@ -6,11 +6,11 @@ var _a, _b;
6
6
  import { assert, TypedEventEmitter } from "@fluidframework/common-utils";
7
7
  import { UsageError } from "@fluidframework/container-utils";
8
8
  import { readAndParse } from "@fluidframework/driver-utils";
9
- import { MessageType, } from "@fluidframework/protocol-definitions";
9
+ import { MessageType } from "@fluidframework/protocol-definitions";
10
10
  import { SharedObject, ValueType } from "@fluidframework/shared-object-base";
11
11
  import { SummaryTreeBuilder } from "@fluidframework/runtime-utils";
12
12
  import * as path from "path-browserify";
13
- import { LocalValueMaker, makeSerializable, } from "./localValues";
13
+ import { LocalValueMaker, makeSerializable } from "./localValues";
14
14
  import { pkgVersion } from "./packageVersion";
15
15
  // We use path-browserify since this code can run safely on the server or the browser.
16
16
  // We standardize on using posix slashes everywhere.
@@ -137,6 +137,8 @@ export class SharedDirectory extends SharedObject {
137
137
  /**
138
138
  * {@inheritDoc IDirectory.get}
139
139
  */
140
+ // TODO: Use `unknown` instead (breaking change).
141
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
140
142
  get(key) {
141
143
  return this.root.get(key);
142
144
  }
@@ -185,13 +187,18 @@ export class SharedDirectory extends SharedObject {
185
187
  * Issue a callback on each entry under this IDirectory.
186
188
  * @param callback - Callback to issue
187
189
  */
190
+ // TODO: Use `unknown` instead (breaking change).
191
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
188
192
  forEach(callback) {
193
+ // eslint-disable-next-line unicorn/no-array-for-each, unicorn/no-array-callback-reference
189
194
  this.root.forEach(callback);
190
195
  }
191
196
  /**
192
197
  * Get an iterator over the entries under this IDirectory.
193
198
  * @returns The iterator
194
199
  */
200
+ // TODO: Use `unknown` instead (breaking change).
201
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
195
202
  [(_a = Symbol.toStringTag, Symbol.iterator)]() {
196
203
  return this.root[Symbol.iterator]();
197
204
  }
@@ -199,6 +206,8 @@ export class SharedDirectory extends SharedObject {
199
206
  * Get an iterator over the entries under this IDirectory.
200
207
  * @returns The iterator
201
208
  */
209
+ // TODO: Use `unknown` instead (breaking change).
210
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
202
211
  entries() {
203
212
  return this.root.entries();
204
213
  }
@@ -219,6 +228,8 @@ export class SharedDirectory extends SharedObject {
219
228
  * Get an iterator over the values under this IDirectory.
220
229
  * @returns The iterator
221
230
  */
231
+ // TODO: Use `unknown` instead (breaking change).
232
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
222
233
  values() {
223
234
  return this.root.values();
224
235
  }
@@ -261,7 +272,7 @@ export class SharedDirectory extends SharedObject {
261
272
  return this.root;
262
273
  }
263
274
  let currentSubDir = this.root;
264
- const subdirs = absolutePath.substr(1).split(posix.sep);
275
+ const subdirs = absolutePath.slice(1).split(posix.sep);
265
276
  for (const subdir of subdirs) {
266
277
  currentSubDir = currentSubDir.getSubDirectory(subdir);
267
278
  if (!currentSubDir) {
@@ -366,7 +377,7 @@ export class SharedDirectory extends SharedObject {
366
377
  /**
367
378
  * {@inheritDoc @fluidframework/shared-object-base#SharedObject.rollback}
368
379
  * @internal
369
- */
380
+ */
370
381
  rollback(content, localOpMetadata) {
371
382
  const op = content;
372
383
  const subdir = this.getWorkingDirectory(op.path);
@@ -392,7 +403,8 @@ export class SharedDirectory extends SharedObject {
392
403
  * @returns The local value that was produced
393
404
  */
394
405
  makeLocal(key, absolutePath, serializable) {
395
- assert(serializable.type === ValueType[ValueType.Plain] || serializable.type === ValueType[ValueType.Shared], 0x1e4 /* "Unexpected serializable type" */);
406
+ assert(serializable.type === ValueType[ValueType.Plain] ||
407
+ serializable.type === ValueType[ValueType.Shared], 0x1e4 /* "Unexpected serializable type" */);
396
408
  return this.localValueMaker.fromSerializable(serializable);
397
409
  }
398
410
  /**
@@ -475,7 +487,6 @@ export class SharedDirectory extends SharedObject {
475
487
  parentSubdir.resubmitSubDirectoryMessage(op, localOpMetadata);
476
488
  }
477
489
  },
478
- // eslint-disable-next-line max-len
479
490
  applyStashedOp: (op) => {
480
491
  const parentSubdir = this.getWorkingDirectory(op.path);
481
492
  if (parentSubdir) {
@@ -497,7 +508,6 @@ export class SharedDirectory extends SharedObject {
497
508
  parentSubdir.resubmitSubDirectoryMessage(op, localOpMetadata);
498
509
  }
499
510
  },
500
- // eslint-disable-next-line max-len
501
511
  applyStashedOp: (op) => {
502
512
  const parentSubdir = this.getWorkingDirectory(op.path);
503
513
  if (parentSubdir) {
@@ -507,6 +517,7 @@ export class SharedDirectory extends SharedObject {
507
517
  });
508
518
  }
509
519
  /**
520
+ * {@inheritDoc @fluidframework/shared-object-base#SharedObjectCore.applyStashedOp}
510
521
  * @internal
511
522
  */
512
523
  applyStashedOp(op) {
@@ -533,14 +544,13 @@ export class SharedDirectory extends SharedObject {
533
544
  }
534
545
  const result = {
535
546
  type: value.type,
536
- // eslint-disable-next-line @typescript-eslint/ban-types
537
547
  value: value.value && JSON.parse(value.value),
538
548
  };
539
549
  if (value.value && value.value.length >= MinValueSizeSeparateSnapshotBlob) {
540
550
  const extraContent = {};
541
551
  let largeContent = extraContent;
542
552
  if (currentSubDir.absolutePath !== posix.sep) {
543
- for (const dir of currentSubDir.absolutePath.substr(1).split(posix.sep)) {
553
+ for (const dir of currentSubDir.absolutePath.slice(1).split(posix.sep)) {
544
554
  const subDataObject = {};
545
555
  largeContent.subdirectories = { [dir]: subDataObject };
546
556
  largeContent = subDataObject;
@@ -573,24 +583,33 @@ export class SharedDirectory extends SharedObject {
573
583
  return builder.getSummaryTree();
574
584
  }
575
585
  }
586
+ /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */
576
587
  function isKeyEditLocalOpMetadata(metadata) {
577
- return metadata !== undefined && typeof metadata.pendingMessageId === "number" && metadata.type === "edit";
588
+ return (metadata !== undefined &&
589
+ typeof metadata.pendingMessageId === "number" &&
590
+ metadata.type === "edit");
578
591
  }
579
592
  function isClearLocalOpMetadata(metadata) {
580
- return metadata !== undefined && metadata.type === "clear" && typeof metadata.pendingMessageId === "number" &&
581
- typeof metadata.previousStorage === "object";
593
+ return (metadata !== undefined &&
594
+ metadata.type === "clear" &&
595
+ typeof metadata.pendingMessageId === "number" &&
596
+ typeof metadata.previousStorage === "object");
582
597
  }
583
598
  function isSubDirLocalOpMetadata(metadata) {
584
- return metadata !== undefined && typeof metadata.pendingMessageId === "number" &&
599
+ return (metadata !== undefined &&
600
+ typeof metadata.pendingMessageId === "number" &&
585
601
  ((metadata.type === "createSubDir" && typeof metadata.previouslyExisted === "boolean") ||
586
- metadata.type === "deleteSubDir");
602
+ metadata.type === "deleteSubDir"));
587
603
  }
588
604
  function isDirectoryLocalOpMetadata(metadata) {
589
- return metadata !== undefined && typeof metadata.pendingMessageId === "number" &&
590
- (metadata.type === "edit" || metadata.type === "deleteSubDir" ||
605
+ return (metadata !== undefined &&
606
+ typeof metadata.pendingMessageId === "number" &&
607
+ (metadata.type === "edit" ||
608
+ metadata.type === "deleteSubDir" ||
591
609
  (metadata.type === "clear" && typeof metadata.previousStorage === "object") ||
592
- (metadata.type === "createSubDir" && typeof metadata.previouslyExisted === "boolean"));
610
+ (metadata.type === "createSubDir" && typeof metadata.previouslyExisted === "boolean")));
593
611
  }
612
+ /* eslint-enable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */
594
613
  /**
595
614
  * Node of the directory tree.
596
615
  * @sealed
@@ -647,10 +666,11 @@ class SubDirectory extends TypedEventEmitter {
647
666
  this.emit("disposed", this);
648
667
  }
649
668
  /**
650
- * Unmark the deleted property when rolling back delete.
669
+ * Unmark the deleted property only when rolling back delete.
651
670
  */
652
671
  undispose() {
653
672
  this._deleted = false;
673
+ this.emit("undisposed", this);
654
674
  }
655
675
  get disposed() {
656
676
  return this._deleted;
@@ -830,6 +850,7 @@ class SubDirectory extends TypedEventEmitter {
830
850
  */
831
851
  forEach(callback) {
832
852
  this.throwIfDisposed();
853
+ // eslint-disable-next-line unicorn/no-array-for-each
833
854
  this._storage.forEach((localValue, key, map) => {
834
855
  callback(localValue.value, key, map);
835
856
  });
@@ -957,7 +978,11 @@ class SubDirectory extends TypedEventEmitter {
957
978
  this.throwIfDisposed();
958
979
  const previousValue = this.deleteCore(op.key, true);
959
980
  const pendingMessageId = this.getKeyMessageId(op);
960
- const localMetadata = { type: "edit", pendingMessageId, previousValue };
981
+ const localMetadata = {
982
+ type: "edit",
983
+ pendingMessageId,
984
+ previousValue,
985
+ };
961
986
  return localMetadata;
962
987
  }
963
988
  /**
@@ -989,7 +1014,11 @@ class SubDirectory extends TypedEventEmitter {
989
1014
  const previousValue = this.setCore(op.key, context, true);
990
1015
  // Create metadata
991
1016
  const pendingMessageId = this.getKeyMessageId(op);
992
- const localMetadata = { type: "edit", pendingMessageId, previousValue };
1017
+ const localMetadata = {
1018
+ type: "edit",
1019
+ pendingMessageId,
1020
+ previousValue,
1021
+ };
993
1022
  return localMetadata;
994
1023
  }
995
1024
  /**
@@ -1118,7 +1147,8 @@ class SubDirectory extends TypedEventEmitter {
1118
1147
  assert(isKeyEditLocalOpMetadata(localOpMetadata), 0x32d /* Invalid localOpMetadata in submit */);
1119
1148
  // clear the old pending message id
1120
1149
  const pendingMessageIds = this.pendingKeys.get(op.key);
1121
- assert(pendingMessageIds !== undefined && pendingMessageIds[0] === localOpMetadata.pendingMessageId, 0x32e /* Unexpected pending message received */);
1150
+ assert(pendingMessageIds !== undefined &&
1151
+ pendingMessageIds[0] === localOpMetadata.pendingMessageId, 0x32e /* Unexpected pending message received */);
1122
1152
  pendingMessageIds.shift();
1123
1153
  if (pendingMessageIds.length === 0) {
1124
1154
  this.pendingKeys.delete(op.key);
@@ -1180,7 +1210,8 @@ class SubDirectory extends TypedEventEmitter {
1180
1210
  assert(isSubDirLocalOpMetadata(localOpMetadata), 0x32f /* Invalid localOpMetadata for sub directory op */);
1181
1211
  // clear the old pending message id
1182
1212
  const pendingMessageIds = this.pendingSubDirectories.get(op.subdirName);
1183
- assert(pendingMessageIds !== undefined && pendingMessageIds[0] === localOpMetadata.pendingMessageId, 0x330 /* Unexpected pending message received */);
1213
+ assert(pendingMessageIds !== undefined &&
1214
+ pendingMessageIds[0] === localOpMetadata.pendingMessageId, 0x330 /* Unexpected pending message received */);
1184
1215
  pendingMessageIds.shift();
1185
1216
  if (pendingMessageIds.length === 0) {
1186
1217
  this.pendingSubDirectories.delete(op.subdirName);
@@ -1252,21 +1283,24 @@ class SubDirectory extends TypedEventEmitter {
1252
1283
  map.delete(key);
1253
1284
  }
1254
1285
  }
1286
+ /* eslint-disable @typescript-eslint/no-unsafe-member-access */
1255
1287
  /**
1256
1288
  * Rollback a local op
1257
1289
  * @param op - The operation to rollback
1258
1290
  * @param localOpMetadata - The local metadata associated with the op.
1259
1291
  */
1292
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1260
1293
  rollback(op, localOpMetadata) {
1261
1294
  if (!isDirectoryLocalOpMetadata(localOpMetadata)) {
1262
1295
  throw new Error("Invalid localOpMetadata");
1263
1296
  }
1264
1297
  if (op.type === "clear" && localOpMetadata.type === "clear") {
1265
- localOpMetadata.previousStorage.forEach((localValue, key) => {
1298
+ for (const [key, localValue] of localOpMetadata.previousStorage.entries()) {
1266
1299
  this.setCore(key, localValue, true);
1267
- });
1300
+ }
1268
1301
  const lastPendingClearId = this.pendingClearMessageIds.pop();
1269
- if (lastPendingClearId === undefined || lastPendingClearId !== localOpMetadata.pendingMessageId) {
1302
+ if (lastPendingClearId === undefined ||
1303
+ lastPendingClearId !== localOpMetadata.pendingMessageId) {
1270
1304
  throw new Error("Rollback op does match last clear");
1271
1305
  }
1272
1306
  }
@@ -1298,6 +1332,7 @@ class SubDirectory extends TypedEventEmitter {
1298
1332
  throw new Error("Unsupported op for rollback");
1299
1333
  }
1300
1334
  }
1335
+ /* eslint-enable @typescript-eslint/no-unsafe-member-access */
1301
1336
  /**
1302
1337
  * Converts the given relative path into an absolute path.
1303
1338
  * @param path - Relative path to convert
@@ -1318,7 +1353,8 @@ class SubDirectory extends TypedEventEmitter {
1318
1353
  needProcessStorageOperation(op, local, localOpMetadata) {
1319
1354
  if (this.pendingClearMessageIds.length > 0) {
1320
1355
  if (local) {
1321
- assert(localOpMetadata !== undefined && isKeyEditLocalOpMetadata(localOpMetadata) &&
1356
+ assert(localOpMetadata !== undefined &&
1357
+ isKeyEditLocalOpMetadata(localOpMetadata) &&
1322
1358
  localOpMetadata.pendingMessageId < this.pendingClearMessageIds[0], 0x010 /* "Received out of order storage op when there is an unackd clear message" */);
1323
1359
  }
1324
1360
  // If I have a NACK clear, we can ignore all ops.
@@ -1331,7 +1367,8 @@ class SubDirectory extends TypedEventEmitter {
1331
1367
  if (local) {
1332
1368
  assert(localOpMetadata !== undefined && isKeyEditLocalOpMetadata(localOpMetadata), 0x011 /* pendingMessageId is missing from the local client's operation */);
1333
1369
  const pendingMessageIds = this.pendingKeys.get(op.key);
1334
- assert(pendingMessageIds !== undefined && pendingMessageIds[0] === localOpMetadata.pendingMessageId, 0x331 /* Unexpected pending message received */);
1370
+ assert(pendingMessageIds !== undefined &&
1371
+ pendingMessageIds[0] === localOpMetadata.pendingMessageId, 0x331 /* Unexpected pending message received */);
1335
1372
  pendingMessageIds.shift();
1336
1373
  if (pendingMessageIds.length === 0) {
1337
1374
  this.pendingKeys.delete(op.key);
@@ -1358,7 +1395,8 @@ class SubDirectory extends TypedEventEmitter {
1358
1395
  if (local) {
1359
1396
  assert(isSubDirLocalOpMetadata(localOpMetadata), 0x012 /* pendingMessageId is missing from the local client's operation */);
1360
1397
  const pendingMessageIds = this.pendingSubDirectories.get(op.subdirName);
1361
- assert(pendingMessageIds !== undefined && pendingMessageIds[0] === localOpMetadata.pendingMessageId, 0x332 /* Unexpected pending message received */);
1398
+ assert(pendingMessageIds !== undefined &&
1399
+ pendingMessageIds[0] === localOpMetadata.pendingMessageId, 0x332 /* Unexpected pending message received */);
1362
1400
  pendingMessageIds.shift();
1363
1401
  if (pendingMessageIds.length === 0) {
1364
1402
  this.pendingSubDirectories.delete(op.subdirName);
@@ -1375,14 +1413,14 @@ class SubDirectory extends TypedEventEmitter {
1375
1413
  // Assuming the pendingKeys is small and the map is large
1376
1414
  // we will get the value for the pendingKeys and clear the map
1377
1415
  const temp = new Map();
1378
- this.pendingKeys.forEach((value, key, map) => {
1416
+ for (const [key] of this.pendingKeys) {
1379
1417
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1380
1418
  temp.set(key, this._storage.get(key));
1381
- });
1419
+ }
1382
1420
  this.clearCore(local);
1383
- temp.forEach((value, key, map) => {
1421
+ for (const [key, value] of temp.entries()) {
1384
1422
  this.setCore(key, value, true);
1385
- });
1423
+ }
1386
1424
  }
1387
1425
  /**
1388
1426
  * Clear implementation used for both locally sourced clears as well as incoming remote clears.