@fluidframework/map 2.0.0-dev.5.3.2.178189 → 2.0.0-dev.6.4.0.191457

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 (47) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/README.md +4 -3
  3. package/dist/directory.d.ts +2 -1
  4. package/dist/directory.d.ts.map +1 -1
  5. package/dist/directory.js +50 -39
  6. package/dist/directory.js.map +1 -1
  7. package/dist/interfaces.d.ts +1 -2
  8. package/dist/interfaces.d.ts.map +1 -1
  9. package/dist/interfaces.js.map +1 -1
  10. package/dist/internalInterfaces.d.ts.map +1 -1
  11. package/dist/internalInterfaces.js.map +1 -1
  12. package/dist/localValues.d.ts.map +1 -1
  13. package/dist/localValues.js +1 -0
  14. package/dist/localValues.js.map +1 -1
  15. package/dist/mapKernel.d.ts +1 -1
  16. package/dist/mapKernel.d.ts.map +1 -1
  17. package/dist/mapKernel.js +13 -12
  18. package/dist/mapKernel.js.map +1 -1
  19. package/dist/packageVersion.d.ts +1 -1
  20. package/dist/packageVersion.js +1 -1
  21. package/dist/packageVersion.js.map +1 -1
  22. package/lib/directory.d.ts +2 -1
  23. package/lib/directory.d.ts.map +1 -1
  24. package/lib/directory.js +32 -21
  25. package/lib/directory.js.map +1 -1
  26. package/lib/interfaces.d.ts +1 -2
  27. package/lib/interfaces.d.ts.map +1 -1
  28. package/lib/interfaces.js.map +1 -1
  29. package/lib/internalInterfaces.d.ts.map +1 -1
  30. package/lib/internalInterfaces.js.map +1 -1
  31. package/lib/localValues.d.ts.map +1 -1
  32. package/lib/localValues.js +1 -0
  33. package/lib/localValues.js.map +1 -1
  34. package/lib/mapKernel.d.ts +1 -1
  35. package/lib/mapKernel.d.ts.map +1 -1
  36. package/lib/mapKernel.js +5 -4
  37. package/lib/mapKernel.js.map +1 -1
  38. package/lib/packageVersion.d.ts +1 -1
  39. package/lib/packageVersion.js +1 -1
  40. package/lib/packageVersion.js.map +1 -1
  41. package/package.json +25 -27
  42. package/src/directory.ts +32 -8
  43. package/src/interfaces.ts +6 -2
  44. package/src/internalInterfaces.ts +2 -0
  45. package/src/localValues.ts +3 -0
  46. package/src/mapKernel.ts +5 -1
  47. package/src/packageVersion.ts +1 -1
package/lib/directory.js CHANGED
@@ -3,8 +3,9 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  var _a, _b;
6
- import { assert, TypedEventEmitter } from "@fluidframework/common-utils";
7
- import { UsageError } from "@fluidframework/container-utils";
6
+ import { assert } from "@fluidframework/core-utils";
7
+ import { TypedEventEmitter } from "@fluid-internal/client-utils";
8
+ import { UsageError } from "@fluidframework/telemetry-utils";
8
9
  import { readAndParse } from "@fluidframework/driver-utils";
9
10
  import { MessageType } from "@fluidframework/protocol-definitions";
10
11
  import { SharedObject, ValueType } from "@fluidframework/shared-object-base";
