@php-wasm/universal 2.0.15 → 2.0.18

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.js CHANGED
@@ -1,8 +1,8 @@
1
- var q = (t) => {
1
+ var W = (t) => {
2
2
  throw TypeError(t);
3
3
  };
4
- var N = (t, e, r) => e.has(t) || q("Cannot " + r);
5
- var u = (t, e, r) => (N(t, e, "read from private field"), r ? r.call(t) : e.get(t)), _ = (t, e, r) => e.has(t) ? q("Cannot add the same private member more than once") : e instanceof WeakSet ? e.add(t) : e.set(t, r), f = (t, e, r, s) => (N(t, e, "write to private field"), s ? s.call(t, r) : e.set(t, r), r), m = (t, e, r) => (N(t, e, "access private method"), r);
4
+ var O = (t, e, r) => e.has(t) || W("Cannot " + r);
5
+ var u = (t, e, r) => (O(t, e, "read from private field"), r ? r.call(t) : e.get(t)), _ = (t, e, r) => e.has(t) ? W("Cannot add the same private member more than once") : e instanceof WeakSet ? e.add(t) : e.set(t, r), w = (t, e, r, s) => (O(t, e, "write to private field"), s ? s.call(t, r) : e.set(t, r), r), m = (t, e, r) => (O(t, e, "access private method"), r);
6
6
  import "@php-wasm/node-polyfills";
7
7
  import { logger } from "@php-wasm/logger";
8
8
  import { dirname, joinPaths, Semaphore, createSpawnHandler, normalizePath, AcquireTimeoutError } from "@php-wasm/util";
@@ -438,6 +438,15 @@ class PHPWorker {
438
438
  s();
439
439
  }
440
440
  }
441
+ /** @inheritDoc @php-wasm/universal!/PHP.cli */
442
+ async cli(e, r) {
443
+ const { php: s, reap: n } = await _private.get(this).requestHandler.processManager.acquirePHPInstance();
444
+ try {
445
+ return await s.cli(e, r);
446
+ } finally {
447
+ n();
448
+ }
449
+ }
441
450
  /** @inheritDoc @php-wasm/universal!/PHP.chdir */
442
451
  chdir(e) {
443
452
  return _private.get(this).php.chdir(e);
@@ -507,7 +516,45 @@ class PHPWorker {
507
516
  await ((e = _private.get(this).requestHandler) == null ? void 0 : e[Symbol.asyncDispose]());
508
517
  }
509
518
  }
