@stacksjs/stx 0.2.154 → 0.2.156

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 (240) hide show
  1. package/dist/a11y.d.ts +87 -46
  2. package/dist/animation.d.ts +96 -42
  3. package/dist/appearance-bootstrap.d.ts +49 -15
  4. package/dist/asset-roots.d.ts +32 -0
  5. package/dist/asset-roots.js +7 -0
  6. package/dist/assets.d.ts +9 -7
  7. package/dist/async-components.d.ts +78 -56
  8. package/dist/auth.d.ts +3 -0
  9. package/dist/build-externalize.d.ts +40 -0
  10. package/dist/build-externalize.js +63 -0
  11. package/dist/build-id.d.ts +22 -22
  12. package/dist/build-message.d.ts +73 -2
  13. package/dist/build-message.js +47 -8
  14. package/dist/builtins/attrs.d.ts +14 -0
  15. package/dist/builtins/drawer.d.ts +22 -0
  16. package/dist/builtins/icon.d.ts +16 -2
  17. package/dist/builtins/index.d.ts +5 -15
  18. package/dist/builtins/modal.d.ts +24 -0
  19. package/dist/builtins/safe-image.d.ts +42 -0
  20. package/dist/builtins/stx-image.d.ts +27 -0
  21. package/dist/builtins/stx-link.d.ts +9 -0
  22. package/dist/builtins/stx-loading-indicator.d.ts +11 -0
  23. package/dist/builtins/suspense.d.ts +28 -0
  24. package/dist/builtins/toast.d.ts +17 -0
  25. package/dist/builtins/transition-group.d.ts +25 -0
  26. package/dist/caching.d.ts +12 -15
  27. package/dist/cli.js +1798 -908
  28. package/dist/client/directive.d.ts +7 -0
  29. package/dist/client/index.d.ts +0 -1
  30. package/dist/client-script-bundler.d.ts +63 -5
  31. package/dist/client-script-bundler.js +30 -2
  32. package/dist/client-script.d.ts +102 -47
  33. package/dist/client-script.js +15 -3
  34. package/dist/codemod.d.ts +56 -0
  35. package/dist/codemod.js +192 -0
  36. package/dist/color-mode-boot.d.ts +83 -65
  37. package/dist/component-client-factories.d.ts +1 -6
  38. package/dist/component-processing.d.ts +58 -49
  39. package/dist/component-processing.js +1 -1
  40. package/dist/component-registry.d.ts +94 -31
  41. package/dist/component-renderer.d.ts +18 -0
  42. package/dist/composable-loader.d.ts +24 -0
  43. package/dist/composable-loader.js +12 -9
  44. package/dist/composables/index.d.ts +7 -0
  45. package/dist/composables/index.js +1 -0
  46. package/dist/composables/use-fetch.js +30 -2
  47. package/dist/composables/use-form.d.ts +91 -0
  48. package/dist/composables/use-form.js +112 -0
  49. package/dist/composables.d.ts +64 -60
  50. package/dist/computed.d.ts +86 -92
  51. package/dist/conditionals.d.ts +24 -8
  52. package/dist/conditionals.js +16 -0
  53. package/dist/config.d.ts +34 -21
  54. package/dist/config.js +35 -14
  55. package/dist/craft.js +1476 -768
  56. package/dist/crosswind-config.d.ts +58 -0
  57. package/dist/crosswind-config.js +40 -0
  58. package/dist/csp.d.ts +107 -41
  59. package/dist/defer.d.ts +24 -0
  60. package/dist/dev-server/crosswind.d.ts +35 -26
  61. package/dist/dev-server/crosswind.js +2 -18
  62. package/dist/dev-server/serve-app.js +4 -3
  63. package/dist/dev-server/terminal-colors.d.ts +32 -32
  64. package/dist/directive-api.d.ts +86 -43
  65. package/dist/document-shell.d.ts +54 -41
  66. package/dist/dynamic-components.d.ts +9 -0
  67. package/dist/error-boundaries.d.ts +47 -41
  68. package/dist/error-handling.d.ts +1 -1
  69. package/dist/errors/codes.d.ts +51 -43
  70. package/dist/errors/formatter.d.ts +58 -38
  71. package/dist/errors/index.d.ts +5 -61
  72. package/dist/errors/logger.d.ts +114 -40
  73. package/dist/errors/sanitizer.d.ts +53 -23
  74. package/dist/errors/types.d.ts +44 -31
  75. package/dist/events.d.ts +86 -25
  76. package/dist/expressions.d.ts +50 -42
  77. package/dist/forms-validation.d.ts +138 -123
  78. package/dist/forms-validation.js +1 -90
  79. package/dist/forms.d.ts +120 -66
  80. package/dist/forms.js +31 -11
  81. package/dist/fragment-container.d.ts +57 -0
  82. package/dist/fragment-container.js +109 -0
  83. package/dist/framework-composables.d.ts +32 -0
  84. package/dist/head.d.ts +156 -114
  85. package/dist/heatmap.d.ts +152 -72
  86. package/dist/html-masking.d.ts +40 -34
  87. package/dist/hydration-runtime.d.ts +20 -24
  88. package/dist/i18n.d.ts +93 -32
  89. package/dist/image-optimization/auto-sibling.d.ts +32 -4
  90. package/dist/includes.d.ts +69 -7
  91. package/dist/index.d.ts +66 -0
  92. package/dist/index.js +23 -0
  93. package/dist/internal-markdown.d.ts +12 -8
  94. package/dist/island-chunking.d.ts +30 -13
  95. package/dist/keep-alive.d.ts +72 -52
  96. package/dist/layout-types.d.ts +45 -0
  97. package/dist/layout-types.js +56 -0
  98. package/dist/lazy-module.d.ts +10 -0
  99. package/dist/loops.d.ts +66 -0
  100. package/dist/loops.js +47 -6
  101. package/dist/markdown.d.ts +0 -1
  102. package/dist/media/image/component.d.ts +25 -9
  103. package/dist/media/image/directive.d.ts +15 -1
  104. package/dist/media/image/placeholder.d.ts +20 -9
  105. package/dist/media/image/processor/cache.d.ts +40 -18
  106. package/dist/media/image/processor/index.d.ts +1 -10
  107. package/dist/media/image/processor/optimizer.d.ts +12 -1
  108. package/dist/media/image/processor/responsive.d.ts +16 -6
  109. package/dist/media/image/srcset.d.ts +47 -50
  110. package/dist/media/shared/cache.d.ts +51 -31
  111. package/dist/media/shared/hash.d.ts +7 -0
  112. package/dist/media/types.d.ts +1235 -754
  113. package/dist/media/video/directive.d.ts +15 -1
  114. package/dist/media/video/index.d.ts +39 -17
  115. package/dist/media/video/processor/cache.d.ts +42 -19
  116. package/dist/media/video/processor/index.d.ts +1 -18
  117. package/dist/media/video/processor/streaming.d.ts +17 -10
  118. package/dist/media/video/processor/thumbnail.d.ts +21 -15
  119. package/dist/media/video/processor/transcoder.d.ts +11 -1
  120. package/dist/method-spoofing.d.ts +7 -0
  121. package/dist/middleware.d.ts +60 -0
  122. package/dist/owned-routes.d.ts +42 -0
  123. package/dist/owned-routes.js +26 -0
  124. package/dist/page-meta.d.ts +38 -0
  125. package/dist/page-meta.js +16 -0
  126. package/dist/parser/directive-parser.d.ts +57 -45
  127. package/dist/parser/expression-parser.d.ts +33 -35
  128. package/dist/parser/index.d.ts +4 -39
  129. package/dist/parser/tokenizer.d.ts +61 -49
  130. package/dist/partial-hydration.d.ts +82 -50
  131. package/dist/performance-utils.d.ts +217 -124
  132. package/dist/placeholder.d.ts +18 -9
  133. package/dist/plugin-system.d.ts +264 -115
  134. package/dist/process.d.ts +11 -6
  135. package/dist/process.js +21 -4
  136. package/dist/production-builder.js +7 -0
  137. package/dist/prop-sentinels.d.ts +11 -11
  138. package/dist/public-env.d.ts +14 -0
  139. package/dist/pwa/directives.d.ts +12 -3
  140. package/dist/pwa/inject.d.ts +10 -0
  141. package/dist/pwa/precache.d.ts +22 -16
  142. package/dist/pwa/service-worker.d.ts +12 -0
  143. package/dist/pwa.js +1318 -610
  144. package/dist/reactive-bindings.d.ts +34 -11
  145. package/dist/reactive.d.ts +58 -30
  146. package/dist/reactive.js +56 -31
  147. package/dist/render.js +1 -0
  148. package/dist/route-middleware.d.ts +2 -35
  149. package/dist/route-types.d.ts +134 -0
  150. package/dist/route-types.js +24 -0
  151. package/dist/router.d.ts +5 -7
  152. package/dist/routes.d.ts +1 -3
  153. package/dist/runtime-globals.d.ts +147 -24
  154. package/dist/runtime-globals.js +16 -1
  155. package/dist/runtime-injection.d.ts +8 -0
  156. package/dist/runtime-injection.js +33 -24
  157. package/dist/script-emit.d.ts +30 -0
  158. package/dist/script-json.d.ts +36 -0
  159. package/dist/script-json.js +6 -0
  160. package/dist/script-validation.d.ts +21 -4
  161. package/dist/seo.d.ts +118 -47
  162. package/dist/server-bindings.d.ts +21 -0
  163. package/dist/sfc-template.d.ts +8 -8
  164. package/dist/signal-processing.d.ts +35 -15
  165. package/dist/signals-api.d.ts +117 -58
  166. package/dist/signals-api.js +7 -4
  167. package/dist/signals.d.ts +24 -17
  168. package/dist/signals.js +765 -60
  169. package/dist/site-builder/build.js +8 -0
  170. package/dist/site-url.d.ts +46 -0
  171. package/dist/site-url.js +70 -0
  172. package/dist/slots.d.ts +86 -20
  173. package/dist/source-signature.d.ts +45 -0
  174. package/dist/source-signature.js +20 -0
  175. package/dist/ssg.d.ts +285 -142
  176. package/dist/ssg.js +1268 -556
  177. package/dist/state-dir.d.ts +4 -4
  178. package/dist/state-management.d.ts +0 -12
  179. package/dist/state-management.js +8 -25
  180. package/dist/store-imports.d.ts +23 -0
  181. package/dist/store-imports.js +3 -0
  182. package/dist/store-loader.d.ts +10 -0
  183. package/dist/store-loader.js +10 -9
  184. package/dist/story/analytics.d.ts +138 -60
  185. package/dist/story/bookmarks.d.ts +87 -34
  186. package/dist/story/cli.d.ts +123 -69
  187. package/dist/story/collect/scanner.d.ts +4 -0
  188. package/dist/story/collect/tree.d.ts +8 -1
  189. package/dist/story/commands/build.d.ts +11 -6
  190. package/dist/story/commands/dev.d.ts +15 -8
  191. package/dist/story/commands/preview.d.ts +13 -7
  192. package/dist/story/config-watcher.d.ts +20 -13
  193. package/dist/story/config.d.ts +11 -8
  194. package/dist/story/context.d.ts +14 -8
  195. package/dist/story/hmr.d.ts +24 -26
  196. package/dist/story/hot-swap.d.ts +34 -23
  197. package/dist/story/keyboard-shortcuts.d.ts +23 -18
  198. package/dist/story/output.d.ts +46 -44
  199. package/dist/story/performance.d.ts +107 -45
  200. package/dist/story/presets.d.ts +107 -41
  201. package/dist/story/renderer.d.ts +41 -27
  202. package/dist/story/search.d.ts +23 -12
  203. package/dist/story/server.d.ts +21 -11
  204. package/dist/story/setup.d.ts +23 -15
  205. package/dist/story/testing.d.ts +65 -40
  206. package/dist/story/types.d.ts +262 -160
  207. package/dist/streaming.d.ts +119 -57
  208. package/dist/stx-virtual-ts.d.ts +165 -0
  209. package/dist/stx-virtual-ts.js +372 -0
  210. package/dist/stx.d.ts +78 -1
  211. package/dist/style-scoping.d.ts +17 -4
  212. package/dist/suspense.d.ts +67 -52
  213. package/dist/teleport.d.ts +22 -0
  214. package/dist/template-tag-balance.d.ts +22 -6
  215. package/dist/transitions.d.ts +66 -55
  216. package/dist/typecheck.d.ts +77 -0
  217. package/dist/typecheck.js +156 -0
  218. package/dist/types/component-types.d.ts +187 -122
  219. package/dist/types/config-types.d.ts +758 -297
  220. package/dist/types/context-types.d.ts +46 -24
  221. package/dist/types/csp-types.d.ts +70 -66
  222. package/dist/types/directive-types.d.ts +211 -155
  223. package/dist/types/index.d.ts +6 -109
  224. package/dist/types/pwa-types.d.ts +273 -148
  225. package/dist/types.d.ts +0 -1
  226. package/dist/typescript-templates.d.ts +11 -0
  227. package/dist/unresolved-identifiers.d.ts +24 -22
  228. package/dist/unresolved-identifiers.js +2 -0
  229. package/dist/utils.d.ts +24 -21
  230. package/dist/validator.d.ts +28 -26
  231. package/dist/variable-extractor.d.ts +48 -13
  232. package/dist/variable-extractor.js +27 -4
  233. package/dist/view-composers.d.ts +80 -81
  234. package/dist/virtual-scrolling.d.ts +101 -81
  235. package/dist/vue-template.d.ts +23 -0
  236. package/dist/web-components/css-scoping.d.ts +21 -11
  237. package/dist/web-components.d.ts +81 -58
  238. package/dist/x-element.d.ts +0 -1
  239. package/package.json +5 -5
  240. package/stx.d.ts +78 -1
