@fluidframework/map 2.0.0-rc.1.0.6 → 2.0.0-rc.2.0.1

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 (132) hide show
  1. package/{.eslintrc.js → .eslintrc.cjs} +10 -1
  2. package/{.mocharc.js → .mocharc.cjs} +1 -1
  3. package/CHANGELOG.md +11 -0
  4. package/{api-extractor-esm.json → api-extractor-cjs.json} +5 -1
  5. package/api-extractor-lint.json +1 -1
  6. package/api-extractor.json +1 -1
  7. package/api-report/map.api.md +14 -57
  8. package/dist/directory.d.ts +10 -50
  9. package/dist/directory.d.ts.map +1 -1
  10. package/dist/directory.js +76 -164
  11. package/dist/directory.js.map +1 -1
  12. package/dist/index.d.ts +45 -4
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +43 -8
  15. package/dist/index.js.map +1 -1
  16. package/dist/interfaces.d.ts.map +1 -1
  17. package/dist/interfaces.js.map +1 -1
  18. package/dist/internalInterfaces.d.ts +2 -2
  19. package/dist/internalInterfaces.d.ts.map +1 -1
  20. package/dist/internalInterfaces.js.map +1 -1
  21. package/dist/localValues.d.ts +3 -5
  22. package/dist/localValues.d.ts.map +1 -1
  23. package/dist/localValues.js +9 -8
  24. package/dist/localValues.js.map +1 -1
  25. package/dist/map-alpha.d.ts +31 -116
  26. package/dist/map-beta.d.ts +24 -105
  27. package/dist/map-public.d.ts +24 -105
  28. package/dist/map-untrimmed.d.ts +31 -116
  29. package/dist/map.d.ts +4 -23
  30. package/dist/map.d.ts.map +1 -1
  31. package/dist/map.js +6 -29
  32. package/dist/map.js.map +1 -1
  33. package/dist/mapKernel.d.ts +3 -4
  34. package/dist/mapKernel.d.ts.map +1 -1
  35. package/dist/mapKernel.js +30 -35
  36. package/dist/mapKernel.js.map +1 -1
  37. package/dist/package.json +3 -0
  38. package/dist/packageVersion.d.ts +1 -1
  39. package/dist/packageVersion.js +1 -1
  40. package/dist/packageVersion.js.map +1 -1
  41. package/dist/tsdoc-metadata.json +1 -1
  42. package/lib/{directory.d.mts → directory.d.ts} +11 -51
  43. package/lib/directory.d.ts.map +1 -0
  44. package/lib/{directory.mjs → directory.js} +77 -165
  45. package/lib/directory.js.map +1 -0
  46. package/lib/index.d.ts +61 -0
  47. package/lib/index.d.ts.map +1 -0
  48. package/lib/index.js +55 -0
  49. package/lib/index.js.map +1 -0
  50. package/lib/{interfaces.d.mts → interfaces.d.ts} +1 -1
  51. package/lib/interfaces.d.ts.map +1 -0
  52. package/lib/{interfaces.mjs → interfaces.js} +1 -1
  53. package/lib/interfaces.js.map +1 -0
  54. package/lib/{internalInterfaces.d.mts → internalInterfaces.d.ts} +3 -3
  55. package/lib/internalInterfaces.d.ts.map +1 -0
  56. package/lib/{internalInterfaces.mjs → internalInterfaces.js} +1 -1
  57. package/lib/internalInterfaces.js.map +1 -0
  58. package/lib/{localValues.d.mts → localValues.d.ts} +4 -6
  59. package/lib/localValues.d.ts.map +1 -0
  60. package/lib/{localValues.mjs → localValues.js} +10 -9
  61. package/lib/localValues.js.map +1 -0
  62. package/lib/{map-alpha.d.mts → map-alpha.d.ts} +43 -116
  63. package/lib/{map-beta.d.mts → map-beta.d.ts} +36 -105
  64. package/lib/{map-public.d.mts → map-public.d.ts} +36 -105
  65. package/lib/{map-untrimmed.d.mts → map-untrimmed.d.ts} +43 -116
  66. package/lib/{map.d.mts → map.d.ts} +5 -24
  67. package/lib/map.d.ts.map +1 -0
  68. package/lib/{map.mjs → map.js} +5 -28
  69. package/lib/map.js.map +1 -0
  70. package/lib/{mapKernel.d.mts → mapKernel.d.ts} +4 -5
  71. package/lib/mapKernel.d.ts.map +1 -0
  72. package/lib/{mapKernel.mjs → mapKernel.js} +32 -37
  73. package/lib/mapKernel.js.map +1 -0
  74. package/lib/{packageVersion.d.mts → packageVersion.d.ts} +2 -2
  75. package/lib/packageVersion.d.ts.map +1 -0
  76. package/lib/{packageVersion.mjs → packageVersion.js} +2 -2
  77. package/lib/packageVersion.js.map +1 -0
  78. package/lib/test/memory/directory.spec.js +71 -0
  79. package/lib/test/memory/directory.spec.js.map +1 -0
  80. package/lib/test/memory/map.spec.js +71 -0
  81. package/lib/test/memory/map.spec.js.map +1 -0
  82. package/lib/test/mocha/directory.order.spec.js +422 -0
  83. package/lib/test/mocha/directory.order.spec.js.map +1 -0
  84. package/lib/test/mocha/directory.snapshot.spec.js +111 -0
  85. package/lib/test/mocha/directory.snapshot.spec.js.map +1 -0
  86. package/lib/test/mocha/directory.spec.js +1406 -0
  87. package/lib/test/mocha/directory.spec.js.map +1 -0
  88. package/lib/test/mocha/directoryEquivalenceUtils.js +36 -0
  89. package/lib/test/mocha/directoryEquivalenceUtils.js.map +1 -0
  90. package/lib/test/mocha/directoryFuzzTests.spec.js +337 -0
  91. package/lib/test/mocha/directoryFuzzTests.spec.js.map +1 -0
  92. package/lib/test/mocha/dirname.cjs +16 -0
  93. package/lib/test/mocha/dirname.cjs.map +1 -0
  94. package/lib/test/mocha/map.fuzz.spec.js +114 -0
  95. package/lib/test/mocha/map.fuzz.spec.js.map +1 -0
  96. package/lib/test/mocha/map.spec.js +685 -0
  97. package/lib/test/mocha/map.spec.js.map +1 -0
  98. package/lib/test/mocha/rebasing.spec.js +158 -0
  99. package/lib/test/mocha/rebasing.spec.js.map +1 -0
  100. package/lib/test/mocha/reconnection.spec.js +327 -0
  101. package/lib/test/mocha/reconnection.spec.js.map +1 -0
  102. package/lib/test/types/validateMapPrevious.generated.js +66 -0
  103. package/lib/test/types/validateMapPrevious.generated.js.map +1 -0
  104. package/package.json +55 -52
  105. package/src/directory.ts +122 -217
  106. package/src/index.ts +57 -4
  107. package/src/interfaces.ts +2 -2
  108. package/src/internalInterfaces.ts +2 -2
  109. package/src/localValues.ts +14 -9
  110. package/src/map.ts +7 -32
  111. package/src/mapKernel.ts +40 -42
  112. package/src/packageVersion.ts +1 -1
  113. package/tsconfig.cjs.json +7 -0
  114. package/tsconfig.json +2 -5
  115. package/lib/directory.d.mts.map +0 -1
  116. package/lib/directory.mjs.map +0 -1
  117. package/lib/index.d.mts +0 -9
  118. package/lib/index.d.mts.map +0 -1
  119. package/lib/index.mjs +0 -8
  120. package/lib/index.mjs.map +0 -1
  121. package/lib/interfaces.d.mts.map +0 -1
  122. package/lib/interfaces.mjs.map +0 -1
  123. package/lib/internalInterfaces.d.mts.map +0 -1
  124. package/lib/internalInterfaces.mjs.map +0 -1
  125. package/lib/localValues.d.mts.map +0 -1
  126. package/lib/localValues.mjs.map +0 -1
  127. package/lib/map.d.mts.map +0 -1
  128. package/lib/map.mjs.map +0 -1
  129. package/lib/mapKernel.d.mts.map +0 -1
  130. package/lib/mapKernel.mjs.map +0 -1
  131. package/lib/packageVersion.d.mts.map +0 -1
  132. package/lib/packageVersion.mjs.map +0 -1
