@vizhub/runtime 4.5.0 → 4.7.0
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 +58 -2
- package/dist/build-BiyVcX4s.cjs +301 -0
- package/dist/build-BiyVcX4s.cjs.map +1 -0
- package/dist/build-DLVodqQH.js +791 -0
- package/dist/build-DLVodqQH.js.map +1 -0
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +138 -217
- package/dist/index.js.map +1 -1
- package/dist/orchestration/createRuntime.d.ts.map +1 -1
- package/dist/test/testStackTrace.d.ts.map +1 -1
- package/dist/worker.cjs +2 -2
- package/dist/worker.cjs.map +1 -1
- package/dist/worker.js +80 -95
- package/dist/worker.js.map +1 -1
- package/package.json +17 -17
- package/dist/build-4ni0mWxG.cjs +0 -317
- package/dist/build-4ni0mWxG.cjs.map +0 -1
- package/dist/build-B7w6NcTo.js +0 -1286
- package/dist/build-B7w6NcTo.js.map +0 -1
package/README.md
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
A powerful, flexible runtime environment for executing code sandboxes in the browser. `@vizhub/runtime` powers [VizHub](https://vizhub.com/) and can be used to build similar interactive coding platforms.
|
|
7
7
|
|
|
8
|
+
> **Latest (v4.6.0):** Upgraded all dependencies (Vite 8, Vitest 4, TS 6, Puppeteer 25, Svelte 5.56+), hardened test infrastructure, improved TypeScript config, and added a React+D3 combo demo fixture — see [Changelog](#changelog).
|
|
9
|
+
|
|
8
10
|
## Overview
|
|
9
11
|
|
|
10
12
|
`@vizhub/runtime` intelligently detects the appropriate runtime version based on the provided files and generates executable HTML that can be used within an iframe's `srcdoc` attribute. It handles everything from simple HTML/JS/CSS combinations to complex module bundling, dependency resolution, and cross-viz imports.
|
|
@@ -365,7 +367,8 @@ const runtime = createRuntime({
|
|
|
365
367
|
setBuildErrorMessage?: (error: string | null) => void,
|
|
366
368
|
getLatestContent?: (vizId: string) => Promise<VizContent | null>,
|
|
367
369
|
resolveSlugKey?: (slugKey: string) => Promise<string | null>,
|
|
368
|
-
writeFile?: (fileName: string, content: string) => void
|
|
370
|
+
writeFile?: (fileName: string, content: string) => void,
|
|
371
|
+
handleRuntimeError?: (formattedErrorMessage: string) => void
|
|
369
372
|
});
|
|
370
373
|
```
|
|
371
374
|
|
|
@@ -373,10 +376,13 @@ const runtime = createRuntime({
|
|
|
373
376
|
|
|
374
377
|
- **iframe**: `HTMLIFrameElement` - The iframe element where the viz will be rendered
|
|
375
378
|
- **worker**: `Worker` - Web Worker instance that handles code building
|
|
376
|
-
- **setBuildErrorMessage**: `(error: string | null) => void` - Optional callback for handling build errors
|
|
379
|
+
- **setBuildErrorMessage**: `(error: string | null) => void` - Optional callback for handling build-time errors
|
|
377
380
|
- **getLatestContent**: `(vizId: string) => Promise<VizContent | null>` - Optional function to fetch viz content for cross-viz imports
|
|
378
381
|
- **resolveSlugKey**: `(slugKey: string) => Promise<string | null>` - Optional function to resolve viz slugs to IDs
|
|
379
382
|
- **writeFile**: `(fileName: string, content: string) => void` - Optional callback when code running in the iframe writes files
|
|
383
|
+
- **handleRuntimeError**: `(formattedErrorMessage: string) => void` - Optional callback for handling runtime errors (exceptions thrown during viz execution)
|
|
384
|
+
|
|
385
|
+
> **Security note (v4.5.1):** The `windowListener` inside `createRuntime` now filters messages by `event.source` to ensure it only processes messages from its own iframe. Previously, any `window.postMessage` with matching types (`runtimeError`, `runError`, `runDone`, `writeFile`) from any iframe on the page would be handled by this runtime, which could cause cross-iframe contamination when multiple runtimes are active (e.g., on an AI edit review page showing a "Before" and "After" comparison).
|
|
380
386
|
|
|
381
387
|
##### Returns
|
|
382
388
|
|
|
@@ -434,6 +440,12 @@ runtime.run({
|
|
|
434
440
|
runtime.cleanup();
|
|
435
441
|
```
|
|
436
442
|
|
|
443
|
+
### Running in Multiple-Iframe Pages
|
|
444
|
+
|
|
445
|
+
When using multiple `createRuntime` instances on the same page (e.g., a before/after comparison view), each runtime previously processed `window.postMessage` events from all iframes, not just its own. This caused runtime errors from one viz to appear as errors in an unrelated viz.
|
|
446
|
+
|
|
447
|
+
As of v4.5.1, each runtime filters messages by `event.source`, so errors only display in the correct iframe.
|
|
448
|
+
|
|
437
449
|
### Building HTML Only
|
|
438
450
|
|
|
439
451
|
```javascript
|
|
@@ -611,6 +623,50 @@ Before finalizing a PR and marking it ready for review, please ensure that:
|
|
|
611
623
|
- Running `npm run preflight` passes without errors
|
|
612
624
|
- The demo app is still working - run `npm run demo` and click through the green buttons to see if everything still works
|
|
613
625
|
|
|
626
|
+
## Changelog
|
|
627
|
+
|
|
628
|
+
### v4.6.0 — Dependency upgrades & test infrastructure hardening
|
|
629
|
+
|
|
630
|
+
**Dependency upgrades:**
|
|
631
|
+
|
|
632
|
+
- Vite 7 → 8
|
|
633
|
+
- Vitest 3 → 4
|
|
634
|
+
- TypeScript 5 → 6
|
|
635
|
+
- Puppeteer 24 → 25
|
|
636
|
+
- Svelte 5.38 → 5.56
|
|
637
|
+
- Rollup 4.50 → 4.62
|
|
638
|
+
- All other devDeps and runtime deps updated to latest
|
|
639
|
+
|
|
640
|
+
**Test infrastructure hardening:**
|
|
641
|
+
|
|
642
|
+
- Added `--no-sandbox` flag to all Puppeteer `launch()` calls for CI compatibility
|
|
643
|
+
- Safer `browser.close()` with null guard in `afterAll` hooks
|
|
644
|
+
- Type-safe stack trace parsing in `testStackTrace.ts` (error instanceof Error check, safer line number extraction)
|
|
645
|
+
- Cleaned up stale comments and removed unused imports
|
|
646
|
+
|
|
647
|
+
**TypeScript config:**
|
|
648
|
+
|
|
649
|
+
- Added `rootDir: "./src"` for correct declaration output structure
|
|
650
|
+
- Changed `moduleResolution` to `"bundler"` for alignment with Vite's resolution strategy
|
|
651
|
+
|
|
652
|
+
**Demo app:**
|
|
653
|
+
|
|
654
|
+
- Added new `reactD3Combo` fixture demonstrating React + D3 integration
|
|
655
|
+
- Fixed Vite `optimizeDeps.include` for transitive CJS deps (sucrase, ts-interface-checker)
|
|
656
|
+
- Extended `server.fs.allow` for WASM file access from @rollup/browser
|
|
657
|
+
|
|
658
|
+
### v4.5.1 — Cross-iframe message contamination fix
|
|
659
|
+
|
|
660
|
+
**Fixed:** The `windowListener` in `createRuntime` now checks `event.source !== iframe.contentWindow` before processing `runDone`, `runError`, `runtimeError`, and `writeFile` messages.
|
|
661
|
+
|
|
662
|
+
**Background:** When multiple `createRuntime` instances (or a `createRuntime` plus raw srcdoc-based iframes built via `buildPreviewHtml`) coexist on the same page, all iframes call `parent.postMessage(...)` with the same message types. Without the source check, one runtime could display errors from another iframe's viz, leading to confusing error reports in the wrong view (e.g., an "After" variant's AI-generated code error showing up in the "Before" comparison panel).
|
|
663
|
+
|
|
664
|
+
**Impact:** All consumers of `@vizhub/runtime` that run multiple iframes on one page benefit from this fix automatically — no code changes required.
|
|
665
|
+
|
|
666
|
+
### v4.5.0 — Original release (current feature set)
|
|
667
|
+
|
|
668
|
+
Supports runtime versions v1–v4 with Rollup bundling, Svelte compilation, cross-viz imports, import maps, hot reloading, and more.
|
|
669
|
+
|
|
614
670
|
## License
|
|
615
671
|
|
|
616
672
|
This project is licensed under the MIT License - see the LICENSE file for details.
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),s=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},c=(n,r,a)=>(a=n==null?{}:e(i(n)),s(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let l=require("magic-sandbox"),u=require("@vizhub/viz-utils"),d=require("sucrase");var f=()=>(Math.random()+``).slice(2);function p(e={}){return{name:`sucrase`,transform(t,n){if(!n.match(/\.(?:js|[jt]sx)$/))return null;let r=(0,d.transform)(t,{transforms:[`jsx`,`typescript`],filePath:n,sourceMapOptions:{compiledFilename:`bundle.js`},production:!0,...e});return{code:r.code,map:r.sourceMap}}}}var m={dependencies:{},vizhub:{},license:`MIT`},h=e=>{let t=e[`package.json`];try{return t?JSON.parse(t):m}catch{return m}},g=e=>h(e).dependencies||{},_=e=>(h(e).vizhub||{}).libraries||{},v=({name:e,version:t},n,r=`jsdelivr`)=>{let i=n[e]&&n[e].path||``;return r===`jsdelivr`?`https://cdn.jsdelivr.net/npm/${e}@${t}${i}`:`https://unpkg.com/${e}@${t}${i}`},y=e=>{let t=e?.vizhub?.libraries;return t?Object.entries(t).reduce((e,[t,n])=>(n.global&&(e[t]=n.global),e),{}):{}},ee={d3:`d3`,react:`React`,"react-dom":`ReactDOM`},b=e=>{let t=y(e);return{...ee,...t}},x=e=>{let[t,...n]=e.split(`/`);return{vizId:t,fileName:n.join(`/`)}},te=`var EOL = {},
|
|
2
|
+
EOF = {},
|
|
3
|
+
QUOTE = 34,
|
|
4
|
+
NEWLINE = 10,
|
|
5
|
+
RETURN = 13;
|
|
6
|
+
|
|
7
|
+
function objectConverter(columns) {
|
|
8
|
+
return new Function(
|
|
9
|
+
'd',
|
|
10
|
+
'return {' +
|
|
11
|
+
columns
|
|
12
|
+
.map(function (name, i) {
|
|
13
|
+
return (
|
|
14
|
+
JSON.stringify(name) + ': d[' + i + '] || ""'
|
|
15
|
+
);
|
|
16
|
+
})
|
|
17
|
+
.join(',') +
|
|
18
|
+
'}',
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function customConverter(columns, f) {
|
|
23
|
+
var object = objectConverter(columns);
|
|
24
|
+
return function (row, i) {
|
|
25
|
+
return f(object(row), i, columns);
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function dsv(delimiter) {
|
|
30
|
+
var DELIMITER = delimiter.charCodeAt(0);
|
|
31
|
+
|
|
32
|
+
function parse(text, f) {
|
|
33
|
+
var convert,
|
|
34
|
+
columns,
|
|
35
|
+
rows = parseRows(text, function (row, i) {
|
|
36
|
+
if (convert) return convert(row, i - 1);
|
|
37
|
+
(columns = row),
|
|
38
|
+
(convert = f
|
|
39
|
+
? customConverter(row, f)
|
|
40
|
+
: objectConverter(row));
|
|
41
|
+
});
|
|
42
|
+
rows.columns = columns || [];
|
|
43
|
+
return rows;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function parseRows(text, f) {
|
|
47
|
+
var rows = [], // output rows
|
|
48
|
+
N = text.length,
|
|
49
|
+
I = 0, // current character index
|
|
50
|
+
n = 0, // current line number
|
|
51
|
+
t, // current token
|
|
52
|
+
eof = N <= 0, // current token followed by EOF?
|
|
53
|
+
eol = false; // current token followed by EOL?
|
|
54
|
+
|
|
55
|
+
// Strip the trailing newline.
|
|
56
|
+
if (text.charCodeAt(N - 1) === NEWLINE) --N;
|
|
57
|
+
if (text.charCodeAt(N - 1) === RETURN) --N;
|
|
58
|
+
|
|
59
|
+
function token() {
|
|
60
|
+
if (eof) return EOF;
|
|
61
|
+
if (eol) return (eol = false), EOL;
|
|
62
|
+
|
|
63
|
+
// Unescape quotes.
|
|
64
|
+
var i,
|
|
65
|
+
j = I,
|
|
66
|
+
c;
|
|
67
|
+
if (text.charCodeAt(j) === QUOTE) {
|
|
68
|
+
while (
|
|
69
|
+
(I++ < N && text.charCodeAt(I) !== QUOTE) ||
|
|
70
|
+
text.charCodeAt(++I) === QUOTE
|
|
71
|
+
);
|
|
72
|
+
if ((i = I) >= N) eof = true;
|
|
73
|
+
else if ((c = text.charCodeAt(I++)) === NEWLINE)
|
|
74
|
+
eol = true;
|
|
75
|
+
else if (c === RETURN) {
|
|
76
|
+
eol = true;
|
|
77
|
+
if (text.charCodeAt(I) === NEWLINE) ++I;
|
|
78
|
+
}
|
|
79
|
+
return text.slice(j + 1, i - 1).replace(/""/g, '"');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Find next delimiter or newline.
|
|
83
|
+
while (I < N) {
|
|
84
|
+
if ((c = text.charCodeAt((i = I++))) === NEWLINE)
|
|
85
|
+
eol = true;
|
|
86
|
+
else if (c === RETURN) {
|
|
87
|
+
eol = true;
|
|
88
|
+
if (text.charCodeAt(I) === NEWLINE) ++I;
|
|
89
|
+
} else if (c !== DELIMITER) continue;
|
|
90
|
+
return text.slice(j, i);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Return last token before EOF.
|
|
94
|
+
return (eof = true), text.slice(j, N);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
while ((t = token()) !== EOF) {
|
|
98
|
+
var row = [];
|
|
99
|
+
while (t !== EOL && t !== EOF)
|
|
100
|
+
row.push(t), (t = token());
|
|
101
|
+
if (f && (row = f(row, n++)) == null) continue;
|
|
102
|
+
rows.push(row);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return rows;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return {
|
|
109
|
+
parse: parse,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
var csv = dsv(',');
|
|
114
|
+
|
|
115
|
+
var csvParse = csv.parse;
|
|
116
|
+
|
|
117
|
+
var tsv = dsv(' ');
|
|
118
|
+
|
|
119
|
+
var tsvParse = tsv.parse;
|
|
120
|
+
|
|
121
|
+
export { csvParse, tsvParse };`,S=e=>e.replace(/\\/g,`\\\\`).replace(/`/g,"\\`"),C=()=>({name:`transformDSV`,transform:async(e,t)=>{let{vizId:n,fileName:r}=x(t),i=r.endsWith(`.csv`),a=r.endsWith(`.tsv`);if(i||a)return{code:`
|
|
122
|
+
${te}
|
|
123
|
+
const data = ${i?`csvParse`:`tsvParse`}(\`${S(e)}\`);
|
|
124
|
+
export default data;
|
|
125
|
+
`,map:{mappings:``}}}}),w=e=>{let t=e.match(/^@([a-zA-Z0-9_-]+)\/([a-zA-Z0-9_-]+)$/);return t?{userName:t[1],idOrSlug:t[2]}:null},T=({vizId:e,slugCache:t})=>({name:`vizResolve`,resolveId:async(n,r)=>{if(n.startsWith(`./`)&&!r?.startsWith(`https://`)){let t=n.substring(2);if(!t.endsWith(`.js`)&&!t.endsWith(`.css`)&&!t.endsWith(`.csv`)&&!t.endsWith(`.svelte`)&&!t.endsWith(`.png`)&&!t.endsWith(`.jpg`)&&!t.endsWith(`.jpeg`)&&!t.endsWith(`.gif`)&&!t.endsWith(`.svg`)&&!t.endsWith(`.webp`)&&!t.endsWith(`.bmp`)&&(t+=`.js`),r){let{vizId:e,fileName:n}=x(r),i=n.split(`/`).slice(0,-1).join(`/`);return`${e}/${i?`${i}/${t}`:t}`}return e+`/`+t}let i=w(n);if(i){let e;if((0,u.isVizId)(i.idOrSlug))e=i.idOrSlug;else{if(!t)throw Error(`slugCache is required to import by slug in v3 runtime`);e=await t.get(`${i.userName}/${i.idOrSlug}`)}return e+`/index.js`}}}),ne=[`.jpg`,`.jpeg`,`.png`,`.gif`,`.svg`,`.webp`,`.bmp`],E=e=>{let t=e.toLowerCase().split(`.`).pop();return t?ne.includes(`.${t}`):!1},re=e=>{switch(e.toLowerCase().split(`.`).pop()){case`jpg`:case`jpeg`:return`image/jpeg`;case`png`:return`image/png`;case`gif`:return`image/gif`;case`svg`:return`image/svg+xml`;case`webp`:return`image/webp`;case`bmp`:return`image/bmp`;default:return`image/png`}},ie=e=>{let t=e.replace(/\s/g,``);return/^[A-Za-z0-9+/]*={0,2}$/.test(t)},D=(e,t)=>{let n=re(e);return e.toLowerCase().split(`.`).pop()===`svg`&&!ie(t)?`data:${n};utf8,${encodeURIComponent(t)}`:`data:${n};base64,${t}`},O=(e,t)=>e.replace(/<img([^>]*)\s+src=["']([^"']+)["']([^>]*)>/gi,(e,n,r,i)=>t[r]!==void 0&&E(r)?`<img${n} src="${D(r,t[r])}"${i}>`:e),ae=({vizCache:e,trackCSSImport:t,vizId:n,files:r})=>({name:`vizLoad`,load:async i=>{let a=x(i),o=a.vizId,s=a.fileName;if(s.endsWith(`.css`))return t(i),``;let c=null;if(c=o===n&&r?r[s]||null:(0,u.getFileText)(await e.get(o),s),c===null)throw Error(`Imported file "${s}" not found.`);return E(s)?`export default "${D(s,c)}";`:c}}),k=new Map,A=new Map,j,M=`https://cdn.jsdelivr.net/npm/svelte@5.37.1`,N=`${M}/compiler/index.js`;async function P(e){let t=A.get(e);if(t)return t;for(let t of[`.js`,`/index.js`]){let n=`${e}${t}`;try{if((await fetch(n,{method:`HEAD`})).ok)return A.set(e,n),n}catch{continue}}let n=`${e}.js`;return A.set(e,n),n}var oe=({getSvelteCompiler:e})=>({name:`transformSvelte`,load:async e=>{if(e===`virtual:esm-env`)return`
|
|
126
|
+
export const BROWSER = true;
|
|
127
|
+
export const DEV = true;
|
|
128
|
+
export const NODE = false;
|
|
129
|
+
export const PROD = false;
|
|
130
|
+
`;if(!e.startsWith(M))return;let t=k.get(e);if(t)return t;let n=await fetch(e).then(e=>e.text());return k.set(e,n),n},resolveId:async(e,t)=>{if(e===`esm-env`)return`virtual:esm-env`;if(e===`svelte`)return`${M}/src/index-client.js`;if(e.startsWith(`svelte/`))return await P(`${M}/src/${e.slice(7)}`);if(e.startsWith(`#client/`))return await P(`${M}/src/internal/client/${e.slice(8)}`);if(/^https?:/.test(e))return e;if(e.startsWith(`.`)&&t&&t.startsWith(M)){let n=new URL(e,t).href;return new URL(e,t).href,n}},transform:async(t,n)=>{let{fileName:r}=x(n);if(r.endsWith(`.svelte`)){if(!j){if(!e)throw Error(`Svelte compiler not available`);j=await e()}let n=j(t,{filename:r,generate:`client`,css:`external`,dev:!1}),i=n.js.code;return n.css&&n.css.code&&(i=`
|
|
131
|
+
// Auto-inject CSS for Svelte component
|
|
132
|
+
(function() {
|
|
133
|
+
if (typeof document !== 'undefined') {
|
|
134
|
+
const style = document.createElement('style');
|
|
135
|
+
style.textContent = ${JSON.stringify(n.css.code)};
|
|
136
|
+
document.head.appendChild(style);
|
|
137
|
+
}
|
|
138
|
+
})();
|
|
139
|
+
`+i),i}}}),F=async({files:e,rollup:t,enableSourcemap:n=!0,vizCache:r,vizId:i,slugCache:a,getSvelteCompiler:o})=>{let s=new Set,c=e=>{s.add(e)};if(!e[`index.js`])throw Error(`Missing index.js`);let l={name:`replace`,transform(e,t){let n=!1,r=e;return r.includes(`process.env.NODE_ENV`)&&(r=r.replace(/\bprocess\.env\.NODE_ENV\b/g,JSON.stringify(`production`)),n=!0),n?{code:r,map:null}:null}},u={input:`./index.js`,plugins:[...i?[T({vizId:i,slugCache:a})]:[],C(),p(),oe({getSvelteCompiler:o}),l,...r?[ae({vizCache:r,trackCSSImport:c,vizId:i,files:e})]:[]],onwarn(e,t){e.code!==`UNRESOLVED_IMPORT`&&t(e)}},d={format:`umd`,name:`Viz`,sourcemap:!!n,compact:!0},f=h(e);if(f){let e=b(f);e&&(u.external=Object.keys(e),d.globals=e)}u.external||=[],d.globals||={},Array.isArray(u.external)&&(u.external=u.external.filter(e=>typeof e==`string`&&!e.startsWith(`#client/`)));let{output:m}=await(await t(u)).generate(d);return{src:m[0].code,cssFiles:Array.from(s)}},se=e=>{if(e instanceof Error){let t=e.stack||``,n=e.message||`Unknown error`;return`${e.name||`Error`}: ${n}\n${t}`}else if(`error`in e&&e.error instanceof Error){let t=e.error,n=t.stack||``,r=t.message||`Unknown error`,i=`filename`in e?e.filename:``,a=`lineno`in e?e.lineno:``,o=`colno`in e?e.colno:``,s=``;return i&&a&&(s=` at ${i}:${a}`,o&&(s+=`:${o}`)),`${t.name||`Error`}: ${r}${s}\n${n}`}else if(`reason`in e){let t=e.reason;if(t instanceof Error){let e=t.stack||``,n=t.message||`Unknown error`;return`Unhandled Promise Rejection - ${t.name||`Error`}: ${n}\n${e}`}else return`Unhandled Promise Rejection: ${String(t)}`}else return`Unknown runtime error: ${String(e)}`},I=()=>`
|
|
140
|
+
// Global error handling for runtime errors
|
|
141
|
+
(() => {
|
|
142
|
+
const formatRuntimeError = ${se.toString()};
|
|
143
|
+
|
|
144
|
+
// Handle uncaught JavaScript errors
|
|
145
|
+
window.addEventListener('error', (event) => {
|
|
146
|
+
const formattedErrorMessage = formatRuntimeError(event);
|
|
147
|
+
parent.postMessage({
|
|
148
|
+
type: 'runtimeError',
|
|
149
|
+
formattedErrorMessage
|
|
150
|
+
}, "*");
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
// Handle unhandled promise rejections
|
|
154
|
+
window.addEventListener('unhandledrejection', (event) => {
|
|
155
|
+
const formattedErrorMessage = formatRuntimeError(event);
|
|
156
|
+
parent.postMessage({
|
|
157
|
+
type: 'runtimeError',
|
|
158
|
+
formattedErrorMessage
|
|
159
|
+
}, "*");
|
|
160
|
+
});
|
|
161
|
+
})();
|
|
162
|
+
`;function L(){return Math.random().toString().slice(2,7)}var R=({cdn:e,src:t,styles:n})=>{let r=`viz-container-${L()}`;return`<!DOCTYPE html>
|
|
163
|
+
<html>
|
|
164
|
+
<head>
|
|
165
|
+
<meta charset="utf-8">${e}${n}
|
|
166
|
+
<style>
|
|
167
|
+
body {
|
|
168
|
+
margin: 0;
|
|
169
|
+
overflow: hidden;
|
|
170
|
+
}
|
|
171
|
+
#${r} {
|
|
172
|
+
height: 100vh;
|
|
173
|
+
}
|
|
174
|
+
</style>
|
|
175
|
+
</head>
|
|
176
|
+
<body>
|
|
177
|
+
<div id="${r}"></div>
|
|
178
|
+
<script>${I()}<\/script>
|
|
179
|
+
<script id="injected-script">${t}<\/script>
|
|
180
|
+
<script>
|
|
181
|
+
(() => {
|
|
182
|
+
let cleanup;
|
|
183
|
+
const render = () => {
|
|
184
|
+
const container = document.getElementById('${r}');
|
|
185
|
+
typeof cleanup === 'function' && cleanup();
|
|
186
|
+
cleanup = (Viz.viz || Viz.main)(container, { state: window.state, setState, writeFile });
|
|
187
|
+
};
|
|
188
|
+
const setState = (next) => {
|
|
189
|
+
window.state = next(window.state);
|
|
190
|
+
render();
|
|
191
|
+
};
|
|
192
|
+
const writeFile = (fileName, content) => {
|
|
193
|
+
parent.postMessage({ type: 'writeFile', fileName, content }, "*");
|
|
194
|
+
};
|
|
195
|
+
const run = () => {
|
|
196
|
+
try {
|
|
197
|
+
setState((state) => state || {});
|
|
198
|
+
} catch (error) {
|
|
199
|
+
console.error(error);
|
|
200
|
+
parent.postMessage({ type: 'runError', error }, "*");
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
run();
|
|
204
|
+
const runJS = (src) => {
|
|
205
|
+
document.getElementById('injected-script')?.remove();
|
|
206
|
+
const script = document.createElement('script');
|
|
207
|
+
script.textContent = src;
|
|
208
|
+
script.id = 'injected-script';
|
|
209
|
+
document.body.appendChild(script);
|
|
210
|
+
run();
|
|
211
|
+
};
|
|
212
|
+
const runCSS = (css) => {
|
|
213
|
+
let style = document.getElementById('injected-style');
|
|
214
|
+
if (!style) {
|
|
215
|
+
style = document.createElement('style');
|
|
216
|
+
style.type = 'text/css';
|
|
217
|
+
style.id = 'injected-style';
|
|
218
|
+
document.head.appendChild(style);
|
|
219
|
+
}
|
|
220
|
+
style.textContent = css;
|
|
221
|
+
};
|
|
222
|
+
onmessage = (message) => {
|
|
223
|
+
switch (message.data.type) {
|
|
224
|
+
case 'runJS':
|
|
225
|
+
runJS(message.data.js);
|
|
226
|
+
parent.postMessage({ type: 'runDone' }, "*");
|
|
227
|
+
break;
|
|
228
|
+
case 'runCSS':
|
|
229
|
+
runCSS(message.data.css);
|
|
230
|
+
break;
|
|
231
|
+
case 'ping':
|
|
232
|
+
parent.postMessage({ type: 'pong' }, "*");
|
|
233
|
+
break;
|
|
234
|
+
default:
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
})();
|
|
239
|
+
<\/script>
|
|
240
|
+
</body>
|
|
241
|
+
</html>`},z=async({files:e,rollup:t,enableSourcemap:n=!0,vizCache:r,vizId:i,slugCache:a,getSvelteCompiler:o})=>{let{src:s,cssFiles:c}=await F({files:e,rollup:t,enableSourcemap:n,vizCache:r,vizId:i,slugCache:a,getSvelteCompiler:o}),l=[];if(c.length>0)for(let t=0;t<c.length;t++){let n=c[t],a=x(n),o=a.vizId,s=a.fileName,d=null;d=o===i&&e?e[s]||null:(0,u.getFileText)(await r.get(o),s),d&&l.push(d)}let d=l.join(`
|
|
242
|
+
`),f=`\n <style id="injected-style">${d}</style>`,p=``,m=Object.entries(g(e));if(m.length>0){let t=_(e);p=m.map(([e,n],r)=>{let i=v({name:e,version:n},t);return`${r>0?` `:`
|
|
243
|
+
`}<script src="${i}"><\/script>`}).join(``)}return{html:R({cdn:p,src:s,styles:f}),css:d,js:s,runtimeVersion:`v3`}},B=({initialContents:e,handleCacheMiss:t})=>{let n=new Map(e.map(e=>[e.id,e]));return{get:async e=>{let r=n.get(e);if(r!==void 0)return r;if(!t)throw Error(`Unresolved import from vizId ${e}, cache miss handler not provided.`);let i=await t(e);if(i)return n.set(e,i),i;throw Error(`Unresolved import from vizId ${e}`)},set:e=>{n.set(e.id,e)},invalidate:e=>{n.delete(e)}}},V=({initialMappings:e={},handleCacheMiss:t})=>({get:async n=>{let r=e[n];if(r!==void 0)return r;if(!t)throw Error(`Unresolved slug ${n}, cache miss handler not provided.`);let i=await t(n);if(i)return e[n]=i,i;throw Error(`Unresolved slug ${n}`)},set:(t,n)=>{e[t]=n},invalidate:t=>{delete e[t]}}),H=({rawMessage:e,vizId:t})=>{let n=new RegExp(t,`g`);return e?.replace(n,`.`)},U=(e,t=`Sample Content for Exporting`,n=(0,u.generateVizId)())=>({id:n,files:(0,u.fileCollectionToVizFiles)(e),title:t}),W=e=>{if(Object.keys(e).length===0)return null;let t=`index.html`in e,n=`index.js`in e,r=`index.jsx`in e;return t?e[`index.html`].includes(`type="module"`)?`v4`:n||r?`v2`:`v1`:!t&&n?`v3`:null},G=(e,t)=>RegExp(`<${t}\\b`,`i`).test(e)&&RegExp(`</${t}>`,`i`).test(e),K=e=>{let t=e.trim();return G(t,`html`)&&G(t,`head`)&&G(t,`body`)?t:`<html><head></head><body>${t}</body></html>`},ce=(e,t)=>e.replace(RegExp(`<script[^>]*src=["'][^"']*${t.source}[^"']*["'][^>]*>\\s*<\/script>`,`gi`),``),q=(e,t,n)=>e.replace(new RegExp(t,`i`),`${n}${t}`),le=(e,t)=>{let n=K(e),r=Object.entries(g(t));if(r.length){let e=_(t);r.forEach(([e])=>{n=ce(n,RegExp(`${e}@`))});let i=r.map(([t,n])=>v({name:t,version:n},e)).map(e=>`<script src="${e}"><\/script>`).join(`
|
|
244
|
+
`);n=q(n,`</head>`,i+`
|
|
245
|
+
`)}if(t[`bundle.js`]!==void 0||t[`index.js`]!==void 0){let e=/<script\b[^>]*\bsrc=["']bundle\.js["'][^>]*>\s*<\/script>/gi,t=[...n.matchAll(e)];t.length===1&&(()=>{let e=t[0].index??-1;if(e===-1)return!1;let r=n.search(/<body\b[^>]*>/i),i=n.search(/<\/body>/i);return r!==-1&&i!==-1&&e>r&&e<i})()||(n=n.replace(e,``),n=q(n,`</body>`,`<script src="bundle.js"><\/script>`))}let i=`<script>${I()}<\/script>\n`;return n=q(n,`</head>`,i),/^\s*<!DOCTYPE/i.test(n)?n:`<!DOCTYPE html>${n}`},ue=e=>{let t=e[`index.html`];return!t&&!e[`index.js`]&&!e[`bundle.js`]?``:le(t||`<!DOCTYPE html><html><head></head><body></body></html>`,e)},de=c(o(((e,t)=>{t.exports={d3:`d3`,"d3-array":`d3`,"d3-axis":`d3`,"d3-brush":`d3`,"d3-chord":`d3`,"d3-collection":`d3`,"d3-color":`d3`,"d3-contour":`d3`,"d3-dispatch":`d3`,"d3-drag":`d3`,"d3-dsv":`d3`,"d3-ease":`d3`,"d3-fetch":`d3`,"d3-force":`d3`,"d3-format":`d3`,"d3-geo":`d3`,"d3-hierarchy":`d3`,"d3-interpolate":`d3`,"d3-path":`d3`,"d3-polygon":`d3`,"d3-quadtree":`d3`,"d3-random":`d3`,"d3-scale":`d3`,"d3-scale-chromatic":`d3`,"d3-selection":`d3`,"d3-shape":`d3`,"d3-tile":`d3`,"d3-time":`d3`,"d3-time-format":`d3`,"d3-timer":`d3`,"d3-transition":`d3`,"d3-voronoi":`d3`,"d3-zoom":`d3`,react:`React`,"react-dom":`ReactDOM`,"react-dropdown-browser":`ReactDropdown`,"react-dropdown":`ReactDropdown`,three:`THREE`,vega:`vega`,"vega-embed":`vegaEmbed`,"vega-lite":`vegaLite`,"vega-lite-api":`vl`,"vega-tooltip":`vegaTooltip`,"vega-themes":`vegaThemes`,"vizhub-vega-lite-config":`vizhubVegaLiteConfig`,semiotic:`Semiotic`,"viz.js":`Viz`}}))(),1),J=`\0virtual:`,fe=e=>{let t=e.replace(/^\.\//,``);return t=t.replace(/\/+/g,`/`),t=t.replace(/\/$/,``),t},pe=(e,t)=>{let n=e.includes(`/`)?e.slice(0,e.lastIndexOf(`/`)):``,r=t.split(`/`),i=n?n.split(`/`):[];for(let e of r)e===`..`?i.pop():e!==`.`&&e!==``&&i.push(e);return i.join(`/`)},Y=e=>({name:`virtual-file-system`,resolveId(t,n){let r=n?.startsWith(`\0virtual:`)?n.slice(9):n;if(t.startsWith(`./`)||t.startsWith(`../`)){let n=fe(r?pe(r,t):t);if(e[n])return J+n;for(let t of[`.js`,`.jsx`,`.ts`,`.tsx`]){let r=n+t;if(e[r])return J+r}}if(e[t])return J+t;for(let n of[`.js`,`.jsx`,`.ts`,`.tsx`]){let r=t+n;if(e[r])return J+r}return null},load(t){if(t.startsWith(`\0virtual:`)){let n=t.slice(9);if(e[n])return E(n)?`export default "${D(n,e[n])}";`:e[n]}return null}}),me=async({files:e,rollup:t,enableSourcemap:n=!0})=>{let r=`index.js`;if(!e[r]&&(r=`index.jsx`,!e[r]))throw Error(`Missing entry point, can't find index.js or index.jsx`);let i={input:`./`+r,plugins:[Y(e),p()],onwarn(e,t){e.code!==`UNRESOLVED_IMPORT`&&t(e)}},a={format:`iife`,sourcemap:n},o=h(e);if(o){let e={...de.default,...b(o)};e&&(i.external=Object.keys(e),a.globals=e)}let{output:s}=await(await t(i)).generate(a);return s[0].code},he=async({files:e,rollup:t,enableSourcemap:n})=>({...e,"bundle.js":await me({files:e,rollup:t,enableSourcemap:n}),"index.html":ue(e)}),ge=e=>{let t=[],n=[],r=/<script\b([^>]*)>([\s\S]*?)<\/script>/gi,i,a=0;for(;(i=r.exec(e))!==null;){let e=i[1],r=i[2];if(!/\btype\s*=\s*["']module["']/i.test(e))continue;let o=e.match(/\bsrc\s*=\s*["']([^"']+)["']/i);if(o)t.push(o[1]);else if(r.trim()){let e=`__inline_script_${a++}.js`;n.push({id:e,content:r.trim()}),t.push(e)}}return{entryPoints:t,inlineScripts:n}},_e=()=>({name:`catch-all-prevent-fs`,resolveId(e,t){return{id:e,external:!0}}}),ve=async({entryPoint:e,files:t,rollup:n,enableSourcemap:r=!0})=>{let{output:i}=await(await n({input:e.startsWith(`./`)?e:`./${e}`,plugins:[Y(t),p({jsxRuntime:`automatic`}),_e()],onwarn(e,t){}})).generate({format:`es`,sourcemap:r});return i[0].code},X=(e,t)=>RegExp(`<${t}\\b`,`i`).test(e)&&RegExp(`</${t}>`,`i`).test(e),ye=e=>{let t=e.trim();return X(t,`html`)&&X(t,`head`)&&X(t,`body`)?t:`<html><head></head><body>${t}</body></html>`},Z=e=>e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`),Q=(e,t,n)=>e.replace(new RegExp(t,`i`),`${n}${t}`),be=e=>{let t=g(e);if(Object.keys(t).length===0)return null;let n=_(e),r={};for(let[e,i]of Object.entries(t))r[e]=v({name:e,version:i},n);return JSON.stringify({imports:r},null,2)},xe=()=>`
|
|
246
|
+
// V4 Hot Reloading Support
|
|
247
|
+
(() => {
|
|
248
|
+
const runJS = (js) => {
|
|
249
|
+
// Remove all existing bundled module scripts
|
|
250
|
+
const existingScripts = document.querySelectorAll('script[type="module"]');
|
|
251
|
+
existingScripts.forEach(script => {
|
|
252
|
+
// Only remove scripts that contain bundled code (not import maps or external scripts)
|
|
253
|
+
if (script.textContent && script.textContent.trim()) {
|
|
254
|
+
script.remove();
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
// Create new script with updated bundled code
|
|
259
|
+
const script = document.createElement('script');
|
|
260
|
+
script.type = 'module';
|
|
261
|
+
script.textContent = js;
|
|
262
|
+
document.body.appendChild(script);
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
const runCSS = (css) => {
|
|
266
|
+
let style = document.getElementById('v4-injected-style');
|
|
267
|
+
if (!style) {
|
|
268
|
+
style = document.createElement('style');
|
|
269
|
+
style.type = 'text/css';
|
|
270
|
+
style.id = 'v4-injected-style';
|
|
271
|
+
document.head.appendChild(style);
|
|
272
|
+
}
|
|
273
|
+
style.textContent = css;
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
// Listen for hot reload messages
|
|
277
|
+
window.addEventListener('message', (message) => {
|
|
278
|
+
switch (message.data.type) {
|
|
279
|
+
case 'runJS':
|
|
280
|
+
try {
|
|
281
|
+
runJS(message.data.js);
|
|
282
|
+
parent.postMessage({ type: 'runDone' }, "*");
|
|
283
|
+
} catch (error) {
|
|
284
|
+
console.error('V4 Hot reload error:', error);
|
|
285
|
+
parent.postMessage({ type: 'runError', error }, "*");
|
|
286
|
+
}
|
|
287
|
+
break;
|
|
288
|
+
case 'runCSS':
|
|
289
|
+
runCSS(message.data.css);
|
|
290
|
+
break;
|
|
291
|
+
case 'ping':
|
|
292
|
+
parent.postMessage({ type: 'pong' }, "*");
|
|
293
|
+
break;
|
|
294
|
+
default:
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
})();
|
|
299
|
+
`,Se=(e,t,n=[],r=!1)=>{if(!e[`index.html`])return``;let i=ye(e[`index.html`]);t.forEach((e,t)=>{if(n.some(e=>e.id===t)){let r=Z(n.find(e=>e.id===t)?.content||``),a=RegExp(`<script\\b[^>]*\\btype=["']module["'][^>]*>\\s*${r}\\s*<\/script>`,`gi`);i=i.replace(a,`<script type="module">\n${e}\n<\/script>`)}else{let n=RegExp(`<script\\b[^>]*\\bsrc=["']${Z(t)}["'][^>]*>[^<]*<\/script>`,`gi`);i=i.replace(n,`<script type="module">\n${e}\n<\/script>`)}});let a=be(e);if(a&&!/<script\b[^>]*type=["']importmap["'][^>]*>/i.test(i)){let e=`<script type="importmap">\n${a}\n<\/script>\n`;i=Q(i,`</head>`,e)}let o=`<script>${I()}<\/script>\n`;if(i=Q(i,`</head>`,o),r){let e=`<script>${xe()}<\/script>\n`;i=Q(i,`</body>`,e)}return/^\s*<!DOCTYPE/i.test(i)?i:`<!DOCTYPE html>${i}`},Ce=async({files:e,rollup:t,enableSourcemap:n=!0})=>{let{entryPoints:r,inlineScripts:i}=ge(e[`index.html`]||``);if(r.length===0)return{files:e,bundledJS:``};let a={...e};for(let e of i)a[e.id]=e.content;let o=new Map,s=[];for(let e of r){let r=await ve({entryPoint:e,files:a,rollup:t,enableSourcemap:n});o.set(e,r),s.push(r)}let c=Se(a,o,i,!0),l=s.join(`
|
|
300
|
+
`);return{files:{...e,"index.html":c},bundledJS:l}},we=e=>{let t=`<script>${I()}<\/script>`;return e.includes(`</head>`)?e.replace(`</head>`,`${t}\n</head>`):e.includes(`</body>`)?e.replace(`</body>`,`${t}\n</body>`):e+t},$=e=>{let t={...e};for(let[n,r]of Object.entries(t))n.toLowerCase().endsWith(`.html`)&&(t[n]=O(r,e));return t},Te=async({files:e,rollup:t,enableSourcemap:n=!0,vizCache:r,vizId:i,slugCache:a,getSvelteCompiler:o})=>{try{if(!e&&!r)throw Error(`Either files or vizCache is required`);if(!e&&r&&!i)throw Error(`vizId is required when using vizCache`);if(!e&&r&&i&&(e=(0,u.vizFilesToFileCollection)((await r.get(i))?.files)),!e)throw Error(`Upable to extract viz files`);let s=W(e);if(s===`v1`)return{html:we((0,l.magicSandbox)($(e))),runtimeVersion:s};if(s===`v2`){if(!t)throw Error(`Rollup is required for v2 runtime`);return{html:(0,l.magicSandbox)($(await he({files:e,rollup:t,enableSourcemap:n}))),runtimeVersion:s}}if(s===`v3`){if(!t)throw Error(`Rollup is required for v3 runtime`);if(!r&&!i){let t=U(e);i=t.id,r=B({initialContents:[t],handleCacheMiss:async()=>{throw Error(`Cache miss handler not implemented`)}})}if(!r)throw Error(`vizCache is required for v3 runtime`);if(!i)throw Error(`vizId is required for v3 runtime if vizCache is provided`);return await z({files:e,rollup:t,vizCache:r,vizId:i,slugCache:a,getSvelteCompiler:o})}if(s===`v4`){if(!t)throw Error(`Rollup is required for v4 runtime`);let r=await Ce({files:e,rollup:t,enableSourcemap:n});return{html:(0,l.magicSandbox)($(r.files)),js:r.bundledJS,runtimeVersion:s}}throw Error(`Unsupported runtime version: ${s}`)}catch(e){throw e instanceof Error&&e.message.indexOf(`\0virtual:`)&&(e.message=e.message.replace(J,``)),e}};Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return V}}),Object.defineProperty(exports,"c",{enumerable:!0,get:function(){return F}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return H}}),Object.defineProperty(exports,"l",{enumerable:!0,get:function(){return N}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return W}}),Object.defineProperty(exports,"o",{enumerable:!0,get:function(){return B}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return U}}),Object.defineProperty(exports,"s",{enumerable:!0,get:function(){return z}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return Te}}),Object.defineProperty(exports,"u",{enumerable:!0,get:function(){return f}});
|
|
301
|
+
//# sourceMappingURL=build-BiyVcX4s.cjs.map
|