Async Workflows and Source Panels
Callback Router Panel
Use a typed callback map to route work while replay keeps the panel in order.
callback router
A callback map keeps branch logic explicit and lets replay show which handler updated the result.
Callback Router Panel
callback_router.ts
Replay: real traced execution (multi-file project)
type Mode = "status" | "refresh" | "archive";
type Handler = (mode: Mode) => string;
const mode: Mode = "status";
let access: string = "";
let handled: string = "";
const handlers: Record<Mode, Handler> = {
status: (current: Mode) => `handled:${current}`,
refresh: (current: Mode) => `cache:${current}`,
archive: (current: Mode) => `queue:${current}`
};
function checkAccess(current: Mode): void {
if (current === "archive") {
access = "review";
} else {
access = "ok";
}
}
checkAccess(mode);
handled = handlers[mode](mode);
console.log(`mode=${mode}`);
console.log(`access=${access}`);
console.log(handled);
type Mode = "status" | "refresh" | "archive";
type Handler = (mode: Mode) => string;
const mode: Mode = "refresh";
let access: string = "";
let handled: string = "";
const handlers: Record<Mode, Handler> = {
status: (current: Mode) => `handled:${current}`,
refresh: (current: Mode) => `cache:${current}`,
archive: (current: Mode) => `queue:${current}`
};
function checkAccess(current: Mode): void {
if (current === "archive") {
access = "review";
} else {
access = "ok";
}
}
checkAccess(mode);
handled = handlers[mode](mode);
console.log(`mode=${mode}`);
console.log(`access=${access}`);
console.log(handled);
type Mode = "status" | "refresh" | "archive";
type Handler = (mode: Mode) => string;
const mode: Mode = "archive";
let access: string = "";
let handled: string = "";
const handlers: Record<Mode, Handler> = {
status: (current: Mode) => `handled:${current}`,
refresh: (current: Mode) => `cache:${current}`,
archive: (current: Mode) => `queue:${current}`
};
function checkAccess(current: Mode): void {
if (current === "archive") {
access = "review";
} else {
access = "ok";
}
}
checkAccess(mode);
handled = handlers[mode](mode);
console.log(`mode=${mode}`);
console.log(`access=${access}`);
console.log(handled);
mode ← status, access ← (empty), handled ← (empty), handlers ← [object Object]
1type Mode = "status" | "refresh" | "archive";2type Handler = (mode: Mode) => string;34const mode→ status: Mode = "status"; //@mode="refresh", "archive"5let access→ (empty): string = "";6let handled→ (empty): string = "";78const handlers→ [object Object]: Record<Mode, Handler> = {9 status: (current: Mode) => `handled:${current}`,10 refresh: (current: Mode) => `cache:${current}`,11 archive: (current: Mode) => `queue:${current}`12};1314function checkAccess(current: Mode): void {15 if (current === "archive") {16 access = "review";17 } else {18 access = "ok";19 }20}2122checkAccess(modestatus);23handled = handlers[mode](mode);function checkAccess(current: Mode): void
11 archive: (current: Mode) => `queue:${current}`12};1314function checkAccess(currentstatus: Mode): void {15 if (current === "archive") {handled ← handled:status
19 }20}2122checkAccess(modestatus);23handled = handlers[object Object][modestatus](mode);2425console.log(`mode=${modestatus}`);26console.log(`access=${accessok}`);27console.log(handledhandled:status);outputmode=status access=ok handled:status
mode ← refresh, access ← (empty), handled ← (empty), handlers ← [object Object]
1type Mode = "status" | "refresh" | "archive";2type Handler = (mode: Mode) => string;34const mode→ refresh: Mode = "refresh";5let access→ (empty): string = "";6let handled→ (empty): string = "";78const handlers→ [object Object]: Record<Mode, Handler> = {9 status: (current: Mode) => `handled:${current}`,10 refresh: (current: Mode) => `cache:${current}`,11 archive: (current: Mode) => `queue:${current}`12};1314function checkAccess(current: Mode): void {15 if (current === "archive") {16 access = "review";17 } else {18 access = "ok";19 }20}2122checkAccess(moderefresh);23handled = handlers[mode](mode);function checkAccess(current: Mode): void
11 archive: (current: Mode) => `queue:${current}`12};1314function checkAccess(currentrefresh: Mode): void {15 if (current === "archive") {handled ← cache:refresh
19 }20}2122checkAccess(moderefresh);23handled = handlers[object Object][moderefresh](mode);2425console.log(`mode=${moderefresh}`);26console.log(`access=${accessok}`);27console.log(handledcache:refresh);outputmode=refresh access=ok cache:refresh
mode ← archive, access ← (empty), handled ← (empty), handlers ← [object Object]
1type Mode = "status" | "refresh" | "archive";2type Handler = (mode: Mode) => string;34const mode→ archive: Mode = "archive";5let access→ (empty): string = "";6let handled→ (empty): string = "";78const handlers→ [object Object]: Record<Mode, Handler> = {9 status: (current: Mode) => `handled:${current}`,10 refresh: (current: Mode) => `cache:${current}`,11 archive: (current: Mode) => `queue:${current}`12};1314function checkAccess(current: Mode): void {15 if (current === "archive") {16 access = "review";17 } else {18 access = "ok";19 }20}2122checkAccess(modearchive);23handled = handlers[mode](mode);function checkAccess(current: Mode): void
11 archive: (current: Mode) => `queue:${current}`12};1314function checkAccess(currentarchive: Mode): void {15 if (current === "archive") {if (current === "archive")
14function checkAccess(current: Mode): void {15 if (currentarchive === "archive") {16 access = "review";17 } else {handled ← queue:archive
19 }20}2122checkAccess(modearchive);23handled = handlers[object Object][modearchive](mode);2425console.log(`mode=${modearchive}`);26console.log(`access=${accessreview}`);27console.log(handledqueue:archive);outputmode=archive access=review queue:archive