510
- const responseTexts = {
519
+ function isExitCode(t) {
520
+ return t instanceof Error ? (t == null ? void 0 : t.name) === "ExitStatus" && "status" in t : !1;
521
+ }
522
+ const RuntimeId = Symbol("RuntimeId"), loadedRuntimes = /* @__PURE__ */ new Map();
523
+ let lastRuntimeId = 0;
524
+ async function loadPHPRuntime(t, ...e) {
525
+ const r = Object.assign({}, ...e), [s, n, i] = makePromise(), o = t.init(currentJsRuntime, {
526
+ onAbort(c) {
527
+ i(c), logger.error(c);
528
+ },
529
+ ENV: {},
530
+ // Emscripten sometimes prepends a '/' to the path, which
531
+ // breaks vite dev mode. An identity `locateFile` function
532
+ // fixes it.
533
+ locateFile: (c) => c,
534
+ ...r,
535
+ noInitialRun: !0,
536
+ onRuntimeInitialized() {
537
+ r.onRuntimeInitialized && r.onRuntimeInitialized(o), n();
538
+ }
539
+ });
540
+ await s;
541
+ const a = ++lastRuntimeId;
542
+ return o.FS, o.id = a, o.originalExit = o._exit, o._exit = function(c) {
543
+ return o.outboundNetworkProxyServer && (o.outboundNetworkProxyServer.close(), o.outboundNetworkProxyServer.closeAllConnections()), loadedRuntimes.delete(a), o.originalExit(c);
544
+ }, o[RuntimeId] = a, loadedRuntimes.set(a, o), a;
545
+ }
546
+ function getLoadedRuntime(t) {
547
+ return loadedRuntimes.get(t);
548
+ }
549
+ const currentJsRuntime = function() {
550
+ var t;
551
+ return typeof process < "u" && ((t = process.release) == null ? void 0 : t.name) === "node" ? "NODE" : typeof window < "u" ? "WEB" : typeof WorkerGlobalScope < "u" && self instanceof WorkerGlobalScope ? "WORKER" : "NODE";
552
+ }(), makePromise = () => {
553
+ const t = [], e = new Promise((r, s) => {
554
+ t.push(r, s);
555
+ });
556
+ return t.unshift(e), t;
557
+ }, responseTexts = {
511
558
  500: "Internal Server Error",
512
559
  502: "Bad Gateway",
513
560
  404: "Not Found",
@@ -693,42 +740,6 @@ class PHPResponse {
693
740
  return new TextDecoder().decode(this.bytes);
694
741
  }
695
742
  }
696
- const RuntimeId = Symbol("RuntimeId"), loadedRuntimes = /* @__PURE__ */ new Map();
697
- let lastRuntimeId = 0;
698
- async function loadPHPRuntime(t, ...e) {
699
- const r = Object.assign({}, ...e), [s, n, i] = makePromise(), o = t.init(currentJsRuntime, {
700
- onAbort(c) {
701
- i(c), logger.error(c);
702
- },
703
- ENV: {},
704
- // Emscripten sometimes prepends a '/' to the path, which
705
- // breaks vite dev mode. An identity `locateFile` function
706
- // fixes it.
707
- locateFile: (c) => c,
708
- ...r,
709
- noInitialRun: !0,
710
- onRuntimeInitialized() {
711
- r.onRuntimeInitialized && r.onRuntimeInitialized(o), n();
712
- }
713
- });
714
- await s;
715
- const a = ++lastRuntimeId;
716
- return o.FS, o.id = a, o.originalExit = o._exit, o._exit = function(c) {
717
- return o.outboundNetworkProxyServer && (o.outboundNetworkProxyServer.close(), o.outboundNetworkProxyServer.closeAllConnections()), loadedRuntimes.delete(a), o.originalExit(c);
718
- }, o[RuntimeId] = a, loadedRuntimes.set(a, o), a;
719
- }
720
- function getLoadedRuntime(t) {
721
- return loadedRuntimes.get(t);
722
- }
723
- const currentJsRuntime = function() {
724
- var t;
725
- return typeof process < "u" && ((t = process.release) == null ? void 0 : t.name) === "node" ? "NODE" : typeof window < "u" ? "WEB" : typeof WorkerGlobalScope < "u" && self instanceof WorkerGlobalScope ? "WORKER" : "NODE";
726
- }(), makePromise = () => {
727
- const t = [], e = new Promise((r, s) => {
728
- t.push(r, s);
729
- });
730
- return t.unshift(e), t;
731
- };
732
743
  var _a;
733
744
  const kError = Symbol("error"), kMessage = Symbol("message");
734
745
  class ErrorEvent2 extends (_a = Event, _a) {
@@ -752,9 +763,6 @@ class ErrorEvent2 extends (_a = Event, _a) {
752
763
  Object.defineProperty(ErrorEvent2.prototype, "error", { enumerable: !0 });
753
764
  Object.defineProperty(ErrorEvent2.prototype, "message", { enumerable: !0 });
754
765
  const ErrorEvent = typeof globalThis.ErrorEvent == "function" ? globalThis.ErrorEvent : ErrorEvent2;
755
- function isExitCode(t) {
756
- return t instanceof Error ? (t == null ? void 0 : t.name) === "ExitStatus" && "status" in t : !1;
757
- }
758
766
  class UnhandledRejectionsTarget extends EventTarget {
759
767
  constructor() {
760
768
  super(...arguments), this.listenersCount = 0;
@@ -899,7 +907,7 @@ class PHPExecutionFailureError extends Error {
899
907
  }
900
908
  }
901
909
  const PHP_INI_PATH = "/internal/shared/php.ini", AUTO_PREPEND_SCRIPT = "/internal/shared/auto_prepend_file.php", OPCACHE_FILE_FOLDER = "/internal/shared/opcache";
902
- var k, E, x, g, v, T, h, z, B, W, $, V, G, J, Y, K, L, X, O, U;
910
+ var k, H, b, E, T, C, y, h, B, z, $, V, G, J, Y, K, L, X, U, j;
903
911
  class PHP {
904
912
  /**
905
913
  * Initializes a PHP runtime.
@@ -911,12 +919,21 @@ class PHP {
911
919
  constructor(t) {
912
920
  _(this, h);
913
921
  _(this, k);
914
- _(this, E);
915
- _(this, x);
916
- _(this, g);
917
- _(this, v);
918
- _(this, T);
919
- f(this, E, !1), f(this, x, null), f(this, g, /* @__PURE__ */ new Map()), f(this, v, []), f(this, T, {}), this.cliCalled = !1, this.runStreamCalled = !1, this.semaphore = new Semaphore({ concurrency: 1 }), t !== void 0 && this.initializeRuntime(t);
922
+ _(this, H, !1);
923
+ _(this, b, null);
924
+ _(this, E, /* @__PURE__ */ new Map());
925
+ _(this, T, []);
926
+ _(this, C, {});
927
+ _(this, y, {
928
+ enabled: !1,
929
+ recreateRuntime: () => 0,
930
+ needsRotating: !1,
931
+ maxRequests: 400,
932
+ requestsMade: 0
933
+ });
934
+ this.semaphore = new Semaphore({ concurrency: 1 }), t !== void 0 && this.initializeRuntime(t), this.addEventListener("request.error", (e) => {
935
+ e.source === "php-wasm" && (u(this, y).needsRotating = !0);
936
+ });
920
937
  }
921
938
  /**
922
939
  * Adds an event listener for a PHP event.
@@ -924,7 +941,7 @@ class PHP {
924
941
  * @param listener - The listener function to be called when the event is triggered.
925
942
  */
926
943
  addEventListener(t, e) {
927
- u(this, g).has(t) || u(this, g).set(t, /* @__PURE__ */ new Set()), u(this, g).get(t).add(e);
944
+ u(this, E).has(t) || u(this, E).set(t, /* @__PURE__ */ new Set()), u(this, E).get(t).add(e);
928
945
  }
929
946
  /**
930
947
  * Removes an event listener for a PHP event.
@@ -933,10 +950,10 @@ class PHP {
933
950
  */
934
951
  removeEventListener(t, e) {
935
952
  var r;
936
- (r = u(this, g).get(t)) == null || r.delete(e);
953
+ (r = u(this, E).get(t)) == null || r.delete(e);
937
954
  }
938
955
  dispatchEvent(t) {
939
- const e = u(this, g).get(t.type);
956
+ const e = u(this, E).get(t.type);
940
957
  if (e)
941
958
  for (const r of e)
942
959
  r(t);
@@ -981,8 +998,8 @@ class PHP {
981
998
  * @param listener Callback function to handle the message.
982
999
  */
983
1000
  onMessage(t) {
984
- return u(this, v).push(t), async () => {
985
- f(this, v, u(this, v).filter(
1001
+ return u(this, T).push(t), async () => {
1002
+ w(this, T, u(this, T).filter(
986
1003
  (e) => e !== t
987
1004
  ));
988
1005
  };
@@ -1076,13 +1093,13 @@ class PHP {
1076
1093
  }
1077
1094
  `
1078
1095
  ), e.onMessage = async (r) => {
1079
- for (const s of u(this, v)) {
1096
+ for (const s of u(this, T)) {
1080
1097
  const n = await s(r);
1081
1098
  if (n)
1082
1099
  return n;
1083
1100
  }
1084
1101
  return "";
1085
- }, f(this, x, improveWASMErrorReporting(e)), this.dispatchEvent({
1102
+ }, w(this, b, improveWASMErrorReporting(e)), this.dispatchEvent({
1086
1103
  type: "runtime.initialized"
1087
1104
  });
1088
1105
  }
@@ -1097,7 +1114,7 @@ class PHP {
1097
1114
  throw new Error(
1098
1115
  "Could not set SAPI name. This can only be done before the PHP WASM module is initialized.Did you already dispatch any requests?"
1099
1116
  );
1100
- f(this, k, t);
1117
+ w(this, k, t);
1101
1118
  }
1102
1119
  /**
1103
1120
  * Changes the current working directory in the PHP filesystem.
@@ -1311,19 +1328,22 @@ class PHP {
1311
1328
  * @returns A StreamedPHPResponse object.
1312
1329
  */
1313
1330
  async runStream(t) {
1314
- if (this.cliCalled)
1315
- throw new Error(
1316
- "php.runStream() can only be called if php.cli() was not called before. The two methods set a conflicting C-level global state."
1317
- );
1318
- this.runStreamCalled = !0;
1319
1331
  const e = await this.semaphore.acquire();
1320
1332
  let r;
1321
- const s = m(this, h, U).call(this, async () => {
1322
- if (u(this, E) || (await m(this, h, B).call(this), f(this, E, !0)), t.scriptPath && !this.fileExists(t.scriptPath))
1333
+ const s = m(this, h, j).call(this, async () => {
1334
+ if (u(this, H) || (await this[__private__dont__use].ccall(
1335
+ "php_wasm_init",
1336
+ null,
1337
+ [],
1338
+ [],
1339
+ {
1340
+ isAsync: !0
1341
+ }
1342
+ ), w(this, H, !0)), t.scriptPath && !this.fileExists(t.scriptPath))
1323
1343
  throw new Error(
1324
1344
  `The script path "${t.scriptPath}" does not exist.`
1325
1345
  );
1326
- m(this, h, W).call(this, t.relativeUri || ""), m(this, h, J).call(this, t.method || "GET");
1346
+ m(this, h, z).call(this, t.relativeUri || ""), m(this, h, J).call(this, t.method || "GET");
1327
1347
  const i = normalizeHeaders(t.headers || {}), o = i.host || "example.com:443", a = m(this, h, G).call(this, o, t.protocol || "http");
1328
1348
  if (m(this, h, $).call(this, o), m(this, h, V).call(this, a), m(this, h, Y).call(this, i), t.body && (r = m(this, h, K).call(this, t.body)), typeof t.code == "string")
1329
1349
  this.writeFile("/internal/eval.php", t.code), m(this, h, L).call(this, "/internal/eval.php");
@@ -1333,12 +1353,12 @@ class PHP {
1333
1353
  throw new TypeError(
1334
1354
  "The request object must have either a `code` or a `scriptPath` property."
1335
1355
  );
1336
- const c = m(this, h, z).call(this, t.$_SERVER, i, a);
1356
+ const c = m(this, h, B).call(this, t.$_SERVER, i, a);
1337
1357
  for (const p in c)
1338
1358
  m(this, h, X).call(this, p, c[p]);
1339
1359
  const l = t.env || {};
1340
1360
  for (const p in l)
1341
- m(this, h, O).call(this, p, l[p]);
1361
+ m(this, h, U).call(this, p, l[p]);
1342
1362
  return await this[__private__dont__use].ccall(
1343
1363
  "wasm_sapi_handle_request",
1344
1364
  NUMBER,
@@ -1360,7 +1380,12 @@ class PHP {
1360
1380
  return s.then(
1361
1381
  (i) => (i.finished.finally(n), i),
1362
1382
  (i) => {
1363
- throw n(), i;
1383
+ try {
1384
+ n();
1385
+ } catch {
1386
+ } finally {
1387
+ throw i;
1388
+ }
1364
1389
  }
1365
1390
  );
1366
1391
  }
@@ -1534,6 +1559,29 @@ class PHP {
1534
1559
  fileExists(t) {
1535
1560
  return FSHelpers.fileExists(this[__private__dont__use].FS, t);
1536
1561
  }
1562
+ /**
1563
+ * Enables inline PHP runtime rotation after a certain number of requests
1564
+ * or an internal crash.
1565
+ */
1566
+ enableRuntimeRotation(t) {
1567
+ w(this, y, {
1568
+ ...u(this, y),
1569
+ enabled: !0,
1570
+ recreateRuntime: t.recreateRuntime,
1571
+ maxRequests: t.maxRequests ?? 400,
1572
+ cwd: t.cwd
1573
+ });
1574
+ }
1575
+ async rotateRuntime() {
1576
+ if (!u(this, y).enabled)
1577
+ throw new Error(
1578
+ "Runtime rotation is not enabled. Call enableRuntimeRotation() first."
1579
+ );
1580
+ await this.hotSwapPHPRuntime(
1581
+ await u(this, y).recreateRuntime(),
1582
+ u(this, y).cwd
1583
+ ), u(this, y).requestsMade = 0, u(this, y).needsRotating = !1;
1584
+ }
1537
1585
  /**
1538
1586
  * Hot-swaps the PHP runtime for a new one without
1539
1587
  * interrupting the operations of this PHP instance.
@@ -1545,16 +1593,16 @@ class PHP {
1545
1593
  * accepts a constructor-level cwd argument.
1546
1594
  */
1547
1595
  async hotSwapPHPRuntime(t, e) {
1548
- const r = this[__private__dont__use].FS, s = [];
1549
- for (const [n, i] of Object.entries(u(this, T)))
1550
- s.push({ mountHandler: i.mountHandler, vfsPath: n }), await i.unmount();
1596
+ const r = this[__private__dont__use].FS, s = this[__private__dont__use].spawnProcess, n = [];
1597
+ for (const [i, o] of Object.entries(u(this, C)))
1598
+ n.push({ mountHandler: o.mountHandler, vfsPath: i }), await o.unmount();
1551
1599
  try {
1552
1600
  this.exit();
1553
1601
  } catch {
1554
1602
  }
1555
- this.initializeRuntime(t), u(this, k) && this.setSapiName(u(this, k)), copyFS(r, this[__private__dont__use].FS, "/internal"), e && copyFS(r, this[__private__dont__use].FS, e);
1556
- for (const { mountHandler: n, vfsPath: i } of s)
1557
- this.mkdir(i), await this.mount(i, n);
1603
+ this.initializeRuntime(t), s && (this[__private__dont__use].spawnProcess = s), u(this, k) && this.setSapiName(u(this, k)), copyFS(r, this[__private__dont__use].FS, "/internal"), e && copyFS(r, this[__private__dont__use].FS, e);
1604
+ for (const { mountHandler: i, vfsPath: o } of n)
1605
+ this.mkdir(o), await this.mount(o, i);
1558
1606
  }
1559
1607
  /**
1560
1608
  * Mounts a filesystem to a given path in the PHP filesystem.
@@ -1571,10 +1619,10 @@ class PHP {
1571
1619
  ), s = {
1572
1620
  mountHandler: e,
1573
1621
  unmount: async () => {
1574
- await r(), delete u(this, T)[t];
1622
+ await r(), delete u(this, C)[t];
1575
1623
  }
1576
1624
  };
1577
- return u(this, T)[t] = s, () => {
1625
+ return u(this, C)[t] = s, () => {
1578
1626
  s.unmount();
1579
1627
  };
1580
1628
  }
@@ -1592,29 +1640,26 @@ class PHP {
1592
1640
  * @returns The exit code of the CLI session.
1593
1641
  */
1594
1642
  async cli(t, e = {}) {
1595
- if (this.cliCalled)
1596
- throw new Error(
1597
- "php.cli() can only be called once. The method sets a C-level global state that does not allow repeated calls."
1598
- );
1599
- if (this.runStreamCalled)
1600
- throw new Error(
1601
- "php.cli() can only be called if php.runStream() was not called before. The two methods set a conflicting C-level global state."
1602
- );
1603
- this.cliCalled = !0;
1604
- const r = await this.semaphore.acquire(), s = e.env || {};
1605
- for (const [n, i] of Object.entries(s))
1606
- m(this, h, O).call(this, n, i);
1607
- t = [t[0], "-c", PHP_INI_PATH, ...t.slice(1)];
1608
- for (const n of t)
1609
- this[__private__dont__use].ccall(
1610
- "wasm_add_cli_arg",
1611
- null,
1612
- [STRING],
1613
- [n]
1614
- );
1615
- return await m(this, h, U).call(this, () => this[__private__dont__use].ccall("run_cli", null, [], [], {
1616
- async: !0
1617
- })).then((n) => (n.exitCode.finally(r), n));
1643
+ u(this, H) && (u(this, y).needsRotating = !0);
1644
+ const r = await this.semaphore.acquire();
1645
+ return await m(this, h, j).call(this, () => {
1646
+ const s = e.env || {};
1647
+ for (const [n, i] of Object.entries(s))
1648
+ m(this, h, U).call(this, n, i);
1649
+ t = [t[0], "-c", PHP_INI_PATH, ...t.slice(1)];
1650
+ for (const n of t)
1651
+ this[__private__dont__use].ccall(
1652
+ "wasm_add_cli_arg",
1653
+ null,
1654
+ [STRING],
1655
+ [n]
1656
+ );
1657
+ return this[__private__dont__use].ccall("run_cli", null, [], [], {
1658
+ async: !0
1659
+ });
1660
+ }).then((s) => (s.exitCode.finally(r), s)).finally(() => {
1661
+ u(this, y).needsRotating = !0;
1662
+ });
1618
1663
  }
1619
1664
  setSkipShebang(t) {
1620
1665
  this[__private__dont__use].ccall(
@@ -1626,19 +1671,19 @@ class PHP {
1626
1671
  }
1627
1672
  exit(t = 0) {
1628
1673
  this.dispatchEvent({
1629
- type: "runtime.beforedestroy"
1674
+ type: "runtime.beforeExit"
1630
1675
  });
1631
1676
  try {
1632
1677
  this[__private__dont__use]._exit(t);
1633
1678
  } catch {
1634
1679
  }
1635
- f(this, E, !1), f(this, x, null), this[__private__dont__use] && (delete this[__private__dont__use].onMessage, delete this[__private__dont__use]);
1680
+ w(this, H, !1), w(this, b, null), this[__private__dont__use] && (delete this[__private__dont__use].onMessage, delete this[__private__dont__use]);
1636
1681
  }
1637
1682
  [Symbol.dispose]() {
1638
- u(this, E) && this.exit(0);
1683
+ this.exit(0);
1639
1684
  }
1640
1685
  }
1641
- k = new WeakMap(), E = new WeakMap(), x = new WeakMap(), g = new WeakMap(), v = new WeakMap(), T = new WeakMap(), h = new WeakSet(), /**
1686
+ k = new WeakMap(), H = new WeakMap(), b = new WeakMap(), E = new WeakMap(), T = new WeakMap(), C = new WeakMap(), y = new WeakMap(), h = new WeakSet(), /**
1642
1687
  * Prepares the $_SERVER entries for the PHP runtime.
1643
1688
  *
1644
1689
  * @param defaults Default entries to include in $_SERVER.
@@ -1647,7 +1692,7 @@ k = new WeakMap(), E = new WeakMap(), x = new WeakMap(), g = new WeakMap(), v =
1647
1692
  * was provided.
1648
1693
  * @returns Computed $_SERVER entries.
1649
1694
  */
1650
- z = function(t, e, r) {
1695
+ B = function(t, e, r) {
1651
1696
  const s = {
1652
1697
  ...t || {}
1653
1698
  };
@@ -1657,11 +1702,7 @@ z = function(t, e, r) {
1657
1702
  ["content-type", "content-length"].includes(n.toLowerCase()) && (i = ""), s[`${i}${n.toUpperCase().replace(/-/g, "_")}`] = e[n];
1658
1703
  }
1659
1704
  return s;
1660
- }, B = function() {
1661
- return this[__private__dont__use].ccall("php_wasm_init", null, [], [], {
1662
- isAsync: !0
1663
- });
1664
- }, W = function(t) {
1705
+ }, z = function(t) {
1665
1706
  this[__private__dont__use].ccall(
1666
1707
  "wasm_set_request_uri",
1667
1708
  null,
@@ -1757,14 +1798,15 @@ z = function(t, e, r) {
1757
1798
  [STRING, STRING],
1758
1799
  [t, e]
1759
1800
  );
1760
- }, O = function(t, e) {
1801
+ }, U = function(t, e) {
1761
1802
  this[__private__dont__use].ccall(
1762
1803
  "wasm_add_ENV_entry",
1763
1804
  null,
1764
1805
  [STRING, STRING],
1765
1806
  [t, e]
1766
1807
  );
1767
- }, U = async function(t) {
1808
+ }, j = async function(t) {
1809
+ u(this, y).enabled && u(this, y).needsRotating && await this.rotateRuntime(), ++u(this, y).requestsMade, u(this, y).requestsMade >= u(this, y).maxRequests && (u(this, y).needsRotating = !0);
1768
1810
  const e = this[__private__dont__use], r = await createInvertedReadableStream();
1769
1811
  e.onHeaders = (d) => {
1770
1812
  a || s || r.controller.enqueue(d.slice());
@@ -1786,30 +1828,30 @@ z = function(t, e, r) {
1786
1828
  try {
1787
1829
  return await Promise.race([
1788
1830
  t(),
1789
- new Promise((w, b) => {
1790
- var j;
1831
+ new Promise((g, R) => {
1832
+ var q;
1791
1833
  c = (D) => {
1792
- isExitCode(D.error) || b(D.error);
1793
- }, (j = u(this, x)) == null || j.addEventListener(
1834
+ isExitCode(D.error) || R(D.error);
1835
+ }, (q = u(this, b)) == null || q.addEventListener(
1794
1836
  "error",
1795
1837
  c,
1796
1838
  { once: !0 }
1797
1839
  );
1798
1840
  })
1799
1841
  ]);
1800
- } catch (y) {
1801
- if (isExitCode(y))
1802
- return y.status;
1803
- i.controller.error(y), o.controller.error(y), r.controller.error(y), a = !0;
1804
- for (const w in this)
1805
- typeof this[w] == "function" && (this[w] = () => {
1842
+ } catch (f) {
1843
+ if (isExitCode(f))
1844
+ return f.status;
1845
+ i.controller.error(f), o.controller.error(f), r.controller.error(f), a = !0;
1846
+ for (const g in this)
1847
+ typeof this[g] == "function" && (this[g] = () => {
1806
1848
  throw new Error(
1807
1849
  "PHP runtime has crashed – see the earlier error for details."
1808
1850
  );
1809
1851
  });
1810
- throw this.functionsMaybeMissingFromAsyncify = getFunctionsMaybeMissingFromAsyncify(), y;
1852
+ throw this.functionsMaybeMissingFromAsyncify = getFunctionsMaybeMissingFromAsyncify(), f;
1811
1853
  } finally {
1812
- a || (i.controller.close(), o.controller.close(), n(), a = !0), (d = u(this, x)) == null || d.removeEventListener(
1854
+ a || (i.controller.close(), o.controller.close(), n(), a = !0), (d = u(this, b)) == null || d.removeEventListener(
1813
1855
  "error",
1814
1856
  c
1815
1857
  );
@@ -1824,11 +1866,11 @@ z = function(t, e, r) {
1824
1866
  source: "php-wasm"
1825
1867
  }), d),
1826
1868
  (d) => {
1869
+ const f = d.source ?? "php-wasm";
1827
1870
  throw this.dispatchEvent({
1828
1871
  type: "request.error",
1829
1872
  error: d,
1830
- // Distinguish between PHP request and PHP-wasm errors
1831
- source: d.source ?? "php-wasm"
1873
+ source: f
1832
1874
  }), d;
1833
1875
  }
1834
1876
  );
@@ -2286,7 +2328,7 @@ const _default = "application/octet-stream", asx = "video/x-ms-asf", atom = "app
2286
2328
  xspf,
2287
2329
  zip
2288
2330
  };
2289
- var S, C, M, F, I, P, A, R, H, Q, Z, ee;
2331
+ var x, I, N, F, M, P, A, v, S, Q, Z, ee;
2290
2332
  class PHPRequestHandler {
2291
2333
  /**
2292
2334
  * The request handler needs to decide whether to serve a static asset or
@@ -2300,15 +2342,15 @@ class PHPRequestHandler {
2300
2342
  * @param config - Request Handler configuration.
2301
2343
  */
2302
2344
  constructor(e) {
2303
- _(this, H);
2304
2345
  _(this, S);
2305
- _(this, C);
2306
- _(this, M);
2307
- _(this, F);
2346
+ _(this, x);
2308
2347
  _(this, I);
2348
+ _(this, N);
2349
+ _(this, F);
2350
+ _(this, M);
2309
2351
  _(this, P);
2310
2352
  _(this, A);
2311
- _(this, R);
2353
+ _(this, v);
2312
2354
  const {
2313
2355
  documentRoot: r = "/www/",
2314
2356
  absoluteUrl: s = typeof location == "object" ? location.href : DEFAULT_BASE_URL,
@@ -2324,16 +2366,16 @@ class PHPRequestHandler {
2324
2366
  return l.isDir(r) || l.mkdir(r), l.chdir(r), l.requestHandler = this, l;
2325
2367
  },
2326
2368
  maxPhpInstances: e.maxPhpInstances
2327
- }), f(this, R, e.cookieStore === void 0 ? new HttpCookieStore() : e.cookieStore), f(this, S, r);
2369
+ }), w(this, v, e.cookieStore === void 0 ? new HttpCookieStore() : e.cookieStore), w(this, x, r);
2328
2370
  const o = new URL(s);
2329
- f(this, M, o.hostname), f(this, F, o.port ? Number(o.port) : o.protocol === "https:" ? 443 : 80), f(this, C, (o.protocol || "").replace(":", ""));
2371
+ w(this, N, o.hostname), w(this, F, o.port ? Number(o.port) : o.protocol === "https:" ? 443 : 80), w(this, I, (o.protocol || "").replace(":", ""));
2330
2372
  const a = u(this, F) !== 443 && u(this, F) !== 80;
2331
- f(this, I, [
2332
- u(this, M),
2373
+ w(this, M, [
2374
+ u(this, N),
2333
2375
  a ? `:${u(this, F)}` : ""
2334
- ].join("")), f(this, P, o.pathname.replace(/\/+$/, "")), f(this, A, [
2335
- `${u(this, C)}://`,
2336
- u(this, I),
2376
+ ].join("")), w(this, P, o.pathname.replace(/\/+$/, "")), w(this, A, [
2377
+ `${u(this, I)}://`,
2378
+ u(this, M),
2337
2379
  u(this, P)
2338
2380
  ].join("")), this.rewriteRules = n, this.getFileNotFoundAction = i;
2339
2381
  }
@@ -2372,7 +2414,7 @@ class PHPRequestHandler {
2372
2414
  * for the files to serve. Default: `/var/www`.
2373
2415
  */
2374
2416
  get documentRoot() {
2375
- return u(this, S);
2417
+ return u(this, x);
2376
2418
  }
2377
2419
  /**
2378
2420
  * Serves the request – either by serving a static file, or by
@@ -2434,7 +2476,7 @@ class PHPRequestHandler {
2434
2476
  ),
2435
2477
  this.rewriteRules
2436
2478
  ), i = await this.getPrimaryPhp();
2437
- let o = joinPaths(u(this, S), n);
2479
+ let o = joinPaths(u(this, x), n);
2438
2480
  if (i.isDir(o)) {
2439
2481
  if (!o.endsWith("/"))
2440
2482
  return new PHPResponse(
@@ -2458,7 +2500,7 @@ class PHPRequestHandler {
2458
2500
  case "response":
2459
2501
  return a.response;
2460
2502
  case "internal-redirect":
2461
- o = joinPaths(u(this, S), a.uri);
2503
+ o = joinPaths(u(this, x), a.uri);
2462
2504
  break;
2463
2505
  case "404":
2464
2506
  return PHPResponse.forHttpCode(404);
@@ -2474,7 +2516,7 @@ class PHPRequestHandler {
2474
2516
  ...e,
2475
2517
  // Pass along URL with the #fragment filtered out
2476
2518
  url: s.toString()
2477
- }, c = await m(this, H, Z).call(this, a, o);
2519
+ }, c = await m(this, S, Z).call(this, a, o);
2478
2520
  return c.ok() && c.exitCode !== 0 ? new PHPResponse(
2479
2521
  500,
2480
2522
  c.headers,
@@ -2483,7 +2525,7 @@ class PHPRequestHandler {
2483
2525
  c.exitCode
2484
2526
  ) : c;
2485
2527
  } else
2486
- return m(this, H, Q).call(this, i, o);
2528
+ return m(this, S, Q).call(this, i, o);
2487
2529
  else
2488
2530
  return PHPResponse.forHttpCode(404);
2489
2531
  }
@@ -2491,7 +2533,7 @@ class PHPRequestHandler {
2491
2533
  await this.processManager[Symbol.asyncDispose]();
2492
2534
  }
2493
2535
  }
2494
- S = new WeakMap(), C = new WeakMap(), M = new WeakMap(), F = new WeakMap(), I = new WeakMap(), P = new WeakMap(), A = new WeakMap(), R = new WeakMap(), H = new WeakSet(), /**
2536
+ x = new WeakMap(), I = new WeakMap(), N = new WeakMap(), F = new WeakMap(), M = new WeakMap(), P = new WeakMap(), A = new WeakMap(), v = new WeakMap(), S = new WeakSet(), /**
2495
2537
  * Serves a static file from the PHP filesystem.
2496
2538
  *
2497
2539
  * @param fsPath - Absolute path of the static file to serve.
@@ -2522,17 +2564,17 @@ Q = function(e, r) {
2522
2564
  return n instanceof MaxPhpInstancesError ? PHPResponse.forHttpCode(502) : PHPResponse.forHttpCode(500);
2523
2565
  }
2524
2566
  try {
2525
- return await m(this, H, ee).call(this, s.php, e, r);
2567
+ return await m(this, S, ee).call(this, s.php, e, r);
2526
2568
  } finally {
2527
2569
  s.reap();
2528
2570
  }
2529
2571
  }, ee = async function(e, r, s) {
2530
2572
  let n = "GET";
2531
2573
  const i = {
2532
- host: u(this, I),
2574
+ host: u(this, M),
2533
2575
  ...normalizeHeaders(r.headers || {})
2534
2576
  };
2535
- u(this, R) && (i.cookie = u(this, R).getCookieRequestHeader());
2577
+ u(this, v) && (i.cookie = u(this, v).getCookieRequestHeader());
2536
2578
  let o = r.body;
2537
2579
  if (typeof o == "object" && !(o instanceof Uint8Array)) {
2538
2580
  n = "POST";
@@ -2545,18 +2587,18 @@ Q = function(e, r) {
2545
2587
  toRelativeUrl(new URL(r.url)),
2546
2588
  u(this, P)
2547
2589
  ),
2548
- protocol: u(this, C),
2590
+ protocol: u(this, I),
2549
2591
  method: r.method || n,
2550
2592
  $_SERVER: {
2551
2593
  REMOTE_ADDR: "127.0.0.1",
2552
- DOCUMENT_ROOT: u(this, S),
2594
+ DOCUMENT_ROOT: u(this, x),
2553
2595
  HTTPS: u(this, A).startsWith("https://") ? "on" : ""
2554
2596
  },
2555
2597
  body: o,
2556
2598
  scriptPath: s,
2557
2599
  headers: i
2558
2600
  });
2559
- return u(this, R) && u(this, R).rememberCookiesFromResponseHeaders(
2601
+ return u(this, v) && u(this, v).rememberCookiesFromResponseHeaders(
2560
2602
  a.headers
2561
2603
  ), a;
2562
2604
  } catch (a) {
@@ -2580,34 +2622,13 @@ function rotatePHPRuntime({
2580
2622
  php: t,
2581
2623
  cwd: e,
2582
2624
  recreateRuntime: r,
2583
- /*
2584
- * 400 is an arbitrary number that should trigger a rotation
2585
- * way before the memory gets too fragmented. If it doesn't,
2586
- * let's explore:
2587
- * * Rotating based on an actual memory usage and
2588
- * fragmentation.
2589
- * * Resetting HEAP to its initial value.
2590
- */
2591
2625
  maxRequests: s = 400
2592
2626
  }) {
2593
- let n = 0;
2594
- async function i() {
2595
- const c = await t.semaphore.acquire();
2596
- try {
2597
- await t.hotSwapPHPRuntime(await r(), e), n = 0;
2598
- } finally {
2599
- c();
2600
- }
2601
- }
2602
- async function o() {
2603
- ++n < s || await i();
2604
- }
2605
- async function a(c) {
2606
- c.type === "request.error" && c.source === "php-wasm" && await i();
2607
- }
2608
- return t.addEventListener("request.error", a), t.addEventListener("request.end", o), function() {
2609
- t.removeEventListener("request.error", a), t.removeEventListener("request.end", o);
2610
- };
2627
+ return t.enableRuntimeRotation({
2628
+ recreateRuntime: r,
2629
+ maxRequests: s,
2630
+ cwd: e
2631
+ });
2611
2632
  }
2612
2633
  async function writeFiles(t, e, r, { rmRoot: s = !1 } = {}) {
2613
2634
  s && await t.isDir(e) && await t.rmdir(e, { recursive: !0 });
@@ -2854,10 +2875,10 @@ function expose(t, e = globalThis, r = ["*"], s) {
2854
2875
  }, l = (i.data.argumentList || []).map(fromWireValue);
2855
2876
  let p;
2856
2877
  try {
2857
- const d = c.slice(0, -1).reduce((w, b) => w[b], t), y = c.reduce((w, b) => w[b], t);
2878
+ const d = c.slice(0, -1).reduce((g, R) => g[R], t), f = c.reduce((g, R) => g[R], t);
2858
2879
  switch (a) {
2859
2880
  case MessageType.GET:
2860
- p = y;
2881
+ p = f;
2861
2882
  break;
2862
2883
  case MessageType.SET:
2863
2884
  d[c.slice(-1)[0]] = fromWireValue(
@@ -2865,18 +2886,18 @@ function expose(t, e = globalThis, r = ["*"], s) {
2865
2886
  ), p = !0;
2866
2887
  break;
2867
2888
  case MessageType.APPLY:
2868
- p = y.apply(d, l);
2889
+ p = f.apply(d, l);
2869
2890
  break;
2870
2891
  case MessageType.CONSTRUCT:
2871
2892
  {
2872
- const w = new y(...l);
2873
- p = proxy(w);
2893
+ const g = new f(...l);
2894
+ p = proxy(g);
2874
2895
  }
2875
2896
  break;
2876
2897
  case MessageType.ENDPOINT:
2877
2898
  {
2878
- const { port1: w, port2: b } = new MessageChannel();
2879
- expose(t, b), p = transfer(w, [w]);
2899
+ const { port1: g, port2: R } = new MessageChannel();
2900
+ expose(t, R), p = transfer(g, [g]);
2880
2901
  }
2881
2902
  break;
2882
2903
  case MessageType.RELEASE:
@@ -2889,14 +2910,14 @@ function expose(t, e = globalThis, r = ["*"], s) {
2889
2910
  p = { value: d, [throwMarker]: 0 };
2890
2911
  }
2891
2912
  Promise.resolve(p).catch((d) => ({ value: d, [throwMarker]: 0 })).then((d) => {
2892
- const [y, w] = toWireValue(d);
2893
- e.postMessage({ ...y, id: o }, w), a === MessageType.RELEASE && (e.removeEventListener("message", n), closeEndPoint(e), finalizer in t && typeof t[finalizer] == "function" && t[finalizer]());
2913
+ const [f, g] = toWireValue(d);
2914
+ e.postMessage({ ...f, id: o }, g), a === MessageType.RELEASE && (e.removeEventListener("message", n), closeEndPoint(e), finalizer in t && typeof t[finalizer] == "function" && t[finalizer]());
2894
2915
  }).catch(() => {
2895
- const [d, y] = toWireValue({
2916
+ const [d, f] = toWireValue({
2896
2917
  value: new TypeError("Unserializable return value"),
2897
2918
  [throwMarker]: 0
2898
2919
  });
2899
- e.postMessage({ ...d, id: o }, y);
2920
+ e.postMessage({ ...d, id: o }, f);
2900
2921
  }).finally(() => {
2901
2922
  s == null || s(i);
2902
2923
  });
@@ -2994,7 +3015,7 @@ function createProxy(t, e, r = [], s = function() {
2994
3015
  e,
2995
3016
  {
2996
3017
  type: MessageType.APPLY,
2997
- path: r.map((y) => y.toString()),
3018
+ path: r.map((f) => f.toString()),
2998
3019
  argumentList: p
2999
3020
  },
3000
3021
  d