@swmansion/popcorn 0.4.0-next.0 → 0.4.0-next.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -9
- package/dist/events.d.ts +7 -7
- package/dist/index.mjs +37 -7
- package/dist/plugins/esbuild.mjs +2 -8
- package/dist/plugins/rollup.mjs +3 -9
- package/dist/plugins/shared.d.ts +17 -37
- package/dist/plugins/shared.mjs +42 -188
- package/dist/plugins/vite.d.ts +6 -1
- package/dist/plugins/vite.mjs +18 -21
- package/dist/popcorn.d.ts +7 -3
- package/dist/runtimes/core/beam.emu.mjs +139 -139
- package/dist/runtimes/core/beam.mjs +139 -139
- package/dist/runtimes/core/beam.wasm +0 -0
- package/dist/runtimes/crypto/beam.emu.mjs +518 -517
- package/dist/runtimes/crypto/beam.mjs +518 -517
- package/dist/runtimes/crypto/beam.wasm +0 -0
- package/dist/types.d.ts +7 -0
- package/dist/worker.mjs +93 -16
- package/package.json +3 -3
- package/dist/plugins/beam_tools/lib/popcorn/beam_tools/beam_patcher.ex +0 -184
- package/dist/plugins/beam_tools/lib/popcorn/beam_tools/cli.ex +0 -74
- package/dist/plugins/beam_tools/lib/popcorn/beam_tools/packager.ex +0 -540
- package/dist/plugins/beam_tools/mix.exs +0 -16
- package/dist/plugins/beam_tools/patches/kernel/prim_tty.erl +0 -13
- package/dist/plugins/beam_tools/patches/stdlib/beam_lib.erl +0 -27
package/dist/plugins/vite.mjs
CHANGED
|
@@ -5,9 +5,9 @@ import { r as runtimeDirectory, p as popcorn$1 } from './shared.mjs';
|
|
|
5
5
|
import 'node:child_process';
|
|
6
6
|
import 'node:os';
|
|
7
7
|
import 'node:util';
|
|
8
|
-
import 'node:zlib';
|
|
9
8
|
|
|
10
|
-
|
|
9
|
+
/** Headers required by the threaded WebAssembly runtime. */
|
|
10
|
+
const crossOriginIsolationHeaders = {
|
|
11
11
|
"Cross-Origin-Opener-Policy": "same-origin",
|
|
12
12
|
"Cross-Origin-Embedder-Policy": "require-corp",
|
|
13
13
|
};
|
|
@@ -22,7 +22,7 @@ const distDir = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
|
22
22
|
* import { popcorn } from "@swmansion/popcorn/vite";
|
|
23
23
|
*
|
|
24
24
|
* export default defineConfig({
|
|
25
|
-
* plugins: [popcorn({ rootDir: "../my_app"
|
|
25
|
+
* plugins: [popcorn({ rootDir: "../my_app" })],
|
|
26
26
|
* });
|
|
27
27
|
* ```
|
|
28
28
|
*
|
|
@@ -43,8 +43,8 @@ function popcorn(options) {
|
|
|
43
43
|
let dirty = false;
|
|
44
44
|
let outDir;
|
|
45
45
|
let assetsDir = "assets";
|
|
46
|
-
// Dev/preview: pack once at
|
|
47
|
-
// compiled beams change. A single in-flight promise dedupes concurrent
|
|
46
|
+
// Dev/preview: pack once at server startup, then re-pack lazily after the
|
|
47
|
+
// app's compiled beams change. A single in-flight promise dedupes concurrent
|
|
48
48
|
// requests; a change during a re-pack re-sets `dirty` so it isn't lost.
|
|
49
49
|
const ensurePrepared = () => {
|
|
50
50
|
if (prepared !== undefined && !dirty)
|
|
@@ -95,24 +95,21 @@ function popcorn(options) {
|
|
|
95
95
|
const filePath = resolve(assetsRoot, requestPath.slice(requestRoot.length));
|
|
96
96
|
if (!isUnder(assetsRoot, filePath)) {
|
|
97
97
|
res.statusCode = 403;
|
|
98
|
-
setHeaders(res);
|
|
99
98
|
res.end("Forbidden");
|
|
100
99
|
return;
|
|
101
100
|
}
|
|
102
101
|
try {
|
|
103
102
|
const compressible = isCompressible(filePath);
|
|
104
103
|
const encoding = compressible
|
|
105
|
-
? selectEncoding(req.headers["accept-encoding"]?.toString()
|
|
104
|
+
? selectEncoding(req.headers["accept-encoding"]?.toString())
|
|
106
105
|
: { name: null, suffix: "" };
|
|
107
106
|
if (compressible && encoding.name === null) {
|
|
108
107
|
res.statusCode = 406;
|
|
109
|
-
setHeaders(res);
|
|
110
108
|
res.setHeader("Vary", "Accept-Encoding");
|
|
111
109
|
res.end("No supported content encoding");
|
|
112
110
|
return;
|
|
113
111
|
}
|
|
114
112
|
const content = await readFile(`${filePath}${encoding.suffix}`);
|
|
115
|
-
setHeaders(res);
|
|
116
113
|
setContentType(res, filePath);
|
|
117
114
|
res.setHeader("Vary", "Accept-Encoding");
|
|
118
115
|
if (encoding.name !== null) {
|
|
@@ -122,7 +119,6 @@ function popcorn(options) {
|
|
|
122
119
|
}
|
|
123
120
|
catch {
|
|
124
121
|
res.statusCode = 404;
|
|
125
|
-
setHeaders(res);
|
|
126
122
|
res.end("Not found");
|
|
127
123
|
}
|
|
128
124
|
};
|
|
@@ -144,10 +140,6 @@ function popcorn(options) {
|
|
|
144
140
|
},
|
|
145
141
|
],
|
|
146
142
|
},
|
|
147
|
-
// COOP/COEP must be on every response (SharedArrayBuffer/pthreads),
|
|
148
|
-
// including the worker/beam files Vite serves from the package itself.
|
|
149
|
-
server: { headers: CORS_HEADERS },
|
|
150
|
-
preview: { headers: CORS_HEADERS },
|
|
151
143
|
};
|
|
152
144
|
},
|
|
153
145
|
configResolved(config) {
|
|
@@ -155,8 +147,9 @@ function popcorn(options) {
|
|
|
155
147
|
outDir = resolve(config.root, config.build.outDir);
|
|
156
148
|
assetsDir = config.build.assetsDir;
|
|
157
149
|
},
|
|
158
|
-
configureServer(server) {
|
|
150
|
+
async configureServer(server) {
|
|
159
151
|
const rootDir = resolve(options.rootDir);
|
|
152
|
+
server.httpServer?.prependListener("request", setIsolationHeaders);
|
|
160
153
|
server.watcher.add(rootDir);
|
|
161
154
|
server.watcher.on("all", (_event, file) => {
|
|
162
155
|
if (isUnder(rootDir, file))
|
|
@@ -164,10 +157,14 @@ function popcorn(options) {
|
|
|
164
157
|
});
|
|
165
158
|
server.middlewares.use(serve);
|
|
166
159
|
server.httpServer?.once("close", cleanup);
|
|
160
|
+
await ensurePrepared();
|
|
161
|
+
dirty = false;
|
|
167
162
|
},
|
|
168
|
-
configurePreviewServer(server) {
|
|
163
|
+
async configurePreviewServer(server) {
|
|
164
|
+
server.httpServer?.prependListener("request", setIsolationHeaders);
|
|
169
165
|
server.middlewares.use(serve);
|
|
170
166
|
server.httpServer?.once("close", cleanup);
|
|
167
|
+
await ensurePrepared();
|
|
171
168
|
},
|
|
172
169
|
async closeBundle() {
|
|
173
170
|
assert(outDir !== undefined, "outDir was not resolved");
|
|
@@ -187,8 +184,8 @@ function popcorn(options) {
|
|
|
187
184
|
function isCompressible(path) {
|
|
188
185
|
return path.endsWith(".tar") || path.endsWith(".wasm");
|
|
189
186
|
}
|
|
190
|
-
function selectEncoding(header
|
|
191
|
-
if (
|
|
187
|
+
function selectEncoding(header) {
|
|
188
|
+
if (header?.includes("br")) {
|
|
192
189
|
return { name: "br", suffix: ".br" };
|
|
193
190
|
}
|
|
194
191
|
if (header?.includes("gzip"))
|
|
@@ -199,8 +196,8 @@ function isUnder(dir, file) {
|
|
|
199
196
|
const rel = relative(dir, file);
|
|
200
197
|
return rel !== "" && !rel.startsWith("..") && !isAbsolute(rel);
|
|
201
198
|
}
|
|
202
|
-
function
|
|
203
|
-
for (const [key, value] of Object.entries(
|
|
199
|
+
function setIsolationHeaders(_req, res) {
|
|
200
|
+
for (const [key, value] of Object.entries(crossOriginIsolationHeaders)) {
|
|
204
201
|
res.setHeader(key, value);
|
|
205
202
|
}
|
|
206
203
|
}
|
|
@@ -224,4 +221,4 @@ function assert(ok, message) {
|
|
|
224
221
|
}
|
|
225
222
|
}
|
|
226
223
|
|
|
227
|
-
export { popcorn };
|
|
224
|
+
export { crossOriginIsolationHeaders, popcorn };
|
package/dist/popcorn.d.ts
CHANGED
|
@@ -123,6 +123,7 @@ export declare class Popcorn<Output extends TtyOutput = "text"> {
|
|
|
123
123
|
private readonly eventHandlers;
|
|
124
124
|
private readonly pendingSends;
|
|
125
125
|
private readonly pendingCalls;
|
|
126
|
+
private readonly readyWaiters;
|
|
126
127
|
private callSeq;
|
|
127
128
|
private readonly trackedValues;
|
|
128
129
|
private trackedKeySeq;
|
|
@@ -137,7 +138,7 @@ export declare class Popcorn<Output extends TtyOutput = "text"> {
|
|
|
137
138
|
*
|
|
138
139
|
* Call {@link boot} to start the VM.
|
|
139
140
|
**/
|
|
140
|
-
constructor(opts
|
|
141
|
+
constructor(opts?: PopcornOpts<Output>);
|
|
141
142
|
private spawnWorker;
|
|
142
143
|
/**
|
|
143
144
|
* Creates an instance and waits for {@link boot}.
|
|
@@ -146,7 +147,7 @@ export declare class Popcorn<Output extends TtyOutput = "text"> {
|
|
|
146
147
|
*
|
|
147
148
|
* @returns Ok tuple or `runtime:eval-unavailable` if the page blocks JavaScript evaluation.
|
|
148
149
|
*/
|
|
149
|
-
static init<Output extends TtyOutput = "text">(opts
|
|
150
|
+
static init<Output extends TtyOutput = "text">(opts?: PopcornOpts<Output>): Promise<Result<Popcorn<Output>>>;
|
|
150
151
|
/**
|
|
151
152
|
* Starts the VM and waits for its bridge and entrypoint application.
|
|
152
153
|
*
|
|
@@ -229,8 +230,11 @@ export declare class Popcorn<Output extends TtyOutput = "text"> {
|
|
|
229
230
|
private castBridge;
|
|
230
231
|
private nextCallId;
|
|
231
232
|
private runJs;
|
|
233
|
+
private handleReadyRequest;
|
|
234
|
+
private flushReadyWaiters;
|
|
235
|
+
private sendReadyReply;
|
|
232
236
|
private asRef;
|
|
233
|
-
private
|
|
237
|
+
private sendBridgeReply;
|
|
234
238
|
private jsWithCurrentEnv;
|
|
235
239
|
private reviveHandles;
|
|
236
240
|
/** Maps pids and `TrackedValue`s during encoding, collecting handles into
|