vvvfs 0.0.7 → 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 +12 -0
- package/index.html +5 -0
- package/index.ts +137 -13
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -42,6 +42,10 @@ const vvvfs = new VVVFS("vvvfs", {
|
|
|
42
42
|
(async function () {
|
|
43
43
|
await vvvfs.reset(); // 重置文件系统
|
|
44
44
|
await vvvfs.init("UserName"); // 初始化文件系统
|
|
45
|
+
await vvvfs.watch("/home/user/Desktop/test.txt", (type) => {
|
|
46
|
+
console.log(type); // 打印文件操作的类型
|
|
47
|
+
return true; // 返回true或false,表示是否取消该操作
|
|
48
|
+
});
|
|
45
49
|
await vvvfs.createDir("/home/user/Desktop"); // 创建目录,返回true和false
|
|
46
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
|
|
47
51
|
console.log(await vvvfs.readText("/home/user/Desktop/test.txt")); // 读取文本文件,读取文件还包括read(path: string): Blob | null和readJson(path: string): Record<string, any> | null方法
|
|
@@ -78,6 +82,14 @@ const vvvfs = new VVVFS("vvvfs", {
|
|
|
78
82
|
|
|
79
83
|
## 更新日志
|
|
80
84
|
|
|
85
|
+
### 0.0.9
|
|
86
|
+
|
|
87
|
+
- 更新 `watch` 方法,监听时,返回 `true` 表示取消该操作
|
|
88
|
+
|
|
89
|
+
### 0.0.8
|
|
90
|
+
|
|
91
|
+
- 新增 `watch` 方法 (该方法属于实验性功能,后期可能会改变)
|
|
92
|
+
|
|
81
93
|
### 0.0.7
|
|
82
94
|
|
|
83
95
|
- AI 了优化一下
|
package/index.html
CHANGED
|
@@ -13,9 +13,14 @@
|
|
|
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);
|
|
20
|
+
await vvvfs.watch("/test.txt", (type) => {
|
|
21
|
+
console.log(type);
|
|
22
|
+
// return true;
|
|
23
|
+
});
|
|
19
24
|
console.log("创建文件", await vvvfs.createFile("/test.txt"));
|
|
20
25
|
console.log("写入文件", await vvvfs.writeText("/test.txt", "Hello World"));
|
|
21
26
|
console.log("文件是否存在", await vvvfs.exists("/test.txt"));
|
package/index.ts
CHANGED
|
@@ -216,6 +216,9 @@ 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) => Promise<boolean>) {
|
|
220
|
+
return await this._vvvfs.watch(this._path, handler);
|
|
221
|
+
}
|
|
219
222
|
}
|
|
220
223
|
|
|
221
224
|
const version = packageJson.version;
|
|
@@ -231,6 +234,10 @@ class VVVFS {
|
|
|
231
234
|
* 虚拟文件系统文件类
|
|
232
235
|
*/
|
|
233
236
|
static File = VVVFSFile;
|
|
237
|
+
/**
|
|
238
|
+
* 虚拟文件系统监听器
|
|
239
|
+
*/
|
|
240
|
+
watchers: Record<string, Array<(type: string) => Promise<boolean>>> = {};
|
|
234
241
|
/**
|
|
235
242
|
* 创建虚拟文件系统
|
|
236
243
|
* @param name 虚拟文件系统名称
|
|
@@ -410,11 +417,21 @@ class VVVFS {
|
|
|
410
417
|
*/
|
|
411
418
|
async createFile(path: string) {
|
|
412
419
|
const targetPath = joinPath(path);
|
|
413
|
-
if (await this.exists(targetPath)) {
|
|
414
|
-
console.warn("文件已存在");
|
|
415
|
-
return true;
|
|
416
|
-
}
|
|
417
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
|
+
}
|
|
418
435
|
const { name, parent } = parsePath(targetPath);
|
|
419
436
|
if (!(await this.exists(parent))) {
|
|
420
437
|
await this.createDir(parent);
|
|
@@ -442,11 +459,21 @@ class VVVFS {
|
|
|
442
459
|
*/
|
|
443
460
|
async createDir(path: string) {
|
|
444
461
|
const targetPath = joinPath(path);
|
|
445
|
-
if (await this.exists(targetPath)) {
|
|
446
|
-
console.warn("目录已存在");
|
|
447
|
-
return true;
|
|
448
|
-
}
|
|
449
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
|
+
}
|
|
450
477
|
const { name, parent } = parsePath(targetPath);
|
|
451
478
|
if (!(await this.exists(parent))) {
|
|
452
479
|
if (parent == "/") {
|
|
@@ -507,6 +534,16 @@ class VVVFS {
|
|
|
507
534
|
async write(path: string, content: Blob) {
|
|
508
535
|
try {
|
|
509
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
|
+
}
|
|
510
547
|
if (!(await this.exists(targetPath))) {
|
|
511
548
|
const success = await this.createFile(targetPath);
|
|
512
549
|
if (!success) {
|
|
@@ -594,6 +631,16 @@ class VVVFS {
|
|
|
594
631
|
async read(path: string) {
|
|
595
632
|
try {
|
|
596
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
|
+
}
|
|
597
644
|
if (!(await this.exists(targetPath))) {
|
|
598
645
|
console.warn("文件不存在");
|
|
599
646
|
if (this.options.throwError) {
|
|
@@ -704,6 +751,23 @@ class VVVFS {
|
|
|
704
751
|
async list(path: string) {
|
|
705
752
|
try {
|
|
706
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
|
+
}
|
|
707
771
|
if (!(await this.isDir(targetPath))) {
|
|
708
772
|
console.warn("路径不是目录");
|
|
709
773
|
if (this.options.throwError) {
|
|
@@ -731,6 +795,16 @@ class VVVFS {
|
|
|
731
795
|
try {
|
|
732
796
|
const sourcePath = joinPath(path);
|
|
733
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
|
+
}
|
|
734
808
|
if (!(await this.exists(sourcePath))) {
|
|
735
809
|
console.warn("文件不存在");
|
|
736
810
|
if (this.options.throwError) {
|
|
@@ -790,6 +864,16 @@ class VVVFS {
|
|
|
790
864
|
async delete(path: string) {
|
|
791
865
|
try {
|
|
792
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
|
+
}
|
|
793
877
|
if (!(await this.exists(targetPath))) {
|
|
794
878
|
console.warn("文件不存在");
|
|
795
879
|
if (this.options.throwError) {
|
|
@@ -803,13 +887,17 @@ class VVVFS {
|
|
|
803
887
|
for (const file of files) {
|
|
804
888
|
await this.delete(joinPath(targetPath, file));
|
|
805
889
|
}
|
|
806
|
-
const dirRecord = await this.db.files
|
|
890
|
+
const dirRecord = await this.db.files
|
|
891
|
+
.where({ name, path: parent, type: "dir" })
|
|
892
|
+
.first();
|
|
807
893
|
if (dirRecord) {
|
|
808
894
|
await this.db.files.delete(dirRecord.id!);
|
|
809
895
|
}
|
|
810
896
|
return true;
|
|
811
897
|
} else {
|
|
812
|
-
const fileRecord = await this.db.files
|
|
898
|
+
const fileRecord = await this.db.files
|
|
899
|
+
.where({ name, path: parent, type: "file" })
|
|
900
|
+
.first();
|
|
813
901
|
if (fileRecord) {
|
|
814
902
|
await this.db.files.delete(fileRecord.id!);
|
|
815
903
|
}
|
|
@@ -832,6 +920,19 @@ class VVVFS {
|
|
|
832
920
|
try {
|
|
833
921
|
const sourcePath = joinPath(path);
|
|
834
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
|
+
}
|
|
835
936
|
if (await this.exists(destinationPath)) {
|
|
836
937
|
console.warn("目标文件已存在");
|
|
837
938
|
if (this.options.throwError) {
|
|
@@ -861,14 +962,18 @@ class VVVFS {
|
|
|
861
962
|
for (const child of children) {
|
|
862
963
|
await this.move(joinPath(sourcePath, child), joinPath(destinationPath, child));
|
|
863
964
|
}
|
|
864
|
-
const dirRecord = await this.db.files
|
|
965
|
+
const dirRecord = await this.db.files
|
|
966
|
+
.where({ name, path: parent, type: "dir" })
|
|
967
|
+
.first();
|
|
865
968
|
if (dirRecord) {
|
|
866
969
|
await this.db.files.delete(dirRecord.id!);
|
|
867
970
|
}
|
|
868
971
|
return true;
|
|
869
972
|
} else {
|
|
870
973
|
await this.createDir(newParent);
|
|
871
|
-
const fileRecord = await this.db.files
|
|
974
|
+
const fileRecord = await this.db.files
|
|
975
|
+
.where({ name, path: parent, type: "file" })
|
|
976
|
+
.first();
|
|
872
977
|
if (fileRecord) {
|
|
873
978
|
await this.db.files.update(fileRecord.id!, { name: newName, path: newParent });
|
|
874
979
|
return true;
|
|
@@ -892,6 +997,16 @@ class VVVFS {
|
|
|
892
997
|
try {
|
|
893
998
|
const sourcePath = joinPath(path);
|
|
894
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
|
+
}
|
|
895
1010
|
if (await this.exists(destinationPath)) {
|
|
896
1011
|
console.warn("目标文件已存在");
|
|
897
1012
|
if (this.options.throwError) {
|
|
@@ -923,7 +1038,9 @@ class VVVFS {
|
|
|
923
1038
|
}
|
|
924
1039
|
return true;
|
|
925
1040
|
} else {
|
|
926
|
-
const fileRecord = await this.db.files
|
|
1041
|
+
const fileRecord = await this.db.files
|
|
1042
|
+
.where({ name, path: parent, type: "file" })
|
|
1043
|
+
.first();
|
|
927
1044
|
if (fileRecord) {
|
|
928
1045
|
await this.db.files.add({
|
|
929
1046
|
name: newName,
|
|
@@ -993,6 +1110,13 @@ class VVVFS {
|
|
|
993
1110
|
return null;
|
|
994
1111
|
}
|
|
995
1112
|
}
|
|
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);
|
|
1119
|
+
}
|
|
996
1120
|
}
|
|
997
1121
|
function parsePath(path: string) {
|
|
998
1122
|
path = joinPath(path);
|