@cavelang/cli 0.34.0 → 0.36.0

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.
Files changed (344) hide show
  1. package/README.md +225 -13
  2. package/dist/internal/act/action.js +2 -1
  3. package/dist/internal/act/action.js.map +1 -1
  4. package/dist/internal/act/declare.d.ts.map +1 -1
  5. package/dist/internal/act/declare.js +82 -53
  6. package/dist/internal/act/declare.js.map +1 -1
  7. package/dist/internal/act/engine.d.ts +4 -3
  8. package/dist/internal/act/engine.d.ts.map +1 -1
  9. package/dist/internal/act/engine.js +121 -32
  10. package/dist/internal/act/engine.js.map +1 -1
  11. package/dist/internal/automate/cancellation.d.ts +3 -0
  12. package/dist/internal/automate/cancellation.d.ts.map +1 -0
  13. package/dist/internal/automate/cancellation.js +38 -0
  14. package/dist/internal/automate/cancellation.js.map +1 -0
  15. package/dist/internal/automate/declare.d.ts.map +1 -1
  16. package/dist/internal/automate/declare.js +49 -24
  17. package/dist/internal/automate/declare.js.map +1 -1
  18. package/dist/internal/automate/engine.d.ts +7 -3
  19. package/dist/internal/automate/engine.d.ts.map +1 -1
  20. package/dist/internal/automate/engine.js +196 -93
  21. package/dist/internal/automate/engine.js.map +1 -1
  22. package/dist/internal/automate/error-message.d.ts +3 -0
  23. package/dist/internal/automate/error-message.d.ts.map +1 -0
  24. package/dist/internal/automate/error-message.js +10 -0
  25. package/dist/internal/automate/error-message.js.map +1 -0
  26. package/dist/internal/automate/main.d.ts.map +1 -1
  27. package/dist/internal/automate/main.js +240 -35
  28. package/dist/internal/automate/main.js.map +1 -1
  29. package/dist/internal/automate/options.d.ts +4 -0
  30. package/dist/internal/automate/options.d.ts.map +1 -0
  31. package/dist/internal/automate/options.js +19 -0
  32. package/dist/internal/automate/options.js.map +1 -0
  33. package/dist/internal/connect/declared.d.ts +204 -0
  34. package/dist/internal/connect/declared.d.ts.map +1 -0
  35. package/dist/internal/connect/declared.js +610 -0
  36. package/dist/internal/connect/declared.js.map +1 -0
  37. package/dist/internal/connect/error-message.d.ts +3 -0
  38. package/dist/internal/connect/error-message.d.ts.map +1 -0
  39. package/dist/internal/connect/error-message.js +10 -0
  40. package/dist/internal/connect/error-message.js.map +1 -0
  41. package/dist/internal/connect/federation.d.ts +9 -0
  42. package/dist/internal/connect/federation.d.ts.map +1 -0
  43. package/dist/internal/connect/federation.js +19 -0
  44. package/dist/internal/connect/federation.js.map +1 -0
  45. package/dist/internal/connect/fetch-failure.d.ts +3 -0
  46. package/dist/internal/connect/fetch-failure.d.ts.map +1 -0
  47. package/dist/internal/connect/fetch-failure.js +36 -0
  48. package/dist/internal/connect/fetch-failure.js.map +1 -0
  49. package/dist/internal/connect/index.d.ts +4 -2
  50. package/dist/internal/connect/index.d.ts.map +1 -1
  51. package/dist/internal/connect/index.js +3 -1
  52. package/dist/internal/connect/index.js.map +1 -1
  53. package/dist/internal/connect/main.d.ts +1 -0
  54. package/dist/internal/connect/main.d.ts.map +1 -1
  55. package/dist/internal/connect/main.js +575 -59
  56. package/dist/internal/connect/main.js.map +1 -1
  57. package/dist/internal/connect/options.d.ts +3 -0
  58. package/dist/internal/connect/options.d.ts.map +1 -0
  59. package/dist/internal/connect/options.js +9 -0
  60. package/dist/internal/connect/options.js.map +1 -0
  61. package/dist/internal/connect/records.d.ts +3 -0
  62. package/dist/internal/connect/records.d.ts.map +1 -0
  63. package/dist/internal/connect/records.js +21 -0
  64. package/dist/internal/connect/records.js.map +1 -0
  65. package/dist/internal/connect/run.d.ts +48 -19
  66. package/dist/internal/connect/run.d.ts.map +1 -1
  67. package/dist/internal/connect/run.js +185 -77
  68. package/dist/internal/connect/run.js.map +1 -1
  69. package/dist/internal/connect/source.d.ts +36 -3
  70. package/dist/internal/connect/source.d.ts.map +1 -1
  71. package/dist/internal/connect/source.js +378 -39
  72. package/dist/internal/connect/source.js.map +1 -1
  73. package/dist/internal/connect/template.d.ts +20 -2
  74. package/dist/internal/connect/template.d.ts.map +1 -1
  75. package/dist/internal/connect/template.js +53 -9
  76. package/dist/internal/connect/template.js.map +1 -1
  77. package/dist/internal/connect/utf8.d.ts +3 -0
  78. package/dist/internal/connect/utf8.d.ts.map +1 -0
  79. package/dist/internal/connect/utf8.js +12 -0
  80. package/dist/internal/connect/utf8.js.map +1 -0
  81. package/dist/internal/eval/cleanup.d.ts +5 -0
  82. package/dist/internal/eval/cleanup.d.ts.map +1 -0
  83. package/dist/internal/eval/cleanup.js +50 -0
  84. package/dist/internal/eval/cleanup.js.map +1 -0
  85. package/dist/internal/eval/error-message.d.ts +3 -0
  86. package/dist/internal/eval/error-message.d.ts.map +1 -0
  87. package/dist/internal/eval/error-message.js +10 -0
  88. package/dist/internal/eval/error-message.js.map +1 -0
  89. package/dist/internal/eval/judge.d.ts.map +1 -1
  90. package/dist/internal/eval/judge.js +3 -31
  91. package/dist/internal/eval/judge.js.map +1 -1
  92. package/dist/internal/eval/loop.d.ts.map +1 -1
  93. package/dist/internal/eval/loop.js +18 -4
  94. package/dist/internal/eval/loop.js.map +1 -1
  95. package/dist/internal/eval/main.d.ts.map +1 -1
  96. package/dist/internal/eval/main.js +22 -10
  97. package/dist/internal/eval/main.js.map +1 -1
  98. package/dist/internal/eval/options.d.ts +6 -0
  99. package/dist/internal/eval/options.d.ts.map +1 -0
  100. package/dist/internal/eval/options.js +31 -0
  101. package/dist/internal/eval/options.js.map +1 -0
  102. package/dist/internal/eval/queries.d.ts.map +1 -1
  103. package/dist/internal/eval/queries.js +9 -6
  104. package/dist/internal/eval/queries.js.map +1 -1
  105. package/dist/internal/eval/run.d.ts.map +1 -1
  106. package/dist/internal/eval/run.js +112 -24
  107. package/dist/internal/eval/run.js.map +1 -1
  108. package/dist/internal/eval/score.d.ts.map +1 -1
  109. package/dist/internal/eval/score.js +9 -2
  110. package/dist/internal/eval/score.js.map +1 -1
  111. package/dist/internal/eval/suite.d.ts.map +1 -1
  112. package/dist/internal/eval/suite.js +14 -2
  113. package/dist/internal/eval/suite.js.map +1 -1
  114. package/dist/internal/ingest/cleanup.d.ts +5 -0
  115. package/dist/internal/ingest/cleanup.d.ts.map +1 -0
  116. package/dist/internal/ingest/cleanup.js +50 -0
  117. package/dist/internal/ingest/cleanup.js.map +1 -0
  118. package/dist/internal/ingest/content.d.ts +6 -0
  119. package/dist/internal/ingest/content.d.ts.map +1 -0
  120. package/dist/internal/ingest/content.js +25 -0
  121. package/dist/internal/ingest/content.js.map +1 -0
  122. package/dist/internal/ingest/context.d.ts.map +1 -1
  123. package/dist/internal/ingest/context.js +25 -7
  124. package/dist/internal/ingest/context.js.map +1 -1
  125. package/dist/internal/ingest/error-message.d.ts +3 -0
  126. package/dist/internal/ingest/error-message.d.ts.map +1 -0
  127. package/dist/internal/ingest/error-message.js +10 -0
  128. package/dist/internal/ingest/error-message.js.map +1 -0
  129. package/dist/internal/ingest/files.d.ts +4 -12
  130. package/dist/internal/ingest/files.d.ts.map +1 -1
  131. package/dist/internal/ingest/files.js +22 -10
  132. package/dist/internal/ingest/files.js.map +1 -1
  133. package/dist/internal/ingest/main.d.ts.map +1 -1
  134. package/dist/internal/ingest/main.js +48 -17
  135. package/dist/internal/ingest/main.js.map +1 -1
  136. package/dist/internal/ingest/options.d.ts +6 -0
  137. package/dist/internal/ingest/options.d.ts.map +1 -0
  138. package/dist/internal/ingest/options.js +27 -0
  139. package/dist/internal/ingest/options.js.map +1 -0
  140. package/dist/internal/ingest/prompt.d.ts.map +1 -1
  141. package/dist/internal/ingest/prompt.js +14 -10
  142. package/dist/internal/ingest/prompt.js.map +1 -1
  143. package/dist/internal/ingest/run.d.ts +9 -2
  144. package/dist/internal/ingest/run.d.ts.map +1 -1
  145. package/dist/internal/ingest/run.js +206 -62
  146. package/dist/internal/ingest/run.js.map +1 -1
  147. package/dist/internal/ingest/timeout.d.ts +3 -0
  148. package/dist/internal/ingest/timeout.d.ts.map +1 -0
  149. package/dist/internal/ingest/timeout.js +14 -0
  150. package/dist/internal/ingest/timeout.js.map +1 -0
  151. package/dist/internal/ingest/web.d.ts +2 -11
  152. package/dist/internal/ingest/web.d.ts.map +1 -1
  153. package/dist/internal/ingest/web.js +131 -25
  154. package/dist/internal/ingest/web.js.map +1 -1
  155. package/dist/internal/loop/budgets.d.ts +3 -0
  156. package/dist/internal/loop/budgets.d.ts.map +1 -0
  157. package/dist/internal/loop/budgets.js +10 -0
  158. package/dist/internal/loop/budgets.js.map +1 -0
  159. package/dist/internal/loop/index.d.ts +2 -0
  160. package/dist/internal/loop/index.d.ts.map +1 -1
  161. package/dist/internal/loop/index.js +2 -0
  162. package/dist/internal/loop/index.js.map +1 -1
  163. package/dist/internal/loop/json-answer.d.ts +7 -0
  164. package/dist/internal/loop/json-answer.d.ts.map +1 -0
  165. package/dist/internal/loop/json-answer.js +79 -0
  166. package/dist/internal/loop/json-answer.js.map +1 -0
  167. package/dist/internal/loop/json-spans.d.ts +3 -0
  168. package/dist/internal/loop/json-spans.d.ts.map +1 -0
  169. package/dist/internal/loop/json-spans.js +88 -0
  170. package/dist/internal/loop/json-spans.js.map +1 -0
  171. package/dist/internal/loop/llm.d.ts +3 -2
  172. package/dist/internal/loop/llm.d.ts.map +1 -1
  173. package/dist/internal/loop/llm.js +115 -32
  174. package/dist/internal/loop/llm.js.map +1 -1
  175. package/dist/internal/loop/process.d.ts +3 -1
  176. package/dist/internal/loop/process.d.ts.map +1 -1
  177. package/dist/internal/loop/process.js +159 -59
  178. package/dist/internal/loop/process.js.map +1 -1
  179. package/dist/internal/loop/read-snapshot.d.ts +4 -0
  180. package/dist/internal/loop/read-snapshot.d.ts.map +1 -0
  181. package/dist/internal/loop/read-snapshot.js +29 -0
  182. package/dist/internal/loop/read-snapshot.js.map +1 -0
  183. package/dist/internal/loop/reconstruct.d.ts +6 -5
  184. package/dist/internal/loop/reconstruct.d.ts.map +1 -1
  185. package/dist/internal/loop/reconstruct.js +19 -8
  186. package/dist/internal/loop/reconstruct.js.map +1 -1
  187. package/dist/internal/loop/score-settings.d.ts +5 -0
  188. package/dist/internal/loop/score-settings.d.ts.map +1 -0
  189. package/dist/internal/loop/score-settings.js +14 -0
  190. package/dist/internal/loop/score-settings.js.map +1 -0
  191. package/dist/internal/loop/sqlite.d.ts.map +1 -1
  192. package/dist/internal/loop/sqlite.js +15 -7
  193. package/dist/internal/loop/sqlite.js.map +1 -1
  194. package/dist/internal/loop/store.d.ts.map +1 -1
  195. package/dist/internal/loop/store.js +11 -7
  196. package/dist/internal/loop/store.js.map +1 -1
  197. package/dist/internal/loop/timeout.d.ts +3 -0
  198. package/dist/internal/loop/timeout.d.ts.map +1 -0
  199. package/dist/internal/loop/timeout.js +13 -0
  200. package/dist/internal/loop/timeout.js.map +1 -0
  201. package/dist/internal/mcp/error-message.d.ts +3 -0
  202. package/dist/internal/mcp/error-message.d.ts.map +1 -0
  203. package/dist/internal/mcp/error-message.js +10 -0
  204. package/dist/internal/mcp/error-message.js.map +1 -0
  205. package/dist/internal/mcp/main.d.ts.map +1 -1
  206. package/dist/internal/mcp/main.js +44 -27
  207. package/dist/internal/mcp/main.js.map +1 -1
  208. package/dist/internal/mcp/read-snapshot.d.ts +4 -0
  209. package/dist/internal/mcp/read-snapshot.d.ts.map +1 -0
  210. package/dist/internal/mcp/read-snapshot.js +22 -0
  211. package/dist/internal/mcp/read-snapshot.js.map +1 -0
  212. package/dist/internal/mcp/server.d.ts.map +1 -1
  213. package/dist/internal/mcp/server.js +181 -21
  214. package/dist/internal/mcp/server.js.map +1 -1
  215. package/dist/internal/mcp/source.d.ts +3 -0
  216. package/dist/internal/mcp/source.d.ts.map +1 -0
  217. package/dist/internal/mcp/source.js +13 -0
  218. package/dist/internal/mcp/source.js.map +1 -0
  219. package/dist/internal/mcp/tools.d.ts.map +1 -1
  220. package/dist/internal/mcp/tools.js +135 -72
  221. package/dist/internal/mcp/tools.js.map +1 -1
  222. package/dist/internal/rules/declarations.d.ts +6 -0
  223. package/dist/internal/rules/declarations.d.ts.map +1 -0
  224. package/dist/internal/rules/declarations.js +14 -0
  225. package/dist/internal/rules/declarations.js.map +1 -0
  226. package/dist/internal/rules/declare.d.ts.map +1 -1
  227. package/dist/internal/rules/declare.js +30 -16
  228. package/dist/internal/rules/declare.js.map +1 -1
  229. package/dist/internal/rules/engine.d.ts +8 -7
  230. package/dist/internal/rules/engine.d.ts.map +1 -1
  231. package/dist/internal/rules/engine.js +150 -44
  232. package/dist/internal/rules/engine.js.map +1 -1
  233. package/dist/internal/rules/rule.d.ts.map +1 -1
  234. package/dist/internal/rules/rule.js +1 -22
  235. package/dist/internal/rules/rule.js.map +1 -1
  236. package/dist/internal/shape/alias-root.d.ts +3 -0
  237. package/dist/internal/shape/alias-root.d.ts.map +1 -0
  238. package/dist/internal/shape/alias-root.js +13 -0
  239. package/dist/internal/shape/alias-root.js.map +1 -0
  240. package/dist/internal/shape/check.d.ts +15 -3
  241. package/dist/internal/shape/check.d.ts.map +1 -1
  242. package/dist/internal/shape/check.js +230 -100
  243. package/dist/internal/shape/check.js.map +1 -1
  244. package/dist/internal/shape/client.d.ts.map +1 -1
  245. package/dist/internal/shape/client.js +42 -20
  246. package/dist/internal/shape/client.js.map +1 -1
  247. package/dist/internal/shape/constraints.d.ts +8 -0
  248. package/dist/internal/shape/constraints.d.ts.map +1 -0
  249. package/dist/internal/shape/constraints.js +17 -0
  250. package/dist/internal/shape/constraints.js.map +1 -0
  251. package/dist/internal/shape/edit-distance.d.ts +3 -0
  252. package/dist/internal/shape/edit-distance.d.ts.map +1 -0
  253. package/dist/internal/shape/edit-distance.js +33 -0
  254. package/dist/internal/shape/edit-distance.js.map +1 -0
  255. package/dist/internal/shape/gate.d.ts.map +1 -1
  256. package/dist/internal/shape/gate.js +0 -0
  257. package/dist/internal/shape/gate.js.map +1 -1
  258. package/dist/internal/shape/snapshot.d.ts +4 -0
  259. package/dist/internal/shape/snapshot.d.ts.map +1 -0
  260. package/dist/internal/shape/snapshot.js +20 -0
  261. package/dist/internal/shape/snapshot.js.map +1 -0
  262. package/dist/internal/shape/suggest.d.ts +8 -6
  263. package/dist/internal/shape/suggest.d.ts.map +1 -1
  264. package/dist/internal/shape/suggest.js +208 -92
  265. package/dist/internal/shape/suggest.js.map +1 -1
  266. package/dist/internal/sync/error-message.d.ts +3 -0
  267. package/dist/internal/sync/error-message.d.ts.map +1 -0
  268. package/dist/internal/sync/error-message.js +10 -0
  269. package/dist/internal/sync/error-message.js.map +1 -0
  270. package/dist/internal/sync/index.d.ts +3 -2
  271. package/dist/internal/sync/index.d.ts.map +1 -1
  272. package/dist/internal/sync/index.js +3 -2
  273. package/dist/internal/sync/index.js.map +1 -1
  274. package/dist/internal/sync/sync.d.ts +8 -5
  275. package/dist/internal/sync/sync.d.ts.map +1 -1
  276. package/dist/internal/sync/sync.js +322 -65
  277. package/dist/internal/sync/sync.js.map +1 -1
  278. package/dist/internal/view/api.d.ts +3 -1
  279. package/dist/internal/view/api.d.ts.map +1 -1
  280. package/dist/internal/view/api.js +154 -90
  281. package/dist/internal/view/api.js.map +1 -1
  282. package/dist/internal/view/error-message.d.ts +3 -0
  283. package/dist/internal/view/error-message.d.ts.map +1 -0
  284. package/dist/internal/view/error-message.js +10 -0
  285. package/dist/internal/view/error-message.js.map +1 -0
  286. package/dist/internal/view/main.d.ts.map +1 -1
  287. package/dist/internal/view/main.js +63 -9
  288. package/dist/internal/view/main.js.map +1 -1
  289. package/dist/internal/view/page.d.ts.map +1 -1
  290. package/dist/internal/view/page.js +119 -20
  291. package/dist/internal/view/page.js.map +1 -1
  292. package/dist/internal/view/report.d.ts.map +1 -1
  293. package/dist/internal/view/report.js +180 -145
  294. package/dist/internal/view/report.js.map +1 -1
  295. package/dist/internal/view/scope.d.ts +6 -2
  296. package/dist/internal/view/scope.d.ts.map +1 -1
  297. package/dist/internal/view/scope.js +107 -24
  298. package/dist/internal/view/scope.js.map +1 -1
  299. package/dist/internal/view/sensitivity.d.ts +4 -0
  300. package/dist/internal/view/sensitivity.d.ts.map +1 -0
  301. package/dist/internal/view/sensitivity.js +11 -0
  302. package/dist/internal/view/sensitivity.js.map +1 -0
  303. package/dist/internal/view/server.d.ts.map +1 -1
  304. package/dist/internal/view/server.js +57 -20
  305. package/dist/internal/view/server.js.map +1 -1
  306. package/dist/src/atomic-output.d.ts +3 -0
  307. package/dist/src/atomic-output.d.ts.map +1 -0
  308. package/dist/src/atomic-output.js +67 -0
  309. package/dist/src/atomic-output.js.map +1 -0
  310. package/dist/src/cli.d.ts +17 -2
  311. package/dist/src/cli.d.ts.map +1 -1
  312. package/dist/src/cli.js +333 -195
  313. package/dist/src/cli.js.map +1 -1
  314. package/dist/src/commands.d.ts +2 -2
  315. package/dist/src/commands.js +2 -2
  316. package/dist/src/commands.js.map +1 -1
  317. package/dist/src/dispatch.d.ts.map +1 -1
  318. package/dist/src/dispatch.js +10 -3
  319. package/dist/src/dispatch.js.map +1 -1
  320. package/dist/src/doctor.d.ts +1 -1
  321. package/dist/src/doctor.d.ts.map +1 -1
  322. package/dist/src/doctor.js +192 -91
  323. package/dist/src/doctor.js.map +1 -1
  324. package/dist/src/error-message.d.ts +3 -0
  325. package/dist/src/error-message.d.ts.map +1 -0
  326. package/dist/src/error-message.js +20 -0
  327. package/dist/src/error-message.js.map +1 -0
  328. package/dist/src/hooks-config.d.ts +3 -0
  329. package/dist/src/hooks-config.d.ts.map +1 -0
  330. package/dist/src/hooks-config.js +23 -0
  331. package/dist/src/hooks-config.js.map +1 -0
  332. package/dist/src/index.d.ts +1 -1
  333. package/dist/src/index.d.ts.map +1 -1
  334. package/dist/src/index.js +1 -1
  335. package/dist/src/index.js.map +1 -1
  336. package/package.json +23 -20
  337. package/src/atomic-output.ts +47 -0
  338. package/src/cli.ts +345 -171
  339. package/src/commands.ts +2 -2
  340. package/src/dispatch.ts +10 -3
  341. package/src/doctor.ts +207 -100
  342. package/src/error-message.ts +13 -0
  343. package/src/hooks-config.ts +22 -0
  344. package/src/index.ts +1 -1
