vvvfs 0.1.0 → 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 +10 -0
- package/index.html +3 -1
- package/index.ts +192 -53
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -48,7 +48,9 @@ const vvvfs = new VVVFS("vvvfs", {
|
|
|
48
48
|
});
|
|
49
49
|
await vvvfs.createDir("/home/user/Desktop"); // 创建目录,返回true和false
|
|
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
|
+
await vvvfs.appendText("/home/user/Desktop/test.txt", "Hello World!"); // 追加文本文件,返回true和false
|
|
51
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
|
|
52
54
|
await vvvfs.delete("/home/user/Desktop/test.txt"); // 删除文件,返回true和false
|
|
53
55
|
if (await vvvfs.exists("/home/user/Desktop")) {
|
|
54
56
|
// 判断文件或目录是否存在
|
|
@@ -82,6 +84,14 @@ const vvvfs = new VVVFS("vvvfs", {
|
|
|
82
84
|
|
|
83
85
|
## 更新日志
|
|
84
86
|
|
|
87
|
+
### 0.1.2
|
|
88
|
+
|
|
89
|
+
- 新增 `readChunk` 和 `readChunkText` 方法,用于读取文件块
|
|
90
|
+
|
|
91
|
+
### 0.1.1
|
|
92
|
+
|
|
93
|
+
- 新增 `append` 和 `appendText` 方法,用于追加内容
|
|
94
|
+
|
|
85
95
|
### 0.1.0
|
|
86
96
|
|
|
87
97
|
- 修复 `init` 重复初始化时重复写入已存在文件和目录
|
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">
|
|
@@ -23,9 +23,11 @@
|
|
|
23
23
|
});
|
|
24
24
|
console.log("创建文件", await vvvfs.createFile("/test.txt"));
|
|
25
25
|
console.log("写入文件", await vvvfs.writeText("/test.txt", "Hello World"));
|
|
26
|
+
console.log("追加文件", await vvvfs.appendText("/test.txt", " - Appended"));
|
|
26
27
|
console.log("文件是否存在", await vvvfs.exists("/test.txt"));
|
|
27
28
|
console.log("文件是否存在", await vvvfs.exists("/test2.txt"));
|
|
28
29
|
console.log("读取文件", await vvvfs.readText("/test.txt"));
|
|
30
|
+
console.log("读取文件块", await vvvfs.readTextChunk("/test.txt", 0, 5));
|
|
29
31
|
console.log("复制文件", await vvvfs.copy("/test.txt", "/test2.txt"));
|
|
30
32
|
console.log("搜索文件", await vvvfs.search("/", "t"));
|
|
31
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 文件对象
|
|
@@ -150,6 +166,20 @@ class VVVFSFile {
|
|
|
150
166
|
async writeJSON(json: Record<string, any>, format: boolean = true) {
|
|
151
167
|
return await this._vvvfs.writeJson(this._path, json, format);
|
|
152
168
|
}
|
|
169
|
+
/**
|
|
170
|
+
* 追加文件内容
|
|
171
|
+
* @param file 文件对象
|
|
172
|
+
*/
|
|
173
|
+
async append(file: Blob) {
|
|
174
|
+
return await this._vvvfs.append(this._path, file);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* 追加文件文本内容
|
|
178
|
+
* @param text 文件文本内容
|
|
179
|
+
*/
|
|
180
|
+
async appendText(text: string) {
|
|
181
|
+
return await this._vvvfs.appendText(this._path, text);
|
|
182
|
+
}
|
|
153
183
|
/**
|
|
154
184
|
* 创建文件
|
|
155
185
|
*/
|
|
@@ -224,7 +254,7 @@ class VVVFSFile {
|
|
|
224
254
|
const version = packageJson.version;
|
|
225
255
|
class VVVFS {
|
|
226
256
|
static defaultDBName = "vvvfs";
|
|
227
|
-
|
|
257
|
+
#db: VVVFSDatabase;
|
|
228
258
|
options: VVVFSOptions;
|
|
229
259
|
/**
|
|
230
260
|
* 虚拟文件系统版本
|
|
@@ -237,7 +267,7 @@ class VVVFS {
|
|
|
237
267
|
/**
|
|
238
268
|
* 虚拟文件系统监听器
|
|
239
269
|
*/
|
|
240
|
-
watchers: Record<string, Array<(type: string) => Promise<boolean>>> = {};
|
|
270
|
+
#watchers: Record<string, Array<(type: string) => Promise<boolean>>> = {};
|
|
241
271
|
/**
|
|
242
272
|
* 创建虚拟文件系统
|
|
243
273
|
* @param name 虚拟文件系统名称
|
|
@@ -251,8 +281,8 @@ class VVVFS {
|
|
|
251
281
|
) {
|
|
252
282
|
this.options = options;
|
|
253
283
|
try {
|
|
254
|
-
this
|
|
255
|
-
this
|
|
284
|
+
this.#db = new Dexie(name || VVVFS.defaultDBName) as VVVFSDatabase;
|
|
285
|
+
this.#db.version(1).stores({
|
|
256
286
|
files: "++id, name, path, type, file, [name+path+type]",
|
|
257
287
|
});
|
|
258
288
|
} catch (error) {
|
|
@@ -390,7 +420,7 @@ class VVVFS {
|
|
|
390
420
|
try {
|
|
391
421
|
for (const file of linuxInitFiles) {
|
|
392
422
|
if (await this.exists(file.path)) continue;
|
|
393
|
-
await this
|
|
423
|
+
await this.#db.files.put(file);
|
|
394
424
|
}
|
|
395
425
|
} catch (error) {
|
|
396
426
|
console.error("初始化文件失败", error);
|
|
@@ -402,9 +432,9 @@ class VVVFS {
|
|
|
402
432
|
*/
|
|
403
433
|
async reset() {
|
|
404
434
|
try {
|
|
405
|
-
await this
|
|
406
|
-
this
|
|
407
|
-
this
|
|
435
|
+
await this.#db.delete();
|
|
436
|
+
this.#db = new Dexie(this.#db.name) as VVVFSDatabase;
|
|
437
|
+
this.#db.version(1).stores({
|
|
408
438
|
files: "++id, name, path, type, file, [name+path+type]",
|
|
409
439
|
});
|
|
410
440
|
} catch (error) {
|
|
@@ -419,8 +449,8 @@ class VVVFS {
|
|
|
419
449
|
async createFile(path: string) {
|
|
420
450
|
const targetPath = joinPath(path);
|
|
421
451
|
try {
|
|
422
|
-
if (this
|
|
423
|
-
for (const handler of this
|
|
452
|
+
if (this.#watchers[targetPath]) {
|
|
453
|
+
for (const handler of this.#watchers[targetPath]) {
|
|
424
454
|
if (await handler("create")) {
|
|
425
455
|
if (this.options.throwError) {
|
|
426
456
|
throw new VVVFSError("CreateFile", "创建文件失败:监听器取消了操作");
|
|
@@ -437,7 +467,7 @@ class VVVFS {
|
|
|
437
467
|
if (!(await this.exists(parent))) {
|
|
438
468
|
await this.createDir(parent);
|
|
439
469
|
}
|
|
440
|
-
await this
|
|
470
|
+
await this.#db.files.add({
|
|
441
471
|
name: name,
|
|
442
472
|
path: parent,
|
|
443
473
|
type: "file",
|
|
@@ -461,8 +491,8 @@ class VVVFS {
|
|
|
461
491
|
async createDir(path: string) {
|
|
462
492
|
const targetPath = joinPath(path);
|
|
463
493
|
try {
|
|
464
|
-
if (this
|
|
465
|
-
for (const handler of this
|
|
494
|
+
if (this.#watchers[targetPath]) {
|
|
495
|
+
for (const handler of this.#watchers[targetPath]) {
|
|
466
496
|
if (await handler("create")) {
|
|
467
497
|
if (this.options.throwError) {
|
|
468
498
|
throw new VVVFSError("CreateDir", "创建目录失败:监听器取消了操作");
|
|
@@ -478,7 +508,7 @@ class VVVFS {
|
|
|
478
508
|
const { name, parent } = parsePath(targetPath);
|
|
479
509
|
if (!(await this.exists(parent))) {
|
|
480
510
|
if (parent == "/") {
|
|
481
|
-
await this
|
|
511
|
+
await this.#db.files.add({
|
|
482
512
|
name: "",
|
|
483
513
|
path: "/",
|
|
484
514
|
type: "dir",
|
|
@@ -489,7 +519,7 @@ class VVVFS {
|
|
|
489
519
|
await this.createDir(parent);
|
|
490
520
|
}
|
|
491
521
|
}
|
|
492
|
-
await this
|
|
522
|
+
await this.#db.files.add({
|
|
493
523
|
name: name,
|
|
494
524
|
path: parent,
|
|
495
525
|
type: "dir",
|
|
@@ -513,7 +543,7 @@ class VVVFS {
|
|
|
513
543
|
const targetPath = joinPath(path);
|
|
514
544
|
const { name, parent } = parsePath(targetPath);
|
|
515
545
|
return (
|
|
516
|
-
(await this
|
|
546
|
+
(await this.#db.files
|
|
517
547
|
.where({
|
|
518
548
|
name: name,
|
|
519
549
|
path: parent,
|
|
@@ -535,8 +565,8 @@ class VVVFS {
|
|
|
535
565
|
async write(path: string, content: Blob) {
|
|
536
566
|
try {
|
|
537
567
|
const targetPath = joinPath(path);
|
|
538
|
-
if (this
|
|
539
|
-
for (const handler of this
|
|
568
|
+
if (this.#watchers[targetPath]) {
|
|
569
|
+
for (const handler of this.#watchers[targetPath]) {
|
|
540
570
|
if (await handler("write")) {
|
|
541
571
|
if (this.options.throwError) {
|
|
542
572
|
throw new VVVFSError("Write", "写入文件失败:监听器取消了操作");
|
|
@@ -566,9 +596,9 @@ class VVVFS {
|
|
|
566
596
|
const file = new File([content], name, {
|
|
567
597
|
type: mime.getType(targetPath) || "application/octet-stream",
|
|
568
598
|
});
|
|
569
|
-
const fileRecord = await this
|
|
599
|
+
const fileRecord = await this.#db.files.where({ name, path: parent }).first();
|
|
570
600
|
if (fileRecord) {
|
|
571
|
-
await this
|
|
601
|
+
await this.#db.files.put({
|
|
572
602
|
...fileRecord,
|
|
573
603
|
file: file,
|
|
574
604
|
});
|
|
@@ -625,6 +655,58 @@ class VVVFS {
|
|
|
625
655
|
return false;
|
|
626
656
|
}
|
|
627
657
|
}
|
|
658
|
+
/**
|
|
659
|
+
* 追加内容
|
|
660
|
+
* @param path 文件路径
|
|
661
|
+
* @param content 追加内容
|
|
662
|
+
*/
|
|
663
|
+
async append(path: string, content: Blob) {
|
|
664
|
+
try {
|
|
665
|
+
const targetPath = joinPath(path);
|
|
666
|
+
if (this.#watchers[targetPath]) {
|
|
667
|
+
for (const handler of this.#watchers[targetPath]) {
|
|
668
|
+
if (await handler("append")) {
|
|
669
|
+
if (this.options.throwError) {
|
|
670
|
+
throw new VVVFSError("Append", "追加文件失败:监听器取消了操作");
|
|
671
|
+
}
|
|
672
|
+
return false;
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
const existingFile = await this.read(targetPath);
|
|
677
|
+
if (existingFile) {
|
|
678
|
+
const blob = new Blob([existingFile, content], {
|
|
679
|
+
type: "application/octet-stream",
|
|
680
|
+
});
|
|
681
|
+
return await this.write(targetPath, blob);
|
|
682
|
+
} else {
|
|
683
|
+
return await this.write(targetPath, content);
|
|
684
|
+
}
|
|
685
|
+
} catch (error) {
|
|
686
|
+
console.error("追加文件失败", error);
|
|
687
|
+
if (this.options.throwError) {
|
|
688
|
+
throw new VVVFSError("Append", "追加文件失败" + error);
|
|
689
|
+
}
|
|
690
|
+
return false;
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
/**
|
|
694
|
+
* 追加文本内容
|
|
695
|
+
* @param path 文件路径
|
|
696
|
+
* @param content 追加内容
|
|
697
|
+
*/
|
|
698
|
+
async appendText(path: string, content: string) {
|
|
699
|
+
try {
|
|
700
|
+
const blob = new Blob([content], { type: "text/plain" });
|
|
701
|
+
return await this.append(path, blob);
|
|
702
|
+
} catch (error) {
|
|
703
|
+
console.error("追加文件失败", error);
|
|
704
|
+
if (this.options.throwError) {
|
|
705
|
+
throw new VVVFSError("Append", "追加文件失败" + error);
|
|
706
|
+
}
|
|
707
|
+
return false;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
628
710
|
/**
|
|
629
711
|
* 读取文件内容
|
|
630
712
|
* @param path 文件路径
|
|
@@ -632,8 +714,8 @@ class VVVFS {
|
|
|
632
714
|
async read(path: string) {
|
|
633
715
|
try {
|
|
634
716
|
const targetPath = joinPath(path);
|
|
635
|
-
if (this
|
|
636
|
-
for (const handler of this
|
|
717
|
+
if (this.#watchers[targetPath]) {
|
|
718
|
+
for (const handler of this.#watchers[targetPath]) {
|
|
637
719
|
if (await handler("read")) {
|
|
638
720
|
if (this.options.throwError) {
|
|
639
721
|
throw new VVVFSError("Read", "读取文件失败:监听器取消了操作");
|
|
@@ -650,7 +732,7 @@ class VVVFS {
|
|
|
650
732
|
return null;
|
|
651
733
|
}
|
|
652
734
|
const { name, parent } = parsePath(targetPath);
|
|
653
|
-
return (await this
|
|
735
|
+
return (await this.#db.files.where({ name, path: parent }).first())?.file;
|
|
654
736
|
} catch (error) {
|
|
655
737
|
console.error("读取文件失败", error);
|
|
656
738
|
if (this.options.throwError) {
|
|
@@ -711,6 +793,63 @@ class VVVFS {
|
|
|
711
793
|
return null;
|
|
712
794
|
}
|
|
713
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
|
+
}
|
|
714
853
|
/**
|
|
715
854
|
* 判断是否是文件
|
|
716
855
|
* @param path 文件路径
|
|
@@ -719,7 +858,7 @@ class VVVFS {
|
|
|
719
858
|
try {
|
|
720
859
|
const targetPath = joinPath(path);
|
|
721
860
|
const { name, parent } = parsePath(targetPath);
|
|
722
|
-
return (await this
|
|
861
|
+
return (await this.#db.files.where({ name, path: parent, type: "file" }).count()) > 0;
|
|
723
862
|
} catch (error) {
|
|
724
863
|
console.error("判断文件类型失败", error);
|
|
725
864
|
if (this.options.throwError) {
|
|
@@ -736,7 +875,7 @@ class VVVFS {
|
|
|
736
875
|
try {
|
|
737
876
|
const targetPath = joinPath(path);
|
|
738
877
|
const { name, parent } = parsePath(targetPath);
|
|
739
|
-
return (await this
|
|
878
|
+
return (await this.#db.files.where({ path: parent, name, type: "dir" }).count()) > 0;
|
|
740
879
|
} catch (error) {
|
|
741
880
|
console.error("判断文件类型失败", error);
|
|
742
881
|
if (this.options.throwError) {
|
|
@@ -752,8 +891,8 @@ class VVVFS {
|
|
|
752
891
|
async list(path: string) {
|
|
753
892
|
try {
|
|
754
893
|
const targetPath = joinPath(path);
|
|
755
|
-
if (this
|
|
756
|
-
for (const handler of this
|
|
894
|
+
if (this.#watchers[targetPath]) {
|
|
895
|
+
for (const handler of this.#watchers[targetPath]) {
|
|
757
896
|
if (await handler("list")) {
|
|
758
897
|
if (this.options.throwError) {
|
|
759
898
|
throw new VVVFSError("List", "列出目录下的文件失败:监听器取消了操作");
|
|
@@ -776,7 +915,7 @@ class VVVFS {
|
|
|
776
915
|
}
|
|
777
916
|
return [];
|
|
778
917
|
}
|
|
779
|
-
return (await this
|
|
918
|
+
return (await this.#db.files.where({ path: targetPath }).toArray())
|
|
780
919
|
.map((file) => file.name)
|
|
781
920
|
.filter((item) => item != "");
|
|
782
921
|
} catch (error) {
|
|
@@ -796,8 +935,8 @@ class VVVFS {
|
|
|
796
935
|
try {
|
|
797
936
|
const sourcePath = joinPath(path);
|
|
798
937
|
const { name, parent } = parsePath(sourcePath);
|
|
799
|
-
if (this
|
|
800
|
-
for (const handler of this
|
|
938
|
+
if (this.#watchers[sourcePath]) {
|
|
939
|
+
for (const handler of this.#watchers[sourcePath]) {
|
|
801
940
|
if (await handler("rename")) {
|
|
802
941
|
if (this.options.throwError) {
|
|
803
942
|
throw new VVVFSError("Rename", "重命名文件失败:监听器取消了操作");
|
|
@@ -824,7 +963,7 @@ class VVVFS {
|
|
|
824
963
|
}
|
|
825
964
|
return false;
|
|
826
965
|
}
|
|
827
|
-
const fileRecord = await this
|
|
966
|
+
const fileRecord = await this.#db.files.where({ path: parent, name }).first();
|
|
828
967
|
if (!fileRecord) {
|
|
829
968
|
console.warn("文件记录未找到");
|
|
830
969
|
if (this.options.throwError) {
|
|
@@ -833,7 +972,7 @@ class VVVFS {
|
|
|
833
972
|
return false;
|
|
834
973
|
}
|
|
835
974
|
if (fileRecord.type === "dir") {
|
|
836
|
-
const descendants = await this
|
|
975
|
+
const descendants = await this.#db.files
|
|
837
976
|
.filter(
|
|
838
977
|
(file) =>
|
|
839
978
|
file.path === sourcePath || file.path.startsWith(sourcePath + "/"),
|
|
@@ -842,10 +981,10 @@ class VVVFS {
|
|
|
842
981
|
for (const descendant of descendants) {
|
|
843
982
|
const relativePath = descendant.path.slice(sourcePath.length);
|
|
844
983
|
const updatedPath = joinPath(newPath + relativePath);
|
|
845
|
-
await this
|
|
984
|
+
await this.#db.files.update(descendant.id!, { path: updatedPath });
|
|
846
985
|
}
|
|
847
986
|
}
|
|
848
|
-
await this
|
|
987
|
+
await this.#db.files.update(fileRecord.id!, {
|
|
849
988
|
name: newName,
|
|
850
989
|
path: parent,
|
|
851
990
|
});
|
|
@@ -865,8 +1004,8 @@ class VVVFS {
|
|
|
865
1004
|
async delete(path: string) {
|
|
866
1005
|
try {
|
|
867
1006
|
const targetPath = joinPath(path);
|
|
868
|
-
if (this
|
|
869
|
-
for (const handler of this
|
|
1007
|
+
if (this.#watchers[targetPath]) {
|
|
1008
|
+
for (const handler of this.#watchers[targetPath]) {
|
|
870
1009
|
if (await handler("delete")) {
|
|
871
1010
|
if (this.options.throwError) {
|
|
872
1011
|
throw new VVVFSError("Delete", "删除文件失败:监听器取消了操作");
|
|
@@ -888,19 +1027,19 @@ class VVVFS {
|
|
|
888
1027
|
for (const file of files) {
|
|
889
1028
|
await this.delete(joinPath(targetPath, file));
|
|
890
1029
|
}
|
|
891
|
-
const dirRecord = await this
|
|
1030
|
+
const dirRecord = await this.#db.files
|
|
892
1031
|
.where({ name, path: parent, type: "dir" })
|
|
893
1032
|
.first();
|
|
894
1033
|
if (dirRecord) {
|
|
895
|
-
await this
|
|
1034
|
+
await this.#db.files.delete(dirRecord.id!);
|
|
896
1035
|
}
|
|
897
1036
|
return true;
|
|
898
1037
|
} else {
|
|
899
|
-
const fileRecord = await this
|
|
1038
|
+
const fileRecord = await this.#db.files
|
|
900
1039
|
.where({ name, path: parent, type: "file" })
|
|
901
1040
|
.first();
|
|
902
1041
|
if (fileRecord) {
|
|
903
|
-
await this
|
|
1042
|
+
await this.#db.files.delete(fileRecord.id!);
|
|
904
1043
|
}
|
|
905
1044
|
return true;
|
|
906
1045
|
}
|
|
@@ -921,8 +1060,8 @@ class VVVFS {
|
|
|
921
1060
|
try {
|
|
922
1061
|
const sourcePath = joinPath(path);
|
|
923
1062
|
const destinationPath = joinPath(newPath);
|
|
924
|
-
if (this
|
|
925
|
-
for (const handler of this
|
|
1063
|
+
if (this.#watchers[sourcePath]) {
|
|
1064
|
+
for (const handler of this.#watchers[sourcePath]) {
|
|
926
1065
|
if (await handler("move")) {
|
|
927
1066
|
if (this.options.throwError) {
|
|
928
1067
|
throw new VVVFSError("Move", "移动文件失败:监听器取消了操作");
|
|
@@ -963,20 +1102,20 @@ class VVVFS {
|
|
|
963
1102
|
for (const child of children) {
|
|
964
1103
|
await this.move(joinPath(sourcePath, child), joinPath(destinationPath, child));
|
|
965
1104
|
}
|
|
966
|
-
const dirRecord = await this
|
|
1105
|
+
const dirRecord = await this.#db.files
|
|
967
1106
|
.where({ name, path: parent, type: "dir" })
|
|
968
1107
|
.first();
|
|
969
1108
|
if (dirRecord) {
|
|
970
|
-
await this
|
|
1109
|
+
await this.#db.files.delete(dirRecord.id!);
|
|
971
1110
|
}
|
|
972
1111
|
return true;
|
|
973
1112
|
} else {
|
|
974
1113
|
await this.createDir(newParent);
|
|
975
|
-
const fileRecord = await this
|
|
1114
|
+
const fileRecord = await this.#db.files
|
|
976
1115
|
.where({ name, path: parent, type: "file" })
|
|
977
1116
|
.first();
|
|
978
1117
|
if (fileRecord) {
|
|
979
|
-
await this
|
|
1118
|
+
await this.#db.files.update(fileRecord.id!, { name: newName, path: newParent });
|
|
980
1119
|
return true;
|
|
981
1120
|
}
|
|
982
1121
|
return false;
|
|
@@ -998,8 +1137,8 @@ class VVVFS {
|
|
|
998
1137
|
try {
|
|
999
1138
|
const sourcePath = joinPath(path);
|
|
1000
1139
|
const destinationPath = joinPath(newPath);
|
|
1001
|
-
if (this
|
|
1002
|
-
for (const handler of this
|
|
1140
|
+
if (this.#watchers[sourcePath]) {
|
|
1141
|
+
for (const handler of this.#watchers[sourcePath]) {
|
|
1003
1142
|
if (await handler("copy")) {
|
|
1004
1143
|
if (this.options.throwError) {
|
|
1005
1144
|
throw new VVVFSError("Copy", "复制文件失败:监听器取消了操作");
|
|
@@ -1039,11 +1178,11 @@ class VVVFS {
|
|
|
1039
1178
|
}
|
|
1040
1179
|
return true;
|
|
1041
1180
|
} else {
|
|
1042
|
-
const fileRecord = await this
|
|
1181
|
+
const fileRecord = await this.#db.files
|
|
1043
1182
|
.where({ name, path: parent, type: "file" })
|
|
1044
1183
|
.first();
|
|
1045
1184
|
if (fileRecord) {
|
|
1046
|
-
await this
|
|
1185
|
+
await this.#db.files.add({
|
|
1047
1186
|
name: newName,
|
|
1048
1187
|
path: newParent,
|
|
1049
1188
|
type: fileRecord.type,
|
|
@@ -1113,10 +1252,10 @@ class VVVFS {
|
|
|
1113
1252
|
}
|
|
1114
1253
|
async watch(path: string, handler: (type: string) => Promise<boolean>) {
|
|
1115
1254
|
path = joinPath(path);
|
|
1116
|
-
if (!this
|
|
1117
|
-
this
|
|
1255
|
+
if (!this.#watchers[path]) {
|
|
1256
|
+
this.#watchers[path] = [];
|
|
1118
1257
|
}
|
|
1119
|
-
this
|
|
1258
|
+
this.#watchers[path].push(handler);
|
|
1120
1259
|
}
|
|
1121
1260
|
}
|
|
1122
1261
|
function parsePath(path: string) {
|