@prestack/thread-ui 0.1.1 → 0.1.2

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 (343) hide show
  1. package/CHANGELOG.md +174 -0
  2. package/dist/ui/animations/anm_appear.d.ts +8 -8
  3. package/dist/ui/animations/anm_blur_in.d.ts +12 -12
  4. package/dist/ui/animations/anm_blur_out.d.ts +12 -12
  5. package/dist/ui/animations/anm_dismiss.d.ts +12 -12
  6. package/dist/ui/animations/anm_drop.d.ts +12 -12
  7. package/dist/ui/animations/anm_fall.d.ts +12 -12
  8. package/dist/ui/animations/anm_flash.d.ts +9 -9
  9. package/dist/ui/animations/anm_glow.d.ts +8 -8
  10. package/dist/ui/animations/anm_lift.d.ts +8 -8
  11. package/dist/ui/animations/anm_nudge.d.ts +8 -8
  12. package/dist/ui/animations/anm_pop_in.d.ts +16 -16
  13. package/dist/ui/animations/anm_pop_out.d.ts +16 -16
  14. package/dist/ui/animations/anm_press.d.ts +9 -9
  15. package/dist/ui/animations/anm_pulse.d.ts +10 -10
  16. package/dist/ui/animations/anm_rise.d.ts +12 -12
  17. package/dist/ui/animations/anm_shake.d.ts +11 -11
  18. package/dist/ui/animations/anm_slide_in_left.d.ts +12 -12
  19. package/dist/ui/animations/anm_slide_in_right.d.ts +12 -12
  20. package/dist/ui/animations/anm_slide_out_left.d.ts +12 -12
  21. package/dist/ui/animations/anm_slide_out_right.d.ts +12 -12
  22. package/dist/ui/animations/anm_spin.d.ts +8 -8
  23. package/dist/ui/animations/anm_swell.d.ts +8 -8
  24. package/dist/ui/animations/anm_wobble.d.ts +13 -13
  25. package/dist/ui/animations/anm_zoom_in.d.ts +12 -12
  26. package/dist/ui/animations/anm_zoom_out.d.ts +12 -12
  27. package/dist/ui/animations.d.ts +8 -8
  28. package/dist/ui/animations.js +4 -4
  29. package/dist/ui/animations.ts +1 -1
  30. package/dist/ui/attach.js +22 -78
  31. package/dist/ui/attach.ts +8 -66
  32. package/dist/ui/charts.d.ts +0 -3
  33. package/dist/ui/charts.js +3 -7
  34. package/dist/ui/charts.tsx +0 -4
  35. package/dist/ui/checked.d.ts +1 -1
  36. package/dist/ui/checked.ts +1 -1
  37. package/dist/ui/collector.js +1 -1
  38. package/dist/ui/collector.ts +1 -1
  39. package/dist/ui/compositions.d.ts +9 -3
  40. package/dist/ui/compositions.js +9 -158
  41. package/dist/ui/compositions.ts +6 -170
  42. package/dist/ui/content.js +4 -7
  43. package/dist/ui/content.tsx +4 -15
  44. package/dist/ui/controls.js +1 -1
  45. package/dist/ui/door.d.ts +1 -1
  46. package/dist/ui/elements/accordion.d.ts +2 -1
  47. package/dist/ui/elements/accordion.js +4 -4
  48. package/dist/ui/elements/accordion.tsx +2 -1
  49. package/dist/ui/elements/aspect-ratio.d.ts +2 -1
  50. package/dist/ui/elements/aspect-ratio.js +1 -1
  51. package/dist/ui/elements/aspect-ratio.tsx +2 -1
  52. package/dist/ui/elements/avatar.d.ts +2 -1
  53. package/dist/ui/elements/avatar.js +3 -3
  54. package/dist/ui/elements/avatar.tsx +2 -1
  55. package/dist/ui/elements/badge.d.ts +2 -1
  56. package/dist/ui/elements/badge.js +3 -3
  57. package/dist/ui/elements/badge.tsx +2 -1
  58. package/dist/ui/elements/bars.d.ts +2 -1
  59. package/dist/ui/elements/bars.js +5 -5
  60. package/dist/ui/elements/bars.tsx +2 -1
  61. package/dist/ui/elements/bars.works.js +3 -3
  62. package/dist/ui/elements/box.d.ts +2 -1
  63. package/dist/ui/elements/box.js +1 -1
  64. package/dist/ui/elements/box.tsx +2 -1
  65. package/dist/ui/elements/breadcrumb.d.ts +2 -1
  66. package/dist/ui/elements/breadcrumb.js +5 -5
  67. package/dist/ui/elements/breadcrumb.tsx +2 -1
  68. package/dist/ui/elements/breadcrumb.works.js +1 -1
  69. package/dist/ui/elements/button.d.ts +2 -1
  70. package/dist/ui/elements/button.js +3 -3
  71. package/dist/ui/elements/button.tsx +2 -1
  72. package/dist/ui/elements/button.works.js +2 -2
  73. package/dist/ui/elements/column.d.ts +2 -1
  74. package/dist/ui/elements/column.js +1 -1
  75. package/dist/ui/elements/column.tsx +2 -1
  76. package/dist/ui/elements/consent.d.ts +2 -1
  77. package/dist/ui/elements/consent.js +10 -10
  78. package/dist/ui/elements/consent.tsx +2 -1
  79. package/dist/ui/elements/consent.works.js +1 -1
  80. package/dist/ui/elements/donut.d.ts +2 -1
  81. package/dist/ui/elements/donut.js +4 -4
  82. package/dist/ui/elements/donut.tsx +2 -1
  83. package/dist/ui/elements/donut.works.js +2 -2
  84. package/dist/ui/elements/each.d.ts +2 -1
  85. package/dist/ui/elements/each.js +3 -3
  86. package/dist/ui/elements/each.tsx +2 -1
  87. package/dist/ui/elements/each.works.js +2 -2
  88. package/dist/ui/elements/empty.d.ts +2 -1
  89. package/dist/ui/elements/empty.js +2 -2
  90. package/dist/ui/elements/empty.tsx +2 -1
  91. package/dist/ui/elements/field.d.ts +2 -1
  92. package/dist/ui/elements/field.js +3 -3
  93. package/dist/ui/elements/field.tsx +2 -1
  94. package/dist/ui/elements/field.works.js +1 -1
  95. package/dist/ui/elements/funnel.d.ts +2 -1
  96. package/dist/ui/elements/funnel.js +5 -5
  97. package/dist/ui/elements/funnel.tsx +2 -1
  98. package/dist/ui/elements/funnel.works.js +3 -3
  99. package/dist/ui/elements/gauge.d.ts +2 -1
  100. package/dist/ui/elements/gauge.js +3 -3
  101. package/dist/ui/elements/gauge.tsx +2 -1
  102. package/dist/ui/elements/gauge.works.js +1 -1
  103. package/dist/ui/elements/glyph.d.ts +2 -1
  104. package/dist/ui/elements/glyph.js +3 -3
  105. package/dist/ui/elements/glyph.tsx +2 -1
  106. package/dist/ui/elements/glyph.works.js +1 -1
  107. package/dist/ui/elements/grid.d.ts +2 -1
  108. package/dist/ui/elements/grid.js +1 -1
  109. package/dist/ui/elements/grid.tsx +2 -1
  110. package/dist/ui/elements/heatmap.d.ts +2 -1
  111. package/dist/ui/elements/heatmap.js +5 -5
  112. package/dist/ui/elements/heatmap.tsx +2 -1
  113. package/dist/ui/elements/heatmap.works.js +1 -1
  114. package/dist/ui/elements/hit-box.d.ts +2 -1
  115. package/dist/ui/elements/hit-box.js +2 -2
  116. package/dist/ui/elements/hit-box.tsx +2 -1
  117. package/dist/ui/elements/hit-box.works.d.ts +2 -2
  118. package/dist/ui/elements/hit-box.works.js +5 -5
  119. package/dist/ui/elements/hit-box.works.tsx +2 -1
  120. package/dist/ui/elements/image.d.ts +2 -1
  121. package/dist/ui/elements/image.js +2 -2
  122. package/dist/ui/elements/image.tsx +2 -1
  123. package/dist/ui/elements/line-chart.d.ts +2 -1
  124. package/dist/ui/elements/line-chart.js +4 -4
  125. package/dist/ui/elements/line-chart.tsx +2 -1
  126. package/dist/ui/elements/line-chart.works.js +2 -2
  127. package/dist/ui/elements/link.d.ts +2 -1
  128. package/dist/ui/elements/link.js +3 -3
  129. package/dist/ui/elements/link.tsx +2 -1
  130. package/dist/ui/elements/link.works.js +1 -1
  131. package/dist/ui/elements/media.d.ts +2 -1
  132. package/dist/ui/elements/media.js +2 -2
  133. package/dist/ui/elements/media.tsx +2 -1
  134. package/dist/ui/elements/menu.d.ts +2 -1
  135. package/dist/ui/elements/menu.js +5 -5
  136. package/dist/ui/elements/menu.tsx +2 -1
  137. package/dist/ui/elements/menu.works.d.ts +2 -1
  138. package/dist/ui/elements/menu.works.js +5 -5
  139. package/dist/ui/elements/menu.works.tsx +2 -1
  140. package/dist/ui/elements/money.d.ts +3 -1
  141. package/dist/ui/elements/money.js +10 -5
  142. package/dist/ui/elements/money.tsx +12 -3
  143. package/dist/ui/elements/money.works.js +1 -1
  144. package/dist/ui/elements/pagination.d.ts +2 -1
  145. package/dist/ui/elements/pagination.js +5 -5
  146. package/dist/ui/elements/pagination.tsx +2 -1
  147. package/dist/ui/elements/progress.d.ts +2 -1
  148. package/dist/ui/elements/progress.js +3 -3
  149. package/dist/ui/elements/progress.tsx +2 -1
  150. package/dist/ui/elements/radio-group.d.ts +2 -1
  151. package/dist/ui/elements/radio-group.js +4 -4
  152. package/dist/ui/elements/radio-group.tsx +2 -1
  153. package/dist/ui/elements/radio-group.works.js +1 -1
  154. package/dist/ui/elements/row.d.ts +2 -1
  155. package/dist/ui/elements/row.js +1 -1
  156. package/dist/ui/elements/row.tsx +2 -1
  157. package/dist/ui/elements/scatter.d.ts +2 -1
  158. package/dist/ui/elements/scatter.js +3 -3
  159. package/dist/ui/elements/scatter.tsx +2 -1
  160. package/dist/ui/elements/scatter.works.js +1 -1
  161. package/dist/ui/elements/select.d.ts +2 -1
  162. package/dist/ui/elements/select.js +4 -4
  163. package/dist/ui/elements/select.tsx +2 -1
  164. package/dist/ui/elements/separator.d.ts +2 -1
  165. package/dist/ui/elements/separator.js +2 -2
  166. package/dist/ui/elements/separator.tsx +2 -1
  167. package/dist/ui/elements/skeleton.d.ts +2 -1
  168. package/dist/ui/elements/skeleton.js +2 -2
  169. package/dist/ui/elements/skeleton.tsx +2 -1
  170. package/dist/ui/elements/slider.d.ts +2 -1
  171. package/dist/ui/elements/slider.js +3 -3
  172. package/dist/ui/elements/slider.tsx +2 -1
  173. package/dist/ui/elements/sparkline.d.ts +2 -1
  174. package/dist/ui/elements/sparkline.js +3 -3
  175. package/dist/ui/elements/sparkline.tsx +2 -1
  176. package/dist/ui/elements/sparkline.works.js +1 -1
  177. package/dist/ui/elements/spinner.d.ts +2 -1
  178. package/dist/ui/elements/spinner.js +2 -2
  179. package/dist/ui/elements/spinner.tsx +2 -1
  180. package/dist/ui/elements/stack.d.ts +2 -1
  181. package/dist/ui/elements/stack.js +1 -1
  182. package/dist/ui/elements/stack.tsx +2 -1
  183. package/dist/ui/elements/stat.d.ts +2 -1
  184. package/dist/ui/elements/stat.js +3 -3
  185. package/dist/ui/elements/stat.tsx +2 -1
  186. package/dist/ui/elements/stat.works.js +1 -1
  187. package/dist/ui/elements/surface.d.ts +2 -1
  188. package/dist/ui/elements/surface.js +2 -2
  189. package/dist/ui/elements/surface.tsx +2 -1
  190. package/dist/ui/elements/surface.works.js +1 -1
  191. package/dist/ui/elements/table.d.ts +2 -1
  192. package/dist/ui/elements/table.js +4 -4
  193. package/dist/ui/elements/table.tsx +2 -1
  194. package/dist/ui/elements/table.works.js +1 -1
  195. package/dist/ui/elements/tabs.d.ts +2 -1
  196. package/dist/ui/elements/tabs.js +4 -4
  197. package/dist/ui/elements/tabs.tsx +2 -1
  198. package/dist/ui/elements/tabs.works.js +1 -1
  199. package/dist/ui/elements/text.d.ts +2 -1
  200. package/dist/ui/elements/text.js +2 -2
  201. package/dist/ui/elements/text.tsx +2 -1
  202. package/dist/ui/elements/textarea.d.ts +2 -1
  203. package/dist/ui/elements/textarea.js +4 -4
  204. package/dist/ui/elements/textarea.tsx +2 -1
  205. package/dist/ui/elements/time.d.ts +3 -1
  206. package/dist/ui/elements/time.js +7 -4
  207. package/dist/ui/elements/time.tsx +9 -2
  208. package/dist/ui/elements/time.works.d.ts +1 -0
  209. package/dist/ui/elements/time.works.js +7 -3
  210. package/dist/ui/elements/time.works.ts +6 -2
  211. package/dist/ui/elements/toggle.d.ts +2 -1
  212. package/dist/ui/elements/toggle.js +3 -3
  213. package/dist/ui/elements/toggle.tsx +2 -1
  214. package/dist/ui/elements/tooltip.d.ts +2 -1
  215. package/dist/ui/elements/tooltip.js +2 -2
  216. package/dist/ui/elements/tooltip.tsx +2 -1
  217. package/dist/ui/elements/tooltip.works.js +2 -2
  218. package/dist/ui/elements/value.d.ts +3 -1
  219. package/dist/ui/elements/value.js +10 -5
  220. package/dist/ui/elements/value.tsx +12 -3
  221. package/dist/ui/elements/value.works.js +1 -1
  222. package/dist/ui/elements.d.ts +15 -11
  223. package/dist/ui/elements.js +6 -6
  224. package/dist/ui/elements.ts +7 -7
  225. package/dist/ui/fonts.d.ts +1 -1
  226. package/dist/ui/fonts.js +1 -1
  227. package/dist/ui/generators/dev.d.ts +1 -2
  228. package/dist/ui/generators/dev.js +33 -37
  229. package/dist/ui/generators/dev.ts +30 -37
  230. package/dist/ui/generators/elements.d.ts +1 -0
  231. package/dist/ui/generators/elements.js +11 -9
  232. package/dist/ui/generators/elements.ts +12 -9
  233. package/dist/ui/generators/i18n.js +6 -23
  234. package/dist/ui/generators/i18n.ts +1 -18
  235. package/dist/ui/generators/icons.js +5 -14
  236. package/dist/ui/generators/icons.ts +1 -10
  237. package/dist/ui/generators/react.js +4 -5
  238. package/dist/ui/generators/react.ts +2 -3
  239. package/dist/ui/generators/routes.js +66 -51
  240. package/dist/ui/generators/routes.ts +67 -46
  241. package/dist/ui/generators/show.js +9 -6
  242. package/dist/ui/generators/show.ts +4 -2
  243. package/dist/ui/generators/styles.js +12 -16
  244. package/dist/ui/generators/styles.ts +1 -5
  245. package/dist/ui/generators/variants.js +3 -3
  246. package/dist/ui/generators/variants.ts +1 -1
  247. package/dist/ui/i18n/catalogs/en.js +1 -1
  248. package/dist/ui/i18n/format.js +1 -1
  249. package/dist/ui/i18n/translator.js +2 -2
  250. package/dist/ui/material.d.ts +11 -11
  251. package/dist/ui/material.js +1 -1
  252. package/dist/ui/materials/mat_bordered.d.ts +13 -13
  253. package/dist/ui/materials/mat_bordered.js +1 -1
  254. package/dist/ui/materials/mat_ceramic.d.ts +13 -13
  255. package/dist/ui/materials/mat_ceramic.js +1 -1
  256. package/dist/ui/materials/mat_clay.d.ts +13 -13
  257. package/dist/ui/materials/mat_clay.js +1 -1
  258. package/dist/ui/materials/mat_elevated.d.ts +13 -13
  259. package/dist/ui/materials/mat_elevated.js +1 -1
  260. package/dist/ui/materials/mat_flat.d.ts +25 -25
  261. package/dist/ui/materials/mat_flat.js +1 -1
  262. package/dist/ui/materials/mat_glass.d.ts +17 -17
  263. package/dist/ui/materials/mat_glass.js +1 -1
  264. package/dist/ui/materials/mat_lit.d.ts +13 -13
  265. package/dist/ui/materials/mat_lit.js +1 -1
  266. package/dist/ui/materials/mat_moulded.d.ts +9 -9
  267. package/dist/ui/materials/mat_moulded.js +1 -1
  268. package/dist/ui/materials.d.ts +30 -30
  269. package/dist/ui/materials.js +3 -3
  270. package/dist/ui/materials.ts +1 -1
  271. package/dist/ui/modes.d.ts +2 -2
  272. package/dist/ui/presented.js +5 -5
  273. package/dist/ui/provider.d.ts +3 -0
  274. package/dist/ui/provider.js +9 -10
  275. package/dist/ui/provider.tsx +7 -5
  276. package/dist/ui/screens.js +6 -6
  277. package/dist/ui/screens.ts +1 -1
  278. package/dist/ui/scroll-lock.js +1 -1
  279. package/dist/ui/series.js +1 -1
  280. package/dist/ui/styleguide.js +1 -1
  281. package/dist/ui/tokens.d.ts +2 -2
  282. package/dist/ui/tokens.js +3 -3
  283. package/dist/ui/tokens.ts +1 -1
  284. package/dist/ui/validators.js +1 -1
  285. package/dist/ui/variant.d.ts +37 -37
  286. package/dist/ui/variant.js +2 -2
  287. package/dist/ui/variants/var_avatar-round.d.ts +13 -13
  288. package/dist/ui/variants/var_avatar-round.js +1 -1
  289. package/dist/ui/variants/var_bubble-me.d.ts +12 -12
  290. package/dist/ui/variants/var_bubble-me.js +1 -1
  291. package/dist/ui/variants/var_bubble-them.d.ts +10 -10
  292. package/dist/ui/variants/var_bubble-them.js +1 -1
  293. package/dist/ui/variants/var_button-border.d.ts +61 -61
  294. package/dist/ui/variants/var_button-border.js +1 -1
  295. package/dist/ui/variants/var_button-cta.d.ts +61 -61
  296. package/dist/ui/variants/var_button-cta.js +1 -1
  297. package/dist/ui/variants/var_button-destructive-ghost.d.ts +59 -59
  298. package/dist/ui/variants/var_button-destructive-ghost.js +1 -1
  299. package/dist/ui/variants/var_button-destructive.d.ts +61 -61
  300. package/dist/ui/variants/var_button-destructive.js +1 -1
  301. package/dist/ui/variants/var_button-fill.d.ts +61 -61
  302. package/dist/ui/variants/var_button-fill.js +1 -1
  303. package/dist/ui/variants/var_button-ghost.d.ts +59 -59
  304. package/dist/ui/variants/var_button-ghost.js +1 -1
  305. package/dist/ui/variants/var_button-glass.d.ts +40 -40
  306. package/dist/ui/variants/var_button-glass.js +1 -1
  307. package/dist/ui/variants/var_button-normal.d.ts +61 -61
  308. package/dist/ui/variants/var_button-normal.js +1 -1
  309. package/dist/ui/variants/var_button-quiet.d.ts +63 -63
  310. package/dist/ui/variants/var_button-quiet.js +1 -1
  311. package/dist/ui/variants/var_card.d.ts +17 -17
  312. package/dist/ui/variants/var_card.js +1 -1
  313. package/dist/ui/variants/var_chip.d.ts +10 -10
  314. package/dist/ui/variants/var_chip.js +1 -1
  315. package/dist/ui/variants/var_choice.d.ts +15 -15
  316. package/dist/ui/variants/var_choice.js +1 -1
  317. package/dist/ui/variants/var_framed.d.ts +5 -5
  318. package/dist/ui/variants/var_framed.js +1 -1
  319. package/dist/ui/variants/var_glyph-plain.d.ts +7 -7
  320. package/dist/ui/variants/var_glyph-plain.js +1 -1
  321. package/dist/ui/variants/var_input.d.ts +30 -30
  322. package/dist/ui/variants/var_input.js +1 -1
  323. package/dist/ui/variants/var_link-inline.d.ts +17 -17
  324. package/dist/ui/variants/var_link-inline.js +1 -1
  325. package/dist/ui/variants/var_list-row.d.ts +22 -22
  326. package/dist/ui/variants/var_list-row.js +1 -1
  327. package/dist/ui/variants/var_rule.d.ts +5 -5
  328. package/dist/ui/variants/var_rule.js +1 -1
  329. package/dist/ui/variants/var_skeleton-block.d.ts +9 -9
  330. package/dist/ui/variants/var_skeleton-block.js +1 -1
  331. package/dist/ui/variants/var_spinner-turning.d.ts +9 -9
  332. package/dist/ui/variants/var_spinner-turning.js +1 -1
  333. package/dist/ui/variants/var_stat-tile.d.ts +10 -10
  334. package/dist/ui/variants/var_stat-tile.js +1 -1
  335. package/dist/ui/variants/var_tab-bar.d.ts +14 -14
  336. package/dist/ui/variants/var_tab-bar.js +1 -1
  337. package/dist/ui/variants/var_tap-target.d.ts +11 -11
  338. package/dist/ui/variants/var_tap-target.js +1 -1
  339. package/dist/ui/variants.d.ts +88 -88
  340. package/dist/ui/wrappers.d.ts +7 -6
  341. package/dist/ui/wrappers.js +16 -14
  342. package/dist/ui/wrappers.tsx +21 -18
  343. package/package.json +2 -2