@@ -5,7 +5,9 @@
5
5
  import { parseArgs } from 'node:util';
6
6
  import { Registry } from '@cavelang/canonical';
7
7
  import { Sensitivity, defaultDbPath, openAt } from '@cavelang/store';
8
+ import { assemble } from '@cavelang/cli/connect';
8
9
  import { defaultHost, defaultPort, serve } from "./server.js";
10
+ import { errorMessage } from "./error-message.js";
9
11
  const usage = `cave serve — browse a CAVE store in the browser (spec §30)
10
12
 
11
13
  Usage:
@@ -30,7 +32,7 @@ and the spec §20 coverage/frontier dashboard, with full-text search
30
32
  within the selected sensitivity ceiling. Every request reads the live store, so a running
31
33
  loop's appends show on the next refresh.
32
34
 
33
- The surface is strictly read-only: only GET is answered and no
35
+ The surface is strictly read-only: only GET/HEAD are answered and no
34
36
  endpoint writes — recording knowledge stays with cave add, the MCP
35
37
  tools and the kinetic layer (spec §24, §25, §29).
36
38
 
@@ -38,8 +40,23 @@ Examples:
38
40
  cave serve --db k.db
39
41
  cave serve --db k.db --port 8080
40
42
  CAVE_DB=k.db cave serve`;
