@php-wasm/web 0.7.1 → 0.7.3

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,13 +1,13 @@
1
- var Z = (e, t, r) => {
1
+ var D = (e, t, r) => {
2
2
  if (!t.has(e))
3
3
  throw TypeError("Cannot " + r);
4
4
  };
5
- var u = (e, t, r) => (Z(e, t, "read from private field"), r ? r.call(e) : t.get(e)), d = (e, t, r) => {
5
+ var d = (e, t, r) => (D(e, t, "read from private field"), r ? r.call(e) : t.get(e)), u = (e, t, r) => {
6
6
  if (t.has(e))
7
7
  throw TypeError("Cannot add the same private member more than once");
8
8
  t instanceof WeakSet ? t.add(e) : t.set(e, r);
9
- }, p = (e, t, r, s) => (Z(e, t, "write to private field"), s ? s.call(e, r) : t.set(e, r), r);
10
- var f = (e, t, r) => (Z(e, t, "access private method"), r);
9
+ }, m = (e, t, r, s) => (D(e, t, "write to private field"), s ? s.call(e, r) : t.set(e, r), r);
10
+ var p = (e, t, r) => (D(e, t, "access private method"), r);
11
11
  const currentJsRuntime$1 = function() {
12
12
  var e;
13
13
  return typeof process < "u" && ((e = process.release) == null ? void 0 : e.name) === "node" ? "NODE" : typeof window < "u" ? "WEB" : (
@@ -59,10 +59,10 @@ if (currentJsRuntime$1 === "NODE") {
59
59
  const o = n.byobRequest.view, a = await s.slice(
60
60
  r,
61
61
  r + o.byteLength
62
- ).arrayBuffer(), c = new Uint8Array(a);
63
- new Uint8Array(o.buffer).set(c);
64
- const l = c.byteLength;
65
- n.byobRequest.respond(l), r += l, r >= s.size && n.close();
62
+ ).arrayBuffer(), l = new Uint8Array(a);
63
+ new Uint8Array(o.buffer).set(l);
64
+ const c = l.byteLength;
65
+ n.byobRequest.respond(c), r += c, r >= s.size && n.close();
66
66
  }
67
67
  });
68
68
  });
@@ -102,6 +102,171 @@ const ErrorEvent = typeof globalThis.ErrorEvent == "function" ? globalThis.Error
102
102
  function isExitCodeZero(e) {
103
103
  return e instanceof Error ? "exitCode" in e && (e == null ? void 0 : e.exitCode) === 0 || (e == null ? void 0 : e.name) === "ExitStatus" && "status" in e && e.status === 0 : !1;
104
104
  }
