@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
@@ -3,17 +3,17 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  var _a, _b;
6
- import { assert } from "@fluidframework/core-utils";
6
+ import { assert, unreachableCase } from "@fluidframework/core-utils";
7
7
  import { TypedEventEmitter } from "@fluid-internal/client-utils";
8
8
  import { UsageError } from "@fluidframework/telemetry-utils";
9
9
  import { readAndParse } from "@fluidframework/driver-utils";
10
10
  import { MessageType } from "@fluidframework/protocol-definitions";
11
- import { SharedObject, ValueType } from "@fluidframework/shared-object-base";
11
+ import { SharedObject, ValueType, parseHandles, } from "@fluidframework/shared-object-base";
12
12
  import { SummaryTreeBuilder } from "@fluidframework/runtime-utils";
13
13
  import path from "path-browserify";
14
14
  import { RedBlackTree } from "@fluidframework/merge-tree";
15
- import { LocalValueMaker, makeSerializable } from "./localValues.mjs";
16
- import { pkgVersion } from "./packageVersion.mjs";
15
+ import { LocalValueMaker, makeSerializable } from "./localValues.js";
16
+ import { pkgVersion } from "./packageVersion.js";
17
17
  // We use path-browserify since this code can run safely on the server or the browser.
18
18
  // We standardize on using posix slashes everywhere.
19
19
  const posix = path.posix;