package/dist/directory.js CHANGED
@@ -18,8 +18,8 @@ const shared_object_base_1 = require("@fluidframework/shared-object-base");
18
18
  const runtime_utils_1 = require("@fluidframework/runtime-utils");
19
19
  const path_browserify_1 = __importDefault(require("path-browserify"));
20
20
  const merge_tree_1 = require("@fluidframework/merge-tree");
21
- const localValues_1 = require("./localValues");
22
- const packageVersion_1 = require("./packageVersion");
21
+ const localValues_js_1 = require("./localValues.js");
22
+ const packageVersion_js_1 = require("./packageVersion.js");
23
23
  // We use path-browserify since this code can run safely on the server or the browser.
24
24
  // We standardize on using posix slashes everywhere.
25
25
  const posix = path_browserify_1.default.posix;
@@ -71,7 +71,7 @@ DirectoryFactory.Type = "https://graph.microsoft.com/types/directory";
71
71
  DirectoryFactory.Attributes = {
72
72
  type: DirectoryFactory.Type,
73
73
  snapshotFormatVersion: "0.1",
74
- packageVersion: packageVersion_1.pkgVersion,
74
+ packageVersion: packageVersion_js_1.pkgVersion,
75
75
  };
76
76
  /**
77
77
  * The comparator essentially performs the following procedure to determine the order of subdirectory creation:
@@ -97,19 +97,19 @@ const seqDataComparator = (a, b) => {
97
97
  if (isAcknowledgedOrDetached(a)) {
98
98
  if (isAcknowledgedOrDetached(b)) {
99
99
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
100
- return a.seq !== b.seq ? a.seq - b.seq : a.clientSeq - b.clientSeq;
100
+ return a.seq === b.seq ? a.clientSeq - b.clientSeq : a.seq - b.seq;
101
101
  }
102
102
  else {
103
103
  return -1;
104
104
  }
105
105
  }
106
106
  else {
107
- if (!isAcknowledgedOrDetached(b)) {
108
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
109
- return a.seq !== b.seq ? a.seq - b.seq : a.clientSeq - b.clientSeq;
107
+ if (isAcknowledgedOrDetached(b)) {
108
+ return 1;
110
109
  }
111
110
  else {
112
- return 1;
111
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
112
+ return a.seq === b.seq ? a.clientSeq - b.clientSeq : a.seq - b.seq;
113
113
  }
114
114
  }
115
115
  };
@@ -230,7 +230,7 @@ class SharedDirectory extends shared_object_base_1.SharedObject {
230
230
  * Mapping of op types to message handlers.
231
231
  */
