@zenfs/core 0.14.1 → 0.15.1
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/dist/backends/locked.d.ts +1 -0
- package/dist/backends/locked.js +1 -0
- package/dist/backends/store/store.d.ts +1 -1
- package/dist/backends/store/store.js +1 -1
- package/dist/browser.min.js +4 -4
- package/dist/browser.min.js.map +4 -4
- package/dist/config.d.ts +1 -1
- package/dist/config.js +11 -4
- package/dist/emulation/promises.d.ts +1 -1
- package/dist/emulation/promises.js +1 -1
- package/dist/file.d.ts +1 -1
- package/dist/file.js +1 -1
- package/dist/polyfills.js +20 -0
- package/license.md +1 -1
- package/package.json +2 -2
- package/readme.md +7 -7
- package/src/backends/locked.ts +1 -0
- package/src/backends/store/store.ts +1 -1
- package/src/config.ts +11 -15
- package/src/emulation/promises.ts +1 -1
- package/src/file.ts +1 -1
- package/src/polyfills.ts +20 -0
- package/dist/symbol-dispose.js +0 -10
- package/src/symbol-dispose.ts +0 -9
- /package/dist/{symbol-dispose.d.ts → polyfills.d.ts} +0 -0
package/dist/config.d.ts
CHANGED
|
@@ -34,7 +34,7 @@ export interface Configuration<T extends ConfigMounts> extends SharedConfig {
|
|
|
34
34
|
/**
|
|
35
35
|
* Configures ZenFS with single mount point /
|
|
36
36
|
*/
|
|
37
|
-
export declare function
|
|
37
|
+
export declare function configureSingle<T extends Backend>(config: MountConfiguration<T>): Promise<void>;
|
|
38
38
|
/**
|
|
39
39
|
* Configures ZenFS with the given configuration
|
|
40
40
|
* @see Configuration
|
package/dist/config.js
CHANGED
|
@@ -47,6 +47,17 @@ export async function resolveMountConfig(config, _depth = 0) {
|
|
|
47
47
|
await mount.ready();
|
|
48
48
|
return mount;
|
|
49
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Configures ZenFS with single mount point /
|
|
52
|
+
*/
|
|
53
|
+
export async function configureSingle(config) {
|
|
54
|
+
if (!isBackendConfig(config)) {
|
|
55
|
+
throw new TypeError('Invalid single mount point configuration');
|
|
56
|
+
}
|
|
57
|
+
const resolved = await resolveMountConfig(config);
|
|
58
|
+
fs.umount('/');
|
|
59
|
+
fs.mount('/', resolved);
|
|
60
|
+
}
|
|
50
61
|
/**
|
|
51
62
|
* Configures ZenFS with the given configuration
|
|
52
63
|
* @see Configuration
|
|
@@ -54,10 +65,6 @@ export async function resolveMountConfig(config, _depth = 0) {
|
|
|
54
65
|
export async function configure(config) {
|
|
55
66
|
const uid = 'uid' in config ? config.uid || 0 : 0;
|
|
56
67
|
const gid = 'gid' in config ? config.gid || 0 : 0;
|
|
57
|
-
if (isMountConfig(config)) {
|
|
58
|
-
// single FS
|
|
59
|
-
config = { mounts: { '/': config } };
|
|
60
|
-
}
|
|
61
68
|
setCred({ uid, gid, suid: uid, sgid: gid, euid: uid, egid: gid });
|
|
62
69
|
if (!config.mounts) {
|
|
63
70
|
return;
|
|
@@ -18,7 +18,7 @@ import { BigIntStats, type Stats } from '../stats.js';
|
|
|
18
18
|
import { Dir, Dirent } from './dir.js';
|
|
19
19
|
import { ReadStream, WriteStream } from './streams.js';
|
|
20
20
|
export * as constants from './constants.js';
|
|
21
|
-
import '../
|
|
21
|
+
import '../polyfills.js';
|
|
22
22
|
export declare class FileHandle implements promises.FileHandle {
|
|
23
23
|
/**
|
|
24
24
|
* The file descriptor for this file handle.
|
|
@@ -54,7 +54,7 @@ import { dirname, join, parse } from './path.js';
|
|
|
54
54
|
import { _statfs, cred, fd2file, fdMap, file2fd, fixError, mounts, resolveMount } from './shared.js';
|
|
55
55
|
import { ReadStream, WriteStream } from './streams.js';
|
|
56
56
|
export * as constants from './constants.js';
|
|
57
|
-
import '../
|
|
57
|
+
import '../polyfills.js';
|
|
58
58
|
export class FileHandle {
|
|
59
59
|
constructor(fdOrFile) {
|
|
60
60
|
const isFile = typeof fdOrFile != 'number';
|
package/dist/file.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import type { FileReadResult } from 'node:fs/promises';
|
|
4
4
|
import type { FileSystem } from './filesystem.js';
|
|
5
5
|
import { Stats, type FileType } from './stats.js';
|
|
6
|
-
import './
|
|
6
|
+
import './polyfills.js';
|
|
7
7
|
declare global {
|
|
8
8
|
interface ArrayBuffer {
|
|
9
9
|
readonly resizable: boolean;
|
package/dist/file.js
CHANGED
|
@@ -2,7 +2,7 @@ import { O_APPEND, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_SYNC, O_TRUNC, O_WRONLY,
|
|
|
2
2
|
import { Errno, ErrnoError } from './error.js';
|
|
3
3
|
import { size_max } from './inode.js';
|
|
4
4
|
import { Stats } from './stats.js';
|
|
5
|
-
import './
|
|
5
|
+
import './polyfills.js';
|
|
6
6
|
const validFlags = ['r', 'r+', 'rs', 'rs+', 'w', 'wx', 'w+', 'wx+', 'a', 'ax', 'a+', 'ax+'];
|
|
7
7
|
export function parseFlag(flag) {
|
|
8
8
|
if (typeof flag === 'number') {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Promise.withResolvers ?? (Promise.withResolvers = function () {
|
|
2
|
+
let _resolve,
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4
|
+
_reject;
|
|
5
|
+
const promise = new Promise((resolve, reject) => {
|
|
6
|
+
_resolve = resolve;
|
|
7
|
+
_reject = reject;
|
|
8
|
+
});
|
|
9
|
+
return { promise, resolve: _resolve, reject: _reject };
|
|
10
|
+
});
|
|
11
|
+
/*
|
|
12
|
+
A polyfill for when these symbols are undefined.
|
|
13
|
+
For some reason, NodeJS does not polyfill them in a VM context.
|
|
14
|
+
Since jest uses a VM context for ESM, these need to be here.
|
|
15
|
+
*/
|
|
16
|
+
// @ts-expect-error 2540
|
|
17
|
+
Symbol['dispose'] ?? (Symbol['dispose'] = Symbol('Symbol.dispose'));
|
|
18
|
+
// @ts-expect-error 2540
|
|
19
|
+
Symbol['asyncDispose'] ?? (Symbol['asyncDispose'] = Symbol('Symbol.asyncDispose'));
|
|
20
|
+
export {};
|
package/license.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zenfs/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.1",
|
|
4
4
|
"description": "A filesystem, anywhere",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"url": "https://github.com/zen-fs/core/issues"
|
|
35
35
|
},
|
|
36
36
|
"engines": {
|
|
37
|
-
"node": ">=
|
|
37
|
+
"node": ">= 16"
|
|
38
38
|
},
|
|
39
39
|
"exports": {
|
|
40
40
|
".": "./dist/index.js",
|
package/readme.md
CHANGED
|
@@ -58,11 +58,11 @@ import { configure, InMemory } from '@zenfs/core';
|
|
|
58
58
|
import { IndexedDB } from '@zenfs/dom';
|
|
59
59
|
import { Zip } from '@zenfs/zip';
|
|
60
60
|
|
|
61
|
-
const
|
|
61
|
+
const res = await fetch('mydata.zip');
|
|
62
62
|
|
|
63
63
|
await configure({
|
|
64
64
|
mounts: {
|
|
65
|
-
'/mnt/zip': { backend: Zip,
|
|
65
|
+
'/mnt/zip': { backend: Zip, data: await res.arrayBuffer() },
|
|
66
66
|
'/tmp': InMemory,
|
|
67
67
|
'/home': IndexedDB,
|
|
68
68
|
}
|
|
@@ -79,10 +79,10 @@ await configure({
|
|
|
79
79
|
Here is an example that mounts the `WebStorage` backend from `@zenfs/dom` on `/`:
|
|
80
80
|
|
|
81
81
|
```js
|
|
82
|
-
import {
|
|
82
|
+
import { configureSingle, fs } from '@zenfs/core';
|
|
83
83
|
import { WebStorage } from '@zenfs/dom';
|
|
84
84
|
|
|
85
|
-
await
|
|
85
|
+
await configureSingle({ backend: WebStorage });
|
|
86
86
|
|
|
87
87
|
if (!fs.existsSync('/test.txt')) {
|
|
88
88
|
fs.writeFileSync('/test.txt', 'This will persist across reloads!');
|
|
@@ -97,11 +97,11 @@ console.log(contents);
|
|
|
97
97
|
The FS promises API is exposed as `promises`.
|
|
98
98
|
|
|
99
99
|
```js
|
|
100
|
-
import {
|
|
100
|
+
import { configureSingle } from '@zenfs/core';
|
|
101
101
|
import { exists, writeFile } from '@zenfs/core/promises';
|
|
102
102
|
import { IndexedDB } from '@zenfs/dom';
|
|
103
103
|
|
|
104
|
-
await
|
|
104
|
+
await configureSingle({ backend: IndexedDB });
|
|
105
105
|
|
|
106
106
|
const exists = await exists('/myfile.txt');
|
|
107
107
|
if (!exists) {
|
|
@@ -137,7 +137,7 @@ await configure({
|
|
|
137
137
|
fs.mkdirSync('/mnt');
|
|
138
138
|
|
|
139
139
|
const res = await fetch('mydata.zip');
|
|
140
|
-
const zipfs = await resolveMountConfig({ backend: Zip,
|
|
140
|
+
const zipfs = await resolveMountConfig({ backend: Zip, data: await res.arrayBuffer() });
|
|
141
141
|
fs.mount('/mnt/zip', zipfs);
|
|
142
142
|
|
|
143
143
|
// do stuff with the mounted zip
|
package/src/backends/locked.ts
CHANGED
|
@@ -5,6 +5,7 @@ import type { FileSystemMetadata } from '../filesystem.js';
|
|
|
5
5
|
import { FileSystem } from '../filesystem.js';
|
|
6
6
|
import type { Stats } from '../stats.js';
|
|
7
7
|
import type { Backend } from './backend.js';
|
|
8
|
+
import '../polyfills.js';
|
|
8
9
|
|
|
9
10
|
export interface MutexLock extends PromiseWithResolvers<void> {
|
|
10
11
|
[Symbol.dispose](): void;
|
package/src/config.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { type Entries } from 'utilium';
|
|
2
1
|
import type { Backend, BackendConfiguration, FilesystemOf, SharedConfig } from './backends/backend.js';
|
|
3
2
|
import { checkOptions, isBackend, isBackendConfig } from './backends/backend.js';
|
|
4
3
|
import * as fs from './emulation/index.js';
|
|
@@ -91,34 +90,31 @@ export interface Configuration<T extends ConfigMounts> extends SharedConfig {
|
|
|
91
90
|
/**
|
|
92
91
|
* Configures ZenFS with single mount point /
|
|
93
92
|
*/
|
|
94
|
-
export async function
|
|
93
|
+
export async function configureSingle<T extends Backend>(config: MountConfiguration<T>): Promise<void> {
|
|
94
|
+
if (!isBackendConfig(config)) {
|
|
95
|
+
throw new TypeError('Invalid single mount point configuration');
|
|
96
|
+
}
|
|
95
97
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
export async function configure<T extends ConfigMounts>(config: Partial<Configuration<T>>): Promise<void>;
|
|
98
|
+
const resolved = await resolveMountConfig(config);
|
|
99
|
+
fs.umount('/');
|
|
100
|
+
fs.mount('/', resolved);
|
|
101
|
+
}
|
|
101
102
|
|
|
102
103
|
/**
|
|
103
104
|
* Configures ZenFS with the given configuration
|
|
104
105
|
* @see Configuration
|
|
105
106
|
*/
|
|
106
|
-
export async function configure(config:
|
|
107
|
+
export async function configure<T extends ConfigMounts>(config: Partial<Configuration<T>>): Promise<void> {
|
|
107
108
|
const uid = 'uid' in config ? config.uid || 0 : 0;
|
|
108
109
|
const gid = 'gid' in config ? config.gid || 0 : 0;
|
|
109
110
|
|
|
110
|
-
if (isMountConfig(config)) {
|
|
111
|
-
// single FS
|
|
112
|
-
config = { mounts: { '/': config } } as Partial<Configuration<ConfigMounts>>;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
111
|
setCred({ uid, gid, suid: uid, sgid: gid, euid: uid, egid: gid });
|
|
116
112
|
|
|
117
113
|
if (!config.mounts) {
|
|
118
114
|
return;
|
|
119
115
|
}
|
|
120
116
|
|
|
121
|
-
for (const [point, mountConfig] of Object.entries(config.mounts)
|
|
117
|
+
for (const [point, mountConfig] of Object.entries(config.mounts)) {
|
|
122
118
|
if (!point.startsWith('/')) {
|
|
123
119
|
throw new ErrnoError(Errno.EINVAL, 'Mount points must have absolute paths');
|
|
124
120
|
}
|
|
@@ -127,7 +123,7 @@ export async function configure(config: MountConfiguration<Backend> | Partial<Co
|
|
|
127
123
|
mountConfig.disableAsyncCache ??= config.disableAsyncCache || false;
|
|
128
124
|
}
|
|
129
125
|
|
|
130
|
-
config.mounts[point] = await resolveMountConfig(mountConfig);
|
|
126
|
+
config.mounts[point as keyof T & `/${string}`] = await resolveMountConfig(mountConfig);
|
|
131
127
|
}
|
|
132
128
|
|
|
133
129
|
fs.mountObject(config.mounts as MountObject);
|
|
@@ -18,7 +18,7 @@ import { dirname, join, parse } from './path.js';
|
|
|
18
18
|
import { _statfs, cred, fd2file, fdMap, file2fd, fixError, mounts, resolveMount } from './shared.js';
|
|
19
19
|
import { ReadStream, WriteStream } from './streams.js';
|
|
20
20
|
export * as constants from './constants.js';
|
|
21
|
-
import '../
|
|
21
|
+
import '../polyfills.js';
|
|
22
22
|
|
|
23
23
|
export class FileHandle implements promises.FileHandle {
|
|
24
24
|
/**
|
package/src/file.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { Errno, ErrnoError } from './error.js';
|
|
|
4
4
|
import type { FileSystem } from './filesystem.js';
|
|
5
5
|
import { size_max } from './inode.js';
|
|
6
6
|
import { Stats, type FileType } from './stats.js';
|
|
7
|
-
import './
|
|
7
|
+
import './polyfills.js';
|
|
8
8
|
|
|
9
9
|
/*
|
|
10
10
|
Typescript does not include a type declaration for resizable array buffers.
|
package/src/polyfills.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Promise.withResolvers ??= function <T>(): PromiseWithResolvers<T> {
|
|
2
|
+
let _resolve: ((value: T | PromiseLike<T>) => void) | undefined,
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4
|
+
_reject: ((reason?: any) => void) | undefined;
|
|
5
|
+
const promise = new Promise<T>((resolve, reject) => {
|
|
6
|
+
_resolve = resolve;
|
|
7
|
+
_reject = reject;
|
|
8
|
+
});
|
|
9
|
+
return { promise, resolve: _resolve!, reject: _reject! };
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/*
|
|
13
|
+
A polyfill for when these symbols are undefined.
|
|
14
|
+
For some reason, NodeJS does not polyfill them in a VM context.
|
|
15
|
+
Since jest uses a VM context for ESM, these need to be here.
|
|
16
|
+
*/
|
|
17
|
+
// @ts-expect-error 2540
|
|
18
|
+
Symbol['dispose'] ??= Symbol('Symbol.dispose');
|
|
19
|
+
// @ts-expect-error 2540
|
|
20
|
+
Symbol['asyncDispose'] ??= Symbol('Symbol.asyncDispose');
|
package/dist/symbol-dispose.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
This file acts as a polyfill for when these symbols are undefined.
|
|
3
|
-
For some reason, NodeJS does not polyfill them in a VM context.
|
|
4
|
-
Since jest uses a VM context for ESM, these need to be here.
|
|
5
|
-
*/
|
|
6
|
-
// @ts-expect-error 2540
|
|
7
|
-
Symbol['dispose'] ?? (Symbol['dispose'] = Symbol('Symbol.dispose'));
|
|
8
|
-
// @ts-expect-error 2540
|
|
9
|
-
Symbol['asyncDispose'] ?? (Symbol['asyncDispose'] = Symbol('Symbol.asyncDispose'));
|
|
10
|
-
export {};
|
package/src/symbol-dispose.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
This file acts as a polyfill for when these symbols are undefined.
|
|
3
|
-
For some reason, NodeJS does not polyfill them in a VM context.
|
|
4
|
-
Since jest uses a VM context for ESM, these need to be here.
|
|
5
|
-
*/
|
|
6
|
-
// @ts-expect-error 2540
|
|
7
|
-
Symbol['dispose'] ??= Symbol('Symbol.dispose');
|
|
8
|
-
// @ts-expect-error 2540
|
|
9
|
-
Symbol['asyncDispose'] ??= Symbol('Symbol.asyncDispose');
|
|
File without changes
|