@@ -1,4 +1,4 @@
1
- import { existsSync, readFileSync, writeFileSync } from '@prestack/thread/core/files'
1
+ import { existsSync, readFileSync, writeFileSync } from '@prestack/thread/integrations/disk'
2
2
  import { join, resolve } from 'node:path'
3
3
  import { argv, stdout } from 'node:process'
4
4
  import { fileURLToPath, pathToFileURL } from 'node:url'
@@ -41,7 +41,7 @@ export function translated(
41
41
  tag: string | Readonly<Record<string, string>>,
42
42
  arranges: boolean,
43
43
  raises: readonly string[],
44
- from: { readonly wrappers: string; readonly content: string; readonly rows: string; readonly validators: string; readonly fonts: string; readonly map: string; readonly parts: string; readonly consent: string; readonly drag: string },
44
+ from: { readonly wrappers: string; readonly content: string; readonly rows: string; readonly validators: string; readonly fonts: string; readonly map: string; readonly parts: string; readonly consent: string; readonly drag: string; readonly checked: string },
45
45
  carries: Readonly<Record<string, string>> = {},
46
46
  always: readonly string[] = [],
47
47
  places: Readonly<Record<string, Readonly<Record<string, string>>>> = {},
@@ -66,7 +66,7 @@ export function translated(
66
66
  }
67
67
 
68
68
  const invoking = [
69
- ...(carries['dispatch'] === undefined ? [' readonly dispatch?: string'] : []),
69
+ ...(carries['dispatch'] === undefined ? [' readonly dispatch?: keyof Dispatching'] : []),
70
70
  ...(carries['input'] === undefined ? [' readonly input?: Readonly<Record<string, unknown>>'] : []),
71
71
  " readonly invokeOn?: 'press' | 'shown'",
72
72
  ]
@@ -430,6 +430,7 @@ ${[
430
430
  : []),
431
431
  ].join('\n')}
