@zenfs/core 0.1.0 → 0.2.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.
- package/dist/ApiError.d.ts +51 -14
- package/dist/ApiError.js +60 -34
- package/dist/FileIndex.d.ts +32 -35
- package/dist/FileIndex.js +93 -109
- package/dist/backends/AsyncMirror.d.ts +42 -43
- package/dist/backends/AsyncMirror.js +146 -133
- package/dist/backends/AsyncStore.d.ts +29 -28
- package/dist/backends/AsyncStore.js +139 -189
- package/dist/backends/InMemory.d.ts +16 -13
- package/dist/backends/InMemory.js +29 -14
- package/dist/backends/Locked.d.ts +8 -28
- package/dist/backends/Locked.js +44 -148
- package/dist/backends/OverlayFS.d.ts +26 -34
- package/dist/backends/OverlayFS.js +208 -371
- package/dist/backends/SyncStore.d.ts +54 -72
- package/dist/backends/SyncStore.js +159 -161
- package/dist/backends/backend.d.ts +45 -29
- package/dist/backends/backend.js +83 -13
- package/dist/backends/index.d.ts +6 -7
- package/dist/backends/index.js +5 -6
- package/dist/browser.min.js +5 -7
- package/dist/browser.min.js.map +4 -4
- package/dist/emulation/callbacks.d.ts +36 -67
- package/dist/emulation/callbacks.js +90 -46
- package/dist/emulation/constants.js +1 -1
- package/dist/emulation/promises.d.ts +228 -129
- package/dist/emulation/promises.js +414 -172
- package/dist/emulation/shared.d.ts +10 -10
- package/dist/emulation/shared.js +18 -20
- package/dist/emulation/sync.d.ts +25 -25
- package/dist/emulation/sync.js +187 -73
- package/dist/file.d.ts +166 -170
- package/dist/file.js +199 -218
- package/dist/filesystem.d.ts +68 -241
- package/dist/filesystem.js +59 -383
- package/dist/index.d.ts +7 -44
- package/dist/index.js +13 -52
- package/dist/inode.d.ts +37 -28
- package/dist/inode.js +123 -65
- package/dist/stats.d.ts +21 -19
- package/dist/stats.js +35 -56
- package/dist/utils.d.ts +26 -9
- package/dist/utils.js +73 -102
- package/package.json +4 -3
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { FileSystem } from '../filesystem.js';
|
|
2
|
+
type OptionType = 'string' | 'number' | 'bigint' | 'boolean' | 'symbol' | 'undefined' | 'object' | 'function';
|
|
2
3
|
/**
|
|
3
4
|
* Describes a file system option.
|
|
4
5
|
*/
|
|
5
|
-
export interface
|
|
6
|
+
export interface OptionConfig<T> {
|
|
6
7
|
/**
|
|
7
8
|
* The basic JavaScript type(s) for this option.
|
|
8
9
|
*/
|
|
9
|
-
type:
|
|
10
|
+
type: OptionType | OptionType[];
|
|
10
11
|
/**
|
|
11
|
-
* Whether or not the option is
|
|
12
|
-
* Defaults to
|
|
12
|
+
* Whether or not the option is required (optional can be set to null or undefined).
|
|
13
|
+
* Defaults to false.
|
|
13
14
|
*/
|
|
14
|
-
|
|
15
|
+
required?: boolean;
|
|
15
16
|
/**
|
|
16
17
|
* Description of the option. Used in error messages and documentation.
|
|
17
18
|
*/
|
|
@@ -26,22 +27,23 @@ export interface BackendOption<T> {
|
|
|
26
27
|
/**
|
|
27
28
|
* Describes all of the options available in a file system.
|
|
28
29
|
*/
|
|
29
|
-
|
|
30
|
-
[name: string]: BackendOption<unknown>;
|
|
31
|
-
}
|
|
30
|
+
type BackendOptionsConfig = Record<string, OptionConfig<unknown>>;
|
|
32
31
|
/**
|
|
33
|
-
*
|
|
32
|
+
* A backend
|
|
34
33
|
*/
|
|
35
|
-
export interface
|
|
36
|
-
|
|
34
|
+
export interface Backend<FS extends FileSystem = FileSystem, OC extends BackendOptionsConfig = BackendOptionsConfig> {
|
|
35
|
+
/**
|
|
36
|
+
* Create a new instance of the backend
|
|
37
|
+
*/
|
|
38
|
+
create(options: object): FS;
|
|
37
39
|
/**
|
|
38
40
|
* A name to identify the backend.
|
|
39
41
|
*/
|
|
40
|
-
|
|
42
|
+
name: string;
|
|
41
43
|
/**
|
|
42
44
|
* Describes all of the options available for this backend.
|
|
43
45
|
*/
|
|
44
|
-
|
|
46
|
+
options: OC;
|
|
45
47
|
/**
|
|
46
48
|
* Whether the backend is available in the current environment.
|
|
47
49
|
* It supports checking synchronously and asynchronously
|
|
@@ -55,20 +57,34 @@ export interface BaseBackendConstructor<FS extends typeof FileSystem = typeof Fi
|
|
|
55
57
|
isAvailable(): boolean;
|
|
56
58
|
}
|
|
57
59
|
/**
|
|
58
|
-
*
|
|
60
|
+
* @internal
|
|
59
61
|
*/
|
|
60
|
-
export
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
62
|
+
export declare function isBackend(arg: unknown): arg is Backend;
|
|
63
|
+
/**
|
|
64
|
+
* Checks that the given options object is valid for the file system options.
|
|
65
|
+
* @internal
|
|
66
|
+
*/
|
|
67
|
+
export declare function checkOptions(backend: Backend, opts: object): Promise<void>;
|
|
68
|
+
export declare function createBackend<B extends Backend>(backend: B, options?: object): Promise<ReturnType<B['create']>>;
|
|
69
|
+
/**
|
|
70
|
+
* Specifies a file system backend type and its options.
|
|
71
|
+
*
|
|
72
|
+
* Individual options can recursively contain BackendConfig objects for
|
|
73
|
+
* option values that require file systems.
|
|
74
|
+
*
|
|
75
|
+
* The option object for each file system corresponds to that file system's option object passed to its `Create()` method.
|
|
76
|
+
*/
|
|
77
|
+
export interface BackendConfig {
|
|
78
|
+
backend: Backend;
|
|
79
|
+
[key: string]: unknown;
|
|
70
80
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
export declare function
|
|
81
|
+
/**
|
|
82
|
+
* @internal
|
|
83
|
+
*/
|
|
84
|
+
export declare function isBackendConfig(arg: unknown): arg is BackendConfig;
|
|
85
|
+
/**
|
|
86
|
+
* Retrieve a file system with the given configuration.
|
|
87
|
+
* @param config A BackendConfig object.
|
|
88
|
+
*/
|
|
89
|
+
export declare function resolveBackendConfig(options: BackendConfig): Promise<FileSystem>;
|
|
90
|
+
export {};
|
package/dist/backends/backend.js
CHANGED
|
@@ -1,14 +1,84 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
import { ApiError, ErrorCode } from '../ApiError.js';
|
|
2
|
+
import { levenshtein } from '../utils.js';
|
|
3
|
+
/**
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
6
|
+
export function isBackend(arg) {
|
|
7
|
+
return arg != null && typeof arg == 'object' && 'isAvailable' in arg && typeof arg.isAvailable == 'function' && 'create' in arg && typeof arg.create == 'function';
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Checks that the given options object is valid for the file system options.
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
export async function checkOptions(backend, opts) {
|
|
14
|
+
if (typeof opts != 'object' || opts === null) {
|
|
15
|
+
throw new ApiError(ErrorCode.EINVAL, 'Invalid options');
|
|
16
|
+
}
|
|
17
|
+
// Check for required options.
|
|
18
|
+
for (const [optName, opt] of Object.entries(backend.options)) {
|
|
19
|
+
const providedValue = opts && opt;
|
|
20
|
+
if (providedValue === undefined || providedValue === null) {
|
|
21
|
+
if (!opt.required) {
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
/* Required option not provided.
|
|
25
|
+
if any incorrect options provided, which ones are close to the provided one?
|
|
26
|
+
(edit distance 5 === close)*/
|
|
27
|
+
const incorrectOptions = Object.keys(opts)
|
|
28
|
+
.filter(o => !(o in backend.options))
|
|
29
|
+
.map((a) => {
|
|
30
|
+
return { str: a, distance: levenshtein(optName, a) };
|
|
31
|
+
})
|
|
32
|
+
.filter(o => o.distance < 5)
|
|
33
|
+
.sort((a, b) => a.distance - b.distance);
|
|
34
|
+
throw new ApiError(ErrorCode.EINVAL, `${backend.name}: Required option '${optName}' not provided.${incorrectOptions.length > 0 ? ` You provided '${incorrectOptions[0].str}', did you mean '${optName}'.` : ''}`);
|
|
35
|
+
}
|
|
36
|
+
// Option provided, check type.
|
|
37
|
+
const typeMatches = Array.isArray(opt.type) ? opt.type.indexOf(typeof providedValue) != -1 : typeof providedValue == opt.type;
|
|
38
|
+
if (!typeMatches) {
|
|
39
|
+
throw new ApiError(ErrorCode.EINVAL, `${backend.name}: Value provided for option ${optName} is not the proper type. Expected ${Array.isArray(opt.type) ? `one of {${opt.type.join(', ')}}` : opt.type}, but received ${typeof providedValue}\nOption description: ${opt.description}`);
|
|
40
|
+
}
|
|
41
|
+
if (opt.validator) {
|
|
42
|
+
await opt.validator(providedValue);
|
|
43
|
+
}
|
|
44
|
+
// Otherwise: All good!
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export function createBackend(backend, options) {
|
|
48
|
+
checkOptions(backend, options);
|
|
49
|
+
const fs = backend.create(options);
|
|
50
|
+
return fs.ready();
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* @internal
|
|
54
|
+
*/
|
|
55
|
+
export function isBackendConfig(arg) {
|
|
56
|
+
return arg != null && typeof arg == 'object' && 'backend' in arg;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Retrieve a file system with the given configuration.
|
|
60
|
+
* @param config A BackendConfig object.
|
|
61
|
+
*/
|
|
62
|
+
export async function resolveBackendConfig(options) {
|
|
63
|
+
const { backend } = options;
|
|
64
|
+
if (!backend) {
|
|
65
|
+
throw new ApiError(ErrorCode.EPERM, 'Missing backend');
|
|
66
|
+
}
|
|
67
|
+
if (typeof options !== 'object' || options == null) {
|
|
68
|
+
throw new ApiError(ErrorCode.EINVAL, 'Invalid options on configuration object.');
|
|
69
|
+
}
|
|
70
|
+
const props = Object.keys(options).filter(k => k != 'backend');
|
|
71
|
+
for (const prop of props) {
|
|
72
|
+
let option = options[prop];
|
|
73
|
+
if (isBackend(option)) {
|
|
74
|
+
option = { backend: option };
|
|
75
|
+
}
|
|
76
|
+
if (isBackendConfig(option)) {
|
|
77
|
+
options[prop] = await resolveBackendConfig(option);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (!backend) {
|
|
81
|
+
throw new ApiError(ErrorCode.EPERM, `Backend "${backend}" is not available`);
|
|
82
|
+
}
|
|
83
|
+
return backend.create(options);
|
|
14
84
|
}
|
package/dist/backends/index.d.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { AsyncMirror } from './AsyncMirror.js';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { BackendConstructor } from './backend.js';
|
|
2
|
+
import { InMemory } from './InMemory.js';
|
|
3
|
+
import { Overlay } from './OverlayFS.js';
|
|
4
|
+
import { Backend } from './backend.js';
|
|
6
5
|
export declare const backends: {
|
|
7
|
-
[backend: string]:
|
|
6
|
+
[backend: string]: Backend;
|
|
8
7
|
};
|
|
9
8
|
export default backends;
|
|
10
|
-
export { AsyncMirror,
|
|
11
|
-
export declare function registerBackend(..._backends:
|
|
9
|
+
export { AsyncMirror, InMemory, Overlay };
|
|
10
|
+
export declare function registerBackend(..._backends: Backend[]): void;
|
package/dist/backends/index.js
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { AsyncMirror } from './AsyncMirror.js';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { OverlayFS } from './OverlayFS.js';
|
|
2
|
+
import { InMemory } from './InMemory.js';
|
|
3
|
+
import { Overlay } from './OverlayFS.js';
|
|
5
4
|
export const backends = {};
|
|
6
5
|
export default backends;
|
|
7
|
-
export { AsyncMirror,
|
|
6
|
+
export { AsyncMirror, InMemory, Overlay };
|
|
8
7
|
export function registerBackend(..._backends) {
|
|
9
8
|
for (const backend of _backends) {
|
|
10
|
-
backends[backend.
|
|
9
|
+
backends[backend.name] = backend;
|
|
11
10
|
}
|
|
12
11
|
}
|
|
13
|
-
registerBackend(AsyncMirror,
|
|
12
|
+
registerBackend(AsyncMirror, InMemory, Overlay);
|