sandbox-fs 1.0.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 (79) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +418 -0
  3. package/dist/FSModule.d.ts +153 -0
  4. package/dist/FSModule.d.ts.map +1 -0
  5. package/dist/FSModule.js +555 -0
  6. package/dist/FSModule.js.map +1 -0
  7. package/dist/PathMapper.d.ts +30 -0
  8. package/dist/PathMapper.d.ts.map +1 -0
  9. package/dist/PathMapper.js +122 -0
  10. package/dist/PathMapper.js.map +1 -0
  11. package/dist/PathModule.d.ts +69 -0
  12. package/dist/PathModule.d.ts.map +1 -0
  13. package/dist/PathModule.js +159 -0
  14. package/dist/PathModule.js.map +1 -0
  15. package/dist/ResourceTracker.d.ts +74 -0
  16. package/dist/ResourceTracker.d.ts.map +1 -0
  17. package/dist/ResourceTracker.js +175 -0
  18. package/dist/ResourceTracker.js.map +1 -0
  19. package/dist/VirtualFileSystem.d.ts +145 -0
  20. package/dist/VirtualFileSystem.d.ts.map +1 -0
  21. package/dist/VirtualFileSystem.js +155 -0
  22. package/dist/VirtualFileSystem.js.map +1 -0
  23. package/dist/index.d.ts +9 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +13 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/operations/newer.d.ts +36 -0
  28. package/dist/operations/newer.d.ts.map +1 -0
  29. package/dist/operations/newer.js +239 -0
  30. package/dist/operations/newer.js.map +1 -0
  31. package/dist/operations/read.d.ts +24 -0
  32. package/dist/operations/read.d.ts.map +1 -0
  33. package/dist/operations/read.js +313 -0
  34. package/dist/operations/read.js.map +1 -0
  35. package/dist/operations/symlink.d.ts +8 -0
  36. package/dist/operations/symlink.d.ts.map +1 -0
  37. package/dist/operations/symlink.js +33 -0
  38. package/dist/operations/symlink.js.map +1 -0
  39. package/dist/operations/write.d.ts +29 -0
  40. package/dist/operations/write.d.ts.map +1 -0
  41. package/dist/operations/write.js +191 -0
  42. package/dist/operations/write.js.map +1 -0
  43. package/dist/utils/ErrorFilter.d.ts +6 -0
  44. package/dist/utils/ErrorFilter.d.ts.map +1 -0
  45. package/dist/utils/ErrorFilter.js +57 -0
  46. package/dist/utils/ErrorFilter.js.map +1 -0
  47. package/dist/utils/callbackify.d.ts +9 -0
  48. package/dist/utils/callbackify.d.ts.map +1 -0
  49. package/dist/utils/callbackify.js +48 -0
  50. package/dist/utils/callbackify.js.map +1 -0
  51. package/dist/wrappers/VirtualDir.d.ts +34 -0
  52. package/dist/wrappers/VirtualDir.d.ts.map +1 -0
  53. package/dist/wrappers/VirtualDir.js +72 -0
  54. package/dist/wrappers/VirtualDir.js.map +1 -0
  55. package/dist/wrappers/VirtualDirent.d.ts +21 -0
  56. package/dist/wrappers/VirtualDirent.d.ts.map +1 -0
  57. package/dist/wrappers/VirtualDirent.js +50 -0
  58. package/dist/wrappers/VirtualDirent.js.map +1 -0
  59. package/example.js +95 -0
  60. package/example.ts +32 -0
  61. package/package.json +29 -0
  62. package/src/FSModule.ts +546 -0
  63. package/src/PathMapper.ts +102 -0
  64. package/src/PathModule.ts +142 -0
  65. package/src/ResourceTracker.ts +162 -0
  66. package/src/VirtualFileSystem.ts +172 -0
  67. package/src/index.ts +9 -0
  68. package/src/operations/newer.ts +223 -0
  69. package/src/operations/read.ts +319 -0
  70. package/src/operations/symlink.ts +31 -0
  71. package/src/operations/write.ts +189 -0
  72. package/src/utils/ErrorFilter.ts +57 -0
  73. package/src/utils/callbackify.ts +54 -0
  74. package/src/wrappers/VirtualDir.ts +84 -0
  75. package/src/wrappers/VirtualDirent.ts +60 -0
  76. package/test-data/example.txt +1 -0
  77. package/test-data/subdir/nested.txt +1 -0
  78. package/tsconfig.example.json +8 -0
  79. package/tsconfig.json +21 -0
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.PathMapper = void 0;
37
+ const path = __importStar(require("path"));
38
+ const fs = __importStar(require("fs"));
39
+ /**
40
+ * Handles conversion between virtual Unix-style paths and real platform-native paths
41
+ */
42
+ class PathMapper {
43
+ constructor(rootPath) {
44
+ // Normalize and resolve the root path to absolute platform-native format
45
+ this.normalizedRoot = path.resolve(rootPath);
46
+ // Validate that the root path exists
47
+ if (!fs.existsSync(this.normalizedRoot)) {
48
+ throw new Error(`VFS root path does not exist: ${rootPath}`);
49
+ }
50
+ // Validate that it's a directory
51
+ const stats = fs.statSync(this.normalizedRoot);
52
+ if (!stats.isDirectory()) {
53
+ throw new Error(`VFS root path is not a directory: ${rootPath}`);
54
+ }
55
+ }
56
+ /**
57
+ * Get the normalized root path
58
+ */
59
+ getRoot() {
60
+ return this.normalizedRoot;
61
+ }
62
+ /**
63
+ * Convert a virtual path (Unix-style with forward slashes) to a real platform-native path
64
+ * @param virtualPath - Virtual path starting with /
65
+ * @returns Real absolute path
66
+ * @throws Error if path traversal is detected
67
+ */
68
+ toRealPath(virtualPath) {
69
+ // Validate virtual path format
70
+ if (!virtualPath.startsWith('/')) {
71
+ throw new Error(`Virtual path must start with /: ${virtualPath}`);
72
+ }
73
+ // Remove leading slash and normalize
74
+ const relativePath = virtualPath.slice(1);
75
+ // Join with root to get real path
76
+ const realPath = path.join(this.normalizedRoot, relativePath);
77
+ // Resolve to get absolute path (handles .. and .)
78
+ const resolvedPath = path.resolve(realPath);
79
+ // Security check: ensure resolved path is within root
80
+ // Use path.relative to check if we've escaped the root
81
+ const rel = path.relative(this.normalizedRoot, resolvedPath);
82
+ // If relative path starts with .. or is an absolute path, we've escaped
83
+ if (rel.startsWith('..') || path.isAbsolute(rel)) {
84
+ throw new Error(`Path traversal detected: ${virtualPath}`);
85
+ }
86
+ return resolvedPath;
87
+ }
88
+ /**
89
+ * Convert a real platform-native path to a virtual Unix-style path
90
+ * @param realPath - Real absolute path
91
+ * @returns Virtual path starting with /
92
+ * @throws Error if real path is not within VFS root
93
+ */
94
+ toVirtualPath(realPath) {
95
+ // Normalize the real path
96
+ const normalized = path.resolve(realPath);
97
+ // Get relative path from root
98
+ const rel = path.relative(this.normalizedRoot, normalized);
99
+ // Check if path is outside root
100
+ if (rel.startsWith('..') || path.isAbsolute(rel)) {
101
+ throw new Error(`Real path is outside VFS root: ${realPath}`);
102
+ }
103
+ // Convert platform separators to forward slashes
104
+ const virtualPath = '/' + rel.split(path.sep).join('/');
105
+ return virtualPath;
106
+ }
107
+ /**
108
+ * Check if a real path is within the VFS root
109
+ */
110
+ isWithinRoot(realPath) {
111
+ try {
112
+ const normalized = path.resolve(realPath);
113
+ const rel = path.relative(this.normalizedRoot, normalized);
114
+ return !rel.startsWith('..') && !path.isAbsolute(rel);
115
+ }
116
+ catch {
117
+ return false;
118
+ }
119
+ }
120
+ }
121
+ exports.PathMapper = PathMapper;
122
+ //# sourceMappingURL=PathMapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PathMapper.js","sourceRoot":"","sources":["../src/PathMapper.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ import * as path from 'path';
2
+ /**
3
+ * Creates a path module that operates in virtual path space
4
+ * All paths use Unix-style forward slashes
5
+ * Fixed virtual CWD of '/'
6
+ */
7
+ export declare function createPathModule(): {
8
+ /**
9
+ * Normalize a path, reducing '..' and '.' parts
10
+ */
11
+ normalize(p: string): string;
12
+ /**
13
+ * Join all path segments together and normalize the result
14
+ */
15
+ join(...paths: string[]): string;
16
+ /**
17
+ * Resolve a sequence of paths to an absolute path
18
+ */
19
+ resolve(...paths: string[]): string;
20
+ /**
21
+ * Return the relative path from 'from' to 'to'
22
+ */
23
+ relative(from: string, to: string): string;
24
+ /**
25
+ * Return the directory name of a path
26
+ */
27
+ dirname(p: string): string;
28
+ /**
29
+ * Return the last portion of a path
30
+ */
31
+ basename(p: string, ext?: string): string;
32
+ /**
33
+ * Return the extension of the path
34
+ */
35
+ extname(p: string): string;
36
+ /**
37
+ * Parse a path into an object
38
+ */
39
+ parse(p: string): path.ParsedPath;
40
+ /**
41
+ * Format a path object into a string
42
+ */
43
+ format(pathObject: path.FormatInputPathObject): string;
44
+ /**
45
+ * Check if a path is absolute
46
+ */
47
+ isAbsolute(p: string): boolean;
48
+ /**
49
+ * Convert path to namespaced path (Windows-only, no-op in virtual space)
50
+ */
51
+ toNamespacedPath(p: string): string;
52
+ /**
53
+ * Path segment separator (always / in virtual space)
54
+ */
55
+ sep: string;
56
+ /**
57
+ * Path delimiter (always : in virtual space)
58
+ */
59
+ delimiter: string;
60
+ /**
61
+ * POSIX-specific methods (same as main module in virtual space)
62
+ */
63
+ posix: any;
64
+ /**
65
+ * Windows-specific methods (same as main module in virtual space)
66
+ */
67
+ win32: any;
68
+ };
69
+ //# sourceMappingURL=PathModule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PathModule.d.ts","sourceRoot":"","sources":["../src/PathModule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B;;;;GAIG;AACH,wBAAgB,gBAAgB;IAI5B;;OAEG;iBACU,MAAM,GAAG,MAAM;IAM5B;;OAEG;mBACY,MAAM,EAAE,GAAG,MAAM;IAIhC;;OAEG;sBACe,MAAM,EAAE,GAAG,MAAM;IAkBnC;;OAEG;mBACY,MAAM,MAAM,MAAM,GAAG,MAAM;IAI1C;;OAEG;eACQ,MAAM,GAAG,MAAM;IAI1B;;OAEG;gBACS,MAAM,QAAQ,MAAM,GAAG,MAAM;IAIzC;;OAEG;eACQ,MAAM,GAAG,MAAM;IAI1B;;OAEG;aACM,MAAM,GAAG,IAAI,CAAC,UAAU;IASjC;;OAEG;uBACgB,IAAI,CAAC,qBAAqB,GAAG,MAAM;IAStD;;OAEG;kBACW,MAAM,GAAG,OAAO;IAI9B;;OAEG;wBACiB,MAAM,GAAG,MAAM;IAKnC;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;WACY,GAAG;IAElB;;OAEG;WACY,GAAG;EAQrB"}
@@ -0,0 +1,159 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.createPathModule = createPathModule;
37
+ const path = __importStar(require("path"));
38
+ /**
39
+ * Creates a path module that operates in virtual path space
40
+ * All paths use Unix-style forward slashes
41
+ * Fixed virtual CWD of '/'
42
+ */
43
+ function createPathModule() {
44
+ const virtualCwd = '/';
45
+ const pathModule = {
46
+ /**
47
+ * Normalize a path, reducing '..' and '.' parts
48
+ */
49
+ normalize(p) {
50
+ const normalized = path.posix.normalize(p);
51
+ // Ensure it starts with / if it's absolute-like
52
+ return normalized.startsWith('/') ? normalized : normalized;
53
+ },
54
+ /**
55
+ * Join all path segments together and normalize the result
56
+ */
57
+ join(...paths) {
58
+ return path.posix.join(...paths);
59
+ },
60
+ /**
61
+ * Resolve a sequence of paths to an absolute path
62
+ */
63
+ resolve(...paths) {
64
+ if (paths.length === 0) {
65
+ return virtualCwd;
66
+ }
67
+ let resolved = virtualCwd;
68
+ for (const p of paths) {
69
+ if (path.posix.isAbsolute(p)) {
70
+ resolved = p;
71
+ }
72
+ else {
73
+ resolved = path.posix.join(resolved, p);
74
+ }
75
+ }
76
+ return path.posix.normalize(resolved);
77
+ },
78
+ /**
79
+ * Return the relative path from 'from' to 'to'
80
+ */
81
+ relative(from, to) {
82
+ return path.posix.relative(from, to);
83
+ },
84
+ /**
85
+ * Return the directory name of a path
86
+ */
87
+ dirname(p) {
88
+ return path.posix.dirname(p);
89
+ },
90
+ /**
91
+ * Return the last portion of a path
92
+ */
93
+ basename(p, ext) {
94
+ return path.posix.basename(p, ext);
95
+ },
96
+ /**
97
+ * Return the extension of the path
98
+ */
99
+ extname(p) {
100
+ return path.posix.extname(p);
101
+ },
102
+ /**
103
+ * Parse a path into an object
104
+ */
105
+ parse(p) {
106
+ const parsed = path.posix.parse(p);
107
+ // Ensure root is always '/' for virtual paths
108
+ if (parsed.root) {
109
+ parsed.root = '/';
110
+ }
111
+ return parsed;
112
+ },
113
+ /**
114
+ * Format a path object into a string
115
+ */
116
+ format(pathObject) {
117
+ // Ensure root is '/' for virtual paths
118
+ const virtualPathObject = { ...pathObject };
119
+ if (virtualPathObject.root) {
120
+ virtualPathObject.root = '/';
121
+ }
122
+ return path.posix.format(virtualPathObject);
123
+ },
124
+ /**
125
+ * Check if a path is absolute
126
+ */
127
+ isAbsolute(p) {
128
+ return p.startsWith('/');
129
+ },
130
+ /**
131
+ * Convert path to namespaced path (Windows-only, no-op in virtual space)
132
+ */
133
+ toNamespacedPath(p) {
134
+ // In virtual space, just return the path as-is
135
+ return p;
136
+ },
137
+ /**
138
+ * Path segment separator (always / in virtual space)
139
+ */
140
+ sep: '/',
141
+ /**
142
+ * Path delimiter (always : in virtual space)
143
+ */
144
+ delimiter: ':',
145
+ /**
146
+ * POSIX-specific methods (same as main module in virtual space)
147
+ */
148
+ posix: null,
149
+ /**
150
+ * Windows-specific methods (same as main module in virtual space)
151
+ */
152
+ win32: null,
153
+ };
154
+ // Both posix and win32 reference the same virtual implementation
155
+ pathModule.posix = pathModule;
156
+ pathModule.win32 = pathModule;
157
+ return pathModule;
158
+ }
159
+ //# sourceMappingURL=PathModule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PathModule.js","sourceRoot":"","sources":["../src/PathModule.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ import { Readable, Writable } from 'stream';
2
+ /**
3
+ * Information about a tracked file descriptor
4
+ */
5
+ export interface FDInfo {
6
+ fd: number;
7
+ virtualPath: string;
8
+ realPath: string;
9
+ flags: string | number;
10
+ mode?: number;
11
+ isStream: boolean;
12
+ }
13
+ /**
14
+ * Manages lifecycle of file descriptors and streams to prevent resource leaks
15
+ * and ensure proper cleanup when VFS is closed
16
+ */
17
+ export declare class ResourceTracker {
18
+ private fdMap;
19
+ private streams;
20
+ private abortControllers;
21
+ private _closed;
22
+ /**
23
+ * Check if the VFS has been closed
24
+ */
25
+ get closed(): boolean;
26
+ /**
27
+ * Assert that the VFS is not closed, throwing EBADF if it is
28
+ */
29
+ assertNotClosed(): void;
30
+ /**
31
+ * Track a file descriptor
32
+ */
33
+ trackFD(fd: number, info: Omit<FDInfo, 'fd'>): void;
34
+ /**
35
+ * Get information about a tracked file descriptor
36
+ */
37
+ getFD(fd: number): FDInfo | undefined;
38
+ /**
39
+ * Check if a file descriptor is tracked
40
+ */
41
+ isTracked(fd: number): boolean;
42
+ /**
43
+ * Untrack a file descriptor (when closed)
44
+ */
45
+ untrackFD(fd: number): FDInfo | undefined;
46
+ /**
47
+ * Track a stream
48
+ */
49
+ trackStream(stream: Readable | Writable): void;
50
+ /**
51
+ * Untrack a stream (when closed)
52
+ */
53
+ untrackStream(stream: Readable | Writable): void;
54
+ /**
55
+ * Register an AbortSignal listener for cleanup
56
+ */
57
+ registerAbortListener(signal: AbortSignal | undefined, cleanup: () => void): void;
58
+ /**
59
+ * Dispose all tracked resources and mark as closed
60
+ */
61
+ dispose(): void;
62
+ /**
63
+ * Get all tracked file descriptors (for debugging)
64
+ */
65
+ getAllFDs(): FDInfo[];
66
+ /**
67
+ * Get count of tracked resources
68
+ */
69
+ getResourceCount(): {
70
+ fds: number;
71
+ streams: number;
72
+ };
73
+ }
74
+ //# sourceMappingURL=ResourceTracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResourceTracker.d.ts","sourceRoot":"","sources":["../src/ResourceTracker.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAE5C;;GAEG;AACH,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;GAGG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,KAAK,CAAkC;IAC/C,OAAO,CAAC,OAAO,CAAuC;IACtD,OAAO,CAAC,gBAAgB,CAAmC;IAC3D,OAAO,CAAC,OAAO,CAAkB;IAEjC;;OAEG;IACH,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED;;OAEG;IACH,eAAe,IAAI,IAAI;IAUvB;;OAEG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,IAAI;IAInD;;OAEG;IACH,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIrC;;OAEG;IACH,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAI9B;;OAEG;IACH,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAMzC;;OAEG;IACH,WAAW,CAAC,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI;IAI9C;;OAEG;IACH,aAAa,CAAC,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI;IAIhD;;OAEG;IACH,qBAAqB,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;IAYjF;;OAEG;IACH,OAAO,IAAI,IAAI;IAsCf;;OAEG;IACH,SAAS,IAAI,MAAM,EAAE;IAIrB;;OAEG;IACH,gBAAgB,IAAI;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;CAMrD"}
@@ -0,0 +1,175 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.ResourceTracker = void 0;
37
+ const fs = __importStar(require("fs"));
38
+ /**
39
+ * Manages lifecycle of file descriptors and streams to prevent resource leaks
40
+ * and ensure proper cleanup when VFS is closed
41
+ */
42
+ class ResourceTracker {
43
+ constructor() {
44
+ this.fdMap = new Map();
45
+ this.streams = new Set();
46
+ this.abortControllers = new Set();
47
+ this._closed = false;
48
+ }
49
+ /**
50
+ * Check if the VFS has been closed
51
+ */
52
+ get closed() {
53
+ return this._closed;
54
+ }
55
+ /**
56
+ * Assert that the VFS is not closed, throwing EBADF if it is
57
+ */
58
+ assertNotClosed() {
59
+ if (this._closed) {
60
+ const error = new Error('bad file descriptor');
61
+ error.code = 'EBADF';
62
+ error.errno = -9;
63
+ error.syscall = 'read';
64
+ throw error;
65
+ }
66
+ }
67
+ /**
68
+ * Track a file descriptor
69
+ */
70
+ trackFD(fd, info) {
71
+ this.fdMap.set(fd, { fd, ...info });
72
+ }
73
+ /**
74
+ * Get information about a tracked file descriptor
75
+ */
76
+ getFD(fd) {
77
+ return this.fdMap.get(fd);
78
+ }
79
+ /**
80
+ * Check if a file descriptor is tracked
81
+ */
82
+ isTracked(fd) {
83
+ return this.fdMap.has(fd);
84
+ }
85
+ /**
86
+ * Untrack a file descriptor (when closed)
87
+ */
88
+ untrackFD(fd) {
89
+ const info = this.fdMap.get(fd);
90
+ this.fdMap.delete(fd);
91
+ return info;
92
+ }
93
+ /**
94
+ * Track a stream
95
+ */
96
+ trackStream(stream) {
97
+ this.streams.add(stream);
98
+ }
99
+ /**
100
+ * Untrack a stream (when closed)
101
+ */
102
+ untrackStream(stream) {
103
+ this.streams.delete(stream);
104
+ }
105
+ /**
106
+ * Register an AbortSignal listener for cleanup
107
+ */
108
+ registerAbortListener(signal, cleanup) {
109
+ if (!signal)
110
+ return;
111
+ const controller = new AbortController();
112
+ this.abortControllers.add(controller);
113
+ signal.addEventListener('abort', () => {
114
+ cleanup();
115
+ this.abortControllers.delete(controller);
116
+ }, { once: true });
117
+ }
118
+ /**
119
+ * Dispose all tracked resources and mark as closed
120
+ */
121
+ dispose() {
122
+ if (this._closed)
123
+ return;
124
+ // Close all tracked file descriptors
125
+ for (const [fd, info] of this.fdMap) {
126
+ try {
127
+ if (!info.isStream) {
128
+ fs.closeSync(fd);
129
+ }
130
+ }
131
+ catch (err) {
132
+ // Ignore errors during cleanup
133
+ }
134
+ }
135
+ this.fdMap.clear();
136
+ // Destroy all tracked streams
137
+ for (const stream of this.streams) {
138
+ try {
139
+ stream.destroy();
140
+ }
141
+ catch (err) {
142
+ // Ignore errors during cleanup
143
+ }
144
+ }
145
+ this.streams.clear();
146
+ // Abort all pending operations
147
+ for (const controller of this.abortControllers) {
148
+ try {
149
+ controller.abort();
150
+ }
151
+ catch (err) {
152
+ // Ignore errors during cleanup
153
+ }
154
+ }
155
+ this.abortControllers.clear();
156
+ this._closed = true;
157
+ }
158
+ /**
159
+ * Get all tracked file descriptors (for debugging)
160
+ */
161
+ getAllFDs() {
162
+ return Array.from(this.fdMap.values());
163
+ }
164
+ /**
165
+ * Get count of tracked resources
166
+ */
167
+ getResourceCount() {
168
+ return {
169
+ fds: this.fdMap.size,
170
+ streams: this.streams.size,
171
+ };
172
+ }
173
+ }
174
+ exports.ResourceTracker = ResourceTracker;
175
+ //# sourceMappingURL=ResourceTracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResourceTracker.js","sourceRoot":"","sources":["../src/ResourceTracker.ts"],"names":[],"mappings":"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"}