@ -1,97 +1,57 @@
( function ( ) {
const importC ache = { } ;
( function ( ) {
const import _c ache = { } ;
function fetchI mport( id ) {
function fetch _i mport( id ) {
return new Promise ( ( fulfil , reject ) => {
curl ( [ ` https://bundle.run/ ${ id } ` ] ) . then ( module => {
importC ache[ id ] = module ;
import _c ache[ id ] = module ;
fulfil ( module ) ;
} , err => {
console . error ( err . stack ) ;
reject ( new Error ( ` Error loading ${ id } from bundle.run ` ) ) ;
} ) ;
} ) ;
}
}
function fetchImports ( imports , progressF unc) {
const missingI mports = imports . filter ( x => ! import C ache[ x ] ) ;
let pendingImports = missingI mports. length ;
function fetch _imports ( imports , progress _f unc) {
const missing _i mports = imports . filter ( x => ! import _c ache[ x ] ) ;
let pending _imports = missing _i mports. length ;
if ( missingI mports. length ) {
if ( missing _i mports. length ) {
let promise = Promise . all (
missingImports . map ( id => fetchI mport( id ) . then ( ( ) => {
pendingI mports -= 1 ;
if ( progressFunc ) progressFunc ( pendingI mports) ;
missing _imports . map ( id => fetch _i mport( id ) . then ( ( ) => {
pending _i mports -= 1 ;
if ( progress _func ) progress _func ( pending _i mports) ;
} ) )
) ;
return promise
return promise ;
} else {
return Promise . resolve ( ) ;
}
}
function handleMessage ( ev ) {
let { action , cmdId } = ev . data ;
const sendMessage = ( payload ) => parent . postMessage ( { ... payload } , ev . origin ) ;
const sendReply = ( payload ) => sendMessage ( { ... payload , cmdId } )
const sendOk = ( ) => sendReply ( { action : "cmdOk" } ) ;
const sendError = ( message , stack ) => sendReply ( { action : "cmdError" , message , stack } )
if ( action == "eval" ) {
let { script } = ev . data . args ;
try {
eval ( script ) ;
sendOk ( ) ;
} catch ( e ) {
sendError ( e . message , e . stack ) ;
}
}
if ( action == "bind_props" ) {
let { props } = ev . data . args
if ( ! window . component ) {
// TODO can this happen?
console . warn ( 'no component to bind to' ) ;
sendOk ( ) ;
return ;
}
function handle _message ( ev ) {
let { action , cmd _id } = ev . data ;
const send _message = ( payload ) => parent . postMessage ( { ... payload } , ev . origin ) ;
const send _reply = ( payload ) => send _message ( { ... payload , cmd _id } ) ;
const send _ok = ( ) => send _reply ( { action : 'cmd_ok' } ) ;
const send _error = ( message , stack ) => send _reply ( { action : 'cmd_error' , message , stack } ) ;
if ( action === 'eval' ) {
try {
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 => {
sendMessage ( { action : "prop_update" , args : { prop , value } } )
} ;
} ) ;
sendOk ( ) ;
} catch ( e ) {
sendError ( e . message , e . stack ) ;
}
}
if ( action == "set_prop" ) {
try {
if ( ! window . component ) {
return ;
}
let { prop , value } = ev . data . args ;
component [ prop ] = value ;
sendOk ( ) ;
const { script } = ev . data . args ;
eval ( script ) ;
send _ok ( ) ;
} catch ( e ) {
sendE rror( e . message , e . stack ) ;
send _error ( e . message , e . stack ) ;
}
}
if ( action == "catch_clicks" ) {
if ( action === 'catch_clicks' ) {
try {
let topO rigin = ev . origin ;
const top _origin = ev . origin ;
document . body . addEventListener ( 'click' , event => {
if ( event . which !== 1 ) return ;
if ( event . metaKey || event . ctrlKey || event . shiftKey ) return ;
@ -106,7 +66,7 @@ function handleMessage(ev) {
event . preventDefault ( ) ;
if ( el . href . startsWith ( top O rigin) ) {
if ( el . href . startsWith ( top _o rigin) ) {
const url = new URL ( el . href ) ;
if ( url . hash [ 0 ] === '#' ) {
window . location . hash = url . hash ;
@ -116,34 +76,30 @@ function handleMessage(ev) {
window . open ( el . href , '_blank' ) ;
} ) ;
sendO k( ) ;
send _o k( ) ;
} catch ( e ) {
sendE rror( e . message , e . stack ) ;
send _e rror( e . message , e . stack ) ;
}
}
if ( action == "fetch_imports" ) {
let { imports , import _map } = ev . data . args ;
fetchImports ( imports , ( remaining ) => {
sendMessage ( { action : "fetch_progress" , args : { remaining } } ) ;
if ( action === 'fetch_imports' ) {
const { imports , import _map } = ev . data . args ;
fetch _imports ( imports , ( remaining ) => {
send _message ( { action : 'fetch_progress' , args : { remaining } } ) ;
} )
. then ( ( ) => {
imports . forEach ( x => {
const module = importC ache[ x ] ;
const module = import _c ache[ x ] ;
const name = import _map . get ( x ) ;
window [ name ] = module ;
} ) ;
sendO k( ) ;
send _o k( ) ;
} )
. catch ( e => {
sendError ( e . message , e . stack ) ;
} )
send _error ( e . message , e . stack ) ;
} ) ;
}
}
}
window . addEventListener ( "message" , handleMessage , false )
console . log ( "repl-runner initialized" ) ;
window . addEventListener ( 'message' , handle _message , false ) ;
} ) ( ) ;