@stacksjs/stx 0.2.174 → 0.2.176

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.
package/dist/includes.js CHANGED
@@ -512,14 +512,18 @@ export async function processIncludes(template, context, filePath, options, depe
512
512
  }
513
513
  const currentFilePath = path.resolve(filePath);
514
514
  includeStack.add(currentFilePath);
515
+ function includeFailure(includePath, message, templateStr, offsetPos) {
516
+ options.onIncludeError?.({ includePath, templatePath: filePath, message, partialsDir });
517
+ return createDetailedErrorMessage("Include", message, filePath, templateStr, offsetPos);
518
+ }
515
519
  async function processIncludeHelper(includePath, localVars = {}, templateStr, offsetPos) {
516
520
  const includeFilePath = resolvePath(includePath, partialsDir, filePath);
517
521
  if (!includeFilePath)
518
- return createDetailedErrorMessage("Include", `Could not resolve path for include: ${includePath}`, filePath, templateStr, offsetPos);
522
+ return includeFailure(includePath, `Could not resolve path for include: ${includePath}`, templateStr, offsetPos);
519
523
  const resolvedIncludePath = path.resolve(includeFilePath);
520
524
  if (includeStack.has(resolvedIncludePath)) {
521
525
  const chain = [...includeStack, resolvedIncludePath].map((p) => path.basename(p)).join(" -> ");
522
- return createDetailedErrorMessage("Include", `Circular include detected: ${chain}`, filePath, templateStr, offsetPos);
526
+ return includeFailure(includePath, `Circular include detected: ${chain}`, templateStr, offsetPos);
523
527
  }
524
528
  try {
525
529
  dependencies.add(includeFilePath);
@@ -529,7 +533,7 @@ export async function processIncludes(template, context, filePath, options, depe
529
533
  partialContent = await Bun.file(includeFilePath).text();
530
534
  } catch (error) {
531
535
  const errorMessage = error instanceof Error ? error.message : String(error);
532
- return createDetailedErrorMessage("Include", `Error loading include file ${includePath}: ${errorMessage}`, filePath, templateStr, offsetPos);
536
+ return includeFailure(includePath, `Error loading include file ${includePath}: ${errorMessage}`, templateStr, offsetPos);
533
537
  }
534
538
  if (partialContent)
535
539
  partialContent = partialContent.replace(/\{\{--[\s\S]*?--\}\}/g, "");
@@ -641,7 +645,7 @@ export async function processIncludes(template, context, filePath, options, depe
641
645
  return processedContent;
642
646
  } catch (error) {
643
647
  const errorMessage = error instanceof Error ? error.message : String(error);
644
- return createDetailedErrorMessage("Include", `Error processing include ${includePath}: ${errorMessage}`, filePath, templateStr, offsetPos);
648
+ return includeFailure(includePath, `Error processing include ${includePath}: ${errorMessage}`, templateStr, offsetPos);
645
649
  }
646
650
  }
647
651
  const includePattern = /@include\s*\(/g;
package/dist/index.d.ts CHANGED
@@ -204,6 +204,7 @@ export * from './reactive-bindings';
204
204
  export * from './client-helpers';
205
205
  export * from './client-script';
206
206
  export * from './strip-literals';
207
+ export * from './resolve-stx-targets';
207
208
  export * from './component-hmr';
208
209
  export * from './hydration';
209
210
  // ssg moved to stx/ssg
package/dist/index.js CHANGED
@@ -113,6 +113,7 @@ export * from "./reactive-bindings.js";
113
113
  export * from "./client-helpers.js";
114
114
  export * from "./client-script.js";
115
115
  export * from "./strip-literals.js";
116
+ export * from "./resolve-stx-targets.js";
116
117
  export * from "./component-hmr.js";
117
118
  export * from "./hydration.js";
118
119
  export * from "./ssr.js";
package/dist/process.js CHANGED
@@ -54,7 +54,7 @@ import { deriveLayoutGroup } from "stx-router/layout-metadata";
54
54
  import { initializeComponentClientFactories, injectComponentClientFactories } from "./component-client-factories.js";
55
55
  import { importOnce } from "./lazy-module.js";
56
56
  export { injectRouterScript } from "./runtime-injection.js";
57
- import { injectSignalsRuntime, outputNeedsSignalsRuntime, pageShipsSignalsRuntime } from "./runtime-injection.js";
57
+ import { injectSignalsRuntime, injectTooltipRuntime, outputNeedsSignalsRuntime, pageShipsSignalsRuntime } from "./runtime-injection.js";
58
58
  export { processJsonDirective, processOnceDirective } from "./misc-directives.js";
59
59
  export { validateClientScript } from "./script-validation.js";
60
60
  const PARENT_PLACEHOLDER = "<!--PARENT_CONTENT_PLACEHOLDER-->";
@@ -843,6 +843,7 @@ ${runtimeScript}`);
843
843
  }
844
844
  if (!pageShipsSignalsRuntime(output) && outputNeedsSignalsRuntime(output))
845
845
  output = await injectSignalsRuntime(output, opts);
846
+ output = injectTooltipRuntime(output);
846
847
  if (opts.csp?.enabled && opts.csp.useNonce && typeof context.cspNonce === "string")
847
848
  output = addNonceToInlineContent(output, context.cspNonce);
848
849
  return output;
package/dist/props.d.ts CHANGED
@@ -1,9 +1,22 @@
1
1
  /**
2
2
  * Define component props with type safety and validation.
3
3
  *
4
+ * Takes an inline object type or a named `interface`/`type` — the named form is
5
+ * shown first because it is the one the framework scaffolds, and because every
6
+ * example here used to be inline. An inline literal has an implicit index
7
+ * signature and a named `interface` does not, so an inline-only docstring
8
+ * demonstrated the one spelling that could not fail (stacksjs/stx#1917).
9
+ *
4
10
  * @example
5
11
  * ```typescript
6
- * // Simple usage with types only
12
+ * // A named type, inline or imported — interface and type alias both work
13
+ * interface CardProps {
14
+ * title: string
15
+ * count: number
16
+ * }
17
+ * const props = defineProps<CardProps>()
18
+ *
19
+ * // Or inline
7
20
  * const props = defineProps<{
8
21
  * title: string
9
22
  * count: number
@@ -24,12 +37,12 @@
24
37
  * })
25
38
  * ```
26
39
  */
27
- export declare function defineProps<T extends Record<string, unknown>>(definitions?: PropsDefinition<T>): T;
40
+ export declare function defineProps<T extends PropsShape>(definitions?: PropsDefinition<T>): T;
28
41
  /**
29
42
  * Define props with runtime validation.
30
43
  * Use this when you need validation errors at runtime.
31
44
  */
32
- export declare function definePropsWithValidation<T extends Record<string, unknown>>(definitions: PropsDefinition<T>, options?: {
45
+ export declare function definePropsWithValidation<T extends PropsShape>(definitions: PropsDefinition<T>, options?: {
33
46
  componentName?: string
34
47
  throwOnError?: boolean
35
48
  logWarnings?: boolean
@@ -49,7 +62,7 @@ export declare function definePropsWithValidation<T extends Record<string, unkno
49
62
  * })
50
63
  * ```
51
64
  */
52
- export declare function withDefaults<T extends Record<string, unknown>>(props: T, defaults: Partial<{ [K in keyof T]: T[K] | (() => T[K]) }>): T;
65
+ export declare function withDefaults<T extends PropsShape>(props: T, defaults: Partial<{ [K in keyof T]: T[K] | (() => T[K]) }>): T;
53
66
  /**
54
67
  * Create a prop type definition for a specific type.
55
68
  */
@@ -77,7 +90,7 @@ export declare function arrayOf<T>(_itemType: PropType<T>, options?: Omit<PropOp
77
90
  /**
78
91
  * Create a prop for object with specific shape.
79
92
  */
80
- export declare function shape<T extends Record<string, unknown>>(_shape: PropsDefinition<T>, options?: Omit<PropOptions<T>, 'type'>): PropOptions<T>;
93
+ export declare function shape<T extends PropsShape>(_shape: PropsDefinition<T>, options?: Omit<PropOptions<T>, 'type'>): PropOptions<T>;
81
94
  /**
82
95
  * Process props passed to a component.
83
96
  * Called internally during component rendering.
@@ -100,7 +113,7 @@ export declare function processComponentProps(rawProps: Record<string, unknown>,
100
113
  * emit('close', undefined)
101
114
  * ```
102
115
  */
103
- export declare function defineEmits<E extends Record<string, unknown>>(): EmitFn<E>;
116
+ export declare function defineEmits<E extends PropsShape>(): EmitFn<E>;
104
117
  /**
105
118
  * Expose component methods/properties to parent.
106
119
  *
@@ -113,7 +126,7 @@ export declare function defineEmits<E extends Record<string, unknown>>(): EmitFn
113
126
  * })
114
127
  * ```
115
128
  */
116
- export declare function defineExpose<T extends Record<string, unknown>>(exposed: T): void;
129
+ export declare function defineExpose<T extends PropsShape>(exposed: T): void;
117
130
  /**
118
131
  * Generate TypeScript interface from prop definitions.
119
132
  * Useful for documentation and type generation.
@@ -151,6 +164,36 @@ export type PropType<T> = | StringConstructor
151
164
  | SymbolConstructor
152
165
  | { new (...args: unknown[]): T }
153
166
  | PropType<T>[];
167
+ /**
168
+ * The constraint every props, emits and expose generic is bounded by.
169
+ *
170
+ * `object` rather than `Record<string, unknown>`, and the difference is not
171
+ * cosmetic: **a TypeScript `interface` does not satisfy an index signature.**
172
+ * Only a type alias gets an implicit one, so
173
+ *
174
+ * interface CardProps { title: string }
175
+ * defineProps<CardProps>() // TS2344, TS2345
176
+ * type CardProps = { title: string }
177
+ * defineProps<CardProps>() // fine
178
+ *
179
+ * differ on the keyword alone. `interface` is the form the framework scaffolds
180
+ * — `storage/framework/defaults/` declares props with it 44 times and with a
181
+ * type alias zero times — so the constraint rejected the entire scaffolded
182
+ * corpus (stacksjs/stx#1917).
183
+ *
184
+ * Two things hid it. Every example in the docstrings passes an inline object
185
+ * literal, which HAS an implicit index signature and so always passed; the
186
+ * error appears only once the type is named, which is the moment it is reused
187
+ * or exported. And apps import from `stx`, which is not a package anyone can
188
+ * install — the module resolved to `any`, the constraint was never enforced,
189
+ * and the component type-checked. Correcting the specifier in one app turned 18
190
+ * "Cannot find module" errors into 36 constraint errors.
191
+ *
192
+ * Named rather than written out seven times so the reason lives in one place
193
+ * and the sites cannot drift apart. `object` still rejects `string`, `number`
194
+ * and `undefined`, which is everything this constraint has to do.
195
+ */
196
+ export type PropsShape = object;
154
197
  /** Props definition object */
155
198
  export type PropsDefinition<T> = {
156
199
  [K in keyof T]?: PropOptions<T[K]> | PropType<T[K]>
@@ -167,7 +210,7 @@ export type ExtractPropTypes<T extends PropsDefinition<unknown>> = {
167
210
  // eslint-disable-next-line pickier/no-unused-vars
168
211
  export type EventHandler<T = unknown> = (payload: T) => void;
169
212
  /** Emit function type */
170
- export type EmitFn<E extends Record<string, unknown>> = <K extends keyof E>(
213
+ export type EmitFn<E extends PropsShape> = <K extends keyof E>(
171
214
  event: K,
172
215
  payload: E[K],
173
216
  ) => void;