Work in a private Space inside the Hub page: pass the page's ?__sign= to the app module, the fonts, the worker and its libraries
Browse files- engine_api.js +4 -1
- engine_worker.js +5 -1
- index.html +12 -1
- styles_v2.css +1 -4
engine_api.js
CHANGED
|
@@ -38,6 +38,9 @@
|
|
| 38 |
|
| 39 |
export const WORKER_URL = "engine_worker.js";
|
| 40 |
export const WORKER_TYPE = "module"; // the worker is an ES module (import onnxruntime-web / pyodide.mjs)
|
|
|
|
|
|
|
|
|
|
| 41 |
|
| 42 |
export function normalizeKnobs(k) {
|
| 43 |
const n = (x, d) => (Number.isFinite(+x) ? +x : d);
|
|
@@ -98,7 +101,7 @@ export function validateExact(r, dims) {
|
|
| 98 |
|
| 99 |
export class Engine {
|
| 100 |
constructor(url = WORKER_URL, type = WORKER_TYPE) {
|
| 101 |
-
this.worker = new Worker(url, { type });
|
| 102 |
this.n = 0;
|
| 103 |
this.pending = new Map();
|
| 104 |
this.statusListeners = [];
|
|
|
|
| 38 |
|
| 39 |
export const WORKER_URL = "engine_worker.js";
|
| 40 |
export const WORKER_TYPE = "module"; // the worker is an ES module (import onnxruntime-web / pyodide.mjs)
|
| 41 |
+
// a private Space signs the page (?__sign=): the worker's requests pass only if the worker's own URL carries the signature
|
| 42 |
+
const SIGN = typeof location === "undefined" ? null : new URLSearchParams(location.search).get("__sign");
|
| 43 |
+
const signed = (u) => (SIGN ? `${u}${String(u).includes("?") ? "&" : "?"}__sign=${encodeURIComponent(SIGN)}` : u);
|
| 44 |
|
| 45 |
export function normalizeKnobs(k) {
|
| 46 |
const n = (x, d) => (Number.isFinite(+x) ? +x : d);
|
|
|
|
| 101 |
|
| 102 |
export class Engine {
|
| 103 |
constructor(url = WORKER_URL, type = WORKER_TYPE) {
|
| 104 |
+
this.worker = new Worker(signed(url), { type });
|
| 105 |
this.n = 0;
|
| 106 |
this.pending = new Map();
|
| 107 |
this.statusListeners = [];
|
engine_worker.js
CHANGED
|
@@ -9,6 +9,10 @@
|
|
| 9 |
import { createEngine, transferables } from "./assets/engine/engine_core.js";
|
| 10 |
|
| 11 |
const BASE = new URL("./assets/engine/", import.meta.url).href;
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
const STAGES = { start: [0.02, "starting Python (Pyodide)"], pyodide: [0.25, "loading numpy, scipy, pandas"],
|
| 13 |
packages: [0.6, "fetching the grid and GENCO"], fetch_rest: [0.65, "loading the engine"],
|
| 14 |
engine: [0.8, "loading GENCO (onnxruntime-web)"], model: [0.9, "warming up"], warmup: [1.0, "ready"] };
|
|
@@ -21,7 +25,7 @@ const status = (stage, detail, progress) => self.postMessage({ type: "status", s
|
|
| 21 |
|
| 22 |
async function start(opts = {}) {
|
| 23 |
status("loading", "loading the engine", 0.01);
|
| 24 |
-
const [{ loadPyodide }, ortModule] = await Promise.all([import(BASE + "pyodide/pyodide.mjs"), import(BASE + "ort/ort.wasm.min.mjs")]);
|
| 25 |
const ort = ortModule.default ?? ortModule;
|
| 26 |
ort.env.wasm.wasmPaths = BASE + "ort/";
|
| 27 |
// GENCO's WASM threads: the visitor's cores, up to 8, when the page is cross-origin isolated (else 1). Measured on a
|
|
|
|
| 9 |
import { createEngine, transferables } from "./assets/engine/engine_core.js";
|
| 10 |
|
| 11 |
const BASE = new URL("./assets/engine/", import.meta.url).href;
|
| 12 |
+
// a private Space: this worker's URL carries the page's signature (engine_api.js); Pyodide and onnxruntime-web import
|
| 13 |
+
// their own files with their URL as the Referer, so they are imported signed too
|
| 14 |
+
const SIGN = new URLSearchParams(self.location.search).get("__sign");
|
| 15 |
+
const signed = (u) => (SIGN ? `${u}?__sign=${encodeURIComponent(SIGN)}` : u);
|
| 16 |
const STAGES = { start: [0.02, "starting Python (Pyodide)"], pyodide: [0.25, "loading numpy, scipy, pandas"],
|
| 17 |
packages: [0.6, "fetching the grid and GENCO"], fetch_rest: [0.65, "loading the engine"],
|
| 18 |
engine: [0.8, "loading GENCO (onnxruntime-web)"], model: [0.9, "warming up"], warmup: [1.0, "ready"] };
|
|
|
|
| 25 |
|
| 26 |
async function start(opts = {}) {
|
| 27 |
status("loading", "loading the engine", 0.01);
|
| 28 |
+
const [{ loadPyodide }, ortModule] = await Promise.all([import(signed(BASE + "pyodide/pyodide.mjs")), import(signed(BASE + "ort/ort.wasm.min.mjs"))]);
|
| 29 |
const ort = ortModule.default ?? ortModule;
|
| 30 |
ort.env.wasm.wasmPaths = BASE + "ort/";
|
| 31 |
// GENCO's WASM threads: the visitor's cores, up to 8, when the page is cross-origin isolated (else 1). Measured on a
|
index.html
CHANGED
|
@@ -9,8 +9,19 @@
|
|
| 9 |
<link rel="icon" href="assets/favicon.svg" type="image/svg+xml">
|
| 10 |
<link rel="stylesheet" href="assets/vendor/maplibre-gl-5.24.0.css">
|
| 11 |
<link rel="stylesheet" href="styles_v2.css">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
<script src="assets/vendor/maplibre-gl-5.24.0.js"></script>
|
| 13 |
-
<script type="module"
|
|
|
|
|
|
|
|
|
|
| 14 |
</head>
|
| 15 |
<body>
|
| 16 |
<header class="hdr">
|
|
|
|
| 9 |
<link rel="icon" href="assets/favicon.svg" type="image/svg+xml">
|
| 10 |
<link rel="stylesheet" href="assets/vendor/maplibre-gl-5.24.0.css">
|
| 11 |
<link rel="stylesheet" href="styles_v2.css">
|
| 12 |
+
<!-- A private Space signs this page (?__sign=): a file another file asks for passes only if the asking file's URL is
|
| 13 |
+
signed. So the fonts are declared here, not in the stylesheet, and the app is imported with the signature. -->
|
| 14 |
+
<style>
|
| 15 |
+
@font-face { font-family: "Mulish"; font-weight: 400; font-display: swap; src: url("assets/fonts/Mulish-Regular.ttf") format("truetype"); }
|
| 16 |
+
@font-face { font-family: "Mulish"; font-weight: 600; font-display: swap; src: url("assets/fonts/Mulish-SemiBold.ttf") format("truetype"); }
|
| 17 |
+
@font-face { font-family: "Mulish"; font-weight: 700; font-display: swap; src: url("assets/fonts/Mulish-Bold.ttf") format("truetype"); }
|
| 18 |
+
@font-face { font-family: "Mulish"; font-weight: 800; font-display: swap; src: url("assets/fonts/Mulish-ExtraBold.ttf") format("truetype"); }
|
| 19 |
+
</style>
|
| 20 |
<script src="assets/vendor/maplibre-gl-5.24.0.js"></script>
|
| 21 |
+
<script type="module">
|
| 22 |
+
const sign = new URLSearchParams(location.search).get("__sign");
|
| 23 |
+
import(sign ? `./app_v2.js?__sign=${encodeURIComponent(sign)}` : "./app_v2.js");
|
| 24 |
+
</script>
|
| 25 |
</head>
|
| 26 |
<body>
|
| 27 |
<header class="hdr">
|
styles_v2.css
CHANGED
|
@@ -1,10 +1,7 @@
|
|
| 1 |
/* Weather what-ifs v2: light, minimal, Vicomtech tokens. 8-pt grid; cards with soft layered shadows instead of borders;
|
| 2 |
a frosted sticky header; segmented controls; thin sliders; 250 ms ease-out motion (none with reduced motion). */
|
| 3 |
|
| 4 |
-
@font-face
|
| 5 |
-
@font-face { font-family: "Mulish"; font-weight: 600; font-display: swap; src: url("assets/fonts/Mulish-SemiBold.ttf") format("truetype"); }
|
| 6 |
-
@font-face { font-family: "Mulish"; font-weight: 700; font-display: swap; src: url("assets/fonts/Mulish-Bold.ttf") format("truetype"); }
|
| 7 |
-
@font-face { font-family: "Mulish"; font-weight: 800; font-display: swap; src: url("assets/fonts/Mulish-ExtraBold.ttf") format("truetype"); }
|
| 8 |
|
| 9 |
:root {
|
| 10 |
--cyan: #00A7C4; --cyan-d: #018299; --cyan-h: #076C7F;
|
|
|
|
| 1 |
/* Weather what-ifs v2: light, minimal, Vicomtech tokens. 8-pt grid; cards with soft layered shadows instead of borders;
|
| 2 |
a frosted sticky header; segmented controls; thin sliders; 250 ms ease-out motion (none with reduced motion). */
|
| 3 |
|
| 4 |
+
/* Mulish's @font-face rules are in index.html: in a private Space the fonts must be asked for by the signed page */
|
|
|
|
|
|
|
|
|
|
| 5 |
|
| 6 |
:root {
|
| 7 |
--cyan: #00A7C4; --cyan-d: #018299; --cyan-h: #076C7F;
|