mirror of
https://github.com/leporello-js/leporello-js
synced 2026-01-13 13:04:30 -08:00
self-hosted tests work
This commit is contained in:
52
src/eval.js
52
src/eval.js
@@ -269,19 +269,13 @@ export const eval_modules = (
|
|||||||
|
|
||||||
// TODO bug if module imported twice, once as external and as regular
|
// TODO bug if module imported twice, once as external and as regular
|
||||||
|
|
||||||
patch_promise(globalThis.run_window)
|
|
||||||
|
|
||||||
const is_async = has_toplevel_await(parse_result.modules)
|
const is_async = has_toplevel_await(parse_result.modules)
|
||||||
|
|
||||||
const codestring =
|
const codestring = `
|
||||||
`
|
|
||||||
let children, prev_children
|
let children, prev_children
|
||||||
|
|
||||||
// TODO refactor, move patch_promise here
|
// TODO use native array for stack for perf? stack contains booleans
|
||||||
globalThis.get_children = () => children
|
|
||||||
globalThis.set_children = (_children) => children = _children
|
|
||||||
|
|
||||||
// TODO use native array for stack for perf?
|
|
||||||
const stack = new Array()
|
const stack = new Array()
|
||||||
|
|
||||||
let logs = []
|
let logs = []
|
||||||
@@ -296,6 +290,44 @@ export const eval_modules = (
|
|||||||
let is_recording_deferred_calls
|
let is_recording_deferred_calls
|
||||||
let is_toplevel_call = true
|
let is_toplevel_call = true
|
||||||
|
|
||||||
|
let promise_then
|
||||||
|
|
||||||
|
function apply_promise_patch() {
|
||||||
|
|
||||||
|
promise_then = Promise.prototype.then
|
||||||
|
|
||||||
|
Promise.prototype.then = function then(on_resolve, on_reject) {
|
||||||
|
if(children == null) {
|
||||||
|
children = []
|
||||||
|
}
|
||||||
|
let children_copy = children
|
||||||
|
|
||||||
|
const make_callback = cb => cb == null
|
||||||
|
? null
|
||||||
|
: value => {
|
||||||
|
const current = children
|
||||||
|
children = children_copy
|
||||||
|
try {
|
||||||
|
return cb(value)
|
||||||
|
} finally {
|
||||||
|
children = current
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return promise_then.call(
|
||||||
|
this,
|
||||||
|
make_callback(on_resolve),
|
||||||
|
make_callback(on_reject),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function remove_promise_patch() {
|
||||||
|
Promise.prototype.then = promise_then
|
||||||
|
}
|
||||||
|
|
||||||
|
apply_promise_patch()
|
||||||
|
|
||||||
const set_record_call = () => {
|
const set_record_call = () => {
|
||||||
for(let i = 0; i < stack.length; i++) {
|
for(let i = 0; i < stack.length; i++) {
|
||||||
stack[i] = true
|
stack[i] = true
|
||||||
@@ -634,6 +666,7 @@ export const eval_modules = (
|
|||||||
const _logs = logs
|
const _logs = logs
|
||||||
logs = []
|
logs = []
|
||||||
children = null
|
children = null
|
||||||
|
remove_promise_patch()
|
||||||
return { modules: __modules, calltree: current_call, logs: _logs }
|
return { modules: __modules, calltree: current_call, logs: _logs }
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
@@ -645,6 +678,7 @@ export const eval_modules = (
|
|||||||
const _logs = logs
|
const _logs = logs
|
||||||
logs = []
|
logs = []
|
||||||
children = null
|
children = null
|
||||||
|
remove_promise_patch()
|
||||||
return { modules: __modules, calltree: current_call, logs: _logs }
|
return { modules: __modules, calltree: current_call, logs: _logs }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,37 +0,0 @@
|
|||||||
export const patch_promise = window => {
|
|
||||||
|
|
||||||
if(window.Promise.__patched) {
|
|
||||||
// already patched
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const _then = window.Promise.prototype.then
|
|
||||||
|
|
||||||
window.Promise.prototype.then = function then(on_resolve, on_reject) {
|
|
||||||
let children = window.get_children()
|
|
||||||
if(children == null) {
|
|
||||||
children = []
|
|
||||||
window.set_children(children)
|
|
||||||
}
|
|
||||||
|
|
||||||
const make_callback = cb => cb == null
|
|
||||||
? null
|
|
||||||
: value => {
|
|
||||||
const current = window.get_children()
|
|
||||||
window.set_children(children)
|
|
||||||
try {
|
|
||||||
return cb(value)
|
|
||||||
} finally {
|
|
||||||
window.set_children(current)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return _then.call(
|
|
||||||
this,
|
|
||||||
make_callback(on_resolve),
|
|
||||||
make_callback(on_reject),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
window.Promise.__patched = true
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
export const unwrap_settled_promises = calltree => {
|
|
||||||
let is_finished = false
|
|
||||||
|
|
||||||
const unwrap = call => {
|
|
||||||
// TODO use run_window.Promise
|
|
||||||
|
|
||||||
if(!call.ok) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if(call.value instanceof Promise) {
|
|
||||||
call.value
|
|
||||||
.then(value => {
|
|
||||||
if(is_finished) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
call.unwrapped_value = {ok: true, value}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
if(is_finished) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
call.unwrapped_value = {ok: false, error}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const unwrap_tree = call => {
|
|
||||||
unwrap(call)
|
|
||||||
if(call.children != null) {
|
|
||||||
for(let c of call.children) {
|
|
||||||
unwrap(c)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unwrap_tree(calltree)
|
|
||||||
|
|
||||||
return Promise.resolve().then(() => {
|
|
||||||
is_finished = true
|
|
||||||
return calltree
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
const delay = new Promise(resolve => setTimeout(() => resolve('123'), 1000))
|
|
||||||
|
|
||||||
const tree = {
|
|
||||||
value: Promise.resolve('resolved'),
|
|
||||||
ok: true,
|
|
||||||
children: [
|
|
||||||
{value: delay, ok: true}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
await unwrap_settled_promises(tree)
|
|
||||||
console.log('tree', tree)
|
|
||||||
*/
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user