@php-wasm/node 1.1.3 → 1.1.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.
Files changed (40) hide show
  1. package/asyncify/7_2_34/php_7_2.wasm +0 -0
  2. package/asyncify/7_3_33/php_7_3.wasm +0 -0
  3. package/asyncify/7_4_33/php_7_4.wasm +0 -0
  4. package/asyncify/8_0_30/php_8_0.wasm +0 -0
  5. package/asyncify/8_1_23/php_8_1.wasm +0 -0
  6. package/asyncify/8_2_10/php_8_2.wasm +0 -0
  7. package/asyncify/8_3_0/php_8_3.wasm +0 -0
  8. package/asyncify/8_4_0/php_8_4.wasm +0 -0
  9. package/asyncify/php_7_2.js +178 -138
  10. package/asyncify/php_7_3.js +177 -137
  11. package/asyncify/php_7_4.js +176 -136
  12. package/asyncify/php_8_0.js +180 -140
  13. package/asyncify/php_8_1.js +179 -139
  14. package/asyncify/php_8_2.js +180 -140
  15. package/asyncify/php_8_3.js +180 -140
  16. package/asyncify/php_8_4.js +179 -139
  17. package/fs_ext.node +0 -0
  18. package/index.cjs +9170 -3617
  19. package/index.js +9054 -3617
  20. package/jspi/7_2_34/php_7_2.wasm +0 -0
  21. package/jspi/7_3_33/php_7_3.wasm +0 -0
  22. package/jspi/7_4_33/php_7_4.wasm +0 -0
  23. package/jspi/8_0_30/php_8_0.wasm +0 -0
  24. package/jspi/8_1_23/php_8_1.wasm +0 -0
  25. package/jspi/8_2_10/php_8_2.wasm +0 -0
  26. package/jspi/8_3_0/php_8_3.wasm +0 -0
  27. package/jspi/8_4_0/php_8_4.wasm +0 -0
  28. package/jspi/php_7_2.js +1922 -1286
  29. package/jspi/php_7_3.js +1922 -1286
  30. package/jspi/php_7_4.js +9262 -7705
  31. package/jspi/php_8_0.js +1922 -1286
  32. package/jspi/php_8_1.js +2434 -1798
  33. package/jspi/php_8_2.js +2414 -1778
  34. package/jspi/php_8_3.js +2414 -1778
  35. package/jspi/php_8_4.js +2414 -1778
  36. package/lib/file-lock-manager-for-node.d.ts +149 -0
  37. package/lib/file-lock-manager.d.ts +96 -0
  38. package/lib/index.d.ts +2 -0
  39. package/lib/load-runtime.d.ts +31 -2
  40. package/package.json +10 -9
