pinokiod 7.1.69 → 7.1.70
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/server/index.js +7 -36
- package/server/lib/secure_router_debug.js +116 -0
- package/server/lib/secure_router_ready.js +96 -0
- package/server/public/setup-wait-debug.js +108 -0
- package/server/views/setup.ejs +31 -74
package/package.json
CHANGED
package/server/index.js
CHANGED
|
@@ -79,6 +79,8 @@ const { createInjectRouter, resolveInjectList } = require("./lib/inject_router")
|
|
|
79
79
|
const { createTaskPackageService } = require("./lib/task_packages")
|
|
80
80
|
const { createTaskWorkspaceLinkService } = require("./lib/task_workspace_links")
|
|
81
81
|
const { createContentValidationService } = require("./lib/content_validation")
|
|
82
|
+
const { buildSecureRouterDebugSnapshot, createSecureRouterDebugStore } = require("./lib/secure_router_debug")
|
|
83
|
+
const { ensureSecureRouterReady } = require("./lib/secure_router_ready")
|
|
82
84
|
const AppRegistryService = require("./lib/app_registry")
|
|
83
85
|
const AppLogService = require("./lib/app_logs")
|
|
84
86
|
const AppSearchService = require("./lib/app_search")
|
|
@@ -253,6 +255,7 @@ class Server {
|
|
|
253
255
|
updated_at: new Date().toISOString()
|
|
254
256
|
}
|
|
255
257
|
this.startup_status_run_id = 0
|
|
258
|
+
this.secure_router_debug = createSecureRouterDebugStore()
|
|
256
259
|
this.installFatalHandlers()
|
|
257
260
|
}
|
|
258
261
|
setStartupStatus(patch = {}) {
|
|
@@ -5518,42 +5521,7 @@ class Server {
|
|
|
5518
5521
|
return { success: true }
|
|
5519
5522
|
}
|
|
5520
5523
|
async ensureSecureRouterReady(timeout = 120000, interval = 500) {
|
|
5521
|
-
|
|
5522
|
-
return { success: true, stage: "disabled" }
|
|
5523
|
-
}
|
|
5524
|
-
const caddy = this.kernel && this.kernel.bin && this.kernel.bin.mod
|
|
5525
|
-
? this.kernel.bin.mod.caddy
|
|
5526
|
-
: null
|
|
5527
|
-
const deadline = Date.now() + timeout
|
|
5528
|
-
let startedCaddyManually = false
|
|
5529
|
-
let refreshedRouter = false
|
|
5530
|
-
let lastStatus = null
|
|
5531
|
-
while (Date.now() < deadline) {
|
|
5532
|
-
lastStatus = await this.check_router_up()
|
|
5533
|
-
if (lastStatus && lastStatus.success) {
|
|
5534
|
-
return lastStatus
|
|
5535
|
-
}
|
|
5536
|
-
if (
|
|
5537
|
-
lastStatus &&
|
|
5538
|
-
lastStatus.error === "caddy admin unavailable" &&
|
|
5539
|
-
!startedCaddyManually &&
|
|
5540
|
-
caddy &&
|
|
5541
|
-
typeof caddy.start === "function"
|
|
5542
|
-
) {
|
|
5543
|
-
startedCaddyManually = true
|
|
5544
|
-
await caddy.start()
|
|
5545
|
-
continue
|
|
5546
|
-
}
|
|
5547
|
-
if (!refreshedRouter) {
|
|
5548
|
-
refreshedRouter = true
|
|
5549
|
-
await this.kernel.refresh(true).catch(() => {})
|
|
5550
|
-
continue
|
|
5551
|
-
}
|
|
5552
|
-
await new Promise((resolve) => {
|
|
5553
|
-
setTimeout(resolve, interval)
|
|
5554
|
-
})
|
|
5555
|
-
}
|
|
5556
|
-
throw new Error(lastStatus && lastStatus.error ? lastStatus.error : "secure router did not come up")
|
|
5524
|
+
return ensureSecureRouterReady(this, timeout, interval)
|
|
5557
5525
|
}
|
|
5558
5526
|
async start(options) {
|
|
5559
5527
|
this.debug = false
|
|
@@ -15483,6 +15451,9 @@ class Server {
|
|
|
15483
15451
|
this.app.get("/pinokio/startup_status", ex((req, res) => {
|
|
15484
15452
|
res.json(this.getStartupStatus())
|
|
15485
15453
|
}))
|
|
15454
|
+
this.app.get("/pinokio/secure_router_debug", ex(async (req, res) => {
|
|
15455
|
+
res.json(await buildSecureRouterDebugSnapshot(this, this.secure_router_debug))
|
|
15456
|
+
}))
|
|
15486
15457
|
this.app.get("/pinokio/requirements_ready", ex((req, res) => {
|
|
15487
15458
|
res.json(this.getStartupStatus())
|
|
15488
15459
|
}))
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
function createSecureRouterDebugStore() {
|
|
2
|
+
return {
|
|
3
|
+
events: [],
|
|
4
|
+
state: {
|
|
5
|
+
active: false,
|
|
6
|
+
started_at: null,
|
|
7
|
+
updated_at: null,
|
|
8
|
+
last_status: null,
|
|
9
|
+
caddy_start_attempted: false,
|
|
10
|
+
caddy_start_finished: false,
|
|
11
|
+
caddy_start_error: null,
|
|
12
|
+
refresh_attempted: false,
|
|
13
|
+
refresh_finished: false,
|
|
14
|
+
refresh_error: null,
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function clone(value) {
|
|
20
|
+
return JSON.parse(JSON.stringify(value))
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function recordSecureRouterDebug(store, message, patch = {}) {
|
|
24
|
+
if (!store) {
|
|
25
|
+
return
|
|
26
|
+
}
|
|
27
|
+
const timestamp = new Date().toISOString()
|
|
28
|
+
store.state = {
|
|
29
|
+
...(store.state || {}),
|
|
30
|
+
...patch,
|
|
31
|
+
updated_at: timestamp
|
|
32
|
+
}
|
|
33
|
+
store.events.push({
|
|
34
|
+
at: timestamp,
|
|
35
|
+
message
|
|
36
|
+
})
|
|
37
|
+
if (store.events.length > 20) {
|
|
38
|
+
store.events.shift()
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async function buildSecureRouterDebugSnapshot(server, store) {
|
|
43
|
+
const kernel = server && server.kernel ? server.kernel : null
|
|
44
|
+
const peer = kernel && kernel.peer ? kernel.peer : null
|
|
45
|
+
const router = kernel && kernel.router && typeof kernel.router.published === "function"
|
|
46
|
+
? (kernel.router.published() || {})
|
|
47
|
+
: {}
|
|
48
|
+
const routerDialKeys = Object.keys(router)
|
|
49
|
+
const hasPinokioLocalhost = routerDialKeys.some((dial) => {
|
|
50
|
+
const domains = Array.isArray(router[dial]) ? router[dial] : []
|
|
51
|
+
return domains.includes("pinokio.localhost")
|
|
52
|
+
})
|
|
53
|
+
const caddy = kernel && kernel.bin && kernel.bin.mod
|
|
54
|
+
? kernel.bin.mod.caddy
|
|
55
|
+
: null
|
|
56
|
+
let caddyInstalled = null
|
|
57
|
+
let caddyRunning = null
|
|
58
|
+
try {
|
|
59
|
+
if (caddy && typeof caddy.installed === "function") {
|
|
60
|
+
caddyInstalled = await caddy.installed()
|
|
61
|
+
}
|
|
62
|
+
} catch (error) {
|
|
63
|
+
caddyInstalled = { error: error && error.message ? error.message : String(error) }
|
|
64
|
+
}
|
|
65
|
+
try {
|
|
66
|
+
if (caddy && typeof caddy.running === "function") {
|
|
67
|
+
caddyRunning = await caddy.running()
|
|
68
|
+
}
|
|
69
|
+
} catch (error) {
|
|
70
|
+
caddyRunning = { error: error && error.message ? error.message : String(error) }
|
|
71
|
+
}
|
|
72
|
+
const startupStatus = server && typeof server.getStartupStatus === "function"
|
|
73
|
+
? server.getStartupStatus()
|
|
74
|
+
: null
|
|
75
|
+
const state = store && store.state ? clone(store.state) : {}
|
|
76
|
+
const events = store && Array.isArray(store.events) ? clone(store.events) : []
|
|
77
|
+
return {
|
|
78
|
+
wait: state,
|
|
79
|
+
flags: {
|
|
80
|
+
peer_active: peer ? !!peer.peer_active : null,
|
|
81
|
+
https_active: peer ? !!peer.https_active : null,
|
|
82
|
+
active: peer ? !!peer.active : null,
|
|
83
|
+
},
|
|
84
|
+
caddy: {
|
|
85
|
+
installed: caddyInstalled,
|
|
86
|
+
running: caddyRunning,
|
|
87
|
+
start_attempted: !!state.caddy_start_attempted,
|
|
88
|
+
start_finished: !!state.caddy_start_finished,
|
|
89
|
+
start_error: state.caddy_start_error || null,
|
|
90
|
+
},
|
|
91
|
+
peer: {
|
|
92
|
+
host: peer && peer.host ? peer.host : null,
|
|
93
|
+
name: peer && peer.name ? peer.name : null,
|
|
94
|
+
has_info: !!(peer && peer.info),
|
|
95
|
+
has_host_info: !!(peer && peer.info && peer.host && peer.info[peer.host]),
|
|
96
|
+
refreshing: !!(peer && peer.refreshing),
|
|
97
|
+
},
|
|
98
|
+
router: {
|
|
99
|
+
published_count: routerDialKeys.length,
|
|
100
|
+
published_dials: routerDialKeys.slice(0, 10),
|
|
101
|
+
has_pinokio_localhost: hasPinokioLocalhost,
|
|
102
|
+
refresh_attempted: !!state.refresh_attempted,
|
|
103
|
+
refresh_finished: !!state.refresh_finished,
|
|
104
|
+
refresh_error: state.refresh_error || null,
|
|
105
|
+
last_status: state.last_status || null,
|
|
106
|
+
},
|
|
107
|
+
startup: startupStatus,
|
|
108
|
+
events
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
module.exports = {
|
|
113
|
+
buildSecureRouterDebugSnapshot,
|
|
114
|
+
createSecureRouterDebugStore,
|
|
115
|
+
recordSecureRouterDebug,
|
|
116
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
const { createSecureRouterDebugStore, recordSecureRouterDebug } = require("./secure_router_debug")
|
|
2
|
+
|
|
3
|
+
async function ensureSecureRouterReady(server, timeout = 120000, interval = 500) {
|
|
4
|
+
if (!(server.kernel && server.kernel.peer && server.kernel.peer.https_active)) {
|
|
5
|
+
return { success: true, stage: "disabled" }
|
|
6
|
+
}
|
|
7
|
+
server.secure_router_debug = createSecureRouterDebugStore()
|
|
8
|
+
recordSecureRouterDebug(server.secure_router_debug, "wait started", {
|
|
9
|
+
active: true,
|
|
10
|
+
started_at: new Date().toISOString(),
|
|
11
|
+
last_status: null,
|
|
12
|
+
caddy_start_attempted: false,
|
|
13
|
+
caddy_start_finished: false,
|
|
14
|
+
caddy_start_error: null,
|
|
15
|
+
refresh_attempted: false,
|
|
16
|
+
refresh_finished: false,
|
|
17
|
+
refresh_error: null,
|
|
18
|
+
})
|
|
19
|
+
const caddy = server.kernel && server.kernel.bin && server.kernel.bin.mod
|
|
20
|
+
? server.kernel.bin.mod.caddy
|
|
21
|
+
: null
|
|
22
|
+
const deadline = Date.now() + timeout
|
|
23
|
+
let startedCaddyManually = false
|
|
24
|
+
let refreshedRouter = false
|
|
25
|
+
let lastStatus = null
|
|
26
|
+
let lastStatusSummary = null
|
|
27
|
+
while (Date.now() < deadline) {
|
|
28
|
+
lastStatus = await server.check_router_up()
|
|
29
|
+
const statusSummary = lastStatus && lastStatus.success
|
|
30
|
+
? "success"
|
|
31
|
+
: (lastStatus && lastStatus.error ? lastStatus.error : JSON.stringify(lastStatus))
|
|
32
|
+
if (statusSummary !== lastStatusSummary) {
|
|
33
|
+
lastStatusSummary = statusSummary
|
|
34
|
+
recordSecureRouterDebug(server.secure_router_debug, `check_router_up -> ${statusSummary}`, {
|
|
35
|
+
last_status: lastStatus
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
if (lastStatus && lastStatus.success) {
|
|
39
|
+
recordSecureRouterDebug(server.secure_router_debug, "wait success", {
|
|
40
|
+
active: false
|
|
41
|
+
})
|
|
42
|
+
return lastStatus
|
|
43
|
+
}
|
|
44
|
+
if (
|
|
45
|
+
lastStatus &&
|
|
46
|
+
lastStatus.error === "caddy admin unavailable" &&
|
|
47
|
+
!startedCaddyManually &&
|
|
48
|
+
caddy &&
|
|
49
|
+
typeof caddy.start === "function"
|
|
50
|
+
) {
|
|
51
|
+
startedCaddyManually = true
|
|
52
|
+
recordSecureRouterDebug(server.secure_router_debug, "manual caddy.start() attempted", {
|
|
53
|
+
caddy_start_attempted: true
|
|
54
|
+
})
|
|
55
|
+
try {
|
|
56
|
+
await caddy.start()
|
|
57
|
+
recordSecureRouterDebug(server.secure_router_debug, "manual caddy.start() finished", {
|
|
58
|
+
caddy_start_finished: true
|
|
59
|
+
})
|
|
60
|
+
} catch (e) {
|
|
61
|
+
recordSecureRouterDebug(server.secure_router_debug, "manual caddy.start() failed", {
|
|
62
|
+
caddy_start_error: e && e.message ? e.message : String(e)
|
|
63
|
+
})
|
|
64
|
+
throw e
|
|
65
|
+
}
|
|
66
|
+
continue
|
|
67
|
+
}
|
|
68
|
+
if (!refreshedRouter) {
|
|
69
|
+
refreshedRouter = true
|
|
70
|
+
recordSecureRouterDebug(server.secure_router_debug, "kernel.refresh(true) attempted", {
|
|
71
|
+
refresh_attempted: true
|
|
72
|
+
})
|
|
73
|
+
await server.kernel.refresh(true).then(() => {
|
|
74
|
+
recordSecureRouterDebug(server.secure_router_debug, "kernel.refresh(true) finished", {
|
|
75
|
+
refresh_finished: true
|
|
76
|
+
})
|
|
77
|
+
}).catch((e) => {
|
|
78
|
+
recordSecureRouterDebug(server.secure_router_debug, "kernel.refresh(true) failed", {
|
|
79
|
+
refresh_error: e && e.message ? e.message : String(e)
|
|
80
|
+
})
|
|
81
|
+
})
|
|
82
|
+
continue
|
|
83
|
+
}
|
|
84
|
+
await new Promise((resolve) => {
|
|
85
|
+
setTimeout(resolve, interval)
|
|
86
|
+
})
|
|
87
|
+
}
|
|
88
|
+
recordSecureRouterDebug(server.secure_router_debug, "wait timeout", {
|
|
89
|
+
active: false
|
|
90
|
+
})
|
|
91
|
+
throw new Error(lastStatus && lastStatus.error ? lastStatus.error : "secure router did not come up")
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
module.exports = {
|
|
95
|
+
ensureSecureRouterReady,
|
|
96
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
(function () {
|
|
2
|
+
const HISTORY_LIMIT = 12
|
|
3
|
+
|
|
4
|
+
function create(waitRoot) {
|
|
5
|
+
const state = {
|
|
6
|
+
events: [],
|
|
7
|
+
phase: null,
|
|
8
|
+
router: null,
|
|
9
|
+
startupError: null,
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function ensurePanel() {
|
|
13
|
+
if (!waitRoot) {
|
|
14
|
+
return null
|
|
15
|
+
}
|
|
16
|
+
let panel = waitRoot.querySelector(".wait-debug")
|
|
17
|
+
if (!panel) {
|
|
18
|
+
panel = document.createElement("div")
|
|
19
|
+
panel.className = "wait-debug"
|
|
20
|
+
panel.style.marginTop = "16px"
|
|
21
|
+
panel.style.padding = "12px"
|
|
22
|
+
panel.style.border = "1px solid rgba(255,255,255,0.12)"
|
|
23
|
+
panel.style.borderRadius = "8px"
|
|
24
|
+
panel.style.background = "rgba(255,255,255,0.04)"
|
|
25
|
+
panel.style.textAlign = "left"
|
|
26
|
+
panel.innerHTML = [
|
|
27
|
+
'<div style="font-size:12px;font-weight:600;letter-spacing:0.04em;text-transform:uppercase;opacity:0.75;margin-bottom:8px;">Debug</div>',
|
|
28
|
+
'<pre class="wait-debug-body" style="margin:0;text-align:left;white-space:pre-wrap;word-break:break-word;font-size:12px;line-height:1.5;opacity:0.9;"></pre>'
|
|
29
|
+
].join("")
|
|
30
|
+
waitRoot.appendChild(panel)
|
|
31
|
+
}
|
|
32
|
+
return panel.querySelector(".wait-debug-body")
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function event(message) {
|
|
36
|
+
const timestamp = new Date().toLocaleTimeString()
|
|
37
|
+
const entry = `[${timestamp}] ${message}`
|
|
38
|
+
if (state.events[state.events.length - 1] !== entry) {
|
|
39
|
+
state.events.push(entry)
|
|
40
|
+
if (state.events.length > HISTORY_LIMIT) {
|
|
41
|
+
state.events.shift()
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function track({ routerStatus, startupStatus } = {}) {
|
|
47
|
+
if (startupStatus && startupStatus.phase && startupStatus.phase !== state.phase) {
|
|
48
|
+
state.phase = startupStatus.phase
|
|
49
|
+
event(`phase -> ${startupStatus.phase}`)
|
|
50
|
+
}
|
|
51
|
+
const routerSummary = routerStatus
|
|
52
|
+
? (routerStatus.success ? "success" : (routerStatus.error || JSON.stringify(routerStatus)))
|
|
53
|
+
: null
|
|
54
|
+
if (routerSummary && routerSummary !== state.router) {
|
|
55
|
+
state.router = routerSummary
|
|
56
|
+
event(`router -> ${routerSummary}`)
|
|
57
|
+
}
|
|
58
|
+
if (startupStatus && startupStatus.error && startupStatus.error !== state.startupError) {
|
|
59
|
+
state.startupError = startupStatus.error
|
|
60
|
+
event(`startup error -> ${startupStatus.error}`)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function render({ startedAt, routerStatus, startupStatus, serverDebug } = {}) {
|
|
65
|
+
const body = ensurePanel()
|
|
66
|
+
if (!body) {
|
|
67
|
+
return
|
|
68
|
+
}
|
|
69
|
+
const elapsedSeconds = startedAt ? Math.max(0, Math.floor((Date.now() - startedAt) / 1000)) : 0
|
|
70
|
+
const lines = [
|
|
71
|
+
`Elapsed: ${elapsedSeconds}s`,
|
|
72
|
+
`Startup phase: ${startupStatus && startupStatus.phase ? startupStatus.phase : "-"}`,
|
|
73
|
+
`Startup error: ${startupStatus && startupStatus.error ? startupStatus.error : "-"}`,
|
|
74
|
+
`Router check: ${routerStatus ? JSON.stringify(routerStatus) : "-"}`,
|
|
75
|
+
]
|
|
76
|
+
if (serverDebug) {
|
|
77
|
+
lines.push(`Flags: ${JSON.stringify(serverDebug.flags || null)}`)
|
|
78
|
+
lines.push(`Caddy: ${JSON.stringify(serverDebug.caddy || null)}`)
|
|
79
|
+
lines.push(`Peer: ${JSON.stringify(serverDebug.peer || null)}`)
|
|
80
|
+
lines.push(`Router: ${JSON.stringify(serverDebug.router || null)}`)
|
|
81
|
+
lines.push(`Wait: ${JSON.stringify(serverDebug.wait || null)}`)
|
|
82
|
+
}
|
|
83
|
+
if (state.events.length > 0) {
|
|
84
|
+
lines.push("")
|
|
85
|
+
lines.push("Recent page events:")
|
|
86
|
+
lines.push(...state.events)
|
|
87
|
+
}
|
|
88
|
+
if (serverDebug && Array.isArray(serverDebug.events) && serverDebug.events.length > 0) {
|
|
89
|
+
lines.push("")
|
|
90
|
+
lines.push("Recent server events:")
|
|
91
|
+
for (const entry of serverDebug.events) {
|
|
92
|
+
lines.push(`[${entry.at}] ${entry.message}`)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
body.textContent = lines.join("\n")
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
event,
|
|
100
|
+
render,
|
|
101
|
+
track,
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
window.PinokioSetupWaitDebug = {
|
|
106
|
+
create
|
|
107
|
+
}
|
|
108
|
+
})();
|
package/server/views/setup.ejs
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
<% if (agent === "electron") { %>
|
|
14
14
|
<link href="/electron.css" rel="stylesheet"/>
|
|
15
15
|
<% } %>
|
|
16
|
+
<script src="/setup-wait-debug.js"></script>
|
|
16
17
|
<style>
|
|
17
18
|
html {
|
|
18
19
|
scroll-behavior: smooth;
|
|
@@ -243,75 +244,44 @@ document.addEventListener("DOMContentLoaded", async () => {
|
|
|
243
244
|
const waitRoot = document.querySelector(".requirements .content")
|
|
244
245
|
const waitLabel = document.querySelector(".requirements .content .loading span")
|
|
245
246
|
const WAIT_TIMEOUT_MS = 120000
|
|
246
|
-
const
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
router: null,
|
|
251
|
-
startupError: null,
|
|
252
|
-
}
|
|
247
|
+
const waitDebug = window.PinokioSetupWaitDebug ? window.PinokioSetupWaitDebug.create(waitRoot) : null
|
|
248
|
+
let lastRouterStatus = null
|
|
249
|
+
let lastStartupStatus = null
|
|
250
|
+
let lastServerDebug = null
|
|
253
251
|
const setWaitLabel = (message) => {
|
|
254
252
|
if (waitLabel) {
|
|
255
253
|
waitLabel.textContent = message
|
|
256
254
|
}
|
|
257
255
|
}
|
|
258
256
|
const pushWaitDebugEvent = (message) => {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
if (waitDebugState.events[waitDebugState.events.length - 1] !== entry) {
|
|
262
|
-
waitDebugState.events.push(entry)
|
|
263
|
-
if (waitDebugState.events.length > WAIT_DEBUG_HISTORY_LIMIT) {
|
|
264
|
-
waitDebugState.events.shift()
|
|
265
|
-
}
|
|
257
|
+
if (waitDebug) {
|
|
258
|
+
waitDebug.event(message)
|
|
266
259
|
}
|
|
267
260
|
}
|
|
268
|
-
const
|
|
269
|
-
if (
|
|
270
|
-
|
|
261
|
+
const renderWaitDebug = ({ startedAt, routerStatus, startupStatus, serverDebug } = {}) => {
|
|
262
|
+
if (typeof routerStatus !== "undefined") {
|
|
263
|
+
lastRouterStatus = routerStatus
|
|
271
264
|
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
panel = document.createElement("div")
|
|
275
|
-
panel.className = "wait-debug"
|
|
276
|
-
panel.style.marginTop = "16px"
|
|
277
|
-
panel.style.padding = "12px"
|
|
278
|
-
panel.style.border = "1px solid rgba(255,255,255,0.12)"
|
|
279
|
-
panel.style.borderRadius = "8px"
|
|
280
|
-
panel.style.background = "rgba(255,255,255,0.04)"
|
|
281
|
-
panel.style.textAlign = "left"
|
|
282
|
-
panel.innerHTML = `
|
|
283
|
-
<div style="font-size:12px;font-weight:600;letter-spacing:0.04em;text-transform:uppercase;opacity:0.75;margin-bottom:8px;">Debug</div>
|
|
284
|
-
<pre class="wait-debug-body" style="margin:0;text-align:left;white-space:pre-wrap;word-break:break-word;font-size:12px;line-height:1.5;opacity:0.9;"></pre>
|
|
285
|
-
`
|
|
286
|
-
waitRoot.appendChild(panel)
|
|
265
|
+
if (typeof startupStatus !== "undefined") {
|
|
266
|
+
lastStartupStatus = startupStatus
|
|
287
267
|
}
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
if (!body) {
|
|
268
|
+
if (typeof serverDebug !== "undefined") {
|
|
269
|
+
lastServerDebug = serverDebug
|
|
270
|
+
}
|
|
271
|
+
if (!waitDebug) {
|
|
293
272
|
return
|
|
294
273
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
requirements_pending: startupStatus.requirements_pending,
|
|
306
|
-
updated_at: startupStatus.updated_at || null
|
|
307
|
-
}) : "-"}`,
|
|
308
|
-
]
|
|
309
|
-
if (waitDebugState.events.length > 0) {
|
|
310
|
-
lines.push("")
|
|
311
|
-
lines.push("Recent events:")
|
|
312
|
-
lines.push(...waitDebugState.events)
|
|
274
|
+
waitDebug.render({
|
|
275
|
+
startedAt,
|
|
276
|
+
routerStatus: lastRouterStatus,
|
|
277
|
+
startupStatus: lastStartupStatus,
|
|
278
|
+
serverDebug: lastServerDebug,
|
|
279
|
+
})
|
|
280
|
+
}
|
|
281
|
+
const trackWaitDebug = ({ routerStatus, startupStatus } = {}) => {
|
|
282
|
+
if (waitDebug) {
|
|
283
|
+
waitDebug.track({ routerStatus, startupStatus })
|
|
313
284
|
}
|
|
314
|
-
body.textContent = lines.join("\n")
|
|
315
285
|
}
|
|
316
286
|
const showWaitError = (message) => {
|
|
317
287
|
if (waitRoot) {
|
|
@@ -369,9 +339,10 @@ document.addEventListener("DOMContentLoaded", async () => {
|
|
|
369
339
|
await new Promise((resolve, reject) => {
|
|
370
340
|
const interval = setInterval(async () => {
|
|
371
341
|
try {
|
|
372
|
-
const [routerStatus, startupStatus] = await Promise.all([
|
|
342
|
+
const [routerStatus, startupStatus, serverDebug] = await Promise.all([
|
|
373
343
|
fetch("/check_router_up").then((res) => res.json()),
|
|
374
|
-
fetch("/pinokio/startup_status").then((res) => res.json()).catch(() => null)
|
|
344
|
+
fetch("/pinokio/startup_status").then((res) => res.json()).catch(() => null),
|
|
345
|
+
fetch("/pinokio/secure_router_debug").then((res) => res.json()).catch(() => null)
|
|
375
346
|
])
|
|
376
347
|
|
|
377
348
|
if (routerStatus && routerStatus.success) {
|
|
@@ -386,21 +357,7 @@ document.addEventListener("DOMContentLoaded", async () => {
|
|
|
386
357
|
if (startupStatus && startupStatus.error) {
|
|
387
358
|
lastKnownError = startupStatus.error
|
|
388
359
|
}
|
|
389
|
-
|
|
390
|
-
waitDebugState.phase = startupStatus.phase
|
|
391
|
-
pushWaitDebugEvent(`phase -> ${startupStatus.phase}`)
|
|
392
|
-
}
|
|
393
|
-
const routerSummary = routerStatus
|
|
394
|
-
? (routerStatus.success ? "success" : (routerStatus.error || JSON.stringify(routerStatus)))
|
|
395
|
-
: null
|
|
396
|
-
if (routerSummary && routerSummary !== waitDebugState.router) {
|
|
397
|
-
waitDebugState.router = routerSummary
|
|
398
|
-
pushWaitDebugEvent(`router -> ${routerSummary}`)
|
|
399
|
-
}
|
|
400
|
-
if (startupStatus && startupStatus.error && startupStatus.error !== waitDebugState.startupError) {
|
|
401
|
-
waitDebugState.startupError = startupStatus.error
|
|
402
|
-
pushWaitDebugEvent(`startup error -> ${startupStatus.error}`)
|
|
403
|
-
}
|
|
360
|
+
trackWaitDebug({ routerStatus, startupStatus })
|
|
404
361
|
if (startupStatus && startupStatus.phase) {
|
|
405
362
|
lastKnownPhase = startupStatus.phase
|
|
406
363
|
const phaseMessage = startupStatus.phase === "ready"
|
|
@@ -408,7 +365,7 @@ document.addEventListener("DOMContentLoaded", async () => {
|
|
|
408
365
|
: `Restarting Pinokio... (${startupStatus.phase.replace(/_/g, " ")})`
|
|
409
366
|
setWaitLabel(phaseMessage)
|
|
410
367
|
}
|
|
411
|
-
renderWaitDebug({ startedAt, routerStatus, startupStatus })
|
|
368
|
+
renderWaitDebug({ startedAt, routerStatus, startupStatus, serverDebug })
|
|
412
369
|
|
|
413
370
|
if (startupStatus && startupStatus.phase === "error") {
|
|
414
371
|
clearInterval(interval)
|