vvvfs 0.1.2 → 0.1.3

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
@@ -42,10 +42,12 @@ 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) => {
45
+ vvvfs.watch("/home/user/Desktop/test.txt", (type) => {
46
46
  console.log(type); // 打印文件操作的类型
47
47
  return true; // 返回true或false,表示是否取消该操作
48
48
  });
49
+ await vvvfs.lock("/home/user/Desktop/test.txt"); // 锁定文件,防止其他代码访问该文件
50
+ await vvvfs.unlock("/home/user/Desktop/test.txt"); // 解锁文件
49
51
  await vvvfs.createDir("/home/user/Desktop"); // 创建目录,返回true和false
50
52
  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
53
  await vvvfs.appendText("/home/user/Desktop/test.txt", "Hello World!"); // 追加文本文件,返回true和false
@@ -84,6 +86,9 @@ const vvvfs = new VVVFS("vvvfs", {
84
86
 
85
87
  ## 更新日志
86
88
 
89
+ ### 0.1.3
90
+ - 新增 `lock` 和 `unlock` 方法,可以锁定文件,防止其他代码访问该文件
91
+
87
92
  ### 0.1.2
88
93
 
89
94
  - 新增 `readChunk` 和 `readChunkText` 方法,用于读取文件块
package/index.html CHANGED
@@ -17,13 +17,14 @@
17
17
  await vvvfs.reset();
18
18
  await vvvfs.init("IFTC");
19
19
  console.log(vvvfs);
20
- await vvvfs.watch("/test.txt", (type) => {
20
+ vvvfs.watch("/test.txt", (type) => {
21
21
  console.log(type);
22
22
  // return true;
23
23
  });
24
24
  console.log("创建文件", await vvvfs.createFile("/test.txt"));
25
25
  console.log("写入文件", await vvvfs.writeText("/test.txt", "Hello World"));
26
26
  console.log("追加文件", await vvvfs.appendText("/test.txt", " - Appended"));
27
+ // await vvvfs.lock("/test.txt");
27
28
  console.log("文件是否存在", await vvvfs.exists("/test.txt"));
28
29
  console.log("文件是否存在", await vvvfs.exists("/test2.txt"));
29
30
  console.log("读取文件", await vvvfs.readText("/test.txt"));
package/index.ts CHANGED
@@ -246,8 +246,23 @@ class VVVFSFile {
246
246
  async search(query: string) {
247
247
  return await this._vvvfs.search(this._path, query);
248
248
  }
249
- async watch(handler: (type: string) => Promise<boolean>) {
250
- return await this._vvvfs.watch(this._path, handler);
249
+ /**
250
+ * 监听文件
251
+ */
252
+ watch(handler: (type: string) => Promise<boolean>) {
253
+ return this._vvvfs.watch(this._path, handler);
254
+ }
255
+ /**
256
+ * 锁定文件
257
+ */
258
+ async lock() {
259
+ return await this._vvvfs.lock(this._path);
260
+ }
261
+ /**
262
+ * 解锁文件
263
+ */
264
+ async unlock() {
265
+ return await this._vvvfs.unlock(this._path);
251
266
  }
252
267
  }
253
268
 
@@ -268,6 +283,10 @@ class VVVFS {
268
283
  * 虚拟文件系统监听器
269
284
  */
270
285
  #watchers: Record<string, Array<(type: string) => Promise<boolean>>> = {};
286
+ /**
287
+ * 锁定的文件
288
+ */
289
+ #lockedFiles: Record<string, boolean> = {};
271
290
  /**
272
291
  * 创建虚拟文件系统
273
292
  * @param name 虚拟文件系统名称
@@ -575,6 +594,13 @@ class VVVFS {
575
594
  }
576
595
  }
577
596
  }
597
+ if (this.#lockedFiles[targetPath]) {
598
+ console.warn("文件已被锁定");
599
+ if (this.options.throwError) {
600
+ throw new VVVFSError("Write", "文件已被锁定");
601
+ }
602
+ return false;
603
+ }
578
604
  if (!(await this.exists(targetPath))) {
579
605
  const success = await this.createFile(targetPath);
580
606
  if (!success) {
@@ -673,6 +699,13 @@ class VVVFS {
673
699
  }
674
700
  }
675
701
  }
702
+ if (this.#lockedFiles[targetPath]) {
703
+ console.warn("文件已被锁定");
704
+ if (this.options.throwError) {
705
+ throw new VVVFSError("Append", "文件已被锁定");
706
+ }
707
+ return false;
708
+ }
676
709
  const existingFile = await this.read(targetPath);
677
710
  if (existingFile) {
678
711
  const blob = new Blob([existingFile, content], {
@@ -724,6 +757,13 @@ class VVVFS {
724
757
  }
725
758
  }
726
759
  }
760
+ if (this.#lockedFiles[targetPath]) {
761
+ console.warn("文件已被锁定");
762
+ if (this.options.throwError) {
763
+ throw new VVVFSError("Read", "文件已被锁定");
764
+ }
765
+ return null;
766
+ }
727
767
  if (!(await this.exists(targetPath))) {
728
768
  console.warn("文件不存在");
729
769
  if (this.options.throwError) {
@@ -812,6 +852,13 @@ class VVVFS {
812
852
  }
813
853
  }
814
854
  }
855
+ if (this.#lockedFiles[targetPath]) {
856
+ console.warn("文件已被锁定");
857
+ if (this.options.throwError) {
858
+ throw new VVVFSError("Read", "文件已被锁定");
859
+ }
860
+ return null;
861
+ }
815
862
  if (!(await this.exists(targetPath))) {
816
863
  console.warn("文件不存在");
817
864
  if (this.options.throwError) {
@@ -901,6 +948,13 @@ class VVVFS {
901
948
  }
902
949
  }
903
950
  }
951
+ if (this.#lockedFiles[targetPath]) {
952
+ console.warn("文件已被锁定");
953
+ if (this.options.throwError) {
954
+ throw new VVVFSError("List", "文件已被锁定");
955
+ }
956
+ return [];
957
+ }
904
958
  if (!(await this.exists(targetPath))) {
905
959
  console.warn("路径不存在");
906
960
  if (this.options.throwError) {
@@ -945,6 +999,13 @@ class VVVFS {
945
999
  }
946
1000
  }
947
1001
  }
1002
+ if (this.#lockedFiles[sourcePath]) {
1003
+ console.warn("文件已被锁定");
1004
+ if (this.options.throwError) {
1005
+ throw new VVVFSError("Rename", "文件已被锁定");
1006
+ }
1007
+ return false;
1008
+ }
948
1009
  if (!(await this.exists(sourcePath))) {
949
1010
  console.warn("文件不存在");
950
1011
  if (this.options.throwError) {
@@ -1014,6 +1075,13 @@ class VVVFS {
1014
1075
  }
1015
1076
  }
1016
1077
  }
1078
+ if (this.#lockedFiles[targetPath]) {
1079
+ console.warn("文件已被锁定");
1080
+ if (this.options.throwError) {
1081
+ throw new VVVFSError("Delete", "文件已被锁定");
1082
+ }
1083
+ return false;
1084
+ }
1017
1085
  if (!(await this.exists(targetPath))) {
1018
1086
  console.warn("文件不存在");
1019
1087
  if (this.options.throwError) {
@@ -1070,6 +1138,13 @@ class VVVFS {
1070
1138
  }
1071
1139
  }
1072
1140
  }
1141
+ if (this.#lockedFiles[sourcePath]) {
1142
+ console.warn("文件已被锁定");
1143
+ if (this.options.throwError) {
1144
+ throw new VVVFSError("Move", "文件已被锁定");
1145
+ }
1146
+ return false;
1147
+ }
1073
1148
  if (sourcePath === destinationPath) {
1074
1149
  return true;
1075
1150
  }
@@ -1147,6 +1222,13 @@ class VVVFS {
1147
1222
  }
1148
1223
  }
1149
1224
  }
1225
+ if (this.#lockedFiles[sourcePath]) {
1226
+ console.warn("文件已被锁定");
1227
+ if (this.options.throwError) {
1228
+ throw new VVVFSError("Copy", "文件已被锁定");
1229
+ }
1230
+ return false;
1231
+ }
1150
1232
  if (await this.exists(destinationPath)) {
1151
1233
  console.warn("目标文件已存在");
1152
1234
  if (this.options.throwError) {
@@ -1250,14 +1332,69 @@ class VVVFS {
1250
1332
  return null;
1251
1333
  }
1252
1334
  }
1253
- async watch(path: string, handler: (type: string) => Promise<boolean>) {
1335
+ /**
1336
+ * 监听文件
1337
+ * @param path 文件路径
1338
+ * @param handler 监听器
1339
+ */
1340
+ watch(path: string, handler: (type: string) => Promise<boolean>) {
1254
1341
  path = joinPath(path);
1255
1342
  if (!this.#watchers[path]) {
1256
1343
  this.#watchers[path] = [];
1257
1344
  }
1258
1345
  this.#watchers[path].push(handler);
1259
1346
  }
1347
+ /**
1348
+ * 锁定文件
1349
+ * @param path 文件路径
1350
+ */
1351
+ async lock(path: string) {
1352
+ path = joinPath(path);
1353
+ if (!(await this.exists(path))) {
1354
+ console.warn("文件不存在");
1355
+ if (this.options.throwError) {
1356
+ throw new VVVFSError("Lock", "文件不存在");
1357
+ }
1358
+ return false;
1359
+ }
1360
+ if (this.#lockedFiles[path]) {
1361
+ console.warn("文件已被锁定");
1362
+ if (this.options.throwError) {
1363
+ throw new VVVFSError("Lock", "文件已被锁定");
1364
+ }
1365
+ return false;
1366
+ }
1367
+ this.#lockedFiles[path] = true;
1368
+ return true;
1369
+ }
1370
+ /**
1371
+ * 解锁文件
1372
+ * @param path 文件路径
1373
+ */
1374
+ async unlock(path: string) {
1375
+ path = joinPath(path);
1376
+ if (!(await this.exists(path))) {
1377
+ console.warn("文件不存在");
1378
+ if (this.options.throwError) {
1379
+ throw new VVVFSError("Unlock", "文件不存在");
1380
+ }
1381
+ return false;
1382
+ }
1383
+ if (!this.#lockedFiles[path]) {
1384
+ console.warn("文件未被锁定");
1385
+ if (this.options.throwError) {
1386
+ throw new VVVFSError("Unlock", "文件未被锁定");
1387
+ }
1388
+ return false;
1389
+ }
1390
+ delete this.#lockedFiles[path];
1391
+ return true;
1392
+ }
1260
1393
  }
1394
+ /**
1395
+ * 解析路径
1396
+ * @param path 路径
1397
+ */
1261
1398
  function parsePath(path: string) {
1262
1399
  path = joinPath(path);
1263
1400
  const oldParts = path.split("/");
@@ -1271,6 +1408,11 @@ function parsePath(path: string) {
1271
1408
  if (joinPath(parent, name).length > 4096) throw new VVVFSError("ParsePath", "文件路径过长");
1272
1409
  return { name, parent };
1273
1410
  }
1411
+
1412
+ /**
1413
+ * 合并路径
1414
+ * @param paths 路径
1415
+ */
1274
1416
  function joinPath(...paths: string[]) {
1275
1417
  const segments = paths.map((p) => String(p)).filter((p) => p.length > 0);
1276
1418
  if (segments.length === 0) return ".";
@@ -1302,4 +1444,10 @@ Object.defineProperty(VVVFS, "version", {
1302
1444
  enumerable: true,
1303
1445
  configurable: false,
1304
1446
  });
1447
+ Object.defineProperty(VVVFS, "author", {
1448
+ value: "IFTC",
1449
+ writable: false,
1450
+ enumerable: true,
1451
+ configurable: false,
1452
+ });
1305
1453
  (globalThis as any).VVVFS = VVVFS;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vvvfs",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "一个使用IndexDB实现的虚拟文件系统",
5
5
  "keywords": [
6
6
  "Virtual",