@swmansion/popcorn 0.4.0-next.3 → 0.4.0-next.4
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 +13 -4
- package/dist/events.d.ts +1 -1
- package/dist/index.mjs +23 -3
- package/dist/popcorn.d.ts +11 -0
- package/dist/runtimes/core/beam.emu.mjs +126 -128
- package/dist/runtimes/core/beam.mjs +126 -128
- package/dist/runtimes/core/beam.wasm +0 -0
- package/dist/runtimes/crypto/beam.emu.mjs +108 -111
- package/dist/runtimes/crypto/beam.mjs +108 -111
- package/dist/runtimes/crypto/beam.wasm +0 -0
- package/dist/types.d.ts +3 -0
- package/dist/worker.mjs +8 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ Run Elixir in a browser with OTP/BEAM compiled to WebAssembly.
|
|
|
4
4
|
This prerelease replaces the AtomVM runtime used by Popcorn 0.3.x.
|
|
5
5
|
|
|
6
6
|
Start with the
|
|
7
|
-
[versioned Popcorn guide](https://popcorn.hexdocs.pm/0.4.0-next.
|
|
7
|
+
[versioned Popcorn guide](https://popcorn.hexdocs.pm/0.4.0-next.4/introduction.html).
|
|
8
8
|
It includes a complete Mix and Vite tutorial.
|
|
9
9
|
|
|
10
10
|
## Install
|
|
@@ -13,12 +13,12 @@ It includes a complete Mix and Vite tutorial.
|
|
|
13
13
|
npm install @swmansion/popcorn@next
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
Add `{:popcorn, "0.4.0-next.
|
|
16
|
+
Add `{:popcorn, "0.4.0-next.4"}` to your Elixir application's dependencies.
|
|
17
17
|
Run `mix deps.get` before building the JavaScript application. The bundler
|
|
18
18
|
plugins invoke Mix locally to compile and package application and
|
|
19
19
|
standard-library code.
|
|
20
20
|
|
|
21
|
-
Use the toolchain pinned in [mise.toml](https://github.com/software-mansion/popcorn/blob/v0.4.0-next.
|
|
21
|
+
Use the toolchain pinned in [mise.toml](https://github.com/software-mansion/popcorn/blob/v0.4.0-next.4/mise.toml).
|
|
22
22
|
The packager checks host OTP compatibility against the selected runtime's manifest.
|
|
23
23
|
|
|
24
24
|
## Configure Vite
|
|
@@ -71,6 +71,15 @@ vm.deinit();
|
|
|
71
71
|
`popcorn.genserver.call()` to call a supervised GenServer from JavaScript.
|
|
72
72
|
Use `popcorn.onEvent()` to receive events from BEAM processes.
|
|
73
73
|
|
|
74
|
+
Each VM starts with 64 MiB of Wasm linear memory and can grow to 256 MiB on
|
|
75
|
+
phones/tablets or 2 GiB on desktop. Device detection uses the browser's user
|
|
76
|
+
agent and touch support. Configure the limits with
|
|
77
|
+
`Popcorn.init({ beam: { maxMemory: { mobile: "256M", desktop: "2G" } } })`.
|
|
78
|
+
Omit `maxMemory` to keep these defaults, or override either key separately.
|
|
79
|
+
Only `M` and `G` suffixes are supported; they mean MiB and GiB.
|
|
80
|
+
The limit must be a multiple of 64 KiB between 64 MiB and 2 GiB; JavaScript and
|
|
81
|
+
filesystem memory are additional.
|
|
82
|
+
|
|
74
83
|
## Serve in production
|
|
75
84
|
|
|
76
85
|
Serve over HTTPS or localhost. Set these headers on the application and runtime responses:
|
|
@@ -85,4 +94,4 @@ Serve `.wasm` as `application/wasm`. Serve compressed `.tar.gz` files with `Cont
|
|
|
85
94
|
The package also emits uncompressed tar files and Brotli variants. Brotli uses standard effort by default. Set `brotliEffort: "max"` for maximum compression in release builds.
|
|
86
95
|
|
|
87
96
|
The JavaScript bridge currently requires a Content Security Policy that permits `unsafe-eval`.
|
|
88
|
-
See the [versioned Elixir API](https://popcorn.hexdocs.pm/0.4.0-next.
|
|
97
|
+
See the [versioned Elixir API](https://popcorn.hexdocs.pm/0.4.0-next.4/) for interoperability details.
|
package/dist/events.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { type Mapper } from "./etf";
|
|
|
3
3
|
import type { AnyValue, BeamBootOptions, BeamEvent, BeamSendPayload, BeamTarget } from "./types";
|
|
4
4
|
type BootEvent = {
|
|
5
5
|
type: "popcorn:boot";
|
|
6
|
-
payload: Pick<BeamBootOptions, "emulatorArgs" | "extraArgs" | "env" | "ttySize" | "noshell"> & {
|
|
6
|
+
payload: Pick<BeamBootOptions, "emulatorArgs" | "extraArgs" | "env" | "maxMemoryBytes" | "ttySize" | "noshell"> & {
|
|
7
7
|
otpAssetsRoot?: string;
|
|
8
8
|
};
|
|
9
9
|
};
|
package/dist/index.mjs
CHANGED
|
@@ -547,6 +547,7 @@ class Popcorn {
|
|
|
547
547
|
vmWorker;
|
|
548
548
|
state = { status: "created" };
|
|
549
549
|
opts;
|
|
550
|
+
maxMemoryBytes;
|
|
550
551
|
ttySize;
|
|
551
552
|
output;
|
|
552
553
|
requestSeq = 0;
|
|
@@ -624,12 +625,13 @@ class Popcorn {
|
|
|
624
625
|
check(isValidTtySize(ttySize));
|
|
625
626
|
check(opts.beam?.otpAssetsRoot === undefined ||
|
|
626
627
|
opts.beam.otpAssetsRoot.endsWith("/"), "otpAssetsRoot must end with a slash");
|
|
628
|
+
const { maxMemory, ...beam } = opts.beam ?? {};
|
|
629
|
+
this.maxMemoryBytes = resolveMaxMemory(maxMemory);
|
|
627
630
|
this.opts = {
|
|
628
631
|
...opts,
|
|
629
632
|
beam: {
|
|
630
|
-
...
|
|
631
|
-
emulatorArgs:
|
|
632
|
-
schedulers({ base: 1, dirtyCpu: 1, dirtyIo: 1 }),
|
|
633
|
+
...beam,
|
|
634
|
+
emulatorArgs: beam.emulatorArgs ?? schedulers({ base: 1, dirtyCpu: 1, dirtyIo: 1 }),
|
|
633
635
|
},
|
|
634
636
|
};
|
|
635
637
|
this.ttySize = { ...ttySize };
|
|
@@ -749,6 +751,7 @@ class Popcorn {
|
|
|
749
751
|
type: "popcorn:boot",
|
|
750
752
|
payload: {
|
|
751
753
|
...this.opts.beam,
|
|
754
|
+
maxMemoryBytes: this.maxMemoryBytes,
|
|
752
755
|
ttySize: this.ttySize,
|
|
753
756
|
noshell: this.opts.tty === undefined,
|
|
754
757
|
},
|
|
@@ -1191,6 +1194,23 @@ class Popcorn {
|
|
|
1191
1194
|
this.deinit(exitReason(payload));
|
|
1192
1195
|
}
|
|
1193
1196
|
}
|
|
1197
|
+
function resolveMaxMemory(limits) {
|
|
1198
|
+
const mobileLimit = parseMemorySize(limits?.mobile ?? "256M");
|
|
1199
|
+
const desktopLimit = parseMemorySize(limits?.desktop ?? "2G");
|
|
1200
|
+
const mobile = /Android|Mobile|iPad|iPhone|iPod/.test(navigator.userAgent);
|
|
1201
|
+
const ipad = /Macintosh/.test(navigator.userAgent) && navigator.maxTouchPoints > 1;
|
|
1202
|
+
return mobile || ipad ? mobileLimit : desktopLimit;
|
|
1203
|
+
}
|
|
1204
|
+
function parseMemorySize(size) {
|
|
1205
|
+
const match = /^(\d+(?:\.\d+)?)([MG])$/.exec(size);
|
|
1206
|
+
check(match !== null, 'maxMemory must use M or G, such as "256M" or "2G"');
|
|
1207
|
+
const bytes = Number(match[1]) * (match[2] === "M" ? 1024 ** 2 : 1024 ** 3);
|
|
1208
|
+
check(Number.isSafeInteger(bytes) &&
|
|
1209
|
+
bytes >= 64 * 1024 * 1024 &&
|
|
1210
|
+
bytes <= 2 * 1024 * 1024 * 1024 &&
|
|
1211
|
+
bytes % 65536 === 0, "maxMemory must be a multiple of 64 KiB between 64 MiB and 2 GiB");
|
|
1212
|
+
return bytes;
|
|
1213
|
+
}
|
|
1194
1214
|
/**
|
|
1195
1215
|
* Builds `beam.emulatorArgs` for scheduler counts.
|
|
1196
1216
|
*
|
package/dist/popcorn.d.ts
CHANGED
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
import { type Result } from "./errors";
|
|
2
2
|
import { type PopcornEvent } from "./events";
|
|
3
3
|
import type { AnyValue, BeamBootOptions, OtpErrorPayload, Pid, TtySize } from "./types";
|
|
4
|
+
type MemoryLimits = {
|
|
5
|
+
mobile?: `${number}${"M" | "G"}`;
|
|
6
|
+
desktop?: `${number}${"M" | "G"}`;
|
|
7
|
+
};
|
|
4
8
|
/** Output type for a terminal. */
|
|
5
9
|
type TtyOutput = "text" | "bytes";
|
|
6
10
|
type OutputChunk<Output extends TtyOutput> = Output extends "bytes" ? Uint8Array : string;
|
|
7
11
|
/** Browser VM configuration. */
|
|
8
12
|
export type PopcornOpts<Output extends TtyOutput = "text"> = {
|
|
9
13
|
beam?: Pick<BeamBootOptions, "emulatorArgs" | "extraArgs" | "env"> & {
|
|
14
|
+
/**
|
|
15
|
+
* Maximum Wasm linear memory by platform. Omitted keys default to
|
|
16
|
+
* mobile: "256M", desktop: "2G". M and G mean MiB and GiB.
|
|
17
|
+
* Limits must be in 64 KiB increments between 64 MiB and 2 GiB.
|
|
18
|
+
*/
|
|
19
|
+
maxMemory?: MemoryLimits;
|
|
10
20
|
/**
|
|
11
21
|
* Asset directory URL.
|
|
12
22
|
*
|
|
@@ -116,6 +126,7 @@ export declare class Popcorn<Output extends TtyOutput = "text"> {
|
|
|
116
126
|
private vmWorker;
|
|
117
127
|
private state;
|
|
118
128
|
private readonly opts;
|
|
129
|
+
private readonly maxMemoryBytes;
|
|
119
130
|
private readonly ttySize;
|
|
120
131
|
private output;
|
|
121
132
|
private requestSeq;
|