@markii/host 0.17.0-next.2 → 0.17.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 +4 -2
- package/dist/browser-worker.js +36 -36
- package/dist/browser.d.ts +6 -2
- package/dist/browser.js +7 -2
- package/dist/host/adapter.d.ts +18 -23
- package/dist/host/conformance-runner.d.ts +4 -1
- package/dist/host/conformance-runner.js +4 -6
- package/dist/host/create-host.d.ts +4 -6
- package/dist/host/editor-behavior.d.ts +2 -6
- package/dist/host/editor-behavior.js +5 -9
- package/dist/host/export-behavior.d.ts +4 -6
- package/dist/host/labels.d.ts +1 -2
- package/dist/host/pack-archive.js +2 -8
- package/dist/host/pack-install.d.ts +1 -2
- package/dist/host/pack-install.js +4 -7
- package/dist/host/pack-load.d.ts +1 -2
- package/dist/host/pack-trust-behavior.js +1 -1
- package/dist/host/refresh-interval.d.ts +1 -3
- package/dist/host/refresh-interval.js +1 -3
- package/dist/host/run-behavior.d.ts +3 -4
- package/dist/host/run-behavior.js +23 -2
- package/dist/host/script-execution.d.ts +1 -1
- package/dist/index.js +1 -2
- package/dist/node-worker.js +20657 -0
- package/dist/node.d.ts +2 -1
- package/dist/node.js +1 -1
- package/dist/packs/discover.js +1 -1
- package/dist/packs/pack-diagnostics.d.ts +6 -8
- package/dist/packs/pack-diagnostics.js +6 -8
- package/dist/packs/pack-paths.js +1 -2
- package/dist/packs/pack-render-registry.d.ts +9 -10
- package/dist/run/browser-isolate.d.ts +5 -5
- package/dist/run/browser-isolate.js +5 -1
- package/dist/run/isolate.d.ts +3 -1
- package/dist/run/net-bridge.d.ts +5 -5
- package/dist/run/net-provider.d.ts +3 -1
- package/dist/run/net-provider.js +20 -6
- package/dist/run/node-isolate.d.ts +13 -21
- package/dist/run/node-isolate.js +31 -80
- package/dist/run/run-flow.d.ts +1 -2
- package/dist/run/run-host.d.ts +3 -3
- package/dist/run/worker-entry-browser.d.ts +24 -4
- package/dist/run/worker-entry-browser.js +99 -4
- package/dist/run/worker-entry.js +2 -0
- package/package.json +14 -11
|
@@ -10,10 +10,11 @@
|
|
|
10
10
|
* the failure classification cannot drift between hosts. This file supplies
|
|
11
11
|
* only the two things a Web Worker has to do differently:
|
|
12
12
|
*
|
|
13
|
-
* 1. Network goes through `./net-bridge.ts` to the host, which
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
13
|
+
* 1. Network goes through `./net-bridge.ts` to the host, which runs the
|
|
14
|
+
* same pinned provider as before. A Web Worker does have network
|
|
15
|
+
* globals, so `lockdownWorkerGlobals` (below) removes them before any
|
|
16
|
+
* script runs. Lua cannot reach JavaScript at all; the removal is a
|
|
17
|
+
* second wall for the case where an interpreter escape does.
|
|
17
18
|
* 2. wasmoon's `glue.wasm` arrives as a URL on the job, because there is
|
|
18
19
|
* no `__dirname` here to find it beside the bundle.
|
|
19
20
|
*
|
|
@@ -23,6 +24,99 @@
|
|
|
23
24
|
*/
|
|
24
25
|
import { isRunJob, resultForInternalError, runJob, } from './run-job.js';
|
|
25
26
|
import { createNetBridge } from './net-bridge-worker.js';
|
|
27
|
+
/**
|
|
28
|
+
* Globals through which a worker can open a connection or keep state outside
|
|
29
|
+
* the run. `fetch` and `importScripts` are handled separately because the
|
|
30
|
+
* Lua engine's start-up needs them (see `lockdownWorkerGlobals`).
|
|
31
|
+
*/
|
|
32
|
+
const REMOVED_GLOBALS = [
|
|
33
|
+
'XMLHttpRequest',
|
|
34
|
+
'WebSocket',
|
|
35
|
+
'EventSource',
|
|
36
|
+
'indexedDB',
|
|
37
|
+
'caches',
|
|
38
|
+
'BroadcastChannel',
|
|
39
|
+
// A nested worker would start with a fresh, unlocked global scope.
|
|
40
|
+
'Worker',
|
|
41
|
+
'SharedWorker',
|
|
42
|
+
'WebTransport',
|
|
43
|
+
'WebSocketStream',
|
|
44
|
+
];
|
|
45
|
+
/** Reads the URL out of a `fetch` argument without assuming DOM types. */
|
|
46
|
+
function requestUrl(input, base) {
|
|
47
|
+
try {
|
|
48
|
+
if (typeof input === 'string')
|
|
49
|
+
return new URL(input, base).href;
|
|
50
|
+
if (input instanceof URL)
|
|
51
|
+
return input.href;
|
|
52
|
+
const url = input?.url;
|
|
53
|
+
if (typeof url === 'string')
|
|
54
|
+
return new URL(url, base).href;
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// an unparseable URL is not the allowed one
|
|
58
|
+
}
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Removes the worker's own ways to reach a network, once, before the first
|
|
63
|
+
* script runs.
|
|
64
|
+
*
|
|
65
|
+
* - Every name in `REMOVED_GLOBALS` (the connection and storage
|
|
66
|
+
* constructors, and `Worker`, which would start an unlocked scope) is
|
|
67
|
+
* shadowed with `undefined`.
|
|
68
|
+
* - `importScripts` becomes a function that throws. It stays a function
|
|
69
|
+
* because the Lua engine's start-up detects a worker by
|
|
70
|
+
* `typeof importScripts`.
|
|
71
|
+
* - `fetch` keeps working for exactly one URL, the `glue.wasm` the job
|
|
72
|
+
* named, because the engine loads its WebAssembly through it for every
|
|
73
|
+
* script. Any other URL is refused.
|
|
74
|
+
*
|
|
75
|
+
* Net traffic is unaffected: it goes to the host with `postMessage`.
|
|
76
|
+
* Idempotent. Covered by `worker-entry-browser.test.ts` and, in a real
|
|
77
|
+
* browser, by the e2e suite.
|
|
78
|
+
*/
|
|
79
|
+
export function lockdownWorkerGlobals(scope, wasmUri) {
|
|
80
|
+
const target = scope;
|
|
81
|
+
if (target.__markiiLocked)
|
|
82
|
+
return;
|
|
83
|
+
const base = target.location?.href ?? 'http://localhost/';
|
|
84
|
+
const allowed = wasmUri === undefined ? undefined : requestUrl(wasmUri, base);
|
|
85
|
+
const realFetch = target.fetch;
|
|
86
|
+
const shadow = (name, value) => {
|
|
87
|
+
try {
|
|
88
|
+
Object.defineProperty(scope, name, {
|
|
89
|
+
value,
|
|
90
|
+
configurable: false,
|
|
91
|
+
writable: false,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
// A non-configurable property cannot be shadowed; assign instead.
|
|
96
|
+
try {
|
|
97
|
+
target[name] = value;
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// nothing more can be done for this name
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
for (const name of REMOVED_GLOBALS)
|
|
105
|
+
shadow(name, undefined);
|
|
106
|
+
shadow('importScripts', () => {
|
|
107
|
+
throw new Error('importScripts is not available in the run isolate');
|
|
108
|
+
});
|
|
109
|
+
if (typeof realFetch === 'function') {
|
|
110
|
+
shadow('fetch', (input, init) => {
|
|
111
|
+
const url = requestUrl(input, base);
|
|
112
|
+
if (allowed !== undefined && url === allowed) {
|
|
113
|
+
return realFetch.call(scope, input, init);
|
|
114
|
+
}
|
|
115
|
+
return Promise.reject(new TypeError('network access is not available in the run isolate'));
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
Object.defineProperty(scope, '__markiiLocked', { value: true });
|
|
119
|
+
}
|
|
26
120
|
function start(scope) {
|
|
27
121
|
const bridge = createNetBridge((message) => {
|
|
28
122
|
scope.postMessage(message);
|
|
@@ -47,6 +141,7 @@ function start(scope) {
|
|
|
47
141
|
return;
|
|
48
142
|
}
|
|
49
143
|
const job = message;
|
|
144
|
+
lockdownWorkerGlobals(scope, job.wasmUri);
|
|
50
145
|
let result;
|
|
51
146
|
try {
|
|
52
147
|
result = await runJob(job, {
|
package/dist/run/worker-entry.js
CHANGED
|
@@ -53,6 +53,8 @@ import { isRunJob, resultForInternalError, runJob } from './run-job.js';
|
|
|
53
53
|
* pass here.
|
|
54
54
|
*/
|
|
55
55
|
function resolveWasmUri() {
|
|
56
|
+
if (typeof __dirname === 'undefined')
|
|
57
|
+
return undefined;
|
|
56
58
|
const candidate = path.join(__dirname, 'glue.wasm');
|
|
57
59
|
return existsSync(candidate) ? candidate : undefined;
|
|
58
60
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markii/host",
|
|
3
|
-
"version": "0.17.0-next.
|
|
3
|
+
"version": "0.17.0-next.3",
|
|
4
4
|
"description": "Shared, host-neutral script-running layer for Markii hosts: tier gating, the grant model, address pinning, and the terminatable-isolate watchdog, plus the HostAdapter contract and createMarkiiHost. Entries: the neutral main entry, /node, /browser, /conformance.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"markdown",
|
|
@@ -32,6 +32,9 @@
|
|
|
32
32
|
"import": "./dist/node.js",
|
|
33
33
|
"default": "./dist/node.js"
|
|
34
34
|
},
|
|
35
|
+
"./node-worker": {
|
|
36
|
+
"default": "./dist/node-worker.js"
|
|
37
|
+
},
|
|
35
38
|
"./browser": {
|
|
36
39
|
"types": "./dist/browser.d.ts",
|
|
37
40
|
"import": "./dist/browser.js",
|
|
@@ -52,20 +55,20 @@
|
|
|
52
55
|
"build:dist": "rm -rf dist && tsc -p tsconfig.build.json && node scripts/build-dist-assets.mjs"
|
|
53
56
|
},
|
|
54
57
|
"dependencies": {
|
|
55
|
-
"@markii/bundle": "^0.17.0-next.
|
|
56
|
-
"@markii/core": "^0.17.0-next.
|
|
57
|
-
"@markii/lua": "^0.17.0-next.
|
|
58
|
-
"@markii/pack": "^0.17.0-next.
|
|
59
|
-
"@markii/runtime": "^0.17.0-next.
|
|
60
|
-
"@markii/stdlib": "^0.17.0-next.
|
|
58
|
+
"@markii/bundle": "^0.17.0-next.3",
|
|
59
|
+
"@markii/core": "^0.17.0-next.3",
|
|
60
|
+
"@markii/lua": "^0.17.0-next.3",
|
|
61
|
+
"@markii/pack": "^0.17.0-next.3",
|
|
62
|
+
"@markii/runtime": "^0.17.0-next.3",
|
|
63
|
+
"@markii/stdlib": "^0.17.0-next.3",
|
|
61
64
|
"fflate": "^0.8.3"
|
|
62
65
|
},
|
|
63
66
|
"files": [
|
|
64
67
|
"dist"
|
|
65
68
|
],
|
|
66
69
|
"peerDependencies": {
|
|
67
|
-
"@markii/html": "^0.17.0-next.
|
|
68
|
-
"@markii/react": "^0.17.0-next.
|
|
70
|
+
"@markii/html": "^0.17.0-next.3",
|
|
71
|
+
"@markii/react": "^0.17.0-next.3"
|
|
69
72
|
},
|
|
70
73
|
"peerDependenciesMeta": {
|
|
71
74
|
"@markii/html": {
|
|
@@ -76,8 +79,8 @@
|
|
|
76
79
|
}
|
|
77
80
|
},
|
|
78
81
|
"devDependencies": {
|
|
79
|
-
"@markii/html": "^0.17.0-next.
|
|
80
|
-
"@markii/react": "^0.17.0-next.
|
|
82
|
+
"@markii/html": "^0.17.0-next.3",
|
|
83
|
+
"@markii/react": "^0.17.0-next.3",
|
|
81
84
|
"esbuild": "^0.28.2"
|
|
82
85
|
},
|
|
83
86
|
"publishConfig": {
|