@@ -0,0 +1,149 @@
1
+ import type { FileLockManager, RequestedRangeLock, WholeFileLock, WholeFileLockOp, Pid, Fd } from './file-lock-manager';
2
+ /**
3
+ * This is the file lock manager for use within JS runtimes like Node.js.
4
+ *
5
+ * A FileLockManagerForNode is a wrapper around a Map of FileLock instances.
6
+ * It provides methods for locking and unlocking files, as well as finding conflicting locks.
7
+ */
8
+ export declare class FileLockManagerForNode implements FileLockManager {
9
+ locks: Map<string, FileLock>;
10
+ constructor();
11
+ /**
12
+ * Lock the whole file.
13
+ *
14
+ * @param path The path to the file to lock. This should be the path
15
+ * of the file in the native filesystem.
16
+ * @param op The whole file lock operation to perform.
17
+ * @returns True if the lock was granted, false otherwise.
18
+ */
19
+ lockWholeFile(path: string, op: WholeFileLockOp): boolean;
20
+ /**
21
+ * Lock a byte range.
22
+ *
23
+ * @param path The path to the file to lock. This should be the path
24
+ * of the file in the native filesystem.
25
+ * @param requestedLock The byte range lock to perform.
26
+ * @returns True if the lock was granted, false otherwise.
27
+ */
28
+ lockFileByteRange(path: string, requestedLock: RequestedRangeLock): boolean;
29
+ /**
30
+ * Find the first conflicting byte range lock.
31
+ *
32
+ * @param path The path to the file to find the conflicting lock for.
33
+ * @param desiredLock The desired byte range lock.
34
+ * @returns The first conflicting byte range lock, or undefined if no conflicting lock exists.
35
+ */
36
+ findFirstConflictingByteRangeLock(path: string, desiredLock: RequestedRangeLock): Omit<RequestedRangeLock, 'fd'> | undefined;
37
+ /**
38
+ * Release all locks for the given process.
39
+ *
40
+ * @param pid The process ID to release locks for.
41
+ */
42
+ releaseLocksForProcess(pid: number): void;
43
+ /**
44
+ * Release all locks for the given process and file descriptor.
45
+ *
46
+ * @param pid The process ID to release locks for.
47
+ * @param fd The file descriptor to release locks for.
48
+ * @param path The path to the file to release locks for.
49
+ */
50
+ releaseLocksForProcessFd(pid: number, fd: number, nativePath: string): void;
51
+ /**
52
+ * Forget the path if it is unlocked.
53
+ *
54
+ * @param path The path to the file to forget.
55
+ */
56
+ private forgetPathIfUnlocked;
57
+ }
58
+ /**
59
+ * A FileLock instance encapsulates a native whole-file lock and file locking between
60
+ * php-wasm processes.
61
+ *
62
+ * A FileLock supports php-wasm whole-file locks and byte range locks.
63
+ * Before granting a php-wasm lock, a FileLock ensures that it first holds a compatible
64
+ * native lock. If a compatible native lock cannot be acquired, the php-wasm lock is
65
+ * not granted.
66
+ */
67
+ export declare class FileLock {
68
+ /**
69
+ * Create a new FileLock instance for the given file and mode.
70
+ * Fail if the underlying native file lock cannot be acquired.
71
+ *
72
+ * @param path The path to the file to lock
73
+ * @param mode The type of lock to acquire
74
+ * @returns A FileLock instance if the lock was acquired, undefined otherwise
75
+ */
76
+ static maybeCreate(path: string, mode: Exclude<WholeFileLock['type'], 'unlocked'>): FileLock | undefined;
77
+ private nativeLock;
78
+ private wholeFileLock;
79
+ private rangeLocks;
80
+ private constructor();
81
+ /**
82
+ * Close the file descriptor and release the native lock.
83
+ *
84
+ * @TODO Replace this with a Symbol.dispose property once supported by all JS runtimes.
85
+ */
86
+ dispose(): void;
87
+ /**
88
+ * Lock the whole file.
89
+ *
90
+ * This method corresponds to the flock() function.
91
+ *
92
+ * @param op The whole file lock operation to perform.
93
+ * @returns True if the lock was granted, false otherwise.
94
+ */
95
+ lockWholeFile(op: WholeFileLockOp): boolean;
96
+ /**
97
+ * Lock a byte range.
98
+ *
99
+ * This method corresponds to the fcntl() F_SETLK command.
100
+ *
101
+ * @param requestedLock The byte range lock to perform.
102
+ * @returns True if the lock was granted, false otherwise.
103
+ */
104
+ lockFileByteRange(requestedLock: RequestedRangeLock): boolean;
105
+ /**
106
+ * Find the first conflicting byte range lock.
107
+ *
108
+ * This method corresponds to the fcntl() F_GETLK command.
109
+ *
110
+ * @param desiredLock The desired byte range lock.
111
+ * @returns The first conflicting byte range lock, or undefined if no conflicting lock exists.
112
+ */
113
+ findFirstConflictingByteRangeLock(desiredLock: RequestedRangeLock): RequestedRangeLock | undefined;
114
+ /**
115
+ * Release all locks for the given process.
116
+ *
117
+ * @param pid The process ID to release locks for.
118
+ */
119
+ releaseLocksForProcess(pid: Pid): void;
120
+ /**
121
+ * Release all locks for the given process and file descriptor.
122
+ *
123
+ * @param pid The process ID to release locks for.
124
+ * @param fd The file descriptor to release locks for.
125
+ */
126
+ releaseLocksForProcessFd(pid: Pid, fd: Fd): void;
127
+ /**
128
+ * Check if the file lock is unlocked.
129
+ *
130
+ * @returns True if the file lock is unlocked, false otherwise.
131
+ */
132
+ isUnlocked(): boolean;
133
+ /**
134
+ * Ensure that the native lock is compatible with the php-wasm lock,
135
+ * upgrading or downgrading as needed.
136
+ *
137
+ * @param overrideWholeFileLockType If provided, use this type for the whole file lock.
138
+ * @param overrideRangeLockType If provided, use this type for the range lock.
139
+ * @returns True if the native lock was upgraded or downgraded, false otherwise.
140
+ */
141
+ private ensureCompatibleNativeLock;
142
+ /**
143
+ * Check if a conflicting lock exists.
144
+ *
145
+ * @param requestedLock The desired byte range lock.
146
+ * @returns True if a conflicting lock exists, false otherwise.
147
+ */
148
+ private doesAConflictingLockExist;
149
+ }
@@ -0,0 +1,96 @@
1
+ /**
2
+ * This is an interface used to abstract byte range locking like fcntl()
3
+ * and whole-file locking like flock().
4
+ */
5
+ export type FileLockManager = {
6
+ /**
7
+ * Update the lock on the whole file.
8
+ *
9
+ * This method is for updating the lock on the whole file with the F_SETLKW fcntl() command.
10
+ * https://sourceware.org/glibc/manual/2.41/html_node/File-Locks.html#index-F_005fSETLKW-1
11
+ *
12
+ * @param path - The path of the file to lock. This should be the path of the file in the
13
+ * underlying filesystem.
14
+ * @param op - The operation to perform, including 'shared', 'exclusive', or 'unlock'.
15
+ * @returns A promise for a boolean value.
16
+ */
17
+ lockWholeFile: (path: string, op: WholeFileLockOp) => boolean;
18
+ /**
19
+ * Update the lock on a byte range of a file.
20
+ *
21
+ * This method is for locking with the F_SETLK fcntl() command.
22
+ * https://sourceware.org/glibc/manual/2.41/html_node/File-Locks.html#index-F_005fSETLK-1
23
+ *
24
+ * @param path - The path of the file to lock. This should be the path of the file in the
25
+ * underlying filesystem.
26
+ * @param requestedLock - The lock to request, including start, end, type, and pid.
27
+ * @returns A promise for a boolean value.
28
+ * When locking: True if the lock was acquired, false if it was not.
29
+ * When unlocking: Always true.
30
+ */
31
+ lockFileByteRange: (path: string, requestedLock: RequestedRangeLock) => boolean;
32
+ /**
33
+ * Get the first lock that would conflict with the specified lock.
34
+ *
35
+ * This method is meant to satisfy the needs of the F_GETLK fcntl() command.
36
+ * https://sourceware.org/glibc/manual/2.41/html_node/File-Locks.html#index-F_005fGETLK-1
37
+ *
38
+ * @param path - The path of the file to check for conflicts. This should be the path
39
+ * of the file in the underlying filesystem.
40
+ * @param desiredLock - The lock to check for conflicts.
41
+ * @returns A promise for the first conflicting lock,
42
+ * or undefined if there is no conflict.
43
+ */
44
+ findFirstConflictingByteRangeLock: (path: string, desiredLock: RequestedRangeLock) => Omit<RequestedRangeLock, 'fd'> | undefined;
45
+ /**
46
+ * Release all locks for a given process.
47
+ *
48
+ * Used when a process exits or is otherwise terminated.
49
+ *
50
+ * @param pid - The PID of the process that wants to release the locks.
51
+ */
52
+ releaseLocksForProcess: (pid: number) => void;
53
+ /**
54
+ * Release all locks for the given process and file descriptor.
55
+ *
56
+ * @param pid The process ID to release locks for.
57
+ * @param fd The file descriptor to release locks for.
58
+ * @param path The path to the file to release locks for. This should be the path
59
+ * of the file in the underlying filesystem.
60
+ */
61
+ releaseLocksForProcessFd: (pid: number, fd: number, path: string) => void;
62
+ };
63
+ export type RequestedRangeLock = Readonly<{
64
+ /** The type of lock request */
65
+ type: 'shared' | 'exclusive' | 'unlocked';
66
+ /** The start offset of the lock range */
67
+ start: bigint;
68
+ /** The end of the lock range */
69
+ end: bigint;
70
+ /** The process ID that owns this lock */
71
+ pid: Pid;
72
+ }>;
73
+ export type WholeFileLock = Readonly<WholeFileLock_Exclusive | WholeFileLock_Shared | WholeFileLock_Unlocked>;
74
+ export type Pid = number;
75
+ export type Fd = number;
76
+ export type WholeFileLock_Exclusive = {
77
+ type: 'exclusive';
78
+ pid: Pid;
79
+ fd: Fd;
80
+ };
81
+ export type WholeFileLock_Shared = {
82
+ type: 'shared';
83
+ /**
84
+ * NOTE: flock() locks are associated with open file descriptors and duplicated file descriptors.
85
+ * We do not currently recognize duplicate file descriptors.
86
+ */
87
+ pidFds: Map<Pid, Set<Fd>>;
88
+ };
89
+ export type WholeFileLock_Unlocked = {
90
+ type: 'unlocked';
91
+ };
92
+ export type WholeFileLockOp = {
93
+ pid: number;
94
+ fd: number;
95
+ type: 'shared' | 'exclusive' | 'unlock';
96
+ };
package/lib/index.d.ts CHANGED
@@ -3,3 +3,5 @@ export * from './networking/with-networking';
3
3
  export * from './load-runtime';
