@zenfs/core 0.9.2 → 0.9.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/dist/backends/Index.d.ts +3 -0
- package/dist/browser.min.js +3 -3
- package/dist/browser.min.js.map +3 -3
- package/dist/filesystem.d.ts +1 -1
- package/dist/filesystem.js +6 -6
- package/package.json +2 -9
- package/src/ApiError.ts +310 -0
- package/src/backends/AsyncStore.ts +635 -0
- package/src/backends/InMemory.ts +56 -0
- package/src/backends/Index.ts +500 -0
- package/src/backends/Locked.ts +181 -0
- package/src/backends/Overlay.ts +591 -0
- package/src/backends/SyncStore.ts +589 -0
- package/src/backends/backend.ts +152 -0
- package/src/config.ts +101 -0
- package/src/cred.ts +21 -0
- package/src/emulation/async.ts +910 -0
- package/src/emulation/constants.ts +176 -0
- package/src/emulation/dir.ts +139 -0
- package/src/emulation/index.ts +8 -0
- package/src/emulation/path.ts +468 -0
- package/src/emulation/promises.ts +1071 -0
- package/src/emulation/shared.ts +128 -0
- package/src/emulation/streams.ts +33 -0
- package/src/emulation/sync.ts +898 -0
- package/src/file.ts +721 -0
- package/src/filesystem.ts +544 -0
- package/src/index.ts +21 -0
- package/src/inode.ts +229 -0
- package/src/mutex.ts +52 -0
- package/src/stats.ts +385 -0
- package/src/utils.ts +287 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// Utilities and shared data
|
|
2
|
+
|
|
3
|
+
import { ApiError, ErrorCode } from '../ApiError.js';
|
|
4
|
+
import { InMemory } from '../backends/InMemory.js';
|
|
5
|
+
import { Cred, rootCred } from '../cred.js';
|
|
6
|
+
import type { File } from '../file.js';
|
|
7
|
+
import { FileSystem } from '../filesystem.js';
|
|
8
|
+
import { normalizePath } from '../utils.js';
|
|
9
|
+
import { resolve } from './path.js';
|
|
10
|
+
|
|
11
|
+
// credentials
|
|
12
|
+
export let cred: Cred = rootCred;
|
|
13
|
+
export function setCred(val: Cred): void {
|
|
14
|
+
cred = val;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// descriptors
|
|
18
|
+
export const fdMap: Map<number, File> = new Map();
|
|
19
|
+
let nextFd = 100;
|
|
20
|
+
export function getFdForFile(file: File): number {
|
|
21
|
+
const fd = nextFd++;
|
|
22
|
+
fdMap.set(fd, file);
|
|
23
|
+
return fd;
|
|
24
|
+
}
|
|
25
|
+
export function fd2file(fd: number): File {
|
|
26
|
+
if (!fdMap.has(fd)) {
|
|
27
|
+
throw new ApiError(ErrorCode.EBADF);
|
|
28
|
+
}
|
|
29
|
+
return fdMap.get(fd);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// mounting
|
|
33
|
+
export interface MountMapping {
|
|
34
|
+
[point: string]: FileSystem;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* The map of mount points
|
|
39
|
+
* @internal
|
|
40
|
+
*/
|
|
41
|
+
export const mounts: Map<string, FileSystem> = new Map();
|
|
42
|
+
|
|
43
|
+
/*
|
|
44
|
+
Set a default root.
|
|
45
|
+
*/
|
|
46
|
+
mount('/', InMemory.create({ name: 'root' }));
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Mounts the file system at the given mount point.
|
|
50
|
+
*/
|
|
51
|
+
export function mount(mountPoint: string, fs: FileSystem): void {
|
|
52
|
+
if (mountPoint[0] !== '/') {
|
|
53
|
+
mountPoint = '/' + mountPoint;
|
|
54
|
+
}
|
|
55
|
+
mountPoint = resolve(mountPoint);
|
|
56
|
+
if (mounts.has(mountPoint)) {
|
|
57
|
+
throw new ApiError(ErrorCode.EINVAL, 'Mount point ' + mountPoint + ' is already in use.');
|
|
58
|
+
}
|
|
59
|
+
mounts.set(mountPoint, fs);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Unmounts the file system at the given mount point.
|
|
64
|
+
*/
|
|
65
|
+
export function umount(mountPoint: string): void {
|
|
66
|
+
if (mountPoint[0] !== '/') {
|
|
67
|
+
mountPoint = `/${mountPoint}`;
|
|
68
|
+
}
|
|
69
|
+
mountPoint = resolve(mountPoint);
|
|
70
|
+
if (!mounts.has(mountPoint)) {
|
|
71
|
+
throw new ApiError(ErrorCode.EINVAL, 'Mount point ' + mountPoint + ' is already unmounted.');
|
|
72
|
+
}
|
|
73
|
+
mounts.delete(mountPoint);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Gets the internal FileSystem for the path, then returns it along with the path relative to the FS' root
|
|
78
|
+
*/
|
|
79
|
+
export function resolveMount(path: string): { fs: FileSystem; path: string; mountPoint: string } {
|
|
80
|
+
path = normalizePath(path);
|
|
81
|
+
const sortedMounts = [...mounts].sort((a, b) => (a[0].length > b[0].length ? -1 : 1)); // decending order of the string length
|
|
82
|
+
for (const [mountPoint, fs] of sortedMounts) {
|
|
83
|
+
// We know path is normalized, so it would be a substring of the mount point.
|
|
84
|
+
if (mountPoint.length <= path.length && path.startsWith(mountPoint)) {
|
|
85
|
+
path = path.slice(mountPoint.length > 1 ? mountPoint.length : 0); // Resolve the path relative to the mount point
|
|
86
|
+
if (path === '') {
|
|
87
|
+
path = '/';
|
|
88
|
+
}
|
|
89
|
+
return { fs, path, mountPoint };
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
throw new ApiError(ErrorCode.EIO, 'ZenFS not initialized with a file system');
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Reverse maps the paths in text from the mounted FileSystem to the global path
|
|
98
|
+
*/
|
|
99
|
+
export function fixPaths(text: string, paths: { [from: string]: string }): string {
|
|
100
|
+
for (const [from, to] of Object.entries(paths)) {
|
|
101
|
+
text = text?.replaceAll(from, to);
|
|
102
|
+
}
|
|
103
|
+
return text;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function fixError<E extends Error>(e: E, paths: { [from: string]: string }): E {
|
|
107
|
+
if (typeof e.stack == 'string') {
|
|
108
|
+
e.stack = fixPaths(e.stack, paths);
|
|
109
|
+
}
|
|
110
|
+
e.message = fixPaths(e.message, paths);
|
|
111
|
+
return e;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function mountMapping(mountMapping: MountMapping): void {
|
|
115
|
+
if ('/' in mountMapping) {
|
|
116
|
+
umount('/');
|
|
117
|
+
}
|
|
118
|
+
for (const [point, fs] of Object.entries(mountMapping)) {
|
|
119
|
+
mount(point, fs);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Types supports as path parameters.
|
|
125
|
+
*
|
|
126
|
+
* In the future, maybe support URL?
|
|
127
|
+
*/
|
|
128
|
+
export type PathLike = string;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type * as Node from 'fs';
|
|
2
|
+
import { Readable, Writable } from 'readable-stream';
|
|
3
|
+
import { Callback } from '../utils.js';
|
|
4
|
+
|
|
5
|
+
export class ReadStream extends Readable implements Node.ReadStream {
|
|
6
|
+
close(callback: Callback = () => null): void {
|
|
7
|
+
try {
|
|
8
|
+
super.destroy();
|
|
9
|
+
super.emit('close');
|
|
10
|
+
callback();
|
|
11
|
+
} catch (err) {
|
|
12
|
+
callback(err);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
bytesRead: number;
|
|
16
|
+
path: string | Buffer;
|
|
17
|
+
pending: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export class WriteStream extends Writable implements Node.WriteStream {
|
|
21
|
+
close(callback: Callback = () => null): void {
|
|
22
|
+
try {
|
|
23
|
+
super.destroy();
|
|
24
|
+
super.emit('close');
|
|
25
|
+
callback();
|
|
26
|
+
} catch (err) {
|
|
27
|
+
callback(err);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
bytesWritten: number;
|
|
31
|
+
path: string | Buffer;
|
|
32
|
+
pending: boolean;
|
|
33
|
+
}
|