@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/index.js CHANGED
@@ -1,74 +1,74 @@
1
- var ne = (r, e, t) => {
2
- if (!e.has(r))
3
- throw TypeError("Cannot " + t);
1
+ var Z = (e, t, r) => {
2
+ if (!t.has(e))
3
+ throw TypeError("Cannot " + r);
4
4
  };
5
- var a = (r, e, t) => (ne(r, e, "read from private field"), t ? t.call(r) : e.get(r)), c = (r, e, t) => {
6
- if (e.has(r))
5
+ var a = (e, t, r) => (Z(e, t, "read from private field"), r ? r.call(e) : t.get(e)), c = (e, t, r) => {
6
+ if (t.has(e))
7
7
  throw TypeError("Cannot add the same private member more than once");
8
- e instanceof WeakSet ? e.add(r) : e.set(r, t);
9
- }, p = (r, e, t, n) => (ne(r, e, "write to private field"), n ? n.call(r, t) : e.set(r, t), t);
10
- var m = (r, e, t) => (ne(r, e, "access private method"), t);
8
+ t instanceof WeakSet ? t.add(e) : t.set(e, r);
9
+ }, u = (e, t, r, s) => (Z(e, t, "write to private field"), s ? s.call(e, r) : t.set(e, r), r);
10
+ var h = (e, t, r) => (Z(e, t, "access private method"), r);
11
11
  if (typeof File > "u") {
12
- class r extends Blob {
13
- constructor(t, n, s) {
14
- super(t);
15
- let i;
16
- s != null && s.lastModified && (i = /* @__PURE__ */ new Date()), (!i || isNaN(i.getFullYear())) && (i = /* @__PURE__ */ new Date()), this.lastModifiedDate = i, this.lastModified = i.getMilliseconds(), this.name = n || "";
12
+ class e extends Blob {
13
+ constructor(r, s, i) {
14
+ super(r);
15
+ let n;
16
+ i != null && i.lastModified && (n = /* @__PURE__ */ new Date()), (!n || isNaN(n.getFullYear())) && (n = /* @__PURE__ */ new Date()), this.lastModifiedDate = n, this.lastModified = n.getMilliseconds(), this.name = s || "";
17
17
  }
18
18
  }
19
- global.File = r;
19
+ global.File = e;
20
20
  }
21
- function ye(r) {
22
- return new Promise(function(e, t) {
23
- r.onload = r.onerror = function(n) {
24
- r.onload = r.onerror = null, n.type === "load" ? e(r.result) : t(new Error("Failed to read the blob/file"));
21
+ function asPromise(e) {
22
+ return new Promise(function(t, r) {
23
+ e.onload = e.onerror = function(s) {
24
+ e.onload = e.onerror = null, s.type === "load" ? t(e.result) : r(new Error("Failed to read the blob/file"));
25
25
  };
26
26
  });
27
27
  }
28
28
  typeof Blob.prototype.arrayBuffer > "u" && (Blob.prototype.arrayBuffer = function() {
29
- const e = new FileReader();
30
- return e.readAsArrayBuffer(this), ye(e);
29
+ const t = new FileReader();
30
+ return t.readAsArrayBuffer(this), asPromise(t);
31
31
  });
32
32
  typeof Blob.prototype.text > "u" && (Blob.prototype.text = function() {
33
- const e = new FileReader();
34
- return e.readAsText(this), ye(e);
33
+ const t = new FileReader();
34
+ return t.readAsText(this), asPromise(t);
35
35
  });
36
- function Le() {
37
- const r = new Uint8Array([1, 2, 3, 4]), t = new File([r], "test").stream();
36
+ function isByobSupported() {
37
+ const e = new Uint8Array([1, 2, 3, 4]), r = new File([e], "test").stream();
38
38
  try {
39
- return t.getReader({ mode: "byob" }), !0;
39
+ return r.getReader({ mode: "byob" }), !0;
40
40
  } catch {
41
41
  return !1;
42
42
  }
43
43
  }
44
- (typeof Blob.prototype.stream > "u" || !Le()) && (Blob.prototype.stream = function() {
45
- let r = 0;
46
- const e = this;
44
+ (typeof Blob.prototype.stream > "u" || !isByobSupported()) && (Blob.prototype.stream = function() {
45
+ let e = 0;
46
+ const t = this;
47
47
  return new ReadableStream({
48
48
  type: "bytes",
49
49
  // 0.5 MB seems like a reasonable chunk size, let's adjust
50
50
  // this if needed.
51
51
  autoAllocateChunkSize: 512 * 1024,
52
- async pull(t) {
53
- const n = t.byobRequest.view, i = await e.slice(r, r + n.byteLength).arrayBuffer(), o = new Uint8Array(i);
54
- new Uint8Array(n.buffer).set(o);
52
+ async pull(r) {
53
+ const s = r.byobRequest.view, n = await t.slice(e, e + s.byteLength).arrayBuffer(), o = new Uint8Array(n);
54
+ new Uint8Array(s.buffer).set(o);
55
55
  const l = o.byteLength;
56
- t.byobRequest.respond(l), r += l, r >= e.size && t.close();
56
+ r.byobRequest.respond(l), e += l, e >= t.size && r.close();
57
57
  }
58
58
  });
59
59
  });
60
60
  if (typeof CustomEvent > "u") {
61
- class r extends Event {
62
- constructor(t, n = {}) {
63
- super(t, n), this.detail = n.detail;
61
+ class e extends Event {
62
+ constructor(r, s = {}) {
63
+ super(r, s), this.detail = s.detail;
64
64
  }
65
65
  initCustomEvent() {
66
66
  }
67
67
  }
68
- globalThis.CustomEvent = r;
68
+ globalThis.CustomEvent = e;
69
69
  }
70
- const ae = Symbol("error"), le = Symbol("message");
71
- class ie extends Event {
70
+ const kError = Symbol("error"), kMessage = Symbol("message");
71
+ class ErrorEvent2 extends Event {
72
72
  /**
73
73
  * Create a new `ErrorEvent`.
74
74
  *
@@ -76,93 +76,93 @@ class ie extends Event {
76
76
  * @param options A dictionary object that allows for setting
77
77
  * attributes via object members of the same name.
78
78
  */
79
- constructor(e, t = {}) {
80
- super(e), this[ae] = t.error === void 0 ? null : t.error, this[le] = t.message === void 0 ? "" : t.message;
79
+ constructor(t, r = {}) {
80
+ super(t), this[kError] = r.error === void 0 ? null : r.error, this[kMessage] = r.message === void 0 ? "" : r.message;
81
81
  }
82
82
  get error() {
83
- return this[ae];
83
+ return this[kError];
84
84
  }
85
85
  get message() {
86
- return this[le];
86
+ return this[kMessage];
87
87
  }
88
88
  }
89
- Object.defineProperty(ie.prototype, "error", { enumerable: !0 });
90
- Object.defineProperty(ie.prototype, "message", { enumerable: !0 });
91
- const Ie = typeof globalThis.ErrorEvent == "function" ? globalThis.ErrorEvent : ie;
92
- function Oe(r) {
93
- return r instanceof Error ? "exitCode" in r && (r == null ? void 0 : r.exitCode) === 0 || (r == null ? void 0 : r.name) === "ExitStatus" && "status" in r && r.status === 0 : !1;
89
+ Object.defineProperty(ErrorEvent2.prototype, "error", { enumerable: !0 });
90
+ Object.defineProperty(ErrorEvent2.prototype, "message", { enumerable: !0 });
91
+ const ErrorEvent = typeof globalThis.ErrorEvent == "function" ? globalThis.ErrorEvent : ErrorEvent2;
92
+ function isExitCodeZero(e) {
93
+ 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;
94
94
  }
95
- class Ne extends EventTarget {
95
+ class UnhandledRejectionsTarget extends EventTarget {
96
96
  constructor() {
97
97
  super(...arguments), this.listenersCount = 0;
98
98
  }
99
- addEventListener(e, t) {
100
- ++this.listenersCount, super.addEventListener(e, t);
99
+ addEventListener(t, r) {
100
+ ++this.listenersCount, super.addEventListener(t, r);
101
101
  }
102
- removeEventListener(e, t) {
103
- --this.listenersCount, super.removeEventListener(e, t);
102
+ removeEventListener(t, r) {
103
+ --this.listenersCount, super.removeEventListener(t, r);
104
104
  }
105
105
  hasListeners() {
106
106
  return this.listenersCount > 0;
107
107
  }
108
108
  }
109
- function qe(r) {
110
- r.asm = {
111
- ...r.asm
109
+ function improveWASMErrorReporting(e) {
110
+ e.asm = {
111
+ ...e.asm
112
112
  };
113
- const e = new Ne();
114
- for (const t in r.asm)
115
- if (typeof r.asm[t] == "function") {
116
- const n = r.asm[t];
117
- r.asm[t] = function(...s) {
118
- var i;
113
+ const t = new UnhandledRejectionsTarget();
114
+ for (const r in e.asm)
115
+ if (typeof e.asm[r] == "function") {
116
+ const s = e.asm[r];
117
+ e.asm[r] = function(...i) {
118
+ var n;
119
119
  try {
120
- return n(...s);
120
+ return s(...i);
121
121
  } catch (o) {
122
122
  if (!(o instanceof Error))
123
123
  throw o;
124
- const l = Me(
124
+ const l = clarifyErrorMessage(
125
125
  o,
126
- (i = r.lastAsyncifyStackSource) == null ? void 0 : i.stack
126
+ (n = e.lastAsyncifyStackSource) == null ? void 0 : n.stack
127
127
  );
128
- if (r.lastAsyncifyStackSource && (o.cause = r.lastAsyncifyStackSource), e.hasListeners()) {
129
- e.dispatchEvent(
130
- new Ie("error", {
128
+ if (e.lastAsyncifyStackSource && (o.cause = e.lastAsyncifyStackSource), t.hasListeners()) {
129
+ t.dispatchEvent(
130
+ new ErrorEvent("error", {
131
131
  error: o,
132
132
  message: l
133
133
  })
134
134
  );
135
135
  return;
136
136
  }
137
- throw Oe(o) || ze(l), o;
137
+ throw isExitCodeZero(o) || showCriticalErrorBox(l), o;
138
138
  }
139
139
  };
140
140
  }
141
- return e;
141
+ return t;
142
142
  }
143
- let se = [];
144
- function De() {
145
- return se;
143
+ let functionsMaybeMissingFromAsyncify = [];
144
+ function getFunctionsMaybeMissingFromAsyncify() {
145
+ return functionsMaybeMissingFromAsyncify;
146
146
  }
147
- function Me(r, e) {
148
- if (r.message === "unreachable") {
149
- let t = je;
150
- e || (t += `
147
+ function clarifyErrorMessage(e, t) {
148
+ if (e.message === "unreachable") {
149
+ let r = UNREACHABLE_ERROR;
150
+ t || (r += `
151
151
 
152
152
  This stack trace is lacking. For a better one initialize
153
153
  the PHP runtime with { debug: true }, e.g. PHPNode.load('8.1', { debug: true }).
154
154
 
155
- `), se = Ge(
156
- e || r.stack || ""
155
+ `), functionsMaybeMissingFromAsyncify = extractPHPFunctionsFromStack(
156
+ t || e.stack || ""
157
157
  );
158
- for (const n of se)
159
- t += ` * ${n}
158
+ for (const s of functionsMaybeMissingFromAsyncify)
159
+ r += ` * ${s}
160
160
  `;
161
- return t;
161
+ return r;
162
162
  }
163
- return r.message;
163
+ return e.message;
164
164
  }
165
- const je = `
165
+ const UNREACHABLE_ERROR = `
166
166
  "unreachable" WASM instruction executed.
167
167
 
168
168
  The typical reason is a PHP function missing from the ASYNCIFY_ONLY
@@ -186,39 +186,39 @@ the Dockerfile, you'll need to trigger this error again with long stack
186
186
  traces enabled. In node.js, you can do it using the --stack-trace-limit=100
187
187
  CLI option:
188
188
 
189
- `, ce = "\x1B[41m", We = "\x1B[1m", ue = "\x1B[0m", he = "\x1B[K";
190
- let de = !1;
191
- function ze(r) {
192
- if (!de && (de = !0, !(r != null && r.trim().startsWith("Program terminated with exit")))) {
193
- console.log(`${ce}
194
- ${he}
195
- ${We} WASM ERROR${ue}${ce}`);
196
- for (const e of r.split(`
189
+ `, redBg = "\x1B[41m", bold = "\x1B[1m", reset = "\x1B[0m", eol = "\x1B[K";
190
+ let logged = !1;
191
+ function showCriticalErrorBox(e) {
192
+ if (!logged && (logged = !0, !(e != null && e.trim().startsWith("Program terminated with exit")))) {
193
+ console.log(`${redBg}
194
+ ${eol}
195
+ ${bold} WASM ERROR${reset}${redBg}`);
196
+ for (const t of e.split(`
197
197
  `))
198
- console.log(`${he} ${e} `);
199
- console.log(`${ue}`);
198
+ console.log(`${eol} ${t} `);
199
+ console.log(`${reset}`);
200
200
  }
201
201
  }
202
- function Ge(r) {
202
+ function extractPHPFunctionsFromStack(e) {
203
203
  try {
204
- const e = r.split(`
205
- `).slice(1).map((t) => {
206
- const n = t.trim().substring(3).split(" ");
204
+ const t = e.split(`
205
+ `).slice(1).map((r) => {
206
+ const s = r.trim().substring(3).split(" ");
207
207
  return {
208
- fn: n.length >= 2 ? n[0] : "<unknown>",
209
- isWasm: t.includes("wasm://")
208
+ fn: s.length >= 2 ? s[0] : "<unknown>",
209
+ isWasm: r.includes("wasm://")
210
210
  };
211
211
  }).filter(
212
- ({ fn: t, isWasm: n }) => n && !t.startsWith("dynCall_") && !t.startsWith("invoke_")
213
- ).map(({ fn: t }) => t);
214
- return Array.from(new Set(e));
212
+ ({ fn: r, isWasm: s }) => s && !r.startsWith("dynCall_") && !r.startsWith("invoke_")
213
+ ).map(({ fn: r }) => r);
214
+ return Array.from(new Set(t));
215
215
  } catch {
216
216
  return [];
217
217
  }
218
218
  }
219
- class we {
220
- constructor({ concurrency: e }) {
221
- this._running = 0, this.concurrency = e, this.queue = [];
219
+ class Semaphore {
220
+ constructor({ concurrency: t }) {
221
+ this._running = 0, this.concurrency = t, this.queue = [];
222
222
  }
223
223
  get running() {
224
224
  return this._running;
@@ -226,116 +226,171 @@ class we {
226
226
  async acquire() {
227
227
  for (; ; )
228
228
  if (this._running >= this.concurrency)
229
- await new Promise((e) => this.queue.push(e));
229
+ await new Promise((t) => this.queue.push(t));
230
230
  else {
231
231
  this._running++;
232
- let e = !1;
232
+ let t = !1;
233
233
  return () => {
234
- e || (e = !0, this._running--, this.queue.length > 0 && this.queue.shift()());
234
+ t || (t = !0, this._running--, this.queue.length > 0 && this.queue.shift()());
235
235
  };
236
236
  }
237
237
  }
238
- async run(e) {
239
- const t = await this.acquire();
238
+ async run(t) {
239
+ const r = await this.acquire();
240
240
  try {
241
- return await e();
241
+ return await t();
242
242
  } finally {
243
- t();
243
+ r();
244
244
  }
245
245
  }
246
246
  }
247
- function ge(...r) {
248
- let e = r.join("/");
249
- const t = e[0] === "/", n = e.substring(e.length - 1) === "/";
250
- return e = oe(e), !e && !t && (e = "."), e && n && (e += "/"), e;
247
+ function joinPaths(...e) {
248
+ let t = e.join("/");
249
+ const r = t[0] === "/", s = t.substring(t.length - 1) === "/";
250
+ return t = normalizePath(t), !t && !r && (t = "."), t && s && (t += "/"), t;
251
251
  }
252
- function Ve(r) {
253
- if (r === "/")
252
+ function dirname(e) {
253
+ if (e === "/")
254
254
  return "/";
255
- r = oe(r);
256
- const e = r.lastIndexOf("/");
257
- return e === -1 ? "" : e === 0 ? "/" : r.substr(0, e);
255
+ e = normalizePath(e);
256
+ const t = e.lastIndexOf("/");
257
+ return t === -1 ? "" : t === 0 ? "/" : e.substr(0, t);
258
+ }
259
+ function normalizePath(e) {
260
+ const t = e[0] === "/";
261
+ return e = normalizePathsArray(
262
+ e.split("/").filter((r) => !!r),
263
+ !t
264
+ ).join("/"), (t ? "/" : "") + e.replace(/\/$/, "");
265
+ }
266
+ function normalizePathsArray(e, t) {
267
+ let r = 0;
268
+ for (let s = e.length - 1; s >= 0; s--) {
269
+ const i = e[s];
270
+ i === "." ? e.splice(s, 1) : i === ".." ? (e.splice(s, 1), r++) : r && (e.splice(s, 1), r--);
271
+ }
272
+ if (t)
273
+ for (; r; r--)
274
+ e.unshift("..");
275
+ return e;
276
+ }
277
+ function createSpawnHandler(e) {
278
+ return function(t) {
279
+ const r = new ChildProcess(), s = new ProcessApi(r);
280
+ return setTimeout(async () => {
281
+ await e(t, s), r.emit("spawn", !0);
282
+ }), r;
283
+ };
284
+ }
285
+ class EventEmitter {
286
+ constructor() {
287
+ this.listeners = {};
288
+ }
289
+ emit(t, r) {
290
+ this.listeners[t] && this.listeners[t].forEach(function(s) {
291
+ s(r);
292
+ });
293
+ }
294
+ on(t, r) {
295
+ this.listeners[t] || (this.listeners[t] = []), this.listeners[t].push(r);
296
+ }
258
297
  }
259
- function oe(r) {
260
- const e = r[0] === "/";
261
- return r = Je(
262
- r.split("/").filter((t) => !!t),
263
- !e
264
- ).join("/"), (e ? "/" : "") + r.replace(/\/$/, "");
298
+ class ProcessApi extends EventEmitter {
299
+ constructor(t) {
300
+ super(), this.childProcess = t, this.exited = !1, this.stdinData = [], t.on("stdin", (r) => {
301
+ this.stdinData ? this.stdinData.push(r.slice()) : this.emit("stdin", r);
302
+ });
303
+ }
304
+ stdout(t) {
305
+ typeof t == "string" && (t = new TextEncoder().encode(t)), this.childProcess.stdout.emit("data", t);
306
+ }
307
+ stderr(t) {
308
+ typeof t == "string" && (t = new TextEncoder().encode(t)), this.childProcess.stderr.emit("data", t);
309
+ }
310
+ exit(t) {
311
+ this.exited || (this.exited = !0, this.childProcess.emit("exit", t));
312
+ }
313
+ flushStdin() {
314
+ if (this.stdinData)
315
+ for (let t = 0; t < this.stdinData.length; t++)
316
+ this.emit("stdin", this.stdinData[t]);
317
+ this.stdinData = null;
318
+ }
265
319
  }
266
- function Je(r, e) {
267
- let t = 0;
268
- for (let n = r.length - 1; n >= 0; n--) {
269
- const s = r[n];
270
- s === "." ? r.splice(n, 1) : s === ".." ? (r.splice(n, 1), t++) : t && (r.splice(n, 1), t--);
271
- }
272
- if (e)
273
- for (; t; t--)
274
- r.unshift("..");
275
- return r;
320
+ let lastPid = 9743;
321
+ class ChildProcess extends EventEmitter {
322
+ constructor(t = lastPid++) {
323
+ super(), this.pid = t, this.stdout = new EventEmitter(), this.stderr = new EventEmitter();
324
+ const r = this;
325
+ this.stdin = {
326
+ write: (s) => {
327
+ r.emit("stdin", s);
328
+ }
329
+ };
330
+ }
276
331
  }
277
- function Ye(...r) {
278
- const e = new Uint8Array(
279
- r.reduce((n, s) => n + s.length, 0)
332
+ function concatUint8Array(...e) {
333
+ const t = new Uint8Array(
334
+ e.reduce((s, i) => s + i.length, 0)
280
335
  );
281
- let t = 0;
282
- for (const n of r)
283
- e.set(n, t), t += n.length;
284
- return e;
336
+ let r = 0;
337
+ for (const s of e)
338
+ t.set(s, r), r += s.length;
339
+ return t;
285
340
  }
286
- function Ke(r) {
287
- if (r === void 0) {
288
- let e = new Uint8Array();
341
+ function concatBytes(e) {
342
+ if (e === void 0) {
343
+ let t = new Uint8Array();
289
344
  return new TransformStream({
290
- transform(t) {
291
- e = Ye(e, t);
345
+ transform(r) {
346
+ t = concatUint8Array(t, r);
292
347
  },
293
- flush(t) {
294
- t.enqueue(e);
348
+ flush(r) {
349
+ r.enqueue(t);
295
350
  }
296
351
  });
297
352
  } else {
298
- const e = new ArrayBuffer(r || 0);
299
- let t = 0;
353
+ const t = new ArrayBuffer(e || 0);
354
+ let r = 0;
300
355
  return new TransformStream({
301
- transform(n) {
302
- new Uint8Array(e).set(n, t), t += n.byteLength;
356
+ transform(s) {
357
+ new Uint8Array(t).set(s, r), r += s.byteLength;
303
358
  },
304
- flush(n) {
305
- n.enqueue(new Uint8Array(e));
359
+ flush(s) {
360
+ s.enqueue(new Uint8Array(t));
306
361
  }
307
362
  });
308
363
  }
309
364
  }
310
- function Ze(r, e) {
311
- if (e === 0)
365
+ function limitBytes(e, t) {
366
+ if (t === 0)
312
367
  return new ReadableStream({
313
- start(s) {
314
- s.close();
368
+ start(i) {
369
+ i.close();
315
370
  }
316
371
  });
317
- const t = r.getReader({ mode: "byob" });
318
- let n = 0;
372
+ const r = e.getReader({ mode: "byob" });
373
+ let s = 0;
319
374
  return new ReadableStream({
320
- async pull(s) {
321
- const { value: i, done: o } = await t.read(
322
- new Uint8Array(e - n)
375
+ async pull(i) {
376
+ const { value: n, done: o } = await r.read(
377
+ new Uint8Array(t - s)
323
378
  );
324
379
  if (o) {
325
- t.releaseLock(), s.close();
380
+ r.releaseLock(), i.close();
326
381
  return;
327
382
  }
328
- n += i.length, s.enqueue(i), n >= e && (t.releaseLock(), s.close());
383
+ s += n.length, i.enqueue(n), s >= t && (r.releaseLock(), i.close());
329
384
  },
330
385
  cancel() {
331
- t.cancel();
386
+ r.cancel();
332
387
  }
333
388
  });
334
389
  }
335
- async function Qe(r, e) {
336
- return e !== void 0 && (r = Ze(r, e)), await r.pipeThrough(Ke(e)).getReader().read().then(({ value: t }) => t);
390
+ async function collectBytes(e, t) {
391
+ return t !== void 0 && (e = limitBytes(e, t)), await e.pipeThrough(concatBytes(t)).getReader().read().then(({ value: r }) => r);
337
392
  }
338
- class Xe extends File {
393
+ class StreamedFile extends File {
339
394
  /**
340
395
  * Creates a new StreamedFile instance.
341
396
  *
@@ -343,8 +398,8 @@ class Xe extends File {
343
398
  * @param name The name of the file.
344
399
  * @param type The MIME type of the file.
345
400
  */
346
- constructor(e, t, n) {
347
- super([], t, { type: n }), this.readableStream = e;
401
+ constructor(t, r, s) {
402
+ super([], r, { type: s }), this.readableStream = t;
348
403
  }
349
404
  /**
350
405
  * Overrides the slice() method of the File class.
@@ -376,79 +431,79 @@ class Xe extends File {
376
431
  * @returns File data as an ArrayBuffer.
377
432
  */
378
433
  async arrayBuffer() {
379
- return await Qe(this.stream());
434
+ return await collectBytes(this.stream());
380
435
  }
381
436
  }
382
437
  ReadableStream.prototype[Symbol.asyncIterator] || (ReadableStream.prototype[Symbol.asyncIterator] = async function* () {
383
- const r = this.getReader();
438
+ const e = this.getReader();
384
439
  try {
385
440
  for (; ; ) {
386
- const { done: e, value: t } = await r.read();
387
- if (e)
441
+ const { done: t, value: r } = await e.read();
442
+ if (t)
388
443
  return;
389
- yield t;
444
+ yield r;
390
445
  }
391
446
  } finally {
392
- r.releaseLock();
447
+ e.releaseLock();
393
448
  }
394
449
  }, ReadableStream.prototype.iterate = // @ts-ignore
395
450
  ReadableStream.prototype[Symbol.asyncIterator]);
396
- function et(r, e) {
451
+ function streamReadFileFromPHP(e, t) {
397
452
  return new ReadableStream({
398
- async pull(t) {
399
- const n = await r.readFileAsBuffer(e);
400
- t.enqueue(n), t.close();
453
+ async pull(r) {
454
+ const s = await e.readFileAsBuffer(t);
455
+ r.enqueue(s), r.close();
401
456
  }
402
457
  });
403
458
  }
404
- async function* bt(r, e, {
405
- relativePaths: t = !0,
406
- pathPrefix: n,
407
- exceptPaths: s = []
459
+ async function* iteratePhpFiles(e, t, {
460
+ relativePaths: r = !0,
461
+ pathPrefix: s,
462
+ exceptPaths: i = []
408
463
  } = {}) {
409
- e = oe(e);
410
- const i = [e];
411
- for (; i.length; ) {
412
- const o = i.pop();
464
+ t = normalizePath(t);
465
+ const n = [t];
466
+ for (; n.length; ) {
467
+ const o = n.pop();
413
468
  if (!o)
414
469
  return;
415
- const l = await r.listFiles(o);
416
- for (const d of l) {
417
- const f = `${o}/${d}`;
418
- if (s.includes(f.substring(e.length + 1)))
470
+ const l = await e.listFiles(o);
471
+ for (const p of l) {
472
+ const d = `${o}/${p}`;
473
+ if (i.includes(d.substring(t.length + 1)))
419
474
  continue;
420
- await r.isDir(f) ? i.push(f) : yield new Xe(
421
- et(r, f),
422
- t ? ge(
423
- n || "",
424
- f.substring(e.length + 1)
425
- ) : f
475
+ await e.isDir(d) ? n.push(d) : yield new StreamedFile(
476
+ streamReadFileFromPHP(e, d),
477
+ r ? joinPaths(
478
+ s || "",
479
+ d.substring(t.length + 1)
480
+ ) : d
426
481
  );
427
482
  }
428
483
  }
429
484
  }
430
- function Pt(r, e) {
485
+ function writeFilesStreamToPhp(e, t) {
431
486
  return new WritableStream({
432
- async write(t) {
433
- const n = ge(e, t.name);
434
- t.type === "directory" ? await r.mkdir(n) : (await r.mkdir(Ve(n)), await r.writeFile(
435
- n,
436
- new Uint8Array(await t.arrayBuffer())
487
+ async write(r) {
488
+ const s = joinPaths(t, r.name);
489
+ r.type === "directory" ? await e.mkdir(s) : (await e.mkdir(dirname(s)), await e.writeFile(
490
+ s,
491
+ new Uint8Array(await r.arrayBuffer())
437
492
  ));
438
493
  }
439
494
  });
440
495
  }
441
- class H {
442
- constructor(e, t, n, s = "", i = 0) {
443
- this.httpStatusCode = e, this.headers = t, this.bytes = n, this.exitCode = i, this.errors = s;
444
- }
445
- static fromRawData(e) {
446
- return new H(
447
- e.httpStatusCode,
448
- e.headers,
449
- e.bytes,
450
- e.errors,
451
- e.exitCode
496
+ class PHPResponse {
497
+ constructor(t, r, s, i = "", n = 0) {
498
+ this.httpStatusCode = t, this.headers = r, this.bytes = s, this.exitCode = n, this.errors = i;
499
+ }
500
+ static fromRawData(t) {
501
+ return new PHPResponse(
502
+ t.httpStatusCode,
503
+ t.headers,
504
+ t.bytes,
505
+ t.errors,
506
+ t.exitCode
452
507
  );
453
508
  }
454
509
  toRawData() {
@@ -473,7 +528,7 @@ class H {
473
528
  return new TextDecoder().decode(this.bytes);
474
529
  }
475
530
  }
476
- const be = [
531
+ const SupportedPHPVersions = [
477
532
  "8.3",
478
533
  "8.2",
479
534
  "8.1",
@@ -483,27 +538,27 @@ const be = [
483
538
  "7.2",
484
539
  "7.1",
485
540
  "7.0"
486
- ], Et = be[0], St = be, tt = [
541
+ ], LatestSupportedPHPVersion = SupportedPHPVersions[0], SupportedPHPVersionsList = SupportedPHPVersions, SupportedPHPExtensionsList = [
487
542
  "iconv",
488
543
  "mbstring",
489
544
  "xml-bundle",
490
545
  "gd"
491
- ], vt = {
492
- "kitchen-sink": tt
546
+ ], SupportedPHPExtensionBundles = {
547
+ "kitchen-sink": SupportedPHPExtensionsList
493
548
  };
494
- var _, A;
495
- class rt {
549
+ var v, S;
550
+ class PHPBrowser {
496
551
  /**
497
552
  * @param server - The PHP server to browse.
498
553
  * @param config - The browser configuration.
499
554
  */
500
- constructor(e, t = {}) {
501
- c(this, _, void 0);
502
- c(this, A, void 0);
503
- this.requestHandler = e, p(this, _, {}), p(this, A, {
555
+ constructor(t, r = {}) {
556
+ c(this, v, void 0);
557
+ c(this, S, void 0);
558
+ this.requestHandler = t, u(this, v, {}), u(this, S, {
504
559
  handleRedirects: !1,
505
560
  maxRedirects: 4,
506
- ...t
561
+ ...r
507
562
  });
508
563
  }
509
564
  /**
@@ -520,37 +575,37 @@ class rt {
520
575
  * @param redirects - Internal. The number of redirects handled so far.
521
576
  * @returns PHPRequestHandler response.
522
577
  */
523
- async request(e, t = 0) {
524
- const n = await this.requestHandler.request({
525
- ...e,
578
+ async request(t, r = 0) {
579
+ const s = await this.requestHandler.request({
580
+ ...t,
526
581
  headers: {
527
- ...e.headers,
582
+ ...t.headers,
528
583
  cookie: this.serializeCookies()
529
584
  }
530
585
  });
531
- if (n.headers["set-cookie"] && this.setCookies(n.headers["set-cookie"]), a(this, A).handleRedirects && n.headers.location && t < a(this, A).maxRedirects) {
532
- const s = new URL(
533
- n.headers.location[0],
586
+ if (s.headers["set-cookie"] && this.setCookies(s.headers["set-cookie"]), a(this, S).handleRedirects && s.headers.location && r < a(this, S).maxRedirects) {
587
+ const i = new URL(
588
+ s.headers.location[0],
534
589
  this.requestHandler.absoluteUrl
535
590
  );
536
591
  return this.request(
537
592
  {
538
- url: s.toString(),
593
+ url: i.toString(),
539
594
  method: "GET",
540
595
  headers: {}
541
596
  },
542
- t + 1
597
+ r + 1
543
598
  );
544
599
  }
545
- return n;
600
+ return s;
546
601
  }
547
602
  /** @inheritDoc */
548
- pathToInternalUrl(e) {
549
- return this.requestHandler.pathToInternalUrl(e);
603
+ pathToInternalUrl(t) {
604
+ return this.requestHandler.pathToInternalUrl(t);
550
605
  }
551
606
  /** @inheritDoc */
552
- internalUrlToPath(e) {
553
- return this.requestHandler.internalUrlToPath(e);
607
+ internalUrlToPath(t) {
608
+ return this.requestHandler.internalUrlToPath(t);
554
609
  }
555
610
  /** @inheritDoc */
556
611
  get absoluteUrl() {
@@ -560,49 +615,49 @@ class rt {
560
615
  get documentRoot() {
561
616
  return this.requestHandler.documentRoot;
562
617
  }
563
- setCookies(e) {
564
- for (const t of e)
618
+ setCookies(t) {
619
+ for (const r of t)
565
620
  try {
566
- if (!t.includes("="))
621
+ if (!r.includes("="))
567
622
  continue;
568
- const n = t.indexOf("="), s = t.substring(0, n), i = t.substring(n + 1).split(";")[0];
569
- a(this, _)[s] = i;
570
- } catch (n) {
571
- console.error(n);
623
+ const s = r.indexOf("="), i = r.substring(0, s), n = r.substring(s + 1).split(";")[0];
624
+ a(this, v)[i] = n;
625
+ } catch (s) {
626
+ console.error(s);
572
627
  }
573
628
  }
574
629
  serializeCookies() {
575
- const e = [];
576
- for (const t in a(this, _))
577
- e.push(`${t}=${a(this, _)[t]}`);
578
- return e.join("; ");
630
+ const t = [];
631
+ for (const r in a(this, v))
632
+ t.push(`${r}=${a(this, v)[r]}`);
633
+ return t.join("; ");
579
634
  }
580
635
  }
581
- _ = new WeakMap(), A = new WeakMap();
582
- const nt = "http://example.com";
583
- function fe(r) {
584
- return r.toString().substring(r.origin.length);
636
+ v = new WeakMap(), S = new WeakMap();
637
+ const DEFAULT_BASE_URL = "http://example.com";
638
+ function toRelativeUrl(e) {
639
+ return e.toString().substring(e.origin.length);
585
640
  }
586
- function pe(r, e) {
587
- return !e || !r.startsWith(e) ? r : r.substring(e.length);
641
+ function removePathPrefix(e, t) {
642
+ return !t || !e.startsWith(t) ? e : e.substring(t.length);
588
643
  }
589
- function st(r, e) {
590
- return !e || r.startsWith(e) ? r : e + r;
644
+ function ensurePathPrefix(e, t) {
645
+ return !t || e.startsWith(t) ? e : t + e;
591
646
  }
592
- var g, $, O, F, U, b, B, L, M, Pe, j, Ee, W, Se;
593
- class it {
647
+ var w, x, A, R, H, _, F, T, U, K, L, Q, N, X;
648
+ class PHPRequestHandler {
594
649
  /**
595
650
  * @param php - The PHP instance.
596
651
  * @param config - Request Handler configuration.
597
652
  */
598
- constructor(e, t = {}) {
653
+ constructor(t, r = {}) {
599
654
  /**
600
655
  * Serves a static file from the PHP filesystem.
601
656
  *
602
657
  * @param fsPath - Absolute path of the static file to serve.
603
658
  * @returns The response.
604
659
  */
605
- c(this, M);
660
+ c(this, U);
606
661
  /**
607
662
  * Runs the requested PHP file with all the request and $_SERVER
608
663
  * superglobals populated.
@@ -610,7 +665,7 @@ class it {
610
665
  * @param request - The request.
611
666
  * @returns The response.
612
667
  */
613
- c(this, j);
668
+ c(this, L);
614
669
  /**
615
670
  * Resolve the requested path to the filesystem path of the requested PHP file.
616
671
  *
@@ -620,68 +675,68 @@ class it {
620
675
  * @throws {Error} If the requested path doesn't exist.
621
676
  * @returns The resolved filesystem path.
622
677
  */
623
- c(this, W);
624
- c(this, g, void 0);
625
- c(this, $, void 0);
626
- c(this, O, void 0);
678
+ c(this, N);
679
+ c(this, w, void 0);
680
+ c(this, x, void 0);
681
+ c(this, A, void 0);
682
+ c(this, R, void 0);
683
+ c(this, H, void 0);
684
+ c(this, _, void 0);
627
685
  c(this, F, void 0);
628
- c(this, U, void 0);
629
- c(this, b, void 0);
630
- c(this, B, void 0);
631
- c(this, L, void 0);
632
- p(this, L, new we({ concurrency: 1 }));
686
+ c(this, T, void 0);
687
+ u(this, T, new Semaphore({ concurrency: 1 }));
633
688
  const {
634
- documentRoot: n = "/www/",
635
- absoluteUrl: s = typeof location == "object" ? location == null ? void 0 : location.href : ""
636
- } = t;
637
- this.php = e, p(this, g, n);
638
- const i = new URL(s);
639
- p(this, O, i.hostname), p(this, F, i.port ? Number(i.port) : i.protocol === "https:" ? 443 : 80), p(this, $, (i.protocol || "").replace(":", ""));
640
- const o = a(this, F) !== 443 && a(this, F) !== 80;
641
- p(this, U, [
642
- a(this, O),
643
- o ? `:${a(this, F)}` : ""
644
- ].join("")), p(this, b, i.pathname.replace(/\/+$/, "")), p(this, B, [
645
- `${a(this, $)}://`,
646
- a(this, U),
647
- a(this, b)
689
+ documentRoot: s = "/www/",
690
+ absoluteUrl: i = typeof location == "object" ? location == null ? void 0 : location.href : ""
691
+ } = r;
692
+ this.php = t, u(this, w, s);
693
+ const n = new URL(i);
694
+ u(this, A, n.hostname), u(this, R, n.port ? Number(n.port) : n.protocol === "https:" ? 443 : 80), u(this, x, (n.protocol || "").replace(":", ""));
695
+ const o = a(this, R) !== 443 && a(this, R) !== 80;
696
+ u(this, H, [
697
+ a(this, A),
698
+ o ? `:${a(this, R)}` : ""
699
+ ].join("")), u(this, _, n.pathname.replace(/\/+$/, "")), u(this, F, [
700
+ `${a(this, x)}://`,
701
+ a(this, H),
702
+ a(this, _)
648
703
  ].join(""));
649
704
  }
650
705
  /** @inheritDoc */
651
- pathToInternalUrl(e) {
652
- return `${this.absoluteUrl}${e}`;
706
+ pathToInternalUrl(t) {
707
+ return `${this.absoluteUrl}${t}`;
653
708
  }
654
709
  /** @inheritDoc */
655
- internalUrlToPath(e) {
656
- const t = new URL(e);
657
- return t.pathname.startsWith(a(this, b)) && (t.pathname = t.pathname.slice(a(this, b).length)), fe(t);
710
+ internalUrlToPath(t) {
711
+ const r = new URL(t);
712
+ return r.pathname.startsWith(a(this, _)) && (r.pathname = r.pathname.slice(a(this, _).length)), toRelativeUrl(r);
658
713
  }
659
714
  get isRequestRunning() {
660
- return a(this, L).running > 0;
715
+ return a(this, T).running > 0;
661
716
  }
662
717
  /** @inheritDoc */
663
718
  get absoluteUrl() {
664
- return a(this, B);
719
+ return a(this, F);
665
720
  }
666
721
  /** @inheritDoc */
667
722
  get documentRoot() {
668
- return a(this, g);
723
+ return a(this, w);
669
724
  }
670
725
  /** @inheritDoc */
671
- async request(e) {
672
- const t = e.url.startsWith("http://") || e.url.startsWith("https://"), n = new URL(
673
- e.url,
674
- t ? void 0 : nt
675
- ), s = pe(
676
- n.pathname,
677
- a(this, b)
678
- ), i = `${a(this, g)}${s}`;
679
- return lt(i) ? await m(this, j, Ee).call(this, e, n) : m(this, M, Pe).call(this, i);
726
+ async request(t) {
727
+ const r = t.url.startsWith("http://") || t.url.startsWith("https://"), s = new URL(
728
+ t.url,
729
+ r ? void 0 : DEFAULT_BASE_URL
730
+ ), i = removePathPrefix(
731
+ s.pathname,
732
+ a(this, _)
733
+ ), n = `${a(this, w)}${i}`;
734
+ return seemsLikeAPHPRequestHandlerPath(n) ? await h(this, L, Q).call(this, t, s) : h(this, U, K).call(this, n);
680
735
  }
681
736
  }
682
- g = new WeakMap(), $ = new WeakMap(), O = new WeakMap(), F = new WeakMap(), U = new WeakMap(), b = new WeakMap(), B = new WeakMap(), L = new WeakMap(), M = new WeakSet(), Pe = function(e) {
683
- if (!this.php.fileExists(e))
684
- return new H(
737
+ w = new WeakMap(), x = new WeakMap(), A = new WeakMap(), R = new WeakMap(), H = new WeakMap(), _ = new WeakMap(), F = new WeakMap(), T = new WeakMap(), U = new WeakSet(), K = function(t) {
738
+ if (!this.php.fileExists(t))
739
+ return new PHPResponse(
685
740
  404,
686
741
  // Let the service worker know that no static file was found
687
742
  // and that it's okay to issue a real fetch() to the server.
@@ -690,104 +745,110 @@ g = new WeakMap(), $ = new WeakMap(), O = new WeakMap(), F = new WeakMap(), U =
690
745
  },
691
746
  new TextEncoder().encode("404 File not found")
692
747
  );
693
- const t = this.php.readFileAsBuffer(e);
694
- return new H(
748
+ const r = this.php.readFileAsBuffer(t);
749
+ return new PHPResponse(
695
750
  200,
696
751
  {
697
- "content-length": [`${t.byteLength}`],
752
+ "content-length": [`${r.byteLength}`],
698
753
  // @TODO: Infer the content-type from the arrayBuffer instead of the file path.
699
754
  // The code below won't return the correct mime-type if the extension
700
755
  // was tampered with.
701
- "content-type": [at(e)],
756
+ "content-type": [inferMimeType(t)],
702
757
  "accept-ranges": ["bytes"],
703
758
  "cache-control": ["public, max-age=0"]
704
759
  },
705
- t
760
+ r
706
761
  );
707
- }, j = new WeakSet(), Ee = async function(e, t) {
708
- var s;
709
- const n = await a(this, L).acquire();
762
+ }, L = new WeakSet(), Q = async function(t, r) {
763
+ var i, n;
764
+ const s = await a(this, T).acquire();
710
765
  try {
711
- this.php.addServerGlobalEntry("DOCUMENT_ROOT", a(this, g)), this.php.addServerGlobalEntry(
766
+ this.php.addServerGlobalEntry("REMOTE_ADDR", "127.0.0.1"), this.php.addServerGlobalEntry("DOCUMENT_ROOT", a(this, w)), this.php.addServerGlobalEntry(
712
767
  "HTTPS",
713
- a(this, B).startsWith("https://") ? "on" : ""
768
+ a(this, F).startsWith("https://") ? "on" : ""
714
769
  );
715
- let i = "GET";
716
- const o = {
717
- host: a(this, U),
718
- ...Be(e.headers || {})
719
- }, l = [];
720
- if (e.files && Object.keys(e.files).length) {
721
- i = "POST";
722
- for (const h in e.files) {
723
- const S = e.files[h];
724
- l.push({
725
- key: h,
726
- name: S.name,
727
- type: S.type,
728
- data: new Uint8Array(await S.arrayBuffer())
770
+ let o = "GET";
771
+ const l = {
772
+ host: a(this, H),
773
+ ...normalizeHeaders(t.headers || {})
774
+ }, p = [];
775
+ if (t.files && Object.keys(t.files).length) {
776
+ o = "POST";
777
+ for (const P in t.files) {
778
+ const I = t.files[P];
779
+ p.push({
780
+ key: P,
781
+ name: I.name,
782
+ type: I.type,
783
+ data: new Uint8Array(await I.arrayBuffer())
729
784
  });
730
785
  }
731
- (s = o["content-type"]) != null && s.startsWith("multipart/form-data") && (e.formData = ot(
732
- e.body || ""
733
- ), o["content-type"] = "application/x-www-form-urlencoded", delete e.body);
786
+ (i = l["content-type"]) != null && i.startsWith("multipart/form-data") && (t.formData = parseMultipartFormDataString(
787
+ t.body || ""
788
+ ), l["content-type"] = "application/x-www-form-urlencoded", delete t.body);
734
789
  }
735
790
  let d;
736
- e.formData !== void 0 ? (i = "POST", o["content-type"] = o["content-type"] || "application/x-www-form-urlencoded", d = new URLSearchParams(
737
- e.formData
738
- ).toString()) : d = e.body;
791
+ t.formData !== void 0 ? (o = "POST", l["content-type"] = l["content-type"] || "application/x-www-form-urlencoded", d = new URLSearchParams(
792
+ t.formData
793
+ ).toString()) : d = t.body;
739
794
  let f;
740
795
  try {
741
- f = m(this, W, Se).call(this, t.pathname);
796
+ let P = r.pathname;
797
+ if ((n = t.headers) != null && n["x-rewrite-url"])
798
+ try {
799
+ P = new URL(
800
+ t.headers["x-rewrite-url"]
801
+ ).pathname;
802
+ } catch {
803
+ }
804
+ f = h(this, N, X).call(this, P);
742
805
  } catch {
743
- return new H(
806
+ return new PHPResponse(
744
807
  404,
745
808
  {},
746
809
  new TextEncoder().encode("404 File not found")
747
810
  );
748
811
  }
749
812
  return await this.php.run({
750
- relativeUri: st(
751
- fe(t),
752
- a(this, b)
813
+ relativeUri: ensurePathPrefix(
814
+ toRelativeUrl(r),
815
+ a(this, _)
753
816
  ),
754
- protocol: a(this, $),
755
- method: e.method || i,
817
+ protocol: a(this, x),
818
+ method: t.method || o,
756
819
  body: d,
757
- fileInfos: l,
820
+ fileInfos: p,
758
821
  scriptPath: f,
759
- headers: o
822
+ headers: l
760
823
  });
761
824
  } finally {
762
- n();
763
- }
764
- }, W = new WeakSet(), Se = function(e) {
765
- let t = pe(e, a(this, b));
766
- t.includes(".php") ? t = t.split(".php")[0] + ".php" : (t.endsWith("/") || (t += "/"), t.endsWith("index.php") || (t += "index.php"));
767
- const n = `${a(this, g)}${t}`;
768
- if (this.php.fileExists(n))
769
- return n;
770
- if (!this.php.fileExists(`${a(this, g)}/index.php`))
771
- throw new Error(`File not found: ${n}`);
772
- return `${a(this, g)}/index.php`;
825
+ s();
826
+ }
827
+ }, N = new WeakSet(), X = function(t) {
828
+ let r = removePathPrefix(t, a(this, _));
829
+ r.includes(".php") ? r = r.split(".php")[0] + ".php" : (r.endsWith("/") || (r += "/"), r.endsWith("index.php") || (r += "index.php"));
830
+ const s = `${a(this, w)}${r}`;
831
+ if (this.php.fileExists(s))
832
+ return s;
833
+ throw new Error(`File not found: ${s}`);
773
834
  };
774
- function ot(r) {
775
- const e = {}, t = r.match(/--(.*)\r\n/);
776
- if (!t)
777
- return e;
778
- const n = t[1], s = r.split(`--${n}`);
779
- return s.shift(), s.pop(), s.forEach((i) => {
780
- const o = i.indexOf(`\r
835
+ function parseMultipartFormDataString(e) {
836
+ const t = {}, r = e.match(/--(.*)\r\n/);
837
+ if (!r)
838
+ return t;
839
+ const s = r[1], i = e.split(`--${s}`);
840
+ return i.shift(), i.pop(), i.forEach((n) => {
841
+ const o = n.indexOf(`\r
781
842
  \r
782
- `), l = i.substring(0, o).trim(), d = i.substring(o + 4).trim(), f = l.match(/name="([^"]+)"/);
783
- if (f) {
784
- const h = f[1];
785
- e[h] = d;
843
+ `), l = n.substring(0, o).trim(), p = n.substring(o + 4).trim(), d = l.match(/name="([^"]+)"/);
844
+ if (d) {
845
+ const f = d[1];
846
+ t[f] = p;
786
847
  }
787
- }), e;
848
+ }), t;
788
849
  }
789
- function at(r) {
790
- switch (r.split(".").pop()) {
850
+ function inferMimeType(e) {
851
+ switch (e.split(".").pop()) {
791
852
  case "css":
792
853
  return "text/css";
793
854
  case "js":
@@ -826,16 +887,16 @@ function at(r) {
826
887
  return "application-octet-stream";
827
888
  }
828
889
  }
829
- function lt(r) {
830
- return ct(r) || ut(r);
890
+ function seemsLikeAPHPRequestHandlerPath(e) {
891
+ return seemsLikeAPHPFile(e) || seemsLikeADirectoryRoot(e);
831
892
  }
832
- function ct(r) {
833
- return r.endsWith(".php") || r.includes(".php/");
893
+ function seemsLikeAPHPFile(e) {
894
+ return e.endsWith(".php") || e.includes(".php/");
834
895
  }
835
- function ut(r) {
836
- return !r.split("/").pop().includes(".");
896
+ function seemsLikeADirectoryRoot(e) {
897
+ return !e.split("/").pop().includes(".");
837
898
  }
838
- const D = {
899
+ const FileErrorCodes = {
839
900
  0: "No error occurred. System call completed successfully.",
840
901
  1: "Argument list too long.",
841
902
  2: "Permission denied.",
@@ -914,22 +975,22 @@ const D = {
914
975
  75: "Cross-device link.",
915
976
  76: "Extension: Capabilities insufficient."
916
977
  };
917
- function ht(r) {
918
- const e = typeof r == "object" ? r == null ? void 0 : r.errno : null;
919
- if (e in D)
920
- return D[e];
978
+ function getEmscriptenFsError(e) {
979
+ const t = typeof e == "object" ? e == null ? void 0 : e.errno : null;
980
+ if (t in FileErrorCodes)
981
+ return FileErrorCodes[t];
921
982
  }
922
- function P(r = "") {
923
- return function(t, n, s) {
924
- const i = s.value;
925
- s.value = function(...o) {
983
+ function rethrowFileSystemError(e = "") {
984
+ return function(r, s, i) {
985
+ const n = i.value;
986
+ i.value = function(...o) {
926
987
  try {
927
- return i.apply(this, o);
988
+ return n.apply(this, o);
928
989
  } catch (l) {
929
- const d = typeof l == "object" ? l == null ? void 0 : l.errno : null;
930
- if (d in D) {
931
- const f = D[d], h = typeof o[0] == "string" ? o[0] : null, S = h !== null ? r.replaceAll("{path}", h) : r;
932
- throw new Error(`${S}: ${f}`, {
990
+ const p = typeof l == "object" ? l == null ? void 0 : l.errno : null;
991
+ if (p in FileErrorCodes) {
992
+ const d = FileErrorCodes[p], f = typeof o[0] == "string" ? o[0] : null, P = f !== null ? e.replaceAll("{path}", f) : e;
993
+ throw new Error(`${P}: ${d}`, {
933
994
  cause: l
934
995
  });
935
996
  }
@@ -938,56 +999,50 @@ function P(r = "") {
938
999
  };
939
1000
  };
940
1001
  }
941
- const dt = Symbol("RuntimeId"), q = /* @__PURE__ */ new Map();
942
- async function Rt(r, e = {}, t = []) {
943
- const [n, s, i] = me(), [o, l] = me(), d = r.init(pt, {
944
- onAbort(h) {
945
- i(h), l(), console.error(h);
1002
+ const RuntimeId = Symbol("RuntimeId"), loadedRuntimes = /* @__PURE__ */ new Map();
1003
+ let lastRuntimeId = 0;
1004
+ async function loadPHPRuntime(e, t = {}) {
1005
+ const [r, s, i] = makePromise(), n = e.init(currentJsRuntime, {
1006
+ onAbort(l) {
1007
+ i(l), console.error(l);
946
1008
  },
947
1009
  ENV: {},
948
1010
  // Emscripten sometimes prepends a '/' to the path, which
949
1011
  // breaks vite dev mode. An identity `locateFile` function
950
1012
  // fixes it.
951
- locateFile: (h) => h,
952
- ...e,
1013
+ locateFile: (l) => l,
1014
+ ...t,
953
1015
  noInitialRun: !0,
954
1016
  onRuntimeInitialized() {
955
- e.onRuntimeInitialized && e.onRuntimeInitialized(), s();
956
- },
957
- monitorRunDependencies(h) {
958
- h === 0 && (delete d.monitorRunDependencies, l());
1017
+ t.onRuntimeInitialized && t.onRuntimeInitialized(), s();
959
1018
  }
960
1019
  });
961
- await Promise.all(
962
- t.map(
963
- ({ default: h }) => h(d)
964
- )
965
- ), t.length || l(), await o, await n;
966
- const f = q.size;
967
- return d.originalExit = d._exit, d._exit = function(h) {
968
- return q.delete(f), d.originalExit(h);
969
- }, d[dt] = f, q.set(f, d), f;
1020
+ await r;
1021
+ const o = ++lastRuntimeId;
1022
+ return n.id = o, n.originalExit = n._exit, n._exit = function(l) {
1023
+ return loadedRuntimes.delete(o), n.originalExit(l);
1024
+ }, n[RuntimeId] = o, loadedRuntimes.set(o, n), o;
970
1025
  }
971
- function ft(r) {
972
- return q.get(r);
1026
+ function getLoadedRuntime(e) {
1027
+ return loadedRuntimes.get(e);
973
1028
  }
974
- const pt = function() {
975
- var r;
976
- return typeof process < "u" && ((r = process.release) == null ? void 0 : r.name) === "node" ? "NODE" : typeof window < "u" ? "WEB" : typeof WorkerGlobalScope < "u" && self instanceof WorkerGlobalScope ? "WORKER" : "NODE";
977
- }(), me = () => {
978
- const r = [], e = new Promise((t, n) => {
979
- r.push(t, n);
1029
+ const currentJsRuntime = function() {
1030
+ var e;
1031
+ return typeof process < "u" && ((e = process.release) == null ? void 0 : e.name) === "node" ? "NODE" : typeof window < "u" ? "WEB" : typeof WorkerGlobalScope < "u" && self instanceof WorkerGlobalScope ? "WORKER" : "NODE";
1032
+ }(), makePromise = () => {
1033
+ const e = [], t = new Promise((r, s) => {
1034
+ e.push(r, s);
980
1035
  });
981
- return r.unshift(e), r;
1036
+ return e.unshift(t), e;
982
1037
  };
983
- var mt = Object.defineProperty, yt = Object.getOwnPropertyDescriptor, E = (r, e, t, n) => {
984
- for (var s = n > 1 ? void 0 : n ? yt(e, t) : e, i = r.length - 1, o; i >= 0; i--)
985
- (o = r[i]) && (s = (n ? o(e, t, s) : o(s)) || s);
986
- return n && s && mt(e, t, s), s;
1038
+ var __defProp = Object.defineProperty, __getOwnPropDesc = Object.getOwnPropertyDescriptor, __decorateClass = (e, t, r, s) => {
1039
+ for (var i = s > 1 ? void 0 : s ? __getOwnPropDesc(t, r) : t, n = e.length - 1, o; n >= 0; n--)
1040
+ (o = e[n]) && (i = (s ? o(t, r, i) : o(i)) || i);
1041
+ return s && i && __defProp(t, r, i), i;
987
1042
  };
988
- const y = "string", C = "number", u = Symbol("__private__dont__use");
989
- var k, R, T, x, v, I, N, z, ve, G, Re, V, xe, J, _e, Y, Fe, K, ke, Z, Te, Q, Ce, X, He, ee, Ae, te, $e, re, Ue;
990
- class w {
1043
+ const STRING = "string", NUMBER = "number", __private__dont__use = Symbol("__private__dont__use");
1044
+ var b, C, k, m, g, E, y, B, M, ee, O, te, D, re, $, se, q, ne, j, ie, z, oe, W, ae, G, le, V, ce, J, ue, Y, de;
1045
+ class BasePHP {
991
1046
  /**
992
1047
  * Initializes a PHP runtime.
993
1048
  *
@@ -996,15 +1051,15 @@ class w {
996
1051
  * @param serverOptions - Optional. Options for the PHPRequestHandler. If undefined, no request handler will be initialized.
997
1052
  */
998
1053
  constructor(e, t) {
1054
+ c(this, M);
1055
+ c(this, O);
1056
+ c(this, D);
1057
+ c(this, $);
1058
+ c(this, q);
1059
+ c(this, j);
999
1060
  c(this, z);
1061
+ c(this, W);
1000
1062
  c(this, G);
1001
- c(this, V);
1002
- c(this, J);
1003
- c(this, Y);
1004
- c(this, K);
1005
- c(this, Z);
1006
- c(this, Q);
1007
- c(this, X);
1008
1063
  /**
1009
1064
  * Adds file information to $_FILES superglobal in PHP.
1010
1065
  *
@@ -1014,40 +1069,41 @@ class w {
1014
1069
  *
1015
1070
  * @param fileInfo - File details
1016
1071
  */
1017
- c(this, ee);
1018
- c(this, te);
1019
- c(this, re);
1072
+ c(this, V);
1073
+ c(this, J);
1074
+ c(this, Y);
1075
+ c(this, b, void 0);
1076
+ c(this, C, void 0);
1020
1077
  c(this, k, void 0);
1021
- c(this, R, void 0);
1022
- c(this, T, void 0);
1023
- c(this, x, void 0);
1024
- c(this, v, void 0);
1025
- c(this, I, void 0);
1026
- c(this, N, void 0);
1027
- p(this, k, []), p(this, R, !1), p(this, T, null), p(this, x, {}), p(this, v, /* @__PURE__ */ new Map()), p(this, I, []), p(this, N, new we({ concurrency: 1 })), e !== void 0 && this.initializeRuntime(e), t && (this.requestHandler = new rt(
1028
- new it(this, t)
1078
+ c(this, m, void 0);
1079
+ c(this, g, void 0);
1080
+ c(this, E, void 0);
1081
+ c(this, y, void 0);
1082
+ c(this, B, void 0);
1083
+ u(this, b, []), u(this, m, !1), u(this, g, null), u(this, E, {}), u(this, y, /* @__PURE__ */ new Map()), u(this, B, []), this.semaphore = new Semaphore({ concurrency: 1 }), e !== void 0 && this.initializeRuntime(e), t && (this.requestHandler = new PHPBrowser(
1084
+ new PHPRequestHandler(this, t)
1029
1085
  ));
1030
1086
  }
1031
1087
  addEventListener(e, t) {
1032
- a(this, v).has(e) || a(this, v).set(e, /* @__PURE__ */ new Set()), a(this, v).get(e).add(t);
1088
+ a(this, y).has(e) || a(this, y).set(e, /* @__PURE__ */ new Set()), a(this, y).get(e).add(t);
1033
1089
  }
1034
1090
  removeEventListener(e, t) {
1035
- var n;
1036
- (n = a(this, v).get(e)) == null || n.delete(t);
1091
+ var r;
1092
+ (r = a(this, y).get(e)) == null || r.delete(t);
1037
1093
  }
1038
1094
  dispatchEvent(e) {
1039
- const t = a(this, v).get(e.type);
1095
+ const t = a(this, y).get(e.type);
1040
1096
  if (t)
1041
- for (const n of t)
1042
- n(e);
1097
+ for (const r of t)
1098
+ r(e);
1043
1099
  }
1044
1100
  /** @inheritDoc */
1045
1101
  async onMessage(e) {
1046
- a(this, I).push(e);
1102
+ a(this, B).push(e);
1047
1103
  }
1048
1104
  /** @inheritDoc */
1049
- async setSpawnHandler(e) {
1050
- this[u].spawnProcess = e;
1105
+ async setSpawnHandler(handler) {
1106
+ typeof handler == "string" && (handler = createSpawnHandler(eval(handler))), this[__private__dont__use].spawnProcess = handler;
1051
1107
  }
1052
1108
  /** @inheritDoc */
1053
1109
  get absoluteUrl() {
@@ -1068,25 +1124,40 @@ class w {
1068
1124
  );
1069
1125
  }
1070
1126
  initializeRuntime(e) {
1071
- if (this[u])
1127
+ if (this[__private__dont__use])
1072
1128
  throw new Error("PHP runtime already initialized.");
1073
- const t = ft(e);
1129
+ const t = getLoadedRuntime(e);
1074
1130
  if (!t)
1075
1131
  throw new Error("Invalid PHP runtime id.");
1076
- this[u] = t, t.onMessage = async (n) => {
1077
- for (const s of a(this, I)) {
1078
- const i = await s(n);
1132
+ this[__private__dont__use] = t, t.onMessage = async (r) => {
1133
+ for (const s of a(this, B)) {
1134
+ const i = await s(r);
1079
1135
  if (i)
1080
1136
  return i;
1081
1137
  }
1082
1138
  return "";
1083
- }, p(this, T, qe(t));
1139
+ }, u(this, g, improveWASMErrorReporting(t)), this.dispatchEvent({
1140
+ type: "runtime.initialized"
1141
+ });
1142
+ }
1143
+ /** @inheritDoc */
1144
+ async setSapiName(e) {
1145
+ if (this[__private__dont__use].ccall(
1146
+ "wasm_set_sapi_name",
1147
+ NUMBER,
1148
+ [STRING],
1149
+ [e]
1150
+ ) !== 0)
1151
+ throw new Error(
1152
+ "Could not set SAPI name. This can only be done before the PHP WASM module is initialized.Did you already dispatch any requests?"
1153
+ );
1154
+ u(this, k, e);
1084
1155
  }
1085
1156
  /** @inheritDoc */
1086
1157
  setPhpIniPath(e) {
1087
- if (a(this, R))
1158
+ if (a(this, m))
1088
1159
  throw new Error("Cannot set PHP ini path after calling run().");
1089
- this[u].ccall(
1160
+ u(this, C, e), this[__private__dont__use].ccall(
1090
1161
  "wasm_set_phpini_path",
1091
1162
  null,
1092
1163
  ["string"],
@@ -1095,13 +1166,13 @@ class w {
1095
1166
  }
1096
1167
  /** @inheritDoc */
1097
1168
  setPhpIniEntry(e, t) {
1098
- if (a(this, R))
1169
+ if (a(this, m))
1099
1170
  throw new Error("Cannot set PHP ini entries after calling run().");
1100
- a(this, k).push([e, t]);
1171
+ a(this, b).push([e, t]);
1101
1172
  }
1102
1173
  /** @inheritDoc */
1103
1174
  chdir(e) {
1104
- this[u].FS.chdir(e);
1175
+ this[__private__dont__use].FS.chdir(e);
1105
1176
  }
1106
1177
  /** @inheritDoc */
1107
1178
  async request(e, t) {
@@ -1111,27 +1182,45 @@ class w {
1111
1182
  }
1112
1183
  /** @inheritDoc */
1113
1184
  async run(e) {
1114
- const t = await a(this, N).acquire();
1185
+ const t = await this.semaphore.acquire();
1186
+ let r;
1115
1187
  try {
1116
- a(this, R) || (m(this, z, ve).call(this), p(this, R, !0)), m(this, Q, Ce).call(this, e.scriptPath || ""), m(this, V, xe).call(this, e.relativeUri || ""), m(this, Y, Fe).call(this, e.method || "GET");
1117
- const n = Be(e.headers || {}), s = n.host || "example.com:443";
1118
- if (m(this, J, _e).call(this, s, e.protocol || "http"), m(this, K, ke).call(this, n), e.body && m(this, Z, Te).call(this, e.body), e.fileInfos)
1119
- for (const i of e.fileInfos)
1120
- m(this, ee, Ae).call(this, i);
1121
- return e.code && m(this, te, $e).call(this, " ?>" + e.code), m(this, X, He).call(this), await m(this, re, Ue).call(this);
1188
+ a(this, m) || (h(this, M, ee).call(this), u(this, m, !0)), h(this, W, ae).call(this, e.scriptPath || ""), h(this, D, re).call(this, e.relativeUri || ""), h(this, q, ne).call(this, e.method || "GET");
1189
+ const s = normalizeHeaders(e.headers || {}), i = s.host || "example.com:443";
1190
+ if (h(this, $, se).call(this, i, e.protocol || "http"), h(this, j, ie).call(this, s), e.body && (r = h(this, z, oe).call(this, e.body)), e.fileInfos)
1191
+ for (const o of e.fileInfos)
1192
+ h(this, V, ce).call(this, o);
1193
+ typeof e.code == "string" && h(this, J, ue).call(this, " ?>" + e.code), h(this, G, le).call(this);
1194
+ const n = await h(this, Y, de).call(this);
1195
+ if (e.throwOnError && n.exitCode !== 0) {
1196
+ const o = {
1197
+ stdout: n.text,
1198
+ stderr: n.errors
1199
+ };
1200
+ console.warn("PHP.run() output was:", o);
1201
+ const l = new Error(
1202
+ `PHP.run() failed with exit code ${n.exitCode} and the following output`
1203
+ );
1204
+ throw l.output = o, l;
1205
+ }
1206
+ return n;
1122
1207
  } finally {
1123
- t(), this.dispatchEvent({
1124
- type: "request.end"
1125
- });
1208
+ try {
1209
+ r && this[__private__dont__use].free(r);
1210
+ } finally {
1211
+ t(), this.dispatchEvent({
1212
+ type: "request.end"
1213
+ });
1214
+ }
1126
1215
  }
1127
1216
  }
1128
1217
  addServerGlobalEntry(e, t) {
1129
- a(this, x)[e] = t;
1218
+ a(this, E)[e] = t;
1130
1219
  }
1131
1220
  defineConstant(e, t) {
1132
- let n = {};
1221
+ let r = {};
1133
1222
  try {
1134
- n = JSON.parse(
1223
+ r = JSON.parse(
1135
1224
  this.fileExists("/tmp/consts.json") && this.readFileAsText("/tmp/consts.json") || "{}"
1136
1225
  );
1137
1226
  } catch {
@@ -1139,13 +1228,13 @@ class w {
1139
1228
  this.writeFile(
1140
1229
  "/tmp/consts.json",
1141
1230
  JSON.stringify({
1142
- ...n,
1231
+ ...r,
1143
1232
  [e]: t
1144
1233
  })
1145
1234
  );
1146
1235
  }
1147
1236
  mkdir(e) {
1148
- this[u].FS.mkdirTree(e);
1237
+ this[__private__dont__use].FS.mkdirTree(e);
1149
1238
  }
1150
1239
  mkdirTree(e) {
1151
1240
  this.mkdir(e);
@@ -1154,67 +1243,91 @@ class w {
1154
1243
  return new TextDecoder().decode(this.readFileAsBuffer(e));
1155
1244
  }
1156
1245
  readFileAsBuffer(e) {
1157
- return this[u].FS.readFile(e);
1246
+ return this[__private__dont__use].FS.readFile(e);
1158
1247
  }
1159
1248
  writeFile(e, t) {
1160
- this[u].FS.writeFile(e, t);
1249
+ this[__private__dont__use].FS.writeFile(e, t);
1161
1250
  }
1162
1251
  unlink(e) {
1163
- this[u].FS.unlink(e);
1252
+ this[__private__dont__use].FS.unlink(e);
1164
1253
  }
1165
1254
  /** @inheritDoc */
1166
1255
  mv(e, t) {
1167
1256
  try {
1168
- this[u].FS.rename(e, t);
1169
- } catch (n) {
1170
- const s = ht(n);
1257
+ this[__private__dont__use].FS.rename(e, t);
1258
+ } catch (r) {
1259
+ const s = getEmscriptenFsError(r);
1171
1260
  throw s ? new Error(
1172
1261
  `Could not move ${e} to ${t}: ${s}`,
1173
1262
  {
1174
- cause: n
1263
+ cause: r
1175
1264
  }
1176
- ) : n;
1265
+ ) : r;
1177
1266
  }
1178
1267
  }
1179
1268
  rmdir(e, t = { recursive: !0 }) {
1180
- t != null && t.recursive && this.listFiles(e).forEach((n) => {
1181
- const s = `${e}/${n}`;
1269
+ t != null && t.recursive && this.listFiles(e).forEach((r) => {
1270
+ const s = `${e}/${r}`;
1182
1271
  this.isDir(s) ? this.rmdir(s, t) : this.unlink(s);
1183
- }), this[u].FS.rmdir(e);
1272
+ }), this[__private__dont__use].FS.rmdir(e);
1184
1273
  }
1185
1274
  listFiles(e, t = { prependPath: !1 }) {
1186
1275
  if (!this.fileExists(e))
1187
1276
  return [];
1188
1277
  try {
1189
- const n = this[u].FS.readdir(e).filter(
1278
+ const r = this[__private__dont__use].FS.readdir(e).filter(
1190
1279
  (s) => s !== "." && s !== ".."
1191
1280
  );
1192
1281
  if (t.prependPath) {
1193
1282
  const s = e.replace(/\/$/, "");
1194
- return n.map((i) => `${s}/${i}`);
1283
+ return r.map((i) => `${s}/${i}`);
1195
1284
  }
1196
- return n;
1197
- } catch (n) {
1198
- return console.error(n, { path: e }), [];
1285
+ return r;
1286
+ } catch (r) {
1287
+ return console.error(r, { path: e }), [];
1199
1288
  }
1200
1289
  }
1201
1290
  isDir(e) {
1202
- return this.fileExists(e) ? this[u].FS.isDir(
1203
- this[u].FS.lookupPath(e).node.mode
1291
+ return this.fileExists(e) ? this[__private__dont__use].FS.isDir(
1292
+ this[__private__dont__use].FS.lookupPath(e).node.mode
1204
1293
  ) : !1;
1205
1294
  }
1206
1295
  fileExists(e) {
1207
1296
  try {
1208
- return this[u].FS.lookupPath(e), !0;
1297
+ return this[__private__dont__use].FS.lookupPath(e), !0;
1209
1298
  } catch {
1210
1299
  return !1;
1211
1300
  }
1212
1301
  }
1302
+ /**
1303
+ * Hot-swaps the PHP runtime for a new one without
1304
+ * interrupting the operations of this PHP instance.
1305
+ *
1306
+ * @param runtime
1307
+ */
1308
+ hotSwapPHPRuntime(e) {
1309
+ const t = this[__private__dont__use].FS;
1310
+ try {
1311
+ this.exit();
1312
+ } catch {
1313
+ }
1314
+ if (this.initializeRuntime(e), a(this, C) && this.setPhpIniPath(a(this, C)), a(this, k) && this.setSapiName(a(this, k)), this.requestHandler) {
1315
+ const r = this.documentRoot;
1316
+ recreateMemFS(this[__private__dont__use].FS, t, r);
1317
+ }
1318
+ }
1213
1319
  exit(e = 0) {
1214
- return this[u]._exit(e);
1320
+ this.dispatchEvent({
1321
+ type: "runtime.beforedestroy"
1322
+ });
1323
+ try {
1324
+ this[__private__dont__use]._exit(e);
1325
+ } catch {
1326
+ }
1327
+ u(this, m, !1), u(this, g, null), delete this[__private__dont__use].onMessage, delete this[__private__dont__use];
1215
1328
  }
1216
1329
  }
1217
- k = new WeakMap(), R = new WeakMap(), T = new WeakMap(), x = new WeakMap(), v = new WeakMap(), I = new WeakMap(), N = new WeakMap(), z = new WeakSet(), ve = function() {
1330
+ b = new WeakMap(), C = new WeakMap(), k = new WeakMap(), m = new WeakMap(), g = new WeakMap(), E = new WeakMap(), y = new WeakMap(), B = new WeakMap(), M = new WeakSet(), ee = function() {
1218
1331
  if (this.setPhpIniEntry("auto_prepend_file", "/tmp/consts.php"), this.fileExists("/tmp/consts.php") || this.writeFile(
1219
1332
  "/tmp/consts.php",
1220
1333
  `<?php
@@ -1226,251 +1339,303 @@ k = new WeakMap(), R = new WeakMap(), T = new WeakMap(), x = new WeakMap(), v =
1226
1339
  }
1227
1340
  }
1228
1341
  }`
1229
- ), a(this, k).length > 0) {
1230
- const e = a(this, k).map(([t, n]) => `${t}=${n}`).join(`
1342
+ ), a(this, b).length > 0) {
1343
+ const e = a(this, b).map(([t, r]) => `${t}=${r}`).join(`
1231
1344
  `) + `
1232
1345
 
1233
1346
  `;
1234
- this[u].ccall(
1347
+ this[__private__dont__use].ccall(
1235
1348
  "wasm_set_phpini_entries",
1236
1349
  null,
1237
- [y],
1350
+ [STRING],
1238
1351
  [e]
1239
1352
  );
1240
1353
  }
1241
- this[u].ccall("php_wasm_init", null, [], []);
1242
- }, G = new WeakSet(), Re = function() {
1354
+ this[__private__dont__use].ccall("php_wasm_init", null, [], []);
1355
+ }, O = new WeakSet(), te = function() {
1243
1356
  const e = "/tmp/headers.json";
1244
1357
  if (!this.fileExists(e))
1245
1358
  throw new Error(
1246
1359
  "SAPI Error: Could not find response headers file."
1247
1360
  );
1248
- const t = JSON.parse(this.readFileAsText(e)), n = {};
1361
+ const t = JSON.parse(this.readFileAsText(e)), r = {};
1249
1362
  for (const s of t.headers) {
1250
1363
  if (!s.includes(": "))
1251
1364
  continue;
1252
- const i = s.indexOf(": "), o = s.substring(0, i).toLowerCase(), l = s.substring(i + 2);
1253
- o in n || (n[o] = []), n[o].push(l);
1365
+ const i = s.indexOf(": "), n = s.substring(0, i).toLowerCase(), o = s.substring(i + 2);
1366
+ n in r || (r[n] = []), r[n].push(o);
1254
1367
  }
1255
1368
  return {
1256
- headers: n,
1369
+ headers: r,
1257
1370
  httpStatusCode: t.status
1258
1371
  };
1259
- }, V = new WeakSet(), xe = function(e) {
1260
- if (this[u].ccall(
1372
+ }, D = new WeakSet(), re = function(e) {
1373
+ if (this[__private__dont__use].ccall(
1261
1374
  "wasm_set_request_uri",
1262
1375
  null,
1263
- [y],
1376
+ [STRING],
1264
1377
  [e]
1265
1378
  ), e.includes("?")) {
1266
1379
  const t = e.substring(e.indexOf("?") + 1);
1267
- this[u].ccall(
1380
+ this[__private__dont__use].ccall(
1268
1381
  "wasm_set_query_string",
1269
1382
  null,
1270
- [y],
1383
+ [STRING],
1271
1384
  [t]
1272
1385
  );
1273
1386
  }
1274
- }, J = new WeakSet(), _e = function(e, t) {
1275
- this[u].ccall(
1387
+ }, $ = new WeakSet(), se = function(e, t) {
1388
+ this[__private__dont__use].ccall(
1276
1389
  "wasm_set_request_host",
1277
1390
  null,
1278
- [y],
1391
+ [STRING],
1279
1392
  [e]
1280
1393
  );
1281
- let n;
1394
+ let r;
1282
1395
  try {
1283
- n = parseInt(new URL(e).port, 10);
1396
+ r = parseInt(new URL(e).port, 10);
1284
1397
  } catch {
1285
1398
  }
1286
- (!n || isNaN(n) || n === 80) && (n = t === "https" ? 443 : 80), this[u].ccall(
1399
+ (!r || isNaN(r) || r === 80) && (r = t === "https" ? 443 : 80), this[__private__dont__use].ccall(
1287
1400
  "wasm_set_request_port",
1288
1401
  null,
1289
- [C],
1290
- [n]
1291
- ), (t === "https" || !t && n === 443) && this.addServerGlobalEntry("HTTPS", "on");
1292
- }, Y = new WeakSet(), Fe = function(e) {
1293
- this[u].ccall(
1402
+ [NUMBER],
1403
+ [r]
1404
+ ), (t === "https" || !t && r === 443) && this.addServerGlobalEntry("HTTPS", "on");
1405
+ }, q = new WeakSet(), ne = function(e) {
1406
+ this[__private__dont__use].ccall(
1294
1407
  "wasm_set_request_method",
1295
1408
  null,
1296
- [y],
1409
+ [STRING],
1297
1410
  [e]
1298
1411
  );
1299
- }, K = new WeakSet(), ke = function(e) {
1300
- e.cookie && this[u].ccall(
1412
+ }, j = new WeakSet(), ie = function(e) {
1413
+ e.cookie && this[__private__dont__use].ccall(
1301
1414
  "wasm_set_cookies",
1302
1415
  null,
1303
- [y],
1416
+ [STRING],
1304
1417
  [e.cookie]
1305
- ), e["content-type"] && this[u].ccall(
1418
+ ), e["content-type"] && this[__private__dont__use].ccall(
1306
1419
  "wasm_set_content_type",
1307
1420
  null,
1308
- [y],
1421
+ [STRING],
1309
1422
  [e["content-type"]]
1310
- ), e["content-length"] && this[u].ccall(
1423
+ ), e["content-length"] && this[__private__dont__use].ccall(
1311
1424
  "wasm_set_content_length",
1312
1425
  null,
1313
- [C],
1426
+ [NUMBER],
1314
1427
  [parseInt(e["content-length"], 10)]
1315
1428
  );
1316
1429
  for (const t in e) {
1317
- let n = "HTTP_";
1318
- ["content-type", "content-length"].includes(t.toLowerCase()) && (n = ""), this.addServerGlobalEntry(
1319
- `${n}${t.toUpperCase().replace(/-/g, "_")}`,
1430
+ let r = "HTTP_";
1431
+ ["content-type", "content-length"].includes(t.toLowerCase()) && (r = ""), this.addServerGlobalEntry(
1432
+ `${r}${t.toUpperCase().replace(/-/g, "_")}`,
1320
1433
  e[t]
1321
1434
  );
1322
1435
  }
1323
- }, Z = new WeakSet(), Te = function(e) {
1324
- this[u].ccall(
1436
+ }, z = new WeakSet(), oe = function(e) {
1437
+ const t = this[__private__dont__use].lengthBytesUTF8(e), r = this[__private__dont__use].malloc(t + 1);
1438
+ if (!r)
1439
+ throw new Error("Could not allocate memory for the request body.");
1440
+ return this[__private__dont__use].stringToUTF8(
1441
+ e,
1442
+ r,
1443
+ t + 1
1444
+ ), this[__private__dont__use].ccall(
1325
1445
  "wasm_set_request_body",
1326
1446
  null,
1327
- [y],
1328
- [e]
1329
- ), this[u].ccall(
1447
+ [NUMBER],
1448
+ [r]
1449
+ ), this[__private__dont__use].ccall(
1330
1450
  "wasm_set_content_length",
1331
1451
  null,
1332
- [C],
1452
+ [NUMBER],
1333
1453
  [new TextEncoder().encode(e).length]
1334
- );
1335
- }, Q = new WeakSet(), Ce = function(e) {
1336
- this[u].ccall(
1454
+ ), r;
1455
+ }, W = new WeakSet(), ae = function(e) {
1456
+ this[__private__dont__use].ccall(
1337
1457
  "wasm_set_path_translated",
1338
1458
  null,
1339
- [y],
1459
+ [STRING],
1340
1460
  [e]
1341
1461
  );
1342
- }, X = new WeakSet(), He = function() {
1343
- for (const e in a(this, x))
1344
- this[u].ccall(
1462
+ }, G = new WeakSet(), le = function() {
1463
+ for (const e in a(this, E))
1464
+ this[__private__dont__use].ccall(
1345
1465
  "wasm_add_SERVER_entry",
1346
1466
  null,
1347
- [y, y],
1348
- [e, a(this, x)[e]]
1467
+ [STRING, STRING],
1468
+ [e, a(this, E)[e]]
1349
1469
  );
1350
- }, ee = new WeakSet(), Ae = function(e) {
1351
- const { key: t, name: n, type: s, data: i } = e, o = `/tmp/${Math.random().toFixed(20)}`;
1352
- this.writeFile(o, i);
1353
- const l = 0;
1354
- this[u].ccall(
1470
+ }, V = new WeakSet(), ce = function(e) {
1471
+ const { key: t, name: r, type: s, data: i } = e, n = `/tmp/${Math.random().toFixed(20)}`;
1472
+ this.writeFile(n, i);
1473
+ const o = 0;
1474
+ this[__private__dont__use].ccall(
1355
1475
  "wasm_add_uploaded_file",
1356
1476
  null,
1357
- [y, y, y, y, C, C],
1358
- [t, n, s, o, l, i.byteLength]
1477
+ [STRING, STRING, STRING, STRING, NUMBER, NUMBER],
1478
+ [t, r, s, n, o, i.byteLength]
1359
1479
  );
1360
- }, te = new WeakSet(), $e = function(e) {
1361
- this[u].ccall(
1480
+ }, J = new WeakSet(), ue = function(e) {
1481
+ this[__private__dont__use].ccall(
1362
1482
  "wasm_set_php_code",
1363
1483
  null,
1364
- [y],
1484
+ [STRING],
1365
1485
  [e]
1366
1486
  );
1367
- }, re = new WeakSet(), Ue = async function() {
1487
+ }, Y = new WeakSet(), de = async function() {
1368
1488
  var i;
1369
1489
  let e, t;
1370
1490
  try {
1371
- e = await new Promise((o, l) => {
1372
- var f;
1373
- t = (h) => {
1374
- const S = new Error("Rethrown");
1375
- S.cause = h.error, S.betterMessage = h.message, l(S);
1376
- }, (f = a(this, T)) == null || f.addEventListener(
1491
+ e = await new Promise((n, o) => {
1492
+ var p;
1493
+ t = (d) => {
1494
+ const f = new Error("Rethrown");
1495
+ f.cause = d.error, f.betterMessage = d.message, o(f);
1496
+ }, (p = a(this, g)) == null || p.addEventListener(
1377
1497
  "error",
1378
1498
  t
1379
1499
  );
1380
- const d = this[u].ccall(
1500
+ const l = this[__private__dont__use].ccall(
1381
1501
  "wasm_sapi_handle_request",
1382
- C,
1502
+ NUMBER,
1383
1503
  [],
1384
1504
  [],
1385
1505
  { async: !0 }
1386
1506
  );
1387
- return d instanceof Promise ? d.then(o, l) : o(d);
1507
+ return l instanceof Promise ? l.then(n, o) : n(l);
1388
1508
  });
1389
- } catch (o) {
1390
- for (const h in this)
1391
- typeof this[h] == "function" && (this[h] = () => {
1509
+ } catch (n) {
1510
+ for (const d in this)
1511
+ typeof this[d] == "function" && (this[d] = () => {
1392
1512
  throw new Error(
1393
1513
  "PHP runtime has crashed – see the earlier error for details."
1394
1514
  );
1395
1515
  });
1396
- this.functionsMaybeMissingFromAsyncify = De();
1397
- const l = o, d = "betterMessage" in l ? l.betterMessage : l.message, f = new Error(d);
1398
- throw f.cause = l, f;
1516
+ this.functionsMaybeMissingFromAsyncify = getFunctionsMaybeMissingFromAsyncify();
1517
+ const o = n, l = "betterMessage" in o ? o.betterMessage : o.message, p = new Error(l);
1518
+ throw p.cause = o, p;
1399
1519
  } finally {
1400
- (i = a(this, T)) == null || i.removeEventListener("error", t), p(this, x, {});
1520
+ (i = a(this, g)) == null || i.removeEventListener("error", t), u(this, E, {});
1401
1521
  }
1402
- const { headers: n, httpStatusCode: s } = m(this, G, Re).call(this);
1403
- return new H(
1522
+ const { headers: r, httpStatusCode: s } = h(this, O, te).call(this);
1523
+ return new PHPResponse(
1404
1524
  s,
1405
- n,
1525
+ r,
1406
1526
  this.readFileAsBuffer("/tmp/stdout"),
1407
1527
  this.readFileAsText("/tmp/stderr"),
1408
1528
  e
1409
1529
  );
1410
1530
  };
1411
- E([
1412
- P('Could not create directory "{path}"')
1413
- ], w.prototype, "mkdir", 1);
1414
- E([
1415
- P('Could not create directory "{path}"')
1416
- ], w.prototype, "mkdirTree", 1);
1417
- E([
1418
- P('Could not read "{path}"')
1419
- ], w.prototype, "readFileAsText", 1);
1420
- E([
1421
- P('Could not read "{path}"')
1422
- ], w.prototype, "readFileAsBuffer", 1);
1423
- E([
1424
- P('Could not write to "{path}"')
1425
- ], w.prototype, "writeFile", 1);
1426
- E([
1427
- P('Could not unlink "{path}"')
1428
- ], w.prototype, "unlink", 1);
1429
- E([
1430
- P('Could not remove directory "{path}"')
1431
- ], w.prototype, "rmdir", 1);
1432
- E([
1433
- P('Could not list files in "{path}"')
1434
- ], w.prototype, "listFiles", 1);
1435
- E([
1436
- P('Could not stat "{path}"')
1437
- ], w.prototype, "isDir", 1);
1438
- E([
1439
- P('Could not stat "{path}"')
1440
- ], w.prototype, "fileExists", 1);
1441
- function Be(r) {
1442
- const e = {};
1443
- for (const t in r)
1444
- e[t.toLowerCase()] = r[t];
1445
- return e;
1531
+ __decorateClass([
1532
+ rethrowFileSystemError('Could not create directory "{path}"')
1533
+ ], BasePHP.prototype, "mkdir", 1);
1534
+ __decorateClass([
1535
+ rethrowFileSystemError('Could not create directory "{path}"')
1536
+ ], BasePHP.prototype, "mkdirTree", 1);
1537
+ __decorateClass([
1538
+ rethrowFileSystemError('Could not read "{path}"')
1539
+ ], BasePHP.prototype, "readFileAsText", 1);
1540
+ __decorateClass([
1541
+ rethrowFileSystemError('Could not read "{path}"')
1542
+ ], BasePHP.prototype, "readFileAsBuffer", 1);
1543
+ __decorateClass([
1544
+ rethrowFileSystemError('Could not write to "{path}"')
1545
+ ], BasePHP.prototype, "writeFile", 1);
1546
+ __decorateClass([
1547
+ rethrowFileSystemError('Could not unlink "{path}"')
1548
+ ], BasePHP.prototype, "unlink", 1);
1549
+ __decorateClass([
1550
+ rethrowFileSystemError('Could not remove directory "{path}"')
1551
+ ], BasePHP.prototype, "rmdir", 1);
1552
+ __decorateClass([
1553
+ rethrowFileSystemError('Could not list files in "{path}"')
1554
+ ], BasePHP.prototype, "listFiles", 1);
1555
+ __decorateClass([
1556
+ rethrowFileSystemError('Could not stat "{path}"')
1557
+ ], BasePHP.prototype, "isDir", 1);
1558
+ __decorateClass([
1559
+ rethrowFileSystemError('Could not stat "{path}"')
1560
+ ], BasePHP.prototype, "fileExists", 1);
1561
+ function normalizeHeaders(e) {
1562
+ const t = {};
1563
+ for (const r in e)
1564
+ t[r.toLowerCase()] = e[r];
1565
+ return t;
1566
+ }
1567
+ function recreateMemFS(e, t, r) {
1568
+ let s;
1569
+ try {
1570
+ s = t.lookupPath(r);
1571
+ } catch {
1572
+ return;
1573
+ }
1574
+ if (!("contents" in s.node))
1575
+ return;
1576
+ try {
1577
+ e = e.lookupPath(r);
1578
+ return;
1579
+ } catch {
1580
+ }
1581
+ if (!t.isDir(s.node.mode)) {
1582
+ e.writeFile(r, t.readFile(r));
1583
+ return;
1584
+ }
1585
+ e.mkdirTree(r);
1586
+ const i = t.readdir(r).filter((n) => n !== "." && n !== "..");
1587
+ for (const n of i)
1588
+ recreateMemFS(e, t, joinPaths(r, n));
1446
1589
  }
1447
- function wt(r) {
1448
- return !(r instanceof w);
1590
+ function isLocalPHP(e) {
1591
+ return !(e instanceof BasePHP);
1449
1592
  }
1450
- function xt(r) {
1451
- return !wt(r);
1593
+ function isRemotePHP(e) {
1594
+ return !isLocalPHP(e);
1595
+ }
1596
+ function rotatePHPRuntime({
1597
+ php: e,
1598
+ recreateRuntime: t,
1599
+ maxRequests: r
1600
+ }) {
1601
+ let s = 0;
1602
+ async function i() {
1603
+ if (++s < r)
1604
+ return;
1605
+ s = 0;
1606
+ const n = await e.semaphore.acquire();
1607
+ try {
1608
+ e.hotSwapPHPRuntime(await t());
1609
+ } finally {
1610
+ n();
1611
+ }
1612
+ }
1613
+ return e.addEventListener("request.end", i), function() {
1614
+ e.removeEventListener("request.end", i);
1615
+ };
1452
1616
  }
1453
1617
  export {
1454
- w as BasePHP,
1455
- nt as DEFAULT_BASE_URL,
1456
- Et as LatestSupportedPHPVersion,
1457
- rt as PHPBrowser,
1458
- it as PHPRequestHandler,
1459
- H as PHPResponse,
1460
- vt as SupportedPHPExtensionBundles,
1461
- tt as SupportedPHPExtensionsList,
1462
- be as SupportedPHPVersions,
1463
- St as SupportedPHPVersionsList,
1464
- Ne as UnhandledRejectionsTarget,
1465
- u as __private__dont__use,
1466
- st as ensurePathPrefix,
1467
- Oe as isExitCodeZero,
1468
- wt as isLocalPHP,
1469
- xt as isRemotePHP,
1470
- bt as iterateFiles,
1471
- Rt as loadPHPRuntime,
1472
- pe as removePathPrefix,
1473
- P as rethrowFileSystemError,
1474
- fe as toRelativeUrl,
1475
- Pt as writeFilesStreamToPhp
1618
+ BasePHP,
1619
+ DEFAULT_BASE_URL,
1620
+ LatestSupportedPHPVersion,
1621
+ PHPBrowser,
1622
+ PHPRequestHandler,
1623
+ PHPResponse,
1624
+ SupportedPHPExtensionBundles,
1625
+ SupportedPHPExtensionsList,
1626
+ SupportedPHPVersions,
1627
+ SupportedPHPVersionsList,
1628
+ UnhandledRejectionsTarget,
1629
+ __private__dont__use,
1630
+ ensurePathPrefix,
1631
+ isExitCodeZero,
1632
+ isLocalPHP,
1633
+ isRemotePHP,
1634
+ iteratePhpFiles as iterateFiles,
1635
+ loadPHPRuntime,
1636
+ removePathPrefix,
1637
+ rethrowFileSystemError,
1638
+ rotatePHPRuntime,
1639
+ toRelativeUrl,
1640
+ writeFilesStreamToPhp
1476
1641
  };