4
4
  export * from './use-host-filesystem';
5
5
  export * from './node-fs-mount';
6
+ export * from './file-lock-manager';
7
+ export * from './file-lock-manager-for-node';
@@ -1,8 +1,36 @@
1
- import type { SupportedPHPVersion, EmscriptenOptions } from '@php-wasm/universal';
1
+ import type { SupportedPHPVersion, EmscriptenOptions, RemoteAPI } from '@php-wasm/universal';
2
+ import type { FileLockManager } from './file-lock-manager';
2
3
  export interface PHPLoaderOptions {
3
4
  emscriptenOptions?: EmscriptenOptions;
4
5
  followSymlinks?: boolean;
5
6
  }
7
+ type PHPLoaderOptionsForNode = PHPLoaderOptions & {
8
+ emscriptenOptions?: EmscriptenOptions & {
9
+ /**
10
+ * The process ID for the PHP runtime.
11
+ *
12
+ * This is used to distinguish between php-wasm processes for the
13
+ * purpose of file locking and more informative trace messages.
14
+ *
15
+ * This ID is optional when running a single php-wasm process.
16
+ */
17
+ processId?: number;
18
+ /**
19
+ * An optional file lock manager to use for the PHP runtime.
20
+ *
21
+ * The lock manager is optional when running a single php-wasm process.
22
+ */
23
+ fileLockManager?: RemoteAPI<FileLockManager>;
24
+ /**
25
+ * An optional function to collect trace messages.
26
+ *
27
+ * @param processId - The process ID of the PHP runtime.
28
+ * @param format - A printf-style format string.
29
+ * @param args - Arguments to the format string.
30
+ */
31
+ trace?: (processId: number, format: string, ...args: any[]) => void;
32
+ };
33
+ };
6
34
  /**
7
35
  * Does what load() does, but synchronously returns
8
36
  * an object with the PHP instance and a promise that
@@ -10,4 +38,5 @@ export interface PHPLoaderOptions {
10
38
  *
11
39
  * @see load
12
40
  */
