reload app window before run code with clear io_trace

This commit is contained in:
Dmitry Vasilev
2024-03-02 07:32:52 +08:00
parent 2cf94fe651
commit 62407ec86b
5 changed files with 51 additions and 47 deletions

View File

@@ -216,6 +216,11 @@ const eval_modules_finished = (state, prev_state, result) => {
return state
}
if(result.rt_cxt.io_trace_is_replay_aborted) {
// execution was discarded, return state to execute `run_code` without io_trace
return clear_io_trace({...state, rt_cxt: result.rt_cxt})
}
const next = find_call(
apply_eval_result(state, result),
current_cursor_position(state)

6
src/effects.js vendored
View File

@@ -7,7 +7,7 @@ import {
get_deferred_calls
} from './calltree.js'
import {current_cursor_position} from './calltree.js'
import {exec, FILES_ROOT} from './index.js'
import {exec, reload_app_window, FILES_ROOT} from './index.js'
// Imports in the context of `app_window`, so global variables in loaded
// modules refer to that window's context
@@ -209,7 +209,9 @@ export const apply_side_effects = (prev, next, ui) => {
next.loading_external_imports_state != null
||
next.eval_modules_state != null
if(is_loading) {
if(next.rt_cxt?.io_trace_is_replay_aborted) {
reload_app_window()
} else if(is_loading) {
ui.calltree.clear_calltree()
clear_coloring(ui)
ui.render_debugger_loading(next)

View File

@@ -129,7 +129,7 @@ const init_app_window = w => {
// If by that time w.closed was set to true, then page was
// closed. Get back to using iframe
globalThis.app_window = iframe.contentWindow
reload_app_window(get_state())
reload_app_window()
} else {
add_load_handler()
}
@@ -140,7 +140,7 @@ const init_app_window = w => {
add_load_handler()
}
const reload_app_window = state => {
export const reload_app_window = (state = get_state()) => {
// after window location reload, `run_code` command will be fired.
globalThis.app_window.location = get_html_url(state)
}
@@ -155,7 +155,7 @@ const get_entrypoint_settings = () => {
export const exec_and_reload_app_window = (...exec_args) => {
exec(...exec_args)
reload_app_window(get_state())
reload_app_window()
}
export const open_directory = () => {

View File

@@ -39,7 +39,16 @@ const make_promise_with_rejector = cxt => {
return [p, rejector]
}
const do_run = function*(module_fns, cxt, io_trace){
export const run = gen_to_promise(function*(module_fns, cxt, io_trace) {
if(!cxt.window.__is_initialized) {
defineMultiversion(cxt.window)
apply_io_patches(cxt.window)
inject_leporello_api(cxt)
cxt.window.__is_initialized = true
} else {
throw new Error('illegal state')
}
let calltree
const calltree_node_by_loc = new Map(
@@ -137,30 +146,6 @@ const do_run = function*(module_fns, cxt, io_trace){
rt_cxt: cxt,
calltree_node_by_loc,
}
}
export const run = gen_to_promise(function*(module_fns, cxt, io_trace) {
if(!cxt.window.__is_initialized) {
defineMultiversion(cxt.window)
apply_io_patches(cxt.window)
inject_leporello_api(cxt)
cxt.window.__is_initialized = true
} else {
throw new Error('illegal state')
}
const result = yield* do_run(module_fns, cxt, io_trace)
if(result.rt_cxt.io_trace_is_replay_aborted) {
// TODO test next line
result.rt_cxt.is_recording_deferred_calls = false
// run again without io trace
// TODO reload app_window before second run
return yield* do_run(module_fns, cxt, null)
} else {
return result
}
})
const inject_leporello_api = cxt => {

View File

@@ -122,36 +122,48 @@ export const test_initial_state = (code, cursor_pos, options = {}) => {
)
}
export const test_initial_state_async = async (code, ...args) => {
const s = test_initial_state(code, ...args)
assert_equal(s.eval_modules_state != null, true)
const result = await s.eval_modules_state.promise
const wait_for_result = async state => {
assert_equal(state.eval_modules_state != null, true)
const result = await state.eval_modules_state.promise
return COMMANDS.eval_modules_finished(
s,
s,
state,
state,
result,
)
}
export const test_initial_state_async = async (code, ...args) => {
const s = test_initial_state(code, ...args)
return wait_for_result(s)
}
export const input = (s, code, index, options = {}) => {
if(typeof(options) != 'object') {
throw new Error('illegal state')
}
const {state, effects} = COMMANDS.input(s, code, index)
return {
state: run_code(state, options.app_window_patches),
effects,
const nextstate = run_code(state, options.app_window_patches)
if(nextstate.rt_cxt?.io_trace_is_replay_aborted) {
const with_clear_trace = run_code(
COMMANDS.clear_io_trace(nextstate),
options.app_window_patches
)
return { state: with_clear_trace, effects }
} else {
return { state: nextstate, effects }
}
}
export const input_async = async (...args) => {
const after_input = input(...args).state
const result = await after_input.eval_modules_state.promise
return COMMANDS.eval_modules_finished(
after_input,
after_input,
result,
)
export const input_async = async (s, code, index, options) => {
const after_input = input(s, code, index, options).state
const state = await wait_for_result(after_input)
if(state.rt_cxt?.io_trace_is_replay_aborted) {
return wait_for_result(
run_code(COMMANDS.clear_io_trace(state), options.app_window_patches)
)
} else {
return state
}
}
export const test_deferred_calls_state = code => {