@php-wasm/web 0.9.18 → 0.9.20
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.d.ts +1 -1160
- package/index.js +139 -139
- package/lib/api.d.ts +17 -0
- package/lib/directory-handle-mount.d.ts +31 -0
- package/lib/get-php-loader-module.d.ts +9 -0
- package/lib/index.d.ts +10 -0
- package/lib/load-runtime.d.ts +8 -0
- package/lib/register-service-worker.d.ts +24 -0
- package/lib/setup-post-message-relay.d.ts +14 -0
- package/package.json +7 -7
package/index.js
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
import { PHPResponse as C, LatestSupportedPHPVersion as
|
|
1
|
+
import { PHPResponse as C, LatestSupportedPHPVersion as R, loadPHPRuntime as L, FSHelpers as w, __private__dont__use as g } from "@php-wasm/universal";
|
|
2
2
|
import * as d from "comlink";
|
|
3
|
-
import { PhpWasmError as
|
|
4
|
-
import { responseTo as
|
|
5
|
-
import { logger as
|
|
6
|
-
import { journalFSEvents as
|
|
7
|
-
function B(
|
|
3
|
+
import { PhpWasmError as m, Semaphore as M, joinPaths as T } from "@php-wasm/util";
|
|
4
|
+
import { responseTo as O } from "@php-wasm/web-service-worker";
|
|
5
|
+
import { logger as h } from "@php-wasm/logger";
|
|
6
|
+
import { journalFSEvents as z } from "@php-wasm/fs-journal";
|
|
7
|
+
function B(t, r = void 0) {
|
|
8
8
|
W();
|
|
9
|
-
const e =
|
|
9
|
+
const e = t instanceof Worker ? t : d.windowEndpoint(t, r), a = d.wrap(e), n = y(a);
|
|
10
10
|
return new Proxy(n, {
|
|
11
11
|
get: (i, s) => s === "isConnected" ? async () => {
|
|
12
12
|
for (; ; )
|
|
13
13
|
try {
|
|
14
|
-
await
|
|
14
|
+
await D(a.isConnected(), 200);
|
|
15
15
|
break;
|
|
16
16
|
} catch {
|
|
17
17
|
}
|
|
18
18
|
} : a[s]
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
|
-
async function
|
|
21
|
+
async function D(t, r) {
|
|
22
22
|
return new Promise((e, a) => {
|
|
23
|
-
setTimeout(a,
|
|
23
|
+
setTimeout(a, r), t.then(e);
|
|
24
24
|
});
|
|
25
25
|
}
|
|
26
|
-
function
|
|
26
|
+
function G(t, r) {
|
|
27
27
|
W();
|
|
28
28
|
const e = Promise.resolve();
|
|
29
29
|
let a, n;
|
|
30
30
|
const i = new Promise((o, u) => {
|
|
31
31
|
a = o, n = u;
|
|
32
|
-
}), s =
|
|
33
|
-
get: (o, u) => u === "isConnected" ? () => e : u === "isReady" ? () => i : u in o ? o[u] :
|
|
32
|
+
}), s = y(t), c = new Proxy(s, {
|
|
33
|
+
get: (o, u) => u === "isConnected" ? () => e : u === "isReady" ? () => i : u in o ? o[u] : r == null ? void 0 : r[u]
|
|
34
34
|
});
|
|
35
35
|
return d.expose(
|
|
36
36
|
c,
|
|
@@ -68,33 +68,33 @@ function W() {
|
|
|
68
68
|
return C.fromRawData(e);
|
|
69
69
|
}
|
|
70
70
|
});
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
const a =
|
|
71
|
+
const t = d.transferHandlers.get("throw"), r = t == null ? void 0 : t.serialize;
|
|
72
|
+
t.serialize = ({ value: e }) => {
|
|
73
|
+
const a = r({ value: e });
|
|
74
74
|
return e.response && (a[0].value.response = e.response), e.source && (a[0].value.source = e.source), a;
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
|
-
function
|
|
78
|
-
return new Proxy(
|
|
79
|
-
get(
|
|
80
|
-
switch (typeof
|
|
77
|
+
function y(t) {
|
|
78
|
+
return new Proxy(t, {
|
|
79
|
+
get(r, e) {
|
|
80
|
+
switch (typeof r[e]) {
|
|
81
81
|
case "function":
|
|
82
|
-
return (...a) =>
|
|
82
|
+
return (...a) => r[e](...a);
|
|
83
83
|
case "object":
|
|
84
|
-
return
|
|
84
|
+
return r[e] === null ? r[e] : y(r[e]);
|
|
85
85
|
case "undefined":
|
|
86
86
|
case "number":
|
|
87
87
|
case "string":
|
|
88
|
-
return
|
|
88
|
+
return r[e];
|
|
89
89
|
default:
|
|
90
|
-
return d.proxy(
|
|
90
|
+
return d.proxy(r[e]);
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
});
|
|
94
94
|
}
|
|
95
|
-
async function
|
|
96
|
-
if (
|
|
97
|
-
switch (
|
|
95
|
+
async function S(t = R, r = "light") {
|
|
96
|
+
if (r === "kitchen-sink")
|
|
97
|
+
switch (t) {
|
|
98
98
|
case "8.3":
|
|
99
99
|
return await import("./kitchen-sink/php_8_3.js");
|
|
100
100
|
case "8.2":
|
|
@@ -115,7 +115,7 @@ async function D(r = O, t = "light") {
|
|
|
115
115
|
return await import("./kitchen-sink/php_7_0.js");
|
|
116
116
|
}
|
|
117
117
|
else
|
|
118
|
-
switch (
|
|
118
|
+
switch (t) {
|
|
119
119
|
case "8.3":
|
|
120
120
|
return await import("./light/php_8_3.js");
|
|
121
121
|
case "8.2":
|
|
@@ -135,11 +135,11 @@ async function D(r = O, t = "light") {
|
|
|
135
135
|
case "7.0":
|
|
136
136
|
return await import("./light/php_7_0.js");
|
|
137
137
|
}
|
|
138
|
-
throw new Error(`Unsupported PHP version ${
|
|
138
|
+
throw new Error(`Unsupported PHP version ${t}`);
|
|
139
139
|
}
|
|
140
|
-
const
|
|
140
|
+
const A = () => ({
|
|
141
141
|
websocket: {
|
|
142
|
-
decorator: (
|
|
142
|
+
decorator: (t) => class extends t {
|
|
143
143
|
constructor() {
|
|
144
144
|
try {
|
|
145
145
|
super();
|
|
@@ -152,94 +152,93 @@ const M = () => ({
|
|
|
152
152
|
}
|
|
153
153
|
}
|
|
154
154
|
});
|
|
155
|
-
async function
|
|
155
|
+
async function Q(t, r = {}) {
|
|
156
156
|
var n;
|
|
157
|
-
const e =
|
|
158
|
-
return (n =
|
|
159
|
-
...
|
|
160
|
-
...
|
|
157
|
+
const e = r.loadAllExtensions ? "kitchen-sink" : "light", a = await S(t, e);
|
|
158
|
+
return (n = r.onPhpLoaderModuleLoaded) == null || n.call(r, a), await L(a, {
|
|
159
|
+
...r.emscriptenOptions || {},
|
|
160
|
+
...A()
|
|
161
161
|
});
|
|
162
162
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
163
|
+
let b;
|
|
164
|
+
const I = new Promise((t) => {
|
|
165
|
+
b = t;
|
|
166
|
+
});
|
|
167
|
+
function X(t) {
|
|
168
|
+
if (!t)
|
|
169
|
+
throw new m("PHP API client must be a valid client object.");
|
|
170
|
+
b(t);
|
|
171
|
+
}
|
|
172
|
+
async function Y(t, r) {
|
|
173
|
+
const e = navigator.serviceWorker;
|
|
174
|
+
if (!e)
|
|
175
|
+
throw window.isSecureContext ? new m(
|
|
167
176
|
"Service workers are not supported in your browser."
|
|
168
|
-
) : new
|
|
177
|
+
) : new m(
|
|
169
178
|
"WordPress Playground uses service workers and may only work on HTTPS and http://localhost/ sites, but the current site is neither."
|
|
170
179
|
);
|
|
171
|
-
await (await
|
|
180
|
+
await (await e.register(r, {
|
|
172
181
|
type: "module",
|
|
173
182
|
// Always bypass HTTP cache when fetching the new Service Worker script:
|
|
174
183
|
updateViaCache: "none"
|
|
175
184
|
})).update(), navigator.serviceWorker.addEventListener(
|
|
176
185
|
"message",
|
|
177
|
-
async function(
|
|
178
|
-
if (t &&
|
|
186
|
+
async function(i) {
|
|
187
|
+
if (t && i.data.scope !== t)
|
|
179
188
|
return;
|
|
180
|
-
const c =
|
|
181
|
-
|
|
189
|
+
const s = await I, c = i.data.args || [], o = i.data.method, u = await s[o](...c);
|
|
190
|
+
i.source.postMessage(O(i.data.requestId, u));
|
|
182
191
|
}
|
|
183
|
-
),
|
|
192
|
+
), e.startMessages();
|
|
184
193
|
}
|
|
185
|
-
function
|
|
194
|
+
function Z(t, r) {
|
|
186
195
|
window.addEventListener("message", (e) => {
|
|
187
|
-
e.source ===
|
|
196
|
+
e.source === t.contentWindow && (r && e.origin !== r || typeof e.data != "object" || e.data.type !== "relay" || window.parent.postMessage(e.data, "*"));
|
|
188
197
|
}), window.addEventListener("message", (e) => {
|
|
189
198
|
var a;
|
|
190
|
-
e.source === window.parent && (typeof e.data != "object" || e.data.type !== "relay" || (a =
|
|
199
|
+
e.source === window.parent && (typeof e.data != "object" || e.data.type !== "relay" || (a = t == null ? void 0 : t.contentWindow) == null || a.postMessage(e.data));
|
|
191
200
|
});
|
|
192
201
|
}
|
|
193
|
-
async function
|
|
194
|
-
|
|
195
|
-
const e = new Worker(r, { type: "module" });
|
|
202
|
+
async function ee(t, r = {}) {
|
|
203
|
+
const e = new Worker(t, { type: "module" });
|
|
196
204
|
return new Promise((a, n) => {
|
|
197
205
|
e.onerror = (s) => {
|
|
198
206
|
const c = new Error(
|
|
199
|
-
`WebWorker failed to load at ${
|
|
207
|
+
`WebWorker failed to load at ${t}. ${s.message ? `Original error: ${s.message}` : ""}`
|
|
200
208
|
);
|
|
201
209
|
c.filename = s.filename, n(c);
|
|
202
|
-
}
|
|
210
|
+
}, e.postMessage({
|
|
211
|
+
type: "startup-options",
|
|
212
|
+
startupOptions: r
|
|
213
|
+
});
|
|
203
214
|
function i(s) {
|
|
204
215
|
s.data === "worker-script-started" && (a(e), e.removeEventListener("message", i));
|
|
205
216
|
}
|
|
206
217
|
e.addEventListener("message", i);
|
|
207
218
|
});
|
|
208
219
|
}
|
|
209
|
-
function
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
const e = new URL(r);
|
|
213
|
-
for (const [a, n] of Object.entries(t))
|
|
214
|
-
if (Array.isArray(n))
|
|
215
|
-
for (const i of n)
|
|
216
|
-
e.searchParams.append(a, i);
|
|
217
|
-
else
|
|
218
|
-
e.searchParams.set(a, n);
|
|
219
|
-
return e.toString();
|
|
220
|
-
}
|
|
221
|
-
function Z(r, t = { initialSync: {} }) {
|
|
222
|
-
return t = {
|
|
223
|
-
...t,
|
|
220
|
+
function te(t, r = { initialSync: {} }) {
|
|
221
|
+
return r = {
|
|
222
|
+
...r,
|
|
224
223
|
initialSync: {
|
|
225
|
-
...
|
|
226
|
-
direction:
|
|
224
|
+
...r.initialSync,
|
|
225
|
+
direction: r.initialSync.direction ?? "opfs-to-memfs"
|
|
227
226
|
}
|
|
228
227
|
}, async function(e, a, n) {
|
|
229
|
-
return
|
|
228
|
+
return r.initialSync.direction === "opfs-to-memfs" ? (w.fileExists(a, n) && w.rmdir(a, n), w.mkdir(a, n), await _(a, t, n)) : await v(
|
|
230
229
|
a,
|
|
231
|
-
|
|
230
|
+
t,
|
|
232
231
|
n,
|
|
233
|
-
|
|
234
|
-
),
|
|
232
|
+
r.initialSync.onProgress
|
|
233
|
+
), q(e, t, n);
|
|
235
234
|
};
|
|
236
235
|
}
|
|
237
|
-
async function
|
|
238
|
-
w.mkdir(
|
|
239
|
-
const a = new
|
|
236
|
+
async function _(t, r, e) {
|
|
237
|
+
w.mkdir(t, e);
|
|
238
|
+
const a = new M({
|
|
240
239
|
concurrency: 40
|
|
241
240
|
}), n = [], i = [
|
|
242
|
-
[
|
|
241
|
+
[r, e]
|
|
243
242
|
];
|
|
244
243
|
for (; i.length > 0; ) {
|
|
245
244
|
const [s, c] = i.pop();
|
|
@@ -251,18 +250,18 @@ async function I(r, t, e) {
|
|
|
251
250
|
);
|
|
252
251
|
if (o.kind === "directory") {
|
|
253
252
|
try {
|
|
254
|
-
|
|
253
|
+
t.mkdir(l);
|
|
255
254
|
} catch (f) {
|
|
256
255
|
if ((f == null ? void 0 : f.errno) !== 20)
|
|
257
|
-
throw
|
|
256
|
+
throw h.error(f), f;
|
|
258
257
|
}
|
|
259
258
|
i.push([o, l]);
|
|
260
259
|
} else if (o.kind === "file") {
|
|
261
|
-
const f = await o.getFile(),
|
|
262
|
-
|
|
260
|
+
const f = await o.getFile(), p = new Uint8Array(await f.arrayBuffer());
|
|
261
|
+
t.createDataFile(
|
|
263
262
|
c,
|
|
264
263
|
o.name,
|
|
265
|
-
|
|
264
|
+
p,
|
|
266
265
|
!0,
|
|
267
266
|
!0,
|
|
268
267
|
!0
|
|
@@ -276,39 +275,39 @@ async function I(r, t, e) {
|
|
|
276
275
|
await Promise.any(n);
|
|
277
276
|
}
|
|
278
277
|
}
|
|
279
|
-
async function
|
|
280
|
-
|
|
278
|
+
async function v(t, r, e, a) {
|
|
279
|
+
t.mkdirTree(e);
|
|
281
280
|
const n = [];
|
|
282
281
|
async function i(o, u) {
|
|
283
282
|
await Promise.all(
|
|
284
|
-
|
|
283
|
+
t.readdir(o).filter(
|
|
285
284
|
(l) => l !== "." && l !== ".."
|
|
286
285
|
).map(async (l) => {
|
|
287
286
|
const f = T(o, l);
|
|
288
|
-
if (
|
|
287
|
+
if (!$(t, f)) {
|
|
289
288
|
n.push([u, f, l]);
|
|
290
289
|
return;
|
|
291
290
|
}
|
|
292
|
-
const
|
|
291
|
+
const p = await u.getDirectoryHandle(l, {
|
|
293
292
|
create: !0
|
|
294
293
|
});
|
|
295
|
-
return await i(f,
|
|
294
|
+
return await i(f, p);
|
|
296
295
|
})
|
|
297
296
|
);
|
|
298
297
|
}
|
|
299
|
-
await i(e,
|
|
298
|
+
await i(e, r);
|
|
300
299
|
let s = 0;
|
|
301
300
|
const c = n.map(
|
|
302
|
-
([o, u, l]) => x(o, l,
|
|
301
|
+
([o, u, l]) => x(o, l, t, u).then(() => {
|
|
303
302
|
a == null || a({ files: ++s, total: n.length });
|
|
304
303
|
})
|
|
305
304
|
);
|
|
306
305
|
await Promise.all(c);
|
|
307
306
|
}
|
|
308
|
-
function
|
|
309
|
-
return
|
|
307
|
+
function $(t, r) {
|
|
308
|
+
return t.isDir(t.lookupPath(r, { follow: !0 }).node.mode);
|
|
310
309
|
}
|
|
311
|
-
async function x(
|
|
310
|
+
async function x(t, r, e, a) {
|
|
312
311
|
let n;
|
|
313
312
|
try {
|
|
314
313
|
n = e.readFile(a, {
|
|
@@ -317,7 +316,7 @@ async function x(r, t, e, a) {
|
|
|
317
316
|
} catch {
|
|
318
317
|
return;
|
|
319
318
|
}
|
|
320
|
-
const i = await
|
|
319
|
+
const i = await t.getFileHandle(r, { create: !0 }), s = i.createWritable !== void 0 ? (
|
|
321
320
|
// Google Chrome, Firefox, probably more browsers
|
|
322
321
|
await i.createWritable()
|
|
323
322
|
) : (
|
|
@@ -330,12 +329,12 @@ async function x(r, t, e, a) {
|
|
|
330
329
|
await s.close();
|
|
331
330
|
}
|
|
332
331
|
}
|
|
333
|
-
function
|
|
334
|
-
const a = [], n =
|
|
332
|
+
function q(t, r, e) {
|
|
333
|
+
const a = [], n = z(t, e, (c) => {
|
|
335
334
|
a.push(c);
|
|
336
|
-
}), i = new
|
|
335
|
+
}), i = new J(t, r, e);
|
|
337
336
|
async function s() {
|
|
338
|
-
const c = await
|
|
337
|
+
const c = await t.semaphore.acquire();
|
|
339
338
|
try {
|
|
340
339
|
for (; a.length; )
|
|
341
340
|
await i.processEntry(a.shift());
|
|
@@ -343,59 +342,59 @@ function $(r, t, e) {
|
|
|
343
342
|
c();
|
|
344
343
|
}
|
|
345
344
|
}
|
|
346
|
-
return
|
|
347
|
-
n(),
|
|
345
|
+
return t.addEventListener("request.end", s), function() {
|
|
346
|
+
n(), t.removeEventListener("request.end", s);
|
|
348
347
|
};
|
|
349
348
|
}
|
|
350
|
-
class
|
|
351
|
-
constructor(
|
|
352
|
-
this.php =
|
|
349
|
+
class J {
|
|
350
|
+
constructor(r, e, a) {
|
|
351
|
+
this.php = r, this.opfs = e, this.memfsRoot = E(a);
|
|
353
352
|
}
|
|
354
|
-
toOpfsPath(
|
|
355
|
-
return E(
|
|
353
|
+
toOpfsPath(r) {
|
|
354
|
+
return E(r.substring(this.memfsRoot.length));
|
|
356
355
|
}
|
|
357
|
-
async processEntry(
|
|
358
|
-
if (!
|
|
356
|
+
async processEntry(r) {
|
|
357
|
+
if (!r.path.startsWith(this.memfsRoot) || r.path === this.memfsRoot)
|
|
359
358
|
return;
|
|
360
|
-
const e = this.toOpfsPath(
|
|
359
|
+
const e = this.toOpfsPath(r.path), a = await H(this.opfs, e), n = k(e);
|
|
361
360
|
if (n)
|
|
362
361
|
try {
|
|
363
|
-
if (
|
|
362
|
+
if (r.operation === "DELETE")
|
|
364
363
|
try {
|
|
365
364
|
await a.removeEntry(n, {
|
|
366
365
|
recursive: !0
|
|
367
366
|
});
|
|
368
367
|
} catch {
|
|
369
368
|
}
|
|
370
|
-
else if (
|
|
371
|
-
|
|
369
|
+
else if (r.operation === "CREATE")
|
|
370
|
+
r.nodeType === "directory" ? await a.getDirectoryHandle(n, {
|
|
372
371
|
create: !0
|
|
373
372
|
}) : await a.getFileHandle(n, {
|
|
374
373
|
create: !0
|
|
375
374
|
});
|
|
376
|
-
else if (
|
|
375
|
+
else if (r.operation === "WRITE")
|
|
377
376
|
await x(
|
|
378
377
|
a,
|
|
379
378
|
n,
|
|
380
|
-
this.php[
|
|
381
|
-
|
|
379
|
+
this.php[g].FS,
|
|
380
|
+
r.path
|
|
382
381
|
);
|
|
383
|
-
else if (
|
|
384
|
-
const i = this.toOpfsPath(
|
|
382
|
+
else if (r.operation === "RENAME" && r.toPath.startsWith(this.memfsRoot)) {
|
|
383
|
+
const i = this.toOpfsPath(r.toPath), s = await H(
|
|
385
384
|
this.opfs,
|
|
386
385
|
i
|
|
387
386
|
), c = k(i);
|
|
388
|
-
if (
|
|
387
|
+
if (r.nodeType === "directory") {
|
|
389
388
|
const o = await s.getDirectoryHandle(
|
|
390
389
|
n,
|
|
391
390
|
{
|
|
392
391
|
create: !0
|
|
393
392
|
}
|
|
394
393
|
);
|
|
395
|
-
await
|
|
396
|
-
this.php[
|
|
394
|
+
await v(
|
|
395
|
+
this.php[g].FS,
|
|
397
396
|
o,
|
|
398
|
-
|
|
397
|
+
r.toPath
|
|
399
398
|
), await a.removeEntry(n, {
|
|
400
399
|
recursive: !0
|
|
401
400
|
});
|
|
@@ -403,22 +402,22 @@ class j {
|
|
|
403
402
|
(await a.getFileHandle(n)).move(s, c);
|
|
404
403
|
}
|
|
405
404
|
} catch (i) {
|
|
406
|
-
throw
|
|
405
|
+
throw h.log({ entry: r, name: n }), h.error(i), i;
|
|
407
406
|
}
|
|
408
407
|
}
|
|
409
408
|
}
|
|
410
|
-
function E(
|
|
411
|
-
return
|
|
409
|
+
function E(t) {
|
|
410
|
+
return t.replace(/\/$/, "").replace(/\/\/+/g, "/");
|
|
412
411
|
}
|
|
413
|
-
function k(
|
|
414
|
-
return
|
|
412
|
+
function k(t) {
|
|
413
|
+
return t.substring(t.lastIndexOf("/") + 1);
|
|
415
414
|
}
|
|
416
|
-
async function H(
|
|
417
|
-
const e =
|
|
415
|
+
async function H(t, r) {
|
|
416
|
+
const e = r.replace(/^\/+|\/+$/g, "").replace(/\/+/, "/");
|
|
418
417
|
if (!e)
|
|
419
|
-
return
|
|
418
|
+
return t;
|
|
420
419
|
const a = e.split("/");
|
|
421
|
-
let n =
|
|
420
|
+
let n = t;
|
|
422
421
|
for (let i = 0; i < a.length - 1; i++) {
|
|
423
422
|
const s = a[i];
|
|
424
423
|
n = await n.getDirectoryHandle(s, { create: !0 });
|
|
@@ -427,11 +426,12 @@ async function H(r, t) {
|
|
|
427
426
|
}
|
|
428
427
|
export {
|
|
429
428
|
B as consumeAPI,
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
X as
|
|
436
|
-
|
|
429
|
+
te as createDirectoryHandleMountHandler,
|
|
430
|
+
G as exposeAPI,
|
|
431
|
+
S as getPHPLoaderModule,
|
|
432
|
+
Q as loadWebRuntime,
|
|
433
|
+
Y as registerServiceWorker,
|
|
434
|
+
X as setPhpApi,
|
|
435
|
+
Z as setupPostMessageRelay,
|
|
436
|
+
ee as spawnPHPWorkerThread
|
|
437
437
|
};
|
package/lib/api.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as Comlink from 'comlink';
|
|
2
|
+
export type WithAPIState = {
|
|
3
|
+
/**
|
|
4
|
+
* Resolves to true when the remote API is ready for
|
|
5
|
+
* Comlink communication, but not necessarily fully initialized yet.
|
|
6
|
+
*/
|
|
7
|
+
isConnected: () => Promise<void>;
|
|
8
|
+
/**
|
|
9
|
+
* Resolves to true when the remote API is declares it's
|
|
10
|
+
* fully loaded and ready to be used.
|
|
11
|
+
*/
|
|
12
|
+
isReady: () => Promise<void>;
|
|
13
|
+
};
|
|
14
|
+
export type RemoteAPI<T> = Comlink.Remote<T> & WithAPIState;
|
|
15
|
+
export declare function consumeAPI<APIType>(remote: Worker | Window, context?: undefined | EventTarget): RemoteAPI<APIType>;
|
|
16
|
+
export type PublicAPI<Methods, PipedAPI = unknown> = RemoteAPI<Methods & PipedAPI>;
|
|
17
|
+
export declare function exposeAPI<Methods, PipedAPI>(apiMethods?: Methods, pipedApi?: PipedAPI): [() => void, (e: Error) => void, PublicAPI<Methods, PipedAPI>];
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Emscripten, MountHandler, PHP } from '../../../universal/src/index.ts';
|
|
2
|
+
declare global {
|
|
3
|
+
interface FileSystemFileHandle {
|
|
4
|
+
move(target: FileSystemDirectoryHandle): Promise<void>;
|
|
5
|
+
move(name: string): Promise<void>;
|
|
6
|
+
move(target: FileSystemDirectoryHandle, name: string): Promise<void>;
|
|
7
|
+
createWritable(): Promise<FileSystemWritableFileStream>;
|
|
8
|
+
}
|
|
9
|
+
interface FileSystemWritableFileStream {
|
|
10
|
+
write(buffer: BufferSource, options?: FileSystemReadWriteOptions): Promise<number>;
|
|
11
|
+
close(): Promise<void>;
|
|
12
|
+
seek(offset: number): Promise<void>;
|
|
13
|
+
truncate(newSize: number): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export interface MountOptions {
|
|
17
|
+
initialSync: {
|
|
18
|
+
direction?: 'opfs-to-memfs' | 'memfs-to-opfs';
|
|
19
|
+
onProgress?: SyncProgressCallback;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export type SyncProgress = {
|
|
23
|
+
/** The number of files that have been synced. */
|
|
24
|
+
files: number;
|
|
25
|
+
/** The number of all files that need to be synced. */
|
|
26
|
+
total: number;
|
|
27
|
+
};
|
|
28
|
+
export type SyncProgressCallback = (progress: SyncProgress) => void;
|
|
29
|
+
export declare function createDirectoryHandleMountHandler(handle: FileSystemDirectoryHandle, options?: MountOptions): MountHandler;
|
|
30
|
+
export declare function copyMemfsToOpfs(FS: Emscripten.RootFS, opfsRoot: FileSystemDirectoryHandle, memfsRoot: string, onProgress?: SyncProgressCallback): Promise<void>;
|
|
31
|
+
export declare function journalFSEventsToOpfs(php: PHP, opfsRoot: FileSystemDirectoryHandle, memfsRoot: string): () => void;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { PHPLoaderModule, SupportedPHPVersion } from '../../../universal/src/index.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Loads the PHP loader module for the given PHP version.
|
|
4
|
+
*
|
|
5
|
+
* @param version The PHP version to load.
|
|
6
|
+
* @param variant Internal. Do not use.
|
|
7
|
+
* @returns The PHP loader module.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getPHPLoaderModule(version?: SupportedPHPVersion, variant?: 'light' | 'kitchen-sink'): Promise<PHPLoaderModule>;
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from './api';
|
|
2
|
+
export type { WithAPIState as WithIsReady } from './api';
|
|
3
|
+
export type { LoaderOptions as PHPWebLoaderOptions } from './load-runtime';
|
|
4
|
+
export { loadWebRuntime } from './load-runtime';
|
|
5
|
+
export { getPHPLoaderModule } from './get-php-loader-module';
|
|
6
|
+
export { registerServiceWorker, setPhpApi } from './register-service-worker';
|
|
7
|
+
export { setupPostMessageRelay } from './setup-post-message-relay';
|
|
8
|
+
export { spawnPHPWorkerThread } from './worker-thread/spawn-php-worker-thread';
|
|
9
|
+
export { createDirectoryHandleMountHandler } from './directory-handle-mount';
|
|
10
|
+
export type { MountOptions, SyncProgress, SyncProgressCallback, } from './directory-handle-mount';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { EmscriptenOptions, PHPLoaderModule, SupportedPHPVersion } from '../../../universal/src/index.ts';
|
|
2
|
+
export interface LoaderOptions {
|
|
3
|
+
emscriptenOptions?: EmscriptenOptions;
|
|
4
|
+
onPhpLoaderModuleLoaded?: (module: PHPLoaderModule) => void;
|
|
5
|
+
/** @deprecated To be replaced with `extensions` in the future */
|
|
6
|
+
loadAllExtensions?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function loadWebRuntime(phpVersion: SupportedPHPVersion, options?: LoaderOptions): Promise<number>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { PHPWorker } from '../../../universal/src/index.ts';
|
|
2
|
+
import { Remote } from 'comlink';
|
|
3
|
+
export interface Client extends Remote<PHPWorker> {
|
|
4
|
+
}
|
|
5
|
+
export declare const phpApiPromise: Promise<Client>;
|
|
6
|
+
/**
|
|
7
|
+
* Sets the PHP API client.
|
|
8
|
+
*
|
|
9
|
+
* @param {Client} api The PHP API client.
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
export declare function setPhpApi(api: Client): void;
|
|
13
|
+
/**
|
|
14
|
+
* Run this in the main application to register the service worker or
|
|
15
|
+
* reload the registered worker if the app expects a different version
|
|
16
|
+
* than the currently registered one.
|
|
17
|
+
*
|
|
18
|
+
* @param scope The numeric value used in the path prefix of the site
|
|
19
|
+
* this service worker is meant to serve. E.g. for a prefix
|
|
20
|
+
* like `/scope:793/`, the scope would be `793`. See the
|
|
21
|
+
* `@php-wasm/scopes` package for more details.
|
|
22
|
+
* @param scriptUrl The URL of the service worker script.
|
|
23
|
+
*/
|
|
24
|
+
export declare function registerServiceWorker(scope: string, scriptUrl: string): Promise<void>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Setup a postMessage relay between the parent window and a nested iframe.
|
|
3
|
+
*
|
|
4
|
+
* When we're running a Playground instance inside an iframe, sometimes that
|
|
5
|
+
* iframe will contain another iframe and so on. The parent application, however,
|
|
6
|
+
* needs to be able to communicate with the innermost iframe. This function relays
|
|
7
|
+
* the communication both ways. Call it in in every iframe layer between the topmost
|
|
8
|
+
* window and the innermost iframe.
|
|
9
|
+
*
|
|
10
|
+
* @param nestedFrame The nested iframe element
|
|
11
|
+
* @param expectedOrigin The origin that the nested iframe is expected to be on. If not
|
|
12
|
+
* provided, any origin is allowed.
|
|
13
|
+
*/
|
|
14
|
+
export declare function setupPostMessageRelay(nestedFrame: HTMLIFrameElement, expectedOrigin?: string): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@php-wasm/web",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.20",
|
|
4
4
|
"description": "PHP.wasm for the web",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"type": "module",
|
|
30
30
|
"main": "index.js",
|
|
31
31
|
"types": "index.d.ts",
|
|
32
|
-
"gitHead": "
|
|
32
|
+
"gitHead": "f619fcb719128d247bec296b9339aff52101e948",
|
|
33
33
|
"engines": {
|
|
34
34
|
"node": ">=16.15.1",
|
|
35
35
|
"npm": ">=8.11.0"
|
|
@@ -40,10 +40,10 @@
|
|
|
40
40
|
"ini": "4.1.2",
|
|
41
41
|
"ws": "8.13.0",
|
|
42
42
|
"yargs": "17.7.2",
|
|
43
|
-
"@php-wasm/universal": "0.9.
|
|
44
|
-
"@php-wasm/util": "0.9.
|
|
45
|
-
"@php-wasm/logger": "0.9.
|
|
46
|
-
"@php-wasm/fs-journal": "0.9.
|
|
47
|
-
"@php-wasm/web-service-worker": "0.9.
|
|
43
|
+
"@php-wasm/universal": "0.9.20",
|
|
44
|
+
"@php-wasm/util": "0.9.20",
|
|
45
|
+
"@php-wasm/logger": "0.9.20",
|
|
46
|
+
"@php-wasm/fs-journal": "0.9.20",
|
|
47
|
+
"@php-wasm/web-service-worker": "0.9.20"
|
|
48
48
|
}
|
|
49
49
|
}
|