more context stuff

pull/2179/head
Richard Harris 7 years ago
parent 8c9cc8bf2a
commit 53653c1c7c

@ -5,14 +5,10 @@
import { decode } from 'sourcemap-codec';
const dispatch = createEventDispatcher();
const { values, navigate } = getContext('REPL');
const { bundle, values, navigate } = getContext('REPL');
export let bundle;
export let dom;
export let ssr;
export let props;
export let sourceError;
export let error;
export let error; // TODO should this be exposed as a prop?
export function setProp(prop, value) {
if (!replProxy) return;
@ -21,13 +17,12 @@
let hasComponent = false;
const refs = {};
let iframe;
let pendingImports = 0;
let pending = false;
let replProxy = null;
const namespaceSpecifier = /\*\s+as\s+(\w+)/;
const namedSpecifiers = /\{(.+)\}/;
@ -73,10 +68,9 @@
}
});
onMount(() => {
replProxy = new ReplProxy(refs.child);
refs.child.addEventListener('load', () => {
replProxy = new ReplProxy(iframe);
iframe.addEventListener('load', () => {
replProxy.onPropUpdate = (prop, value) => {
dispatch('binding', { prop, value });
values.update(values => Object.assign({}, values, {
@ -96,7 +90,7 @@
let toDestroy = null;
const init = () => {
if (sourceError) return;
if ($bundle.error) return;
const removeStyles = () => {
replProxy.eval(`
@ -121,7 +115,7 @@
toDestroy = null;
}
if (ssr) { // this only gets generated if component uses lifecycle hooks
if ($bundle.ssr) { // this only gets generated if component uses lifecycle hooks
pending = true;
createHtml();
} else {
@ -131,7 +125,7 @@
}
const createHtml = () => {
replProxy.eval(`${ssr.code}
replProxy.eval(`${$bundle.ssr.code}
var rendered = SvelteComponent.render(${JSON.stringify($values)});
if (rendered.css.code) {
@ -144,7 +138,7 @@
document.body.innerHTML = rendered.html;
`)
.catch( e => {
const loc = getLocationFromStack(e.stack, ssr.map);
const loc = getLocationFromStack(e.stack, $bundle.ssr.map);
if (loc) {
e.filename = loc.source;
e.loc = { line: loc.line, column: loc.column };
@ -156,9 +150,9 @@
const createComponent = () => {
// remove leftover styles from SSR renderer
if (ssr) removeStyles();
if ($bundle.ssr) removeStyles();
replProxy.eval(`${dom.code}
replProxy.eval(`${$bundle.dom.code}
if (window.component) {
try {
window.component.$destroy();
@ -183,7 +177,7 @@
// TODO show in UI
hasComponent = false;
const loc = getLocationFromStack(e.stack, dom.map);
const loc = getLocationFromStack(e.stack, $bundle.dom.map);
if (loc) {
e.filename = loc.source;
e.loc = { line: loc.line, column: loc.column };
@ -196,7 +190,7 @@
// Download the imports (sets them on iframe window when complete)
{
let cancelled = false;
promise = replProxy.fetchImports(bundle);
promise = replProxy.fetchImports($bundle.imports, $bundle.import_map);
promise.cancel = () => { cancelled = true };
promise.then(() => {
if (cancelled) return;
@ -219,8 +213,8 @@
};
}
bundle_handler = bundle => {
if (!bundle) return; // TODO can this ever happen?
bundle_handler = $bundle => {
if (!$bundle) return; // TODO can this ever happen?
if (promise) promise.cancel();
toDestroy = hasComponent;
@ -228,8 +222,6 @@
init();
};
});
});
@ -238,7 +230,7 @@
let bundle_handler = noop;
let props_handler = noop;
$: bundle_handler(bundle);
$: bundle_handler($bundle);
$: props_handler(props);
</script>
@ -292,7 +284,7 @@
</style>
<div class="iframe-container">
<iframe title="Result" bind:this={refs.child} sandbox="allow-popups-to-escape-sandbox allow-scripts allow-popups allow-forms allow-pointer-lock allow-top-navigation allow-modals" class="{error || pending || pendingImports ? 'greyed-out' : ''}" srcdoc='
<iframe title="Result" bind:this={iframe} sandbox="allow-popups-to-escape-sandbox allow-scripts allow-popups allow-forms allow-pointer-lock allow-top-navigation allow-modals" class="{error || pending || pendingImports ? 'greyed-out' : ''}" srcdoc='
<!doctype html>
<html>
<head>

@ -6,16 +6,11 @@
import PropEditor from './PropEditor.svelte';
import CodeMirror from '../CodeMirror.svelte';
const { values } = getContext('REPL');
const { bundle, values } = getContext('REPL');
export let bundle;
export let js;
export let css;
export let dom;
export let ssr;
export let props;
export let json5;
export let sourceError;
export let sourceErrorLoc;
export let runtimeError;
export let compile_options;
@ -121,14 +116,10 @@
{#if view === 'result'}
<SplitPane type="vertical" pos={67} fixed={!show_props} fixed_pos={100}>
<div slot="a">
{#if bundle}
{#if $bundle}
<Viewer
bind:this={viewer}
{bundle}
{dom}
{ssr}
{props}
{sourceError}
bind:error={runtimeError}
on:binding="{e => setPropFromViewer(e.detail.prop, e.detail.value)}"
/>

@ -83,7 +83,7 @@ export default class ReplProxy {
return this.iframeCommand("catch_clicks", {});
}
fetchImports(bundle) {
return this.iframeCommand("fetch_imports", { bundle })
fetchImports(imports, import_map) {
return this.iframeCommand("fetch_imports", { imports, import_map })
}
}

@ -23,20 +23,26 @@
version; // workaround
return {
imports: bundle && bundle.imports || [],
imports,
components: $components,
values: $values
};
}
export function update(app) {
// TODO
}
const components = writable([]);
const values = writable({});
const selected = writable(null);
const bundle = writable(null);
setContext('REPL', {
components,
values,
selected,
bundle,
navigate: item => {
const match = /^(.+)\.(\w+)$/.exec(item.filename);
@ -78,7 +84,8 @@
let workers;
let bundle = null;
let imports = null;
let import_map = null;
let dom;
let ssr;
let sourceError = null;
@ -119,7 +126,8 @@
workers.bundler.postMessage({ type: 'init', version });
workers.bundler.onmessage = event => {
({ bundle, dom, ssr, warnings, error: sourceError } = event.data);
bundle.set(event.data);
({ imports, import_map, dom, ssr, warnings, error: sourceError } = event.data);
if (sourceError) console.error(sourceError);
runtimeError = null;
};
@ -284,11 +292,7 @@
{version}
{js}
{css}
{bundle}
{ssr}
{dom}
{props}
{sourceError}
{runtimeError}
{embedded}
{show_props}

@ -14,8 +14,8 @@ function fetchImport(id) {
});
}
function fetchImports(bundle, progressFunc) {
const missingImports = bundle.imports.filter(x => !importCache[x]);
function fetchImports(imports, progressFunc) {
const missingImports = imports.filter(x => !importCache[x]);
let pendingImports = missingImports.length;
if (missingImports.length) {
@ -124,14 +124,14 @@ function handleMessage(ev) {
if (action == "fetch_imports") {
let { bundle } = ev.data.args;
fetchImports(bundle, (remaining) => {
let { imports, import_map } = ev.data.args;
fetchImports(imports, (remaining) => {
sendMessage({action: "fetch_progress", args: { remaining }});
})
.then(() => {
bundle.imports.forEach(x=> {
imports.forEach(x=> {
const module = importCache[x];
const name = bundle.importMap.get(x);
const name = import_map.get(x);
window[name] = module;
});
sendOk();

@ -147,6 +147,7 @@ async function bundle(components) {
lookup[path] = component;
});
const import_map = new Map();
let dom;
let error;
@ -164,14 +165,13 @@ async function bundle(components) {
cached.dom = dom.cache;
let uid = 1;
const importMap = new Map();
const domResult = await dom.bundle.generate({
const dom_result = await dom.bundle.generate({
format: 'iife',
name: 'SvelteComponent',
globals: id => {
const name = `import_${uid++}`;
importMap.set(id, name);
import_map.set(id, name);
return name;
},
sourcemap: true
@ -192,22 +192,20 @@ async function bundle(components) {
if (token !== currentToken) return;
const ssrResult = ssr
const ssr_result = ssr
? await ssr.bundle.generate({
format: 'iife',
name: 'SvelteComponent',
globals: id => importMap.get(id),
globals: id => import_map.get(id),
sourcemap: true
})
: null;
return {
bundle: {
imports: dom.bundle.imports,
importMap
},
dom: domResult,
ssr: ssrResult,
import_map,
dom: dom_result,
ssr: ssr_result,
warnings: dom.warnings,
error: null
};
@ -216,7 +214,8 @@ async function bundle(components) {
delete e.toString;
return {
bundle: null,
imports: [],
import_map,
dom: null,
ssr: null,
warnings: dom.warnings,

Loading…
Cancel
Save