232
232
  this.messageHandlers = new Map();
233
- this.localValueMaker = new localValues_1.LocalValueMaker(this.serializer);
233
+ this.localValueMaker = new localValues_js_1.LocalValueMaker();
234
234
  this.setMessageHandlers();
235
235
  // Mirror the containedValueChanged op on the SharedDirectory
236
236
  this.root.on("containedValueChanged", (changed, local) => {
@@ -480,9 +480,9 @@ class SharedDirectory extends shared_object_base_1.SharedObject {
480
480
  clientSeq: ++currentSubDir.localCreationSeq,
481
481
  };
482
482
  }
483
- newSubDir = new SubDirectory(seqData, createInfo !== undefined
484
- ? new Set(createInfo.ccIds)
485
- : new Set(), this, this.runtime, this.serializer, posix.join(currentSubDir.absolutePath, subdirName), this.logger);
483
+ newSubDir = new SubDirectory(seqData, createInfo === undefined
484
+ ? new Set()
485
+ : new Set(createInfo.ccIds), this, this.runtime, this.serializer, posix.join(currentSubDir.absolutePath, subdirName), this.logger);
486
486
  currentSubDir.populateSubDirectory(subdirName, newSubDir);
487
487
  // Record the newly inserted subdirectory to the creation tracker
488
488
  currentSubDir.ackedCreationSeqTracker.set(subdirName, {
@@ -494,7 +494,9 @@ class SharedDirectory extends shared_object_base_1.SharedObject {
494
494
  }
495
495
  if (currentSubDirObject.storage) {
496
496
  for (const [key, serializable] of Object.entries(currentSubDirObject.storage)) {
497
- const localValue = this.makeLocal(key, currentSubDir.absolutePath, serializable);
497
+ const localValue = this.makeLocal(key, currentSubDir.absolutePath,
498
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
499
+ (0, shared_object_base_1.parseHandles)(serializable, this.serializer));
498
500
  currentSubDir.populateStorage(key, localValue);
499
501
  }
500
502
  }
@@ -543,7 +545,7 @@ class SharedDirectory extends shared_object_base_1.SharedObject {
543
545
  serializable) {
544
546
  (0, core_utils_1.assert)(serializable.type === shared_object_base_1.ValueType[shared_object_base_1.ValueType.Plain] ||
545
547
  serializable.type === shared_object_base_1.ValueType[shared_object_base_1.ValueType.Shared], 0x1e4 /* "Unexpected serializable type" */);
546
- return this.localValueMaker.fromSerializable(serializable);
548
+ return this.localValueMaker.fromSerializable(serializable, this.serializer, this.handle);
547
549
  }
548
550
  /**
549
551
  * This checks if there is pending delete op for local delete for a any subdir in the relative path.
@@ -590,12 +592,6 @@ class SharedDirectory extends shared_object_base_1.SharedObject {
590
592
  subdir.resubmitClearMessage(op, localOpMetadata);
591
593
  }
592
594
  },
593
- applyStashedOp: (op) => {
594
- const subdir = this.getWorkingDirectory(op.path);
595
- if (subdir) {
596
- return subdir.applyStashedClearMessage(op);
597
- }
598
- },
599
595
  });
600
596
  this.messageHandlers.set("delete", {
601
597
  process: (msg, op, local, localOpMetadata) => {
@@ -612,12 +608,6 @@ class SharedDirectory extends shared_object_base_1.SharedObject {
612
608
  subdir.resubmitKeyMessage(op, localOpMetadata);
613
609
  }
614
610
  },
615
- applyStashedOp: (op) => {
616
- const subdir = this.getWorkingDirectory(op.path);
617
- if (subdir) {
618
- return subdir.applyStashedDeleteMessage(op);
619
- }
620
- },
621
611
  });
622
612
  this.messageHandlers.set("set", {
623
613
  process: (msg, op, local, localOpMetadata) => {
@@ -635,13 +625,6 @@ class SharedDirectory extends shared_object_base_1.SharedObject {
635
625
  subdir.resubmitKeyMessage(op, localOpMetadata);
636
626
  }
637
627
  },
638
- applyStashedOp: (op) => {
639
- const subdir = this.getWorkingDirectory(op.path);
640
- if (subdir) {
641
- const context = this.makeLocal(op.key, op.path, op.value);
642
- return subdir.applyStashedSetMessage(op, context);
643
- }
644
- },
645
628
  });
646
629
  this.messageHandlers.set("createSubDirectory", {
647
630
  process: (msg, op, local, localOpMetadata) => {
@@ -659,12 +642,6 @@ class SharedDirectory extends shared_object_base_1.SharedObject {
659
642
  parentSubdir.resubmitSubDirectoryMessage(op, localOpMetadata);
660
643
  }
661
644
  },
662
- applyStashedOp: (op) => {
663
- const parentSubdir = this.getWorkingDirectory(op.path);
664
- if (parentSubdir) {
665
- return parentSubdir.applyStashedCreateSubDirMessage(op);
666
- }
667
- },
668
645
  });
669
646
  this.messageHandlers.set("deleteSubDirectory", {
670
647
  process: (msg, op, local, localOpMetadata) => {
@@ -682,23 +659,39 @@ class SharedDirectory extends shared_object_base_1.SharedObject {
682
659
  parentSubdir.resubmitSubDirectoryMessage(op, localOpMetadata);
683
660
  }
684
661
  },
685
- applyStashedOp: (op) => {
686
- const parentSubdir = this.getWorkingDirectory(op.path);
687
- if (parentSubdir) {
688
- return parentSubdir.applyStashedDeleteSubDirMessage(op);
689
- }
690
- },
691
662
  });
692
663
  }
693
664
  /**
694
665
  * {@inheritDoc @fluidframework/shared-object-base#SharedObjectCore.applyStashedOp}
695
666
  */
696
667
  applyStashedOp(op) {
697
- const handler = this.messageHandlers.get(op.type);
698
- if (handler === undefined) {
699
- throw new Error("no apply stashed op handler");
668
+ const directoryOp = op;
669
+ const dir = this.getWorkingDirectory(directoryOp.path);
670
+ switch (directoryOp.type) {
671
+ case "clear": {
672
+ dir?.clear();
673
+ break;
674
+ }
675
+ case "createSubDirectory": {
676
+ dir?.createSubDirectory(directoryOp.subdirName);
677
+ break;
678
+ }
679
+ case "delete": {
680
+ dir?.delete(directoryOp.key);
681
+ break;
682
+ }
683
+ case "deleteSubDirectory": {
684
+ dir?.deleteSubDirectory(directoryOp.subdirName);
685
+ break;
686
+ }
687
+ case "set": {
688
+ dir?.set(directoryOp.key, this.localValueMaker.fromSerializable(directoryOp.value, this.serializer, this.handle).value);
689
+ break;
690
+ }
691
+ default: {
692
+ (0, core_utils_1.unreachableCase)(directoryOp);
693
+ }
700
694
  }
701
- return handler.applyStashedOp(op);
702
695
  }
703
696
  serializeDirectory(root, serializer, telemetryContext) {
704
697
  const MinValueSizeSeparateSnapshotBlob = 8 * 1024;
@@ -781,6 +774,7 @@ function isDirectoryLocalOpMetadata(metadata) {
781
774
  isSubDirLocalOpMetadata(metadata));
782
775
  }
783
776
  /* eslint-enable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */
777
+ // eslint-disable-next-line @rushstack/no-new-null
784
778
  function assertNonNullClientId(clientId) {
785
779
  (0, core_utils_1.assert)(clientId !== null, 0x6af /* client id should never be null */);
786
780
  }
@@ -905,7 +899,7 @@ class SubDirectory extends client_utils_1.TypedEventEmitter {
905
899
  }
906
900
  // Create a local value and serialize it.
907
901
  const localValue = this.directory.localValueMaker.fromInMemory(value);
908
- const serializableValue = (0, localValues_1.makeSerializable)(localValue, this.serializer, this.directory.handle);
902
+ const serializableValue = (0, localValues_js_1.makeSerializable)(localValue, this.serializer, this.directory.handle);
909
903
  // Set the value locally.
910
904
  const previousValue = this.setCore(key, localValue, true);
911
905
  // If we are not attached, don't submit the op.
@@ -959,13 +953,15 @@ class SubDirectory extends client_utils_1.TypedEventEmitter {
959
953
  return subDir;
960
954
  }
961
955
  /**
962
- * @returns The Sequence Data which should be used for local changes.
956
+ * Gets the Sequence Data which should be used for local changes.
957
+ *
963
958
  * @remarks While detached, 0 is used rather than -1 to represent a change which should be universally known (as opposed to known
964
959
  * only by the local client). This ensures that if the directory is later attached, none of its data needs to be updated (the values
965
960
  * last set while detached will now be known to any new client, until they are changed).
966
961
  *
967
962
  * The client sequence number is incremented by 1 for maintaining the internal order of locally created subdirectories
968
- * TODO: Convert these conventions to named constants. The semantics used here match those for merge-tree.
963
+ *
964
+ * @privateRemarks TODO: Convert these conventions to named constants. The semantics used here match those for merge-tree.
969
965
  */
970
966
  getLocalSeq() {
971
967
  return this.directory.isAttached()
@@ -1040,6 +1036,7 @@ class SubDirectory extends client_utils_1.TypedEventEmitter {
1040
1036
  if (this.index < subdirNames.length) {
1041
1037
  const subdirName = subdirNames[this.index++];
1042
1038
  const subdir = this.dirs.get(subdirName);
1039
+ (0, core_utils_1.assert)(subdir !== undefined, 0x8ac /* Could not find expected sub-directory. */);
1043
1040
  return { value: [subdirName, subdir], done: false };
1044
1041
  }
1045
1042
  return { value: undefined, done: true };
@@ -1188,7 +1185,6 @@ class SubDirectory extends client_utils_1.TypedEventEmitter {
1188
1185
  * @param local - Whether the message originated from the local client
1189
1186
  * @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.
1190
1187
  * For messages from a remote client, this will be undefined.
1191
- * @internal
1192
1188
  */
1193
1189
  processClearMessage(msg, op, local, localOpMetadata) {
1194
1190
  this.throwIfDisposed();
@@ -1203,24 +1199,6 @@ class SubDirectory extends client_utils_1.TypedEventEmitter {
1203
1199
  }
1204
1200
  this.clearExceptPendingKeys(false);
1205
1201
  }
1206
- /**
1207
- * Apply clear operation locally and generate metadata
1208
- * @param op - Op to apply
1209
- * @returns metadata generated for stahed op
1210
- */
1211
- applyStashedClearMessage(op) {
1212
- this.throwIfDisposed();
1213
- const previousValue = new Map(this._storage);
1214
- this.clearExceptPendingKeys(true);
1215
- const pendingMsgId = ++this.pendingMessageId;
1216
- this.pendingClearMessageIds.push(pendingMsgId);
1217
- const metadata = {
1218
- type: "clear",
1219
- pendingMessageId: pendingMsgId,
1220
- previousStorage: previousValue,
1221
- };
1222
- return metadata;
1223
- }
1224
1202
  /**
1225
1203
  * Process a delete operation.
1226
1204
  * @param msg - The message from the server to apply.
@@ -1228,7 +1206,6 @@ class SubDirectory extends client_utils_1.TypedEventEmitter {
1228
1206
  * @param local - Whether the message originated from the local client
1229
1207
  * @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.
1230
1208
  * For messages from a remote client, this will be undefined.
1231
- * @internal
1232
1209
  */
1233
1210
  processDeleteMessage(msg, op, local, localOpMetadata) {
1234
1211
  this.throwIfDisposed();
@@ -1238,22 +1215,6 @@ class SubDirectory extends client_utils_1.TypedEventEmitter {
1238
1215
  }
1239
1216
  this.deleteCore(op.key, local);
1240
1217
  }
1241
- /**
1242
- * Apply delete operation locally and generate metadata
1243
- * @param op - Op to apply
1244
- * @returns metadata generated for stahed op
1245
- */
1246
- applyStashedDeleteMessage(op) {
1247
- this.throwIfDisposed();
1248
- const previousValue = this.deleteCore(op.key, true);
1249
- const pendingMessageId = this.getKeyMessageId(op);
1250
- const localMetadata = {
1251
- type: "edit",
1252
- pendingMessageId,
1253
- previousValue,
1254
- };
1255
- return localMetadata;
1256
- }
1257
1218
  /**
1258
1219
  * Process a set operation.
1259
1220
  * @param msg - The message from the server to apply.
@@ -1261,7 +1222,6 @@ class SubDirectory extends client_utils_1.TypedEventEmitter {
1261
1222
  * @param local - Whether the message originated from the local client
1262
1223
  * @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.
1263
1224
  * For messages from a remote client, this will be undefined.
1264
- * @internal
1265
1225
  */
1266
1226
  processSetMessage(msg, op, context, local, localOpMetadata) {
1267
1227
  this.throwIfDisposed();
@@ -1274,24 +1234,6 @@ class SubDirectory extends client_utils_1.TypedEventEmitter {
1274
1234
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1275
1235
  this.setCore(op.key, context, local);
1276
1236
  }
1277
- /**
1278
- * Apply set operation locally and generate metadata
1279
- * @param op - Op to apply
1280
- * @returns metadata generated for stahed op
1281
- */
1282
- applyStashedSetMessage(op, context) {
1283
- this.throwIfDisposed();
1284
- // Set the value locally.
1285
- const previousValue = this.setCore(op.key, context, true);
1286
- // Create metadata
1287
- const pendingMessageId = this.getKeyMessageId(op);
1288
- const localMetadata = {
1289
- type: "edit",
1290
- pendingMessageId,
1291
- previousValue,
1292
- };
1293
- return localMetadata;
1294
- }
1295
1237
  /**
1296
1238
  * Process a create subdirectory operation.
1297
1239
  * @param msg - The message from the server to apply.
@@ -1299,7 +1241,6 @@ class SubDirectory extends client_utils_1.TypedEventEmitter {
1299
1241
  * @param local - Whether the message originated from the local client
1300
1242
  * @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.
1301
1243
  * For messages from a remote client, this will be undefined.
1302
- * @internal
1303
1244
  */
1304
1245
  processCreateSubDirectoryMessage(msg, op, local, localOpMetadata) {
1305
1246
  this.throwIfDisposed();
@@ -1310,21 +1251,6 @@ class SubDirectory extends client_utils_1.TypedEventEmitter {
1310
1251
  assertNonNullClientId(msg.clientId);
1311
1252
  this.createSubDirectoryCore(op.subdirName, local, { seq: msg.sequenceNumber, clientSeq: msg.clientSequenceNumber }, msg.clientId);
1312
1253
  }
1313
- /**
1314
- * Apply createSubDirectory operation locally and generate metadata
1315
- * @param op - Op to apply
1316
- * @returns metadata generated for stahed op
1317
- */
1318
- applyStashedCreateSubDirMessage(op) {
1319
- this.throwIfDisposed();
1320
- // Create the sub directory locally first.
1321
- this.createSubDirectoryCore(op.subdirName, true, this.getLocalSeq(), this.runtime.clientId ?? "detached");
1322
- this.updatePendingSubDirMessageCount(op);
1323
- const localOpMetadata = {
1324
- type: "createSubDir",
1325
- };
1326
- return localOpMetadata;
1327
- }
1328
1254
  /**
1329
1255
  * Process a delete subdirectory operation.
1330
1256
  * @param msg - The message from the server to apply.
@@ -1332,7 +1258,6 @@ class SubDirectory extends client_utils_1.TypedEventEmitter {
1332
1258
  * @param local - Whether the message originated from the local client
1333
1259
  * @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.
1334
1260
  * For messages from a remote client, this will be undefined.
1335
- * @internal
1336
1261
  */
1337
1262
  processDeleteSubDirectoryMessage(msg, op, local, localOpMetadata) {
1338
1263
  this.throwIfDisposed();
@@ -1342,21 +1267,6 @@ class SubDirectory extends client_utils_1.TypedEventEmitter {
1342
1267
  }
1343
1268
  this.deleteSubDirectoryCore(op.subdirName, local);
1344
1269
  }
1345
- /**
1346
- * Apply deleteSubDirectory operation locally and generate metadata
1347
- * @param op - Op to apply
1348
- * @returns metadata generated for stahed op
1349
- */
1350
- applyStashedDeleteSubDirMessage(op) {
1351
- this.throwIfDisposed();
1352
- const subDir = this.deleteSubDirectoryCore(op.subdirName, true);
1353
- this.updatePendingSubDirMessageCount(op);
1354
- const metadata = {
1355
- type: "deleteSubDir",
1356
- subDirectory: subDir,
1357
- };
1358
- return metadata;
1359
- }
1360
1270
  /**
1361
1271
  * Submit a clear operation.
1362
1272
  * @param op - The operation
@@ -1375,7 +1285,6 @@ class SubDirectory extends client_utils_1.TypedEventEmitter {
1375
1285
  /**
1376
1286
  * Resubmit a clear operation.
1377
1287
  * @param op - The operation
1378
- * @internal
1379
1288
  */
1380
1289
  resubmitClearMessage(op, localOpMetadata) {
1381
1290
  (0, core_utils_1.assert)(isClearLocalOpMetadata(localOpMetadata), 0x32b /* Invalid localOpMetadata for clear */);
@@ -1394,11 +1303,11 @@ class SubDirectory extends client_utils_1.TypedEventEmitter {
1394
1303
  // We don't reuse the metadata pendingMessageId but send a new one on each submit.
1395
1304
  const pendingMessageId = ++this.pendingMessageId;
1396
1305
  const pendingMessageIds = this.pendingKeys.get(op.key);
1397
- if (pendingMessageIds !== undefined) {
1398
- pendingMessageIds.push(pendingMessageId);
1306
+ if (pendingMessageIds === undefined) {
1307
+ this.pendingKeys.set(op.key, [pendingMessageId]);
1399
1308
  }
1400
1309
  else {
1401
- this.pendingKeys.set(op.key, [pendingMessageId]);
1310
+ pendingMessageIds.push(pendingMessageId);
1402
1311
  }
1403
1312
  return pendingMessageId;
1404
1313
  }
@@ -1417,7 +1326,6 @@ class SubDirectory extends client_utils_1.TypedEventEmitter {
1417
1326
  * Submit a key message to remote clients based on a previous submit.
1418
1327
  * @param op - The map key message
1419
1328
  * @param localOpMetadata - Metadata from the previous submit
1420
- * @internal
1421
1329
  */
1422
1330
  resubmitKeyMessage(op, localOpMetadata) {
1423
1331
  (0, core_utils_1.assert)(isKeyEditLocalOpMetadata(localOpMetadata), 0x32d /* Invalid localOpMetadata in submit */);
@@ -1426,7 +1334,7 @@ class SubDirectory extends client_utils_1.TypedEventEmitter {
1426
1334
  // Only submit the op, if we have record for it, otherwise it is possible that the older instance
1427
1335
  // is already deleted, in which case we don't need to submit the op.
1428
1336
  if (pendingMessageIds !== undefined) {
1429
- const index = pendingMessageIds.findIndex((id) => id === localOpMetadata.pendingMessageId);
1337
+ const index = pendingMessageIds.indexOf(localOpMetadata.pendingMessageId);
1430
1338
  if (index === -1) {
1431
1339
  return;
1432
1340
  }
@@ -1490,7 +1398,6 @@ class SubDirectory extends client_utils_1.TypedEventEmitter {
1490
1398
  * Submit a subdirectory operation again
1491
1399
  * @param op - The operation
1492
1400
  * @param localOpMetadata - metadata submitted with the op originally
1493
- * @internal
1494
1401
  */
1495
1402
  resubmitSubDirectoryMessage(op, localOpMetadata) {
1496
1403
  (0, core_utils_1.assert)(isSubDirLocalOpMetadata(localOpMetadata), 0x32f /* Invalid localOpMetadata for sub directory op */);
@@ -1517,7 +1424,6 @@ class SubDirectory extends client_utils_1.TypedEventEmitter {
1517
1424
  * Get the storage of this subdirectory in a serializable format, to be used in snapshotting.
1518
1425
  * @param serializer - The serializer to use to serialize handles in its values.
1519
1426
  * @returns The JSONable string representing the storage of this subdirectory
1520
- * @internal
1521
1427
  */
1522
1428
  *getSerializedStorage(serializer) {
1523
1429
  this.throwIfDisposed();
@@ -1531,7 +1437,7 @@ class SubDirectory extends client_utils_1.TypedEventEmitter {
1531
1437
  this.throwIfDisposed();
1532
1438
  const createInfo = {
1533
1439
  csn: this.seqData.seq,
1534
- ccIds: Array.from(this.clientIds),
1440
+ ccIds: [...this.clientIds],
1535
1441
  };
1536
1442
  return createInfo;
1537
1443
  }
@@ -1539,7 +1445,6 @@ class SubDirectory extends client_utils_1.TypedEventEmitter {
1539
1445
  * Populate a key value in this subdirectory's storage, to be used when loading from snapshot.
1540
1446
  * @param key - The key to populate
1541
1447
  * @param localValue - The local value to populate into it
1542
- * @internal
1543
1448
  */
1544
1449
  populateStorage(key, localValue) {
1545
1450
  this.throwIfDisposed();
@@ -1549,7 +1454,6 @@ class SubDirectory extends client_utils_1.TypedEventEmitter {
1549
1454
  * Populate a subdirectory into this subdirectory, to be used when loading from snapshot.
1550
1455
  * @param subdirName - The name of the subdirectory to add
1551
1456
  * @param newSubDir - The new subdirectory to add
1552
- * @internal
1553
1457
  */
1554
1458
  populateSubDirectory(subdirName, newSubDir) {
1555
1459
  this.throwIfDisposed();
@@ -1560,7 +1464,6 @@ class SubDirectory extends client_utils_1.TypedEventEmitter {
1560
1464
  * value so op handlers can be retrieved
1561
1465
  * @param key - The key to retrieve from
1562
1466
  * @returns The local value
1563
- * @internal
1564
1467
  */
1565
1468
  getLocalValue(key) {
1566
1469
  this.throwIfDisposed();
@@ -1603,37 +1506,46 @@ class SubDirectory extends client_utils_1.TypedEventEmitter {
1603
1506
  }
1604
1507
  }
1605
1508
  else if ((op.type === "delete" || op.type === "set") && localOpMetadata.type === "edit") {
1509
+ const key = op.key;
1510
+ (0, core_utils_1.assert)(key !== undefined, 0x8ad /* "key" property is missing from edit operation. */);
1511
+ (0, core_utils_1.assert)(typeof key === "string", 0x8ae /* "key" property in edit operation is misconfigured. Expected a string. */);
1606
1512
  if (localOpMetadata.previousValue === undefined) {
1607
- this.deleteCore(op.key, true);
1513
+ this.deleteCore(key, true);
1608
1514
  }
1609
1515
  else {
1610
- this.setCore(op.key, localOpMetadata.previousValue, true);
1516
+ this.setCore(key, localOpMetadata.previousValue, true);
1611
1517
  }
1612
- this.rollbackPendingMessageId(this.pendingKeys, op.key, localOpMetadata.pendingMessageId);
1518
+ this.rollbackPendingMessageId(this.pendingKeys, key, localOpMetadata.pendingMessageId);
1613
1519
  }
1614
1520
  else if (op.type === "createSubDirectory" && localOpMetadata.type === "createSubDir") {
1615
- this.deleteSubDirectoryCore(op.subdirName, true);
1616
- this.decrementPendingSubDirCount(this.pendingCreateSubDirectoriesTracker, op.subdirName);
1521
+ const subdirName = op.subdirName;
1522
+ (0, core_utils_1.assert)(subdirName !== undefined, 0x8af /* "subdirName" property is missing from "createSubDirectory" operation. */);
1523
+ (0, core_utils_1.assert)(typeof subdirName === "string", 0x8b0 /* "subdirName" property in "createSubDirectory" operation is misconfigured. Expected a string. */);
1524
+ this.deleteSubDirectoryCore(subdirName, true);
1525
+ this.decrementPendingSubDirCount(this.pendingCreateSubDirectoriesTracker, subdirName);
1617
1526
  }
1618
1527
  else if (op.type === "deleteSubDirectory" && localOpMetadata.type === "deleteSubDir") {
1528
+ const subdirName = op.subdirName;
1529
+ (0, core_utils_1.assert)(subdirName !== undefined, 0x8b1 /* "subdirName" property is missing from "deleteSubDirectory" operation. */);
1530
+ (0, core_utils_1.assert)(typeof subdirName === "string", 0x8b2 /* "subdirName" property in "deleteSubDirectory" operation is misconfigured. Expected a string. */);
1619
1531
  if (localOpMetadata.subDirectory !== undefined) {
1620
1532
  this.undeleteSubDirectoryTree(localOpMetadata.subDirectory);
1621
1533
  // don't need to register events because deleting never unregistered
1622
- this._subdirectories.set(op.subdirName, localOpMetadata.subDirectory);
1534
+ this._subdirectories.set(subdirName, localOpMetadata.subDirectory);
1623
1535
  // Restore the record in creation tracker
1624
1536
  if (isAcknowledgedOrDetached(localOpMetadata.subDirectory.seqData)) {
1625
- this.ackedCreationSeqTracker.set(op.subdirName, {
1537
+ this.ackedCreationSeqTracker.set(subdirName, {
1626
1538
  ...localOpMetadata.subDirectory.seqData,
1627
1539
  });
1628
1540
  }
1629
1541
  else {
1630
- this.localCreationSeqTracker.set(op.subdirName, {
1542
+ this.localCreationSeqTracker.set(subdirName, {
1631
1543
  ...localOpMetadata.subDirectory.seqData,
1632
1544
  });
1633
1545
  }
1634
- this.emit("subDirectoryCreated", op.subdirName, true, this);
1546
+ this.emit("subDirectoryCreated", subdirName, true, this);
1635
1547
  }
1636
- this.decrementPendingSubDirCount(this.pendingDeleteSubDirectoriesTracker, op.subDirName);
1548
+ this.decrementPendingSubDirCount(this.pendingDeleteSubDirectoriesTracker, subdirName);
1637
1549
  }
1638
1550
  else {
1639
1551
  throw new Error("Unsupported op for rollback");
@@ -1882,11 +1794,11 @@ class SubDirectory extends client_utils_1.TypedEventEmitter {
1882
1794
  * Store the sequnce numbers of newly created subdirectory to the proper creation tracker, based
1883
1795
  * on whether the creation behavior has been ack'd or not
1884
1796
  */
1885
- if (!isAcknowledgedOrDetached(seqData)) {
1886
- this.localCreationSeqTracker.set(subdirName, { ...seqData });
1797
+ if (isAcknowledgedOrDetached(seqData)) {
1798
+ this.ackedCreationSeqTracker.set(subdirName, { ...seqData });
1887
1799
  }
1888
1800
  else {
1889
- this.ackedCreationSeqTracker.set(subdirName, { ...seqData });
1801
+ this.localCreationSeqTracker.set(subdirName, { ...seqData });
1890
1802
  }
1891
1803
  this.registerEventsOnSubDirectory(subDir, subdirName);
1892
1804
  this._subdirectories.set(subdirName, subDir);