@b9g/filesystem 0.1.1 → 0.1.4

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 ADDED
@@ -0,0 +1,339 @@
1
+ # @b9g/filesystem
2
+
3
+ Universal filesystem abstraction with multiple backend implementations for different runtimes and storage systems.
4
+
5
+ ## Features
6
+
7
+ - **Universal API**: Same interface across Node.js, Bun, browsers, and edge platforms
8
+ - **Multiple Backends**: Memory, Node.js fs, Bun, S3, R2, and more
9
+ - **Registry Pattern**: Register filesystem implementations by name
10
+ - **Async/Await**: Promise-based API throughout
11
+ - **Directory Handles**: File System Access API compatible
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install @b9g/filesystem
17
+ ```
18
+
19
+ ## Quick Start
20
+
21
+ ```javascript
22
+ import { FilesystemRegistry, MemoryFilesystem } from '@b9g/filesystem';
23
+
24
+ // Create registry
25
+ const registry = new FilesystemRegistry();
26
+
27
+ // Register backends
28
+ registry.register('memory', () => new MemoryFilesystem());
29
+ registry.register('temp', () => new NodeFilesystem('/tmp'));
30
+
31
+ // Get filesystem
32
+ const fs = await registry.get('memory');
33
+
34
+ // Create directory
35
+ const dir = await fs.getDirectoryHandle('projects', { create: true });
36
+
37
+ // Create file
38
+ const file = await dir.getFileHandle('readme.txt', { create: true });
39
+
40
+ // Write content
41
+ const writable = await file.createWritable();
42
+ await writable.write('Hello World!');
43
+ await writable.close();
44
+
45
+ // Read content
46
+ const fileData = await file.getFile();
47
+ const text = await fileData.text();
48
+ console.log(text); // 'Hello World!'
49
+ ```
50
+
51
+ ## Filesystem Implementations
52
+
53
+ ### MemoryFilesystem
54
+
55
+ In-memory filesystem for testing and temporary storage:
56
+
57
+ ```javascript
58
+ import { MemoryFilesystem } from '@b9g/filesystem';
59
+
60
+ const fs = new MemoryFilesystem();
61
+ ```
62
+
63
+ ### NodeFilesystem
64
+
65
+ Node.js filesystem backend:
66
+
67
+ ```javascript
68
+ import { NodeFilesystem } from '@b9g/filesystem';
69
+
70
+ const fs = new NodeFilesystem('/app/data');
71
+ ```
72
+
73
+ ### BunS3Filesystem
74
+
75
+ Bun with S3-compatible storage:
76
+
77
+ ```javascript
78
+ import { BunS3Filesystem } from '@b9g/filesystem';
79
+
80
+ const fs = new BunS3Filesystem({
81
+ bucket: 'my-bucket',
82
+ region: 'us-east-1',
83
+ accessKeyId: process.env.AWS_ACCESS_KEY_ID,
84
+ secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
85
+ });
86
+ ```
87
+
88
+ ## Registry Usage
89
+
90
+ ```javascript
91
+ import {
92
+ FilesystemRegistry,
93
+ MemoryFilesystem,
94
+ NodeFilesystem
95
+ } from '@b9g/filesystem';
96
+
97
+ const registry = new FilesystemRegistry();
98
+
99
+ // Register implementations
100
+ registry.register('memory', () => new MemoryFilesystem());
101
+ registry.register('local', () => new NodeFilesystem('./data'));
102
+ registry.register('temp', () => new NodeFilesystem('/tmp'));
103
+
104
+ // Use by name
105
+ const memFs = await registry.get('memory');
106
+ const localFs = await registry.get('local');
107
+ ```
108
+
109
+ ## File System Access API
110
+
111
+ Compatible with the File System Access API:
112
+
113
+ ```javascript
114
+ // Get directory handle
115
+ const dirHandle = await fs.getDirectoryHandle('uploads', { create: true });
116
+
117
+ // List directory contents
118
+ for await (const [name, handle] of dirHandle.entries()) {
119
+ if (handle.kind === 'file') {
120
+ console.log(`File: ${name}`);
121
+ } else {
122
+ console.log(`Directory: ${name}`);
123
+ }
124
+ }
125
+
126
+ // Get file handle
127
+ const fileHandle = await dirHandle.getFileHandle('data.json', { create: true });
128
+
129
+ // Check if exists
130
+ try {
131
+ await dirHandle.getFileHandle('missing.txt');
132
+ } catch (error) {
133
+ console.log('File does not exist');
134
+ }
135
+
136
+ // Remove file
137
+ await dirHandle.removeEntry('old-file.txt');
138
+
139
+ // Remove directory
140
+ await dirHandle.removeEntry('old-dir', { recursive: true });
141
+ ```
142
+
143
+ ## File Operations
144
+
145
+ ### Writing Files
146
+
147
+ ```javascript
148
+ // Get file handle
149
+ const file = await dir.getFileHandle('config.json', { create: true });
150
+
151
+ // Create writable stream
152
+ const writable = await file.createWritable();
153
+
154
+ // Write data
155
+ await writable.write(JSON.stringify({ setting: 'value' }));
156
+ await writable.close();
157
+
158
+ // Or write all at once
159
+ await writable.write(new Blob(['Hello World']));
160
+ await writable.close();
161
+ ```
162
+
163
+ ### Reading Files
164
+
165
+ ```javascript
166
+ // Get file handle
167
+ const file = await dir.getFileHandle('config.json');
168
+
169
+ // Get file object
170
+ const fileData = await file.getFile();
171
+
172
+ // Read as text
173
+ const text = await fileData.text();
174
+
175
+ // Read as JSON
176
+ const json = JSON.parse(text);
177
+
178
+ // Read as ArrayBuffer
179
+ const buffer = await fileData.arrayBuffer();
180
+
181
+ // Read as stream
182
+ const stream = fileData.stream();
183
+ ```
184
+
185
+ ## Integration Examples
186
+
187
+ ### Cache Storage
188
+
189
+ ```javascript
190
+ import { FilesystemRegistry, NodeFilesystem } from '@b9g/filesystem';
191
+
192
+ const registry = new FilesystemRegistry();
193
+ registry.register('cache', () => new NodeFilesystem('./cache'));
194
+
195
+ // Use with cache
196
+ const fs = await registry.get('cache');
197
+ const cacheDir = await fs.getDirectoryHandle('pages', { create: true });
198
+
199
+ // Store cached response
200
+ const file = await cacheDir.getFileHandle('index.html', { create: true });
201
+ const writable = await file.createWritable();
202
+ await writable.write('<html>...</html>');
203
+ await writable.close();
204
+ ```
205
+
206
+ ### Asset Pipeline
207
+
208
+ ```javascript
209
+ // Static assets filesystem
210
+ registry.register('assets', () => new NodeFilesystem('./dist/assets'));
211
+
212
+ const assets = await registry.get('assets');
213
+ const staticDir = await assets.getDirectoryHandle('static', { create: true });
214
+
215
+ // Copy build assets
216
+ for (const asset of buildAssets) {
217
+ const file = await staticDir.getFileHandle(asset.name, { create: true });
218
+ const writable = await file.createWritable();
219
+ await writable.write(asset.content);
220
+ await writable.close();
221
+ }
222
+ ```
223
+
224
+ ### Upload Handling
225
+
226
+ ```javascript
227
+ router.post('/upload', async (request) => {
228
+ const formData = await request.formData();
229
+ const file = formData.get('file');
230
+
231
+ if (file) {
232
+ const uploads = await registry.get('uploads');
233
+ const uploadsDir = await uploads.getDirectoryHandle('files', { create: true });
234
+
235
+ const fileHandle = await uploadsDir.getFileHandle(file.name, { create: true });
236
+ const writable = await fileHandle.createWritable();
237
+ await writable.write(await file.arrayBuffer());
238
+ await writable.close();
239
+
240
+ return Response.json({ success: true, filename: file.name });
241
+ }
242
+
243
+ return BadRequest('No file provided');
244
+ });
245
+ ```
246
+
247
+ ## API Reference
248
+
249
+ ### FilesystemRegistry
250
+
251
+ ```typescript
252
+ class FilesystemRegistry {
253
+ register(name: string, factory: () => Filesystem): void;
254
+ get(name: string): Promise<Filesystem>;
255
+ has(name: string): boolean;
256
+ delete(name: string): boolean;
257
+ keys(): string[];
258
+ }
259
+ ```
260
+
261
+ ### Filesystem Interface
262
+
263
+ ```typescript
264
+ interface Filesystem {
265
+ getDirectoryHandle(name: string, options?: GetDirectoryOptions): Promise<DirectoryHandle>;
266
+ }
267
+
268
+ interface DirectoryHandle {
269
+ kind: 'directory';
270
+ name: string;
271
+
272
+ getDirectoryHandle(name: string, options?: GetDirectoryOptions): Promise<DirectoryHandle>;
273
+ getFileHandle(name: string, options?: GetFileOptions): Promise<FileHandle>;
274
+ removeEntry(name: string, options?: RemoveOptions): Promise<void>;
275
+ entries(): AsyncIterableIterator<[string, DirectoryHandle | FileHandle]>;
276
+ keys(): AsyncIterableIterator<string>;
277
+ values(): AsyncIterableIterator<DirectoryHandle | FileHandle>;
278
+ }
279
+
280
+ interface FileHandle {
281
+ kind: 'file';
282
+ name: string;
283
+
284
+ getFile(): Promise<File>;
285
+ createWritable(options?: CreateWritableOptions): Promise<WritableStream>;
286
+ }
287
+ ```
288
+
289
+ ## Backend-Specific Options
290
+
291
+ ### S3 Configuration
292
+
293
+ ```javascript
294
+ import { BunS3Filesystem } from '@b9g/filesystem';
295
+
296
+ const s3fs = new BunS3Filesystem({
297
+ bucket: 'my-bucket',
298
+ region: 'us-west-2',
299
+ endpoint: 'https://s3.us-west-2.amazonaws.com',
300
+ accessKeyId: process.env.AWS_ACCESS_KEY_ID,
301
+ secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
302
+ pathStyle: false,
303
+ prefix: 'app-data/'
304
+ });
305
+ ```
306
+
307
+ ### Memory Options
308
+
309
+ ```javascript
310
+ import { MemoryFilesystem } from '@b9g/filesystem';
311
+
312
+ const memfs = new MemoryFilesystem({
313
+ maxSize: 100 * 1024 * 1024, // 100MB limit
314
+ caseSensitive: true
315
+ });
316
+ ```
317
+
318
+ ## Error Handling
319
+
320
+ ```javascript
321
+ try {
322
+ const file = await dir.getFileHandle('missing.txt');
323
+ } catch (error) {
324
+ if (error.name === 'NotFoundError') {
325
+ console.log('File not found');
326
+ } else {
327
+ console.error('Unexpected error:', error);
328
+ }
329
+ }
330
+
331
+ // Check before accessing
332
+ const exists = await dir.getFileHandle('data.txt')
333
+ .then(() => true)
334
+ .catch(() => false);
335
+ ```
336
+
337
+ ## License
338
+
339
+ MIT
package/package.json CHANGED
@@ -1,14 +1,20 @@
1
1
  {
2
2
  "name": "@b9g/filesystem",
3
- "version": "0.1.1",
3
+ "version": "0.1.4",
4
4
  "description": "Universal File System Access API implementations for all platforms",
5
5
  "license": "MIT",
6
6
  "devDependencies": {
7
- "@b9g/libuild": "^0.1.10",
7
+ "@b9g/libuild": "^0.1.11",
8
8
  "@types/bun": "^1.2.2"
9
9
  },
10
10
  "peerDependencies": {
11
- "@types/wicg-file-system-access": "^2023.10.7"
11
+ "@types/wicg-file-system-access": "^2023.10.7",
12
+ "@types/node": "^18.0.0"
13
+ },
14
+ "peerDependenciesMeta": {
15
+ "@types/node": {
16
+ "optional": true
17
+ }
12
18
  },
13
19
  "type": "module",
14
20
  "types": "src/index.d.ts",
@@ -66,6 +72,14 @@
66
72
  "types": "./src/types.d.ts",
67
73
  "import": "./src/types.js"
68
74
  },
69
- "./package.json": "./package.json"
75
+ "./package.json": "./package.json",
76
+ "./directory-storage": {
77
+ "types": "./src/directory-storage.d.ts",
78
+ "import": "./src/directory-storage.js"
79
+ },
80
+ "./directory-storage.js": {
81
+ "types": "./src/directory-storage.d.ts",
82
+ "import": "./src/directory-storage.js"
83
+ }
70
84
  }
71
85
  }
package/src/bun-s3.d.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  * Leverages Bun's native S3Client and S3File for high-performance
5
5
  * cloud storage operations with File System Access API compatibility.
6
6
  */
7
- import type { FileSystemAdapter, FileSystemConfig } from "@b9g/filesystem";
7
+ import type { Bucket, FileSystemConfig } from "./types.js";
8
8
  /**
9
9
  * Bun S3 implementation of FileSystemWritableFileStream
10
10
  */
@@ -59,13 +59,13 @@ export declare class BunS3FileSystemDirectoryHandle implements FileSystemDirecto
59
59
  requestPermission(): Promise<PermissionState>;
60
60
  }
61
61
  /**
62
- * Bun S3 filesystem adapter using Bun's native S3Client
62
+ * S3 bucket using Bun's native S3Client
63
63
  */
64
- export declare class BunS3FileSystemAdapter implements FileSystemAdapter {
64
+ export declare class S3Bucket implements Bucket {
65
65
  private config;
66
66
  private s3Client;
67
67
  constructor(s3Client: any, config?: FileSystemConfig);
68
- getFileSystemRoot(name?: string): Promise<FileSystemDirectoryHandle>;
68
+ getDirectoryHandle(name: string): Promise<FileSystemDirectoryHandle>;
69
69
  getConfig(): FileSystemConfig;
70
70
  dispose(): Promise<void>;
71
71
  }
package/src/bun-s3.js CHANGED
@@ -216,7 +216,7 @@ var BunS3FileSystemDirectoryHandle = class _BunS3FileSystemDirectoryHandle {
216
216
  return "granted";
217
217
  }
218
218
  };
219
- var BunS3FileSystemAdapter = class {
219
+ var S3Bucket = class {
220
220
  config;
221
221
  s3Client;
222
222
  constructor(s3Client, config = {}) {
@@ -226,8 +226,8 @@ var BunS3FileSystemAdapter = class {
226
226
  };
227
227
  this.s3Client = s3Client;
228
228
  }
229
- async getFileSystemRoot(name = "default") {
230
- const prefix = `filesystems/${name}`;
229
+ async getDirectoryHandle(name) {
230
+ const prefix = name ? `filesystems/${name}` : "filesystems/root";
231
231
  return new BunS3FileSystemDirectoryHandle(this.s3Client, prefix);
232
232
  }
233
233
  getConfig() {
@@ -237,8 +237,8 @@ var BunS3FileSystemAdapter = class {
237
237
  }
238
238
  };
239
239
  export {
240
- BunS3FileSystemAdapter,
241
240
  BunS3FileSystemDirectoryHandle,
242
241
  BunS3FileSystemFileHandle,
243
- BunS3FileSystemWritableFileStream
242
+ BunS3FileSystemWritableFileStream,
243
+ S3Bucket
244
244
  };
@@ -0,0 +1,50 @@
1
+ import type { Bucket } from "./types.js";
2
+ /**
3
+ * BucketStorage implements bucket storage with a configurable factory
4
+ * The factory function receives the bucket name and can return different filesystem types
5
+ * This mirrors the CustomCacheStorage pattern for consistency
6
+ *
7
+ * Example usage:
8
+ * ```typescript
9
+ * const buckets = new BucketStorage((name) => {
10
+ * if (name === 'uploads') return new S3Bucket('my-bucket');
11
+ * if (name === 'temp') return new LocalBucket('/tmp');
12
+ * return new LocalBucket('./dist'); // Default to dist
13
+ * });
14
+ * ```
15
+ */
16
+ export declare class BucketStorage {
17
+ private factory;
18
+ private instances;
19
+ constructor(factory: (name: string) => Bucket | Promise<Bucket>);
20
+ /**
21
+ * Opens a bucket with the given name
22
+ * Returns existing instance if already opened, otherwise creates a new one
23
+ */
24
+ open(name: string): Promise<FileSystemDirectoryHandle>;
25
+ /**
26
+ * Returns true if a bucket with the given name exists (has been opened)
27
+ */
28
+ has(name: string): Promise<boolean>;
29
+ /**
30
+ * Deletes a bucket with the given name
31
+ * Disposes of the instance if it exists
32
+ */
33
+ delete(name: string): Promise<boolean>;
34
+ /**
35
+ * Returns a list of all opened bucket names
36
+ */
37
+ keys(): Promise<string[]>;
38
+ /**
39
+ * Get statistics about the bucket storage
40
+ */
41
+ getStats(): {
42
+ openInstances: number;
43
+ bucketNames: string[];
44
+ };
45
+ /**
46
+ * Dispose of all open adapter instances
47
+ * Useful for cleanup during shutdown
48
+ */
49
+ dispose(): Promise<void>;
50
+ }
@@ -0,0 +1,74 @@
1
+ /// <reference types="./directory-storage.d.ts" />
2
+ // src/directory-storage.ts
3
+ var BucketStorage = class {
4
+ constructor(factory) {
5
+ this.factory = factory;
6
+ }
7
+ instances = /* @__PURE__ */ new Map();
8
+ /**
9
+ * Opens a bucket with the given name
10
+ * Returns existing instance if already opened, otherwise creates a new one
11
+ */
12
+ async open(name) {
13
+ const existingInstance = this.instances.get(name);
14
+ if (existingInstance) {
15
+ return await existingInstance.getDirectoryHandle("");
16
+ }
17
+ const adapter = await this.factory(name);
18
+ this.instances.set(name, adapter);
19
+ return await adapter.getDirectoryHandle("");
20
+ }
21
+ /**
22
+ * Returns true if a bucket with the given name exists (has been opened)
23
+ */
24
+ async has(name) {
25
+ return this.instances.has(name);
26
+ }
27
+ /**
28
+ * Deletes a bucket with the given name
29
+ * Disposes of the instance if it exists
30
+ */
31
+ async delete(name) {
32
+ const instance = this.instances.get(name);
33
+ if (instance) {
34
+ if (instance.dispose) {
35
+ await instance.dispose();
36
+ }
37
+ this.instances.delete(name);
38
+ return true;
39
+ }
40
+ return false;
41
+ }
42
+ /**
43
+ * Returns a list of all opened bucket names
44
+ */
45
+ async keys() {
46
+ return Array.from(this.instances.keys());
47
+ }
48
+ /**
49
+ * Get statistics about the bucket storage
50
+ */
51
+ getStats() {
52
+ return {
53
+ openInstances: this.instances.size,
54
+ bucketNames: Array.from(this.instances.keys())
55
+ };
56
+ }
57
+ /**
58
+ * Dispose of all open adapter instances
59
+ * Useful for cleanup during shutdown
60
+ */
61
+ async dispose() {
62
+ const disposePromises = [];
63
+ for (const [_name, instance] of this.instances) {
64
+ if (instance.dispose) {
65
+ disposePromises.push(instance.dispose());
66
+ }
67
+ }
68
+ await Promise.all(disposePromises);
69
+ this.instances.clear();
70
+ }
71
+ };
72
+ export {
73
+ BucketStorage
74
+ };
package/src/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- export type { FileSystemAdapter, FileSystemConfig } from "./types.js";
2
- export { MemoryFileSystemAdapter } from "./memory.js";
3
- export { NodeFileSystemAdapter, NodeFileSystemDirectoryHandle, NodeFileSystemFileHandle } from "./node.js";
4
- export { BunS3FileSystemAdapter, BunS3FileSystemDirectoryHandle, BunS3FileSystemFileHandle } from "./bun-s3.js";
5
- export { FileSystemRegistry, getFileSystemRoot } from "./registry.js";
1
+ export type { Bucket, FileSystemConfig } from "./types.js";
2
+ export { MemoryBucket } from "./memory.js";
3
+ export { LocalBucket, NodeFileSystemDirectoryHandle, NodeFileSystemFileHandle } from "./node.js";
4
+ export { S3Bucket, BunS3FileSystemDirectoryHandle, BunS3FileSystemFileHandle } from "./bun-s3.js";
5
+ export { BucketStorage } from "./directory-storage.js";
6
+ export { FileSystemRegistry, getDirectoryHandle, getBucket, getFileSystemRoot } from "./registry.js";
package/src/index.js CHANGED
@@ -1,17 +1,21 @@
1
1
  /// <reference types="./index.d.ts" />
2
2
  // src/index.ts
3
- import { MemoryFileSystemAdapter } from "./memory.js";
4
- import { NodeFileSystemAdapter, NodeFileSystemDirectoryHandle, NodeFileSystemFileHandle } from "./node.js";
5
- import { BunS3FileSystemAdapter, BunS3FileSystemDirectoryHandle, BunS3FileSystemFileHandle } from "./bun-s3.js";
6
- import { FileSystemRegistry, getFileSystemRoot } from "./registry.js";
3
+ import { MemoryBucket } from "./memory.js";
4
+ import { LocalBucket, NodeFileSystemDirectoryHandle, NodeFileSystemFileHandle } from "./node.js";
5
+ import { S3Bucket, BunS3FileSystemDirectoryHandle, BunS3FileSystemFileHandle } from "./bun-s3.js";
6
+ import { BucketStorage } from "./directory-storage.js";
7
+ import { FileSystemRegistry, getDirectoryHandle, getBucket, getFileSystemRoot } from "./registry.js";
7
8
  export {
8
- BunS3FileSystemAdapter,
9
+ BucketStorage,
9
10
  BunS3FileSystemDirectoryHandle,
10
11
  BunS3FileSystemFileHandle,
11
12
  FileSystemRegistry,
12
- MemoryFileSystemAdapter,
13
- NodeFileSystemAdapter,
13
+ LocalBucket,
14
+ MemoryBucket,
14
15
  NodeFileSystemDirectoryHandle,
15
16
  NodeFileSystemFileHandle,
17
+ S3Bucket,
18
+ getBucket,
19
+ getDirectoryHandle,
16
20
  getFileSystemRoot
17
21
  };
package/src/memory.d.ts CHANGED
@@ -4,15 +4,15 @@
4
4
  * Provides a complete filesystem interface using in-memory data structures.
5
5
  * Useful for testing, development, and temporary storage scenarios.
6
6
  */
7
- import type { FileSystemAdapter, FileSystemConfig } from "./types.js";
7
+ import type { Bucket, FileSystemConfig } from "./types.js";
8
8
  /**
9
- * Memory filesystem adapter
9
+ * Memory bucket
10
10
  */
11
- export declare class MemoryFileSystemAdapter implements FileSystemAdapter {
11
+ export declare class MemoryBucket implements Bucket {
12
12
  private config;
13
13
  private filesystems;
14
14
  constructor(config?: FileSystemConfig);
15
- getFileSystemRoot(name?: string): Promise<FileSystemDirectoryHandle>;
15
+ getDirectoryHandle(name: string): Promise<FileSystemDirectoryHandle>;
16
16
  getConfig(): FileSystemConfig;
17
17
  dispose(): Promise<void>;
18
18
  }
package/src/memory.js CHANGED
@@ -190,7 +190,7 @@ var MemoryFileSystemDirectoryHandle = class _MemoryFileSystemDirectoryHandle {
190
190
  return "granted";
191
191
  }
192
192
  };
193
- var MemoryFileSystemAdapter = class {
193
+ var MemoryBucket = class {
194
194
  config;
195
195
  filesystems = /* @__PURE__ */ new Map();
196
196
  constructor(config = {}) {
@@ -199,16 +199,17 @@ var MemoryFileSystemAdapter = class {
199
199
  ...config
200
200
  };
201
201
  }
202
- async getFileSystemRoot(name = "default") {
203
- if (!this.filesystems.has(name)) {
202
+ async getDirectoryHandle(name) {
203
+ const dirName = name || "root";
204
+ if (!this.filesystems.has(dirName)) {
204
205
  const root2 = {
205
206
  name: "root",
206
207
  files: /* @__PURE__ */ new Map(),
207
208
  directories: /* @__PURE__ */ new Map()
208
209
  };
209
- this.filesystems.set(name, root2);
210
+ this.filesystems.set(dirName, root2);
210
211
  }
211
- const root = this.filesystems.get(name);
212
+ const root = this.filesystems.get(dirName);
212
213
  return new MemoryFileSystemDirectoryHandle(root);
213
214
  }
214
215
  getConfig() {
@@ -219,5 +220,5 @@ var MemoryFileSystemAdapter = class {
219
220
  }
220
221
  };
221
222
  export {
222
- MemoryFileSystemAdapter
223
+ MemoryBucket
223
224
  };
package/src/node.d.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  * Implements FileSystemDirectoryHandle and FileSystemFileHandle using fs/promises
5
5
  * to provide universal File System Access API on Node.js platforms.
6
6
  */
7
- import type { FileSystemAdapter, FileSystemConfig } from "./types.js";
7
+ import type { Bucket, FileSystemConfig } from "./types.js";
8
8
  /**
9
9
  * Node.js implementation of FileSystemWritableFileStream
10
10
  */
@@ -56,12 +56,12 @@ export declare class NodeFileSystemDirectoryHandle implements FileSystemDirector
56
56
  requestPermission(): Promise<PermissionState>;
57
57
  }
58
58
  /**
59
- * Node.js filesystem adapter
59
+ * Local filesystem bucket using Node.js fs
60
60
  */
61
- export declare class NodeFileSystemAdapter implements FileSystemAdapter {
61
+ export declare class LocalBucket implements Bucket {
62
62
  private config;
63
63
  private rootPath;
64
64
  constructor(config?: FileSystemConfig);
65
- getFileSystemRoot(name?: string): Promise<FileSystemDirectoryHandle>;
65
+ getDirectoryHandle(name: string): Promise<FileSystemDirectoryHandle>;
66
66
  getConfig(): FileSystemConfig;
67
67
  }
package/src/node.js CHANGED
@@ -236,7 +236,7 @@ var NodeFileSystemDirectoryHandle = class _NodeFileSystemDirectoryHandle {
236
236
  return "granted";
237
237
  }
238
238
  };
239
- var NodeFileSystemAdapter = class {
239
+ var LocalBucket = class {
240
240
  config;
241
241
  rootPath;
242
242
  constructor(config = {}) {
@@ -246,20 +246,20 @@ var NodeFileSystemAdapter = class {
246
246
  };
247
247
  this.rootPath = config.rootPath || path.join(process.cwd(), "dist");
248
248
  }
249
- async getFileSystemRoot(name = "default") {
250
- const bucketPath = path.join(this.rootPath, name);
249
+ async getDirectoryHandle(name) {
250
+ const dirPath = name ? path.join(this.rootPath, name) : this.rootPath;
251
251
  try {
252
- await fs.mkdir(bucketPath, { recursive: true });
252
+ await fs.mkdir(dirPath, { recursive: true });
253
253
  } catch (error) {
254
254
  }
255
- return new NodeFileSystemDirectoryHandle(bucketPath);
255
+ return new NodeFileSystemDirectoryHandle(dirPath);
256
256
  }
257
257
  getConfig() {
258
258
  return { ...this.config };
259
259
  }
260
260
  };
261
261
  export {
262
- NodeFileSystemAdapter,
262
+ LocalBucket,
263
263
  NodeFileSystemDirectoryHandle,
264
264
  NodeFileSystemFileHandle,
265
265
  NodeFileSystemWritableFileStream
package/src/registry.d.ts CHANGED
@@ -36,8 +36,17 @@ declare class Registry {
36
36
  */
37
37
  export declare const FileSystemRegistry: Registry;
38
38
  /**
39
- * Get a file system root handle using the registered adapters
40
- * @param name Optional adapter name (uses default if not specified)
39
+ * Get a file system directory handle using the registered adapters
40
+ * @param name Directory name. Use "" for root directory
41
+ * @param adapterName Optional adapter name (uses default if not specified)
42
+ */
43
+ export declare function getDirectoryHandle(name: string, adapterName?: string): Promise<FileSystemDirectoryHandle>;
44
+ /**
45
+ * @deprecated Use getDirectoryHandle() instead
46
+ */
47
+ export declare function getBucket(name?: string, adapterName?: string): Promise<FileSystemDirectoryHandle>;
48
+ /**
49
+ * @deprecated Use getDirectoryHandle() instead
41
50
  */
42
51
  export declare function getFileSystemRoot(name?: string): Promise<FileSystemDirectoryHandle>;
43
52
  export {};
package/src/registry.js CHANGED
@@ -1,11 +1,11 @@
1
1
  /// <reference types="./registry.d.ts" />
2
2
  // src/registry.ts
3
- import { MemoryFileSystemAdapter } from "./memory.js";
3
+ import { MemoryBucket } from "./memory.js";
4
4
  var Registry = class {
5
5
  adapters = /* @__PURE__ */ new Map();
6
6
  defaultAdapter;
7
7
  constructor() {
8
- this.defaultAdapter = new MemoryFileSystemAdapter();
8
+ this.defaultAdapter = new MemoryBucket();
9
9
  }
10
10
  /**
11
11
  * Register a filesystem adapter with a name
@@ -46,18 +46,34 @@ var Registry = class {
46
46
  }
47
47
  };
48
48
  var FileSystemRegistry = new Registry();
49
- async function getFileSystemRoot(name) {
50
- const adapter = FileSystemRegistry.get(name);
49
+ async function getDirectoryHandle(name, adapterName) {
50
+ const adapter = FileSystemRegistry.get(adapterName);
51
51
  if (!adapter) {
52
- if (name) {
53
- throw new Error(`No filesystem adapter registered with name: ${name}`);
52
+ if (adapterName) {
53
+ throw new Error(`No filesystem adapter registered with name: ${adapterName}`);
54
54
  } else {
55
55
  throw new Error("No default filesystem adapter registered");
56
56
  }
57
57
  }
58
- return await adapter.getFileSystemRoot(name);
58
+ return await adapter.getDirectoryHandle(name);
59
+ }
60
+ async function getBucket(name, adapterName) {
61
+ const adapter = FileSystemRegistry.get(adapterName);
62
+ if (!adapter) {
63
+ throw new Error("No default filesystem adapter registered");
64
+ }
65
+ return await adapter.getDirectoryHandle(name || "");
66
+ }
67
+ async function getFileSystemRoot(name) {
68
+ const adapter = FileSystemRegistry.get();
69
+ if (!adapter) {
70
+ throw new Error("No default filesystem adapter registered");
71
+ }
72
+ return await adapter.getDirectoryHandle(name || "");
59
73
  }
60
74
  export {
61
75
  FileSystemRegistry,
76
+ getBucket,
77
+ getDirectoryHandle,
62
78
  getFileSystemRoot
63
79
  };
package/src/types.d.ts CHANGED
@@ -11,21 +11,21 @@ export interface FileSystemConfig {
11
11
  [key: string]: any;
12
12
  }
13
13
  /**
14
- * Core interface that all filesystem adapters must implement
14
+ * Core interface that all buckets must implement
15
15
  * Provides File System Access API compatibility across all platforms
16
16
  */
17
- export interface FileSystemAdapter {
17
+ export interface Bucket {
18
18
  /**
19
- * Get a root directory handle for the filesystem
20
- * @param name Optional filesystem name/bucket identifier
19
+ * Get a directory handle for the bucket
20
+ * @param name Directory name. Use "" for root directory
21
21
  */
22
- getFileSystemRoot(name?: string): Promise<FileSystemDirectoryHandle>;
22
+ getDirectoryHandle(name: string): Promise<FileSystemDirectoryHandle>;
23
23
  /**
24
- * Get configuration for this adapter
24
+ * Get configuration for this bucket
25
25
  */
26
26
  getConfig(): FileSystemConfig;
27
27
  /**
28
- * Cleanup resources when adapter is no longer needed
28
+ * Cleanup resources when bucket is no longer needed
29
29
  */
30
30
  dispose?(): Promise<void>;
31
31
  }