432
432
 
433
+ import type { Dispatching } from '${from.checked}'
433
434
  import { type Element, element, useSurface } from '${from.wrappers}'
434
435
  ${Object.values(places).some((made) => ((made as Record<string, string> | undefined)?.['takes'] ?? '').split(/\s+/).includes('validator')) ? `import { limited } from '${from.validators}'\n` : ''}${repeats ? `import { Each } from '../elements/each.tsx'\n` : ''}${works === undefined || wanted.length === 0 ? '' : `import { ${wanted.join(', ')} } from '${works}'\n`}
435
436
 
@@ -601,7 +602,7 @@ export const CARRIES: readonly string[] = Object.keys(KINDS)
601
602
 
602
603
  export const READINGS: readonly string[] = Object.keys(READS)
603
604
 
604
- const BESIDE = { wrappers: '../wrappers.tsx', content: '../content.tsx', rows: '../charts.tsx', validators: '../validators.ts', fonts: '../fonts.ts', map: '../islands/map.ts', parts: '../disclosure.tsx', consent: '../consent.ts', drag: '../drag.ts' } as const
605
+ const BESIDE = { wrappers: '../wrappers.tsx', content: '../content.tsx', rows: '../charts.tsx', validators: '../validators.ts', fonts: '../fonts.ts', map: '../islands/map.ts', parts: '../disclosure.tsx', consent: '../consent.ts', drag: '../drag.ts', checked: '../checked.ts' } as const
605
606
 