@@ -0,0 +1,63 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ export const EXTERNALIZED_ASSET_DIR = "_stx";
4
+ function contentHash(source) {
5
+ return Bun.hash(source).toString(16).slice(0, 8);
6
+ }
7
+ function listHtmlFiles(dir) {
8
+ const found = [], walk = (current) => {
9
+ for (const entry of fs.readdirSync(current, { withFileTypes: !0 })) {
10
+ const full = path.join(current, entry.name);
11
+ if (entry.isDirectory())
12
+ walk(full);
13
+ else if (entry.isFile() && full.endsWith(".html"))
14
+ found.push(full);
15
+ }
16
+ };
17
+ if (fs.existsSync(dir))
18
+ walk(dir);
19
+ return found;
20
+ }
21
+ export function externalizeSharedAssets(outDir) {
22
+ const result = { pages: 0, assets: 0, bytesInlined: 0 }, assetDir = path.join(outDir, EXTERNALIZED_ASSET_DIR), written = new Set, writeAsset = (filename, contents) => {
23
+ if (written.has(filename))
24
+ return;
25
+ written.add(filename);
26
+ fs.mkdirSync(assetDir, { recursive: !0 });
27
+ fs.writeFileSync(path.join(assetDir, filename), contents);
28
+ result.assets++;
29
+ };
30
+ for (const file of listHtmlFiles(outDir)) {
31
+ const original = fs.readFileSync(file, "utf8");
32
+ let html = original;
33
+ html = html.replace(/<script\b([^>]*\bdata-stx-runtime\b[^>]*)>([\s\S]*?)<\/script>/gi, (whole, attrs, body) => {
34
+ if (/\bsrc\s*=/.test(attrs) || !body.trim())
35
+ return whole;
36
+ const filename = `runtime.${contentHash(body)}.js`;
37
+ writeAsset(filename, body);
38
+ result.bytesInlined += body.length;
39
+ return `<script data-stx-runtime src="/${EXTERNALIZED_ASSET_DIR}/${filename}"></script>`;
40
+ });
41
+ html = html.replace(/<script\b([^>]*\bdata-stx-router\b[^>]*)>([\s\S]*?)<\/script>/gi, (whole, attrs, body) => {
42
+ if (/\bsrc\s*=/.test(attrs) || !body.trim())
43
+ return whole;
44
+ const filename = `router.${contentHash(body)}.js`;
45
+ writeAsset(filename, body);
46
+ result.bytesInlined += body.length;
47
+ return `<script data-stx-router src="/${EXTERNALIZED_ASSET_DIR}/${filename}"></script>`;
48
+ });
49
+ html = html.replace(/<style\b([^>]*\bdata-crosswind=(?:"generated"|'generated')[^>]*)>([\s\S]*?)<\/style>/gi, (whole, _attrs, css) => {
50
+ if (!css.trim())
51
+ return whole;
52
+ const filename = `crosswind.${contentHash(css)}.css`;
53
+ writeAsset(filename, css);
54
+ result.bytesInlined += css.length;
55
+ return `<link data-crosswind="generated" rel="stylesheet" href="/${EXTERNALIZED_ASSET_DIR}/${filename}">`;
56
+ });
57
+ if (html !== original) {
58
+ fs.writeFileSync(file, html);
59
+ result.pages++;
60
+ }
61
+ }
62
+ return result;
63
+ }
@@ -1,23 +1,3 @@
1
- /**
2
- * The current process's build id.
3
- *
4
- * Stable for the lifetime of the process, which is the unit that matters: a
5
- * `bun --watch` restart produces a new process and therefore a new id, while a
6
- * production build stamps every page it renders with one value.
7
- *
8
- * `STX_BUILD_ID` overrides it, for deployments that render across several
9
- * processes and need them to agree.
10
- */
11
- export declare function getBuildId(): string;
12
- /** @internal test-only — force the id, or with `null` restore generation. */
13
- export declare function __setBuildIdForTest(id: string | null): void;
14
- /**
15
- * Add `<meta name="stx-build">` to `<head>` if it isn't already there.
16
- *
17
- * Idempotent, and a no-op for output with no `<head>` — SPA fragments carry the
18
- * id in a response header instead, since they have nowhere to put a meta.
19
- */
20
- export declare function injectBuildId(html: string, buildId?: string): string;
21
1
  /**
22
2
  * Per-process build identity, used to detect runtime/fragment skew
23
3
  * (stacksjs/stx#1772).
@@ -44,6 +24,26 @@ export declare function injectBuildId(html: string, buildId?: string): string;
44
24
  * @module build-id
45
25
  */