13
- export declare function loadNodeRuntime(phpVersion: SupportedPHPVersion, options?: PHPLoaderOptions): Promise<number>;
41
+ export declare function loadNodeRuntime(phpVersion: SupportedPHPVersion, options?: PHPLoaderOptionsForNode): Promise<number>;
42
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@php-wasm/node",
3
- "version": "1.1.3",
3
+ "version": "1.1.4",
4
4
  "description": "PHP.wasm for Node.js",
5
5
  "repository": {
6
6
  "type": "git",
@@ -38,24 +38,25 @@
38
38
  },
39
39
  "license": "GPL-2.0-or-later",
40
40
  "types": "index.d.ts",
41
- "gitHead": "977f8e90eabb2c8d4eed75677ddd9fb6c13274ae",
41
+ "gitHead": "ed646326d99ba84bad911d65b6634265f508f073",
42
42
  "engines": {
43
43
  "node": ">=20.18.3",
44
44
  "npm": ">=10.1.0"
45
45
  },
46
46
  "dependencies": {
47
- "comlink": "^4.4.1",
47
+ "comlink": "^4.4.2",
48
48
  "express": "4.21.2",
49
+ "fs-ext": "2.1.1",
49
50
  "ini": "4.1.2",
50
51
  "wasm-feature-detect": "1.8.0",
51
52
  "ws": "8.18.1",
52
53
  "yargs": "17.7.2",
53
- "@php-wasm/node-polyfills": "1.1.3",
54
- "@php-wasm/universal": "1.1.3",
55
- "@php-wasm/util": "1.1.3",
56
- "@php-wasm/logger": "1.1.3",
57
- "@wp-playground/common": "1.1.3",
58
- "@wp-playground/wordpress": "1.1.3"
54
+ "@php-wasm/node-polyfills": "1.1.4",
55
+ "@php-wasm/universal": "1.1.4",
56
+ "@php-wasm/logger": "1.1.4",
57
+ "@php-wasm/util": "1.1.4",
58
+ "@wp-playground/common": "1.1.4",
59
+ "@wp-playground/wordpress": "1.1.4"
59
60
  },
60
61
  "overrides": {
61
62
  "rollup": "^4.34.6",