@lova/mem-vfs 0.1.0

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.
Files changed (58) hide show
  1. package/README.md +222 -0
  2. package/dist/core/vfs-directory.d.ts +35 -0
  3. package/dist/core/vfs-directory.d.ts.map +1 -0
  4. package/dist/core/vfs-directory.js +78 -0
  5. package/dist/core/vfs-directory.js.map +1 -0
  6. package/dist/core/vfs-file.d.ts +25 -0
  7. package/dist/core/vfs-file.d.ts.map +1 -0
  8. package/dist/core/vfs-file.js +60 -0
  9. package/dist/core/vfs-file.js.map +1 -0
  10. package/dist/core/vfs-node.d.ts +42 -0
  11. package/dist/core/vfs-node.d.ts.map +1 -0
  12. package/dist/core/vfs-node.js +69 -0
  13. package/dist/core/vfs-node.js.map +1 -0
  14. package/dist/core/vfs-symlink.d.ts +21 -0
  15. package/dist/core/vfs-symlink.d.ts.map +1 -0
  16. package/dist/core/vfs-symlink.js +41 -0
  17. package/dist/core/vfs-symlink.js.map +1 -0
  18. package/dist/core/vfs.d.ts +107 -0
  19. package/dist/core/vfs.d.ts.map +1 -0
  20. package/dist/core/vfs.js +775 -0
  21. package/dist/core/vfs.js.map +1 -0
  22. package/dist/errors/file-system-errors.d.ts +79 -0
  23. package/dist/errors/file-system-errors.d.ts.map +1 -0
  24. package/dist/errors/file-system-errors.js +127 -0
  25. package/dist/errors/file-system-errors.js.map +1 -0
  26. package/dist/index.d.ts +20 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +23 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/path/path-normalizer.d.ts +23 -0
  31. package/dist/path/path-normalizer.d.ts.map +1 -0
  32. package/dist/path/path-normalizer.js +159 -0
  33. package/dist/path/path-normalizer.js.map +1 -0
  34. package/dist/path/path-resolver.d.ts +31 -0
  35. package/dist/path/path-resolver.d.ts.map +1 -0
  36. package/dist/path/path-resolver.js +68 -0
  37. package/dist/path/path-resolver.js.map +1 -0
  38. package/dist/path/path-validator.d.ts +12 -0
  39. package/dist/path/path-validator.d.ts.map +1 -0
  40. package/dist/path/path-validator.js +87 -0
  41. package/dist/path/path-validator.js.map +1 -0
  42. package/dist/types/index.d.ts +171 -0
  43. package/dist/types/index.d.ts.map +1 -0
  44. package/dist/types/index.js +29 -0
  45. package/dist/types/index.js.map +1 -0
  46. package/dist/watcher/debouncer.d.ts +31 -0
  47. package/dist/watcher/debouncer.d.ts.map +1 -0
  48. package/dist/watcher/debouncer.js +66 -0
  49. package/dist/watcher/debouncer.js.map +1 -0
  50. package/dist/watcher/watcher-events.d.ts +30 -0
  51. package/dist/watcher/watcher-events.d.ts.map +1 -0
  52. package/dist/watcher/watcher-events.js +52 -0
  53. package/dist/watcher/watcher-events.js.map +1 -0
  54. package/dist/watcher/watcher.d.ts +57 -0
  55. package/dist/watcher/watcher.d.ts.map +1 -0
  56. package/dist/watcher/watcher.js +194 -0
  57. package/dist/watcher/watcher.js.map +1 -0
  58. package/package.json +53 -0
