vvvfs 0.0.8 → 0.0.9

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
@@ -44,6 +44,7 @@ const vvvfs = new VVVFS("vvvfs", {
44
44
  await vvvfs.init("UserName"); // 初始化文件系统
45
45
  await vvvfs.watch("/home/user/Desktop/test.txt", (type) => {
46
46
  console.log(type); // 打印文件操作的类型
47
+ return true; // 返回true或false,表示是否取消该操作
47
48
  });
48
49
  await vvvfs.createDir("/home/user/Desktop"); // 创建目录,返回true和false
49
50
  await vvvfs.writeText("/home/user/Desktop/test.txt", "Hello World!"); // 写入文本文件,写入文件还包括write(path: string, content: Blob)和writeJson(path: string, content: Record<string, any>)方法,返回true和false
@@ -81,9 +82,13 @@ const vvvfs = new VVVFS("vvvfs", {
81
82
 
82
83
  ## 更新日志
83
84
 
85
+ ### 0.0.9
86
+
87
+ - 更新 `watch` 方法,监听时,返回 `true` 表示取消该操作
88
+
84
89
  ### 0.0.8
85
90
 
86
- - 新增 `watch` 方法
91
+ - 新增 `watch` 方法 (该方法属于实验性功能,后期可能会改变)
87
92
 
88
93
  ### 0.0.7
89
94
 
package/index.html CHANGED
@@ -13,11 +13,13 @@
13
13
  (async () => {
14
14
  try {
15
15
  globalThis.vvvfs = new VVVFS();
16
+ vvvfs.options.throwError = true;
16
17
  await vvvfs.reset();
17
18
  await vvvfs.init("IFTC");
18
19
  console.log(vvvfs);
19
20
  await vvvfs.watch("/test.txt", (type) => {
20
21
  console.log(type);
22
+ // return true;
21
23
  });
22
24
  console.log("创建文件", await vvvfs.createFile("/test.txt"));
23
25
  console.log("写入文件", await vvvfs.writeText("/test.txt", "Hello World"));
package/index.ts CHANGED
@@ -216,7 +216,7 @@ class VVVFSFile {
216
216
  async search(query: string) {
217
217
  return await this._vvvfs.search(this._path, query);
218
218
  }
219
- async watch(handler: (type: string) => void) {
219
+ async watch(handler: (type: string) => Promise<boolean>) {
220
220
  return await this._vvvfs.watch(this._path, handler);
221
221
  }
222
222
  }
@@ -234,6 +234,10 @@ class VVVFS {
234
234
  * 虚拟文件系统文件类
235
235
  */
236
236
  static File = VVVFSFile;
237
+ /**
238
+ * 虚拟文件系统监听器
239
+ */
240
+ watchers: Record<string, Array<(type: string) => Promise<boolean>>> = {};
237
241
  /**
238
242
  * 创建虚拟文件系统
239
243
  * @param name 虚拟文件系统名称
@@ -413,11 +417,21 @@ class VVVFS {
413
417
  */
414
418
  async createFile(path: string) {
415
419
  const targetPath = joinPath(path);
416
- if (await this.exists(targetPath)) {
417
- console.warn("文件已存在");
418
- return true;
419
- }
420
420
  try {
421
+ if (this.watchers[targetPath]) {
422
+ for (const handler of this.watchers[targetPath]) {
423
+ if (await handler("create")) {
424
+ if (this.options.throwError) {
425
+ throw new VVVFSError("CreateFile", "创建文件失败:监听器取消了操作");
426
+ }
427
+ return false;
428
+ }
429
+ }
430
+ }
431
+ if (await this.exists(targetPath)) {
432
+ console.warn("文件已存在");
433
+ return true;
434
+ }
421
435
  const { name, parent } = parsePath(targetPath);
422
436
  if (!(await this.exists(parent))) {
423
437
  await this.createDir(parent);
@@ -445,11 +459,21 @@ class VVVFS {
445
459
  */
446
460
  async createDir(path: string) {
447
461
  const targetPath = joinPath(path);
448
- if (await this.exists(targetPath)) {
449
- console.warn("目录已存在");
450
- return true;
451
- }
452
462
  try {
463
+ if (this.watchers[targetPath]) {
464
+ for (const handler of this.watchers[targetPath]) {
465
+ if (await handler("create")) {
466
+ if (this.options.throwError) {
467
+ throw new VVVFSError("CreateDir", "创建目录失败:监听器取消了操作");
468
+ }
469
+ return false;
470
+ }
471
+ }
472
+ }
473
+ if (await this.exists(targetPath)) {
474
+ console.warn("目录已存在");
475
+ return true;
476
+ }
453
477
  const { name, parent } = parsePath(targetPath);
454
478
  if (!(await this.exists(parent))) {
455
479
  if (parent == "/") {
@@ -510,6 +534,16 @@ class VVVFS {
510
534
  async write(path: string, content: Blob) {
511
535
  try {
512
536
  const targetPath = joinPath(path);
537
+ if (this.watchers[targetPath]) {
538
+ for (const handler of this.watchers[targetPath]) {
539
+ if (await handler("write")) {
540
+ if (this.options.throwError) {
541
+ throw new VVVFSError("Write", "写入文件失败:监听器取消了操作");
542
+ }
543
+ return false;
544
+ }
545
+ }
546
+ }
513
547
  if (!(await this.exists(targetPath))) {
514
548
  const success = await this.createFile(targetPath);
515
549
  if (!success) {
@@ -597,6 +631,16 @@ class VVVFS {
597
631
  async read(path: string) {
598
632
  try {
599
633
  const targetPath = joinPath(path);
634
+ if (this.watchers[targetPath]) {
635
+ for (const handler of this.watchers[targetPath]) {
636
+ if (await handler("read")) {
637
+ if (this.options.throwError) {
638
+ throw new VVVFSError("Read", "读取文件失败:监听器取消了操作");
639
+ }
640
+ return null;
641
+ }
642
+ }
643
+ }
600
644
  if (!(await this.exists(targetPath))) {
601
645
  console.warn("文件不存在");
602
646
  if (this.options.throwError) {
@@ -707,6 +751,23 @@ class VVVFS {
707
751
  async list(path: string) {
708
752
  try {
709
753
  const targetPath = joinPath(path);
754
+ if (this.watchers[targetPath]) {
755
+ for (const handler of this.watchers[targetPath]) {
756
+ if (await handler("list")) {
757
+ if (this.options.throwError) {
758
+ throw new VVVFSError("List", "列出目录下的文件失败:监听器取消了操作");
759
+ }
760
+ return [];
761
+ }
762
+ }
763
+ }
764
+ if (!(await this.exists(targetPath))) {
765
+ console.warn("路径不存在");
766
+ if (this.options.throwError) {
767
+ throw new VVVFSError("List", "路径不存在");
768
+ }
769
+ return [];
770
+ }
710
771
  if (!(await this.isDir(targetPath))) {
711
772
  console.warn("路径不是目录");
712
773
  if (this.options.throwError) {
@@ -734,6 +795,16 @@ class VVVFS {
734
795
  try {
735
796
  const sourcePath = joinPath(path);
736
797
  const { name, parent } = parsePath(sourcePath);
798
+ if (this.watchers[sourcePath]) {
799
+ for (const handler of this.watchers[sourcePath]) {
800
+ if (await handler("rename")) {
801
+ if (this.options.throwError) {
802
+ throw new VVVFSError("Rename", "重命名文件失败:监听器取消了操作");
803
+ }
804
+ return false;
805
+ }
806
+ }
807
+ }
737
808
  if (!(await this.exists(sourcePath))) {
738
809
  console.warn("文件不存在");
739
810
  if (this.options.throwError) {
@@ -793,6 +864,16 @@ class VVVFS {
793
864
  async delete(path: string) {
794
865
  try {
795
866
  const targetPath = joinPath(path);
867
+ if (this.watchers[targetPath]) {
868
+ for (const handler of this.watchers[targetPath]) {
869
+ if (await handler("delete")) {
870
+ if (this.options.throwError) {
871
+ throw new VVVFSError("Delete", "删除文件失败:监听器取消了操作");
872
+ }
873
+ return false;
874
+ }
875
+ }
876
+ }
796
877
  if (!(await this.exists(targetPath))) {
797
878
  console.warn("文件不存在");
798
879
  if (this.options.throwError) {
@@ -839,6 +920,19 @@ class VVVFS {
839
920
  try {
840
921
  const sourcePath = joinPath(path);
841
922
  const destinationPath = joinPath(newPath);
923
+ if (this.watchers[sourcePath]) {
924
+ for (const handler of this.watchers[sourcePath]) {
925
+ if (await handler("move")) {
926
+ if (this.options.throwError) {
927
+ throw new VVVFSError("Move", "移动文件失败:监听器取消了操作");
928
+ }
929
+ return false;
930
+ }
931
+ }
932
+ }
933
+ if (sourcePath === destinationPath) {
934
+ return true;
935
+ }
842
936
  if (await this.exists(destinationPath)) {
843
937
  console.warn("目标文件已存在");
844
938
  if (this.options.throwError) {
@@ -903,6 +997,16 @@ class VVVFS {
903
997
  try {
904
998
  const sourcePath = joinPath(path);
905
999
  const destinationPath = joinPath(newPath);
1000
+ if (this.watchers[sourcePath]) {
1001
+ for (const handler of this.watchers[sourcePath]) {
1002
+ if (await handler("copy")) {
1003
+ if (this.options.throwError) {
1004
+ throw new VVVFSError("Copy", "复制文件失败:监听器取消了操作");
1005
+ }
1006
+ return false;
1007
+ }
1008
+ }
1009
+ }
906
1010
  if (await this.exists(destinationPath)) {
907
1011
  console.warn("目标文件已存在");
908
1012
  if (this.options.throwError) {
@@ -1006,62 +1110,12 @@ class VVVFS {
1006
1110
  return null;
1007
1111
  }
1008
1112
  }
1009
- async watch(path: string, handler: (type: string) => void) {
1010
- const targetPath = joinPath(path);
1011
-
1012
- const getState = async () => {
1013
- const exists = await this.exists(targetPath);
1014
- if (!exists) {
1015
- return { exists: false, signature: "" };
1016
- }
1017
- if (await this.isDir(targetPath)) {
1018
- const records = await this.db.files
1019
- .filter(
1020
- (file) =>
1021
- file.path === targetPath || file.path.startsWith(targetPath + "/"),
1022
- )
1023
- .toArray();
1024
- const signature = records
1025
- .map((file) => {
1026
- const fullPath = joinPath(file.path, file.name);
1027
- const fileInfo = file.file
1028
- ? `${file.file.type}:${file.file.size}:${file.file.lastModified}`
1029
- : "null";
1030
- return `${fullPath}:${file.type}:${fileInfo}`;
1031
- })
1032
- .sort()
1033
- .join("|");
1034
- return { exists: true, signature };
1035
- }
1036
- const { name, parent } = parsePath(targetPath);
1037
- const record = await this.db.files.where({ name, path: parent, type: "file" }).first();
1038
- const signature = record?.file
1039
- ? `${record.file.type}:${record.file.size}:${record.file.lastModified}`
1040
- : "";
1041
- return { exists: true, signature };
1042
- };
1043
-
1044
- let previousState = await getState();
1045
- setInterval(async () => {
1046
- try {
1047
- const currentState = await getState();
1048
- if (
1049
- previousState.exists !== currentState.exists ||
1050
- previousState.signature !== currentState.signature
1051
- ) {
1052
- if (!previousState.exists && currentState.exists) {
1053
- handler("create");
1054
- } else if (previousState.exists && !currentState.exists) {
1055
- handler("unlink");
1056
- } else {
1057
- handler("change");
1058
- }
1059
- previousState = currentState;
1060
- }
1061
- } catch (error) {
1062
- console.error("监听失败", error);
1063
- }
1064
- });
1113
+ async watch(path: string, handler: (type: string) => Promise<boolean>) {
1114
+ path = joinPath(path);
1115
+ if (!this.watchers[path]) {
1116
+ this.watchers[path] = [];
1117
+ }
1118
+ this.watchers[path].push(handler);
1065
1119
  }
1066
1120
  }
1067
1121
  function parsePath(path: string) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vvvfs",
3
- "version": "0.0.8",
3
+ "version": "0.0.9",
4
4
  "description": "一个使用IndexDB实现的虚拟文件系统",
5
5
  "keywords": [
6
6
  "Virtual",