@@ -67,6 +68,7 @@ DirectoryFactory.Attributes = {
67
68
  * {@inheritDoc ISharedDirectory}
68
69
  *
69
70
  * @example
71
+ *
70
72
  * ```typescript
71
73
  * mySharedDirectory.createSubDirectory("a").createSubDirectory("b").createSubDirectory("c").set("foo", val1);
72
74
  * const mySubDir = mySharedDirectory.getWorkingDirectory("/a/b/c");
@@ -409,7 +411,9 @@ export class SharedDirectory extends SharedObject {
409
411
  * @param serializable - The remote information that we can convert into a real object
410
412
  * @returns The local value that was produced
411
413
  */
412
- makeLocal(key, absolutePath, serializable) {
414
+ makeLocal(key, absolutePath,
415
+ // eslint-disable-next-line import/no-deprecated
416
+ serializable) {
413
417
  assert(serializable.type === ValueType[ValueType.Plain] ||
414
418
  serializable.type === ValueType[ValueType.Shared], 0x1e4 /* "Unexpected serializable type" */);
415
419
  return this.localValueMaker.fromSerializable(serializable);
@@ -417,7 +421,7 @@ export class SharedDirectory extends SharedObject {
417
421
  /**
418
422
  * This checks if there is pending delete op for local delete for a any subdir in the relative path.
419
423
  * @param relativePath - path of sub directory.
420
- * @returns - true if there is pending delete.
424
+ * @returns `true` if there is pending delete, `false` otherwise.
421
425
  */
422
426
  isSubDirectoryDeletePending(relativePath) {
423
427
  const absolutePath = this.makeAbsolute(relativePath);
@@ -586,6 +590,7 @@ export class SharedDirectory extends SharedObject {
586
590
  if (!currentSubDirObject.storage) {
587
591
  currentSubDirObject.storage = {};
588
592
  }
593
+ // eslint-disable-next-line import/no-deprecated
589
594
  const result = {
590
595
  type: value.type,
591
596
  value: value.value && JSON.parse(value.value),
@@ -750,9 +755,8 @@ class SubDirectory extends TypedEventEmitter {
750
755
  * {@inheritDoc IDirectory.get}
751
756
  */
752
757
  get(key) {
753
- var _c;
754
758
  this.throwIfDisposed();
755
- return (_c = this._storage.get(key)) === null || _c === void 0 ? void 0 : _c.value;
759
+ return this._storage.get(key)?.value;
756
760
  }
757
761
  /**
758
762
  * {@inheritDoc IDirectory.set}
@@ -791,7 +795,6 @@ class SubDirectory extends TypedEventEmitter {
791
795
  * {@inheritDoc IDirectory.createSubDirectory}
792
796
  */
793
797
  createSubDirectory(subdirName) {
794
- var _c;
795
798
  this.throwIfDisposed();
796
799
  // Undefined/null subdirectory names can't be serialized to JSON in the manner we currently snapshot.
797
800
  if (subdirName === undefined || subdirName === null) {
@@ -801,7 +804,7 @@ class SubDirectory extends TypedEventEmitter {
801
804
  throw new Error(`SubDirectory name may not contain ${posix.sep}`);
802
805
  }
803
806
  // Create the sub directory locally first.
804
- const isNew = this.createSubDirectoryCore(subdirName, true, -1, (_c = this.runtime.clientId) !== null && _c !== void 0 ? _c : "detached");
807
+ const isNew = this.createSubDirectoryCore(subdirName, true, this.getLocalSeq(), this.runtime.clientId ?? "detached");
805
808
  const subDir = this._subdirectories.get(subdirName);
806
809
  assert(subDir !== undefined, 0x5aa /* subdirectory should exist after creation */);
807
810
  // If we are not attached, don't submit the op.
@@ -819,6 +822,16 @@ class SubDirectory extends TypedEventEmitter {
819
822
  }
820
823
  return subDir;
821
824
  }
825
+ /**
826
+ * @returns A sequenceNumber which should be used for local changes.
827
+ * @remarks While detached, 0 is used rather than -1 to represent a change which should be universally known (as opposed to known
828
+ * only by the local client). This ensures that if the directory is later attached, none of its data needs to be updated (the values
829
+ * last set while detached will now be known to any new client, until they are changed).
830
+ * TODO: Convert these conventions to named constants. The semantics used here match those for merge-tree.
831
+ */
832
+ getLocalSeq() {
833
+ return this.directory.isAttached() ? -1 : 0;
834
+ }
822
835
  /**
823
836
  * {@inheritDoc IDirectory.getSubDirectory}
824
837
  */
@@ -872,7 +885,7 @@ class SubDirectory extends TypedEventEmitter {
872
885
  /**
873
886
  * This checks if there is pending delete op for local delete for a given child subdirectory.
874
887
  * @param subDirName - directory name.
875
- * @returns - true if there is pending delete.
888
+ * @returns true if there is pending delete.
876
889
  */
877
890
  isSubDirectoryDeletePending(subDirName) {
878
891
  if (this.pendingDeleteSubDirectoriesTracker.has(subDirName)) {
@@ -1128,10 +1141,9 @@ class SubDirectory extends TypedEventEmitter {
1128
1141
  * @returns metadata generated for stahed op
1129
1142
  */
1130
1143
  applyStashedCreateSubDirMessage(op) {
1131
- var _c;
1132
1144
  this.throwIfDisposed();
1133
1145
  // Create the sub directory locally first.
1134
- this.createSubDirectoryCore(op.subdirName, true, -1, (_c = this.runtime.clientId) !== null && _c !== void 0 ? _c : "detached");
1146
+ this.createSubDirectoryCore(op.subdirName, true, this.getLocalSeq(), this.runtime.clientId ?? "detached");
1135
1147
  this.updatePendingSubDirMessageCount(op);
1136
1148
  const localOpMetadata = {
1137
1149
  type: "createSubDir",
@@ -1248,13 +1260,11 @@ class SubDirectory extends TypedEventEmitter {
1248
1260
  }
1249
1261
  }
1250
1262
  incrementPendingSubDirCount(map, subDirName) {
1251
- var _c;
1252
- const count = (_c = map.get(subDirName)) !== null && _c !== void 0 ? _c : 0;
1263
+ const count = map.get(subDirName) ?? 0;
1253
1264
  map.set(subDirName, count + 1);
1254
1265
  }
1255
1266
  decrementPendingSubDirCount(map, subDirName) {
1256
- var _c;
1257
- const count = (_c = map.get(subDirName)) !== null && _c !== void 0 ? _c : 0;
1267
+ const count = map.get(subDirName) ?? 0;
1258
1268
  map.set(subDirName, count - 1);
1259
1269
  if (count <= 1) {
1260
1270
  map.delete(subDirName);
@@ -1385,7 +1395,7 @@ class SubDirectory extends TypedEventEmitter {
1385
1395
  */
1386
1396
  rollbackPendingMessageId(map, key, pendingMessageId) {
1387
1397
  const pendingMessageIds = map.get(key);
1388
- const lastPendingMessageId = pendingMessageIds === null || pendingMessageIds === void 0 ? void 0 : pendingMessageIds.pop();
1398
+ const lastPendingMessageId = pendingMessageIds?.pop();
1389
1399
  if (!pendingMessageIds || lastPendingMessageId !== pendingMessageId) {
1390
1400
  throw new Error("Rollback op does not match last pending");
1391
1401
  }
@@ -1573,8 +1583,9 @@ class SubDirectory extends TypedEventEmitter {
1573
1583
  if (op.type === "createSubDirectory") {
1574
1584
  const dir = this._subdirectories.get(op.subdirName);
1575
1585
  // Child sub directory create seq number can't be lower than the parent subdirectory.
1576
- if (this.sequenceNumber !== -1 && this.sequenceNumber < msg.sequenceNumber) {
1577
- if ((dir === null || dir === void 0 ? void 0 : dir.sequenceNumber) === -1) {
1586
+ // The sequence number for multiple ops can be the same when multiple createSubDirectory occurs with grouped batching enabled, thus <= and not just <.
1587
+ if (this.sequenceNumber !== -1 && this.sequenceNumber <= msg.sequenceNumber) {
1588
+ if (dir?.sequenceNumber === -1) {
1578
1589
  // Only set the seq on the first message, could be more
1579
1590
  dir.sequenceNumber = msg.sequenceNumber;
1580
1591
  }
@@ -1625,7 +1636,7 @@ class SubDirectory extends TypedEventEmitter {
1625
1636
  */
1626
1637
  deleteCore(key, local) {
1627
1638
  const previousLocalValue = this._storage.get(key);
1628
- const previousValue = previousLocalValue === null || previousLocalValue === void 0 ? void 0 : previousLocalValue.value;
1639
+ const previousValue = previousLocalValue?.value;
1629
1640
  const successfullyRemoved = this._storage.delete(key);
1630
1641
  if (successfullyRemoved) {
1631
1642
  const event = { key, path: this.absolutePath, previousValue };
@@ -1644,7 +1655,7 @@ class SubDirectory extends TypedEventEmitter {
1644
1655
  */
1645
1656
  setCore(key, value, local) {
1646
1657
  const previousLocalValue = this._storage.get(key);
1647
- const previousValue = previousLocalValue === null || previousLocalValue === void 0 ? void 0 : previousLocalValue.value;
1658
+ const previousValue = previousLocalValue?.value;
1648
1659
  this._storage.set(key, value);
1649
1660
  const event = { key, path: this.absolutePath, previousValue };
1650
1661
  this.directory.emit("valueChanged", event, local, this.directory);
@@ -1658,7 +1669,7 @@ class SubDirectory extends TypedEventEmitter {
1658
1669
  * @param local - Whether the message originated from the local client
1659
1670
  * @param seq - Sequence number at which this directory is created
1660
1671
  * @param clientId - Id of client which created this directory.
1661
- * @returns - True if is newly created, false if it already existed.
1672
+ * @returns True if is newly created, false if it already existed.
1662
1673
  */
1663
1674
  createSubDirectoryCore(subdirName, local, seq, clientId) {
1664
1675
  const subdir = this._subdirectories.get(subdirName);