vvvfs 0.1.1 → 0.1.2
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 +5 -0
- package/index.html +2 -1
- package/index.ts +128 -55
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -50,6 +50,7 @@ const vvvfs = new VVVFS("vvvfs", {
|
|
|
50
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
|
|
51
51
|
await vvvfs.appendText("/home/user/Desktop/test.txt", "Hello World!"); // 追加文本文件,返回true和false
|
|
52
52
|
console.log(await vvvfs.readText("/home/user/Desktop/test.txt")); // 读取文本文件,读取文件还包括read(path: string): Blob | null和readJson(path: string): Record<string, any> | null方法
|
|
53
|
+
console.log(await vvvfs.readChunkText("/home/user/Desktop/test.txt", 0, 5)); // 读取文件块,返回string | null
|
|
53
54
|
await vvvfs.delete("/home/user/Desktop/test.txt"); // 删除文件,返回true和false
|
|
54
55
|
if (await vvvfs.exists("/home/user/Desktop")) {
|
|
55
56
|
// 判断文件或目录是否存在
|
|
@@ -83,6 +84,10 @@ const vvvfs = new VVVFS("vvvfs", {
|
|
|
83
84
|
|
|
84
85
|
## 更新日志
|
|
85
86
|
|
|
87
|
+
### 0.1.2
|
|
88
|
+
|
|
89
|
+
- 新增 `readChunk` 和 `readChunkText` 方法,用于读取文件块
|
|
90
|
+
|
|
86
91
|
### 0.1.1
|
|
87
92
|
|
|
88
93
|
- 新增 `append` 和 `appendText` 方法,用于追加内容
|
package/index.html
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
|
-
<html lang="
|
|
2
|
+
<html lang="zh-CN">
|
|
3
3
|
|
|
4
4
|
<head>
|
|
5
5
|
<meta charset="UTF-8">
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
console.log("文件是否存在", await vvvfs.exists("/test.txt"));
|
|
28
28
|
console.log("文件是否存在", await vvvfs.exists("/test2.txt"));
|
|
29
29
|
console.log("读取文件", await vvvfs.readText("/test.txt"));
|
|
30
|
+
console.log("读取文件块", await vvvfs.readTextChunk("/test.txt", 0, 5));
|
|
30
31
|
console.log("复制文件", await vvvfs.copy("/test.txt", "/test2.txt"));
|
|
31
32
|
console.log("搜索文件", await vvvfs.search("/", "t"));
|
|
32
33
|
console.log("移动文件", await vvvfs.move("/test2.txt", "/test3.txt"));
|
package/index.ts
CHANGED
|
@@ -129,6 +129,22 @@ class VVVFSFile {
|
|
|
129
129
|
async readJSON() {
|
|
130
130
|
return await this._vvvfs.readJson(this._path);
|
|
131
131
|
}
|
|
132
|
+
/**
|
|
133
|
+
* 读取文件内容
|
|
134
|
+
* @param start 起始位置
|
|
135
|
+
* @param end 结束位置
|
|
136
|
+
*/
|
|
137
|
+
async readChunk(start: number, end: number) {
|
|
138
|
+
return await this._vvvfs.readChunk(this._path, start, end);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* 读取文件内容
|
|
142
|
+
* @param start 起始位置
|
|
143
|
+
* @param end 结束位置
|
|
144
|
+
*/
|
|
145
|
+
async readTextChunk(start: number, end: number) {
|
|
146
|
+
return await this._vvvfs.readTextChunk(this._path, start, end);
|
|
147
|
+
}
|
|
132
148
|
/**
|
|
133
149
|
* 写入文件
|
|
134
150
|
* @param file 文件对象
|
|
@@ -238,7 +254,7 @@ class VVVFSFile {
|
|
|
238
254
|
const version = packageJson.version;
|
|
239
255
|
class VVVFS {
|
|
240
256
|
static defaultDBName = "vvvfs";
|
|
241
|
-
|
|
257
|
+
#db: VVVFSDatabase;
|
|
242
258
|
options: VVVFSOptions;
|
|
243
259
|
/**
|
|
244
260
|
* 虚拟文件系统版本
|
|
@@ -251,7 +267,7 @@ class VVVFS {
|
|
|
251
267
|
/**
|
|
252
268
|
* 虚拟文件系统监听器
|
|
253
269
|
*/
|
|
254
|
-
watchers: Record<string, Array<(type: string) => Promise<boolean>>> = {};
|
|
270
|
+
#watchers: Record<string, Array<(type: string) => Promise<boolean>>> = {};
|
|
255
271
|
/**
|
|
256
272
|
* 创建虚拟文件系统
|
|
257
273
|
* @param name 虚拟文件系统名称
|
|
@@ -265,8 +281,8 @@ class VVVFS {
|
|
|
265
281
|
) {
|
|
266
282
|
this.options = options;
|
|
267
283
|
try {
|
|
268
|
-
this
|
|
269
|
-
this
|
|
284
|
+
this.#db = new Dexie(name || VVVFS.defaultDBName) as VVVFSDatabase;
|
|
285
|
+
this.#db.version(1).stores({
|
|
270
286
|
files: "++id, name, path, type, file, [name+path+type]",
|
|
271
287
|
});
|
|
272
288
|
} catch (error) {
|
|
@@ -404,7 +420,7 @@ class VVVFS {
|
|
|
404
420
|
try {
|
|
405
421
|
for (const file of linuxInitFiles) {
|
|
406
422
|
if (await this.exists(file.path)) continue;
|
|
407
|
-
await this
|
|
423
|
+
await this.#db.files.put(file);
|
|
408
424
|
}
|
|
409
425
|
} catch (error) {
|
|
410
426
|
console.error("初始化文件失败", error);
|
|
@@ -416,9 +432,9 @@ class VVVFS {
|
|
|
416
432
|
*/
|
|
417
433
|
async reset() {
|
|
418
434
|
try {
|
|
419
|
-
await this
|
|
420
|
-
this
|
|
421
|
-
this
|
|
435
|
+
await this.#db.delete();
|
|
436
|
+
this.#db = new Dexie(this.#db.name) as VVVFSDatabase;
|
|
437
|
+
this.#db.version(1).stores({
|
|
422
438
|
files: "++id, name, path, type, file, [name+path+type]",
|
|
423
439
|
});
|
|
424
440
|
} catch (error) {
|
|
@@ -433,8 +449,8 @@ class VVVFS {
|
|
|
433
449
|
async createFile(path: string) {
|
|
434
450
|
const targetPath = joinPath(path);
|
|
435
451
|
try {
|
|
436
|
-
if (this
|
|
437
|
-
for (const handler of this
|
|
452
|
+
if (this.#watchers[targetPath]) {
|
|
453
|
+
for (const handler of this.#watchers[targetPath]) {
|
|
438
454
|
if (await handler("create")) {
|
|
439
455
|
if (this.options.throwError) {
|
|
440
456
|
throw new VVVFSError("CreateFile", "创建文件失败:监听器取消了操作");
|
|
@@ -451,7 +467,7 @@ class VVVFS {
|
|
|
451
467
|
if (!(await this.exists(parent))) {
|
|
452
468
|
await this.createDir(parent);
|
|
453
469
|
}
|
|
454
|
-
await this
|
|
470
|
+
await this.#db.files.add({
|
|
455
471
|
name: name,
|
|
456
472
|
path: parent,
|
|
457
473
|
type: "file",
|
|
@@ -475,8 +491,8 @@ class VVVFS {
|
|
|
475
491
|
async createDir(path: string) {
|
|
476
492
|
const targetPath = joinPath(path);
|
|
477
493
|
try {
|
|
478
|
-
if (this
|
|
479
|
-
for (const handler of this
|
|
494
|
+
if (this.#watchers[targetPath]) {
|
|
495
|
+
for (const handler of this.#watchers[targetPath]) {
|
|
480
496
|
if (await handler("create")) {
|
|
481
497
|
if (this.options.throwError) {
|
|
482
498
|
throw new VVVFSError("CreateDir", "创建目录失败:监听器取消了操作");
|
|
@@ -492,7 +508,7 @@ class VVVFS {
|
|
|
492
508
|
const { name, parent } = parsePath(targetPath);
|
|
493
509
|
if (!(await this.exists(parent))) {
|
|
494
510
|
if (parent == "/") {
|
|
495
|
-
await this
|
|
511
|
+
await this.#db.files.add({
|
|
496
512
|
name: "",
|
|
497
513
|
path: "/",
|
|
498
514
|
type: "dir",
|
|
@@ -503,7 +519,7 @@ class VVVFS {
|
|
|
503
519
|
await this.createDir(parent);
|
|
504
520
|
}
|
|
505
521
|
}
|
|
506
|
-
await this
|
|
522
|
+
await this.#db.files.add({
|
|
507
523
|
name: name,
|
|
508
524
|
path: parent,
|
|
509
525
|
type: "dir",
|
|
@@ -527,7 +543,7 @@ class VVVFS {
|
|
|
527
543
|
const targetPath = joinPath(path);
|
|
528
544
|
const { name, parent } = parsePath(targetPath);
|
|
529
545
|
return (
|
|
530
|
-
(await this
|
|
546
|
+
(await this.#db.files
|
|
531
547
|
.where({
|
|
532
548
|
name: name,
|
|
533
549
|
path: parent,
|
|
@@ -549,8 +565,8 @@ class VVVFS {
|
|
|
549
565
|
async write(path: string, content: Blob) {
|
|
550
566
|
try {
|
|
551
567
|
const targetPath = joinPath(path);
|
|
552
|
-
if (this
|
|
553
|
-
for (const handler of this
|
|
568
|
+
if (this.#watchers[targetPath]) {
|
|
569
|
+
for (const handler of this.#watchers[targetPath]) {
|
|
554
570
|
if (await handler("write")) {
|
|
555
571
|
if (this.options.throwError) {
|
|
556
572
|
throw new VVVFSError("Write", "写入文件失败:监听器取消了操作");
|
|
@@ -580,9 +596,9 @@ class VVVFS {
|
|
|
580
596
|
const file = new File([content], name, {
|
|
581
597
|
type: mime.getType(targetPath) || "application/octet-stream",
|
|
582
598
|
});
|
|
583
|
-
const fileRecord = await this
|
|
599
|
+
const fileRecord = await this.#db.files.where({ name, path: parent }).first();
|
|
584
600
|
if (fileRecord) {
|
|
585
|
-
await this
|
|
601
|
+
await this.#db.files.put({
|
|
586
602
|
...fileRecord,
|
|
587
603
|
file: file,
|
|
588
604
|
});
|
|
@@ -647,8 +663,8 @@ class VVVFS {
|
|
|
647
663
|
async append(path: string, content: Blob) {
|
|
648
664
|
try {
|
|
649
665
|
const targetPath = joinPath(path);
|
|
650
|
-
if (this
|
|
651
|
-
for (const handler of this
|
|
666
|
+
if (this.#watchers[targetPath]) {
|
|
667
|
+
for (const handler of this.#watchers[targetPath]) {
|
|
652
668
|
if (await handler("append")) {
|
|
653
669
|
if (this.options.throwError) {
|
|
654
670
|
throw new VVVFSError("Append", "追加文件失败:监听器取消了操作");
|
|
@@ -698,8 +714,8 @@ class VVVFS {
|
|
|
698
714
|
async read(path: string) {
|
|
699
715
|
try {
|
|
700
716
|
const targetPath = joinPath(path);
|
|
701
|
-
if (this
|
|
702
|
-
for (const handler of this
|
|
717
|
+
if (this.#watchers[targetPath]) {
|
|
718
|
+
for (const handler of this.#watchers[targetPath]) {
|
|
703
719
|
if (await handler("read")) {
|
|
704
720
|
if (this.options.throwError) {
|
|
705
721
|
throw new VVVFSError("Read", "读取文件失败:监听器取消了操作");
|
|
@@ -716,7 +732,7 @@ class VVVFS {
|
|
|
716
732
|
return null;
|
|
717
733
|
}
|
|
718
734
|
const { name, parent } = parsePath(targetPath);
|
|
719
|
-
return (await this
|
|
735
|
+
return (await this.#db.files.where({ name, path: parent }).first())?.file;
|
|
720
736
|
} catch (error) {
|
|
721
737
|
console.error("读取文件失败", error);
|
|
722
738
|
if (this.options.throwError) {
|
|
@@ -777,6 +793,63 @@ class VVVFS {
|
|
|
777
793
|
return null;
|
|
778
794
|
}
|
|
779
795
|
}
|
|
796
|
+
/**
|
|
797
|
+
* 读取文件内容
|
|
798
|
+
* @param path 文件路径
|
|
799
|
+
* @param start 开始位置
|
|
800
|
+
* @param end 结束位置
|
|
801
|
+
*/
|
|
802
|
+
async readChunk(path: string, start: number, end: number) {
|
|
803
|
+
try {
|
|
804
|
+
const targetPath = joinPath(path);
|
|
805
|
+
if (this.#watchers[targetPath]) {
|
|
806
|
+
for (const handler of this.#watchers[targetPath]) {
|
|
807
|
+
if (await handler("read")) {
|
|
808
|
+
if (this.options.throwError) {
|
|
809
|
+
throw new VVVFSError("Read", "读取文件失败:监听器取消了操作");
|
|
810
|
+
}
|
|
811
|
+
return null;
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
if (!(await this.exists(targetPath))) {
|
|
816
|
+
console.warn("文件不存在");
|
|
817
|
+
if (this.options.throwError) {
|
|
818
|
+
throw new VVVFSError("Read", "文件不存在");
|
|
819
|
+
}
|
|
820
|
+
return null;
|
|
821
|
+
}
|
|
822
|
+
const file = await this.read(targetPath);
|
|
823
|
+
return file?.slice(start, end) || null;
|
|
824
|
+
} catch (error) {
|
|
825
|
+
console.error("读取文件失败", error);
|
|
826
|
+
if (this.options.throwError) {
|
|
827
|
+
throw new VVVFSError("Read", "读取文件失败" + error);
|
|
828
|
+
}
|
|
829
|
+
return null;
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
/**
|
|
833
|
+
* 读取文件内容
|
|
834
|
+
* @param path 文件路径
|
|
835
|
+
* @param start 读取开始位置
|
|
836
|
+
* @param end 读取结束位置
|
|
837
|
+
*/
|
|
838
|
+
async readTextChunk(path: string, start: number, end: number) {
|
|
839
|
+
try {
|
|
840
|
+
const chunk = await this.readChunk(path, start, end);
|
|
841
|
+
if (chunk) {
|
|
842
|
+
return await chunk.text();
|
|
843
|
+
} else {
|
|
844
|
+
return null;
|
|
845
|
+
}
|
|
846
|
+
} catch (error) {
|
|
847
|
+
console.error("读取文件失败", error);
|
|
848
|
+
if (this.options.throwError) {
|
|
849
|
+
throw new VVVFSError("Read", "读取文件失败" + error);
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
}
|
|
780
853
|
/**
|
|
781
854
|
* 判断是否是文件
|
|
782
855
|
* @param path 文件路径
|
|
@@ -785,7 +858,7 @@ class VVVFS {
|
|
|
785
858
|
try {
|
|
786
859
|
const targetPath = joinPath(path);
|
|
787
860
|
const { name, parent } = parsePath(targetPath);
|
|
788
|
-
return (await this
|
|
861
|
+
return (await this.#db.files.where({ name, path: parent, type: "file" }).count()) > 0;
|
|
789
862
|
} catch (error) {
|
|
790
863
|
console.error("判断文件类型失败", error);
|
|
791
864
|
if (this.options.throwError) {
|
|
@@ -802,7 +875,7 @@ class VVVFS {
|
|
|
802
875
|
try {
|
|
803
876
|
const targetPath = joinPath(path);
|
|
804
877
|
const { name, parent } = parsePath(targetPath);
|
|
805
|
-
return (await this
|
|
878
|
+
return (await this.#db.files.where({ path: parent, name, type: "dir" }).count()) > 0;
|
|
806
879
|
} catch (error) {
|
|
807
880
|
console.error("判断文件类型失败", error);
|
|
808
881
|
if (this.options.throwError) {
|
|
@@ -818,8 +891,8 @@ class VVVFS {
|
|
|
818
891
|
async list(path: string) {
|
|
819
892
|
try {
|
|
820
893
|
const targetPath = joinPath(path);
|
|
821
|
-
if (this
|
|
822
|
-
for (const handler of this
|
|
894
|
+
if (this.#watchers[targetPath]) {
|
|
895
|
+
for (const handler of this.#watchers[targetPath]) {
|
|
823
896
|
if (await handler("list")) {
|
|
824
897
|
if (this.options.throwError) {
|
|
825
898
|
throw new VVVFSError("List", "列出目录下的文件失败:监听器取消了操作");
|
|
@@ -842,7 +915,7 @@ class VVVFS {
|
|
|
842
915
|
}
|
|
843
916
|
return [];
|
|
844
917
|
}
|
|
845
|
-
return (await this
|
|
918
|
+
return (await this.#db.files.where({ path: targetPath }).toArray())
|
|
846
919
|
.map((file) => file.name)
|
|
847
920
|
.filter((item) => item != "");
|
|
848
921
|
} catch (error) {
|
|
@@ -862,8 +935,8 @@ class VVVFS {
|
|
|
862
935
|
try {
|
|
863
936
|
const sourcePath = joinPath(path);
|
|
864
937
|
const { name, parent } = parsePath(sourcePath);
|
|
865
|
-
if (this
|
|
866
|
-
for (const handler of this
|
|
938
|
+
if (this.#watchers[sourcePath]) {
|
|
939
|
+
for (const handler of this.#watchers[sourcePath]) {
|
|
867
940
|
if (await handler("rename")) {
|
|
868
941
|
if (this.options.throwError) {
|
|
869
942
|
throw new VVVFSError("Rename", "重命名文件失败:监听器取消了操作");
|
|
@@ -890,7 +963,7 @@ class VVVFS {
|
|
|
890
963
|
}
|
|
891
964
|
return false;
|
|
892
965
|
}
|
|
893
|
-
const fileRecord = await this
|
|
966
|
+
const fileRecord = await this.#db.files.where({ path: parent, name }).first();
|
|
894
967
|
if (!fileRecord) {
|
|
895
968
|
console.warn("文件记录未找到");
|
|
896
969
|
if (this.options.throwError) {
|
|
@@ -899,7 +972,7 @@ class VVVFS {
|
|
|
899
972
|
return false;
|
|
900
973
|
}
|
|
901
974
|
if (fileRecord.type === "dir") {
|
|
902
|
-
const descendants = await this
|
|
975
|
+
const descendants = await this.#db.files
|
|
903
976
|
.filter(
|
|
904
977
|
(file) =>
|
|
905
978
|
file.path === sourcePath || file.path.startsWith(sourcePath + "/"),
|
|
@@ -908,10 +981,10 @@ class VVVFS {
|
|
|
908
981
|
for (const descendant of descendants) {
|
|
909
982
|
const relativePath = descendant.path.slice(sourcePath.length);
|
|
910
983
|
const updatedPath = joinPath(newPath + relativePath);
|
|
911
|
-
await this
|
|
984
|
+
await this.#db.files.update(descendant.id!, { path: updatedPath });
|
|
912
985
|
}
|
|
913
986
|
}
|
|
914
|
-
await this
|
|
987
|
+
await this.#db.files.update(fileRecord.id!, {
|
|
915
988
|
name: newName,
|
|
916
989
|
path: parent,
|
|
917
990
|
});
|
|
@@ -931,8 +1004,8 @@ class VVVFS {
|
|
|
931
1004
|
async delete(path: string) {
|
|
932
1005
|
try {
|
|
933
1006
|
const targetPath = joinPath(path);
|
|
934
|
-
if (this
|
|
935
|
-
for (const handler of this
|
|
1007
|
+
if (this.#watchers[targetPath]) {
|
|
1008
|
+
for (const handler of this.#watchers[targetPath]) {
|
|
936
1009
|
if (await handler("delete")) {
|
|
937
1010
|
if (this.options.throwError) {
|
|
938
1011
|
throw new VVVFSError("Delete", "删除文件失败:监听器取消了操作");
|
|
@@ -954,19 +1027,19 @@ class VVVFS {
|
|
|
954
1027
|
for (const file of files) {
|
|
955
1028
|
await this.delete(joinPath(targetPath, file));
|
|
956
1029
|
}
|
|
957
|
-
const dirRecord = await this
|
|
1030
|
+
const dirRecord = await this.#db.files
|
|
958
1031
|
.where({ name, path: parent, type: "dir" })
|
|
959
1032
|
.first();
|
|
960
1033
|
if (dirRecord) {
|
|
961
|
-
await this
|
|
1034
|
+
await this.#db.files.delete(dirRecord.id!);
|
|
962
1035
|
}
|
|
963
1036
|
return true;
|
|
964
1037
|
} else {
|
|
965
|
-
const fileRecord = await this
|
|
1038
|
+
const fileRecord = await this.#db.files
|
|
966
1039
|
.where({ name, path: parent, type: "file" })
|
|
967
1040
|
.first();
|
|
968
1041
|
if (fileRecord) {
|
|
969
|
-
await this
|
|
1042
|
+
await this.#db.files.delete(fileRecord.id!);
|
|
970
1043
|
}
|
|
971
1044
|
return true;
|
|
972
1045
|
}
|
|
@@ -987,8 +1060,8 @@ class VVVFS {
|
|
|
987
1060
|
try {
|
|
988
1061
|
const sourcePath = joinPath(path);
|
|
989
1062
|
const destinationPath = joinPath(newPath);
|
|
990
|
-
if (this
|
|
991
|
-
for (const handler of this
|
|
1063
|
+
if (this.#watchers[sourcePath]) {
|
|
1064
|
+
for (const handler of this.#watchers[sourcePath]) {
|
|
992
1065
|
if (await handler("move")) {
|
|
993
1066
|
if (this.options.throwError) {
|
|
994
1067
|
throw new VVVFSError("Move", "移动文件失败:监听器取消了操作");
|
|
@@ -1029,20 +1102,20 @@ class VVVFS {
|
|
|
1029
1102
|
for (const child of children) {
|
|
1030
1103
|
await this.move(joinPath(sourcePath, child), joinPath(destinationPath, child));
|
|
1031
1104
|
}
|
|
1032
|
-
const dirRecord = await this
|
|
1105
|
+
const dirRecord = await this.#db.files
|
|
1033
1106
|
.where({ name, path: parent, type: "dir" })
|
|
1034
1107
|
.first();
|
|
1035
1108
|
if (dirRecord) {
|
|
1036
|
-
await this
|
|
1109
|
+
await this.#db.files.delete(dirRecord.id!);
|
|
1037
1110
|
}
|
|
1038
1111
|
return true;
|
|
1039
1112
|
} else {
|
|
1040
1113
|
await this.createDir(newParent);
|
|
1041
|
-
const fileRecord = await this
|
|
1114
|
+
const fileRecord = await this.#db.files
|
|
1042
1115
|
.where({ name, path: parent, type: "file" })
|
|
1043
1116
|
.first();
|
|
1044
1117
|
if (fileRecord) {
|
|
1045
|
-
await this
|
|
1118
|
+
await this.#db.files.update(fileRecord.id!, { name: newName, path: newParent });
|
|
1046
1119
|
return true;
|
|
1047
1120
|
}
|
|
1048
1121
|
return false;
|
|
@@ -1064,8 +1137,8 @@ class VVVFS {
|
|
|
1064
1137
|
try {
|
|
1065
1138
|
const sourcePath = joinPath(path);
|
|
1066
1139
|
const destinationPath = joinPath(newPath);
|
|
1067
|
-
if (this
|
|
1068
|
-
for (const handler of this
|
|
1140
|
+
if (this.#watchers[sourcePath]) {
|
|
1141
|
+
for (const handler of this.#watchers[sourcePath]) {
|
|
1069
1142
|
if (await handler("copy")) {
|
|
1070
1143
|
if (this.options.throwError) {
|
|
1071
1144
|
throw new VVVFSError("Copy", "复制文件失败:监听器取消了操作");
|
|
@@ -1105,11 +1178,11 @@ class VVVFS {
|
|
|
1105
1178
|
}
|
|
1106
1179
|
return true;
|
|
1107
1180
|
} else {
|
|
1108
|
-
const fileRecord = await this
|
|
1181
|
+
const fileRecord = await this.#db.files
|
|
1109
1182
|
.where({ name, path: parent, type: "file" })
|
|
1110
1183
|
.first();
|
|
1111
1184
|
if (fileRecord) {
|
|
1112
|
-
await this
|
|
1185
|
+
await this.#db.files.add({
|
|
1113
1186
|
name: newName,
|
|
1114
1187
|
path: newParent,
|
|
1115
1188
|
type: fileRecord.type,
|
|
@@ -1179,10 +1252,10 @@ class VVVFS {
|
|
|
1179
1252
|
}
|
|
1180
1253
|
async watch(path: string, handler: (type: string) => Promise<boolean>) {
|
|
1181
1254
|
path = joinPath(path);
|
|
1182
|
-
if (!this
|
|
1183
|
-
this
|
|
1255
|
+
if (!this.#watchers[path]) {
|
|
1256
|
+
this.#watchers[path] = [];
|
|
1184
1257
|
}
|
|
1185
|
-
this
|
|
1258
|
+
this.#watchers[path].push(handler);
|
|
1186
1259
|
}
|
|
1187
1260
|
}
|
|
1188
1261
|
function parsePath(path: string) {
|