105
+ const logToConsole = (e, ...t) => {
106
+ switch (e.severity) {
107
+ case "Debug":
108
+ console.debug(e.message, ...t);
109
+ break;
110
+ case "Info":
111
+ console.info(e.message, ...t);
112
+ break;
113
+ case "Warn":
114
+ console.warn(e.message, ...t);
115
+ break;
116
+ case "Error":
117
+ console.error(e.message, ...t);
118
+ break;
119
+ case "Fatal":
120
+ console.error(e.message, ...t);
121
+ break;
122
+ default:
123
+ console.log(e.message, ...t);
124
+ }
125
+ }, prepareLogMessage = (e, ...t) => [
126
+ typeof e == "object" ? JSON.stringify(e) : e,
127
+ ...t.map((r) => JSON.stringify(r))
128
+ ].join(" "), logs = [], addToLogArray = (e) => {
129
+ logs.push(e);
130
+ }, logToMemory = (e) => {
131
+ if (e.raw === !0)
132
+ addToLogArray(e.message);
133
+ else {
134
+ const t = formatLogEntry(
135
+ typeof e.message == "object" ? prepareLogMessage(e.message) : e.message,
136
+ e.severity ?? "Info",
137
+ e.prefix ?? "JavaScript"
138
+ );
139
+ addToLogArray(t);
140
+ }
141
+ };
142
+ class Logger extends EventTarget {
143
+ // constructor
144
+ constructor(t = []) {
145
+ super(), this.handlers = t, this.fatalErrorEvent = "playground-fatal-error";
146
+ }
147
+ /**
148
+ * Get all logs.
149
+ * @returns string[]
150
+ */
151
+ getLogs() {
152
+ return this.handlers.includes(logToMemory) ? [...logs] : (this.error(`Logs aren't stored because the logToMemory handler isn't registered.
153
+ If you're using a custom logger instance, make sure to register logToMemory handler.
154
+ `), []);
155
+ }
156
+ /**
157
+ * Log message with severity.
158
+ *
159
+ * @param message any
160
+ * @param severity LogSeverity
161
+ * @param raw boolean
162
+ * @param args any
163
+ */
164
+ logMessage(t, ...r) {
165
+ for (const s of this.handlers)
166
+ s(t, ...r);
167
+ }
168
+ /**
169
+ * Log message
170
+ *
171
+ * @param message any
172
+ * @param args any
173
+ */
174
+ log(t, ...r) {
175
+ this.logMessage(
176
+ {
177
+ message: t,
178
+ severity: void 0,
179
+ prefix: "JavaScript",
180
+ raw: !1
181
+ },
182
+ ...r
183
+ );
184
+ }
185
+ /**
186
+ * Log debug message
187
+ *
188
+ * @param message any
189
+ * @param args any
190
+ */
191
+ debug(t, ...r) {
192
+ this.logMessage(
193
+ {
194
+ message: t,
195
+ severity: "Debug",
196
+ prefix: "JavaScript",
197
+ raw: !1
198
+ },
199
+ ...r
200
+ );
201
+ }
202
+ /**
203
+ * Log info message
204
+ *
205
+ * @param message any
206
+ * @param args any
207
+ */
208
+ info(t, ...r) {
209
+ this.logMessage(
210
+ {
211
+ message: t,
212
+ severity: "Info",
213
+ prefix: "JavaScript",
214
+ raw: !1
215
+ },
216
+ ...r
217
+ );
218
+ }
219
+ /**
220
+ * Log warning message
221
+ *
222
+ * @param message any
223
+ * @param args any
224
+ */
225
+ warn(t, ...r) {
226
+ this.logMessage(
227
+ {
228
+ message: t,
229
+ severity: "Warn",
230
+ prefix: "JavaScript",
231
+ raw: !1
232
+ },
233
+ ...r
234
+ );
235
+ }
236
+ /**
237
+ * Log error message
238
+ *
239
+ * @param message any
240
+ * @param args any
241
+ */
242
+ error(t, ...r) {
243
+ this.logMessage(
244
+ {
245
+ message: t,
246
+ severity: "Error",
247
+ prefix: "JavaScript",
248
+ raw: !1
249
+ },
250
+ ...r
251
+ );
252
+ }
253
+ }
254
+ const logger = new Logger([logToMemory, logToConsole]), formatLogEntry = (e, t, r) => {
255
+ const s = /* @__PURE__ */ new Date(), n = new Intl.DateTimeFormat("en-GB", {
256
+ year: "numeric",
257
+ month: "short",
258
+ day: "2-digit",
259
+ timeZone: "UTC"
260
+ }).format(s).replace(/ /g, "-"), o = new Intl.DateTimeFormat("en-GB", {
261
+ hour: "2-digit",
262
+ minute: "2-digit",
263
+ second: "2-digit",
264
+ hour12: !1,
265
+ timeZone: "UTC",
266
+ timeZoneName: "short"
267
+ }).format(s);
268
+ return `[${n + " " + o}] ${r} ${t}: ${e}`;
269
+ };
105
270
  class UnhandledRejectionsTarget extends EventTarget {
106
271
  constructor() {
107
272
  super(...arguments), this.listenersCount = 0;
@@ -200,13 +365,13 @@ CLI option:
200
365
  let logged = !1;
201
366
  function showCriticalErrorBox(e) {
202
367
  if (!logged && (logged = !0, !(e != null && e.trim().startsWith("Program terminated with exit")))) {
203
- console.log(`${redBg}
368
+ logger.log(`${redBg}
204
369
  ${eol}
205
370
  ${bold} WASM ERROR${reset}${redBg}`);
206
371
  for (const t of e.split(`
207
372
  `))
208
- console.log(`${eol} ${t} `);
209
- console.log(`${reset}`);
373
+ logger.log(`${eol} ${t} `);
374
+ logger.log(`${reset}`);
210
375
  }
211
376
  }
212
377
  function extractPHPFunctionsFromStack(e) {
@@ -309,8 +474,8 @@ function splitShellCommand(e) {
309
474
  const o = [];
310
475
  let i = "";
311
476
  for (let a = 0; a < e.length; a++) {
312
- const c = e[a];
313
- c === "\\" ? ((e[a + 1] === '"' || e[a + 1] === "'") && a++, i += e[a]) : s === 0 ? c === '"' || c === "'" ? (s = 1, n = c) : c.match(/\s/) ? (i.trim().length && o.push(i.trim()), i = c) : o.length && !i ? i = o.pop() + c : i += c : s === 1 && (c === n ? (s = 0, n = "") : i += c);
477
+ const l = e[a];
478
+ l === "\\" ? ((e[a + 1] === '"' || e[a + 1] === "'") && a++, i += e[a]) : s === 0 ? l === '"' || l === "'" ? (s = 1, n = l) : l.match(/\s/) ? (i.trim().length && o.push(i.trim()), i = l) : o.length && !i ? i = o.pop() + l : i += l : s === 1 && (l === n ? (s = 0, n = "") : i += l);
314
479
  }
315
480
  return i && o.push(i.trim()), o;
316
481
  }
@@ -327,7 +492,12 @@ function createSpawnHandler(e) {
327
492
  i = t;
328
493
  else
329
494
  throw new Error("Invalid command ", t);
330
- await e(i, o, s), n.emit("spawn", !0);
495
+ try {
496
+ await e(i, o, s);
497
+ } catch (a) {
498
+ n.emit("error", a), typeof a == "object" && a !== null && "message" in a && typeof a.message == "string" && o.stderr(a.message), o.exit(1);
499
+ }
500
+ n.emit("spawn", !0);
331
501
  }), n;
332
502
  };
333
503
  }
@@ -398,10 +568,34 @@ ReadableStream.prototype[Symbol.asyncIterator] || (ReadableStream.prototype[Symb
398
568
  }
399
569
  }, ReadableStream.prototype.iterate = // @ts-ignore
400
570
  ReadableStream.prototype[Symbol.asyncIterator]);
571
+ const responseTexts = {
572
+ 500: "Internal Server Error",
573
+ 502: "Bad Gateway",
574
+ 404: "Not Found",
575
+ 403: "Forbidden",
576
+ 401: "Unauthorized",
577
+ 400: "Bad Request",
578
+ 301: "Moved Permanently",
579
+ 302: "Found",
580
+ 307: "Temporary Redirect",
581
+ 308: "Permanent Redirect",
582
+ 204: "No Content",
583
+ 201: "Created",
584
+ 200: "OK"
585
+ };
401
586
  class PHPResponse {
402
587
  constructor(t, r, s, n = "", o = 0) {
403
588
  this.httpStatusCode = t, this.headers = r, this.bytes = s, this.exitCode = o, this.errors = n;
404
589
  }
590
+ static forHttpCode(t, r = "") {
591
+ return new PHPResponse(
592
+ t,
593
+ {},
594
+ new TextEncoder().encode(
595
+ r || responseTexts[t] || ""
596
+ )
597
+ );
598
+ }
405
599
  static fromRawData(t) {
406
600
  return new PHPResponse(
407
601
  t.httpStatusCode,
@@ -443,411 +637,7 @@ const SupportedPHPVersions = [
443
637
  "7.2",
444
638
  "7.1",
445
639
  "7.0"
446
- ], LatestSupportedPHPVersion = SupportedPHPVersions[0], DEFAULT_BASE_URL = "http://example.com";
447
- function toRelativeUrl(e) {
448
- return e.toString().substring(e.origin.length);
449
- }
450
- function removePathPrefix(e, t) {
451
- return !t || !e.startsWith(t) ? e : e.substring(t.length);
452
- }
453
- function ensurePathPrefix(e, t) {
454
- return !t || e.startsWith(t) ? e : t + e;
455
- }
456
- async function encodeAsMultipart(e) {
457
- const t = `----${Math.random().toString(36).slice(2)}`, r = `multipart/form-data; boundary=${t}`, s = new TextEncoder(), n = [];
458
- for (const [c, l] of Object.entries(e))
459
- n.push(`--${t}\r
460
- `), n.push(`Content-Disposition: form-data; name="${c}"`), l instanceof File && n.push(`; filename="${l.name}"`), n.push(`\r
461
- `), l instanceof File && (n.push("Content-Type: application/octet-stream"), n.push(`\r
462
- `)), n.push(`\r
463
- `), l instanceof File ? n.push(await fileToUint8Array(l)) : n.push(l), n.push(`\r
464
- `);
465
- n.push(`--${t}--\r
466
- `);
467
- const o = n.reduce((c, l) => c + l.length, 0), i = new Uint8Array(o);
468
- let a = 0;
469
- for (const c of n)
470
- i.set(
471
- typeof c == "string" ? s.encode(c) : c,
472
- a
473
- ), a += c.length;
474
- return { bytes: i, contentType: r };
475
- }
476
- function fileToUint8Array(e) {
477
- return new Promise((t) => {
478
- const r = new FileReader();
479
- r.onload = () => {
480
- t(new Uint8Array(r.result));
481
- }, r.readAsArrayBuffer(e);
482
- });
483
- }
484
- class HttpCookieStore {
485
- constructor() {
486
- this.cookies = {};
487
- }
488
- rememberCookiesFromResponseHeaders(t) {
489
- if (t != null && t["set-cookie"])
490
- for (const r of t["set-cookie"])
491
- try {
492
- if (!r.includes("="))
493
- continue;
494
- const s = r.indexOf("="), n = r.substring(0, s), o = r.substring(s + 1).split(";")[0];
495
- this.cookies[n] = o;
496
- } catch (s) {
497
- console.error(s);
498
- }
499
- }
500
- getCookieRequestHeader() {
501
- const t = [];
502
- for (const r in this.cookies)
503
- t.push(`${r}=${this.cookies[r]}`);
504
- return t.join("; ");
505
- }
506
- }
507
- var g, x, M, v, S, y, T, R, k, I, X, N, ee, L, te;
508
- class PHPRequestHandler {
509
- /**
510
- * @param php - The PHP instance.
511
- * @param config - Request Handler configuration.
512
- */
513
- constructor(t, r = {}) {
514
- /**
515
- * Serves a static file from the PHP filesystem.
516
- *
517
- * @param fsPath - Absolute path of the static file to serve.
518
- * @returns The response.
519
- */
520
- d(this, I);
521
- /**
522
- * Runs the requested PHP file with all the request and $_SERVER
523
- * superglobals populated.
524
- *
525
- * @param request - The request.
526
- * @returns The response.
527
- */
528
- d(this, N);
529
- /**
530
- * Resolve the requested path to the filesystem path of the requested PHP file.
531
- *
532
- * Fall back to index.php as if there was a url rewriting rule in place.
533
- *
534
- * @param requestedPath - The requested pathname.
535
- * @throws {Error} If the requested path doesn't exist.
536
- * @returns The resolved filesystem path.
537
- */
538
- d(this, L);
539
- d(this, g, void 0);
540
- d(this, x, void 0);
541
- d(this, M, void 0);
542
- d(this, v, void 0);
543
- d(this, S, void 0);
544
- d(this, y, void 0);
545
- d(this, T, void 0);
546
- d(this, R, void 0);
547
- d(this, k, void 0);
548
- p(this, R, new Semaphore({ concurrency: 1 }));
549
- const {
550
- documentRoot: s = "/www/",
551
- absoluteUrl: n = typeof location == "object" ? location == null ? void 0 : location.href : "",
552
- rewriteRules: o = []
553
- } = r;
554
- this.php = t, p(this, k, new HttpCookieStore()), p(this, g, s);
555
- const i = new URL(n);
556
- p(this, M, i.hostname), p(this, v, i.port ? Number(i.port) : i.protocol === "https:" ? 443 : 80), p(this, x, (i.protocol || "").replace(":", ""));
557
- const a = u(this, v) !== 443 && u(this, v) !== 80;
558
- p(this, S, [
559
- u(this, M),
560
- a ? `:${u(this, v)}` : ""
561
- ].join("")), p(this, y, i.pathname.replace(/\/+$/, "")), p(this, T, [
562
- `${u(this, x)}://`,
563
- u(this, S),
564
- u(this, y)
565
- ].join("")), this.rewriteRules = o;
566
- }
567
- /**
568
- * Converts a path to an absolute URL based at the PHPRequestHandler
569
- * root.
570
- *
571
- * @param path The server path to convert to an absolute URL.
572
- * @returns The absolute URL.
573
- */
574
- pathToInternalUrl(t) {
575
- return `${this.absoluteUrl}${t}`;
576
- }
577
- /**
578
- * Converts an absolute URL based at the PHPRequestHandler to a relative path
579
- * without the server pathname and scope.
580
- *
581
- * @param internalUrl An absolute URL based at the PHPRequestHandler root.
582
- * @returns The relative path.
583
- */
584
- internalUrlToPath(t) {
585
- const r = new URL(t);
586
- return r.pathname.startsWith(u(this, y)) && (r.pathname = r.pathname.slice(u(this, y).length)), toRelativeUrl(r);
587
- }
588
- get isRequestRunning() {
589
- return u(this, R).running > 0;
590
- }
591
- /**
592
- * The absolute URL of this PHPRequestHandler instance.
593
- */
594
- get absoluteUrl() {
595
- return u(this, T);
596
- }
597
- /**
598
- * The directory in the PHP filesystem where the server will look
599
- * for the files to serve. Default: `/var/www`.
600
- */
601
- get documentRoot() {
602
- return u(this, g);
603
- }
604
- /**
605
- * Serves the request – either by serving a static file, or by
606
- * dispatching it to the PHP runtime.
607
- *
608
- * The request() method mode behaves like a web server and only works if
609
- * the PHP was initialized with a `requestHandler` option (which the online version
610
- * of WordPress Playground does by default).
611
- *
612
- * In the request mode, you pass an object containing the request information
613
- * (method, headers, body, etc.) and the path to the PHP file to run:
614
- *
615
- * ```ts
616
- * const php = PHP.load('7.4', {
617
- * requestHandler: {
618
- * documentRoot: "/www"
619
- * }
620
- * })
621
- * php.writeFile("/www/index.php", `<?php echo file_get_contents("php://input");`);
622
- * const result = await php.request({
623
- * method: "GET",
624
- * headers: {
625
- * "Content-Type": "text/plain"
626
- * },
627
- * body: "Hello world!",
628
- * path: "/www/index.php"
629
- * });
630
- * // result.text === "Hello world!"
631
- * ```
632
- *
633
- * The `request()` method cannot be used in conjunction with `cli()`.
634
- *
635
- * @example
636
- * ```js
637
- * const output = await php.request({
638
- * method: 'GET',
639
- * url: '/index.php',
640
- * headers: {
641
- * 'X-foo': 'bar',
642
- * },
643
- * body: {
644
- * foo: 'bar',
645
- * },
646
- * });
647
- * console.log(output.stdout); // "Hello world!"
648
- * ```
649
- *
650
- * @param request - PHP Request data.
651
- */
652
- async request(t) {
653
- const r = t.url.startsWith("http://") || t.url.startsWith("https://"), s = new URL(
654
- // Remove the hash part of the URL as it's not meant for the server.
655
- t.url.split("#")[0],
656
- r ? void 0 : DEFAULT_BASE_URL
657
- ), n = applyRewriteRules(
658
- removePathPrefix(
659
- decodeURIComponent(s.pathname),
660
- u(this, y)
661
- ),
662
- this.rewriteRules
663
- ), o = joinPaths(u(this, g), n);
664
- return seemsLikeAPHPRequestHandlerPath(o) ? await f(this, N, ee).call(this, t, s) : f(this, I, X).call(this, o);
665
- }
666
- }
667
- g = new WeakMap(), x = new WeakMap(), M = new WeakMap(), v = new WeakMap(), S = new WeakMap(), y = new WeakMap(), T = new WeakMap(), R = new WeakMap(), k = new WeakMap(), I = new WeakSet(), X = function(t) {
668
- if (!this.php.fileExists(t))
669
- return new PHPResponse(
670
- 404,
671
- // Let the service worker know that no static file was found
672
- // and that it's okay to issue a real fetch() to the server.
673
- {
674
- "x-file-type": ["static"]
675
- },
676
- new TextEncoder().encode("404 File not found")
677
- );
678
- const r = this.php.readFileAsBuffer(t);
679
- return new PHPResponse(
680
- 200,
681
- {
682
- "content-length": [`${r.byteLength}`],
683
- // @TODO: Infer the content-type from the arrayBuffer instead of the file path.
684
- // The code below won't return the correct mime-type if the extension
685
- // was tampered with.
686
- "content-type": [inferMimeType(t)],
687
- "accept-ranges": ["bytes"],
688
- "cache-control": ["public, max-age=0"]
689
- },
690
- r
691
- );
692
- }, N = new WeakSet(), ee = async function(t, r) {
693
- var n;
694
- if (u(this, R).running > 0 && ((n = t.headers) == null ? void 0 : n["x-request-issuer"]) === "php")
695
- return console.warn(
696
- "Possible deadlock: Called request() before the previous request() have finished. PHP likely issued an HTTP call to itself. Normally this would lead to infinite waiting as Request 1 holds the lock that the Request 2 is waiting to acquire. That's not useful, so PHPRequestHandler will return error 502 instead."
697
- ), new PHPResponse(
698
- 502,
699
- {},
700
- new TextEncoder().encode("502 Bad Gateway")
701
- );
702
- const s = await u(this, R).acquire();
703
- try {
704
- let o = "GET";
705
- const i = {
706
- host: u(this, S),
707
- ...normalizeHeaders(t.headers || {}),
708
- cookie: u(this, k).getCookieRequestHeader()
709
- };
710
- let a = t.body;
711
- if (typeof a == "object" && !(a instanceof Uint8Array)) {
712
- o = "POST";
713
- const { bytes: l, contentType: h } = await encodeAsMultipart(a);
714
- a = l, i["content-type"] = h;
715
- }
716
- let c;
717
- try {
718
- c = f(this, L, te).call(this, decodeURIComponent(r.pathname));
719
- } catch {
720
- return new PHPResponse(
721
- 404,
722
- {},
723
- new TextEncoder().encode("404 File not found")
724
- );
725
- }
726
- try {
727
- const l = await this.php.run({
728
- relativeUri: ensurePathPrefix(
729
- toRelativeUrl(r),
730
- u(this, y)
731
- ),
732
- protocol: u(this, x),
733
- method: t.method || o,
734
- $_SERVER: {
735
- REMOTE_ADDR: "127.0.0.1",
736
- DOCUMENT_ROOT: u(this, g),
737
- HTTPS: u(this, T).startsWith("https://") ? "on" : ""
738
- },
739
- body: a,
740
- scriptPath: c,
741
- headers: i
742
- });
743
- return u(this, k).rememberCookiesFromResponseHeaders(
744
- l.headers
745
- ), l;
746
- } catch (l) {
747
- const h = l;
748
- if (h != null && h.response)
749
- return h.response;
750
- throw l;
751
- }
752
- } finally {
753
- s();
754
- }
755
- }, L = new WeakSet(), te = function(t) {
756
- let r = removePathPrefix(t, u(this, y));
757
- r = applyRewriteRules(r, this.rewriteRules), r.includes(".php") ? r = r.split(".php")[0] + ".php" : this.php.isDir(`${u(this, g)}${r}`) ? (r.endsWith("/") || (r = `${r}/`), r = `${r}index.php`) : r = "/index.php";
758
- const s = `${u(this, g)}${r}`;
759
- if (this.php.fileExists(s))
760
- return s;
761
- throw new Error(`File not found: ${s}`);
762
- };
763
- function inferMimeType(e) {
764
- switch (e.split(".").pop()) {
765
- case "css":
766
- return "text/css";
767
- case "js":
768
- return "application/javascript";
769
- case "png":
770
- return "image/png";
771
- case "jpg":
772
- case "jpeg":
773
- return "image/jpeg";
774
- case "gif":
775
- return "image/gif";
776
- case "svg":
777
- return "image/svg+xml";
778
- case "woff":
779
- return "font/woff";
780
- case "woff2":
781
- return "font/woff2";
782
- case "ttf":
783
- return "font/ttf";
784
- case "otf":
785
- return "font/otf";
786
- case "eot":
787
- return "font/eot";
788
- case "ico":
789
- return "image/x-icon";
790
- case "html":
791
- return "text/html";
792
- case "json":
793
- return "application/json";
794
- case "xml":
795
- return "application/xml";
796
- case "txt":
797
- case "md":
798
- return "text/plain";
799
- case "pdf":
800
- return "application/pdf";
801
- case "webp":
802
- return "image/webp";
803
- case "mp3":
804
- return "audio/mpeg";
805
- case "mp4":
806
- return "video/mp4";
807
- case "csv":
808
- return "text/csv";
809
- case "xls":
810
- return "application/vnd.ms-excel";
811
- case "xlsx":
812
- return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
813
- case "doc":
814
- return "application/msword";
815
- case "docx":
816
- return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
817
- case "ppt":
818
- return "application/vnd.ms-powerpoint";
819
- case "pptx":
820
- return "application/vnd.openxmlformats-officedocument.presentationml.presentation";
821
- case "zip":
822
- return "application/zip";
823
- case "rar":
824
- return "application/x-rar-compressed";
825
- case "tar":
826
- return "application/x-tar";
827
- case "gz":
828
- return "application/gzip";
829
- case "7z":
830
- return "application/x-7z-compressed";
831
- default:
832
- return "application-octet-stream";
833
- }
834
- }
835
- function seemsLikeAPHPRequestHandlerPath(e) {
836
- return seemsLikeAPHPFile(e) || seemsLikeADirectoryRoot(e);
837
- }
838
- function seemsLikeAPHPFile(e) {
839
- return e.endsWith(".php") || e.includes(".php/");
840
- }
841
- function seemsLikeADirectoryRoot(e) {
842
- return !e.split("/").pop().includes(".");
843
- }
844
- function applyRewriteRules(e, t) {
845
- for (const r of t)
846
- if (new RegExp(r.match).test(e))
847
- return e.replace(r.match, r.replacement);
848
- return e;
849
- }
850
- const FileErrorCodes = {
640
+ ], LatestSupportedPHPVersion = SupportedPHPVersions[0], FileErrorCodes = {
851
641
  0: "No error occurred. System call completed successfully.",
852
642
  1: "Argument list too long.",
853
643
  2: "Permission denied.",
@@ -938,10 +728,10 @@ function rethrowFileSystemError(e = "") {
938
728
  try {
939
729
  return o.apply(this, i);
940
730
  } catch (a) {
941
- const c = typeof a == "object" ? a == null ? void 0 : a.errno : null;
942
- if (c in FileErrorCodes) {
943
- const l = FileErrorCodes[c], h = typeof i[0] == "string" ? i[0] : null, _ = h !== null ? e.replaceAll("{path}", h) : e;
944
- throw new Error(`${_}: ${l}`, {
731
+ const l = typeof a == "object" ? a == null ? void 0 : a.errno : null;
732
+ if (l in FileErrorCodes) {
733
+ const c = FileErrorCodes[l], h = typeof i[0] == "string" ? i[0] : null, _ = h !== null ? e.replaceAll("{path}", h) : e;
734
+ throw new Error(`${_}: ${c}`, {
945
735
  cause: a
946
736
  });
947
737
  }
@@ -955,7 +745,7 @@ let lastRuntimeId = 0;
955
745
  async function loadPHPRuntime(e, t = {}) {
956
746
  const [r, s, n] = makePromise(), o = e.init(currentJsRuntime, {
957
747
  onAbort(a) {
958
- n(a), console.error(a);
748
+ n(a), logger.error(a);
959
749
  },
960
750
  ENV: {},
961
751
  // Emscripten sometimes prepends a '/' to the path, which
@@ -997,16 +787,16 @@ class PHPExecutionFailureError extends Error {
997
787
  super(t), this.response = r, this.source = s;
998
788
  }
999
789
  }
1000
- var b, C, H, w, E, P, F, O, re, U, se, W, ne, B, ie, D, oe, $, ae, q, le, z, ce, j, ue, V, de, G, he, J, pe, Q, fe, Y, me, K, _e;
790
+ var P, E, v, y, w, g, b, R, q, x, z, T, U, k, $, C, V, F, G, H, j, M, J, I, Q, N, Y, A, Z, L, K, O, X, W, ee, B, te;
1001
791
  class BasePHP {
1002
792
  /**
1003
793
  * Initializes a PHP runtime.
1004
794
  *
1005
795
  * @internal
1006
796
  * @param PHPRuntime - Optional. PHP Runtime ID as initialized by loadPHPRuntime.
1007
- * @param serverOptions - Optional. Options for the PHPRequestHandler. If undefined, no request handler will be initialized.
797
+ * @param requestHandlerOptions - Optional. Options for the PHPRequestHandler. If undefined, no request handler will be initialized.
1008
798
  */
1009
- constructor(e, t) {
799
+ constructor(e) {
1010
800
  /**
1011
801
  * Prepares the $_SERVER entries for the PHP runtime.
1012
802
  *
@@ -1016,46 +806,46 @@ class BasePHP {
1016
806
  * was provided.
1017
807
  * @returns Computed $_SERVER entries.
1018
808
  */
1019
- d(this, O);
1020
- d(this, U);
1021
- d(this, W);
1022
- d(this, B);
1023
- d(this, D);
1024
- d(this, $);
1025
- d(this, q);
1026
- d(this, z);
1027
- d(this, j);
1028
- d(this, V);
1029
- d(this, G);
1030
- d(this, J);
1031
- d(this, Q);
1032
- d(this, Y);
1033
- d(this, K);
1034
- d(this, b, void 0);
1035
- d(this, C, void 0);
1036
- d(this, H, void 0);
1037
- d(this, w, void 0);
1038
- d(this, E, void 0);
1039
- d(this, P, void 0);
1040
- d(this, F, void 0);
1041
- p(this, b, []), p(this, w, !1), p(this, E, null), p(this, P, /* @__PURE__ */ new Map()), p(this, F, []), this.semaphore = new Semaphore({ concurrency: 1 }), e !== void 0 && this.initializeRuntime(e), t && (this.requestHandler = new PHPRequestHandler(this, t));
809
+ u(this, R);
810
+ u(this, x);
811
+ u(this, T);
812
+ u(this, k);
813
+ u(this, C);
814
+ u(this, F);
815
+ u(this, H);
816
+ u(this, M);
817
+ u(this, I);
818
+ u(this, N);
819
+ u(this, A);
820
+ u(this, L);
821
+ u(this, O);
822
+ u(this, W);
823
+ u(this, B);
824
+ u(this, P, void 0);
825
+ u(this, E, void 0);
826
+ u(this, v, void 0);
827
+ u(this, y, void 0);
828
+ u(this, w, void 0);
829
+ u(this, g, void 0);
830
+ u(this, b, void 0);
831
+ m(this, P, []), m(this, y, !1), m(this, w, null), m(this, g, /* @__PURE__ */ new Map()), m(this, b, []), this.semaphore = new Semaphore({ concurrency: 1 }), e !== void 0 && this.initializeRuntime(e);
1042
832
  }
1043
833
  addEventListener(e, t) {
1044
- u(this, P).has(e) || u(this, P).set(e, /* @__PURE__ */ new Set()), u(this, P).get(e).add(t);
834
+ d(this, g).has(e) || d(this, g).set(e, /* @__PURE__ */ new Set()), d(this, g).get(e).add(t);
1045
835
  }
1046
836
  removeEventListener(e, t) {
1047
837
  var r;
1048
- (r = u(this, P).get(e)) == null || r.delete(t);
838
+ (r = d(this, g).get(e)) == null || r.delete(t);
1049
839
  }
1050
840
  dispatchEvent(e) {
1051
- const t = u(this, P).get(e.type);
841
+ const t = d(this, g).get(e.type);
1052
842
  if (t)
1053
843
  for (const r of t)
1054
844
  r(e);
1055
845
  }
1056
846
  /** @inheritDoc */
1057
847
  async onMessage(e) {
1058
- u(this, F).push(e);
848
+ d(this, b).push(e);
1059
849
  }
1060
850
  /** @inheritDoc */
1061
851
  async setSpawnHandler(handler) {
@@ -1084,13 +874,13 @@ class BasePHP {
1084
874
  if (!t)
1085
875
  throw new Error("Invalid PHP runtime id.");
1086
876
  this[__private__dont__use] = t, t.onMessage = async (r) => {
1087
- for (const s of u(this, F)) {
877
+ for (const s of d(this, b)) {
1088
878
  const n = await s(r);
1089
879
  if (n)
1090
880
  return n;
1091
881
  }
1092
882
  return "";
1093
- }, p(this, E, improveWASMErrorReporting(t)), this.dispatchEvent({
883
+ }, m(this, w, improveWASMErrorReporting(t)), this.dispatchEvent({
1094
884
  type: "runtime.initialized"
1095
885
  });
1096
886
  }
@@ -1105,13 +895,13 @@ class BasePHP {
1105
895
  throw new Error(
1106
896
  "Could not set SAPI name. This can only be done before the PHP WASM module is initialized.Did you already dispatch any requests?"
1107
897
  );
1108
- p(this, H, e);
898
+ m(this, v, e);
1109
899
  }
1110
900
  /** @inheritDoc */
1111
901
  setPhpIniPath(e) {
1112
- if (u(this, w))
902
+ if (d(this, y))
1113
903
  throw new Error("Cannot set PHP ini path after calling run().");
1114
- p(this, C, e), this[__private__dont__use].ccall(
904
+ m(this, E, e), this[__private__dont__use].ccall(
1115
905
  "wasm_set_phpini_path",
1116
906
  null,
1117
907
  ["string"],
@@ -1120,17 +910,22 @@ class BasePHP {
1120
910
  }
1121
911
  /** @inheritDoc */
1122
912
  setPhpIniEntry(e, t) {
1123
- if (u(this, w))
913
+ if (d(this, y))
1124
914
  throw new Error("Cannot set PHP ini entries after calling run().");
1125
- u(this, b).push([e, t]);
915
+ d(this, P).push([e, t]);
1126
916
  }
1127
917
  /** @inheritDoc */
1128
918
  chdir(e) {
1129
919
  this[__private__dont__use].FS.chdir(e);
1130
920
  }
1131
- /** @inheritDoc */
921
+ /**
922
+ * Do not use. Use new PHPRequestHandler() instead.
923
+ * @deprecated
924
+ */
1132
925
  async request(e) {
1133
- if (!this.requestHandler)
926
+ if (logger.warn(
927
+ "PHP.request() is deprecated. Please use new PHPRequestHandler() instead."
928
+ ), !this.requestHandler)
1134
929
  throw new Error("No request handler available.");
1135
930
  return this.requestHandler.request(e);
1136
931
  }
@@ -1139,30 +934,30 @@ class BasePHP {
1139
934
  const t = await this.semaphore.acquire();
1140
935
  let r;
1141
936
  try {
1142
- if (u(this, w) || (f(this, U, se).call(this), p(this, w, !0)), e.scriptPath && !this.fileExists(e.scriptPath))
937
+ if (d(this, y) || (p(this, x, z).call(this), m(this, y, !0)), e.scriptPath && !this.fileExists(e.scriptPath))
1143
938
  throw new Error(
1144
939
  `The script path "${e.scriptPath}" does not exist.`
1145
940
  );
1146
- f(this, G, he).call(this, e.scriptPath || ""), f(this, B, ie).call(this, e.relativeUri || ""), f(this, z, ce).call(this, e.method || "GET");
1147
- const s = normalizeHeaders(e.headers || {}), n = s.host || "example.com:443", o = f(this, q, le).call(this, n, e.protocol || "http");
1148
- f(this, D, oe).call(this, n), f(this, $, ae).call(this, o), f(this, j, ue).call(this, s), e.body && (r = f(this, V, de).call(this, e.body)), typeof e.code == "string" && f(this, Y, me).call(this, " ?>" + e.code);
1149
- const i = f(this, O, re).call(this, e.$_SERVER, s, o);
1150
- for (const l in i)
1151
- f(this, J, pe).call(this, l, i[l]);
941
+ p(this, A, Z).call(this, e.scriptPath || ""), p(this, k, $).call(this, e.relativeUri || ""), p(this, M, J).call(this, e.method || "GET");
942
+ const s = normalizeHeaders(e.headers || {}), n = s.host || "example.com:443", o = p(this, H, j).call(this, n, e.protocol || "http");
943
+ p(this, C, V).call(this, n), p(this, F, G).call(this, o), p(this, I, Q).call(this, s), e.body && (r = p(this, N, Y).call(this, e.body)), typeof e.code == "string" && p(this, W, ee).call(this, " ?>" + e.code);
944
+ const i = p(this, R, q).call(this, e.$_SERVER, s, o);
945
+ for (const c in i)
946
+ p(this, L, K).call(this, c, i[c]);
1152
947
  const a = e.env || {};
1153
- for (const l in a)
1154
- f(this, Q, fe).call(this, l, a[l]);
1155
- const c = await f(this, K, _e).call(this);
1156
- if (c.exitCode !== 0) {
1157
- console.warn("PHP.run() output was:", c.text);
1158
- const l = new PHPExecutionFailureError(
1159
- `PHP.run() failed with exit code ${c.exitCode} and the following output: ` + c.errors,
1160
- c,
948
+ for (const c in a)
949
+ p(this, O, X).call(this, c, a[c]);
950
+ const l = await p(this, B, te).call(this);
951
+ if (l.exitCode !== 0) {
952
+ logger.warn("PHP.run() output was:", l.text);
953
+ const c = new PHPExecutionFailureError(
954
+ `PHP.run() failed with exit code ${l.exitCode} and the following output: ` + l.errors,
955
+ l,
1161
956
  "request"
1162
957
  );
1163
- throw console.error(l), l;
958
+ throw logger.error(c), c;
1164
959
  }
1165
- return c;
960
+ return l;
1166
961
  } catch (s) {
1167
962
  throw this.dispatchEvent({
1168
963
  type: "request.error",
@@ -1247,7 +1042,7 @@ class BasePHP {
1247
1042
  }
1248
1043
  return r;
1249
1044
  } catch (r) {
1250
- return console.error(r, { path: e }), [];
1045
+ return logger.error(r, { path: e }), [];
1251
1046
  }
1252
1047
  }
1253
1048
  isDir(e) {
@@ -1278,7 +1073,7 @@ class BasePHP {
1278
1073
  this.exit();
1279
1074
  } catch {
1280
1075
  }
1281
- this.initializeRuntime(e), u(this, C) && this.setPhpIniPath(u(this, C)), u(this, H) && this.setSapiName(u(this, H)), t && copyFS(r, this[__private__dont__use].FS, t);
1076
+ this.initializeRuntime(e), d(this, E) && this.setPhpIniPath(d(this, E)), d(this, v) && this.setSapiName(d(this, v)), t && copyFS(r, this[__private__dont__use].FS, t);
1282
1077
  }
1283
1078
  exit(e = 0) {
1284
1079
  this.dispatchEvent({
@@ -1288,10 +1083,13 @@ class BasePHP {
1288
1083
  this[__private__dont__use]._exit(e);
1289
1084
  } catch {
1290
1085
  }
1291
- p(this, w, !1), p(this, E, null), delete this[__private__dont__use].onMessage, delete this[__private__dont__use];
1086
+ m(this, y, !1), m(this, w, null), delete this[__private__dont__use].onMessage, delete this[__private__dont__use];
1087
+ }
1088
+ [Symbol.dispose]() {
1089
+ d(this, y) && this.exit(0);
1292
1090
  }
1293
1091
  }
1294
- b = new WeakMap(), C = new WeakMap(), H = new WeakMap(), w = new WeakMap(), E = new WeakMap(), P = new WeakMap(), F = new WeakMap(), O = new WeakSet(), re = function(e, t, r) {
1092
+ P = new WeakMap(), E = new WeakMap(), v = new WeakMap(), y = new WeakMap(), w = new WeakMap(), g = new WeakMap(), b = new WeakMap(), R = new WeakSet(), q = function(e, t, r) {
1295
1093
  const s = {
1296
1094
  ...e || {}
1297
1095
  };
@@ -1301,7 +1099,7 @@ b = new WeakMap(), C = new WeakMap(), H = new WeakMap(), w = new WeakMap(), E =
1301
1099
  ["content-type", "content-length"].includes(n.toLowerCase()) && (o = ""), s[`${o}${n.toUpperCase().replace(/-/g, "_")}`] = t[n];
1302
1100
  }
1303
1101
  return s;
1304
- }, U = new WeakSet(), se = function() {
1102
+ }, x = new WeakSet(), z = function() {
1305
1103
  if (this.setPhpIniEntry("auto_prepend_file", "/internal/consts.php"), this.fileExists("/internal/consts.php") || this.writeFile(
1306
1104
  "/internal/consts.php",
1307
1105
  `<?php
@@ -1313,8 +1111,8 @@ b = new WeakMap(), C = new WeakMap(), H = new WeakMap(), w = new WeakMap(), E =
1313
1111
  }
1314
1112
  }
1315
1113
  }`
1316
- ), u(this, b).length > 0) {
1317
- const e = u(this, b).map(([t, r]) => `${t}=${r}`).join(`
1114
+ ), d(this, P).length > 0) {
1115
+ const e = d(this, P).map(([t, r]) => `${t}=${r}`).join(`
1318
1116
  `) + `
1319
1117
 
1320
1118
  `;
@@ -1326,7 +1124,7 @@ b = new WeakMap(), C = new WeakMap(), H = new WeakMap(), w = new WeakMap(), E =
1326
1124
  );
1327
1125
  }
1328
1126
  this[__private__dont__use].ccall("php_wasm_init", null, [], []);
1329
- }, W = new WeakSet(), ne = function() {
1127
+ }, T = new WeakSet(), U = function() {
1330
1128
  const e = "/internal/headers.json";
1331
1129
  if (!this.fileExists(e))
1332
1130
  throw new Error(
@@ -1343,7 +1141,7 @@ b = new WeakMap(), C = new WeakMap(), H = new WeakMap(), w = new WeakMap(), E =
1343
1141
  headers: r,
1344
1142
  httpStatusCode: t.status
1345
1143
  };
1346
- }, B = new WeakSet(), ie = function(e) {
1144
+ }, k = new WeakSet(), $ = function(e) {
1347
1145
  if (this[__private__dont__use].ccall(
1348
1146
  "wasm_set_request_uri",
1349
1147
  null,
@@ -1358,35 +1156,35 @@ b = new WeakMap(), C = new WeakMap(), H = new WeakMap(), w = new WeakMap(), E =
1358
1156
  [t]
1359
1157
  );
1360
1158
  }
1361
- }, D = new WeakSet(), oe = function(e) {
1159
+ }, C = new WeakSet(), V = function(e) {
1362
1160
  this[__private__dont__use].ccall(
1363
1161
  "wasm_set_request_host",
1364
1162
  null,
1365
1163
  [STRING],
1366
1164
  [e]
1367
1165
  );
1368
- }, $ = new WeakSet(), ae = function(e) {
1166
+ }, F = new WeakSet(), G = function(e) {
1369
1167
  this[__private__dont__use].ccall(
1370
1168
  "wasm_set_request_port",
1371
1169
  null,
1372
1170
  [NUMBER],
1373
1171
  [e]
1374
1172
  );
1375
- }, q = new WeakSet(), le = function(e, t) {
1173
+ }, H = new WeakSet(), j = function(e, t) {
1376
1174
  let r;
1377
1175
  try {
1378
1176
  r = parseInt(new URL(e).port, 10);
1379
1177
  } catch {
1380
1178
  }
1381
1179
  return (!r || isNaN(r) || r === 80) && (r = t === "https" ? 443 : 80), r;
1382
- }, z = new WeakSet(), ce = function(e) {
1180
+ }, M = new WeakSet(), J = function(e) {
1383
1181
  this[__private__dont__use].ccall(
1384
1182
  "wasm_set_request_method",
1385
1183
  null,
1386
1184
  [STRING],
1387
1185
  [e]
1388
1186
  );
1389
- }, j = new WeakSet(), ue = function(e) {
1187
+ }, I = new WeakSet(), Q = function(e) {
1390
1188
  e.cookie && this[__private__dont__use].ccall(
1391
1189
  "wasm_set_cookies",
1392
1190
  null,
@@ -1403,9 +1201,9 @@ b = new WeakMap(), C = new WeakMap(), H = new WeakMap(), w = new WeakMap(), E =
1403
1201
  [NUMBER],
1404
1202
  [parseInt(e["content-length"], 10)]
1405
1203
  );
1406
- }, V = new WeakSet(), de = function(e) {
1204
+ }, N = new WeakSet(), Y = function(e) {
1407
1205
  let t, r;
1408
- typeof e == "string" ? (console.warn(
1206
+ typeof e == "string" ? (logger.warn(
1409
1207
  "Passing a string as the request body is deprecated. Please use a Uint8Array instead. See https://github.com/WordPress/wordpress-playground/issues/997 for more details"
1410
1208
  ), r = this[__private__dont__use].lengthBytesUTF8(e), t = r + 1) : (r = e.byteLength, t = e.byteLength);
1411
1209
  const s = this[__private__dont__use].malloc(t);
@@ -1426,45 +1224,45 @@ b = new WeakMap(), C = new WeakMap(), H = new WeakMap(), w = new WeakMap(), E =
1426
1224
  [NUMBER],
1427
1225
  [r]
1428
1226
  ), s;
1429
- }, G = new WeakSet(), he = function(e) {
1227
+ }, A = new WeakSet(), Z = function(e) {
1430
1228
  this[__private__dont__use].ccall(
1431
1229
  "wasm_set_path_translated",
1432
1230
  null,
1433
1231
  [STRING],
1434
1232
  [e]
1435
1233
  );
1436
- }, J = new WeakSet(), pe = function(e, t) {
1234
+ }, L = new WeakSet(), K = function(e, t) {
1437
1235
  this[__private__dont__use].ccall(
1438
1236
  "wasm_add_SERVER_entry",
1439
1237
  null,
1440
1238
  [STRING, STRING],
1441
1239
  [e, t]
1442
1240
  );
1443
- }, Q = new WeakSet(), fe = function(e, t) {
1241
+ }, O = new WeakSet(), X = function(e, t) {
1444
1242
  this[__private__dont__use].ccall(
1445
1243
  "wasm_add_ENV_entry",
1446
1244
  null,
1447
1245
  [STRING, STRING],
1448
1246
  [e, t]
1449
1247
  );
1450
- }, Y = new WeakSet(), me = function(e) {
1248
+ }, W = new WeakSet(), ee = function(e) {
1451
1249
  this[__private__dont__use].ccall(
1452
1250
  "wasm_set_php_code",
1453
1251
  null,
1454
1252
  [STRING],
1455
1253
  [e]
1456
1254
  );
1457
- }, K = new WeakSet(), _e = async function() {
1255
+ }, B = new WeakSet(), te = async function() {
1458
1256
  var n;
1459
1257
  let e, t;
1460
1258
  try {
1461
1259
  e = await new Promise((o, i) => {
1462
- var c;
1463
- t = (l) => {
1464
- console.error(l), console.error(l.error);
1260
+ var l;
1261
+ t = (c) => {
1262
+ logger.error(c), logger.error(c.error);
1465
1263
  const h = new Error("Rethrown");
1466
- h.cause = l.error, h.betterMessage = l.message, i(h);
1467
- }, (c = u(this, E)) == null || c.addEventListener(
1264
+ h.cause = c.error, h.betterMessage = c.message, i(h);
1265
+ }, (l = d(this, w)) == null || l.addEventListener(
1468
1266
  "error",
1469
1267
  t
1470
1268
  );
@@ -1478,19 +1276,19 @@ b = new WeakMap(), C = new WeakMap(), H = new WeakMap(), w = new WeakMap(), E =
1478
1276
  return a instanceof Promise ? a.then(o, i) : o(a);
1479
1277
  });
1480
1278
  } catch (o) {
1481
- for (const l in this)
1482
- typeof this[l] == "function" && (this[l] = () => {
1279
+ for (const c in this)
1280
+ typeof this[c] == "function" && (this[c] = () => {
1483
1281
  throw new Error(
1484
1282
  "PHP runtime has crashed – see the earlier error for details."
1485
1283
  );
1486
1284
  });
1487
1285
  this.functionsMaybeMissingFromAsyncify = getFunctionsMaybeMissingFromAsyncify();
1488
- const i = o, a = "betterMessage" in i ? i.betterMessage : i.message, c = new Error(a);
1489
- throw c.cause = i, console.error(c), c;
1286
+ const i = o, a = "betterMessage" in i ? i.betterMessage : i.message, l = new Error(a);
1287
+ throw l.cause = i, logger.error(l), l;
1490
1288
  } finally {
1491
- (n = u(this, E)) == null || n.removeEventListener("error", t);
1289
+ (n = d(this, w)) == null || n.removeEventListener("error", t);
1492
1290
  }
1493
- const { headers: r, httpStatusCode: s } = f(this, W, ne).call(this);
1291
+ const { headers: r, httpStatusCode: s } = p(this, T, U).call(this);
1494
1292
  return new PHPResponse(
1495
1293
  e === 0 ? s : 500,
1496
1294
  r,
@@ -1601,50 +1399,50 @@ function expose(e, t = globalThis, r = ["*"]) {
1601
1399
  console.warn(`Invalid origin '${n.origin}' for comlink proxy`);
1602
1400
  return;
1603
1401
  }
1604
- const { id: o, type: i, path: a } = Object.assign({ path: [] }, n.data), c = (n.data.argumentList || []).map(fromWireValue);
1605
- let l;
1402
+ const { id: o, type: i, path: a } = Object.assign({ path: [] }, n.data), l = (n.data.argumentList || []).map(fromWireValue);
1403
+ let c;
1606
1404
  try {
1607
- const h = a.slice(0, -1).reduce((m, A) => m[A], e), _ = a.reduce((m, A) => m[A], e);
1405
+ const h = a.slice(0, -1).reduce((f, S) => f[S], e), _ = a.reduce((f, S) => f[S], e);
1608
1406
  switch (i) {
1609
1407
  case "GET":
1610
- l = _;
1408
+ c = _;
1611
1409
  break;
1612
1410
  case "SET":
1613
- h[a.slice(-1)[0]] = fromWireValue(n.data.value), l = !0;
1411
+ h[a.slice(-1)[0]] = fromWireValue(n.data.value), c = !0;
1614
1412
  break;
1615
1413
  case "APPLY":
1616
- l = _.apply(h, c);
1414
+ c = _.apply(h, l);
1617
1415
  break;
1618
1416
  case "CONSTRUCT":
1619
1417
  {
1620
- const m = new _(...c);
1621
- l = proxy(m);
1418
+ const f = new _(...l);
1419
+ c = proxy(f);
1622
1420
  }
1623
1421
  break;
1624
1422
  case "ENDPOINT":
1625
1423
  {
1626
- const { port1: m, port2: A } = new MessageChannel();
1627
- expose(e, A), l = transfer(m, [m]);
1424
+ const { port1: f, port2: S } = new MessageChannel();
1425
+ expose(e, S), c = transfer(f, [f]);
1628
1426
  }
1629
1427
  break;
1630
1428
  case "RELEASE":
1631
- l = void 0;
1429
+ c = void 0;
1632
1430
  break;
1633
1431
  default:
1634
1432
  return;
1635
1433
  }
1636
1434
  } catch (h) {
1637
- l = { value: h, [throwMarker]: 0 };
1435
+ c = { value: h, [throwMarker]: 0 };
1638
1436
  }
1639
- Promise.resolve(l).catch((h) => ({ value: h, [throwMarker]: 0 })).then((h) => {
1640
- const [_, m] = toWireValue(h);
1641
- t.postMessage(Object.assign(Object.assign({}, _), { id: o }), m), i === "RELEASE" && (t.removeEventListener("message", s), closeEndPoint(t), finalizer in e && typeof e[finalizer] == "function" && e[finalizer]());
1437
+ Promise.resolve(c).catch((h) => ({ value: h, [throwMarker]: 0 })).then((h) => {
1438
+ const [_, f] = toWireValue(h);
1439
+ t.postMessage(Object.assign(Object.assign({}, _), { id: o }), f), i === "RELEASE" && (t.removeEventListener("message", s), closeEndPoint(t), finalizer in e && typeof e[finalizer] == "function" && e[finalizer]());
1642
1440
  }).catch((h) => {
1643
- const [_, m] = toWireValue({
1441
+ const [_, f] = toWireValue({
1644
1442
  value: new TypeError("Unserializable return value"),
1645
1443
  [throwMarker]: 0
1646
1444
  });
1647
- t.postMessage(Object.assign(Object.assign({}, _), { id: o }), m);
1445
+ t.postMessage(Object.assign(Object.assign({}, _), { id: o }), f);
1648
1446
  });
1649
1447
  }), t.start && t.start();
1650
1448
  }
@@ -1693,7 +1491,7 @@ function createProxy(e, t = [], r = function() {
1693
1491
  return { then: () => n };
1694
1492
  const a = requestResponseMessage(e, {
1695
1493
  type: "GET",
1696
- path: t.map((c) => c.toString())
1494
+ path: t.map((l) => l.toString())
1697
1495
  }).then(fromWireValue);
1698
1496
  return a.then.bind(a);
1699
1497
  }
@@ -1701,37 +1499,37 @@ function createProxy(e, t = [], r = function() {
1701
1499
  },
1702
1500
  set(o, i, a) {
1703
1501
  throwIfProxyReleased(s);
1704
- const [c, l] = toWireValue(a);
1502
+ const [l, c] = toWireValue(a);
1705
1503
  return requestResponseMessage(e, {
1706
1504
  type: "SET",
1707
1505
  path: [...t, i].map((h) => h.toString()),
1708
- value: c
1709
- }, l).then(fromWireValue);
1506
+ value: l
1507
+ }, c).then(fromWireValue);
1710
1508
  },
1711
1509
  apply(o, i, a) {
1712
1510
  throwIfProxyReleased(s);
1713
- const c = t[t.length - 1];
1714
- if (c === createEndpoint)
1511
+ const l = t[t.length - 1];
1512
+ if (l === createEndpoint)
1715
1513
  return requestResponseMessage(e, {
1716
1514
  type: "ENDPOINT"
1717
1515
  }).then(fromWireValue);
1718
- if (c === "bind")
1516
+ if (l === "bind")
1719
1517
  return createProxy(e, t.slice(0, -1));
1720
- const [l, h] = processArguments(a);
1518
+ const [c, h] = processArguments(a);
1721
1519
  return requestResponseMessage(e, {
1722
1520
  type: "APPLY",
1723
1521
  path: t.map((_) => _.toString()),
1724
- argumentList: l
1522
+ argumentList: c
1725
1523
  }, h).then(fromWireValue);
1726
1524
  },
1727
1525
  construct(o, i) {
1728
1526
  throwIfProxyReleased(s);
1729
- const [a, c] = processArguments(i);
1527
+ const [a, l] = processArguments(i);
1730
1528
  return requestResponseMessage(e, {
1731
1529
  type: "CONSTRUCT",
1732
- path: t.map((l) => l.toString()),
1530
+ path: t.map((c) => c.toString()),
1733
1531
  argumentList: a
1734
- }, c).then(fromWireValue);
1532
+ }, l).then(fromWireValue);
1735
1533
  }
1736
1534
  });
1737
1535
  return registerProxy(n, e), n;
@@ -1820,10 +1618,10 @@ function exposeAPI(e, t) {
1820
1618
  setupTransferHandlers();
1821
1619
  const r = Promise.resolve();
1822
1620
  let s, n;
1823
- const o = new Promise((c, l) => {
1824
- s = c, n = l;
1621
+ const o = new Promise((l, c) => {
1622
+ s = l, n = c;
1825
1623
  }), i = proxyClone(e), a = new Proxy(i, {
1826
- get: (c, l) => l === "isConnected" ? () => r : l === "isReady" ? () => o : l in c ? c[l] : t == null ? void 0 : t[l]
1624
+ get: (l, c) => c === "isConnected" ? () => r : c === "isReady" ? () => o : c in l ? l[c] : t == null ? void 0 : t[c]
1827
1625
  });
1828
1626
  return expose(
1829
1627
  a,
@@ -1846,7 +1644,7 @@ function setupTransferHandlers() {
1846
1644
  }), transferHandlers.set("FUNCTION", {
1847
1645
  canHandle: (r) => typeof r == "function",
1848
1646
  serialize(r) {
1849
- console.debug("[Comlink][Performance] Proxying a function");
1647
+ logger.debug("[Comlink][Performance] Proxying a function");
1850
1648
  const { port1: s, port2: n } = new MessageChannel();
1851
1649
  return expose(r, s), [n, [n]];
1852
1650
  },
@@ -1960,10 +1758,7 @@ class WebPHP extends BasePHP {
1960
1758
  * @returns A new PHP instance
1961
1759
  */
1962
1760
  static async load(t, r = {}) {
1963
- return new WebPHP(
1964
- await WebPHP.loadRuntime(t, r),
1965
- r.requestHandler
1966
- );
1761
+ return new WebPHP(await WebPHP.loadRuntime(t, r));
1967
1762
  }
1968
1763
  static async loadRuntime(t, r = {}) {
1969
1764
  var o;
@@ -1979,17 +1774,33 @@ class WebPHPEndpoint {
1979
1774
  /** @inheritDoc */
1980
1775
  constructor(t, r) {
1981
1776
  _private.set(this, {
1982
- php: t,
1983
- monitor: r
1777
+ monitor: r,
1778
+ requestHandler: t
1984
1779
  }), this.absoluteUrl = t.absoluteUrl, this.documentRoot = t.documentRoot;
1985
1780
  }
1986
- /** @inheritDoc @php-wasm/universal!RequestHandler.pathToInternalUrl */
1781
+ /**
1782
+ * @internal
1783
+ * @deprecated
1784
+ * Do not use this method directly in the code consuming
1785
+ * the web API. It will change or even be removed without
1786
+ * a warning.
1787
+ */
1788
+ __internal_getPHP() {
1789
+ return _private.get(this).php;
1790
+ }
1791
+ async setPrimaryPHP(t) {
1792
+ _private.set(this, {
1793
+ ..._private.get(this),
1794
+ php: t
1795
+ });
1796
+ }
1797
+ /** @inheritDoc @php-wasm/universal!PHPRequestHandler.pathToInternalUrl */
1987
1798
  pathToInternalUrl(t) {
1988
- return _private.get(this).php.pathToInternalUrl(t);
1799
+ return _private.get(this).requestHandler.pathToInternalUrl(t);
1989
1800
  }
1990
- /** @inheritDoc @php-wasm/universal!RequestHandler.internalUrlToPath */
1801
+ /** @inheritDoc @php-wasm/universal!PHPRequestHandler.internalUrlToPath */
1991
1802
  internalUrlToPath(t) {
1992
- return _private.get(this).php.internalUrlToPath(t);
1803
+ return _private.get(this).requestHandler.internalUrlToPath(t);
1993
1804
  }
1994
1805
  /**
1995
1806
  * The onDownloadProgress event listener.
@@ -1999,20 +1810,25 @@ class WebPHPEndpoint {
1999
1810
  return (r = _private.get(this).monitor) == null ? void 0 : r.addEventListener("progress", t);
2000
1811
  }
2001
1812
  /** @inheritDoc @php-wasm/universal!IsomorphicLocalPHP.mv */
2002
- mv(t, r) {
1813
+ async mv(t, r) {
2003
1814
  return _private.get(this).php.mv(t, r);
2004
1815
  }
2005
1816
  /** @inheritDoc @php-wasm/universal!IsomorphicLocalPHP.rmdir */
2006
- rmdir(t, r) {
1817
+ async rmdir(t, r) {
2007
1818
  return _private.get(this).php.rmdir(t, r);
2008
1819
  }
2009
- /** @inheritDoc @php-wasm/universal!RequestHandler.request */
2010
- request(t) {
2011
- return _private.get(this).php.request(t);
1820
+ /** @inheritDoc @php-wasm/universal!PHPRequestHandler.request */
1821
+ async request(t) {
1822
+ return await _private.get(this).requestHandler.request(t);
2012
1823
  }
2013
1824
  /** @inheritDoc @php-wasm/web!WebPHP.run */
2014
1825
  async run(t) {
2015
- return _private.get(this).php.run(t);
1826
+ const { php: r, reap: s } = await _private.get(this).requestHandler.processManager.acquirePHPInstance();
1827
+ try {
1828
+ return await r.run(t);
1829
+ } finally {
1830
+ s();
1831
+ }
2016
1832
  }
2017
1833
  /** @inheritDoc @php-wasm/web!WebPHP.chdir */
2018
1834
  chdir(t) {
@@ -2098,7 +1914,7 @@ async function registerServiceWorker(e, t, r) {
2098
1914
  ) : new PhpWasmError(
2099
1915
  "WordPress Playground uses service workers and may only work on HTTPS and http://localhost/ sites, but the current site is neither."
2100
1916
  );
2101
- console.debug("[window][sw] Registering a Service Worker"), await (await s.register(r, {
1917
+ logger.debug("[window][sw] Registering a Service Worker"), await (await s.register(r, {
2102
1918
  type: "module",
2103
1919
  // Always bypass HTTP cache when fetching the new Service Worker script:
2104
1920
  updateViaCache: "none"
@@ -2107,8 +1923,8 @@ async function registerServiceWorker(e, t, r) {
2107
1923
  async function(i) {
2108
1924
  if (t && i.data.scope !== t)
2109
1925
  return;
2110
- const a = i.data.args || [], c = i.data.method, l = await e[c](...a);
2111
- i.source.postMessage(responseTo(i.data.requestId, l));
1926
+ const a = i.data.args || [], l = i.data.method, c = await e[l](...a);
1927
+ i.source.postMessage(responseTo(i.data.requestId, c));
2112
1928
  }
2113
1929
  ), s.startMessages();
2114
1930
  }