@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
@@ -13,6 +13,8 @@ import {
13
13
  import { dirname, join, relative } from "node:path";
14
14
  import process from "node:process";
15
15
  import stxPlugin from "bun-plugin-stx";
16
+ import { CONVENTIONAL_ASSET_OUTPUT, resolveConventionalAssetRoot } from "../asset-roots.js";
17
+ import { externalizeSharedAssets } from "../build-externalize.js";
16
18
  import { injectCrosswindCSS } from "../dev-server/crosswind.js";
17
19
  import { injectSeo } from "./seo.js";
18
20
  import { generateSitemap } from "./sitemap.js";
@@ -87,8 +89,14 @@ export async function buildStaticSite(options) {
87
89
  ;
88
90
  }
89
91
  }
92
+ const externalized = externalizeSharedAssets(outDir);
93
+ if (externalized.assets > 0)
94
+ console.log(`[stx] externalized ${externalized.assets} asset(s) from ${externalized.pages} page(s) (${(externalized.bytesInlined / 1024).toFixed(1)}KB removed from HTML)`);
90
95
  if (existsSync(publicDir))
91
96
  cpSync(publicDir, outDir, { recursive: !0 });
97
+ const conventionalAssets = resolveConventionalAssetRoot();
98
+ if (conventionalAssets)
99
+ cpSync(conventionalAssets, join(outDir, CONVENTIONAL_ASSET_OUTPUT), { recursive: !0 });
92
100
  const fourOhFourSrc = join(outDir, "404.html");