@@ -90,19 +90,19 @@ const seqDataComparator = (a, b) => {
90
90
  if (isAcknowledgedOrDetached(a)) {
91
91
  if (isAcknowledgedOrDetached(b)) {
92
92
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
93
- return a.seq !== b.seq ? a.seq - b.seq : a.clientSeq - b.clientSeq;
93
+ return a.seq === b.seq ? a.clientSeq - b.clientSeq : a.seq - b.seq;
94
94
  }
95
95
  else {
96
96
  return -1;
97
97
  }
98
98
  }
99
99
  else {
100
- if (!isAcknowledgedOrDetached(b)) {
101
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
102
- return a.seq !== b.seq ? a.seq - b.seq : a.clientSeq - b.clientSeq;
100
+ if (isAcknowledgedOrDetached(b)) {
101
+ return 1;
103
102
  }
104
103
  else {
105
- return 1;
104
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
105
+ return a.seq === b.seq ? a.clientSeq - b.clientSeq : a.seq - b.seq;
106
106
  }
107
107
  }
108
108
  };
@@ -223,7 +223,7 @@ export class SharedDirectory extends SharedObject {
223
223
  * Mapping of op types to message handlers.
224
224
  */
225
225
  this.messageHandlers = new Map();
226
- this.localValueMaker = new LocalValueMaker(this.serializer);
226
+ this.localValueMaker = new LocalValueMaker();
227
227
  this.setMessageHandlers();
228
228
  // Mirror the containedValueChanged op on the SharedDirectory
229
229
  this.root.on("containedValueChanged", (changed, local) => {
@@ -473,9 +473,9 @@ export class SharedDirectory extends SharedObject {
473
473
  clientSeq: ++currentSubDir.localCreationSeq,
474
474
  };
475
475
  }
476
- newSubDir = new SubDirectory(seqData, createInfo !== undefined
477
- ? new Set(createInfo.ccIds)
478
- : new Set(), this, this.runtime, this.serializer, posix.join(currentSubDir.absolutePath, subdirName), this.logger);
476
+ newSubDir = new SubDirectory(seqData, createInfo === undefined
477
+ ? new Set()
478
+ : new Set(createInfo.ccIds), this, this.runtime, this.serializer, posix.join(currentSubDir.absolutePath, subdirName), this.logger);
479
479
  currentSubDir.populateSubDirectory(subdirName, newSubDir);
480
480
  // Record the newly inserted subdirectory to the creation tracker
481
481
  currentSubDir.ackedCreationSeqTracker.set(subdirName, {
@@ -487,7 +487,9 @@ export class SharedDirectory extends SharedObject {
487
487
  }
488
488
  if (currentSubDirObject.storage) {
489
489
  for (const [key, serializable] of Object.entries(currentSubDirObject.storage)) {
490
- const localValue = this.makeLocal(key, currentSubDir.absolutePath, serializable);
490
+ const localValue = this.makeLocal(key, currentSubDir.absolutePath,
491
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
492
+ parseHandles(serializable, this.serializer));
491
493
  currentSubDir.populateStorage(key, localValue);
492
494
  }
493
495
  }
@@ -536,7 +538,7 @@ export class SharedDirectory extends SharedObject {
536
538
  serializable) {
537
539
  assert(serializable.type === ValueType[ValueType.Plain] ||
538
540
  serializable.type === ValueType[ValueType.Shared], 0x1e4 /* "Unexpected serializable type" */);
539
- return this.localValueMaker.fromSerializable(serializable);
541
+ return this.localValueMaker.fromSerializable(serializable, this.serializer, this.handle);
540
542
  }
541
543
  /**
542
544
  * This checks if there is pending delete op for local delete for a any subdir in the relative path.
@@ -583,12 +585,6 @@ export class SharedDirectory extends SharedObject {
583
585
  subdir.resubmitClearMessage(op, localOpMetadata);
584
586
  }
585
587
  },
586
- applyStashedOp: (op) => {
587
- const subdir = this.getWorkingDirectory(op.path);
588
- if (subdir) {
589
- return subdir.applyStashedClearMessage(op);
590
- }
591
- },
592
588
  });
593
589
  this.messageHandlers.set("delete", {
594
590
  process: (msg, op, local, localOpMetadata) => {
@@ -605,12 +601,6 @@ export class SharedDirectory extends SharedObject {
605
601
  subdir.resubmitKeyMessage(op, localOpMetadata);
606
602
  }
607
603
  },
608
- applyStashedOp: (op) => {
609
- const subdir = this.getWorkingDirectory(op.path);
610
- if (subdir) {
611
- return subdir.applyStashedDeleteMessage(op);
612
- }
613
- },
614
604
  });
615
605
  this.messageHandlers.set("set", {
616
606
  process: (msg, op, local, localOpMetadata) => {
@@ -628,13 +618,6 @@ export class SharedDirectory extends SharedObject {
628
618
  subdir.resubmitKeyMessage(op, localOpMetadata);
629
619
  }
630
620
  },
631
- applyStashedOp: (op) => {
632
- const subdir = this.getWorkingDirectory(op.path);
633
- if (subdir) {
634
- const context = this.makeLocal(op.key, op.path, op.value);
635
- return subdir.applyStashedSetMessage(op, context);
636
- }
637
- },
638
621
  });
639
622
  this.messageHandlers.set("createSubDirectory", {
640
623
  process: (msg, op, local, localOpMetadata) => {
@@ -652,12 +635,6 @@ export class SharedDirectory extends SharedObject {
652
635
  parentSubdir.resubmitSubDirectoryMessage(op, localOpMetadata);
653
636
  }
654
637
  },
655
- applyStashedOp: (op) => {
656
- const parentSubdir = this.getWorkingDirectory(op.path);
657
- if (parentSubdir) {
658
- return parentSubdir.applyStashedCreateSubDirMessage(op);
659
- }
660
- },
661
638
  });
662
639
  this.messageHandlers.set("deleteSubDirectory", {
663
640
  process: (msg, op, local, localOpMetadata) => {
@@ -675,23 +652,39 @@ export class SharedDirectory extends SharedObject {
675
652
  parentSubdir.resubmitSubDirectoryMessage(op, localOpMetadata);
676
653
  }
677
654
  },
678
- applyStashedOp: (op) => {
679
- const parentSubdir = this.getWorkingDirectory(op.path);
680
- if (parentSubdir) {
681
- return parentSubdir.applyStashedDeleteSubDirMessage(op);
682
- }
683
- },
684
655
  });
685
656
  }
686
657
  /**
687
658
  * {@inheritDoc @fluidframework/shared-object-base#SharedObjectCore.applyStashedOp}
688
659
  */
689
660
  applyStashedOp(op) {
690
- const handler = this.messageHandlers.get(op.type);
691
- if (handler === undefined) {
692
- throw new Error("no apply stashed op handler");
661
+ const directoryOp = op;
662
+ const dir = this.getWorkingDirectory(directoryOp.path);
663
+ switch (directoryOp.type) {
664
+ case "clear": {
665
+ dir?.clear();
666
+ break;
667
+ }
668
+ case "createSubDirectory": {
669
+ dir?.createSubDirectory(directoryOp.subdirName);
670
+ break;
671
+ }
672
+ case "delete": {
673
+ dir?.delete(directoryOp.key);
674
+ break;
675
+ }
676
+ case "deleteSubDirectory": {
677
+ dir?.deleteSubDirectory(directoryOp.subdirName);
678
+ break;
679
+ }
680
+ case "set": {
681
+ dir?.set(directoryOp.key, this.localValueMaker.fromSerializable(directoryOp.value, this.serializer, this.handle).value);
682
+ break;
683
+ }
684
+ default: {
685
+ unreachableCase(directoryOp);
686
+ }
693
687
  }
694
- return handler.applyStashedOp(op);
695
688
  }
696
689
  serializeDirectory(root, serializer, telemetryContext) {
697
690
  const MinValueSizeSeparateSnapshotBlob = 8 * 1024;
@@ -773,6 +766,7 @@ function isDirectoryLocalOpMetadata(metadata) {
773
766
  isSubDirLocalOpMetadata(metadata));
774
767
  }
775
768
  /* eslint-enable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */
769
+ // eslint-disable-next-line @rushstack/no-new-null
776
770
  function assertNonNullClientId(clientId) {
777
771
  assert(clientId !== null, 0x6af /* client id should never be null */);
778
772
  }
@@ -951,13 +945,15 @@ class SubDirectory extends TypedEventEmitter {
951
945
  return subDir;
952
946
  }
953
947
  /**
954
- * @returns The Sequence Data which should be used for local changes.
948
+ * Gets the Sequence Data which should be used for local changes.
949
+ *
955
950
  * @remarks While detached, 0 is used rather than -1 to represent a change which should be universally known (as opposed to known
956
951
  * only by the local client). This ensures that if the directory is later attached, none of its data needs to be updated (the values
957
952
  * last set while detached will now be known to any new client, until they are changed).
958
953
  *
959
954
  * The client sequence number is incremented by 1 for maintaining the internal order of locally created subdirectories
960
- * TODO: Convert these conventions to named constants. The semantics used here match those for merge-tree.
955
+ *
956
+ * @privateRemarks TODO: Convert these conventions to named constants. The semantics used here match those for merge-tree.
961
957
  */
962
958
  getLocalSeq() {
963
959
  return this.directory.isAttached()
@@ -1032,6 +1028,7 @@ class SubDirectory extends TypedEventEmitter {
1032
1028
  if (this.index < subdirNames.length) {
1033
1029
  const subdirName = subdirNames[this.index++];
1034
1030
  const subdir = this.dirs.get(subdirName);
1031
+ assert(subdir !== undefined, 0x8ac /* Could not find expected sub-directory. */);
1035
1032
  return { value: [subdirName, subdir], done: false };
1036
1033
  }
1037
1034
  return { value: undefined, done: true };
@@ -1180,7 +1177,6 @@ class SubDirectory extends TypedEventEmitter {
1180
1177
  * @param local - Whether the message originated from the local client
1181
1178
  * @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.
1182
1179
  * For messages from a remote client, this will be undefined.
1183
- * @internal
1184
1180
  */
1185
1181
  processClearMessage(msg, op, local, localOpMetadata) {
1186
1182
  this.throwIfDisposed();
@@ -1195,24 +1191,6 @@ class SubDirectory extends TypedEventEmitter {
1195
1191
  }
1196
1192
  this.clearExceptPendingKeys(false);
1197
1193
  }
1198
- /**
1199
- * Apply clear operation locally and generate metadata
1200
- * @param op - Op to apply
1201
- * @returns metadata generated for stahed op
1202
- */
1203
- applyStashedClearMessage(op) {
1204
- this.throwIfDisposed();
1205
- const previousValue = new Map(this._storage);
1206
- this.clearExceptPendingKeys(true);
1207
- const pendingMsgId = ++this.pendingMessageId;
1208
- this.pendingClearMessageIds.push(pendingMsgId);
1209
- const metadata = {
1210
- type: "clear",
1211
- pendingMessageId: pendingMsgId,
1212
- previousStorage: previousValue,
1213
- };
1214
- return metadata;
1215
- }
1216
1194
  /**
1217
1195
  * Process a delete operation.
1218
1196
  * @param msg - The message from the server to apply.
@@ -1220,7 +1198,6 @@ class SubDirectory extends TypedEventEmitter {
1220
1198
  * @param local - Whether the message originated from the local client
1221
1199
  * @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.
1222
1200
  * For messages from a remote client, this will be undefined.
1223
- * @internal
1224
1201
  */
1225
1202
  processDeleteMessage(msg, op, local, localOpMetadata) {
1226
1203
  this.throwIfDisposed();
@@ -1230,22 +1207,6 @@ class SubDirectory extends TypedEventEmitter {
1230
1207
  }
1231
1208
  this.deleteCore(op.key, local);
1232
1209
  }
1233
- /**
1234
- * Apply delete operation locally and generate metadata
1235
- * @param op - Op to apply
1236
- * @returns metadata generated for stahed op
1237
- */
1238
- applyStashedDeleteMessage(op) {
1239
- this.throwIfDisposed();
1240
- const previousValue = this.deleteCore(op.key, true);
1241
- const pendingMessageId = this.getKeyMessageId(op);
1242
- const localMetadata = {
1243
- type: "edit",
1244
- pendingMessageId,
1245
- previousValue,
1246
- };
1247
- return localMetadata;
1248
- }
1249
1210
  /**
1250
1211
  * Process a set operation.
1251
1212
  * @param msg - The message from the server to apply.
@@ -1253,7 +1214,6 @@ class SubDirectory extends TypedEventEmitter {
1253
1214
  * @param local - Whether the message originated from the local client
1254
1215
  * @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.
1255
1216
  * For messages from a remote client, this will be undefined.
1256
- * @internal
1257
1217
  */
1258
1218
  processSetMessage(msg, op, context, local, localOpMetadata) {
1259
1219
  this.throwIfDisposed();
@@ -1266,24 +1226,6 @@ class SubDirectory extends TypedEventEmitter {
1266
1226
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1267
1227
  this.setCore(op.key, context, local);
1268
1228
  }
1269
- /**
1270
- * Apply set operation locally and generate metadata
1271
- * @param op - Op to apply
1272
- * @returns metadata generated for stahed op
1273
- */
1274
- applyStashedSetMessage(op, context) {
1275
- this.throwIfDisposed();
1276
- // Set the value locally.
1277
- const previousValue = this.setCore(op.key, context, true);
1278
- // Create metadata
1279
- const pendingMessageId = this.getKeyMessageId(op);
1280
- const localMetadata = {
1281
- type: "edit",
1282
- pendingMessageId,
1283
- previousValue,
1284
- };
1285
- return localMetadata;
1286
- }
1287
1229
  /**
1288
1230
  * Process a create subdirectory operation.
1289
1231
  * @param msg - The message from the server to apply.
@@ -1291,7 +1233,6 @@ class SubDirectory extends TypedEventEmitter {
1291
1233
  * @param local - Whether the message originated from the local client
1292
1234
  * @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.
1293
1235
  * For messages from a remote client, this will be undefined.
1294
- * @internal
1295
1236
  */
1296
1237
  processCreateSubDirectoryMessage(msg, op, local, localOpMetadata) {
1297
1238
  this.throwIfDisposed();
@@ -1302,21 +1243,6 @@ class SubDirectory extends TypedEventEmitter {
1302
1243
  assertNonNullClientId(msg.clientId);
1303
1244
  this.createSubDirectoryCore(op.subdirName, local, { seq: msg.sequenceNumber, clientSeq: msg.clientSequenceNumber }, msg.clientId);
1304
1245
  }
1305
- /**
1306
- * Apply createSubDirectory operation locally and generate metadata
1307
- * @param op - Op to apply
1308
- * @returns metadata generated for stahed op
1309
- */
1310
- applyStashedCreateSubDirMessage(op) {
1311
- this.throwIfDisposed();
1312
- // Create the sub directory locally first.
1313
- this.createSubDirectoryCore(op.subdirName, true, this.getLocalSeq(), this.runtime.clientId ?? "detached");
1314
- this.updatePendingSubDirMessageCount(op);
1315
- const localOpMetadata = {
1316
- type: "createSubDir",
1317
- };
1318
- return localOpMetadata;
1319
- }
1320
1246
  /**
1321
1247
  * Process a delete subdirectory operation.
1322
1248
  * @param msg - The message from the server to apply.
@@ -1324,7 +1250,6 @@ class SubDirectory extends TypedEventEmitter {
1324
1250
  * @param local - Whether the message originated from the local client
1325
1251
  * @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.
1326
1252
  * For messages from a remote client, this will be undefined.
1327
- * @internal
1328
1253
  */
1329
1254
  processDeleteSubDirectoryMessage(msg, op, local, localOpMetadata) {
1330
1255
  this.throwIfDisposed();
@@ -1334,21 +1259,6 @@ class SubDirectory extends TypedEventEmitter {
1334
1259
  }
1335
1260
  this.deleteSubDirectoryCore(op.subdirName, local);
1336
1261
  }
1337
- /**
1338
- * Apply deleteSubDirectory operation locally and generate metadata
1339
- * @param op - Op to apply
1340
- * @returns metadata generated for stahed op
1341
- */
1342
- applyStashedDeleteSubDirMessage(op) {
1343
- this.throwIfDisposed();
1344
- const subDir = this.deleteSubDirectoryCore(op.subdirName, true);
1345
- this.updatePendingSubDirMessageCount(op);
1346
- const metadata = {
1347
- type: "deleteSubDir",
1348
- subDirectory: subDir,
1349
- };
1350
- return metadata;
1351
- }
1352
1262
  /**
1353
1263
  * Submit a clear operation.
1354
1264
  * @param op - The operation
@@ -1367,7 +1277,6 @@ class SubDirectory extends TypedEventEmitter {
1367
1277
  /**
1368
1278
  * Resubmit a clear operation.
1369
1279
  * @param op - The operation
1370
- * @internal
1371
1280
  */
1372
1281
  resubmitClearMessage(op, localOpMetadata) {
1373
1282
  assert(isClearLocalOpMetadata(localOpMetadata), 0x32b /* Invalid localOpMetadata for clear */);
@@ -1386,11 +1295,11 @@ class SubDirectory extends TypedEventEmitter {
1386
1295
  // We don't reuse the metadata pendingMessageId but send a new one on each submit.
1387
1296
  const pendingMessageId = ++this.pendingMessageId;
1388
1297
  const pendingMessageIds = this.pendingKeys.get(op.key);
1389
- if (pendingMessageIds !== undefined) {
1390
- pendingMessageIds.push(pendingMessageId);
1298
+ if (pendingMessageIds === undefined) {
1299
+ this.pendingKeys.set(op.key, [pendingMessageId]);
1391
1300
  }
1392
1301
  else {
1393
- this.pendingKeys.set(op.key, [pendingMessageId]);
1302
+ pendingMessageIds.push(pendingMessageId);
1394
1303
  }
1395
1304
  return pendingMessageId;
1396
1305
  }
@@ -1409,7 +1318,6 @@ class SubDirectory extends TypedEventEmitter {
1409
1318
  * Submit a key message to remote clients based on a previous submit.
1410
1319
  * @param op - The map key message
1411
1320
  * @param localOpMetadata - Metadata from the previous submit
1412
- * @internal
1413
1321
  */
1414
1322
  resubmitKeyMessage(op, localOpMetadata) {
1415
1323
  assert(isKeyEditLocalOpMetadata(localOpMetadata), 0x32d /* Invalid localOpMetadata in submit */);
@@ -1418,7 +1326,7 @@ class SubDirectory extends TypedEventEmitter {
1418
1326
  // Only submit the op, if we have record for it, otherwise it is possible that the older instance
1419
1327
  // is already deleted, in which case we don't need to submit the op.
1420
1328
  if (pendingMessageIds !== undefined) {
1421
- const index = pendingMessageIds.findIndex((id) => id === localOpMetadata.pendingMessageId);
1329
+ const index = pendingMessageIds.indexOf(localOpMetadata.pendingMessageId);
1422
1330
  if (index === -1) {
1423
1331
  return;
1424
1332
  }
@@ -1482,7 +1390,6 @@ class SubDirectory extends TypedEventEmitter {
1482
1390
  * Submit a subdirectory operation again
1483
1391
  * @param op - The operation
1484
1392
  * @param localOpMetadata - metadata submitted with the op originally
1485
- * @internal
1486
1393
  */
1487
1394
  resubmitSubDirectoryMessage(op, localOpMetadata) {
1488
1395
  assert(isSubDirLocalOpMetadata(localOpMetadata), 0x32f /* Invalid localOpMetadata for sub directory op */);
@@ -1509,7 +1416,6 @@ class SubDirectory extends TypedEventEmitter {
1509
1416
  * Get the storage of this subdirectory in a serializable format, to be used in snapshotting.
1510
1417
  * @param serializer - The serializer to use to serialize handles in its values.
1511
1418
  * @returns The JSONable string representing the storage of this subdirectory
1512
- * @internal
1513
1419
  */
1514
1420
  *getSerializedStorage(serializer) {
1515
1421
  this.throwIfDisposed();
@@ -1523,7 +1429,7 @@ class SubDirectory extends TypedEventEmitter {
1523
1429
  this.throwIfDisposed();
1524
1430
  const createInfo = {
1525
1431
  csn: this.seqData.seq,
1526
- ccIds: Array.from(this.clientIds),
1432
+ ccIds: [...this.clientIds],
1527
1433
  };
1528
1434
  return createInfo;
1529
1435
  }
@@ -1531,7 +1437,6 @@ class SubDirectory extends TypedEventEmitter {
1531
1437
  * Populate a key value in this subdirectory's storage, to be used when loading from snapshot.
1532
1438
  * @param key - The key to populate
1533
1439
  * @param localValue - The local value to populate into it
1534
- * @internal
1535
1440
  */
1536
1441
  populateStorage(key, localValue) {
1537
1442
  this.throwIfDisposed();
@@ -1541,7 +1446,6 @@ class SubDirectory extends TypedEventEmitter {
1541
1446
  * Populate a subdirectory into this subdirectory, to be used when loading from snapshot.
1542
1447
  * @param subdirName - The name of the subdirectory to add
1543
1448
  * @param newSubDir - The new subdirectory to add
1544
- * @internal
1545
1449
  */
1546
1450
  populateSubDirectory(subdirName, newSubDir) {
1547
1451
  this.throwIfDisposed();
@@ -1552,7 +1456,6 @@ class SubDirectory extends TypedEventEmitter {
1552
1456
  * value so op handlers can be retrieved
1553
1457
  * @param key - The key to retrieve from
1554
1458
  * @returns The local value
1555
- * @internal
1556
1459
  */
1557
1460
  getLocalValue(key) {
1558
1461
  this.throwIfDisposed();
@@ -1595,37 +1498,46 @@ class SubDirectory extends TypedEventEmitter {
1595
1498
  }
1596
1499
  }
1597
1500
  else if ((op.type === "delete" || op.type === "set") && localOpMetadata.type === "edit") {
1501
+ const key = op.key;
1502
+ assert(key !== undefined, 0x8ad /* "key" property is missing from edit operation. */);
1503
+ assert(typeof key === "string", 0x8ae /* "key" property in edit operation is misconfigured. Expected a string. */);
1598
1504
  if (localOpMetadata.previousValue === undefined) {
1599
- this.deleteCore(op.key, true);
1505
+ this.deleteCore(key, true);
1600
1506
  }
1601
1507
  else {
1602
- this.setCore(op.key, localOpMetadata.previousValue, true);
1508
+ this.setCore(key, localOpMetadata.previousValue, true);
1603
1509
  }
1604
- this.rollbackPendingMessageId(this.pendingKeys, op.key, localOpMetadata.pendingMessageId);
1510
+ this.rollbackPendingMessageId(this.pendingKeys, key, localOpMetadata.pendingMessageId);
1605
1511
  }
1606
1512
  else if (op.type === "createSubDirectory" && localOpMetadata.type === "createSubDir") {
1607
- this.deleteSubDirectoryCore(op.subdirName, true);
1608
- this.decrementPendingSubDirCount(this.pendingCreateSubDirectoriesTracker, op.subdirName);
1513
+ const subdirName = op.subdirName;
1514
+ assert(subdirName !== undefined, 0x8af /* "subdirName" property is missing from "createSubDirectory" operation. */);
1515
+ assert(typeof subdirName === "string", 0x8b0 /* "subdirName" property in "createSubDirectory" operation is misconfigured. Expected a string. */);
1516
+ this.deleteSubDirectoryCore(subdirName, true);
1517
+ this.decrementPendingSubDirCount(this.pendingCreateSubDirectoriesTracker, subdirName);
1609
1518
  }
1610
1519
  else if (op.type === "deleteSubDirectory" && localOpMetadata.type === "deleteSubDir") {
1520
+ const subdirName = op.subdirName;
1521
+ assert(subdirName !== undefined, 0x8b1 /* "subdirName" property is missing from "deleteSubDirectory" operation. */);
1522
+ assert(typeof subdirName === "string", 0x8b2 /* "subdirName" property in "deleteSubDirectory" operation is misconfigured. Expected a string. */);
1611
1523
  if (localOpMetadata.subDirectory !== undefined) {
1612
1524
  this.undeleteSubDirectoryTree(localOpMetadata.subDirectory);
1613
1525
  // don't need to register events because deleting never unregistered
1614
- this._subdirectories.set(op.subdirName, localOpMetadata.subDirectory);
1526
+ this._subdirectories.set(subdirName, localOpMetadata.subDirectory);
1615
1527
  // Restore the record in creation tracker
1616
1528
  if (isAcknowledgedOrDetached(localOpMetadata.subDirectory.seqData)) {
1617
- this.ackedCreationSeqTracker.set(op.subdirName, {
1529
+ this.ackedCreationSeqTracker.set(subdirName, {
1618
1530
  ...localOpMetadata.subDirectory.seqData,
1619
1531
  });
1620
1532
  }
1621
1533
  else {
1622
- this.localCreationSeqTracker.set(op.subdirName, {
1534
+ this.localCreationSeqTracker.set(subdirName, {
1623
1535
  ...localOpMetadata.subDirectory.seqData,
1624
1536
  });
1625
1537
  }
1626
- this.emit("subDirectoryCreated", op.subdirName, true, this);
1538
+ this.emit("subDirectoryCreated", subdirName, true, this);
1627
1539
  }
1628
- this.decrementPendingSubDirCount(this.pendingDeleteSubDirectoriesTracker, op.subDirName);
1540
+ this.decrementPendingSubDirCount(this.pendingDeleteSubDirectoriesTracker, subdirName);
1629
1541
  }
1630
1542
  else {
1631
1543
  throw new Error("Unsupported op for rollback");
@@ -1874,11 +1786,11 @@ class SubDirectory extends TypedEventEmitter {
1874
1786
  * Store the sequnce numbers of newly created subdirectory to the proper creation tracker, based
1875
1787
  * on whether the creation behavior has been ack'd or not
1876
1788
  */
1877
- if (!isAcknowledgedOrDetached(seqData)) {
1878
- this.localCreationSeqTracker.set(subdirName, { ...seqData });
1789
+ if (isAcknowledgedOrDetached(seqData)) {
1790
+ this.ackedCreationSeqTracker.set(subdirName, { ...seqData });
1879
1791
  }
1880
1792
  else {
1881
- this.ackedCreationSeqTracker.set(subdirName, { ...seqData });
1793
+ this.localCreationSeqTracker.set(subdirName, { ...seqData });
1882
1794
  }
1883
1795
  this.registerEventsOnSubDirectory(subDir, subdirName);
1884
1796
  this._subdirectories.set(subdirName, subDir);
@@ -1946,4 +1858,4 @@ class SubDirectory extends TypedEventEmitter {
1946
1858
  }
1947
1859
  }
1948
1860
  }
1949
- //# sourceMappingURL=directory.mjs.map
1861
+ //# sourceMappingURL=directory.js.map