pinokiod 7.1.68 → 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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinokiod",
3
- "version": "7.1.68",
3
+ "version": "7.1.70",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
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 = {}) {
@@ -5480,53 +5483,45 @@ class Server {
5480
5483
  return list
5481
5484
  }
5482
5485
  async check_router_up() {
5483
- let response
5484
- let config
5486
+ // check if caddy is runnign properly
5487
+ // try https://pinokio.localhost
5488
+ // if it works, proceed
5489
+ // if not, redirect
5490
+ let https_running = false
5485
5491
  try {
5486
5492
  let res = await axios.get(`http://127.0.0.1:2019/config/`, {
5487
5493
  timeout: 2000
5488
5494
  })
5489
- config = res.data
5490
- } catch (e) {
5491
- response = {
5492
- stage: "caddy_admin_unavailable",
5493
- error: "caddy admin unavailable",
5494
- detail: e && e.message ? e.message : String(e)
5495
+ let test = /pinokio\.localhost/.test(JSON.stringify(res.data))
5496
+ if (test) {
5497
+ https_running = true
5495
5498
  }
5499
+ } catch (e) {
5500
+ return { error: "caddy admin unavailable" }
5496
5501
  }
5497
- if (!response) {
5498
- if (config === null || typeof config === "undefined") {
5499
- response = {
5500
- stage: "caddy_config_empty",
5501
- error: "caddy config not yet loaded"
5502
- }
5503
- } else if (!/pinokio\.localhost/.test(JSON.stringify(config))) {
5504
- response = {
5505
- stage: "caddy_route_missing",
5506
- error: "pinokio.localhost missing from caddy config"
5507
- }
5508
- } else {
5509
- let router_running = false
5510
- let router = this.kernel.router.published()
5511
- for (let ip in router) {
5512
- let domains = router[ip]
5513
- if (domains.includes("pinokio.localhost")) {
5514
- router_running = true
5515
- break
5516
- }
5517
- }
5518
- if (!router_running) {
5519
- response = {
5520
- stage: "pinokio_router_missing",
5521
- error: "pinokio.localhost not yet published by Pinokio router"
5522
- }
5523
- }
5502
+ // console.log({ https_running })
5503
+ if (!https_running) {
5504
+ return { error: "pinokio.host not yet available" }
5505
+ }
5506
+
5507
+ // check if pinokio.localhost router is running
5508
+ let router_running = false
5509
+ let router = this.kernel.router.published()
5510
+ for(let ip in router) {
5511
+ let domains = router[ip]
5512
+ if (domains.includes("pinokio.localhost")) {
5513
+ router_running = true
5514
+ break
5524
5515
  }
5525
5516
  }
5526
- if (!response) {
5527
- response = { success: true, stage: "ready" }
5517
+ if (!router_running) {
5518
+ return { error: "pinokio.localhost not yet available" }
5528
5519
  }
5529
- return response
5520
+
5521
+ return { success: true }
5522
+ }
5523
+ async ensureSecureRouterReady(timeout = 120000, interval = 500) {
5524
+ return ensureSecureRouterReady(this, timeout, interval)
5530
5525
  }
5531
5526
  async start(options) {
5532
5527
  this.debug = false
@@ -5797,6 +5792,12 @@ class Server {
5797
5792
  phase: "initializing_environment"
5798
5793
  })
5799
5794
  await Environment.init({}, this.kernel)
5795
+ if (this.kernel && this.kernel.peer && this.kernel.peer.https_active) {
5796
+ setStartupStatus({
5797
+ phase: "waiting_for_secure_router"
5798
+ })
5799
+ await this.ensureSecureRouterReady()
5800
+ }
5800
5801
  setStartupStatus({
5801
5802
  sys_ready: this.getStartupStatus().sys_ready,
5802
5803
  managed_ready: true,
@@ -11438,8 +11439,36 @@ class Server {
11438
11439
  return
11439
11440
  }
11440
11441
 
11441
- const routerStatus = await this.check_router_up()
11442
- if (!routerStatus.success) {
11442
+ let https_running = false
11443
+ try {
11444
+ let res = await axios.get(`http://127.0.0.1:2019/config/`, {
11445
+ timeout: 2000
11446
+ })
11447
+ let test = /pinokio\.localhost/.test(JSON.stringify(res.data))
11448
+ if (test) {
11449
+ https_running = true
11450
+ }
11451
+ } catch (e) {
11452
+ console.log(e)
11453
+ }
11454
+ if (!https_running) {
11455
+ // res.json({ error: "pinokio.host not yet available" })
11456
+ res.redirect("/setup/connect?callback=/connect/" + req.params.provider)
11457
+ return
11458
+ }
11459
+
11460
+ // check if pinokio.localhost router is running
11461
+ let router_running = false
11462
+ let router = this.kernel.router.published()
11463
+ for(let ip in router) {
11464
+ let domains = router[ip]
11465
+ if (domains.includes("pinokio.localhost")) {
11466
+ router_running = true
11467
+ break
11468
+ }
11469
+ }
11470
+ if (!router_running) {
11471
+ // res.json({ error: "pinokio.localhost not yet available" })
11443
11472
  res.redirect("/setup/connect?callback=/connect/" + req.params.provider)
11444
11473
  return
11445
11474
  }
@@ -15422,6 +15451,9 @@ class Server {
15422
15451
  this.app.get("/pinokio/startup_status", ex((req, res) => {
15423
15452
  res.json(this.getStartupStatus())
15424
15453
  }))
15454
+ this.app.get("/pinokio/secure_router_debug", ex(async (req, res) => {
15455
+ res.json(await buildSecureRouterDebugSnapshot(this, this.secure_router_debug))
15456
+ }))
15425
15457
  this.app.get("/pinokio/requirements_ready", ex((req, res) => {
15426
15458
  res.json(this.getStartupStatus())
15427
15459
  }))
@@ -15557,13 +15589,6 @@ class Server {
15557
15589
  server_ready: true,
15558
15590
  phase: this.getStartupStatus().phase === "idle" ? "ready" : this.getStartupStatus().phase
15559
15591
  })
15560
- if (this.kernel && this.kernel.peer && this.kernel.peer.https_active) {
15561
- this.kernel.refresh(true).then(() => {
15562
- return this.check_router_up()
15563
- }).catch((error) => {
15564
- console.warn("[Pinokiod] initial secure router refresh failed", error && error.message ? error.message : error)
15565
- })
15566
- }
15567
15592
  resolve()
15568
15593
  });
15569
15594
  this.httpTerminator = createHttpTerminator({
@@ -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
+ })();
@@ -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,17 +244,45 @@ 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 ROUTER_STAGE_MESSAGES = {
247
- caddy_admin_unavailable: "Restarting Pinokio... (waiting for Caddy)",
248
- caddy_config_empty: "Restarting Pinokio... (publishing secure router)",
249
- caddy_route_missing: "Restarting Pinokio... (loading pinokio.localhost)",
250
- pinokio_router_missing: "Restarting Pinokio... (waiting for Pinokio router)"
251
- }
247
+ const waitDebug = window.PinokioSetupWaitDebug ? window.PinokioSetupWaitDebug.create(waitRoot) : null
248
+ let lastRouterStatus = null
249
+ let lastStartupStatus = null
250
+ let lastServerDebug = null
252
251
  const setWaitLabel = (message) => {
253
252
  if (waitLabel) {
254
253
  waitLabel.textContent = message
255
254
  }
256
255
  }
256
+ const pushWaitDebugEvent = (message) => {
257
+ if (waitDebug) {
258
+ waitDebug.event(message)
259
+ }
260
+ }
261
+ const renderWaitDebug = ({ startedAt, routerStatus, startupStatus, serverDebug } = {}) => {
262
+ if (typeof routerStatus !== "undefined") {
263
+ lastRouterStatus = routerStatus
264
+ }
265
+ if (typeof startupStatus !== "undefined") {
266
+ lastStartupStatus = startupStatus
267
+ }
268
+ if (typeof serverDebug !== "undefined") {
269
+ lastServerDebug = serverDebug
270
+ }
271
+ if (!waitDebug) {
272
+ return
273
+ }
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 })
284
+ }
285
+ }
257
286
  const showWaitError = (message) => {
258
287
  if (waitRoot) {
259
288
  waitRoot.innerHTML = `
@@ -265,6 +294,7 @@ document.addEventListener("DOMContentLoaded", async () => {
265
294
  <a class='btn' href='${location.href}'>Retry</a>
266
295
  </div>
267
296
  `
297
+ renderWaitDebug()
268
298
  } else {
269
299
  alert(message)
270
300
  }
@@ -272,6 +302,8 @@ document.addEventListener("DOMContentLoaded", async () => {
272
302
 
273
303
  try {
274
304
  setWaitLabel("Enabling secure localhost access...")
305
+ pushWaitDebugEvent("saving secure localhost flags")
306
+ renderWaitDebug()
275
307
  const networkResponse = await fetch("/network", {
276
308
  method: "post",
277
309
  headers: { "Content-Type": "application/json" },
@@ -285,8 +317,12 @@ document.addEventListener("DOMContentLoaded", async () => {
285
317
  if (networkResponse && networkResponse.error) {
286
318
  throw new Error(networkResponse.error)
287
319
  }
320
+ pushWaitDebugEvent("secure localhost flags saved")
321
+ renderWaitDebug()
288
322
 
289
323
  setWaitLabel("Restarting Pinokio...")
324
+ pushWaitDebugEvent("restart requested")
325
+ renderWaitDebug()
290
326
  try {
291
327
  await fetch("/restart", {
292
328
  method: "post"
@@ -298,13 +334,15 @@ document.addEventListener("DOMContentLoaded", async () => {
298
334
  const startedAt = Date.now()
299
335
  let lastKnownError = null
300
336
  let lastKnownPhase = null
337
+ renderWaitDebug({ startedAt })
301
338
 
302
339
  await new Promise((resolve, reject) => {
303
340
  const interval = setInterval(async () => {
304
341
  try {
305
- const [routerStatus, startupStatus] = await Promise.all([
342
+ const [routerStatus, startupStatus, serverDebug] = await Promise.all([
306
343
  fetch("/check_router_up").then((res) => res.json()),
307
- 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)
308
346
  ])
309
347
 
310
348
  if (routerStatus && routerStatus.success) {
@@ -319,16 +357,15 @@ document.addEventListener("DOMContentLoaded", async () => {
319
357
  if (startupStatus && startupStatus.error) {
320
358
  lastKnownError = startupStatus.error
321
359
  }
360
+ trackWaitDebug({ routerStatus, startupStatus })
322
361
  if (startupStatus && startupStatus.phase) {
323
- lastKnownPhase = (routerStatus && routerStatus.stage) || startupStatus.phase
324
- const routerStageMessage = routerStatus && routerStatus.stage
325
- ? ROUTER_STAGE_MESSAGES[routerStatus.stage]
326
- : null
327
- const phaseMessage = routerStageMessage || (startupStatus.phase === "ready"
362
+ lastKnownPhase = startupStatus.phase
363
+ const phaseMessage = startupStatus.phase === "ready"
328
364
  ? "Secure router is almost ready..."
329
- : `Restarting Pinokio... (${startupStatus.phase.replace(/_/g, " ")})`)
365
+ : `Restarting Pinokio... (${startupStatus.phase.replace(/_/g, " ")})`
330
366
  setWaitLabel(phaseMessage)
331
367
  }
368
+ renderWaitDebug({ startedAt, routerStatus, startupStatus, serverDebug })
332
369
 
333
370
  if (startupStatus && startupStatus.phase === "error") {
334
371
  clearInterval(interval)
@@ -339,10 +376,14 @@ document.addEventListener("DOMContentLoaded", async () => {
339
376
  if ((Date.now() - startedAt) >= WAIT_TIMEOUT_MS) {
340
377
  clearInterval(interval)
341
378
  const detail = lastKnownError || lastKnownPhase || "secure localhost router did not come up"
379
+ pushWaitDebugEvent(`timeout -> ${detail}`)
380
+ renderWaitDebug({ startedAt, routerStatus, startupStatus })
342
381
  reject(new Error(`Timed out waiting for restart: ${detail}`))
343
382
  }
344
383
  } catch (error) {
345
384
  lastKnownError = error && error.message ? error.message : String(error)
385
+ pushWaitDebugEvent(`poll error -> ${lastKnownError}`)
386
+ renderWaitDebug({ startedAt })
346
387
  if ((Date.now() - startedAt) >= WAIT_TIMEOUT_MS) {
347
388
  clearInterval(interval)
348
389
  reject(new Error(`Timed out waiting for restart: ${lastKnownError}`))