@php-wasm/universal 0.5.6 → 0.6.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/lib/base-php.d.ts CHANGED
@@ -3,6 +3,7 @@ import { PHPRequestHandlerConfiguration } from './php-request-handler';
3
3
  import { PHPResponse } from './php-response';
4
4
  import type { PHPRuntimeId } from './load-php-runtime';
5
5
  import { IsomorphicLocalPHP, MessageListener, PHPRequest, PHPRequestHeaders, PHPRunOptions, RmDirOptions, ListFilesOptions, SpawnHandler, PHPEventListener, PHPEvent } from './universal-php';
6
+ import { Semaphore } from '../../../util/src/index.ts';
6
7
  export declare const __private__dont__use: unique symbol;
7
8
  /**
8
9
  * An environment-agnostic wrapper around the Emscripten PHP runtime
@@ -16,6 +17,11 @@ export declare abstract class BasePHP implements IsomorphicLocalPHP {
16
17
  #private;
17
18
  protected [__private__dont__use]: any;
18
19
  requestHandler?: PHPBrowser;
20
+ /**
21
+ * An exclusive lock that prevent multiple requests from running at
22
+ * the same time.
23
+ */
24
+ semaphore: Semaphore;
19
25
  /**
20
26
  * Initializes a PHP runtime.
21
27
  *
@@ -30,7 +36,7 @@ export declare abstract class BasePHP implements IsomorphicLocalPHP {
30
36
  /** @inheritDoc */
31
37
  onMessage(listener: MessageListener): Promise<void>;
32
38
  /** @inheritDoc */
33
- setSpawnHandler(handler: SpawnHandler): Promise<void>;
39
+ setSpawnHandler(handler: SpawnHandler | string): Promise<void>;
34
40
  /** @inheritDoc */
35
41
  get absoluteUrl(): string;
36
42
  /** @inheritDoc */