46
26
  /** `<meta name="stx-build">` on every rendered page. */
47
- export declare const BUILD_ID_META: 'stx-build';
27
+ export declare const BUILD_ID_META = "stx-build";
48
28
  /** Response header carrying the id that rendered an SPA fragment. */
49
- export declare const BUILD_ID_HEADER: 'X-STX-Build';
29
+ export declare const BUILD_ID_HEADER = "X-STX-Build";
30
+ /**
31
+ * The current process's build id.
32
+ *
33
+ * Stable for the lifetime of the process, which is the unit that matters: a
34
+ * `bun --watch` restart produces a new process and therefore a new id, while a
35
+ * production build stamps every page it renders with one value.
36
+ *
37
+ * `STX_BUILD_ID` overrides it, for deployments that render across several
38
+ * processes and need them to agree.
39
+ */
40
+ export declare function getBuildId(): string;
41
+ /** @internal test-only — force the id, or with `null` restore generation. */
42
+ export declare function __setBuildIdForTest(id: string | null): void;
43
+ /**
44
+ * Add `<meta name="stx-build">` to `<head>` if it isn't already there.
45
+ *
46
+ * Idempotent, and a no-op for output with no `<head>` — SPA fragments carry the
47
+ * id in a response header instead, since they have nowhere to put a meta.
48
+ */
49
+ export declare function injectBuildId(html: string, buildId?: string): string;
@@ -1,10 +1,81 @@
1
1
  /**
2
- * Render a build failure as `path:line:column: message`, falling back to the
3
- * plain message when no position is available.
2
+ * Make a Bun build failure say where it happened (stacksjs/stx#1810).
3
+ *
4
+ * A single unparseable view produced `BuildMessage: Unexpected ===` and nothing
5
+ * else — no path, no line — leaving the reporter to binary-search the scanned
6
+ * views by hand.
7
+ *
8
+ * The location was never missing. Bun computes it and puts it on
9
+ * `BuildMessage.position`; it is `.message` and `.toString()` that omit it. And
10
+ * because `BuildMessage` is not an `instanceof Error` and carries no `.stack`,
11
+ * the usual `error instanceof Error ? error.message : String(error)` idiom —
12
+ * which this codebase uses in a dozen places — reduces it to exactly that bare
13
+ * string.
14
+ *
15
+ * Two further wrinkles this handles:
16
+ *
17
+ * - `Bun.build()` does not throw a BuildMessage. It throws an AggregateError
18
+ * whose `.errors` holds them, so the useful detail is one level down.
19
+ * - `Bun.Transpiler.transformSync()` reports `position.file` as its synthetic
20
+ * entry name, never the real path. The caller knows the real one, so it is
21
+ * threaded in rather than trusted from the message.
22
+ */
23
+ /**
24
+ * One failure, with its position kept separate rather than baked into a string.
25
+ *
26
+ * A terminal wants `path:line:col: message`; a dev-server overlay wants to draw
27
+ * a code frame and put a caret under the column. Both are rendered from this,
28
+ * so the two cannot drift into disagreeing about where the error is (#1884).
29
+ */
30
+ export interface BuildFailureDetail {
31
+ file?: string;
32
+ line?: number;
33
+ column?: number;
34
+ message: string;
35
+ /** The offending source line, when Bun reported one. */
36
+ lineText?: string;
37
+ }
38
+ /**
39
+ * Pull every failure out of whatever was thrown, with positions intact.
4
40
  *
5
41
  * @param error whatever was thrown — BuildMessage, AggregateError, Error, or
6
42
  * anything else
7
43
  * @param sourcePath the real file being compiled. Preferred over the position's
8
44
  * own `file`, which is a synthetic entry name on the transpiler path.
9
45
  */
