@php-wasm/universal 3.0.54 → 3.1.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/index.cjs +24 -24
- package/index.cjs.map +1 -1
- package/index.js +1567 -944
- package/index.js.map +1 -1
- package/lib/api.d.ts +6 -4
- package/lib/comlink-node-process-adapter.d.ts +7 -0
- package/lib/emscripten-types.d.ts +3 -1
- package/lib/file-lock-interval-tree.d.ts +38 -0
- package/lib/file-lock-manager-composite.d.ts +14 -0
- package/lib/file-lock-manager-in-memory.d.ts +169 -0
- package/lib/file-lock-manager.d.ts +117 -0
- package/lib/index.d.ts +7 -0
- package/lib/object-pool-proxy.d.ts +30 -0
- package/lib/universal-php.d.ts +2 -1
- package/package.json +7 -10
package/lib/api.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { type NodeEndpoint, type Remote, type IsomorphicMessagePort } from './comlink-sync';
|
|
1
|
+
import { releaseProxy, type NodeEndpoint as NodeWorker, type Remote, type IsomorphicMessagePort, type ProxyMethods } from './comlink-sync';
|
|
2
|
+
import { type NodeProcess } from './comlink-node-process-adapter';
|
|
3
|
+
export declare const releaseApiProxy: typeof releaseProxy;
|
|
2
4
|
export type WithAPIState = {
|
|
3
5
|
/**
|
|
4
6
|
* Resolves to true when the remote API is ready for
|
|
@@ -11,9 +13,9 @@ export type WithAPIState = {
|
|
|
11
13
|
*/
|
|
12
14
|
isReady: () => Promise<void>;
|
|
13
15
|
};
|
|
14
|
-
export type RemoteAPI<T> = Remote<T> & WithAPIState;
|
|
16
|
+
export type RemoteAPI<T> = Remote<T> & ProxyMethods & WithAPIState;
|
|
15
17
|
export declare function consumeAPISync<APIType>(remote: IsomorphicMessagePort): Promise<APIType>;
|
|
16
|
-
export declare function consumeAPI<APIType>(remote: Worker | Window |
|
|
18
|
+
export declare function consumeAPI<APIType>(remote: Worker | Window | NodeWorker | NodeProcess, context?: undefined | EventTarget): RemoteAPI<APIType>;
|
|
17
19
|
export type PublicAPI<Methods, PipedAPI = unknown> = RemoteAPI<Methods & PipedAPI>;
|
|
18
|
-
export declare function exposeAPI<Methods, PipedAPI>(apiMethods?: Methods, pipedApi?: PipedAPI, targetWorker?:
|
|
20
|
+
export declare function exposeAPI<Methods, PipedAPI>(apiMethods?: Methods, pipedApi?: PipedAPI, targetWorker?: MessagePort | NodeWorker | NodeProcess): [() => void, (e: Error) => void, PublicAPI<Methods, PipedAPI>];
|
|
19
21
|
export declare function exposeSyncAPI<Methods>(apiMethods: Methods, port: IsomorphicMessagePort): Promise<[() => void, (e: Error) => void, Methods]>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Endpoint } from './comlink-sync';
|
|
2
|
+
export interface NodeProcess {
|
|
3
|
+
send: (...args: any[]) => unknown;
|
|
4
|
+
addListener: (type: string, listener: EventListenerOrEventListenerObject) => void;
|
|
5
|
+
removeListener: (type: string, listener: EventListenerOrEventListenerObject) => void;
|
|
6
|
+
}
|
|
7
|
+
export declare function nodeProcessEndpoint(worker?: NodeProcess): Endpoint;
|
|
@@ -116,7 +116,7 @@ export declare namespace Emscripten {
|
|
|
116
116
|
}
|
|
117
117
|
interface Mount {
|
|
118
118
|
type: Emscripten.FileSystemType;
|
|
119
|
-
opts:
|
|
119
|
+
opts: Record<string, any>;
|
|
120
120
|
mountpoint: string;
|
|
121
121
|
mounts: Mount[];
|
|
122
122
|
root: FSNode;
|
|
@@ -145,6 +145,7 @@ export declare namespace Emscripten {
|
|
|
145
145
|
write: boolean;
|
|
146
146
|
readonly isFolder: boolean;
|
|
147
147
|
readonly isDevice: boolean;
|
|
148
|
+
readonly isSharedFS?: boolean;
|
|
148
149
|
}
|
|
149
150
|
interface ErrnoError extends Error {
|
|
150
151
|
name: 'ErronoError';
|
|
@@ -220,6 +221,7 @@ export declare namespace Emscripten {
|
|
|
220
221
|
export const MEMFS: Emscripten.FileSystemType;
|
|
221
222
|
export const NODEFS: Emscripten.FileSystemType;
|
|
222
223
|
export const IDBFS: Emscripten.FileSystemType;
|
|
224
|
+
export const PROXYFS: Emscripten.FileSystemType;
|
|
223
225
|
type StringToType<R> = R extends Emscripten.JSType ? {
|
|
224
226
|
number: number;
|
|
225
227
|
string: string;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ByteRange, LockedRange, RequestedRangeLock } from './file-lock-manager';
|
|
2
|
+
export declare class FileLockIntervalTree {
|
|
3
|
+
private root;
|
|
4
|
+
isEmpty(): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Insert a new locked range into the tree
|
|
7
|
+
*/
|
|
8
|
+
insert(range: LockedRange): void;
|
|
9
|
+
/**
|
|
10
|
+
* Find all ranges that overlap with the given range
|
|
11
|
+
*/
|
|
12
|
+
findOverlapping(range: ByteRange): LockedRange[];
|
|
13
|
+
/**
|
|
14
|
+
* Remove a lock range from the tree
|
|
15
|
+
*/
|
|
16
|
+
remove(range: RequestedRangeLock): void;
|
|
17
|
+
/**
|
|
18
|
+
* Find all ranges locked by the given process.
|
|
19
|
+
*
|
|
20
|
+
* @param pid The process ID to find locks for.
|
|
21
|
+
* @returns All locked ranges for the given process.
|
|
22
|
+
*/
|
|
23
|
+
findLocksForProcess(pid: number): RequestedRangeLock[];
|
|
24
|
+
/**
|
|
25
|
+
* Find the strictest existing lock type in the range lock tree.
|
|
26
|
+
*
|
|
27
|
+
* @returns The strictest existing lock type, or 'unlocked' if no locks exist.
|
|
28
|
+
*/
|
|
29
|
+
findStrictestExistingLockType(): RequestedRangeLock['type'];
|
|
30
|
+
private insertNode;
|
|
31
|
+
private bigintMax;
|
|
32
|
+
private findOverlappingRanges;
|
|
33
|
+
private doRangesOverlap;
|
|
34
|
+
private removeNode;
|
|
35
|
+
private findMin;
|
|
36
|
+
private areRangesEqual;
|
|
37
|
+
private findLocksForProcessInNode;
|
|
38
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type Path, type RequestedRangeLock, type WholeFileLockOp, type FileLockManager } from './file-lock-manager';
|
|
2
|
+
export declare class FileLockManagerComposite implements FileLockManager {
|
|
3
|
+
nativeLockManager: FileLockManager;
|
|
4
|
+
wasmLockManager: FileLockManager;
|
|
5
|
+
constructor({ nativeLockManager, wasmLockManager, }: {
|
|
6
|
+
nativeLockManager: FileLockManager;
|
|
7
|
+
wasmLockManager: FileLockManager;
|
|
8
|
+
});
|
|
9
|
+
lockWholeFile(path: Path, op: WholeFileLockOp): boolean;
|
|
10
|
+
lockFileByteRange(path: Path, requestedLock: RequestedRangeLock, waitForLock: boolean): boolean;
|
|
11
|
+
findFirstConflictingByteRangeLock(path: Path, desiredLock: RequestedRangeLock): Omit<RequestedRangeLock, 'fd'> | undefined;
|
|
12
|
+
releaseLocksForProcess(pid: number): void;
|
|
13
|
+
releaseLocksOnFdClose(pid: number, fd: number, path: Path): void;
|
|
14
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import type { FileLockManager, RequestedRangeLock, WholeFileLockOp, Pid, Fd } from './file-lock-manager';
|
|
2
|
+
import { type LockedRange } from './file-lock-manager';
|
|
3
|
+
/**
|
|
4
|
+
* This is the file lock manager for use within JS runtimes like Node.js.
|
|
5
|
+
*
|
|
6
|
+
* A FileLockManagerInMemory is a wrapper around a Map of FileLock instances.
|
|
7
|
+
* It provides methods for locking and unlocking files, as well as finding conflicting locks.
|
|
8
|
+
*/
|
|
9
|
+
export declare class FileLockManagerInMemory implements FileLockManager {
|
|
10
|
+
locks: Map<string, FileLock>;
|
|
11
|
+
/**
|
|
12
|
+
* Create a new FileLockManagerInMemory instance.
|
|
13
|
+
*
|
|
14
|
+
* @param nativeFlockSync A synchronous flock() function to lock files via the host OS.
|
|
15
|
+
*/
|
|
16
|
+
constructor();
|
|
17
|
+
/**
|
|
18
|
+
* Lock the whole file.
|
|
19
|
+
*
|
|
20
|
+
* @param path The path to the file to lock. This should be the path
|
|
21
|
+
* of the file in the native filesystem.
|
|
22
|
+
* @param op The whole file lock operation to perform.
|
|
23
|
+
* @returns True if the lock was granted, false otherwise.
|
|
24
|
+
*/
|
|
25
|
+
lockWholeFile(path: string,
|
|
26
|
+
/**
|
|
27
|
+
* NOTE: FileLockManagerInMemory does not support waiting for a lock
|
|
28
|
+
* because it is intended to be used with a native file lock manager
|
|
29
|
+
* which does support waiting.
|
|
30
|
+
*/
|
|
31
|
+
op: Omit<WholeFileLockOp, 'waitForLock'>): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Lock a byte range.
|
|
34
|
+
*
|
|
35
|
+
* @param path The path to the file to lock. This should be the path
|
|
36
|
+
* of the file in the native filesystem.
|
|
37
|
+
* @param requestedLock The byte range lock to perform.
|
|
38
|
+
* @returns True if the lock was granted, false otherwise.
|
|
39
|
+
*/
|
|
40
|
+
lockFileByteRange(path: string,
|
|
41
|
+
/**
|
|
42
|
+
* NOTE: fcntl()-style F_SETLK/F_GETLK do not associate
|
|
43
|
+
* resulting locks with a file descrtiptor, so we ignore fd here.
|
|
44
|
+
*/
|
|
45
|
+
requestedLock: Omit<RequestedRangeLock, 'fd'>
|
|
46
|
+
/**
|
|
47
|
+
* NOTE: FileLockManagerInMemory does not support waiting for a lock
|
|
48
|
+
* because it is intended to be used with a native file lock manager
|
|
49
|
+
* which does support waiting.
|
|
50
|
+
*/
|
|
51
|
+
): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Find the first conflicting byte range lock.
|
|
54
|
+
*
|
|
55
|
+
* @param path The path to the file to find the conflicting lock for.
|
|
56
|
+
* @param desiredLock The desired byte range lock.
|
|
57
|
+
* @returns The first conflicting byte range lock, or undefined if no conflicting lock exists.
|
|
58
|
+
*/
|
|
59
|
+
findFirstConflictingByteRangeLock(path: string,
|
|
60
|
+
/**
|
|
61
|
+
* NOTE: fcntl()-style F_SETLK/F_GETLK do not associate
|
|
62
|
+
* resulting locks with a file descrtiptor, so we ignore fd here.
|
|
63
|
+
*/
|
|
64
|
+
desiredLock: Omit<RequestedRangeLock, 'fd'>): Omit<RequestedRangeLock, 'fd'> | undefined;
|
|
65
|
+
/**
|
|
66
|
+
* Release all locks for the given process.
|
|
67
|
+
*
|
|
68
|
+
* @param pid The process ID to release locks for.
|
|
69
|
+
*/
|
|
70
|
+
releaseLocksForProcess(pid: number): void;
|
|
71
|
+
/**
|
|
72
|
+
* Release all locks for the given process and file descriptor.
|
|
73
|
+
*
|
|
74
|
+
* @param pid The process ID to release locks for.
|
|
75
|
+
* @param fd The file descriptor to release locks for.
|
|
76
|
+
* @param path The path to the file to release locks for.
|
|
77
|
+
*/
|
|
78
|
+
releaseLocksOnFdClose(pid: number, fd: number, nativePath: string): void;
|
|
79
|
+
/**
|
|
80
|
+
* Forget the path if it is unlocked.
|
|
81
|
+
*
|
|
82
|
+
* @param path The path to the file to forget.
|
|
83
|
+
*/
|
|
84
|
+
private forgetPathIfUnlocked;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* A FileLock instance encapsulates a native whole-file lock and file locking between
|
|
88
|
+
* php-wasm processes.
|
|
89
|
+
*
|
|
90
|
+
* A FileLock supports php-wasm whole-file locks and byte range locks.
|
|
91
|
+
* Before granting a php-wasm lock, a FileLock ensures that it first holds a compatible
|
|
92
|
+
* native lock. If a compatible native lock cannot be acquired, the php-wasm lock is
|
|
93
|
+
* not granted.
|
|
94
|
+
*/
|
|
95
|
+
export declare class FileLock {
|
|
96
|
+
private wholeFileLock;
|
|
97
|
+
private rangeLocks;
|
|
98
|
+
constructor();
|
|
99
|
+
/**
|
|
100
|
+
* Lock the whole file.
|
|
101
|
+
*
|
|
102
|
+
* This method corresponds to the flock() function.
|
|
103
|
+
*
|
|
104
|
+
* @param op The whole file lock operation to perform.
|
|
105
|
+
* @returns True if the lock was granted, false otherwise.
|
|
106
|
+
*/
|
|
107
|
+
lockWholeFile(op: Omit<WholeFileLockOp, 'waitForLock'>): boolean;
|
|
108
|
+
/**
|
|
109
|
+
* Lock a byte range.
|
|
110
|
+
*
|
|
111
|
+
* This method corresponds to the fcntl() F_SETLK command.
|
|
112
|
+
*
|
|
113
|
+
* @param requestedLock The byte range lock to perform.
|
|
114
|
+
* @returns True if the lock was granted, false otherwise.
|
|
115
|
+
*/
|
|
116
|
+
lockFileByteRange(requestedLock: Omit<RequestedRangeLock, 'fd' | 'waitForLock'>): boolean;
|
|
117
|
+
/**
|
|
118
|
+
* Find the first conflicting byte range lock.
|
|
119
|
+
*
|
|
120
|
+
* This method corresponds to the fcntl() F_GETLK command.
|
|
121
|
+
*
|
|
122
|
+
* @param desiredLock The desired byte range lock.
|
|
123
|
+
* @returns The first conflicting byte range lock, or undefined if no conflicting lock exists.
|
|
124
|
+
*/
|
|
125
|
+
findFirstConflictingByteRangeLock(
|
|
126
|
+
/**
|
|
127
|
+
* NOTE: fcntl()-style F_SETLK/F_GETLK do not associate
|
|
128
|
+
* resulting locks with a file descrtiptor, so we ignore fd here.
|
|
129
|
+
*/
|
|
130
|
+
desiredLock: Omit<RequestedRangeLock, 'fd'>): LockedRange | {
|
|
131
|
+
type: "shared" | "exclusive";
|
|
132
|
+
start: bigint;
|
|
133
|
+
end: bigint;
|
|
134
|
+
pid: number;
|
|
135
|
+
} | undefined;
|
|
136
|
+
/**
|
|
137
|
+
* Release all locks for the given process.
|
|
138
|
+
*
|
|
139
|
+
* @param pid The process ID to release locks for.
|
|
140
|
+
*/
|
|
141
|
+
releaseLocksForProcess(pid: Pid): void;
|
|
142
|
+
/**
|
|
143
|
+
* Release all locks for the given process and file descriptor.
|
|
144
|
+
*
|
|
145
|
+
* @param pid The process ID to release locks for.
|
|
146
|
+
* @param fd The file descriptor to release locks for.
|
|
147
|
+
*/
|
|
148
|
+
releaseLocksOnFdClose(pid: Pid, fd: Fd): void;
|
|
149
|
+
/**
|
|
150
|
+
* Check if the file lock is unlocked.
|
|
151
|
+
*
|
|
152
|
+
* @returns True if the file lock is unlocked, false otherwise.
|
|
153
|
+
*/
|
|
154
|
+
isUnlocked(): boolean;
|
|
155
|
+
/**
|
|
156
|
+
* Check if a lock exists that conflicts with the requested range lock.
|
|
157
|
+
*
|
|
158
|
+
* @param requestedLock The desired byte range lock.
|
|
159
|
+
* @returns True if a conflicting lock exists, false otherwise.
|
|
160
|
+
*/
|
|
161
|
+
private isThereAConflictWithRequestedRangeLock;
|
|
162
|
+
/**
|
|
163
|
+
* Check if a lock exists that conflicts with the requested whole-file lock.
|
|
164
|
+
*
|
|
165
|
+
* @param requestedLock The desired whole-file lock.
|
|
166
|
+
* @returns True if a conflicting lock exists, false otherwise.
|
|
167
|
+
*/
|
|
168
|
+
private isThereAConflictWithRequestedWholeFileLock;
|
|
169
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
export declare const MAX_ADDRESSABLE_FILE_OFFSET: bigint;
|
|
2
|
+
export type Path = string;
|
|
3
|
+
export type Pid = number;
|
|
4
|
+
export type Fd = number;
|
|
5
|
+
/**
|
|
6
|
+
* This is an interface used to abstract byte range locking like fcntl()
|
|
7
|
+
* and whole-file locking like flock().
|
|
8
|
+
*/
|
|
9
|
+
export type FileLockManager = {
|
|
10
|
+
/**
|
|
11
|
+
* Update the lock on the whole file.
|
|
12
|
+
*
|
|
13
|
+
* This method is for updating the lock on the whole file with the F_SETLKW fcntl() command.
|
|
14
|
+
* https://sourceware.org/glibc/manual/2.41/html_node/File-Locks.html#index-F_005fSETLKW-1
|
|
15
|
+
*
|
|
16
|
+
* @param path - The path of the file to lock. This should be the path of the file in the
|
|
17
|
+
* underlying filesystem.
|
|
18
|
+
* @param op - The operation to perform, including 'shared', 'exclusive', or 'unlock'.
|
|
19
|
+
* @returns A promise for a boolean value.
|
|
20
|
+
*/
|
|
21
|
+
lockWholeFile: (path: Path, op: WholeFileLockOp) => boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Update the lock on a byte range of a file.
|
|
24
|
+
*
|
|
25
|
+
* This method is for locking with the F_SETLK fcntl() command.
|
|
26
|
+
* https://sourceware.org/glibc/manual/2.41/html_node/File-Locks.html#index-F_005fSETLK-1
|
|
27
|
+
*
|
|
28
|
+
* @param path - The path of the file to lock. This should be the path of the file in the
|
|
29
|
+
* underlying filesystem.
|
|
30
|
+
* @param requestedLock - The lock to request, including start, end, type, and pid.
|
|
31
|
+
* @param waitForLock - Whether to block until the lock is acquired.
|
|
32
|
+
* @returns A promise for a boolean value.
|
|
33
|
+
* When locking: True if the lock was acquired, false if it was not.
|
|
34
|
+
* When unlocking: Always true.
|
|
35
|
+
*/
|
|
36
|
+
lockFileByteRange: (path: Path, requestedLock: RequestedRangeLock, waitForLock: boolean) => boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Get the first lock that would conflict with the specified lock.
|
|
39
|
+
*
|
|
40
|
+
* This method is meant to satisfy the needs of the F_GETLK fcntl() command.
|
|
41
|
+
* https://sourceware.org/glibc/manual/2.41/html_node/File-Locks.html#index-F_005fGETLK-1
|
|
42
|
+
*
|
|
43
|
+
* @param path - The path of the file to check for conflicts. This should be the path
|
|
44
|
+
* of the file in the underlying filesystem.
|
|
45
|
+
* @param desiredLock - The lock to check for conflicts.
|
|
46
|
+
* @returns A promise for the first conflicting lock,
|
|
47
|
+
* or undefined if there is no conflict.
|
|
48
|
+
*/
|
|
49
|
+
findFirstConflictingByteRangeLock: (path: Path, desiredLock: RequestedRangeLock) => Omit<RequestedRangeLock, 'fd'> | undefined;
|
|
50
|
+
/**
|
|
51
|
+
* Release all locks for a given process.
|
|
52
|
+
*
|
|
53
|
+
* Used when a process exits or is otherwise terminated.
|
|
54
|
+
*
|
|
55
|
+
* @param pid - The PID of the process that wants to release the locks.
|
|
56
|
+
*/
|
|
57
|
+
releaseLocksForProcess: (pid: number) => void;
|
|
58
|
+
/**
|
|
59
|
+
* Release all locks for the given process and file descriptor.
|
|
60
|
+
*
|
|
61
|
+
* @param pid The process ID to release locks for.
|
|
62
|
+
* @param fd The file descriptor to release locks for.
|
|
63
|
+
* @param path The path to the file to release locks for. This should be the path
|
|
64
|
+
* of the file in the underlying filesystem.
|
|
65
|
+
*/
|
|
66
|
+
releaseLocksOnFdClose: (pid: number, fd: number, path: Path) => void;
|
|
67
|
+
};
|
|
68
|
+
export type ByteRange = {
|
|
69
|
+
start: bigint;
|
|
70
|
+
end: bigint;
|
|
71
|
+
};
|
|
72
|
+
export type RequestedRangeLock = ByteRange & {
|
|
73
|
+
/**
|
|
74
|
+
* The type of lock request
|
|
75
|
+
*/
|
|
76
|
+
type: 'shared' | 'exclusive' | 'unlocked';
|
|
77
|
+
/**
|
|
78
|
+
* The file descriptor to use. This should be the native file descriptor,
|
|
79
|
+
* not the Emscripten file descriptor because it may be used to lock the file
|
|
80
|
+
* using native OS file locking APIs.
|
|
81
|
+
*/
|
|
82
|
+
fd: Fd;
|
|
83
|
+
/** The process ID that owns this lock */
|
|
84
|
+
pid: Pid;
|
|
85
|
+
};
|
|
86
|
+
export type LockedRange = RequestedRangeLock & {
|
|
87
|
+
type: Exclude<RequestedRangeLock['type'], 'unlocked'>;
|
|
88
|
+
};
|
|
89
|
+
export type ConflictingLockedRange = Omit<LockedRange, 'fd'>;
|
|
90
|
+
export type WholeFileLock = Readonly<WholeFileLock_Exclusive | WholeFileLock_Shared | WholeFileLock_Unlocked>;
|
|
91
|
+
export type WholeFileLock_Exclusive = {
|
|
92
|
+
type: 'exclusive';
|
|
93
|
+
pid: Pid;
|
|
94
|
+
fd: Fd;
|
|
95
|
+
};
|
|
96
|
+
export type WholeFileLock_Shared = {
|
|
97
|
+
type: 'shared';
|
|
98
|
+
/**
|
|
99
|
+
* NOTE: flock() locks are associated with open file descriptors and duplicated file descriptors.
|
|
100
|
+
* We do not currently recognize duplicate file descriptors.
|
|
101
|
+
*/
|
|
102
|
+
pidFds: Map<Pid, Set<Fd>>;
|
|
103
|
+
};
|
|
104
|
+
export type WholeFileLock_Unlocked = {
|
|
105
|
+
type: 'unlocked';
|
|
106
|
+
};
|
|
107
|
+
export type WholeFileLockOp = {
|
|
108
|
+
pid: number;
|
|
109
|
+
fd: number;
|
|
110
|
+
type: 'shared' | 'exclusive';
|
|
111
|
+
/** Whether to block until the lock is acquired. */
|
|
112
|
+
waitForLock: boolean;
|
|
113
|
+
} | {
|
|
114
|
+
pid: number;
|
|
115
|
+
fd: number;
|
|
116
|
+
type: 'unlock';
|
|
117
|
+
};
|
package/lib/index.d.ts
CHANGED
|
@@ -40,4 +40,11 @@ export { proxyFileSystem, isPathToSharedFS } from './proxy-file-system';
|
|
|
40
40
|
export { sandboxedSpawnHandlerFactory } from './sandboxed-spawn-handler-factory';
|
|
41
41
|
export * from './api';
|
|
42
42
|
export type { WithAPIState as WithIsReady } from './api';
|
|
43
|
+
export type { NodeProcess } from './comlink-node-process-adapter';
|
|
44
|
+
export * from './file-lock-manager';
|
|
45
|
+
export * from './file-lock-manager-in-memory';
|
|
46
|
+
export * from './file-lock-manager-composite';
|
|
47
|
+
export * from './file-lock-interval-tree';
|
|
43
48
|
export type { Remote } from './comlink-sync';
|
|
49
|
+
export { createObjectPoolProxy } from './object-pool-proxy';
|
|
50
|
+
export type { Pooled } from './object-pool-proxy';
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts an object type to a promisified version where:
|
|
3
|
+
* - Methods return `Promise<Awaited<ReturnType>>` (no double-wrapping)
|
|
4
|
+
* - Properties become `Promise<Awaited<PropertyType>>`
|
|
5
|
+
*/
|
|
6
|
+
type Promisified<T extends object> = {
|
|
7
|
+
[K in keyof T]: T[K] extends (...args: infer A) => infer R ? (...args: A) => Promise<Awaited<R>> : Promise<Awaited<T[K]>>;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* The type returned by `createObjectPoolProxy`. All method calls and
|
|
11
|
+
* property accesses are wrapped in promises because acquiring a free
|
|
12
|
+
* pool instance is inherently async.
|
|
13
|
+
*
|
|
14
|
+
* Dispose/asyncDispose symbols are omitted because the pool proxy
|
|
15
|
+
* forwards calls to a single random instance — disposing one
|
|
16
|
+
* instance out of the pool is never the intended behavior. Pool
|
|
17
|
+
* lifecycle should be managed by the code that created the pool.
|
|
18
|
+
*/
|
|
19
|
+
export type Pooled<T extends object> = Omit<Promisified<T>, typeof Symbol.dispose | typeof Symbol.asyncDispose>;
|
|
20
|
+
/**
|
|
21
|
+
* Creates a proxy that distributes method calls and property accesses
|
|
22
|
+
* across a pool of object instances. Only one ongoing access per
|
|
23
|
+
* instance is allowed at a time. If all instances are busy, accesses
|
|
24
|
+
* wait until one becomes free.
|
|
25
|
+
*
|
|
26
|
+
* The returned proxy provides a promisified version of the original
|
|
27
|
+
* interface: method calls and property accesses all return promises.
|
|
28
|
+
*/
|
|
29
|
+
export declare function createObjectPoolProxy<T extends object>(instances: T[]): Pooled<T>;
|
|
30
|
+
export {};
|
package/lib/universal-php.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Remote } from './comlink-sync';
|
|
2
|
+
import type { Pooled } from './object-pool-proxy';
|
|
2
3
|
import type { LimitedPHPApi } from './php-worker';
|
|
3
4
|
/**
|
|
4
5
|
* Represents an event related to the PHP request.
|
|
@@ -43,7 +44,7 @@ export type PHPEvent = PHPRequestEndEvent | PHPRequestErrorEvent | PHPRuntimeIni
|
|
|
43
44
|
* A callback function that handles PHP events.
|
|
44
45
|
*/
|
|
45
46
|
export type PHPEventListener = (event: PHPEvent) => void;
|
|
46
|
-
export type UniversalPHP = LimitedPHPApi | Remote<LimitedPHPApi>;
|
|
47
|
+
export type UniversalPHP = LimitedPHPApi | Remote<LimitedPHPApi> | Pooled<LimitedPHPApi>;
|
|
47
48
|
export type MessageListener = (data: string) => Promise<string | Uint8Array | void> | string | void;
|
|
48
49
|
export interface EventEmitter {
|
|
49
50
|
on(event: string, listener: (...args: any[]) => void): this;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@php-wasm/universal",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.1",
|
|
4
4
|
"description": "PHP.wasm – emscripten bindings for PHP",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -37,18 +37,18 @@
|
|
|
37
37
|
"module": "./index.js",
|
|
38
38
|
"types": "index.d.ts",
|
|
39
39
|
"license": "GPL-2.0-or-later",
|
|
40
|
-
"gitHead": "
|
|
40
|
+
"gitHead": "71560d81fcde96435d5730a0430abcafaa6f92b8",
|
|
41
41
|
"engines": {
|
|
42
42
|
"node": ">=20.10.0",
|
|
43
43
|
"npm": ">=10.2.3"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"ini": "4.1.2",
|
|
47
|
-
"@php-wasm/node-polyfills": "3.
|
|
48
|
-
"@php-wasm/logger": "3.
|
|
49
|
-
"@php-wasm/util": "3.
|
|
50
|
-
"@php-wasm/stream-compression": "3.
|
|
51
|
-
"@php-wasm/progress": "3.
|
|
47
|
+
"@php-wasm/node-polyfills": "3.1.1",
|
|
48
|
+
"@php-wasm/logger": "3.1.1",
|
|
49
|
+
"@php-wasm/util": "3.1.1",
|
|
50
|
+
"@php-wasm/stream-compression": "3.1.1",
|
|
51
|
+
"@php-wasm/progress": "3.1.1"
|
|
52
52
|
},
|
|
53
53
|
"packageManager": "npm@10.9.2",
|
|
54
54
|
"overrides": {
|
|
@@ -62,8 +62,5 @@
|
|
|
62
62
|
"form-data": "^4.0.4",
|
|
63
63
|
"lodash": "^4.17.23",
|
|
64
64
|
"glob": "^9.3.0"
|
|
65
|
-
},
|
|
66
|
-
"optionalDependencies": {
|
|
67
|
-
"fs-ext": "2.1.1"
|
|
68
65
|
}
|
|
69
66
|
}
|