@@ -41,6 +47,8 @@ export declare abstract class BasePHP implements IsomorphicLocalPHP {
41
47
  internalUrlToPath(internalUrl: string): string;
42
48
  initializeRuntime(runtimeId: PHPRuntimeId): void;
43
49
  /** @inheritDoc */
50
+ setSapiName(newName: string): Promise<void>;
51
+ /** @inheritDoc */
44
52
  setPhpIniPath(path: string): void;
45
53
  /** @inheritDoc */
46
54
  setPhpIniEntry(key: string, value: string): void;
@@ -51,7 +59,7 @@ export declare abstract class BasePHP implements IsomorphicLocalPHP {
51
59
  /** @inheritDoc */
52
60
  run(request: PHPRunOptions): Promise<PHPResponse>;
53
61
  addServerGlobalEntry(key: string, value: string): void;
54
- defineConstant(key: string, value: string | number | null): void;
62
+ defineConstant(key: string, value: string | boolean | number | null): void;
55
63
  /** @inheritDoc */
56
64
  mkdir(path: string): void;
57
65
  /** @inheritDoc */
@@ -74,6 +82,13 @@ export declare abstract class BasePHP implements IsomorphicLocalPHP {
74
82
  isDir(path: string): boolean;
75
83
  /** @inheritDoc */
76
84
  fileExists(path: string): boolean;
77
- exit(code?: number): any;
85
+ /**
86
+ * Hot-swaps the PHP runtime for a new one without
87
+ * interrupting the operations of this PHP instance.
88
+ *
89
+ * @param runtime
90
+ */
91
+ hotSwapPHPRuntime(runtime: number): void;
92
+ exit(code?: number): void;
78
93
  }
79
94
  export declare function normalizeHeaders(headers: PHPRequestHeaders): PHPRequestHeaders;
package/lib/index.d.ts CHANGED
@@ -20,5 +20,6 @@ export type { PHPRequestHandlerConfiguration } from './php-request-handler';
20
20
  export { PHPRequestHandler } from './php-request-handler';
21
21
  export type { PHPBrowserConfiguration } from './php-browser';
22
22
  export { PHPBrowser } from './php-browser';
23
+ export { rotatePHPRuntime } from './rotate-php-runtime';
23
24
  export { DEFAULT_BASE_URL, ensurePathPrefix, removePathPrefix, toRelativeUrl, } from './urls';
24
25
  export { isExitCodeZero } from './is-exit-code-zero';
@@ -112,10 +112,9 @@
112
112
  * @public
113
113
  * @param phpLoaderModule - The ESM-wrapped Emscripten module. Consult the Dockerfile for the build process.
114
114
  * @param phpModuleArgs - The Emscripten module arguments, see https://emscripten.org/docs/api_reference/module.html#affecting-execution.
115
- * @param dataDependenciesModules - A list of the ESM-wrapped Emscripten data dependency modules.
116
115
  * @returns Loaded runtime id.
117
116
  */
118
- export declare function loadPHPRuntime(phpLoaderModule: PHPLoaderModule, phpModuleArgs?: EmscriptenOptions, dataDependenciesModules?: DataModule[]): Promise<number>;
117
+ export declare function loadPHPRuntime(phpLoaderModule: PHPLoaderModule, phpModuleArgs?: EmscriptenOptions): Promise<number>;
119
118
  export type RuntimeType = 'NODE' | 'WEB' | 'WORKER';
120
119
  export type PHPRuntimeId = number;
121
120
  export declare function getLoadedRuntime(id: PHPRuntimeId): PHPRuntime;
@@ -140,7 +139,6 @@ export type EmscriptenOptions = {
140
139
  ENV?: Record<string, string>;
141
140
  locateFile?: (path: string) => string;
142
141
  noInitialRun?: boolean;
143
- dataFileDownloads?: Record<string, number>;
144
142
  print?: (message: string) => void;
145
143
  printErr?: (message: string) => void;
146
144
  quit?: (status: number, toThrow: any) => void;
@@ -0,0 +1,23 @@
1
+ import { BasePHP } from './base-php';
2
+ export interface RotateOptions<T extends BasePHP> {
3
+ php: T;
4
+ recreateRuntime: () => Promise<number> | number;
5
+ maxRequests: number;
6
+ }
7
+ /**
8
+ * Listens to PHP events and swaps the internal PHP Runtime for a fresh one
9
+ * after a certain number of run() calls (which are responsible for handling
10
+ * HTTP requests).
11
+ *
12
+ * Why? Because PHP and PHP extension have a memory leak. Each request leaves
13
+ * the memory a bit more fragmented and with a bit less available space than
14
+ * before. Eventually, new allocations start failing.
15
+ *
16
+ * Rotating the PHP instance may seem like a workaround, but it's actually
17
+ * what PHP-FPM does natively:
18
+ *
19
+ * https://www.php.net/manual/en/install.fpm.configuration.php#pm.max-tasks
20
+ *
21
+ * @return cleanup function to restore
22
+ */
23
+ export declare function rotatePHPRuntime<T extends BasePHP>({ php, recreateRuntime, maxRequests, }: RotateOptions<T>): () => void;
@@ -1,17 +1,29 @@
1
1
  import { Remote } from 'comlink';
2
2
  import { PHPResponse } from './php-response';
3
3
  /**
4
- * Represents an event related to the PHP filesystem.
4
+ * Represents an event related to the PHP request.
5
5
  */
6
6
  export interface PHPRequestEndEvent {
7
7
  type: 'request.end';
8
8
  }
9
+ /**
10
+ * Represents a PHP runtime initialization event.
11
+ */
12
+ export interface PHPRuntimeInitializedEvent {
13
+ type: 'runtime.initialized';
14
+ }
15
+ /**
16
+ * Represents a PHP runtime destruction event.
17
+ */
18
+ export interface PHPRuntimeBeforeDestroyEvent {
19
+ type: 'runtime.beforedestroy';
20
+ }
9
21
  /**
10
22
  * Represents an event related to the PHP instance.
11
23
  * This is intentionally not an extension of CustomEvent
12
24
  * to make it isomorphic between different JavaScript runtimes.
13
25
  */
14
- export type PHPEvent = PHPRequestEndEvent;
26
+ export type PHPEvent = PHPRequestEndEvent | PHPRuntimeInitializedEvent | PHPRuntimeBeforeDestroyEvent;
15
27
  /**
16
28
  * A callback function that handles PHP events.
17
29
  */
@@ -147,6 +159,11 @@ export interface RequestHandler {
147
159
  documentRoot: string;
148
160
  }
149
161
  export interface IsomorphicLocalPHP extends RequestHandler {
162
+ /**
163
+ * Sets the SAPI name exposed by the PHP module.
164
+ * @param newName - The new SAPI name.
165
+ */
166
+ setSapiName(newName: string): void;
150
167
  /**
151
168
  * Defines a constant in the PHP runtime.
152
169
  * @param key - The name of the constant.
@@ -384,7 +401,7 @@ export interface IsomorphicLocalPHP extends RequestHandler {
384
401
  *
385
402
  * @param handler Callback function to spawn a process.
386
403
  */
387
- setSpawnHandler(handler: SpawnHandler): void;
404
+ setSpawnHandler(handler: SpawnHandler | string): void;
388
405
  }
389
406
  export type MessageListener = (data: string) => Promise<string | Uint8Array | void> | string | void;
390
407
  interface EventEmitter {
@@ -395,7 +412,7 @@ type ChildProcess = EventEmitter & {
395
412
  stdout: EventEmitter;
396
413
  stderr: EventEmitter;
397
414
  };
398
- export type SpawnHandler = (command: string) => ChildProcess;
415
+ export type SpawnHandler = (command: string, args: string[]) => ChildProcess;
399
416
  export type IsomorphicRemotePHP = Remote<IsomorphicLocalPHP>;
400
417
  export type UniversalPHP = IsomorphicLocalPHP | IsomorphicRemotePHP;
401
418
  export type HTTPMethod = 'GET' | 'POST' | 'HEAD' | 'OPTIONS' | 'PATCH' | 'PUT' | 'DELETE';
@@ -460,6 +477,11 @@ export interface PHPRunOptions {
460
477
  * The code snippet to eval instead of a php file.
461
478
  */
462
479
  code?: string;
480
+ /**
481
+ * Whether to throw an error if the PHP process exits with a non-zero code
482
+ * or outputs to stderr.
483
+ */
484
+ throwOnError?: boolean;
463
485
  }
464
486
  /**
465
487
  * Output of the PHP.wasm runtime.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@php-wasm/universal",
3
- "version": "0.5.6",
3
+ "version": "0.6.0",
4
4
  "description": "PHP.wasm – emscripten bindings for PHP",
5
5
  "repository": {
6
6
  "type": "git",
@@ -36,7 +36,7 @@
36
36
  "main": "./index.cjs",
37
37
  "module": "./index.js",
38
38
  "license": "GPL-2.0-or-later",
39
- "gitHead": "72e190ebb407051ccb5ef544e2a62018395395a0",
39
+ "gitHead": "3f137306ec8e3b10ec0674a1fe69ee43349edb4a",
40
40
  "engines": {
41
41
  "node": ">=18.18.2",
42
42
  "npm": ">=8.11.0"