@fluidframework/map 0.58.2002 → 0.59.1000

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.
package/lib/directory.js CHANGED
@@ -3,6 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  import { assert, TypedEventEmitter } from "@fluidframework/common-utils";
6
+ import { UsageError } from "@fluidframework/container-utils";
6
7
  import { readAndParse } from "@fluidframework/driver-utils";
7
8
  import { MessageType, } from "@fluidframework/protocol-definitions";
8
9
  import { SharedObject, ValueType } from "@fluidframework/shared-object-base";
@@ -196,6 +197,12 @@ export class SharedDirectory extends SharedObject {
196
197
  this.root.set(key, value);
197
198
  return this;
198
199
  }
200
+ dispose(error) {
201
+ this.root.dispose(error);
202
+ }
203
+ get disposed() {
204
+ return this.root.disposed;
205
+ }
199
206
  /**
200
207
  * Deletes the given key from within this IDirectory.
201
208
  * @param key - The key to delete
@@ -245,6 +252,12 @@ export class SharedDirectory extends SharedObject {
245
252
  entries() {
246
253
  return this.root.entries();
247
254
  }
255
+ /**
256
+ * {@inheritDoc IDirectory.countSubDirectory}
257
+ */
258
+ countSubDirectory() {
259
+ return this.root.countSubDirectory();
260
+ }
248
261
  /**
249
262
  * Get an iterator over the keys under this IDirectory.
250
263
  * @returns The iterator
@@ -527,6 +540,10 @@ class SubDirectory extends TypedEventEmitter {
527
540
  this.runtime = runtime;
528
541
  this.serializer = serializer;
529
542
  this.absolutePath = absolutePath;
543
+ /**
544
+ * Tells if the sub directory is disposed or not.
545
+ */
546
+ this._disposed = false;
530
547
  /**
531
548
  * String representation for the class.
532
549
  */
@@ -557,12 +574,25 @@ class SubDirectory extends TypedEventEmitter {
557
574
  */
558
575
  this.pendingClearMessageId = -1;
559
576
  }
577
+ dispose(error) {
578
+ this._disposed = true;
579
+ this.emit("disposed", this);
580
+ }
581
+ get disposed() {
582
+ return this._disposed;
583
+ }
584
+ throwIfDisposed() {
585
+ if (this._disposed) {
586
+ throw new UsageError("Cannot access Disposed subDirectory");
587
+ }
588
+ }
560
589
  /**
561
590
  * Checks whether the given key exists in this IDirectory.
562
591
  * @param key - The key to check
563
592
  * @returns True if the key exists, false otherwise
564
593
  */
565
594
  has(key) {
595
+ this.throwIfDisposed();
566
596
  return this._storage.has(key);
567
597
  }
568
598
  /**
@@ -570,12 +600,14 @@ class SubDirectory extends TypedEventEmitter {
570
600
  */
571
601
  get(key) {
572
602
  var _a;
603
+ this.throwIfDisposed();
573
604
  return (_a = this._storage.get(key)) === null || _a === void 0 ? void 0 : _a.value;
574
605
  }
575
606
  /**
576
607
  * {@inheritDoc IDirectory.set}
577
608
  */
