vvvfs 0.0.6 → 0.0.7

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/README.md CHANGED
@@ -78,6 +78,10 @@ const vvvfs = new VVVFS("vvvfs", {
78
78
 
79
79
  ## 更新日志
80
80
 
81
+ ### 0.0.7
82
+
83
+ - AI 了优化一下
84
+
81
85
  ### 0.0.6
82
86
 
83
87
  - `VVVFS.File` 类中新增 `dbname` 和 `options` 属性
package/index.html CHANGED
@@ -26,6 +26,7 @@
26
26
  console.log("移动文件", await vvvfs.move("/test2.txt", "/test3.txt"));
27
27
  console.log("删除文件", await vvvfs.delete("/test.txt"));
28
28
  const file = new VVVFS.File("test.txt");
29
+ console.log("写入文件", await file.writeText("Hello World"));
29
30
  } catch (error) {
30
31
  console.error(error);
31
32
  }
package/index.ts CHANGED
@@ -409,22 +409,22 @@ class VVVFS {
409
409
  * @param path 文件路径
410
410
  */
411
411
  async createFile(path: string) {
412
- if (await this.exists(path)) {
412
+ const targetPath = joinPath(path);
413
+ if (await this.exists(targetPath)) {
413
414
  console.warn("文件已存在");
414
415
  return true;
415
416
  }
416
417
  try {
417
- const { name, parent } = parsePath(path);
418
+ const { name, parent } = parsePath(targetPath);
418
419
  if (!(await this.exists(parent))) {
419
420
  await this.createDir(parent);
420
421
  }
421
- // console.log(name, parent);
422
422
  await this.db.files.add({
423
423
  name: name,
424
424
  path: parent,
425
425
  type: "file",
426
426
  file: new File([], name, {
427
- type: mime.getType(path) || "application/octet-stream",
427
+ type: mime.getType(targetPath) || "application/octet-stream",
428
428
  }),
429
429
  });
430
430
  return true;
@@ -441,12 +441,13 @@ class VVVFS {
441
441
  * @param path 目录路径
442
442
  */
443
443
  async createDir(path: string) {
444
- if (await this.exists(path)) {
444
+ const targetPath = joinPath(path);
445
+ if (await this.exists(targetPath)) {
445
446
  console.warn("目录已存在");
446
447
  return true;
447
448
  }
448
449
  try {
449
- const { name, parent } = parsePath(path);
450
+ const { name, parent } = parsePath(targetPath);
450
451
  if (!(await this.exists(parent))) {
451
452
  if (parent == "/") {
452
453
  await this.db.files.add({
@@ -460,7 +461,6 @@ class VVVFS {
460
461
  await this.createDir(parent);
461
462
  }
462
463
  }
463
- console.log(name, parent);
464
464
  await this.db.files.add({
465
465
  name: name,
466
466
  path: parent,
@@ -482,7 +482,8 @@ class VVVFS {
482
482
  */
483
483
  async exists(path: string) {
484
484
  try {
485
- const { name, parent } = parsePath(path);
485
+ const targetPath = joinPath(path);
486
+ const { name, parent } = parsePath(targetPath);
486
487
  return (
487
488
  (await this.db.files
488
489
  .where({
@@ -505,8 +506,9 @@ class VVVFS {
505
506
  */
506
507
  async write(path: string, content: Blob) {
507
508
  try {
508
- if (!(await this.exists(path))) {
509
- const success = await this.createFile(path);
509
+ const targetPath = joinPath(path);
510
+ if (!(await this.exists(targetPath))) {
511
+ const success = await this.createFile(targetPath);
510
512
  if (!success) {
511
513
  console.warn("创建文件失败");
512
514
  if (this.options.throwError) {
@@ -515,19 +517,17 @@ class VVVFS {
515
517
  return false;
516
518
  }
517
519
  }
518
- const { name, parent } = parsePath(path);
519
- console.log(name, parent);
520
- if (await this.isDir(parent + "/" + name)) {
520
+ if (await this.isDir(targetPath)) {
521
521
  console.warn("路径已存在");
522
522
  if (this.options.throwError) {
523
523
  throw new VVVFSError("Write", "路径已存在");
524
524
  }
525
525
  return false;
526
526
  }
527
+ const { name, parent } = parsePath(targetPath);
527
528
  const file = new File([content], name, {
528
- type: mime.getType(path) || "application/octet-stream",
529
+ type: mime.getType(targetPath) || "application/octet-stream",
529
530
  });
530
- console.log(file);
531
531
  const fileRecord = await this.db.files.where({ name, path: parent }).first();
532
532
  if (fileRecord) {
533
533
  await this.db.files.put({
@@ -593,14 +593,15 @@ class VVVFS {
593
593
  */
594
594
  async read(path: string) {
595
595
  try {
596
- if (!(await this.exists(path))) {
596
+ const targetPath = joinPath(path);
597
+ if (!(await this.exists(targetPath))) {
597
598
  console.warn("文件不存在");
598
599
  if (this.options.throwError) {
599
600
  throw new VVVFSError("Read", "文件不存在");
600
601
  }
601
602
  return null;
602
603
  }
603
- const { name, parent } = parsePath(path);
604
+ const { name, parent } = parsePath(targetPath);
604
605
  return (await this.db.files.where({ name, path: parent }).first())?.file;
605
606
  } catch (error) {
606
607
  console.error("读取文件失败", error);
@@ -668,7 +669,8 @@ class VVVFS {
668
669
  */
669
670
  async isFile(path: string) {
670
671
  try {
671
- const { name, parent } = parsePath(path);
672
+ const targetPath = joinPath(path);
673
+ const { name, parent } = parsePath(targetPath);
672
674
  return (await this.db.files.where({ name, path: parent, type: "file" }).count()) > 0;
673
675
  } catch (error) {
674
676
  console.error("判断文件类型失败", error);
@@ -684,7 +686,8 @@ class VVVFS {
684
686
  */
685
687
  async isDir(path: string) {
686
688
  try {
687
- const { name, parent } = parsePath(path);
689
+ const targetPath = joinPath(path);
690
+ const { name, parent } = parsePath(targetPath);
688
691
  return (await this.db.files.where({ path: parent, name, type: "dir" }).count()) > 0;
689
692
  } catch (error) {
690
693
  console.error("判断文件类型失败", error);
@@ -700,8 +703,15 @@ class VVVFS {
700
703
  */
701
704
  async list(path: string) {
702
705
  try {
703
- const { name, parent } = parsePath(path);
704
- return (await this.db.files.where({ path: parent }).toArray())
706
+ const targetPath = joinPath(path);
707
+ if (!(await this.isDir(targetPath))) {
708
+ console.warn("路径不是目录");
709
+ if (this.options.throwError) {
710
+ throw new VVVFSError("List", "路径不是目录");
711
+ }
712
+ return [];
713
+ }
714
+ return (await this.db.files.where({ path: targetPath }).toArray())
705
715
  .map((file) => file.name)
706
716
  .filter((item) => item != "");
707
717
  } catch (error) {
@@ -719,20 +729,50 @@ class VVVFS {
719
729
  */
720
730
  async rename(path: string, newName: string) {
721
731
  try {
722
- if (!(await this.exists(path))) {
732
+ const sourcePath = joinPath(path);
733
+ const { name, parent } = parsePath(sourcePath);
734
+ if (!(await this.exists(sourcePath))) {
723
735
  console.warn("文件不存在");
724
736
  if (this.options.throwError) {
725
737
  throw new VVVFSError("Rename", "文件不存在");
726
738
  }
727
739
  return false;
728
740
  }
729
- const { name, parent } = parsePath(path);
730
- const file = await this.db.files.get({ path, name });
731
- await this.db.files.put({
741
+ const newPath = joinPath(parent, newName);
742
+ if (newPath === sourcePath) {
743
+ return true;
744
+ }
745
+ if (await this.exists(newPath)) {
746
+ console.warn("目标文件已存在");
747
+ if (this.options.throwError) {
748
+ throw new VVVFSError("Rename", "目标文件已存在");
749
+ }
750
+ return false;
751
+ }
752
+ const fileRecord = await this.db.files.where({ path: parent, name }).first();
753
+ if (!fileRecord) {
754
+ console.warn("文件记录未找到");
755
+ if (this.options.throwError) {
756
+ throw new VVVFSError("Rename", "文件记录未找到");
757
+ }
758
+ return false;
759
+ }
760
+ if (fileRecord.type === "dir") {
761
+ const descendants = await this.db.files
762
+ .filter(
763
+ (file) =>
764
+ file.path === sourcePath || file.path.startsWith(sourcePath + "/"),
765
+ )
766
+ .toArray();
767
+ for (const descendant of descendants) {
768
+ const relativePath = descendant.path.slice(sourcePath.length);
769
+ const updatedPath = joinPath(newPath + relativePath);
770
+ await this.db.files.update(descendant.id!, { path: updatedPath });
771
+ }
772
+ }
773
+ await this.db.files.update(fileRecord.id!, {
732
774
  name: newName,
733
775
  path: parent,
734
- type: "file",
735
- file: file!.file,
736
776
  });
737
777
  return true;
738
778
  } catch (e) {
@@ -749,29 +789,30 @@ class VVVFS {
749
789
  */
750
790
  async delete(path: string) {
751
791
  try {
752
- if (!(await this.exists(path))) {
792
+ const targetPath = joinPath(path);
793
+ if (!(await this.exists(targetPath))) {
753
794
  console.warn("文件不存在");
754
795
  if (this.options.throwError) {
755
796
  throw new VVVFSError("Delete", "文件不存在");
756
797
  }
757
798
  return false;
758
799
  }
759
- const { name, parent } = parsePath(path);
760
- if (await this.isDir(path)) {
761
- const files = await this.list(path);
800
+ const { name, parent } = parsePath(targetPath);
801
+ if (await this.isDir(targetPath)) {
802
+ const files = await this.list(targetPath);
762
803
  for (const file of files) {
763
- if (await this.isDir(joinPath(path, file))) {
764
- const fileRecord = await this.db.files
765
- .where({ name, path: parent })
766
- .first();
767
- await this.db.files.delete(fileRecord!.id!);
768
- }
769
- await this.delete(joinPath(parent, file));
804
+ await this.delete(joinPath(targetPath, file));
805
+ }
806
+ const dirRecord = await this.db.files.where({ name, path: parent, type: "dir" }).first();
807
+ if (dirRecord) {
808
+ await this.db.files.delete(dirRecord.id!);
770
809
  }
771
810
  return true;
772
811
  } else {
773
- const fileRecord = await this.db.files.where({ name, path: parent }).first();
774
- await this.db.files.delete(fileRecord!.id!);
812
+ const fileRecord = await this.db.files.where({ name, path: parent, type: "file" }).first();
813
+ if (fileRecord) {
814
+ await this.db.files.delete(fileRecord.id!);
815
+ }
775
816
  return true;
776
817
  }
777
818
  } catch (e) {
@@ -789,34 +830,51 @@ class VVVFS {
789
830
  */
790
831
  async move(path: string, newPath: string) {
791
832
  try {
792
- if (await this.exists(newPath)) {
833
+ const sourcePath = joinPath(path);
834
+ const destinationPath = joinPath(newPath);
835
+ if (await this.exists(destinationPath)) {
793
836
  console.warn("目标文件已存在");
794
837
  if (this.options.throwError) {
795
838
  throw new VVVFSError("Move", "目标文件已存在");
796
839
  }
797
840
  return false;
798
841
  }
799
- if (!(await this.exists(path))) {
842
+ if (!(await this.exists(sourcePath))) {
800
843
  console.warn("源文件不存在");
801
844
  if (this.options.throwError) {
802
845
  throw new VVVFSError("Move", "源文件不存在");
803
846
  }
804
847
  return false;
805
848
  }
806
- const { name, parent } = parsePath(path);
807
- const { name: newName, parent: newParent } = parsePath(newPath);
808
- await this.createDir(newParent);
809
- if (await this.isDir(path)) {
810
- const dirs = await this.list(path);
811
- for (const dir of dirs) {
812
- await this.move(path + "/" + dir, newPath + "/" + dir);
849
+ if (destinationPath.startsWith(sourcePath + "/")) {
850
+ console.warn("目标路径是源路径的子路径");
851
+ if (this.options.throwError) {
852
+ throw new VVVFSError("Move", "目标路径是源路径的子路径");
853
+ }
854
+ return false;
855
+ }
856
+ const { name, parent } = parsePath(sourcePath);
857
+ const { name: newName, parent: newParent } = parsePath(destinationPath);
858
+ if (await this.isDir(sourcePath)) {
859
+ await this.createDir(destinationPath);
860
+ const children = await this.list(sourcePath);
861
+ for (const child of children) {
862
+ await this.move(joinPath(sourcePath, child), joinPath(destinationPath, child));
863
+ }
864
+ const dirRecord = await this.db.files.where({ name, path: parent, type: "dir" }).first();
865
+ if (dirRecord) {
866
+ await this.db.files.delete(dirRecord.id!);
813
867
  }
868
+ return true;
814
869
  } else {
815
- const fileRecord = await this.db.files.where({ name, path: parent }).first();
816
- await this.db.files.update(fileRecord!.id!, { name: newName, path: newParent });
870
+ await this.createDir(newParent);
871
+ const fileRecord = await this.db.files.where({ name, path: parent, type: "file" }).first();
872
+ if (fileRecord) {
873
+ await this.db.files.update(fileRecord.id!, { name: newName, path: newParent });
874
+ return true;
875
+ }
876
+ return false;
817
877
  }
818
- await this.delete(path);
819
- return true;
820
878
  } catch (e) {
821
879
  console.error(e);
822
880
  if (this.options.throwError) {
@@ -832,33 +890,51 @@ class VVVFS {
832
890
  */
833
891
  async copy(path: string, newPath: string) {
834
892
  try {
835
- if (await this.exists(newPath)) {
893
+ const sourcePath = joinPath(path);
894
+ const destinationPath = joinPath(newPath);
895
+ if (await this.exists(destinationPath)) {
836
896
  console.warn("目标文件已存在");
837
897
  if (this.options.throwError) {
838
898
  throw new VVVFSError("Copy", "目标文件已存在");
839
899
  }
840
900
  return false;
841
901
  }
842
- if (!(await this.exists(path))) {
902
+ if (!(await this.exists(sourcePath))) {
843
903
  console.warn("源文件不存在");
844
904
  if (this.options.throwError) {
845
905
  throw new VVVFSError("Copy", "源文件不存在");
846
906
  }
847
907
  return false;
848
908
  }
849
- const { name, parent } = parsePath(path);
850
- const { name: newName, parent: newParent } = parsePath(newPath);
851
- await this.createDir(newParent);
852
- if (await this.isDir(path)) {
853
- const dirs = await this.list(path);
854
- for (const dir of dirs) {
855
- await this.move(path + "/" + dir, newPath + "/" + dir);
909
+ if (destinationPath.startsWith(sourcePath + "/")) {
910
+ console.warn("目标路径是源路径的子路径");
911
+ if (this.options.throwError) {
912
+ throw new VVVFSError("Copy", "目标路径是源路径的子路径");
856
913
  }
914
+ return false;
915
+ }
916
+ const { name, parent } = parsePath(sourcePath);
917
+ const { name: newName, parent: newParent } = parsePath(destinationPath);
918
+ if (await this.isDir(sourcePath)) {
919
+ await this.createDir(destinationPath);
920
+ const children = await this.list(sourcePath);
921
+ for (const child of children) {
922
+ await this.copy(joinPath(sourcePath, child), joinPath(destinationPath, child));
923
+ }
924
+ return true;
857
925
  } else {
858
- const fileRecord = await this.db.files.where({ name, path: parent }).first();
859
- await this.db.files.update(fileRecord!.id!, { name: newName, path: newParent });
926
+ const fileRecord = await this.db.files.where({ name, path: parent, type: "file" }).first();
927
+ if (fileRecord) {
928
+ await this.db.files.add({
929
+ name: newName,
930
+ path: newParent,
931
+ type: fileRecord.type,
932
+ file: fileRecord.file,
933
+ });
934
+ return true;
935
+ }
936
+ return false;
860
937
  }
861
- return true;
862
938
  } catch (e) {
863
939
  console.error(e);
864
940
  if (this.options.throwError) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vvvfs",
3
- "version": "0.0.6",
3
+ "version": "0.0.7",
4
4
  "description": "一个使用IndexDB实现的虚拟文件系统",
5
5
  "keywords": [
6
6
  "Virtual",