46
+ export declare function describeBuildFailure(error: unknown, sourcePath?: string): BuildFailureDetail[];
47
+ /**
48
+ * Render a build failure as `path:line:column: message`, falling back to the
49
+ * plain message when no position is available.
50
+ */
10
51
  export declare function formatBuildFailure(error: unknown, sourcePath?: string): string;
52
+ /**
53
+ * Find a failure's line in the ORIGINAL source.
54
+ *
55
+ * The client-script bundler compiles a temp entry under `.stx/bundle-tmp`, so
56
+ * Bun's `position.line` counts lines in THAT file — for a `<script client>`
57
+ * block halfway down a page it is off by however many lines precede the block,
58
+ * and for an unresolved import it comes back as `-1`. Pointing an overlay at
59
+ * that line is worse than pointing at none: it sends the reader to code that is
60
+ * fine.
61
+ *
62
+ * `lineText` is the one thing that survives the move. If it occurs exactly once
63
+ * in the source, that is the line. Ambiguous or absent yields nothing, which the
64
+ * caller renders as a message with no frame.
65
+ */
66
+ export declare function locateFailureLine(source: string, lineText?: string): number | undefined;
67
+ /** One line of a code frame. */
68
+ export interface CodeFrameLine {
69
+ number: number;
70
+ text: string;
71
+ /** The line the error is on. */
72
+ isError: boolean;
73
+ }
74
+ /**
75
+ * The lines around a failure, for an overlay to draw.
76
+ *
77
+ * Returns the offending line plus `context` lines either side, which is what
78
+ * turns "Could not resolve" into something a reader can act on without opening
79
+ * the file. Empty when there is no line to centre on.
80
+ */
81
+ export declare function buildCodeFrame(source: string, line?: number, context?: number): CodeFrameLine[];
@@ -9,18 +9,57 @@ function unwrap(error) {
9
9
  return error.errors;
10
10
  return [error];
11
11
  }