41
- const waitForAbort = (signal) => signal?.aborted === true ? Promise.resolve() : new Promise(resolve => signal?.addEventListener('abort', () => resolve(), { once: true }));
43
+ const waitForStop = (server, signal, errors) => {
44
+ let wake;
45
+ const wait = new Promise(resolve => { wake = resolve; });
46
+ const failed = (error) => { errors.push(error); wake(); };
47
+ server.on('error', failed);
48
+ signal?.addEventListener('abort', wake, { once: true });
49
+ if (signal?.aborted)
50
+ wake();
51
+ return { wait, close: () => {
52
+ server.removeListener('error', failed);
53
+ signal?.removeEventListener('abort', wake);
54
+ } };
55
+ };
42
56
  export const runServe = async (argv, context = {}) => {
57
+ const signal = context.signal;
58
+ if (signal?.aborted === true)
59
+ return 0;
43
60
  const stdout = context.stdout ?? process.stdout;
44
61
  const stderr = context.stderr ?? process.stderr;
45
62
  const { values, positionals } = parseArgs({
@@ -62,8 +79,12 @@ export const runServe = async (argv, context = {}) => {
62
79
  stderr.write(`cave serve: unexpected argument ${JSON.stringify(positionals[0])}\n`);
63
80
  return 1;
64
81
  }
82
+ if (values.host !== undefined && values.host.trim() === '') {
83
+ stderr.write('cave serve: --host expects a non-empty hostname or address\n');
84
+ return 1;
85
+ }
65
86
  const port = values.port === undefined ? defaultPort : Number(values.port);
66
- if (!Number.isInteger(port) || port < 0 || port > 65535) {
87
+ if (values.port?.trim() === '' || !Number.isInteger(port) || port < 0 || port > 65535) {
67
88
  stderr.write(`cave serve: --port expects 0..65535, got '${values.port}'\n`);
68
89
  return 1;
69
90
  }
@@ -73,8 +94,10 @@ export const runServe = async (argv, context = {}) => {
73
94
  return 1;
74
95
  }
75
96
  const dbPath = values.db ?? defaultDbPath();
76
- const store = openAt(dbPath, { intent: 'read', ...values['no-prelude'] === true ? { registry: Registry.empty } : {} });
97
+ const store = openAt(dbPath, { intent: 'read', assemble, ...values['no-prelude'] === true ? { registry: Registry.empty } : {} });
77
98
  let handle;
99
+ const errors = [];
100
+ let stop;
78
101
  try {
79
102
  handle = await serve(store, {
80
103
  port,
@@ -82,17 +105,48 @@ export const runServe = async (argv, context = {}) => {
82
105
  maxSensitivity: maximum,
83
106
  ...values.host === undefined ? {} : { host: values.host }
84
107
  });
108
+ stop = waitForStop(handle.server, signal, errors);
85
109
  stdout.write(`serving ${dbPath} at ${handle.url} (sensitivity <= ${maximum}, read-only, ctrl-c to stop)\n`);
86
- await waitForAbort(context.signal);
87
- return 0;
110
+ await stop.wait;
111
+ }
112
+ catch (error) {
113
+ errors.push(error);
88
114
  }
89
- finally {
90
- if (handle?.server.listening === true) {
91
- const closing = handle.close();
115
+ if (handle?.server.listening === true) {
116
+ let closing;
117
+ try {
118
+ closing = handle.close();
119
+ // Observe immediately, then retain its error in cleanup order below.
120
+ void closing.catch(() => { });
121
+ }
122
+ catch (error) {
123
+ errors.push(error);
124
+ }
125
+ try {
92
126
  handle.server.closeAllConnections();
127
+ }
128
+ catch (error) {
129
+ errors.push(error);
130
+ }
131
+ try {
93
132
  await closing;
94
133
  }
134
+ catch (error) {
135
+ errors.push(error);
136
+ }
137
+ }
138
+ try {
95
139
  store.close();
96
140
  }
141
+ catch (error) {
142
+ errors.push(error);
143
+ }
144
+ stop?.close();
145
+ if (errors.length === 1)
146
+ throw errors[0];
147
+ if (errors.length > 1) {
148
+ throw new AggregateError(errors, `viewer failed: ${errors.map(errorMessage).join('; ')}`, { cause: errors[0] });
149
+ }
150
+ return 0;
97
151
  };
98
152
  //# sourceMappingURL=main.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/main.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAC9C,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AACpE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAE7D,MAAM,KAAK,GAAG;;;;;;;;yCAQ2B,WAAW;;8CAEN,WAAW;;;;;;;;;;;;;;;;;;;;;0BAqB/B,CAAA;AAQ1B,MAAM,YAAY,GAAG,CAAC,MAAoB,EAAiB,EAAE,CAC3D,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;AAE3I,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,EAAE,IAAuB,EAAE,UAAsB,EAAE,EAAmB,EAAE;IACnG,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAA;IAC/C,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAA;IAC/C,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC;QACxC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;QACf,OAAO,EAAE;YACP,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YACtB,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YACxB,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YACxB,iBAAiB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YACrC,YAAY,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;YACjC,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE;SACtC;QACD,gBAAgB,EAAE,IAAI;KACvB,CAAC,CAAA;IACF,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;QACzB,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,IAAI,CAAC,CAAA;QAC1B,OAAO,CAAC,CAAA;IACV,CAAC;IACD,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,CAAC,KAAK,CAAC,mCAAmC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;QACnF,OAAO,CAAC,CAAA;IACV,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAC1E,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;QACxD,MAAM,CAAC,KAAK,CAAC,6CAA6C,MAAM,CAAC,IAAI,KAAK,CAAC,CAAA;QAC3E,OAAO,CAAC,CAAA;IACV,CAAC;IACD,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,iBAAiB,CAAC,IAAI,WAAW,CAAC,cAAc,CAAC,CAAA;IAC1F,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,CAAC,KAAK,CAAC,yCAAyC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,CAAA;QAC1I,OAAO,CAAC,CAAA;IACV,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,EAAE,IAAI,aAAa,EAAE,CAAA;IAC3C,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IACtH,IAAI,MAAqD,CAAA;IACzD,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,KAAK,CAAC,KAAK,EAAE;YAC1B,IAAI;YACJ,KAAK,EAAE,MAAM;YACb,cAAc,EAAE,OAAO;YACvB,GAAG,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE;SAC1D,CAAC,CAAA;QACF,MAAM,CAAC,KAAK,CAAC,WAAW,MAAM,OAAO,MAAM,CAAC,GAAG,oBAAoB,OAAO,gCAAgC,CAAC,CAAA;QAC3G,MAAM,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;QAClC,OAAO,CAAC,CAAA;IACV,CAAC;YAAS,CAAC;QACT,IAAI,MAAM,EAAE,MAAM,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;YACtC,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,EAAE,CAAA;YAC9B,MAAM,CAAC,MAAM,CAAC,mBAAmB,EAAE,CAAA;YACnC,MAAM,OAAO,CAAA;QACf,CAAC;QACD,KAAK,CAAC,KAAK,EAAE,CAAA;IACf,CAAC;AACH,CAAC,CAAA"}
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/main.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../src/page.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,eAAO,MAAM,IAAI,EAAE,MAoWlB,CAAA"}
1
+ {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../src/page.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,eAAO,MAAM,IAAI,EAAE,MAuclB,CAAA"}
@@ -34,17 +34,19 @@ export const page = `<!doctype html>
34
34
  * { box-sizing: border-box; }
35
35
  body {
36
36
  margin: 0; background: var(--bg); color: var(--fg);
37
- font: 15px/1.5 system-ui, sans-serif;
37
+ font: 15px/1.5 system-ui, sans-serif; overflow-wrap: anywhere;
38
38
  }
39
39
  a { color: var(--accent); text-decoration: none; }
40
40
  a:hover { text-decoration: underline; }
41
+ a:focus-visible, input:focus-visible, button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
42
+ a:focus-visible { text-decoration: underline; }
41
43
  header {
42
44
  position: sticky; top: 0; display: flex; gap: 1rem; align-items: center;
43
45
  padding: .55rem 1rem; background: var(--bg); border-bottom: 1px solid var(--line);
44
46
  }
45
47
  header .brand { font-weight: 700; color: var(--fg); }
46
48
  header input[type=search] {
47
- flex: 1; max-width: 26rem; padding: .3rem .6rem; border: 1px solid var(--line);
49
+ flex: 1; min-width: 0; max-width: 26rem; padding: .3rem .6rem; border: 1px solid var(--line);
48
50
  border-radius: .4rem; background: var(--pill); color: var(--fg); font: inherit;
49
51
  }
50
52
  header label { color: var(--dim); font-size: .85rem; display: flex; gap: .35rem; align-items: center; }
@@ -60,6 +62,7 @@ section h2 { font-size: .8rem; text-transform: uppercase; letter-spacing: .06em;
60
62
  section h2 .n { font-weight: 400; }
61
63
  .none { color: var(--dim); font-size: .85rem; margin: .2rem 0; }
62
64
  .err { color: var(--bad); }
65
+ .retry { padding: .35rem .7rem; border: 1px solid var(--line); border-radius: .4rem; background: var(--pill); color: var(--fg); font: inherit; cursor: pointer; }
63
66
  .tiles { display: flex; flex-wrap: wrap; gap: .5rem; }
64
67
  .tile { background: var(--pill); border-radius: .5rem; padding: .45rem .8rem; min-width: 5.4rem; }
65
68
  .tile b { display: block; font-size: 1.15rem; }
@@ -99,31 +102,53 @@ section h2 .n { font-weight: 400; }
99
102
  .aka { color: var(--dim); font-size: .85rem; }
100
103
  mark { background: var(--mark); color: inherit; border-radius: .2rem; }
101
104
  .linked { font-size: .8rem; color: var(--dim); margin-top: .3rem; }
105
+ .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
106
+ .skip-link { position: fixed; top: .5rem; left: .5rem; z-index: 10; padding: .6rem .9rem; background: var(--bg); border: 2px solid var(--accent); border-radius: .3rem; transform: translateY(-200%); }
107
+ .skip-link:focus { transform: translateY(0); }
102
108
  </style>
103
109
  </head>
104
110
  <body>
111
+ <a class="skip-link" href="#view">Skip to content</a>
105
112
  <header>
106
113
  <a class="brand" href="#/">cave</a>
107
- <input id="q" type="search" placeholder="search claims… (enter)">
114
+ <input id="q" type="search" aria-label="Search claims by phrase" aria-keyshortcuts="Enter" enterkeyhint="search" placeholder="search phrase… (enter)">
108
115
  <label><input id="aliases" type="checkbox"> aliases</label>
109
116
  </header>
110
- <main id="view"></main>
117
+ <div id="loading-status" class="sr-only" role="status"></div>
118
+ <main id="view" tabindex="-1" aria-busy="false"></main>
111
119
  <footer>cave __CAVE_VERSION__ &middot; __CAVE_DB__ &middot; sensitivity &le; __CAVE_SENSITIVITY__ &middot; read-only view</footer>
112
120
  <script>
113
121
  'use strict'
114
122
  var view = document.getElementById('view')
123
+ var loadingStatus = document.getElementById('loading-status')
115
124
  var aliasBox = document.getElementById('aliases')
116
125
  var searchBox = document.getElementById('q')
126
+ var baseTitle = document.title
117
127
  var BACKTICK = '\\u0060'
118
128
 
119
- aliasBox.checked = localStorage.getItem('cave-aliases') === '1'
129
+ document.querySelector('.skip-link').addEventListener('click', function (event) {
130
+ event.preventDefault()
131
+ focusViewElement(view)
132
+ })
133
+
134
+ try {
135
+ aliasBox.checked = localStorage.getItem('cave-aliases') === '1'
136
+ } catch (_) {
137
+ aliasBox.checked = false
138
+ }
120
139
  aliasBox.addEventListener('change', function () {
121
- localStorage.setItem('cave-aliases', aliasBox.checked ? '1' : '0')
140
+ try {
141
+ localStorage.setItem('cave-aliases', aliasBox.checked ? '1' : '0')
142
+ } catch (_) { /* Persistence is optional; the current toggle still applies. */ }
122
143
  route()
123
144
  })
124
145
  searchBox.addEventListener('keydown', function (event) {
125
- if (event.key === 'Enter' && searchBox.value.trim() !== '') {
126
- location.hash = '#/s/' + encodeURIComponent(searchBox.value.trim())
146
+ if (event.key === 'Enter' && !event.isComposing &&
147
+ !event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey && searchBox.value.trim() !== '') {
148
+ event.preventDefault()
149
+ var destination = '#/s/' + encodeURIComponent(searchBox.value.trim())
150
+ if (location.hash === destination) route()
151
+ else location.hash = destination
127
152
  }
128
153
  })
129
154
 
@@ -133,7 +158,12 @@ function esc (value) {
133
158
  })
134
159
  }
135
160
  var enc = encodeURIComponent
136
- function pct (value) { return Math.round(value * 1000) / 10 + '%' }
161
+ function pct (value) {
162
+ var rounded = Math.round(value * 1000) / 10
163
+ if (value > 0 && rounded === 0) { return '<0.1%' }
164
+ if (value < 1 && rounded === 100) { return '>99.9%' }
165
+ return rounded + '%'
166
+ }
137
167
 
138
168
  function api (path, params) {
139
169
  var pairs = []
@@ -145,8 +175,13 @@ function api (path, params) {
145
175
  })
146
176
  return fetch('/api/' + path + (pairs.length ? '?' + pairs.join('&') : '')).then(function (res) {
147
177
  return res.json().then(function (body) {
148
- if (!res.ok) { throw new Error(body.error || ('http ' + res.status)) }
178
+ if (!res.ok) {
179
+ var message = body && typeof body.error === 'string' && body.error
180
+ throw new Error(message || ('HTTP ' + res.status))
181
+ }
149
182
  return body
183
+ }, function () {
184
+ throw new Error(res.ok ? 'Could not read JSON response (HTTP ' + res.status + ')' : 'HTTP ' + res.status)
150
185
  })
151
186
  })
152
187
  }
@@ -162,7 +197,7 @@ function claimHtml (c, opts) {
162
197
  opts = opts || {}
163
198
  var parts = []
164
199
  if (opts.when) { parts.push('<span class="when" title="' + esc(c.at) + '">' + esc(c.at.slice(0, 10)) + '</span>') }
165
- if (opts.bar) { parts.push('<span class="bar" title="confidence ' + pct(c.conf) + '"><i style="width:' + (c.conf * 100) + '%"></i></span>') }
200
+ if (opts.bar) { parts.push('<span class="bar" title="confidence ' + esc(pct(c.conf)) + '"><i style="width:' + (c.conf * 100) + '%"></i></span>') }
166
201
  parts.push(entityHtml(c.subject))
167
202
  parts.push('<span class="v">' + esc(c.verb) + '</span>' + (c.negated ? ' <em class="not">NOT</em>' : ''))
168
203
  if (c.object !== undefined) {
@@ -173,6 +208,7 @@ function claimHtml (c, opts) {
173
208
  parts.push('<span class="val">' + esc(c.value) + '</span>')
174
209
  }
175
210
  if (c.delta !== undefined) { parts.push('<span class="val">+/- ' + esc(c.delta) + '</span>') }
211
+ if (c.sigmaLevel !== undefined) { parts.push('<span class="val">(' + esc(c.sigmaLevel) + 'σ)</span>') }
176
212
  c.contexts.forEach(function (ctx) {
177
213
  var source = (c.sources || []).filter(function (item) { return item.context === ctx })[0]
178
214
  var label = '@' + esc(ctx)
@@ -187,7 +223,7 @@ function claimHtml (c, opts) {
187
223
  if (c.conf === 0) {
188
224
  parts.push('<span class="conf retracted" title="retracted">@ 0%</span>')
189
225
  } else if (c.conf < 1) {
190
- parts.push('<span class="conf">@ ' + pct(c.conf) + '</span>')
226
+ parts.push('<span class="conf">@ ' + esc(pct(c.conf)) + '</span>')
191
227
  }
192
228
  if (c.importance) { parts.push('<span class="imp">!</span>') }
193
229
  if (c.comment !== undefined) { parts.push('<span class="cmt">; ' + esc(c.comment) + '</span>') }
@@ -232,7 +268,7 @@ function dashboard (data) {
232
268
  html += section('coverage', '<div class="tiles">' +
233
269
  tile(cov.rows, 'rows') + tile(cov.facts, 'facts') + tile(cov.current, 'current') +
234
270
  tile(cov.entities, 'entities') + tile(cov.typedEntities, 'typed') +
235
- tile(cov.averageConfidence === null ? '&mdash;' : pct(cov.averageConfidence), 'avg conf') +
271
+ tile(cov.averageConfidence === null ? '&mdash;' : esc(pct(cov.averageConfidence)), 'avg conf') +
236
272
  tile(cov.retracted, 'retracted') + tile(cov.negated, 'negated') + tile(cov.lowConfidence, 'low conf') +
237
273
  tile(cov.satisfied + '/' + cov.checks, 'shape checks') +
238
274
  '</div>')
@@ -300,10 +336,13 @@ function topicPage (data) {
300
336
  }
301
337
 
302
338
  function historyPage (data) {
303
- var current = data.rows[data.rows.length - 1]
304
- var html = '<h1>' + esc(current.line) + ' <span class="kind">belief history</span></h1>'
339
+ var latest = data.rows[data.rows.length - 1]
340
+ var html = '<h1>' + esc(latest.line) + ' <span class="kind">belief history</span></h1>'
305
341
  html += '<p class="linked">claim key <code>' + esc(data.key) + '</code> &middot; ' + data.rows.length +
306
- ' event(s) &middot; oldest first, the last row is current belief</p>'
342
+ ' event(s) &middot; oldest first, the last row is the latest visible event</p>'
343
+ if (latest.conf === 0) {
344
+ html += '<p>This series is retracted in the selected audience.</p>'
345
+ }
307
346
  html += claimList(data.rows, { when: true, bar: true })
308
347
  view.innerHTML = html
309
348
  }
@@ -324,26 +363,85 @@ function treeHtml0 (nodes) { return nodes.length === 0 ? '' : treeHtml(nodes) }
324
363
  function lineagePage (data) {
325
364
  var html = '<h1>' + esc(data.row.line) + ' <span class="kind">lineage</span></h1>'
326
365
  html += claimHtml(data.row)
327
- html += section('cites — why this is believed (BECAUSE premises, VIA rules, WHEN conditions)', treeHtml(data.cites))
366
+ html += '<p>These links show recorded evidence. Later changes to premises do not rewrite this claim’s original evidence.</p>'
367
+ html += section('cites — recorded evidence (BECAUSE premises, VIA rules, WHEN conditions)', treeHtml(data.cites))
328
368
  html += section('cited by — what depends on it', treeHtml(data.citedBy))
329
369
  view.innerHTML = html
330
370
  }
331
371
 
332
372
  function searchPage (text, data) {
333
- searchBox.value = text
334
373
  view.innerHTML = '<h1>' + esc(text) + ' <span class="kind">search</span></h1>' +
374
+ '<p>Search includes earlier revisions and retracted claims, newest first. Open a claim’s history to follow its changes.</p>' +
375
+ (data.length === 100 ? '<p>Showing the newest 100 matches. More may exist; refine the search phrase to narrow the results.</p>' : '') +
335
376
  section('matches', claimList(data, { when: true }), data.length)
336
377
  }
337
378
 
379
+ var navigation = 0
380
+ var renderedHash
381
+
382
+ function focusViewElement (destination) {
383
+ destination.setAttribute('tabindex', '-1')
384
+ destination.focus({ preventScroll: true })
385
+ destination.scrollIntoView({ block: 'start', behavior: 'instant' })
386
+ var header = document.querySelector('header')
387
+ var overlap = (header ? header.getBoundingClientRect().bottom : 0) + 12 - destination.getBoundingClientRect().top
388
+ if (overlap > 0) window.scrollBy({ top: -overlap, behavior: 'instant' })
389
+ }
390
+
391
+ function focusDestination (restoreFocus) {
392
+ if (restoreFocus && document.activeElement === document.body) {
393
+ var destination = view.querySelector('h1, [role="alert"]') || view.querySelector('h2')
394
+ if (destination) {
395
+ focusViewElement(destination)
396
+ }
397
+ }
398
+ }
399
+
338
400
  function show (promise, render) {
401
+ var current = navigation
402
+ document.title = 'Loading view — ' + baseTitle
403
+ var restoreFocus = view.contains(document.activeElement)
404
+ view.setAttribute('aria-busy', 'true')
405
+ loadingStatus.textContent = 'Loading view.'
339
406
  view.innerHTML = '<p class="none">loading&hellip;</p>'
340
- promise.then(render).catch(function (error) {
341
- view.innerHTML = '<p class="err">' + esc(error.message) + '</p>'
407
+ promise.then(function (data) {
408
+ if (current === navigation) {
409
+ render(data)
410
+ var heading = view.querySelector('h1')
411
+ document.title = (heading ? heading.textContent : 'Overview') + ' — ' + baseTitle
412
+ view.setAttribute('aria-busy', 'false')
413
+ loadingStatus.textContent = 'View loaded.'
414
+ focusDestination(restoreFocus)
415
+ }
416
+ }).catch(function (error) {
417
+ if (current === navigation) showError(error, restoreFocus)
342
418
  })
343
419
  }
344
420
 
421
+ function showError (error, restoreFocus) {
422
+ document.title = 'View error — ' + baseTitle
423
+ view.setAttribute('aria-busy', 'false')
424
+ loadingStatus.textContent = ''
425
+ view.innerHTML = '<p class="err" role="alert">' + esc(error.message) + '</p>' +
426
+ '<button class="retry" type="button">Retry view</button>'
427
+ view.querySelector('.retry').addEventListener('click', route)
428
+ focusDestination(restoreFocus)
429
+ }
430
+
345
431
  function route () {
432
+ navigation++
433
+ var restoreFocus = view.contains(document.activeElement)
434
+ try {
435
+ renderRoute()
436
+ } catch (error) {
437
+ showError(error, restoreFocus)
438
+ }
439
+ }
440
+
441
+ function renderRoute () {
346
442
  var hash = location.hash || '#/'
443
+ var changedRoute = hash !== renderedHash
444
+ renderedHash = hash
347
445
  var aliases = aliasBox.checked
348
446
  var match
349
447
  if ((match = hash.match(/^#\\/e\\/(.+)$/))) {
@@ -356,6 +454,7 @@ function route () {
356
454
  show(api('lineage', { id: decodeURIComponent(match[1]) }), lineagePage)
357
455
  } else if ((match = hash.match(/^#\\/s\\/(.+)$/))) {
358
456
  var text = decodeURIComponent(match[1])
457
+ if (changedRoute) searchBox.value = text
359
458
  show(api('search', { q: text }), function (data) { searchPage(text, data) })
360
459
  } else {
361
460
  show(api('overview'), dashboard)
@@ -1 +1 @@
1
- {"version":3,"file":"page.js","sourceRoot":"","sources":["../../src/page.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,CAAC,MAAM,IAAI,GAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoW3B,CAAA"}
1
+ {"version":3,"file":"page.js","sourceRoot":"","sources":["../../src/page.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,CAAC,MAAM,IAAI,GAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuc3B,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/report.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAOH,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAC7C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAG5C,MAAM,MAAM,OAAO,GAAG;IACpB,sDAAsD;IACtD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,4FAA4F;IAC5F,QAAQ,CAAC,cAAc,CAAC,EAAE,WAAW,CAAC,KAAK,CAAA;IAC3C,qDAAqD;IACrD,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;IAC1B,sDAAsD;IACtD,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;IAC1B,gEAAgE;IAChE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,sGAAsG;IACtG,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,MAAM,GAAG;IACnB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,gEAAgE;IAChE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAA;CACtC,CAAA;AAqXD,eAAO,MAAM,MAAM,GAAI,OAAO,KAAK,EAAE,UAAU,MAAM,EAAE,UAAS,aAAkB,KAAG,MAEzC,CAAA"}
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/report.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAQH,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAC7C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAO5C,MAAM,MAAM,OAAO,GAAG;IACpB,sDAAsD;IACtD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,4FAA4F;IAC5F,QAAQ,CAAC,cAAc,CAAC,EAAE,WAAW,CAAC,KAAK,CAAA;IAC3C,qDAAqD;IACrD,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;IAC1B,sDAAsD;IACtD,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;IAC1B,gEAAgE;IAChE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,sGAAsG;IACtG,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,MAAM,GAAG;IACnB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,gEAAgE;IAChE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAA;CACtC,CAAA;AAuXD,eAAO,MAAM,MAAM,GAAI,OAAO,KAAK,EAAE,UAAU,MAAM,EAAE,UAAS,aAAkB,KAAG,MAapF,CAAA"}