578
609
  set(key, value) {
610
+ this.throwIfDisposed();
579
611
  // Undefined/null keys can't be serialized to JSON in the manner we currently snapshot.
580
612
  if (key === undefined || key === null) {
581
613
  throw new Error("Undefined and null keys are not supported");
@@ -598,10 +630,17 @@ class SubDirectory extends TypedEventEmitter {
598
630
  this.submitKeyMessage(op);
599
631
  return this;
600
632
  }
633
+ /**
634
+ * {@inheritDoc IDirectory.countSubDirectory}
635
+ */
636
+ countSubDirectory() {
637
+ return this._subdirectories.size;
638
+ }
601
639
  /**
602
640
  * {@inheritDoc IDirectory.createSubDirectory}
603
641
  */
604
642
  createSubDirectory(subdirName) {
643
+ this.throwIfDisposed();
605
644
  // Undefined/null subdirectory names can't be serialized to JSON in the manner we currently snapshot.
606
645
  if (subdirName === undefined || subdirName === null) {
607
646
  throw new Error("SubDirectory name may not be undefined or null");
@@ -629,18 +668,21 @@ class SubDirectory extends TypedEventEmitter {
629
668
  * {@inheritDoc IDirectory.getSubDirectory}
630
669
  */
631
670
  getSubDirectory(subdirName) {
671
+ this.throwIfDisposed();
632
672
  return this._subdirectories.get(subdirName);
633
673
  }
634
674
  /**
635
675
  * {@inheritDoc IDirectory.hasSubDirectory}
636
676
  */
637
677
  hasSubDirectory(subdirName) {
678
+ this.throwIfDisposed();
638
679
  return this._subdirectories.has(subdirName);
639
680
  }
640
681
  /**
641
682
  * {@inheritDoc IDirectory.deleteSubDirectory}
642
683
  */
643
684
  deleteSubDirectory(subdirName) {
685
+ this.throwIfDisposed();
644
686
  // Delete the sub directory locally first.
645
687
  const successfullyRemoved = this.deleteSubDirectoryCore(subdirName, true);
646
688
  // If we are not attached, don't submit the op.
@@ -659,12 +701,14 @@ class SubDirectory extends TypedEventEmitter {
659
701
  * {@inheritDoc IDirectory.subdirectories}
660
702
  */
661
703
  subdirectories() {
704
+ this.throwIfDisposed();
662
705
  return this._subdirectories.entries();
663
706
  }
664
707
  /**
665
708
  * {@inheritDoc IDirectory.getWorkingDirectory}
666
709
  */
667
710
  getWorkingDirectory(relativePath) {
711
+ this.throwIfDisposed();
668
712
  return this.directory.getWorkingDirectory(this.makeAbsolute(relativePath));
669
713
  }
670
714
  /**
@@ -673,6 +717,7 @@ class SubDirectory extends TypedEventEmitter {
673
717
  * @returns True if the key existed and was deleted, false if it did not exist
674
718
  */
675
719
  delete(key) {
720
+ this.throwIfDisposed();
676
721
  // Delete the key locally first.
677
722
  const successfullyRemoved = this.deleteCore(key, true);
678
723
  // If we are not attached, don't submit the op.
@@ -691,6 +736,7 @@ class SubDirectory extends TypedEventEmitter {
691
736
  * Deletes all keys from within this IDirectory.
692
737
  */
693
738
  clear() {
739
+ this.throwIfDisposed();
694
740
  // Clear the data locally first.
695
741
  this.clearCore(true);
696
742
  // If we are not attached, don't submit the op.
@@ -708,6 +754,7 @@ class SubDirectory extends TypedEventEmitter {
708
754
  * @param callback - Callback to issue
709
755
  */
710
756
  forEach(callback) {
757
+ this.throwIfDisposed();
711
758
  this._storage.forEach((localValue, key, map) => {
712
759
  callback(localValue.value, key, map);
713
760
  });
@@ -716,6 +763,7 @@ class SubDirectory extends TypedEventEmitter {
716
763
  * The number of entries under this IDirectory.
717
764
  */
718
765
  get size() {
766
+ this.throwIfDisposed();
719
767
  return this._storage.size;
720
768
  }
721
769
  /**
@@ -723,6 +771,7 @@ class SubDirectory extends TypedEventEmitter {
723
771
  * @returns The iterator
724
772
  */
725
773
  entries() {
774
+ this.throwIfDisposed();
726
775
  const localEntriesIterator = this._storage.entries();
727
776
  const iterator = {
728
777
  next() {
@@ -746,6 +795,7 @@ class SubDirectory extends TypedEventEmitter {
746
795
  * @returns The iterator
747
796
  */
748
797
  keys() {
798
+ this.throwIfDisposed();
749
799
  return this._storage.keys();
750
800
  }
751
801
  /**
@@ -753,6 +803,7 @@ class SubDirectory extends TypedEventEmitter {
753
803
  * @returns The iterator
754
804
  */
755
805
  values() {
806
+ this.throwIfDisposed();
756
807
  const localValuesIterator = this._storage.values();
757
808
  const iterator = {
758
809
  next() {
@@ -776,6 +827,7 @@ class SubDirectory extends TypedEventEmitter {
776
827
  * @returns The iterator
777
828
  */
778
829
  [Symbol.iterator]() {
830
+ this.throwIfDisposed();
779
831
  return this.entries();
780
832
  }
781
833
  /**
@@ -788,6 +840,7 @@ class SubDirectory extends TypedEventEmitter {
788
840
  * @internal
789
841
  */
790
842
  processClearMessage(op, local, localOpMetadata) {
843
+ this.throwIfDisposed();
791
844
  if (local) {
792
845
  assert(localOpMetadata !== undefined, 0x00f /* `pendingMessageId is missing from the local client's ${op.type} operation` */);
793
846
  const pendingMessageId = localOpMetadata;
@@ -809,6 +862,7 @@ class SubDirectory extends TypedEventEmitter {
809
862
  * @internal
810
863
  */
811
864
  processDeleteMessage(op, local, localOpMetadata) {
865
+ this.throwIfDisposed();
812
866
  if (!this.needProcessStorageOperation(op, local, localOpMetadata)) {
813
867
  return;
814
868
  }
@@ -824,6 +878,7 @@ class SubDirectory extends TypedEventEmitter {
824
878
  * @internal
825
879
  */
826
880
  processSetMessage(op, context, local, localOpMetadata) {
881
+ this.throwIfDisposed();
827
882
  if (!this.needProcessStorageOperation(op, local, localOpMetadata)) {
828
883
  return;
829
884
  }
@@ -842,6 +897,7 @@ class SubDirectory extends TypedEventEmitter {
842
897
  * @internal
843
898
  */
844
899
  processCreateSubDirectoryMessage(op, local, localOpMetadata) {
900
+ this.throwIfDisposed();
845
901
  if (!this.needProcessSubDirectoryOperations(op, local, localOpMetadata)) {
846
902
  return;
847
903
  }
@@ -857,6 +913,7 @@ class SubDirectory extends TypedEventEmitter {
857
913
  * @internal
858
914
  */
859
915
  processDeleteSubDirectoryMessage(op, local, localOpMetadata) {
916
+ this.throwIfDisposed();
860
917
  if (!this.needProcessSubDirectoryOperations(op, local, localOpMetadata)) {
861
918
  return;
862
919
  }
@@ -868,6 +925,7 @@ class SubDirectory extends TypedEventEmitter {
868
925
  * @internal
869
926
  */
870
927
  submitClearMessage(op) {
928
+ this.throwIfDisposed();
871
929
  const pendingMessageId = ++this.pendingMessageId;
872
930
  this.directory.submitDirectoryMessage(op, pendingMessageId);
873
931
  this.pendingClearMessageId = pendingMessageId;
@@ -878,6 +936,7 @@ class SubDirectory extends TypedEventEmitter {
878
936
  * @internal
879
937
  */
880
938
  submitKeyMessage(op) {
939
+ this.throwIfDisposed();
881
940
  const pendingMessageId = ++this.pendingMessageId;
882
941
  this.directory.submitDirectoryMessage(op, pendingMessageId);
883
942
  this.pendingKeys.set(op.key, pendingMessageId);
@@ -888,6 +947,7 @@ class SubDirectory extends TypedEventEmitter {
888
947
  * @internal
889
948
  */
890
949
  submitSubDirectoryMessage(op) {
950
+ this.throwIfDisposed();
891
951
  const pendingMessageId = ++this.pendingMessageId;
892
952
  this.directory.submitDirectoryMessage(op, pendingMessageId);
893
953
  this.pendingSubDirectories.set(op.subdirName, pendingMessageId);
@@ -899,6 +959,7 @@ class SubDirectory extends TypedEventEmitter {
899
959
  * @internal
900
960
  */
901
961
  *getSerializedStorage(serializer) {
962
+ this.throwIfDisposed();
902
963
  for (const [key, localValue] of this._storage) {
903
964
  const value = localValue.makeSerialized(serializer, this.directory.handle);
904
965
  const res = [key, value];
@@ -912,6 +973,7 @@ class SubDirectory extends TypedEventEmitter {
912
973
  * @internal
913
974
  */
914
975
  populateStorage(key, localValue) {
976
+ this.throwIfDisposed();
915
977
  this._storage.set(key, localValue);
916
978
  }
917
979
  /**
@@ -921,6 +983,7 @@ class SubDirectory extends TypedEventEmitter {
921
983
  * @internal
922
984
  */
923
985
  populateSubDirectory(subdirName, newSubDir) {
986
+ this.throwIfDisposed();
924
987
  this._subdirectories.set(subdirName, newSubDir);
925
988
  }
926
989
  /**
@@ -931,6 +994,7 @@ class SubDirectory extends TypedEventEmitter {
931
994
  * @internal
932
995
  */
933
996
  getLocalValue(key) {
997
+ this.throwIfDisposed();
934
998
  return this._storage.get(key);
935
999
  }
936
1000
  /**
@@ -1074,9 +1138,25 @@ class SubDirectory extends TypedEventEmitter {
1074
1138
  * @param op - The message if from a remote delete, or null if from a local delete
1075
1139
  */
1076
1140
  deleteSubDirectoryCore(subdirName, local) {
1141
+ const previousValue = this.getSubDirectory(subdirName);
1077
1142
  // This should make the subdirectory structure unreachable so it can be GC'd and won't appear in snapshots
1078
1143
  // Might want to consider cleaning out the structure more exhaustively though?
1079
- return this._subdirectories.delete(subdirName);
1144
+ const successfullyRemoved = this._subdirectories.delete(subdirName);
1145
+ this.disposeSubDirectoryTree(previousValue);
1146
+ return successfullyRemoved;
1147
+ }
1148
+ disposeSubDirectoryTree(directory) {
1149
+ if (!directory) {
1150
+ return;
1151
+ }
1152
+ // Dispose the subdirectory tree. This will dispose the subdirectories from bottom to top.
1153
+ const subDirectories = directory.subdirectories();
1154
+ for (const [_, subDirectory] of subDirectories) {
1155
+ this.disposeSubDirectoryTree(subDirectory);
1156
+ }
1157
+ if (typeof directory.dispose === "function") {
1158
+ directory.dispose();
1159
+ }
1080
1160
  }
1081
1161
  }
1082
1162
  //# sourceMappingURL=directory.js.map