Commit 31ab42e
authored
fix(appkit): non-blocking typegen on Analytics (#406)
* fix(appkit): don't crash typegen when the warehouse is unreachable
Type generation threw an uncaught error whenever the SQL warehouse was
down. Every DESCRIBE QUERY failed, all queries degraded to an unknown
result, and generateFromEntryPoint unconditionally threw an aggregate
"Type generation failed" error that escaped uncaught at the Vite plugin
(un-awaited generate()) and the CLI (sync cmd.parse()) call sites.
Distinguish connectivity failures from genuine SQL errors:
- Connectivity (executeStatement rejects): degrade silently. Reuse the
last-known-good cached type if present, otherwise emit an unknown
result. Never fatal, so a transient outage no longer fails a build.
- SQL error (reachable warehouse, DESCRIBE FAILED): surface via a typed
TypegenSyntaxError so the existing prod-throws / dev-warns gate
applies. Eligible to fail prod builds only.
Also stop caching unknown results: only successful describes with a
result schema are persisted, so a transient outage never poisons the
cache and a fixed query recovers on the next run.
PR1 of 2 (user-visible behavior). PR2 will await the Vite
buildStart/watcher, use parseAsync().catch() in the CLI, and add
degrade/throw regression tests.
Co-authored-by: Isaac
Signed-off-by: Atila Fassina <atila@fassina.eu>
* test(appkit): cover typegen warehouse-down classification and throw seam
Add the regression coverage the warehouse-down crash slipped through: the
prior suite tested rejection->unknown as graceful but never connected it to
the aggregate throw in generateFromEntryPoint.
query-registry (generate-queries.test.ts):
- connectivity reuses the last-known-good cached type
- empty result (described, no columns) -> unknown, not syntax, not cached
- syntax (FAILED) -> recorded in syntaxErrors, not cached
- cache HIT serves the stored type without a warehouse call
- legacy retry-flagged entry is re-described, not reused
- mixed run records only the syntax failure; failures are not persisted
generateFromEntryPoint (index.test.ts):
- syntax errors throw TypegenSyntaxError
- connectivity-only failures do NOT throw (the warehouse-down regression)
- the .d.ts is written before the throw
Layers 1+2 of the test plan; Layer 3 (analytics vite-plugin) and Layer 4
(CLI exit codes) land in PR2 with their await/parseAsync refactors.
Co-authored-by: Isaac
Signed-off-by: Atila Fassina <atila@fassina.eu>
* fix: classify typegen describe rejections
Signed-off-by: Atila Fassina <atila@fassina.eu>
* fix(appkit): harden typegen describe error handling
Signed-off-by: Atila Fassina <atila@fassina.eu>
* feat(appkit): warehouse-aware typegen pre-flight
Add a warehouse-status pre-flight to typegen and rework error handling so a
stopped, starting, or unreachable warehouse degrades gracefully instead of
crashing or emitting EMPTY types.
- Classify connectivity (incl. the SDK's "Can't connect to <url>"/code-500 DNS
wrapper) as OFFLINE, and non-terminal describe states (PENDING/RUNNING) as
degraded rather than EMPTY.
- Surface typegen errors as their actionable message (no internal stack trace);
format and de-duplicate the failure output.
- Add a warehouse status probe + pure pre-flight policy; block in the CLI/build,
roll forward (degrade) in dev.
- Dev: regenerate types in the background once the warehouse reaches RUNNING
(single-flight guarded); auto-start a stopped warehouse in dev.
- CLI: --no-block degrades instead of describing so postinstall never blocks.
Co-authored-by: Isaac
Signed-off-by: Atila Fassina <atila@fassina.eu>
* refactor(appkit): collapse typegen pre-flight modes to non-blocking|blocking
Replace the dev/blocking/degrade modes with two: non-blocking (default) and
blocking. non-blocking always degrades (skip probe + DESCRIBE, write cache-or-
unknown instantly); blocking keeps the current probe+wait flow. The CLI default
flips to non-blocking and --no-block becomes a positive --block flag. The dev
plugin runs the foreground in non-blocking (instant degrade) while its
background warehouse-watch regenerates in blocking so real types still land.
Co-authored-by: Isaac
Signed-off-by: Atila Fassina <atila@fassina.eu>
* feat(appkit): blocking typegen auto-starts a stopped warehouse and waits
In blocking mode a STOPPED/STOPPING warehouse is now started and waited on
(startWaitProceed: startWarehouse -> waitUntilRunning -> describe) instead of
failing fast. Only DELETED/DELETING is fatal. STARTING still waits; RUNNING
describes. The write-the-.d.ts-then-throw invariant is preserved for the fatal
and wait-timeout paths.
Co-authored-by: Isaac
Signed-off-by: Atila Fassina <atila@fassina.eu>
* fix(appkit): dev typegen background-describes a running warehouse
The dev background lifecycle returned early for RUNNING, a leftover from when
the foreground described it synchronously. Now that the foreground always
degrades instantly (non-blocking), RUNNING must also background-describe or a
running warehouse never gets real types in dev. Only DELETED/DELETING leaves
degraded; single-flight coalescing and abort-on-shutdown are preserved.
Co-authored-by: Isaac
Signed-off-by: Atila Fassina <atila@fassina.eu>
* feat(appkit): non-blocking typegen CLI spawns a detached blocking worker
The default (non-blocking) generate-types now writes degraded types, then spawns
a detached `generate-types --block` worker behind a single-flight lock and exits
0 -- so postinstall/predev never block on warehouse state. The worker does the
full blocking lifecycle in the background, refreshes real types, and releases the
lock on exit (process-exit guard covers a hard fail). A stale lock from a crashed
worker is stolen after 6 min; spawn failure is non-fatal to the foreground.
Co-authored-by: Isaac
Signed-off-by: Atila Fassina <atila@fassina.eu>
* chore(appkit): wire app template to non-blocking typegen, document --block
Template postinstall/predev now run the non-blocking default `appkit
generate-types` (instant degrade + background refresh) instead of a dedicated
no-block script; prebuild keeps `--block` for accurate CI types. Removed the now
redundant `typegen:no-block` script. Documented the non-blocking default and the
`--block` flag in the type-generation guide.
Co-authored-by: Isaac
Signed-off-by: Atila Fassina <atila@fassina.eu>
* fix(appkit): don't print typegen SQL errors twice
A failed DESCRIBE logged the raw SQL error message per query during the describe
loop, and the aggregated TypegenSyntaxError (printed by the Vite plugin / CLI)
carries the same message in its formatted block -- so every SQL syntax error
showed up twice in dev. Drop the per-query warn; the formatted block and the
summary table already surface it.
Co-authored-by: Isaac
Signed-off-by: Atila Fassina <atila@fassina.eu>
* fix(appkit): forward execArgv so the detached typegen worker runs under tsx
The non-blocking CLI spawned its background worker as `node <argv[1]>` without
the parent's node/loader flags. Run from source via tsx, argv[1] is a .ts file
that plain node can't parse, so the worker died silently (detached + stdio
ignore) and the degraded types never refreshed -- the queries appeared to never
run. Forward process.execArgv, which carries tsx's --require/--import loader
flags (and is empty for the built bin, so production is unaffected), so the
worker runs under the same runtime as the parent.
Co-authored-by: Isaac
Signed-off-by: Atila Fassina <atila@fassina.eu>
* refactor(appkit): rename typegen --block flag to --wait
Rename the user-facing CLI flag --block to --wait (commander option property
block -> wait), including the detached worker's self-spawn arg, the --help
example, the template prebuild script, and the type-generation guide. The
internal "blocking"/"non-blocking" PreflightMode names are unchanged -- they
describe runtime behaviour and aren't user-facing. The flag only ever existed
on this branch (unreleased), so no deprecation alias is needed.
Co-authored-by: Isaac
Signed-off-by: Atila Fassina <atila@fassina.eu>
---------
Signed-off-by: Atila Fassina <atila@fassina.eu>1 parent 2609f34 commit 31ab42e
19 files changed
Lines changed: 3490 additions & 157 deletions
File tree
- docs/docs/development
- packages
- appkit/src/type-generator
- tests
- template
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
72 | 72 | | |
73 | 73 | | |
74 | 74 | | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
75 | 87 | | |
76 | 88 | | |
77 | 89 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
| 4 | + | |
4 | 5 | | |
5 | 6 | | |
6 | 7 | | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
| 11 | + | |
10 | 12 | | |
11 | 13 | | |
12 | | - | |
| 14 | + | |
13 | 15 | | |
14 | 16 | | |
15 | 17 | | |
16 | 18 | | |
17 | 19 | | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
18 | 167 | | |
19 | 168 | | |
20 | 169 | | |
| |||
57 | 206 | | |
58 | 207 | | |
59 | 208 | | |
| 209 | + | |
60 | 210 | | |
61 | | - | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
62 | 218 | | |
63 | 219 | | |
64 | 220 | | |
65 | 221 | | |
66 | 222 | | |
67 | | - | |
68 | | - | |
69 | | - | |
70 | | - | |
71 | | - | |
72 | | - | |
73 | | - | |
74 | | - | |
75 | | - | |
76 | | - | |
77 | | - | |
78 | | - | |
79 | | - | |
80 | | - | |
81 | | - | |
82 | | - | |
83 | | - | |
84 | | - | |
85 | | - | |
86 | | - | |
87 | | - | |
88 | | - | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
89 | 233 | | |
90 | 234 | | |
91 | 235 | | |
| |||
97 | 241 | | |
98 | 242 | | |
99 | 243 | | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
100 | 255 | | |
101 | 256 | | |
102 | 257 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
0 commit comments