606
607
  interface Row {
607
608
  readonly id: string
@@ -664,7 +665,7 @@ async function run(): Promise<number> {
664
665
 
665
666
  const held = own
666
667
  ? ((await import(pathToFileURL(resolve(fileURLToPath(import.meta.url), '../../elements.ts')).href)) as {
667
- ELEMENTS?: { readonly declares?: readonly Row[] }
668
+ ELEMENTS?: { readonly derives?: readonly Row[]; readonly declares?: readonly Row[] }
668
669
  })
669
670
  : undefined
670
671
 
@@ -681,7 +682,7 @@ async function run(): Promise<number> {
681
682
  tree === undefined
682
683
  ? { ELEMENT: held?.ELEMENTS }
683
684
  : ((await import(pathToFileURL(inTree(tree, SHEET)).href)) as {
684
- ELEMENT?: { readonly declares?: readonly Row[] }
685
+ ELEMENT?: { readonly derives?: readonly Row[]; readonly declares?: readonly Row[] }
685
686
  })
686
687
 
687
688
  if (sheet.ELEMENT === undefined) {
@@ -696,10 +697,12 @@ async function run(): Promise<number> {
696
697
  const root = findTree().at
697
698
  const from = BESIDE
698
699
 
699
- for (const one of sheet.ELEMENT.declares ?? []) declared.add(one.id)
700
+ const listed = sheet.ELEMENT.derives ?? sheet.ELEMENT.declares ?? []
701
+
702
+ for (const one of listed) declared.add(one.id)
700
703
 
701
704
  const dressed = await variants(own)
702
- for (const one of sheet.ELEMENT.declares ?? []) {
705
+ for (const one of listed) {
703
706
  const held: Record<string, string> = {}
704
707
  for (const row of dressed) {
705
708
  if (!row.wears.includes(pascal(one.id))) continue
@@ -708,7 +711,7 @@ async function run(): Promise<number> {
708
711
  wears.set(one.id, held)
709
712
  }
710
713
 
711
- const rows = (sheet.ELEMENT.declares ?? []).filter((row) => derived(row, own))
714
+ const rows = listed.filter((row) => derived(row, own))
712
715
  const checking = argv.includes('--check')
713
716
 
714
717
  for (const row of rows) {
@@ -6,14 +6,14 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
6
6
  }
7
7
  return path;
8
8
  };
9
- import { existsSync, readFileSync, readdirSync, writeFileSync } from "@prestack/thread/core/files";
9
+ import { existsSync, readFileSync, readdirSync, writeFileSync } from '@prestack/thread/integrations/disk';
10
10
  import { join, relative } from 'node:path';
11
11
  import { argv, stderr, stdout } from 'node:process';
12
12
  import { pathToFileURL } from 'node:url';
13
- import { exit, invoked } from "@prestack/thread/core/invoked";
14
- import { named as packageOf } from "@prestack/thread/core/scope";
15
- import { findTree, inTree } from "@prestack/thread/core/tree";
16
- import { fileFor, languagesIn, sourceIn } from "../localizations.js";
13
+ import { exit, invoked } from '@prestack/thread/core/invoked';
14
+ import { named as packageOf } from '@prestack/thread/core/scope';
15
+ import { findTree, inTree } from '@prestack/thread/core/tree';
16
+ import { fileFor, languagesIn, sourceIn } from '../localizations.js';
17
17
  const GENERATED = `app/_generated/wording.${'ts'}`;
18
18
  const SKIP = new Set(['node_modules', '.next', '.git', 'dist', '_generated']);
19
19
  const CODE = /\.(tsx?|jsx?)$/;
@@ -65,7 +65,7 @@ export function keysIn(text, props) {
65
65
  return [...text.matchAll(named(props))].map((one) => one[1] ?? one[2] ?? '');
66
66
  }
67
67
  async function shipped(at) {
68
- const held = (await import("../i18n/catalogs/en.js"));
68
+ const held = (await import('../i18n/catalogs/en.js'));
69
69
  const made = {};
70
70
  for (const [key, entry] of Object.entries(held.en ?? {})) {
71
71
  made[key] = typeof entry === 'string' ? entry : String(entry.text ?? '');
@@ -105,8 +105,6 @@ function moduleFor(languages, source, used, wording) {
105
105
  ].join('\n');
106
106
  };
107
107
  return [
108
- '/* GENERATED by thread — do not edit. Change the wording in i18n/, or the rows, and regenerate. */',
109
- '',
110
108
  'export type Language =',
111
109
  ...languages.map((one) => ` | ${asJson(one.id)}`),
112
110
  '',
@@ -116,9 +114,6 @@ function moduleFor(languages, source, used, wording) {
116
114
  ...languages.map((one) => ` { id: ${asJson(one.id)}, name: ${asJson(one.name)}, flag: ${asJson(one.flag)} },`),
117
115
  ']',
118
116
  '',
119
- '/*',
120
- ' * Every key this interface names.',
121
- ' */',
122
117
  'export type Used =',
123
118
  ...(used.length === 0 ? [' | never'] : used.map((one) => ` | ${asJson(one)}`)),
124
119
  '',
@@ -126,18 +121,6 @@ function moduleFor(languages, source, used, wording) {
126
121
  ...languages.map((one) => catalogue(one.id)),
127
122
  '} as const',
128
123
  '',
129
- '/*',
130
- ' * AN UNANSWERED KEY IS A TYPE ERROR, NAMING THE LANGUAGE AND THE KEY.',
131
- ' *',
132
- ' * `Filled` is what makes the compiler one of the surfaces that refuses rather than a formality.',
133
- ' * The catalogue above is `as const`, so every value is a literal type — an empty one is the',
134
- ' * literal `""`, which `Filled` maps to `never`, which nothing is assignable to. So a key some',
135
- ' * language has not answered fails HERE, at the line naming both, before anything is run.',
136
- ' *',
137
- ' * Written as an assignment rather than `satisfies`, and that is deliberate: `satisfies` on the',
138
- ' * literal refuses the EXTRA keys too, and there are always extra ones — an app holds every',
139
- ' * message it has, and `Used` is only the ones its markup names.',
140
- ' */',
141
124
  "type Filled<S> = S extends '' ? never : S",
142
125
  '',
143
126
  'type Answered<L extends Language> = {',
@@ -1,4 +1,4 @@
1
- import { existsSync, readFileSync, readdirSync, writeFileSync } from '@prestack/thread/core/files'
1
+ import { existsSync, readFileSync, readdirSync, writeFileSync } from '@prestack/thread/integrations/disk'
2
2
  import { dirname, join, relative } from 'node:path'
3
3
  import { argv, stderr, stdout } from 'node:process'
4
4
  import { pathToFileURL } from 'node:url'
@@ -110,8 +110,6 @@ function moduleFor(
110
110
  }
111
111
 
112
112
  return [
113
- '/* GENERATED by thread — do not edit. Change the wording in i18n/, or the rows, and regenerate. */',
114
- '',
115
113
  'export type Language =',
116
114
  ...languages.map((one) => ` | ${asJson(one.id)}`),
117
115
  '',
@@ -121,9 +119,6 @@ function moduleFor(
121
119
  ...languages.map((one) => ` { id: ${asJson(one.id)}, name: ${asJson(one.name)}, flag: ${asJson(one.flag)} },`),
122
120
  ']',
123
121
  '',
124
- '/*',
125
- ' * Every key this interface names.',
126
- ' */',
127
122
  'export type Used =',
128
123
  ...(used.length === 0 ? [' | never'] : used.map((one) => ` | ${asJson(one)}`)),
129
124
  '',
@@ -131,18 +126,6 @@ function moduleFor(
131
126
  ...languages.map((one) => catalogue(one.id)),
132
127
  '} as const',
133
128
  '',
134
- '/*',
135
- ' * AN UNANSWERED KEY IS A TYPE ERROR, NAMING THE LANGUAGE AND THE KEY.',
136
- ' *',
137
- ' * `Filled` is what makes the compiler one of the surfaces that refuses rather than a formality.',
138
- ' * The catalogue above is `as const`, so every value is a literal type — an empty one is the',
139
- ' * literal `""`, which `Filled` maps to `never`, which nothing is assignable to. So a key some',
140
- ' * language has not answered fails HERE, at the line naming both, before anything is run.',
141
- ' *',
142
- ' * Written as an assignment rather than `satisfies`, and that is deliberate: `satisfies` on the',
143
- ' * literal refuses the EXTRA keys too, and there are always extra ones — an app holds every',
144
- ' * message it has, and `Used` is only the ones its markup names.',
145
- ' */',
146
129
  "type Filled<S> = S extends '' ? never : S",
147
130
  '',
148
131
  'type Answered<L extends Language> = {',
@@ -1,11 +1,11 @@
1
1
  import { createRequire } from 'node:module';
2
- import { existsSync, readdirSync, readFileSync, writeFileSync } from "@prestack/thread/core/files";
3
- import { valuesIn } from "@prestack/thread/core/rows";
2
+ import { existsSync, readdirSync, readFileSync, writeFileSync } from '@prestack/thread/integrations/disk';
3
+ import { valuesIn } from '@prestack/thread/core/rows';
4
4
  import { dirname, join } from 'node:path';
5
5
  import { argv, stderr, stdout } from 'node:process';
6
- import { exit } from "@prestack/thread/core/invoked";
7
- import { findTree, inTree } from "@prestack/thread/core/tree";
8
- import { brandExport, drawnAs, setNamed, sizeRows, SET_ROW } from "../icons.js";
6
+ import { exit } from '@prestack/thread/core/invoked';
7
+ import { findTree, inTree } from '@prestack/thread/core/tree';
8
+ import { brandExport, drawnAs, setNamed, sizeRows, SET_ROW } from '../icons.js';
9
9
  function inside(node) {
10
10
  return [...(node.holds ?? []), ...(node.declares ?? [])];
11
11
  }
@@ -15,8 +15,6 @@ function module(set, drawn, sizes) {
15
15
  return [
16
16
  "'use client'",
17
17
  '',
18
- '/* GENERATED by thread — do not edit. Change the icon rows and regenerate. */',
19
- '',
20
18
  `import { ${names.join(', ')} } from '${set.module}'`,
21
19
  "import { installIcons } from '../icons.ts'",
22
20
  '',
@@ -31,13 +29,6 @@ function module(set, drawn, sizes) {
31
29
  ' },',
32
30
  ')',
33
31
  '',
34
- '/*',
35
- ' * Rendered once by the layout, and that is the point of it.',
36
- ' *',
37
- ' * A bare side-effect import of a client module from a server layout is a client REFERENCE, not',
38
- ' * an evaluation: the install never ran, and every icon refused on a page whose layout plainly',
39
- ' * imported it. Rendering this is what evaluates the module, in the graph the elements run in.',
40
- ' */',
41
32
  'export function ThreadIcons(): null {',
42
33
  ' return null',
43
34
  '}',
@@ -1,6 +1,6 @@
1
1
  import { createRequire } from 'node:module'
2
2
 
3
- import { existsSync, readdirSync, readFileSync, writeFileSync } from '@prestack/thread/core/files'
3
+ import { existsSync, readdirSync, readFileSync, writeFileSync } from '@prestack/thread/integrations/disk'
4
4
  import { valuesIn } from '@prestack/thread/core/rows'
5
5
  import { dirname, join } from 'node:path'
6
6
  import { argv, stderr, stdout } from 'node:process'
@@ -39,8 +39,6 @@ function module(
39
39
 
40
40
  "'use client'",
41
41
  '',
42
- '/* GENERATED by thread — do not edit. Change the icon rows and regenerate. */',
43
- '',
44
42
  `import { ${names.join(', ')} } from '${set.module}'`,
45
43
  "import { installIcons } from '../icons.ts'",
46
44
  '',
@@ -55,13 +53,6 @@ function module(
55
53
  ' },',
56
54
  ')',
57
55
  '',
58
- '/*',
59
- ' * Rendered once by the layout, and that is the point of it.',
60
- ' *',
61
- ' * A bare side-effect import of a client module from a server layout is a client REFERENCE, not',
62
- ' * an evaluation: the install never ran, and every icon refused on a page whose layout plainly',
63
- ' * imported it. Rendering this is what evaluates the module, in the graph the elements run in.',
64
- ' */',
65
56
  'export function ThreadIcons(): null {',
66
57
  ' return null',
67
58
  '}',
@@ -1,11 +1,10 @@
1
1
  import { createHash } from 'node:crypto';
2
- import { readFileSync as bytesAt } from 'node:fs';
3
- import { existsSync, readFileSync, statSync } from "@prestack/thread/core/files";
2
+ import { existsSync, readFileSync, statSync } from '@prestack/thread/integrations/disk';
4
3
  import { cwd } from 'node:process';
5
4
  import { dirname, join, resolve } from 'node:path';
6
5
  import ts from 'typescript';
7
- import { idOf } from "../checked.js";
8
- import { classOf } from "../variant.js";
6
+ import { idOf } from '../checked.js';
7
+ import { classOf } from '../variant.js';
9
8
  const OWNED = /\.(t|j)sx$/;
10
9
  const VARIANT_MEMBER = /^[a-z]/;
11
10
  const ARRANGERS = new Set(['composition', 'screen']);
@@ -193,7 +192,7 @@ export function ungated(from) {
193
192
  const held = JSON.parse(readFileSync(at, 'utf8'));
194
193
  for (const [named, was] of Object.entries(held.of ?? {})) {
195
194
  const now = existsSync(join(dirname(dirname(at)), named))
196
- ? createHash('sha256').update(bytesAt(join(dirname(dirname(at)), named))).digest('hex').slice(0, 16)
195
+ ? createHash('sha256').update(readFileSync(join(dirname(dirname(at)), named))).digest('hex').slice(0, 16)
197
196
  : 'gone';
198
197
  if (now === was)
199
198
  continue;
@@ -1,6 +1,5 @@
1
1
  import { createHash } from 'node:crypto'
2
- import { readFileSync as bytesAt } from 'node:fs'
3
- import { existsSync, readFileSync, statSync } from '@prestack/thread/core/files'
2
+ import { existsSync, readFileSync, statSync } from '@prestack/thread/integrations/disk'
4
3
  import { cwd } from 'node:process'
5
4
  import { dirname, join, resolve } from 'node:path'
6
5
 
@@ -237,7 +236,7 @@ export function ungated(from: string): string | null {
237
236
  const held = JSON.parse(readFileSync(at, 'utf8')) as { of?: Record<string, string> }
238
237
  for (const [named, was] of Object.entries(held.of ?? {})) {
239
238
  const now = existsSync(join(dirname(dirname(at)), named))
240
- ? createHash('sha256').update(bytesAt(join(dirname(dirname(at)), named))).digest('hex').slice(0, 16)
239
+ ? createHash('sha256').update(readFileSync(join(dirname(dirname(at)), named))).digest('hex').slice(0, 16)
241
240
  : 'gone'
242
241
  if (now === was) continue
243
242
  checked = `${named} has changed since the gate last passed, so what this tree declares and what it was measured as no longer agree. Run \`thread gate\``
@@ -1,25 +1,34 @@
1
1
  import { dirname, join, relative } from 'node:path';
2
2
  import { argv, stderr, stdout } from 'node:process';
3
3
  import ts from 'typescript';
4
- import { existsSync, readFileSync, realpathSync, writeFileSync } from "@prestack/thread/core/files";
5
- import { exit, invoked } from "@prestack/thread/core/invoked";
6
- import { valuesIn } from "@prestack/thread/core/rows";
7
- import { named as packageOf } from "@prestack/thread/core/scope";
8
- import { findTree, inTree } from "@prestack/thread/core/tree";
9
- import { PERMITS_AT } from "@prestack/thread/operations/access";
10
- import { COMPILED, compiledAt, nameOf as compositionOf } from "../compositions.js";
11
- import { PRESENTATIONS } from "../door.js";
12
- import { PAGE, entryAmong, nameOf, pageAt, presentedIn, routeFor } from "../screens.js";
13
- import { keyProps } from "./i18n.js";
4
+ import { existsSync, readFileSync, realpathSync, writeFileSync } from '@prestack/thread/integrations/disk';
5
+ import { exit, invoked } from '@prestack/thread/core/invoked';
6
+ import { valuesIn } from '@prestack/thread/core/rows';
7
+ import { named as packageOf } from '@prestack/thread/core/scope';
8
+ import { findTree, inTree } from '@prestack/thread/core/tree';
9
+ import { PERMITS_AT } from '@prestack/thread/operations/access';
10
+ import { COMPILED, compiledAt, nameOf as compositionOf } from '../compositions.js';
11
+ import { PRESENTATIONS } from '../door.js';
12
+ import { PAGE, entryAmong, nameOf, pageAt, presentedIn, routeFor } from '../screens.js';
13
+ import { keyProps } from './i18n.js';
14
14
  const LAYOUT = `app/layout.${'tsx'}`;
15
15
  const WORDING = `app/_generated/wording.${'ts'}`;
16
- const DECLARED = `src/_generated/seams.${'ts'}`;
16
+ const DECLARED = 'src/_generated/reaching.' + 'ts';
17
17
  const CLIENT = `app/_generated/dispatching.${'ts'}`;
18
18
  const DOOR = `app/_generated/door.${'tsx'}`;
19
19
  const MAP = `app/_generated/map.${'ts'}`;
20
20
  const PROVIDER = `${COMPILED}/ui/provider.tsx`;
21
21
  const GRAMMAR = `${COMPILED}/ui/islands/map.ts`;
22
22
  const MOVES = 'navigateTo';
23
+ function served(at) {
24
+ try {
25
+ const held = JSON.parse(readFileSync(join(at, 'package.json'), 'utf8'));
26
+ return Object.values(held.scripts ?? {}).some((one) => /(?:^|[\s;&|])next(?:\s|$)/.test(one));
27
+ }
28
+ catch {
29
+ return false;
30
+ }
31
+ }
23
32
  const sheetAt = (at) => {
24
33
  if (!existsSync(at))
25
34
  return {};
@@ -32,8 +41,6 @@ function door(knowing, wording, dispatching, moving, presenting) {
32
41
  return [
33
42
  "'use client'",
34
43
  '',
35
- '/* GENERATED by thread — do not edit. It is derived from what this app declares. */',
36
- '',
37
44
  ...(moving || knowing
38
45
  ? [
39
46
  `import { useCallback, ${moving && opening ? 'useState, ' : ''}type ReactNode } from 'react'`,
@@ -266,8 +273,6 @@ function mapModule(map) {
266
273
  `entry: ${String(one.entry)}, shows: [${one.shows.map(quoted).join(', ')}] },`;
267
274
  const link = (one) => ` { from: ${quoted(one.from)}, to: ${quoted(one.to)}${one.labelKey === undefined ? '' : `, labelKey: ${quoted(one.labelKey)}`} },`;
268
275
  return [
269
- '/* GENERATED by thread — do not edit. It is derived from the screens, and from every navigateTo they and their compositions hold. */',
270
- '',
271
276
  `import type { MapIsland } from '${reaching(MAP, GRAMMAR)}'`,
272
277
  '',
273
278
  'export const MAP: MapIsland = {',
@@ -302,8 +307,6 @@ function reaching(file, at) {
302
307
  function page(name, at, route) {
303
308
  const from = reaching(pageAt(route), compiledAt(at));
304
309
  return [
305
- '/* GENERATED by thread — do not edit. It follows from the screen\'s name and its place among the pages. */',
306
- '',
307
310
  `import { ${name} } from '${from}'`,
308
311
  '',
309
312
  'export default function Page() {',
@@ -323,7 +326,7 @@ function gate(typed) {
323
326
  'if (!existsSync(receipt)) {',
324
327
  ' throw new Error(',
325
328
  " 'thread: this tree has no passing gate, so nothing in it may compile. Run `thread gate` — or the ' +",
326
- " 'dev, build and start scripts, which run it for you. A gate that has never run is not a gate that passed.',",
329
+ " 'thread dev, which runs it before anything is served. A gate that has never run is not a gate that passed.',",
327
330
  ' )',
328
331
  '}',
329
332
  "const passed = Symbol.for('thread.gate')",
@@ -346,10 +349,6 @@ function gate(typed) {
346
349
  }
347
350
  function layout(wording, icons, source, knowing, doored) {
348
351
  return [
349
- '/* GENERATED by thread — do not edit. It is derived from what the other generators produce. */',
350
- '',
351
- '/// <reference types="next/types/global" />',
352
- '',
353
352
  ...gate(true),
354
353
  "import type { ReactNode } from 'react'",
355
354
  ...(doored ? ["import { Door } from './_generated/door.tsx'"] : [`import { ThreadUi } from '${reaching(LAYOUT, PROVIDER)}'`]),
@@ -426,11 +425,11 @@ function externalFor(at) {
426
425
  const path = join(dirname(wiring), (one ?? '').replace(/\.tsx?$/, '')) + '.ts';
427
426
  return [path, read(path)];
428
427
  });
429
- const SEAM = /export\s+const\s+store\s*:/;
428
+ const STORE = /export\s+const\s+store\s*:/;
430
429
  for (const [where, text] of [[wiring, wiredIn], ...reachable]) {
431
430
  const held = DRIVER.exec(text)?.[1];
432
431
  if (held === undefined) {
433
- if (where === wiring || !SEAM.test(text))
432
+ if (where === wiring || !STORE.test(text))
434
433
  continue;
435
434
  stderr.write(`routes: ${relative(at, where)} declares a store and does not say what must stay out of the bundle. ` +
436
435
  'A store opens something, and a config written without that entry breaks where the driver is used rather ' +
@@ -451,8 +450,6 @@ function config(root, external) {
451
450
  ...(root === undefined ? [] : [` root: join(import.meta.dirname, ${JSON.stringify(root)}),`]),
452
451
  ];
453
452
  return [
454
- '/* GENERATED by thread — do not edit. It is derived from where the packages resolve. */',
455
- '',
456
453
  ...gate(false),
457
454
  'export default {',
458
455
  ...(turbopack.length === 0 ? [] : [' turbopack: {', ...turbopack, ' },']),
@@ -464,12 +461,51 @@ function config(root, external) {
464
461
  '',
465
462
  ].join('\n');
466
463
  }
464
+ function landed(at, made) {
465
+ if (!argv.includes('--check')) {
466
+ for (const one of made)
467
+ writeFileSync(join(at, one.path), one.text, 'utf8');
468
+ return undefined;
469
+ }
470
+ for (const one of SHADOWS) {
471
+ if (!existsSync(join(at, one)))
472
+ continue;
473
+ stderr.write(`routes: ${one} sits beside ${CONFIG}, and Next loads ${CONFIG} because it is the first name it ` +
474
+ `looks for. Nothing reads ${one} — an edit to it changes nothing and says nothing. Delete it.\n`);
475
+ return 1;
476
+ }
477
+ for (const one of made) {
478
+ let current = '';
479
+ try {
480
+ current = readFileSync(join(at, one.path), 'utf8');
481
+ }
482
+ catch {
483
+ current = '';
484
+ }
485
+ if (current === one.text)
486
+ continue;
487
+ stderr.write(`routes: ${one.path} is not what the declarations produce. A derived file that differs from its ` +
488
+ 'generator is a hand edit wearing a generated name. Run `thread routes` and commit what it writes.\n');
489
+ return 1;
490
+ }
491
+ return undefined;
492
+ }
467
493
  async function run() {
468
494
  const tree = findTree();
469
495
  const at = tree.at;
470
496
  const screensAt = inTree(tree, `screens.${'ts'}`);
471
497
  if (!existsSync(screensAt)) {
472
- stdout.write(`routes: this tree has no ${relative(at, screensAt)}, so it declares no screen and there is no map, page or layout to write or check.\n`);
498
+ if (!served(at)) {
499
+ stdout.write(`routes: this tree has no ${relative(at, screensAt)} and its manifest runs no page server, so it declares ` +
500
+ 'no screen and there is nothing to write or check.\n');
501
+ return 0;
502
+ }
503
+ const only = [{ path: CONFIG, text: config(rootFor(at), externalFor(at)) }];
504
+ const refused = landed(at, only);
505
+ if (refused !== undefined)
506
+ return refused;
507
+ stdout.write(`routes: ${CONFIG} ${argv.includes('--check') ? 'is what the declarations produce' : 'written'} — this tree ` +
508
+ `declares no screen, and Next serves it all the same.\n`);
473
509
  return 0;
474
510
  }
475
511
  const sheet = valuesIn(readFileSync(screensAt));
@@ -573,36 +609,15 @@ async function run() {
573
609
  });
574
610
  const paged = map.screens.filter((one) => one.path !== undefined).length;
575
611
  const counted = `${String(map.screens.length)} screen(s), ${String(paged)} route(s), ${String(map.links.length)} link(s)`;
612
+ const refused = landed(at, made);
613
+ if (refused !== undefined)
614
+ return refused;
576
615
  if (argv.includes('--check')) {
577
- for (const one of SHADOWS) {
578
- if (!existsSync(join(at, one)))
579
- continue;
580
- stderr.write(`routes: ${one} sits beside ${CONFIG}, and Next loads ${CONFIG} because it is the first name it ` +
581
- `looks for. Nothing reads ${one} — an edit to it changes nothing and says nothing. Delete it.\n`);
582
- return 1;
583
- }
584
- for (const one of made) {
585
- let current = '';
586
- try {
587
- current = readFileSync(join(at, one.path), 'utf8');
588
- }
589
- catch {
590
- current = '';
591
- }
592
- if (current === one.text)
593
- continue;
594
- stderr.write(`routes: ${one.path} is not what the declarations produce. A derived file that differs from its ` +
595
- 'generator is a hand edit wearing a generated name. Run `thread routes` and commit what it writes.\n');
596
- return 1;
597
- }
598
616
  stdout.write(`routes: ${String(made.length)} file(s) are what the screens produce — ${counted}\n`);
599
617
  for (const line of shown(map))
600
618
  stdout.write(`${line}\n`);
601
619
  return 0;
602
620
  }
603
- for (const one of made) {
604
- writeFileSync(join(at, one.path), one.text, 'utf8');
605
- }
606
621
  stdout.write(`routes: the map — ${counted}\n`);
607
622
  for (const line of shown(map))
608
623
  stdout.write(`${line}\n`);