@@ -0,0 +1,194 @@
1
+ /**
2
+ * VFSWatcher
3
+ * 虛擬檔案系統監聽器
4
+ */
5
+ import { FileChangeType } from '../types/index.js';
6
+ import { SimpleEventEmitter } from './watcher-events.js';
7
+ import { Debouncer } from './debouncer.js';
8
+ import { normalizePath, isSubPath } from '../path/path-resolver.js';
9
+ /** VFS Watcher 類別 */
10
+ export class VFSWatcher extends SimpleEventEmitter {
11
+ /** 監聽路徑 */
12
+ watchPath;
13
+ /** 選項 */
14
+ options;
15
+ /** 是否已關閉 */
16
+ closed = false;
17
+ /** 事件防抖器 */
18
+ debouncer;
19
+ /** 已知路徑快取(用於判斷新增或修改) */
20
+ knownPaths = new Set();
21
+ /** 預設選項 */
22
+ static DEFAULT_OPTIONS = {
23
+ persistent: true,
24
+ recursive: true,
25
+ ignoreInitial: false,
26
+ followSymlinks: true,
27
+ ignored: [],
28
+ debounce: 100,
29
+ depth: Infinity,
30
+ };
31
+ constructor(watchPath, options) {
32
+ super();
33
+ this.watchPath = normalizePath(watchPath);
34
+ this.options = { ...VFSWatcher.DEFAULT_OPTIONS, ...options };
35
+ this.debouncer = new Debouncer((events) => this.flushEvents(events), this.options.debounce);
36
+ }
37
+ /** 通知檔案變更 */
38
+ notifyChange(path, stats) {
39
+ if (this.closed) {
40
+ return;
41
+ }
42
+ const normalizedPath = normalizePath(path);
43
+ if (!this.shouldWatch(normalizedPath)) {
44
+ return;
45
+ }
46
+ const isNew = !this.knownPaths.has(normalizedPath);
47
+ this.knownPaths.add(normalizedPath);
48
+ const event = {
49
+ type: isNew ? FileChangeType.Add : FileChangeType.Change,
50
+ path: normalizedPath,
51
+ stats,
52
+ };
53
+ this.debouncer.add(normalizedPath, event);
54
+ }
55
+ /** 通知檔案刪除 */
56
+ notifyUnlink(path, isDirectory = false) {
57
+ if (this.closed) {
58
+ return;
59
+ }
60
+ const normalizedPath = normalizePath(path);
61
+ if (!this.shouldWatch(normalizedPath)) {
62
+ return;
63
+ }
64
+ this.knownPaths.delete(normalizedPath);
65
+ const event = {
66
+ type: isDirectory ? FileChangeType.UnlinkDir : FileChangeType.Unlink,
67
+ path: normalizedPath,
68
+ };
69
+ this.debouncer.add(normalizedPath, event);
70
+ }
71
+ /** 通知目錄新增 */
72
+ notifyAddDir(path, stats) {
73
+ if (this.closed) {
74
+ return;
75
+ }
76
+ const normalizedPath = normalizePath(path);
77
+ if (!this.shouldWatch(normalizedPath)) {
78
+ return;
79
+ }
80
+ this.knownPaths.add(normalizedPath);
81
+ const event = {
82
+ type: FileChangeType.AddDir,
83
+ path: normalizedPath,
84
+ stats,
85
+ };
86
+ this.debouncer.add(normalizedPath, event);
87
+ }
88
+ /** 發送 ready 事件 */
89
+ emitReady() {
90
+ if (this.closed) {
91
+ return;
92
+ }
93
+ this.emit('ready');
94
+ }
95
+ /** 發送錯誤事件 */
96
+ emitError(error) {
97
+ if (this.closed) {
98
+ return;
99
+ }
100
+ this.emit('error', error);
101
+ }
102
+ /** 註冊已知路徑 */
103
+ registerPath(path) {
104
+ this.knownPaths.add(normalizePath(path));
105
+ }
106
+ /** 取消註冊路徑 */
107
+ unregisterPath(path) {
108
+ this.knownPaths.delete(normalizePath(path));
109
+ }
110
+ /** 關閉監聽器 */
111
+ close() {
112
+ if (this.closed) {
113
+ return;
114
+ }
115
+ this.closed = true;
116
+ this.debouncer.cancel();
117
+ this.removeAllListeners();
118
+ this.knownPaths.clear();
119
+ }
120
+ /** 是否已關閉 */
121
+ get isClosed() {
122
+ return this.closed;
123
+ }
124
+ /** 監聽的路徑 */
125
+ get path() {
126
+ return this.watchPath;
127
+ }
128
+ /** 覆寫 on 方法 */
129
+ on(event, handler) {
130
+ return super.on(event, handler);
131
+ }
132
+ /** 檢查路徑是否應該被監聽 */
133
+ shouldWatch(path) {
134
+ // 檢查路徑是否在監聽範圍內
135
+ if (path !== this.watchPath && !isSubPath(path, this.watchPath)) {
136
+ return false;
137
+ }
138
+ // 檢查深度
139
+ const depth = this.getPathDepth(path);
140
+ if (depth > this.options.depth) {
141
+ return false;
142
+ }
143
+ // 檢查忽略規則
144
+ if (this.isIgnored(path)) {
145
+ return false;
146
+ }
147
+ return true;
148
+ }
149
+ /** 計算相對於監聽路徑的深度 */
150
+ getPathDepth(path) {
151
+ if (path === this.watchPath) {
152
+ return 0;
153
+ }
154
+ const relativePath = path.slice(this.watchPath.length);
155
+ return relativePath.split('/').filter(Boolean).length;
156
+ }
157
+ /** 檢查是否被忽略 */
158
+ isIgnored(path) {
159
+ const { ignored } = this.options;
160
+ if (!ignored) {
161
+ return false;
162
+ }
163
+ if (typeof ignored === 'function') {
164
+ return ignored(path);
165
+ }
166
+ const patterns = Array.isArray(ignored) ? ignored : [ignored];
167
+ for (const pattern of patterns) {
168
+ if (this.matchPattern(path, pattern)) {
169
+ return true;
170
+ }
171
+ }
172
+ return false;
173
+ }
174
+ /** 簡單的 pattern 匹配 */
175
+ matchPattern(path, pattern) {
176
+ // 簡單實作:支援 * 萬用字元
177
+ const regex = new RegExp('^' + pattern.replace(/[.+^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '.*') + '$');
178
+ return regex.test(path) || regex.test(path.split('/').pop() ?? '');
179
+ }
180
+ /** 批量發送事件 */
181
+ flushEvents(events) {
182
+ for (const event of events.values()) {
183
+ // 發送特定類型事件
184
+ this.emit(event.type, event);
185
+ // 發送 'all' 事件
186
+ this.emit('all', event);
187
+ }
188
+ }
189
+ }
190
+ /** 建立 VFSWatcher 實例 */
191
+ export function createWatcher(path, options) {
192
+ return new VFSWatcher(path, options);
193
+ }
194
+ //# sourceMappingURL=watcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watcher.js","sourceRoot":"","sources":["../../src/watcher/watcher.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@lova/mem-vfs",
3
+ "version": "0.1.0",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
7
+ "description": "High-performance in-memory virtual file system with symlink support, file watching, and snapshot/rollback capabilities",
8
+ "type": "module",
9
+ "main": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "import": "./dist/index.js",
14
+ "types": "./dist/index.d.ts"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "scripts": {
21
+ "build": "tsc",
22
+ "typecheck": "tsc --noEmit",
23
+ "test": "vitest run",
24
+ "test:watch": "vitest",
25
+ "test:coverage": "vitest run --coverage",
26
+ "lint": "eslint src tests --ext .ts",
27
+ "prepublishOnly": "pnpm build"
28
+ },
29
+ "keywords": [
30
+ "virtual-file-system",
31
+ "vfs",
32
+ "memfs",
33
+ "in-memory",
34
+ "file-system",
35
+ "symlink",
36
+ "snapshot",
37
+ "watch"
38
+ ],
39
+ "author": "",
40
+ "license": "MIT",
41
+ "devDependencies": {
42
+ "@types/node": "^20.10.0",
43
+ "@typescript-eslint/eslint-plugin": "^6.13.0",
44
+ "@typescript-eslint/parser": "^6.13.0",
45
+ "@vitest/coverage-v8": "1.6.0",
46
+ "eslint": "^8.54.0",
47
+ "typescript": "^5.3.0",
48
+ "vitest": "^1.0.0"
49
+ },
50
+ "engines": {
51
+ "node": ">=18.0.0"
52
+ }
53
+ }