93
101
  if (!existsSync(fourOhFourSrc) && existsSync(join(outDir, "index.html"))) {
94
102
  const fallback = readFileSync(join(outDir, "index.html"), "utf8").replace(/<title>[^<]*<\/title>/i, `<title>404 \u2014 ${escapeText(options.name)}</title>`);
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Where the canonical site URL comes from.
3
+ *
4
+ * The SSG defaulted `domain` to `http://localhost` and read no config at all,
5
+ * so an app that declared `url: 'https://example.org'` still shipped a
6
+ * sitemap.xml in which every entry was `http://localhost/…` — valid XML,
7
+ * accepted by the build, and useless to a crawler. Nothing warned, because
8
+ * from the build's point of view nothing failed (stacksjs/stx#1866).
9
+ *
10
+ * The URL is looked for in the places apps actually declare it, because there
11
+ * is more than one: `stx.config.ts` for stx-native apps, `site.config.ts` for
12
+ * the site-builder path (which has had `site.url` all along — that generator
13
+ * was never wired to this one), and the deploy-platform env vars, which are the
14
+ * only source available in CI where neither file knows the preview domain.
15
+ *
16
+ * @module site-url
17
+ */
18
+ /** Where a resolved URL came from, for diagnostics. */
19
+ export type SiteUrlSource = 'option' | 'stx.config' | 'site.config' | 'env' | 'fallback';
20
+ export interface ResolvedSiteUrl {
21
+ url: string;
22
+ source: SiteUrlSource;
23
+ /** The env var or config key it came from, when there is one. */
24
+ via?: string;
25
+ }
26
+ /** Last resort. Deliberately not a real domain, so it is obvious in output. */
27
+ export declare const SITE_URL_FALLBACK = "http://localhost";
28
+ /**
29
+ * Resolve the canonical site URL, reporting where it came from so the caller
30
+ * can warn when it had to fall back.
31
+ *
32
+ * Order is explicit-option, then app config, then deploy env, then localhost.
33
+ */
34
+ export declare function resolveSiteUrl(options?: {
35
+ explicit?: string;
36
+ stxConfig?: unknown;
37
+ cwd?: string;
38
+ env?: Record<string, string | undefined>;
39
+ }): Promise<ResolvedSiteUrl>;
40
+ /**
41
+ * The warning shown when a build produced localhost URLs.
42
+ *
43
+ * Loud, and it names the fix — a sitemap full of `http://localhost` is not
44
+ * something anyone notices by reading build output.
45
+ */
46
+ export declare function siteUrlFallbackWarning(): string;
@@ -0,0 +1,70 @@
1
+ export const SITE_URL_FALLBACK = "http://localhost";
2
+ const ENV_KEYS = ["STX_SITE_URL", "SITE_URL", "URL", "VERCEL_URL", "CF_PAGES_URL"];
3
+ function normalize(raw) {
4
+ const trimmed = raw.trim();
5
+ if (!trimmed)
6
+ return null;
7
+ const withScheme = /^https?:\/\//i.test(trimmed) ? trimmed : `https://${trimmed}`;
8
+ try {
9
+ return new URL(withScheme).origin + new URL(withScheme).pathname.replace(/\/$/, "");
10
+ } catch {
11
+ return null;
12
+ }
13
+ }
14
+ function fromEnv(env) {
15
+ for (const key of ENV_KEYS) {
16
+ const value = env[key];
17
+ if (!value)
18
+ continue;
19
+ const url = normalize(value);
20
+ if (url)
21
+ return { url, source: "env", via: key };
22
+ }
23
+ return null;
24
+ }
25
+ function fromConfigObject(config) {
26
+ if (!config || typeof config !== "object")
27
+ return null;
28
+ const record = config, candidate = record.site?.url ?? record.url ?? record.app?.url;
29
+ return typeof candidate === "string" ? normalize(candidate) : null;
30
+ }
31
+ async function loadSiteConfigFile(cwd) {
32
+ const { existsSync } = await import("node:fs"), path = await import("node:path");
33
+ for (const name of ["site.config.ts", "site.config.js", ".config/site.config.ts"]) {
34
+ const file = path.resolve(cwd, name);
35
+ if (!existsSync(file))
36
+ continue;
37
+ try {
38
+ const module = await import(file), url = fromConfigObject(module.default ?? module);
39
+ if (url)
40
+ return url;
41
+ } catch {}
42
+ }
43
+ return null;
44
+ }
45
+ export async function resolveSiteUrl(options = {}) {
46
+ const cwd = options.cwd ?? process.cwd(), env = options.env ?? process.env;
47
+ if (options.explicit) {
48
+ const url = normalize(options.explicit);
49
+ if (url)
50
+ return { url, source: "option" };
51
+ }
52
+ const fromStx = fromConfigObject(options.stxConfig);
53
+ if (fromStx)
54
+ return { url: fromStx, source: "stx.config", via: "site.url" };
55
+ const fromSiteFile = await loadSiteConfigFile(cwd);
56
+ if (fromSiteFile)
57
+ return { url: fromSiteFile, source: "site.config", via: "url" };
58
+ const env_ = fromEnv(env);
59
+ if (env_)
60
+ return env_;
61
+ return { url: SITE_URL_FALLBACK, source: "fallback" };
62
+ }
63
+ export function siteUrlFallbackWarning() {
64
+ return [
65
+ "No site URL configured \u2014 sitemap.xml and robots.txt will point at http://localhost.",
66
+ " Set one in stx.config.ts (site: { url: 'https://example.com' }), in site.config.ts,",
67
+ " via --domain, or with SITE_URL in the build environment."
68
+ ].join(`
69
+ `);
70
+ }
package/dist/slots.d.ts CHANGED
@@ -1,3 +1,84 @@
1
+ /**
2
+ * STX Slots Module
3
+ *
4
+ * Provides Vue-style named slots and scoped slots support.
5
+ *
6
+ * @module slots
7
+ *
8
+ * ## Named Slots
9
+ *
10
+ * Parent component:
11
+ * ```html
12
+ * <Card>
13
+ * <template #header>
14
+ * <h1>Title</h1>
15
+ * </template>
16
+ *
17
+ * <p>Default slot content</p>
18
+ *
19
+ * <template #footer>
20
+ * <button>Submit</button>
21
+ * </template>
22
+ * </Card>
23
+ * ```
24
+ *
25
+ * Child component (Card.stx):
26
+ * ```html
27
+ * <div class="card">
28
+ * <header>
29
+ * <slot name="header">Default Header</slot>
30
+ * </header>
31
+ * <main>
32
+ * <slot />
33
+ * </main>
34
+ * <footer>
35
+ * <slot name="footer" />
36
+ * </footer>
37
+ * </div>
38
+ * ```
39
+ *
40
+ * ## Scoped Slots
41
+ *
42
+ * Parent component:
43
+ * ```html
44
+ * <DataTable :items="users">
45
+ * <template #row="{ item, index }">
46
+ * <td>{{ index + 1 }}</td>
47
+ * <td>{{ item.name }}</td>
48
+ * </template>
49
+ * </DataTable>
50
+ * ```
51
+ *
52
+ * Child component (DataTable.stx):
53
+ * ```html
54
+ * <table>
55
+ * @foreach (items as item, index)
56
+ * <tr>
57
+ * <slot name="row" :item="item" :index="index">
58
+ * <td>{{ item }}</td>
59
+ * </slot>
60
+ * </tr>
61
+ * @endforeach
62
+ * </table>
63
+ * ```
64
+ */
65
+ export interface SlotDefinition {
66
+ /** Slot name (empty string for default slot) */
67
+ name: string;
68
+ /** Slot content (the template) */
69
+ content: string;
70
+ /** Scoped slot props binding (e.g., "{ item, index }") */
71
+ propsBinding?: string;
72
+ }
73
+ export interface SlotProps {
74
+ [key: string]: unknown;
75
+ }
76
+ export interface ParsedSlots {
77
+ /** Default slot content */
78
+ default: string;
79
+ /** Named slots */
80
+ named: Map<string, SlotDefinition>;
81
+ }
1
82
  /**
2
83
  * Parse slot content from component children.
3
84
  *
@@ -14,9 +95,9 @@ export declare function parseSlots(childContent: string): ParsedSlots;
14
95
  * Returns: { name: 'row', props: { item: 'item', index: 'index' } }
15
96
  */
16
97
  export declare function parseSlotElement(slotTag: string): {
17
- name: string
18
- props: Record<string, string>
19
- defaultContent: string
98
+ name: string;
99
+ props: Record<string, string>;
100
+ defaultContent: string;
20
101
  };
21
102
  /**
22
103
  * Render a slot with its content and props.
@@ -38,26 +119,11 @@ export declare function processSlots(template: string, parsedSlots: ParsedSlots,
38
119
  * This is called when processing a component to separate slot content.
39
120
  */
40
121
  export declare function extractSlotContent(childContent: string): {
41
- defaultSlot: string
42
- namedSlots: Map<string, SlotDefinition>
122
+ defaultSlot: string;
123
+ namedSlots: Map<string, SlotDefinition>;
43
124
  };
44
125
  /**
45
126
  * Apply slots to a component template.
46
127
  * This replaces <slot> elements with the provided slot content.
47
128
  */
48
129
  export declare function applySlots(componentTemplate: string, defaultSlotContent: string, namedSlots: Map<string, SlotDefinition>, context: Record<string, unknown>): Promise<string>;
49
- // =============================================================================
50
- // Types
51
- // =============================================================================
52
- export declare interface SlotDefinition {
53
- name: string
54
- content: string
55
- propsBinding?: string
56
- }
57
- export declare interface SlotProps {
58
- [key: string]: unknown
59
- }
60
- export declare interface ParsedSlots {
61
- default: string
62
- named: Map<string, SlotDefinition>
63
- }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * A cheap fingerprint of a set of source files, so a memoised bundle cannot
3
+ * outlive its sources.
4
+ *
5
+ * The store and composable loaders memoised their built bundle per directory
6
+ * and nothing ever invalidated it. `clearStoreCache()` and
7
+ * `clearComposableCache()` existed and were exported, but the only callers in
8
+ * the entire workspace were tests — so in dev, no edit to a store reached the
9
+ * browser without restarting the server, including creating the first one
10
+ * (stacksjs/stx#1877).
11
+ *
12
+ * A watcher alone is not enough: it fixes the common case but a missed event
13
+ * still leaves a stale bundle serving indefinitely, with no symptom other than
14
+ * an edit that seems not to have happened. Keying the memo on the sources means
15
+ * the worst a missed event costs is one stale request, not the rest of the
16
+ * session.
17
+ *
18
+ * Statting a handful of files is nothing next to the `Bun.build` it guards, so
19
+ * this runs on every call rather than being cached itself.
20
+ *
21
+ * @module source-signature
22
+ */
23
+ /**
24
+ * Fingerprint `files` by path, size and mtime.
25
+ *
26
+ * Size is included because mtime resolution is coarse enough on some
27
+ * filesystems that a fast rewrite of the same length can land in the same
28
+ * millisecond. Sorted, so directory-scan order cannot change the result.
29
+ *
30
+ * A file that cannot be statted contributes a `missing` marker rather than
31
+ * throwing — it is a difference from the last run either way.
32
+ */
33
+ export declare function sourceSignature(files: readonly string[]): string;
34
+ /** A memo entry that knows which sources it was built from. */
35
+ export interface SignedCacheEntry<T> {
36
+ signature: string;
37
+ value: T;
38
+ }
39
+ /**
40
+ * Read a memo entry, returning `undefined` when the sources have changed since
41
+ * it was written.
42
+ */
43
+ export declare function readSigned<T>(cache: Map<string, SignedCacheEntry<T>>, key: string, signature: string): T | undefined;
44
+ /** Write a memo entry stamped with the signature of its sources. */
45
+ export declare function writeSigned<T>(cache: Map<string, SignedCacheEntry<T>>, key: string, signature: string, value: T): T;
@@ -0,0 +1,20 @@
1
+ import fs from "node:fs";
2
+ export function sourceSignature(files) {
3
+ return [...files].sort().map((file) => {
4
+ try {
5
+ const stat = fs.statSync(file);
6
+ return `${file}:${stat.size}:${stat.mtimeMs}`;
7
+ } catch {
8
+ return `${file}:missing`;
9
+ }
10
+ }).join(`
11
+ `);
12
+ }
13
+ export function readSigned(cache, key, signature) {
14
+ const entry = cache.get(key);
15
+ return entry !== void 0 && entry.signature === signature ? entry.value : void 0;
16
+ }
17
+ export function writeSigned(cache, key, signature, value) {
18
+ cache.set(key, { signature, value });
19
+ return value;
20
+ }