mirror of https://github.com/sveltejs/svelte
parent
9b7d0152bc
commit
2c537e7cb4
@ -0,0 +1,136 @@
|
||||
|
||||
|
||||
|
||||
const importCache = {};
|
||||
|
||||
|
||||
|
||||
function fetchImport(id) {
|
||||
return new Promise((fulfil, reject) => {
|
||||
curl([`https://bundle.run/${id}`]).then(module => {
|
||||
importCache[id] = module;
|
||||
fulfil(module);
|
||||
}, err => {
|
||||
console.error(err.stack);
|
||||
reject(new Error(`Error loading ${id} from bundle.run`));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function fetchImports(bundle, progressFunc) {
|
||||
const missingImports = bundle.imports.filter(x => !importCache[x]);
|
||||
let pendingImports = missingImports.length;
|
||||
|
||||
if (missingImports.length) {
|
||||
let promise = Promise.all(
|
||||
missingImports.map(id => fetchImport(id).then(() => {
|
||||
pendingImports -= 1;
|
||||
if (progressFunc) progressFunc(pendingImports);
|
||||
}))
|
||||
);
|
||||
|
||||
return promise
|
||||
} else {
|
||||
return P.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function handleMessage(ev) {
|
||||
if (ev.data.action == "eval") {
|
||||
let { script, evalId } = ev.data.args;
|
||||
try {
|
||||
eval(script);
|
||||
parent.postMessage({
|
||||
action: "evalOk",
|
||||
args: {
|
||||
evalId: evalId
|
||||
}
|
||||
}, ev.origin);
|
||||
} catch (e) {
|
||||
parent.postMessage({
|
||||
action: "evalError",
|
||||
args: {
|
||||
evalId: evalId,
|
||||
stack: e.stack,
|
||||
message: e.message
|
||||
}
|
||||
}, ev.origin);
|
||||
}
|
||||
}
|
||||
|
||||
if (ev.data.action == "bind_props") {
|
||||
let { props } = ev.data.args
|
||||
|
||||
if (!window.component) {
|
||||
// TODO can this happen?
|
||||
console.error(`no component to bind to`);
|
||||
return;
|
||||
}
|
||||
|
||||
props.forEach(prop => {
|
||||
// TODO should there be a public API for binding?
|
||||
// e.g. `component.$watch(prop, handler)`?
|
||||
// (answer: probably)
|
||||
window.component.$$.bound[prop] = value => {
|
||||
parent.postMessage({
|
||||
action: "propUpdate",
|
||||
args: {
|
||||
prop: prop,
|
||||
value: value
|
||||
}
|
||||
}, ev.origin);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
if (ev.data.action == "set_prop") {
|
||||
if (!window.component) {
|
||||
return;
|
||||
}
|
||||
let { prop, value } = ev.data.args;
|
||||
component[prop] = value;
|
||||
}
|
||||
|
||||
if (ev.data.action == "fetch_imports") {
|
||||
let { bundle, fetchId } = ev.data.args;
|
||||
fetchImports(bundle, (remaining) => {
|
||||
parent.postMessage({
|
||||
action: "fetch_progress",
|
||||
args: {
|
||||
fetchId: fetchId,
|
||||
remaining: remaining
|
||||
}
|
||||
}, ev.origin);
|
||||
})
|
||||
.then(() => {
|
||||
bundle.imports.forEach(x=> {
|
||||
const module = importCache[x];
|
||||
const name = bundle.importMap.get(x);
|
||||
window[name] = module;
|
||||
});
|
||||
|
||||
parent.postMessage({
|
||||
action: "fetch_complete",
|
||||
args: {
|
||||
fetchId: fetchId
|
||||
}
|
||||
}, ev.origin);
|
||||
})
|
||||
.catch(e => {
|
||||
parent.postMessage({
|
||||
action: "fetch_error",
|
||||
args: {
|
||||
fetchId: fetchId,
|
||||
message: e.message
|
||||
}
|
||||
}, ev.origin);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("message", handleMessage, false)
|
||||
|
||||
console.log("repl-runner initialized");
|
||||
|
Loading…
Reference in new issue