@ricsam/isolate-fs 0.0.1 → 0.1.2

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.
@@ -0,0 +1,708 @@
1
+ // @bun
2
+ // packages/fs/src/index.ts
3
+ import ivm from "isolated-vm";
4
+ import { setupCore, clearAllInstanceState } from "@ricsam/isolate-core";
5
+ import { createNodeFileSystemHandler } from "./node-adapter.mjs";
6
+ var instanceStateMap = new WeakMap;
7
+ var nextInstanceId = 1;
8
+ function getInstanceStateMapForContext(context) {
9
+ let map = instanceStateMap.get(context);
10
+ if (!map) {
11
+ map = new Map;
12
+ instanceStateMap.set(context, map);
13
+ }
14
+ return map;
15
+ }
16
+ function setupFileSystemDirectoryHandle(context, stateMap) {
17
+ const global = context.global;
18
+ global.setSync("__FileSystemDirectoryHandle_get_name", new ivm.Callback((instanceId) => {
19
+ const state = stateMap.get(instanceId);
20
+ return state?.name ?? "";
21
+ }));
22
+ global.setSync("__FileSystemDirectoryHandle_get_path", new ivm.Callback((instanceId) => {
23
+ const state = stateMap.get(instanceId);
24
+ return state?.path ?? "/";
25
+ }));
26
+ const getFileHandleRef = new ivm.Reference(async (instanceId, name, optionsJson) => {
27
+ const state = stateMap.get(instanceId);
28
+ if (!state) {
29
+ throw new Error("[NotFoundError]Directory handle not found");
30
+ }
31
+ const options = JSON.parse(optionsJson);
32
+ const childPath = state.path === "/" ? `/${name}` : `${state.path}/${name}`;
33
+ try {
34
+ await state.handler.getFileHandle(childPath, options);
35
+ } catch (err) {
36
+ if (err instanceof Error) {
37
+ throw new Error(err.message);
38
+ }
39
+ throw err;
40
+ }
41
+ const fileInstanceId = nextInstanceId++;
42
+ const fileState = {
43
+ instanceId: fileInstanceId,
44
+ path: childPath,
45
+ name,
46
+ handler: state.handler
47
+ };
48
+ stateMap.set(fileInstanceId, fileState);
49
+ return JSON.stringify({ instanceId: fileInstanceId });
50
+ });
51
+ global.setSync("__FileSystemDirectoryHandle_getFileHandle_ref", getFileHandleRef);
52
+ const getDirectoryHandleRef = new ivm.Reference(async (instanceId, name, optionsJson) => {
53
+ const state = stateMap.get(instanceId);
54
+ if (!state) {
55
+ throw new Error("[NotFoundError]Directory handle not found");
56
+ }
57
+ const options = JSON.parse(optionsJson);
58
+ const childPath = state.path === "/" ? `/${name}` : `${state.path}/${name}`;
59
+ try {
60
+ await state.handler.getDirectoryHandle(childPath, options);
61
+ } catch (err) {
62
+ if (err instanceof Error) {
63
+ throw new Error(err.message);
64
+ }
65
+ throw err;
66
+ }
67
+ const dirInstanceId = nextInstanceId++;
68
+ const dirState = {
69
+ instanceId: dirInstanceId,
70
+ path: childPath,
71
+ name,
72
+ handler: state.handler
73
+ };
74
+ stateMap.set(dirInstanceId, dirState);
75
+ return JSON.stringify({ instanceId: dirInstanceId });
76
+ });
77
+ global.setSync("__FileSystemDirectoryHandle_getDirectoryHandle_ref", getDirectoryHandleRef);
78
+ const removeEntryRef = new ivm.Reference(async (instanceId, name, optionsJson) => {
79
+ const state = stateMap.get(instanceId);
80
+ if (!state) {
81
+ throw new Error("[NotFoundError]Directory handle not found");
82
+ }
83
+ const options = JSON.parse(optionsJson);
84
+ const childPath = state.path === "/" ? `/${name}` : `${state.path}/${name}`;
85
+ try {
86
+ await state.handler.removeEntry(childPath, options);
87
+ } catch (err) {
88
+ if (err instanceof Error) {
89
+ throw new Error(err.message);
90
+ }
91
+ throw err;
92
+ }
93
+ });
94
+ global.setSync("__FileSystemDirectoryHandle_removeEntry_ref", removeEntryRef);
95
+ const readDirectoryRef = new ivm.Reference(async (instanceId) => {
96
+ const state = stateMap.get(instanceId);
97
+ if (!state) {
98
+ throw new Error("[NotFoundError]Directory handle not found");
99
+ }
100
+ try {
101
+ const entries = await state.handler.readDirectory(state.path);
102
+ const result = entries.map((entry) => {
103
+ const entryId = nextInstanceId++;
104
+ const entryPath = state.path === "/" ? `/${entry.name}` : `${state.path}/${entry.name}`;
105
+ if (entry.kind === "file") {
106
+ const fileState = {
107
+ instanceId: entryId,
108
+ path: entryPath,
109
+ name: entry.name,
110
+ handler: state.handler
111
+ };
112
+ stateMap.set(entryId, fileState);
113
+ } else {
114
+ const dirState = {
115
+ instanceId: entryId,
116
+ path: entryPath,
117
+ name: entry.name,
118
+ handler: state.handler
119
+ };
120
+ stateMap.set(entryId, dirState);
121
+ }
122
+ return {
123
+ name: entry.name,
124
+ kind: entry.kind,
125
+ instanceId: entryId
126
+ };
127
+ });
128
+ return JSON.stringify(result);
129
+ } catch (err) {
130
+ if (err instanceof Error) {
131
+ throw new Error(err.message);
132
+ }
133
+ throw err;
134
+ }
135
+ });
136
+ global.setSync("__FileSystemDirectoryHandle_readDirectory_ref", readDirectoryRef);
137
+ global.setSync("__FileSystemDirectoryHandle_isSameEntry", new ivm.Callback((id1, id2) => {
138
+ const state1 = stateMap.get(id1);
139
+ const state2 = stateMap.get(id2);
140
+ if (!state1 || !state2)
141
+ return false;
142
+ return state1.path === state2.path;
143
+ }));
144
+ const resolveRef = new ivm.Reference(async (instanceId, descendantId) => {
145
+ const state = stateMap.get(instanceId);
146
+ const descendantState = stateMap.get(descendantId);
147
+ if (!state || !descendantState) {
148
+ return "null";
149
+ }
150
+ const basePath = state.path === "/" ? "" : state.path;
151
+ if (!descendantState.path.startsWith(basePath + "/") && descendantState.path !== state.path) {
152
+ return "null";
153
+ }
154
+ const relativePath = descendantState.path.slice(basePath.length);
155
+ const components = relativePath.split("/").filter((c) => c.length > 0);
156
+ return JSON.stringify(components);
157
+ });
158
+ global.setSync("__FileSystemDirectoryHandle_resolve_ref", resolveRef);
159
+ const directoryHandleCode = `
160
+ (function() {
161
+ const _directoryHandleInstanceIds = new WeakMap();
162
+
163
+ function __decodeError(err) {
164
+ if (!(err instanceof Error)) return err;
165
+ const match = err.message.match(/^\\[(TypeError|RangeError|NotFoundError|TypeMismatchError|InvalidModificationError|Error)\\](.*)$/);
166
+ if (match) {
167
+ if (['NotFoundError', 'TypeMismatchError', 'InvalidModificationError'].includes(match[1])) {
168
+ return new DOMException(match[2], match[1]);
169
+ }
170
+ const ErrorType = globalThis[match[1]] || Error;
171
+ return new ErrorType(match[2]);
172
+ }
173
+ return err;
174
+ }
175
+
176
+ class FileSystemDirectoryHandle {
177
+ constructor(path, name) {
178
+ // Internal construction from instance ID
179
+ if (typeof path === 'number' && name === null) {
180
+ _directoryHandleInstanceIds.set(this, path);
181
+ return;
182
+ }
183
+ const instanceId = __FileSystemDirectoryHandle_construct(path, name);
184
+ _directoryHandleInstanceIds.set(this, instanceId);
185
+ }
186
+
187
+ static _fromInstanceId(instanceId) {
188
+ return new FileSystemDirectoryHandle(instanceId, null);
189
+ }
190
+
191
+ _getInstanceId() {
192
+ return _directoryHandleInstanceIds.get(this);
193
+ }
194
+
195
+ get kind() {
196
+ return 'directory';
197
+ }
198
+
199
+ get name() {
200
+ return __FileSystemDirectoryHandle_get_name(this._getInstanceId());
201
+ }
202
+
203
+ getFileHandle(name, options = {}) {
204
+ try {
205
+ const resultJson = __FileSystemDirectoryHandle_getFileHandle_ref.applySyncPromise(
206
+ undefined,
207
+ [this._getInstanceId(), name, JSON.stringify(options)]
208
+ );
209
+ const result = JSON.parse(resultJson);
210
+ return FileSystemFileHandle._fromInstanceId(result.instanceId);
211
+ } catch (err) {
212
+ throw __decodeError(err);
213
+ }
214
+ }
215
+
216
+ getDirectoryHandle(name, options = {}) {
217
+ try {
218
+ const resultJson = __FileSystemDirectoryHandle_getDirectoryHandle_ref.applySyncPromise(
219
+ undefined,
220
+ [this._getInstanceId(), name, JSON.stringify(options)]
221
+ );
222
+ const result = JSON.parse(resultJson);
223
+ return FileSystemDirectoryHandle._fromInstanceId(result.instanceId);
224
+ } catch (err) {
225
+ throw __decodeError(err);
226
+ }
227
+ }
228
+
229
+ removeEntry(name, options = {}) {
230
+ try {
231
+ __FileSystemDirectoryHandle_removeEntry_ref.applySyncPromise(
232
+ undefined,
233
+ [this._getInstanceId(), name, JSON.stringify(options)]
234
+ );
235
+ } catch (err) {
236
+ throw __decodeError(err);
237
+ }
238
+ }
239
+
240
+ async *entries() {
241
+ let entriesJson;
242
+ try {
243
+ entriesJson = __FileSystemDirectoryHandle_readDirectory_ref.applySyncPromise(
244
+ undefined,
245
+ [this._getInstanceId()]
246
+ );
247
+ } catch (err) {
248
+ throw __decodeError(err);
249
+ }
250
+ const entries = JSON.parse(entriesJson);
251
+ for (const entry of entries) {
252
+ if (entry.kind === 'file') {
253
+ yield [entry.name, FileSystemFileHandle._fromInstanceId(entry.instanceId)];
254
+ } else {
255
+ yield [entry.name, FileSystemDirectoryHandle._fromInstanceId(entry.instanceId)];
256
+ }
257
+ }
258
+ }
259
+
260
+ async *keys() {
261
+ for await (const [name] of this.entries()) {
262
+ yield name;
263
+ }
264
+ }
265
+
266
+ async *values() {
267
+ for await (const [, handle] of this.entries()) {
268
+ yield handle;
269
+ }
270
+ }
271
+
272
+ [Symbol.asyncIterator]() {
273
+ return this.entries();
274
+ }
275
+
276
+ isSameEntry(other) {
277
+ if (!(other instanceof FileSystemDirectoryHandle)) {
278
+ return false;
279
+ }
280
+ return __FileSystemDirectoryHandle_isSameEntry(
281
+ this._getInstanceId(),
282
+ other._getInstanceId()
283
+ );
284
+ }
285
+
286
+ resolve(possibleDescendant) {
287
+ try {
288
+ const resultJson = __FileSystemDirectoryHandle_resolve_ref.applySyncPromise(
289
+ undefined,
290
+ [this._getInstanceId(), possibleDescendant._getInstanceId()]
291
+ );
292
+ return resultJson === 'null' ? null : JSON.parse(resultJson);
293
+ } catch (err) {
294
+ throw __decodeError(err);
295
+ }
296
+ }
297
+ }
298
+
299
+ globalThis.FileSystemDirectoryHandle = FileSystemDirectoryHandle;
300
+ })();
301
+ `;
302
+ context.evalSync(directoryHandleCode);
303
+ }
304
+ function setupFileSystemFileHandle(context, stateMap) {
305
+ const global = context.global;
306
+ global.setSync("__FileSystemFileHandle_get_name", new ivm.Callback((instanceId) => {
307
+ const state = stateMap.get(instanceId);
308
+ return state?.name ?? "";
309
+ }));
310
+ global.setSync("__FileSystemFileHandle_get_path", new ivm.Callback((instanceId) => {
311
+ const state = stateMap.get(instanceId);
312
+ return state?.path ?? "";
313
+ }));
314
+ const getFileRef = new ivm.Reference(async (instanceId) => {
315
+ const state = stateMap.get(instanceId);
316
+ if (!state) {
317
+ throw new Error("[NotFoundError]File handle not found");
318
+ }
319
+ try {
320
+ const fileData = await state.handler.readFile(state.path);
321
+ return JSON.stringify({
322
+ name: state.name,
323
+ data: Array.from(fileData.data),
324
+ size: fileData.size,
325
+ lastModified: fileData.lastModified,
326
+ type: fileData.type
327
+ });
328
+ } catch (err) {
329
+ if (err instanceof Error) {
330
+ throw new Error(err.message);
331
+ }
332
+ throw err;
333
+ }
334
+ });
335
+ global.setSync("__FileSystemFileHandle_getFile_ref", getFileRef);
336
+ const createWritableRef = new ivm.Reference(async (instanceId, _optionsJson) => {
337
+ const state = stateMap.get(instanceId);
338
+ if (!state) {
339
+ throw new Error("[NotFoundError]File handle not found");
340
+ }
341
+ const streamInstanceId = nextInstanceId++;
342
+ const streamState = {
343
+ instanceId: streamInstanceId,
344
+ filePath: state.path,
345
+ position: 0,
346
+ buffer: [],
347
+ closed: false,
348
+ handler: state.handler
349
+ };
350
+ stateMap.set(streamInstanceId, streamState);
351
+ return streamInstanceId;
352
+ });
353
+ global.setSync("__FileSystemFileHandle_createWritable_ref", createWritableRef);
354
+ global.setSync("__FileSystemFileHandle_isSameEntry", new ivm.Callback((id1, id2) => {
355
+ const state1 = stateMap.get(id1);
356
+ const state2 = stateMap.get(id2);
357
+ if (!state1 || !state2)
358
+ return false;
359
+ return state1.path === state2.path;
360
+ }));
361
+ const fileHandleCode = `
362
+ (function() {
363
+ const _fileHandleInstanceIds = new WeakMap();
364
+
365
+ function __decodeError(err) {
366
+ if (!(err instanceof Error)) return err;
367
+ const match = err.message.match(/^\\[(TypeError|RangeError|NotFoundError|TypeMismatchError|InvalidModificationError|Error)\\](.*)$/);
368
+ if (match) {
369
+ if (['NotFoundError', 'TypeMismatchError', 'InvalidModificationError'].includes(match[1])) {
370
+ return new DOMException(match[2], match[1]);
371
+ }
372
+ const ErrorType = globalThis[match[1]] || Error;
373
+ return new ErrorType(match[2]);
374
+ }
375
+ return err;
376
+ }
377
+
378
+ class FileSystemFileHandle {
379
+ constructor(path, name) {
380
+ // Internal construction from instance ID
381
+ if (typeof path === 'number' && name === null) {
382
+ _fileHandleInstanceIds.set(this, path);
383
+ return;
384
+ }
385
+ const instanceId = __FileSystemFileHandle_construct(path, name);
386
+ _fileHandleInstanceIds.set(this, instanceId);
387
+ }
388
+
389
+ static _fromInstanceId(instanceId) {
390
+ return new FileSystemFileHandle(instanceId, null);
391
+ }
392
+
393
+ _getInstanceId() {
394
+ return _fileHandleInstanceIds.get(this);
395
+ }
396
+
397
+ get kind() {
398
+ return 'file';
399
+ }
400
+
401
+ get name() {
402
+ return __FileSystemFileHandle_get_name(this._getInstanceId());
403
+ }
404
+
405
+ getFile() {
406
+ try {
407
+ const metadataJson = __FileSystemFileHandle_getFile_ref.applySyncPromise(
408
+ undefined,
409
+ [this._getInstanceId()]
410
+ );
411
+ const metadata = JSON.parse(metadataJson);
412
+ // Create File object from metadata and content
413
+ const content = new Uint8Array(metadata.data);
414
+ return new File([content], metadata.name, {
415
+ type: metadata.type,
416
+ lastModified: metadata.lastModified
417
+ });
418
+ } catch (err) {
419
+ throw __decodeError(err);
420
+ }
421
+ }
422
+
423
+ createWritable(options = {}) {
424
+ try {
425
+ const streamId = __FileSystemFileHandle_createWritable_ref.applySyncPromise(
426
+ undefined,
427
+ [this._getInstanceId(), JSON.stringify(options)]
428
+ );
429
+ return FileSystemWritableFileStream._fromInstanceId(streamId);
430
+ } catch (err) {
431
+ throw __decodeError(err);
432
+ }
433
+ }
434
+
435
+ isSameEntry(other) {
436
+ if (!(other instanceof FileSystemFileHandle)) {
437
+ return false;
438
+ }
439
+ return __FileSystemFileHandle_isSameEntry(
440
+ this._getInstanceId(),
441
+ other._getInstanceId()
442
+ );
443
+ }
444
+ }
445
+
446
+ globalThis.FileSystemFileHandle = FileSystemFileHandle;
447
+ })();
448
+ `;
449
+ context.evalSync(fileHandleCode);
450
+ }
451
+ function setupFileSystemWritableFileStream(context, stateMap) {
452
+ const global = context.global;
453
+ const writeRef = new ivm.Reference(async (instanceId, bytesJson, position) => {
454
+ const state = stateMap.get(instanceId);
455
+ if (!state) {
456
+ throw new Error("[InvalidStateError]Stream not found");
457
+ }
458
+ if (state.closed) {
459
+ throw new Error("[InvalidStateError]Stream is closed");
460
+ }
461
+ const bytes = JSON.parse(bytesJson);
462
+ const data = new Uint8Array(bytes);
463
+ if (position !== null) {
464
+ state.position = position;
465
+ }
466
+ try {
467
+ await state.handler.writeFile(state.filePath, data, state.position);
468
+ state.position += data.length;
469
+ } catch (err) {
470
+ if (err instanceof Error) {
471
+ throw new Error(err.message);
472
+ }
473
+ throw err;
474
+ }
475
+ });
476
+ global.setSync("__FileSystemWritableFileStream_write_ref", writeRef);
477
+ global.setSync("__FileSystemWritableFileStream_seek", new ivm.Callback((instanceId, position) => {
478
+ const state = stateMap.get(instanceId);
479
+ if (!state) {
480
+ throw new Error("[InvalidStateError]Stream not found");
481
+ }
482
+ if (state.closed) {
483
+ throw new Error("[InvalidStateError]Stream is closed");
484
+ }
485
+ state.position = position;
486
+ }));
487
+ const truncateRef = new ivm.Reference(async (instanceId, size) => {
488
+ const state = stateMap.get(instanceId);
489
+ if (!state) {
490
+ throw new Error("[InvalidStateError]Stream not found");
491
+ }
492
+ if (state.closed) {
493
+ throw new Error("[InvalidStateError]Stream is closed");
494
+ }
495
+ try {
496
+ await state.handler.truncateFile(state.filePath, size);
497
+ if (state.position > size) {
498
+ state.position = size;
499
+ }
500
+ } catch (err) {
501
+ if (err instanceof Error) {
502
+ throw new Error(err.message);
503
+ }
504
+ throw err;
505
+ }
506
+ });
507
+ global.setSync("__FileSystemWritableFileStream_truncate_ref", truncateRef);
508
+ const closeRef = new ivm.Reference(async (instanceId) => {
509
+ const state = stateMap.get(instanceId);
510
+ if (!state) {
511
+ throw new Error("[InvalidStateError]Stream not found");
512
+ }
513
+ if (state.closed) {
514
+ throw new Error("[InvalidStateError]Stream is already closed");
515
+ }
516
+ state.closed = true;
517
+ });
518
+ global.setSync("__FileSystemWritableFileStream_close_ref", closeRef);
519
+ const abortRef = new ivm.Reference(async (instanceId, _reason) => {
520
+ const state = stateMap.get(instanceId);
521
+ if (!state) {
522
+ throw new Error("[InvalidStateError]Stream not found");
523
+ }
524
+ state.closed = true;
525
+ state.buffer = [];
526
+ });
527
+ global.setSync("__FileSystemWritableFileStream_abort_ref", abortRef);
528
+ global.setSync("__FileSystemWritableFileStream_get_locked", new ivm.Callback((instanceId) => {
529
+ const state = stateMap.get(instanceId);
530
+ return state ? !state.closed : false;
531
+ }));
532
+ const writableStreamCode = `
533
+ (function() {
534
+ const _writableStreamInstanceIds = new WeakMap();
535
+
536
+ function __decodeError(err) {
537
+ if (!(err instanceof Error)) return err;
538
+ const match = err.message.match(/^\\[(TypeError|RangeError|InvalidStateError|NotFoundError|Error)\\](.*)$/);
539
+ if (match) {
540
+ if (['InvalidStateError', 'NotFoundError'].includes(match[1])) {
541
+ return new DOMException(match[2], match[1]);
542
+ }
543
+ const ErrorType = globalThis[match[1]] || Error;
544
+ return new ErrorType(match[2]);
545
+ }
546
+ return err;
547
+ }
548
+
549
+ class FileSystemWritableFileStream {
550
+ constructor(instanceId) {
551
+ _writableStreamInstanceIds.set(this, instanceId);
552
+ }
553
+
554
+ static _fromInstanceId(instanceId) {
555
+ return new FileSystemWritableFileStream(instanceId);
556
+ }
557
+
558
+ _getInstanceId() {
559
+ return _writableStreamInstanceIds.get(this);
560
+ }
561
+
562
+ write(data) {
563
+ try {
564
+ // Handle different data types
565
+ let writeData;
566
+ let position = null;
567
+ let type = 'write';
568
+
569
+ if (data && typeof data === 'object' && !ArrayBuffer.isView(data) &&
570
+ !(data instanceof Blob) && !(data instanceof ArrayBuffer) &&
571
+ !Array.isArray(data) && typeof data.type === 'string') {
572
+ // WriteParams object: { type, data, position, size }
573
+ type = data.type || 'write';
574
+ if (type === 'seek') {
575
+ return this.seek(data.position);
576
+ }
577
+ if (type === 'truncate') {
578
+ return this.truncate(data.size);
579
+ }
580
+ writeData = data.data;
581
+ position = data.position ?? null;
582
+ } else {
583
+ writeData = data;
584
+ }
585
+
586
+ // Convert data to bytes array for transfer
587
+ let bytes;
588
+ if (typeof writeData === 'string') {
589
+ bytes = Array.from(new TextEncoder().encode(writeData));
590
+ } else if (writeData instanceof Blob) {
591
+ // Synchronously get blob bytes - use the internal callback
592
+ const blobText = writeData.text ? writeData.text() : '';
593
+ bytes = Array.from(new TextEncoder().encode(blobText));
594
+ } else if (writeData instanceof ArrayBuffer) {
595
+ bytes = Array.from(new Uint8Array(writeData));
596
+ } else if (ArrayBuffer.isView(writeData)) {
597
+ bytes = Array.from(new Uint8Array(writeData.buffer, writeData.byteOffset, writeData.byteLength));
598
+ } else if (Array.isArray(writeData)) {
599
+ bytes = writeData;
600
+ } else {
601
+ throw new TypeError('Invalid data type for write');
602
+ }
603
+
604
+ __FileSystemWritableFileStream_write_ref.applySyncPromise(
605
+ undefined,
606
+ [this._getInstanceId(), JSON.stringify(bytes), position]
607
+ );
608
+ } catch (err) {
609
+ throw __decodeError(err);
610
+ }
611
+ }
612
+
613
+ seek(position) {
614
+ try {
615
+ __FileSystemWritableFileStream_seek(this._getInstanceId(), position);
616
+ } catch (err) {
617
+ throw __decodeError(err);
618
+ }
619
+ }
620
+
621
+ truncate(size) {
622
+ try {
623
+ __FileSystemWritableFileStream_truncate_ref.applySyncPromise(
624
+ undefined,
625
+ [this._getInstanceId(), size]
626
+ );
627
+ } catch (err) {
628
+ throw __decodeError(err);
629
+ }
630
+ }
631
+
632
+ close() {
633
+ try {
634
+ __FileSystemWritableFileStream_close_ref.applySyncPromise(
635
+ undefined,
636
+ [this._getInstanceId()]
637
+ );
638
+ } catch (err) {
639
+ throw __decodeError(err);
640
+ }
641
+ }
642
+
643
+ abort(reason) {
644
+ try {
645
+ __FileSystemWritableFileStream_abort_ref.applySyncPromise(
646
+ undefined,
647
+ [this._getInstanceId(), reason ? String(reason) : null]
648
+ );
649
+ } catch (err) {
650
+ throw __decodeError(err);
651
+ }
652
+ }
653
+
654
+ get locked() {
655
+ return __FileSystemWritableFileStream_get_locked(this._getInstanceId());
656
+ }
657
+ }
658
+
659
+ globalThis.FileSystemWritableFileStream = FileSystemWritableFileStream;
660
+ })();
661
+ `;
662
+ context.evalSync(writableStreamCode);
663
+ }
664
+ function setupGetDirectoryGlobal(context, stateMap, options) {
665
+ const global = context.global;
666
+ const getDirectoryRef = new ivm.Reference(async (path) => {
667
+ const handler = await options.getDirectory(path);
668
+ const instanceId = nextInstanceId++;
669
+ const state = {
670
+ instanceId,
671
+ path: "/",
672
+ name: path.split("/").filter(Boolean).pop() || "",
673
+ handler
674
+ };
675
+ stateMap.set(instanceId, state);
676
+ return instanceId;
677
+ });
678
+ global.setSync("__getDirectory_ref", getDirectoryRef);
679
+ const getDirectoryCode = `
680
+ (function() {
681
+ globalThis.getDirectory = async function(path) {
682
+ const instanceId = await __getDirectory_ref.applySyncPromise(undefined, [path]);
683
+ return FileSystemDirectoryHandle._fromInstanceId(instanceId);
684
+ };
685
+ })();
686
+ `;
687
+ context.evalSync(getDirectoryCode);
688
+ }
689
+ async function setupFs(context, options) {
690
+ await setupCore(context);
691
+ const stateMap = getInstanceStateMapForContext(context);
692
+ setupFileSystemDirectoryHandle(context, stateMap);
693
+ setupFileSystemFileHandle(context, stateMap);
694
+ setupFileSystemWritableFileStream(context, stateMap);
695
+ setupGetDirectoryGlobal(context, stateMap, options);
696
+ return {
697
+ dispose() {
698
+ stateMap.clear();
699
+ }
700
+ };
701
+ }
702
+ export {
703
+ setupFs,
704
+ createNodeFileSystemHandler,
705
+ clearAllInstanceState
706
+ };
707
+
708
+ //# debugId=1B534AD8A27DB4E164756E2164756E21