12
- export function formatBuildFailure(error, sourcePath) {
13
- const parts = [];
12
+ export function describeBuildFailure(error, sourcePath) {
13
+ const details = [];
14
14
  for (const item of unwrap(error)) {
15
15
  if (isBuildMessageLike(item)) {
16
- const position = item.position || void 0, file = sourcePath || position?.file, where = file ? `${file}${position?.line ? `:${position.line}${position.column ? `:${position.column}` : ""}` : ""}` : "", snippet = position?.lineText ? `
17
- ${position.lineText.trim()}` : "";
18
- parts.push(where ? `${where}: ${item.message}${snippet}` : `${item.message}${snippet}`);
16
+ const position = item.position || void 0;
17
+ details.push({
18
+ file: sourcePath || position?.file,
19
+ line: position?.line,
20
+ column: position?.column,
21
+ message: item.message ?? "",
22
+ lineText: position?.lineText
23
+ });
19
24
  continue;
20
25
  }
21
- const message = item instanceof Error ? item.message : String(item);
22
- parts.push(sourcePath ? `${sourcePath}: ${message}` : message);
26
+ details.push({
27
+ file: sourcePath,
28
+ message: item instanceof Error ? item.message : String(item)
29
+ });
23
30
  }
24
- return parts.join(`
31
+ return details;
32
+ }
33
+ export function formatBuildFailure(error, sourcePath) {
34
+ return describeBuildFailure(error, sourcePath).map((detail) => {
35
+ const where = detail.file ? `${detail.file}${detail.line ? `:${detail.line}${detail.column ? `:${detail.column}` : ""}` : ""}` : "", snippet = detail.lineText ? `
36
+ ${detail.lineText.trim()}` : "";
37
+ return where ? `${where}: ${detail.message}${snippet}` : `${detail.message}${snippet}`;
38
+ }).join(`
39
+ `);
40
+ }
41
+ export function locateFailureLine(source, lineText) {
42
+ const needle = lineText?.trim();
43
+ if (!needle)
44
+ return;
45
+ const lines = source.split(`
25
46
  `);
47
+ let found;
48
+ for (let i = 0;i < lines.length; i++) {
49
+ if (lines[i].trim() !== needle)
50
+ continue;
51
+ if (found !== void 0)
52
+ return;
53
+ found = i + 1;
54
+ }
55
+ return found;
56
+ }
57
+ export function buildCodeFrame(source, line, context = 2) {
58
+ if (!line || line < 1)
59
+ return [];
60
+ const lines = source.split(`
61
+ `), start = Math.max(1, line - context), end = Math.min(lines.length, line + context), frame = [];
62
+ for (let n = start;n <= end; n++)
63
+ frame.push({ number: n, text: lines[n - 1] ?? "", isError: n === line });
64
+ return frame;
26
65
  }
@@ -1,3 +1,17 @@
1
+ /**
2
+ * Attribute pass-through for builtin components.
3
+ *
4
+ * `<StxLink>`, `<StxImage>` and `<SafeImage>` all consume the props they know
5
+ * about and forward whatever is left onto the element they render, so an author
6
+ * can write `<StxLink to="/x" aria-label="Shop" data-testid="nav">` and have the
7
+ * last two land on the `<a>`. Each of them grew its own copy of that loop, which
8
+ * meant each of them independently forwarded the *camelized* prop key — emitting
9
+ * `ariaLabel="Shop"`, an attribute no browser knows.
10
+ *
11
+ * One implementation, so the naming round-trip is right in one place.
12
+ *
13
+ * @module builtins/attrs
14
+ */
1
15
  import type { ResolvedProps } from '../component-registry';
2
16
  /**
3
17
  * Render the static props a builtin did not consume as HTML attributes.
@@ -1,2 +1,24 @@
1
+ /**
2
+ * StxDrawer Builtin Component
3
+ *
4
+ * Renders a hidden slide-in panel with slot content. Opened/closed via
5
+ * the runtime `drawer.open(id)` / `drawer.close(id)` / `drawer.toggle(id)` globals.
6
+ *
7
+ * Usage:
8
+ * <StxDrawer id="settings" side="right" size="md">
9
+ * <h2>Settings</h2>
10
+ * <p>Drawer content here</p>
11
+ * </StxDrawer>
12
+ *
13
+ * Props:
14
+ * - id (required) — unique drawer identifier
15
+ * - side — 'left' | 'right' (default: 'right')
16
+ * - size — 'sm' | 'md' | 'lg' | 'xl' (default: 'md')
17
+ * - closeOnBackdrop — whether clicking backdrop closes drawer (default: true)
18
+ * - closeOnEscape — whether Escape key closes drawer (default: true)
19
+ * - overlay — whether to show backdrop overlay (default: true)
20
+ *
21
+ * @module builtins/drawer
22
+ */
1
23
  import type { BuiltinComponentDef } from '../component-registry';
2
24
  export declare const StxDrawerBuiltin: BuiltinComponentDef;
@@ -1,3 +1,18 @@
1
+ /**
2
+ * Icon Builtin Component
3
+ *
4
+ * Renders an inline SVG from the Iconify icon library at template processing
5
+ * time. No client-side runtime needed — the SVG is baked into the HTML.
6
+ *
7
+ * Usage:
8
+ * <Icon name="house" />
9
+ * <Icon name="lucide:house" size="20" class="text-gray-500" />
10
+ * <Icon name="chevron-right" size="16" color="red" />
11
+ *
12
+ * Default collection: lucide. Override with prefix: <Icon name="heroicons:home" />
13
+ *
14
+ * @module builtins/icon
15
+ */
1
16
  import type { BuiltinComponentDef } from '../component-registry';
2
17
  /**
3
18
  * Resolve the on-disk path of an icon collection JSON.
@@ -14,10 +29,9 @@ import type { BuiltinComponentDef } from '../component-registry';
14
29
  * node_modules in apps that vendor there).
15
30
  */
16
31
  export declare function resolveCollectionPath(prefix: string): string | null;
32
+ export declare const IconBuiltin: BuiltinComponentDef;
17
33
  /**
18
34
  * Pre-load icon collections so they're available synchronously during render.
19
35
  * Call this before template processing starts.
20
36
  */
21
37
  export declare function preloadIconCollection(prefix?: string): Promise<void>;
22
- export declare const IconBuiltin: BuiltinComponentDef;
23
- declare type IconCollection = Record<string, { body: string, width?: number, height?: number }>;
@@ -1,18 +1,3 @@
1
- import { IconBuiltin } from './icon';
2
- import { SafeImageBuiltin } from './safe-image';
3
- import { StxDrawerBuiltin } from './drawer';
4
- import { StxImageBuiltin } from './stx-image';
5
- import { StxLinkBuiltin } from './stx-link';
6
- import { StxLoadingIndicatorBuiltin } from './stx-loading-indicator';
7
- import { StxModalBuiltin } from './modal';
8
- import { StxToastBuiltin } from './toast';
9
- import { SuspenseBuiltin } from './suspense';
10
- import { TransitionGroupBuiltin } from './transition-group';
11
- /**
12
- * Register all builtin components with the singleton registry.
13
- * Call this once during framework initialization.
14
- */
15
- export declare function registerBuiltins(): void;
16
1
  /**
17
2
  * Builtin Components Barrel
18
3
  *
@@ -33,3 +18,8 @@ export { IconBuiltin, preloadIconCollection } from './icon';
33
18
  export { getTooltipRuntime } from './tooltip';
34
19
  export { SuspenseBuiltin } from './suspense';
35
20
  export { TransitionGroupBuiltin } from './transition-group';
21
+ /**
22
+ * Register all builtin components with the singleton registry.
23
+ * Call this once during framework initialization.
24
+ */
25
+ export declare function registerBuiltins(): void;
@@ -1,2 +1,26 @@
1
+ /**
2
+ * StxModal Builtin Component
3
+ *
4
+ * Renders a hidden modal dialog with slot content. Opened/closed via
5
+ * the runtime `modal.open(id)` / `modal.close(id)` globals.
6
+ *
7
+ * Usage:
8
+ * <StxModal id="settings">
9
+ * <h2>Settings</h2>
10
+ * <p>Modal content here</p>
11
+ * </StxModal>
12
+ *
13
+ * <StxModal id="delete-confirm" size="sm" closeOnBackdrop="false">
14
+ * <h3>Are you sure?</h3>
15
+ * </StxModal>
16
+ *
17
+ * Props:
18
+ * - id (required) — unique modal identifier
19
+ * - size — 'sm' | 'md' | 'lg' | 'xl' | 'full' (default: 'md')
20
+ * - closeOnBackdrop — whether clicking backdrop closes modal (default: true)
21
+ * - closeOnEscape — whether Escape key closes modal (default: true)
22
+ *
23
+ * @module builtins/modal
24
+ */
1
25
  import type { BuiltinComponentDef } from '../component-registry';
2
26
  export declare const StxModalBuiltin: BuiltinComponentDef;
@@ -1,2 +1,44 @@
1
+ /**
2
+ * SafeImage Builtin Component
3
+ *
4
+ * Drop-in `<img>` replacement with a declarative broken-image fallback.
5
+ * Third-party image URLs (external-CDN avatars, user content that gets
6
+ * deleted, seed data pointing at links that 404) fail frequently in
7
+ * production; without intervention the browser draws the alt text inside
8
+ * whatever layout frame the `<img>` had — round avatar frames in
9
+ * particular look broken.
10
+ *
11
+ * SafeImage wires an inline `onerror=` handler that swaps to a fallback
12
+ * image (and optionally swaps the class string) when the primary src
13
+ * fails to load.
14
+ *
15
+ * Usage:
16
+ * <SafeImage src="/avatars/u.png" alt="User" fallback="/avatars/default.svg" />
17
+ * <SafeImage :src="judge.photo" :alt="judge.name"
18
+ * className="h-12 w-12 rounded-full grayscale filter"
19
+ * fallbackClassName="h-12 w-12 rounded-full"
20
+ * fallback="/images/avatars/default-judge.svg" />
21
+ *
22
+ * Why inline `onerror=` rather than a delegated capture-phase listener:
23
+ * `error` events don't bubble, so a listener attached by a component's
24
+ * `<script client>` IIFE runs AFTER the element's first load attempt —
25
+ * cached 404s and offline first paint slip past it. The inline HTML
26
+ * `onerror=` attribute is parsed-and-attached synchronously with the
27
+ * element by the browser's HTML parser, before the image request fires.
28
+ * That's the only race-free option for the error path.
29
+ *
30
+ * Why a single window-level handler rather than per-instance inline
31
+ * closures: keeps rendered HTML small (a ~35-byte attribute vs. a
32
+ * ~120-byte inline function body per `<img>`). The handler is emitted
33
+ * once per page render (gated on a render-context flag) and registered
34
+ * once per browser session (gated on the `window.__stxSafeImageHandler`
35
+ * existence check, so it's also idempotent across SPA navigation).
36
+ * Per-instance config travels via `data-*` attributes, so the handler
37
+ * stays stateless.
38
+ *
39
+ * Resolves stacksjs/stx#1732.
40
+ *
41
+ * @module builtins/safe-image
42
+ */
1
43
  import type { BuiltinComponentDef } from '../component-registry';
2
44
  export declare const SafeImageBuiltin: BuiltinComponentDef;
@@ -1,2 +1,29 @@
1
+ /**
2
+ * StxImage Builtin Component
3
+ *
4
+ * Full-featured image component matching NuxtImage capabilities:
5
+ *
6
+ * - Auto `loading="lazy"` + `decoding="async"`
7
+ * - Responsive `srcset` + `sizes` auto-generation from breakpoints
8
+ * - Density descriptors (`1x`, `2x`, `3x`)
9
+ * - `<picture>` wrapper with format negotiation (avif, webp fallback)
10
+ * - Blur-up / color / empty placeholder modes
11
+ * - Aspect ratio preservation (CLS prevention)
12
+ * - Preload hint injection (`<link rel="preload">`)
13
+ * - CDN provider support (Cloudinary, imgix, custom)
14
+ *
15
+ * Usage:
16
+ * <StxImage src="/images/hero.jpg" alt="Hero" />
17
+ * <StxImage src="/images/hero.jpg" alt="Hero" width="800" height="600" />
18
+ * <StxImage src="/images/hero.jpg" alt="Hero" sizes="sm:100vw md:50vw lg:33vw" />
19
+ * <StxImage src="/images/hero.jpg" alt="Hero" densities="1x 2x" />
20
+ * <StxImage src="/images/hero.jpg" alt="Hero" format="webp" />
21
+ * <StxImage src="/images/hero.jpg" alt="Hero" placeholder="blur" />
22
+ * <StxImage src="/images/hero.jpg" alt="Hero" placeholder="thumbhash" />
23
+ * <StxImage src="/images/hero.jpg" alt="Hero" preload />
24
+ * <StxImage src="/images/hero.jpg" alt="Hero" provider="cloudinary" />
25
+ *
26
+ * @module builtins/stx-image
27
+ */
1
28
  import type { BuiltinComponentDef } from '../component-registry';
2
29
  export declare const StxImageBuiltin: BuiltinComponentDef;
@@ -1,2 +1,11 @@
1
+ /**
2
+ * StxLink Builtin Component
3
+ *
4
+ * Renders a client-side navigation-aware `<a>` element with support for
5
+ * active class management, prefetching, and reactive href bindings.
6
+ * Produces plain HTML — no wrapper component or custom element overhead.
7
+ *
8
+ * @module builtins/stx-link
9
+ */
1
10
  import type { BuiltinComponentDef } from '../component-registry';
2
11
  export declare const StxLinkBuiltin: BuiltinComponentDef;
@@ -1,2 +1,13 @@
1
+ /**
2
+ * StxLoadingIndicator Builtin Component
3
+ *
4
+ * Renders a fixed-position progress bar at the top of the viewport that
5
+ * activates on navigation. Includes shimmer animation, automatic
6
+ * link-click interception, and a global `window.stxLoading` API.
7
+ *
8
+ * Ported from the inline implementation in component-processing.ts.
9
+ *
10
+ * @module builtins/stx-loading-indicator
11
+ */
1
12
  import type { BuiltinComponentDef } from '../component-registry';
2
13
  export declare const StxLoadingIndicatorBuiltin: BuiltinComponentDef;
@@ -1,2 +1,30 @@
1
+ /**
2
+ * Suspense Builtin Component (stacksjs/stx#1742)
3
+ *
4
+ * A client loading boundary. Renders three regions that the signals runtime
5
+ * (`bindSuspense`) toggles based on the aggregated state of descendant suspense
6
+ * queries (`useQuery` / `useFetch` with `{ suspense: true }`):
7
+ *
8
+ * - `[data-stx-suspense-fallback]` — shown while any descendant query loads
9
+ * - `[data-stx-suspense-error]` — shown when a descendant query errors
10
+ * - `[data-stx-suspense-content]` — shown once all descendant queries resolve
11
+ *
12
+ * The default slot is the content; `fallback` / `errorFallback` come from props
13
+ * or from `slot="fallback"` / `slot="error"` elements in the slot content.
14
+ *
15
+ * ```stx
16
+ * <Suspense fallback="Loading…">
17
+ * <CommentsList /> <!-- uses useQuery(url, { suspense: true }) -->
18
+ * </Suspense>
19
+ *
20
+ * <Suspense>
21
+ * <template slot="fallback"><Skeleton count="2" /></template>
22
+ * <template slot="error">Couldn't load comments.</template>
23
+ * <CommentsList />
24
+ * </Suspense>
25
+ * ```
26
+ *
27
+ * @module builtins/suspense
28
+ */
1
29
  import type { BuiltinComponentDef } from '../component-registry';
2
30
  export declare const SuspenseBuiltin: BuiltinComponentDef;
@@ -1,2 +1,19 @@
1
+ /**
2
+ * StxToast Builtin Component
3
+ *
4
+ * Renders a fixed-position toast notification container. The runtime
5
+ * `toast()` global (success / error / info / warning / dismiss) creates
6
+ * and animates individual toast elements inside this container.
7
+ *
8
+ * Usage:
9
+ * <StxToast />
10
+ * <StxToast position="top-right" max="5" />
11
+ * <StxToast position="bottom-left" />
12
+ *
13
+ * Positions: top-right (default), top-left, top-center,
14
+ * bottom-right, bottom-left, bottom-center
15
+ *
16
+ * @module builtins/toast
17
+ */
1
18
  import type { BuiltinComponentDef } from '../component-registry';
2
19
  export declare const StxToastBuiltin: BuiltinComponentDef;
@@ -1,2 +1,27 @@
1
+ /**
2
+ * TransitionGroup Builtin Component (stacksjs/stx#1742)
3
+ *
4
+ * Class-driven enter/leave + FLIP move animations for a keyed list. Renders a
5
+ * single wrapper element marked `data-stx-transition-group="<name>"`; the
6
+ * signals runtime's `bindFor` animates the list items inside it when they are
7
+ * added, removed, or reordered.
8
+ *
9
+ * The default slot must contain a single `:for` (or `x-for`) element whose
10
+ * rendered items become the wrapper's direct children:
11
+ *
12
+ * ```stx
13
+ * <TransitionGroup name="card" tag="ul" class="space-y-2">
14
+ * <li :for="r in reviews()" :key="r.id" class="card">{{ r.title }}</li>
15
+ * </TransitionGroup>
16
+ * ```
17
+ *
18
+ * With `name="card"`, supply the transition classes (e.g. via crosswind/CSS):
19
+ * `card-enter-from` / `card-enter-active` / `card-enter-to`,
20
+ * `card-leave-from` / `card-leave-active` / `card-leave-to`, and `card-move`
21
+ * (applied to elements that shift position during a reorder). The first render
22
+ * does not animate; subsequent list changes do.
23
+ *
24
+ * @module builtins/transition-group
25
+ */
1
26
  import type { BuiltinComponentDef } from '../component-registry';
2
27
  export declare const TransitionGroupBuiltin: BuiltinComponentDef;
package/dist/caching.d.ts CHANGED
@@ -1,4 +1,13 @@
1
1
  import type { StxOptions } from './types';
2
+ /**
3
+ * Cache entry structure
4
+ */
5
+ interface CacheEntry {
6
+ output: string;
7
+ mtime: number;
8
+ dependencies: Set<string>;
9
+ }
10
+ export declare const templateCache: Map<string, CacheEntry>;
2
11
  /**
3
12
  * Read a file with mtime-based caching.
4
13
  * Returns cached content if file hasn't been modified since last read.
@@ -21,6 +30,8 @@ export declare function invalidateFileCache(filePath: string): void;
21
30
  * Invalidate all files matching a pattern from the content cache.
22
31
  */
23
32
  export declare function invalidateFileCacheByDir(dirPath: string): void;
33
+ /** The two runtime generators caching depends on (subset of `./signals`). */
34
+ type SignalsGenerators = Pick<typeof import('./signals'), 'generateSignalsRuntime' | 'generateSignalsRuntimeDev'>;
24
35
  /** @internal test-only — inject (or, with `null`, restore) the signals generators. */
25
36
  export declare function __setSignalsGeneratorsForTest(generators: SignalsGenerators | null): void;
26
37
  /**
@@ -55,18 +66,4 @@ export declare function cacheTemplate(filePath: string, output: string, dependen
55
66
  * @returns A 16-character hex string suitable for use as a filename
56
67
  */
57
68
  export declare function hashFilePath(filePath: string): string;
58
- // Memory cache for compiled templates
59
- export declare const templateCache: Map<string, CacheEntry>;
60
- /**
61
- * Cache entry structure
62
- */
63
- declare interface CacheEntry {
64
- output: string
65
- mtime: number
66
- dependencies: Set<string>
67
- }
68
- /** The two runtime generators caching depends on (subset of `./signals`). */
69
- declare type SignalsGenerators = Pick<
70
- typeof import('./signals'),
71
- 'generateSignalsRuntime' | 'generateSignalsRuntimeDev'
72
- >;
69
+ export {};