@stacksjs/stx 0.2.9 → 0.2.11

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 (128) hide show
  1. package/README.md +16 -11
  2. package/dist/a11y.d.ts +2 -1
  3. package/dist/analyzer.d.ts +4 -0
  4. package/dist/app-shell.d.ts +72 -0
  5. package/dist/app.d.ts +1 -0
  6. package/dist/broadcasting.d.ts +77 -0
  7. package/dist/build-assets.d.ts +32 -0
  8. package/dist/build-mode-detector.d.ts +26 -0
  9. package/dist/build.d.ts +31 -0
  10. package/dist/builtins/icon.d.ts +7 -0
  11. package/dist/builtins/index.d.ts +21 -0
  12. package/dist/builtins/stx-image.d.ts +2 -0
  13. package/dist/builtins/stx-link.d.ts +2 -0
  14. package/dist/builtins/stx-loading-indicator.d.ts +2 -0
  15. package/dist/bundle-analyzer/index.d.ts +2 -0
  16. package/dist/bundle-analyzer.js +20 -20
  17. package/dist/caching.d.ts +27 -0
  18. package/dist/cli.js +3941 -2609
  19. package/dist/client-helpers.d.ts +7 -3
  20. package/dist/client-script-bundler.d.ts +27 -0
  21. package/dist/client-script.d.ts +5 -1
  22. package/dist/client.d.ts +1 -0
  23. package/dist/component-hmr.d.ts +1 -0
  24. package/dist/component-processing.d.ts +107 -0
  25. package/dist/component-registry.d.ts +54 -0
  26. package/dist/component-renderer.d.ts +18 -0
  27. package/dist/components/StxImage.stx +12 -0
  28. package/dist/components/StxLink.stx +18 -8
  29. package/dist/composables/index.d.ts +7 -0
  30. package/dist/composables/use-broadcast-channel.d.ts +1 -0
  31. package/dist/composables/use-channel.d.ts +67 -0
  32. package/dist/composables/use-intersection-observer.d.ts +2 -0
  33. package/dist/composables/use-keyboard.d.ts +1 -0
  34. package/dist/composables/use-mouse.d.ts +1 -0
  35. package/dist/composables/use-router.d.ts +4 -0
  36. package/dist/composables/use-websocket.d.ts +1 -0
  37. package/dist/composables.d.ts +2 -0
  38. package/dist/composition-api.d.ts +1 -0
  39. package/dist/computed.d.ts +1 -0
  40. package/dist/config.d.ts +12 -1
  41. package/dist/craft-bridge.d.ts +6 -3
  42. package/dist/craft-components.d.ts +1 -0
  43. package/dist/craft.js +39 -33
  44. package/dist/deploy/index.d.ts +1 -0
  45. package/dist/dev-server/crosswind.d.ts +2 -5
  46. package/dist/dev-server/native-window.d.ts +19 -1
  47. package/dist/dev-server/serve-app.d.ts +15 -0
  48. package/dist/dev-server/serve-file.d.ts +3 -0
  49. package/dist/dev-server/serve-markdown.d.ts +3 -0
  50. package/dist/dev-server/serve-multi.d.ts +5 -0
  51. package/dist/dev-server/types.d.ts +2 -0
  52. package/dist/dev-server.d.ts +6 -40
  53. package/dist/devtools.d.ts +1 -0
  54. package/dist/directive-api.d.ts +1 -1
  55. package/dist/document-shell.d.ts +33 -0
  56. package/dist/error-boundaries.d.ts +1 -0
  57. package/dist/events.d.ts +1 -0
  58. package/dist/expressions.d.ts +38 -0
  59. package/dist/forms-validation.d.ts +2 -0
  60. package/dist/head.d.ts +1 -0
  61. package/dist/hot-reload.d.ts +1 -0
  62. package/dist/hydration-runtime.d.ts +1 -0
  63. package/dist/hydration.d.ts +1 -0
  64. package/dist/i18n.d.ts +3 -1
  65. package/dist/image-optimization/build-plugin.d.ts +1 -0
  66. package/dist/index.d.ts +22 -1
  67. package/dist/index.js +5569 -4182
  68. package/dist/inline-assets.d.ts +28 -0
  69. package/dist/internal-markdown.d.ts +0 -4
  70. package/dist/jsx-runtime.d.ts +1 -0
  71. package/dist/keep-alive.d.ts +1 -0
  72. package/dist/manifest.d.ts +41 -0
  73. package/dist/markdown.d.ts +1 -0
  74. package/dist/media/client/blur-up.d.ts +1 -0
  75. package/dist/media/client/lazy-load.d.ts +1 -0
  76. package/dist/media/client/upload-handler.d.ts +1 -0
  77. package/dist/media/shared/cache.d.ts +2 -0
  78. package/dist/media/video/index.d.ts +1 -0
  79. package/dist/media/video/processor/thumbnail.d.ts +1 -0
  80. package/dist/misc-directives.d.ts +49 -0
  81. package/dist/parser/directive-parser.d.ts +13 -0
  82. package/dist/performance-utils.d.ts +2 -0
  83. package/dist/placeholder.d.ts +45 -0
  84. package/dist/plugin-system.d.ts +32 -2
  85. package/dist/process.d.ts +11 -1
  86. package/dist/production-builder.d.ts +42 -0
  87. package/dist/production-server.d.ts +19 -0
  88. package/dist/props.d.ts +1 -0
  89. package/dist/pwa.js +3883 -2679
  90. package/dist/reactive.d.ts +2 -16
  91. package/dist/reactivity.d.ts +1 -0
  92. package/dist/router.d.ts +1 -1
  93. package/dist/runtime-injection.d.ts +20 -0
  94. package/dist/runtime.d.ts +2 -2
  95. package/dist/script-classifier.d.ts +35 -0
  96. package/dist/script-validation.d.ts +16 -0
  97. package/dist/server-bindings.d.ts +7 -0
  98. package/dist/server-components.d.ts +4 -0
  99. package/dist/signal-processing.d.ts +109 -0
  100. package/dist/signals-api.d.ts +309 -0
  101. package/dist/signals.d.ts +2 -309
  102. package/dist/spa-shell.d.ts +1 -0
  103. package/dist/ssg.js +3862 -2655
  104. package/dist/ssr.d.ts +1 -0
  105. package/dist/state-management.d.ts +27 -0
  106. package/dist/store-imports.d.ts +24 -0
  107. package/dist/store-loader.d.ts +16 -0
  108. package/dist/story/bun-test.d.ts +1 -0
  109. package/dist/story/compiled-output.d.ts +1 -0
  110. package/dist/story/interactions.d.ts +1 -0
  111. package/dist/story/renderer.d.ts +2 -0
  112. package/dist/story/setup.d.ts +1 -0
  113. package/dist/story/ui/code-panel.d.ts +1 -0
  114. package/dist/stx.d.ts +437 -0
  115. package/dist/style-scoping.d.ts +23 -0
  116. package/dist/template-compiler.d.ts +31 -0
  117. package/dist/template-hydrator.d.ts +18 -0
  118. package/dist/transitions.d.ts +1 -0
  119. package/dist/types/config-types.d.ts +62 -0
  120. package/dist/validator.d.ts +1 -0
  121. package/dist/variable-extractor.d.ts +1 -1
  122. package/dist/view-composers.d.ts +1 -0
  123. package/dist/virtual-scrolling.d.ts +1 -0
  124. package/dist/visual-testing.js +2 -2
  125. package/dist/web-components.d.ts +1 -0
  126. package/dist/x-element.d.ts +1 -0
  127. package/package.json +72 -7
  128. package/stx.d.ts +437 -0
@@ -1,18 +1,4 @@
1
- /**
2
- * Process reactive directives in a template.
3
- *
4
- * Transforms `x-data`, `x-model`, `x-show`, etc. into client-side reactivity.
5
- *
6
- * @param template - The HTML template string
7
- * @param context - Template context
8
- * @param filePath - Source file path for error messages
9
- * @returns Processed template with reactive runtime script
10
- */
11
- export declare function processReactiveDirectives(template: string, _context: Record<string, unknown>, _filePath: string): string;
12
- /**
13
- * Check if a template contains reactive directives
14
- */
15
- export declare function hasReactiveDirectives(template: string): boolean;
1
+ /* eslint-disable prefer-const, style/max-statements-per-line, no-super-linear-backtracking, regexp/no-unused-capturing-group */
16
2
  /**
17
3
  * Reactive Directives Module
18
4
  *
@@ -82,7 +68,7 @@ export declare interface ReactiveScope {
82
68
  }
83
69
  export declare interface ReactiveBinding {
84
70
  elementId: string
85
- type: 'model' | 'show' | 'hide' | 'text' | 'html' | 'bind' | 'class' | 'style'
71
+ type: 'model' | 'show' | 'hide' | 'text' | 'html' | 'bind' | 'class' | 'style' | 'event'
86
72
  expression: string
87
73
  attribute?: string
88
74
  inputType?: string
@@ -207,6 +207,7 @@ export type DefineComponent<Props = {}, RawBindings = {}, D = any> = {
207
207
  /** Generic component type */
208
208
  export type Component<Props = any> = DefineComponent<Props>;
209
209
  /** Subscriber callback */
210
+ // eslint-disable-next-line pickier/no-unused-vars
210
211
  export type WatchCallback<T> = (newValue: T, oldValue: T | undefined) => void;
211
212
  /** Lifecycle hook callback */
212
213
  export type LifecycleHook = () => void | Promise<void>;
package/dist/router.d.ts CHANGED
@@ -8,4 +8,4 @@ export declare interface RouterOptions {
8
8
  pagesDir?: string
9
9
  extensions?: string[]
10
10
  }
11
- export { findErrorPage, formatRoutes, generateRouteTypes, matchRoute } from 'stx-router';
11
+ export { findErrorPage, formatRoutes, generateRouteManifest, generateRouteTypes, matchRoute } from 'stx-router';
@@ -0,0 +1,20 @@
1
+ import type { StxOptions } from './types';
2
+ /**
3
+ * Inject @stacksjs/browser initialization script into the template.
4
+ * This sets up window.StacksBrowser for auto-imports to work.
5
+ *
6
+ * IMPORTANT: Only checks CLIENT scripts (not <script server>).
7
+ * Server scripts should use the server ORM directly, not browser functions.
8
+ */
9
+ export declare function injectBrowserRuntime(template: string): string;
10
+ /**
11
+ * Inject STX signals runtime into the template.
12
+ * The runtime provides client-side reactivity.
13
+ */
14
+ export declare function injectSignalsRuntime(template: string, options: StxOptions): Promise<string>;
15
+ /**
16
+ * Inject the SPA router script into the template.
17
+ * The router is provided by the canonical router in packages/router/src/client.ts.
18
+ * It guards against double-initialization so it's safe to inject alongside @stxRouter.
19
+ */
20
+ export declare function injectRouterScript(template: string, options?: StxOptions): Promise<string>;
package/dist/runtime.d.ts CHANGED
@@ -9,9 +9,9 @@
9
9
  * appStore.setState({ count: appStore.state.count + 1 })
10
10
  * ```
11
11
  */
12
- export declare function useStore<T = unknown>(name: string): StoreRef<T> | null;
12
+ export declare function useStore<T = unknown>(name: string): StoreRef<T>;
13
13
  /**
14
- * Get a store, throwing if not found
14
+ * @deprecated Use `useStore` — it now throws if the store is not found.
15
15
  */
16
16
  export declare function useStoreOrThrow<T = unknown>(name: string): StoreRef<T>;
17
17
  /**
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Classify a `<script>` tag as signals, client, or server.
3
+ *
4
+ * Classification rules (in priority order):
5
+ * 1. Explicit `server` attribute → server
6
+ * 2. Uses signals API (state, derived, effect, etc.) → signals
7
+ * 3. Has `client` attribute, `type="module"`, or `src=` → client
8
+ * 4. Everything else → server (executed at build time for variable extraction)
9
+ */
10
+ export declare function classifyScript(attrs: string, content: string, fullTag: string): ScriptClassification;
11
+ /**
12
+ * Classify all `<script>` tags in a template.
13
+ *
14
+ * Returns arrays of scripts grouped by type.
15
+ */
16
+ export declare function classifyAllScripts(content: string): {
17
+ signals: ScriptClassification[]
18
+ client: ScriptClassification[]
19
+ server: ScriptClassification[]
20
+ };
21
+ export declare interface ScriptClassification {
22
+ type: ScriptType
23
+ fullTag: string
24
+ content: string
25
+ attrs: string
26
+ }
27
+ /**
28
+ * Script Classification
29
+ *
30
+ * Single source of truth for classifying `<script>` tags in `.stx` files.
31
+ * Used by bun-plugin, dev-server, and process.ts to ensure consistent behavior.
32
+ *
33
+ * @module script-classifier
34
+ */
35
+ export type ScriptType = 'signals' | 'client' | 'server';
@@ -0,0 +1,16 @@
1
+ import type { StrictModeConfig } from './types';
2
+ /**
3
+ * Validate client script content for prohibited DOM API patterns.
4
+ * When strict mode is enabled with `failOnViolation`, throws an error.
5
+ * Otherwise, emits warnings.
6
+ *
7
+ * @param content - The script content to validate
8
+ * @param filePath - The file path for error reporting
9
+ * @param strict - Strict mode configuration
10
+ */
11
+ export declare function validateClientScript(content: string, filePath: string, strict?: boolean | StrictModeConfig): void;
12
+ /**
13
+ * Prohibited DOM API patterns in client scripts.
14
+ * STX provides Vue-style alternatives via the STX global object.
15
+ */
16
+ export declare const PROHIBITED_DOM_PATTERNS: readonly [unknown];
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Process server-side `:attr="expr"` bindings in a template.
3
+ *
4
+ * Called after server scripts have executed and before expression processing,
5
+ * so the context contains all server-side variables.
6
+ */
7
+ export declare function processServerBindings(template: string, context: Record<string, any>): string;
@@ -39,6 +39,10 @@ export declare function renderClientComponent(name: string, options?: RenderOpti
39
39
  * Render any registered component.
40
40
  */
41
41
  export declare function renderComponent(name: string, options?: RenderOptions): Promise<RenderResult>;
42
+ /**
43
+ * Clean up resolved/errored suspense states to prevent memory leaks.
44
+ */
45
+ export declare function cleanupSuspenseStates(): void;
42
46
  /**
43
47
  * Create a suspense boundary.
44
48
  */
@@ -0,0 +1,109 @@
1
+ import type { StxOptions } from './types';
2
+ /**
3
+ * Scan a template for `<script>` tags in browser order: each opening tag is
4
+ * closed by the **first** subsequent `</script>` (case-insensitive), and the
5
+ * scanner then continues from after that close tag. This matches how HTML
6
+ * parsers tokenize `<script>` as a RAWTEXT element — they don't re-scan the
7
+ * body for more `<script` openings.
8
+ *
9
+ * A plain regex like `/<script[^>]*>([\s\S]*?)<\/script>/g` doesn't give you
10
+ * this property: if a script body contains the literal text `<script client>`
11
+ * (e.g. inside a JS comment), the regex matches it as a fresh script tag,
12
+ * which breaks downstream TypeScript transpilation and directive parsing.
13
+ *
14
+ * `skipAttrs` lets callers drop tags whose attribute string contains certain
15
+ * patterns (e.g. `server`, `src=`, `data-stx-scoped`).
16
+ */
17
+ export declare function scanScriptTags(html: string, opts?: { skipAttrs?: RegExp }): Array<{ fullMatch: string, attrs: string, body: string, start: number, end: number }>;
18
+ /**
19
+ * Parse a loop argument — accepts every syntax stx supports at runtime.
20
+ *
21
+ * ```
22
+ * parseLoopExpression('items as item') → { style:'as', iterable:'items', itemVar:'item', indexVar:null }
23
+ * parseLoopExpression('items as idx => item') → { style:'as', iterable:'items', itemVar:'item', indexVar:'idx' }
24
+ * parseLoopExpression('items as item, idx') → { style:'as', iterable:'items', itemVar:'item', indexVar:'idx' }
25
+ * parseLoopExpression('items as (item, idx)') → { style:'as', iterable:'items', itemVar:'item', indexVar:'idx' }
26
+ * parseLoopExpression('obj.list as item') → { style:'as', iterable:'obj.list', itemVar:'item', indexVar:null }
27
+ * parseLoopExpression('item in items') → { style:'in', iterable:'items', itemVar:'item', indexVar:null }
28
+ * parseLoopExpression('(item, idx) in items') → { style:'in', iterable:'items', itemVar:'item', indexVar:'idx' }
29
+ * parseLoopExpression('item of items') → { style:'in', iterable:'items', itemVar:'item', indexVar:null }
30
+ * ```
31
+ */
32
+ export declare function parseLoopExpression(expr: string): ParsedLoopExpression;
33
+ /**
34
+ * Check if template uses STX signals syntax.
35
+ *
36
+ * STX directives work seamlessly on both server and client:
37
+ * - `@if`, `@else` - Conditional rendering
38
+ * - `@for` - List iteration
39
+ * - `@show` - Toggle visibility (keeps element in DOM)
40
+ * - `@model` - Two-way binding
41
+ * - `@bind:attr` - Dynamic attribute binding
42
+ * - `@class`, `@style` - Dynamic class/style binding
43
+ * - `@click`, `@submit` - Event handling
44
+ * - Scripts containing `state(`, `derived(`, `effect(` - Signal APIs
45
+ *
46
+ * Server-side directives are processed at build time.
47
+ * Remaining directives with reactive values are handled by the client runtime.
48
+ */
49
+ export declare function hasSignalsSyntax(template: string): boolean;
50
+ /**
51
+ * Convert @if(expr)...@endif directive blocks to attribute-style for signal templates.
52
+ *
53
+ * This allows the signals runtime to handle reactive conditionals instead of
54
+ * evaluating them at build time with mock values.
55
+ *
56
+ * Converts:
57
+ * @if(loading())
58
+ * <div>Loading...</div>
59
+ * @endif
60
+ *
61
+ * To:
62
+ * <template @if="loading()">
63
+ * <div>Loading...</div>
64
+ * </template>
65
+ *
66
+ * Note: Uses <template> wrapper for blocks with multiple children or text nodes.
67
+ */
68
+ export declare function convertSignalDirectivesToAttributes(template: string): string;
69
+ /**
70
+ * Convert @for(item in items())...@endfor directive blocks to attribute-style.
71
+ *
72
+ * Converts:
73
+ * @for(item in items())
74
+ * <div>{{ item.name }}</div>
75
+ * @endfor
76
+ *
77
+ * To:
78
+ * <template @for="item in items()">
79
+ * <div>{{ item.name }}</div>
80
+ * </template>
81
+ */
82
+ export declare function convertSignalLoopsToAttributes(template: string, context?: Record<string, any>): string;
83
+ export declare function processScriptSetup(template: string, filePath?: string): Promise<{ output: string, setupCode: string | null }>;
84
+ /**
85
+ * Extract exported variable names from setup script.
86
+ * Returns variables that should be exposed to the template.
87
+ * Only extracts TOP-LEVEL declarations, not variables inside nested functions.
88
+ */
89
+ export declare function extractExports(setupContent: string): string;
90
+ /**
91
+ * Main orchestrator for signal processing.
92
+ *
93
+ * Detects signal syntax, wraps scripts in setup functions,
94
+ * injects the signals runtime and browser runtime.
95
+ */
96
+ export declare function processSignals(template: string, options: StxOptions, filePath?: string): Promise<string>;
97
+ /**
98
+ * Parsed form of a loop expression (`@for` / `@foreach` argument).
99
+ *
100
+ * `style: 'as'` — "iterable as item" / "iterable as idx => item" / "iterable as (item, idx)"
101
+ * `style: 'in'` — "item in iterable" / "(item, idx) in iterable" / "item of iterable"
102
+ * `style: 'unknown'` — fell through all parsers; iterable is `null`
103
+ */
104
+ export declare interface ParsedLoopExpression {
105
+ style: 'as' | 'in' | 'unknown'
106
+ iterable: string | null
107
+ itemVar: string | null
108
+ indexVar: string | null
109
+ }
@@ -0,0 +1,309 @@
1
+ /**
2
+ * Creates a reactive state signal.
3
+ *
4
+ * State signals are the foundation of STX reactivity. They hold a value that,
5
+ * when changed, automatically updates any derived signals or effects that
6
+ * depend on it.
7
+ *
8
+ * @param initialValue - The initial value for the signal
9
+ * @returns A signal that can be read, set, and subscribed to
10
+ *
11
+ * @example Basic usage
12
+ * ```typescript
13
+ * const count = state(0)
14
+ *
15
+ * // Read the value
16
+ * console.log(count()) // 0
17
+ *
18
+ * // Set a new value
19
+ * count.set(5)
20
+ * console.log(count()) // 5
21
+ *
22
+ * // Update based on current value
23
+ * count.update(n => n + 1)
24
+ * console.log(count()) // 6
25
+ * ```
26
+ *
27
+ * @example With objects
28
+ * ```typescript
29
+ * const user = state({ name: 'Alice', age: 30 })
30
+ *
31
+ * // Update the whole object
32
+ * user.set({ name: 'Bob', age: 25 })
33
+ *
34
+ * // Or update a property (creates new object for immutability)
35
+ * user.update(u => ({ ...u, age: u.age + 1 }))
36
+ * ```
37
+ *
38
+ * @example With arrays
39
+ * ```typescript
40
+ * const items = state<string[]>([])
41
+ *
42
+ * // Add an item
43
+ * items.update(arr => [...arr, 'new item'])
44
+ *
45
+ * // Remove an item
46
+ * items.update(arr => arr.filter(i => i !== 'remove me'))
47
+ * ```
48
+ */
49
+ export declare function state<T>(initialValue: T): Signal<T>;
50
+ /**
51
+ * Creates a derived signal that automatically computes its value from other signals.
52
+ *
53
+ * Derived signals are lazy - they only recompute when read after a dependency
54
+ * has changed. They're perfect for computed values that depend on other state.
55
+ *
56
+ * @param compute - A function that computes the derived value
57
+ * @returns A read-only signal with the computed value
58
+ *
59
+ * @example Basic derived value
60
+ * ```typescript
61
+ * const count = state(5)
62
+ * const doubled = derived(() => count() * 2)
63
+ *
64
+ * console.log(doubled()) // 10
65
+ * count.set(10)
66
+ * console.log(doubled()) // 20
67
+ * ```
68
+ *
69
+ * @example Combining multiple signals
70
+ * ```typescript
71
+ * const firstName = state('John')
72
+ * const lastName = state('Doe')
73
+ *
74
+ * const fullName = derived(() => `${firstName()} ${lastName()}`)
75
+ * console.log(fullName()) // "John Doe"
76
+ * ```
77
+ *
78
+ * @example Filtering and transforming
79
+ * ```typescript
80
+ * const items = state([1, 2, 3, 4, 5])
81
+ * const filter = state('even')
82
+ *
83
+ * const filteredItems = derived(() => {
84
+ * const list = items()
85
+ * return filter() === 'even'
86
+ * ? list.filter(n => n % 2 === 0)
87
+ * : list.filter(n => n % 2 !== 0)
88
+ * })
89
+ * ```
90
+ */
91
+ export declare function derived<T>(compute: () => T): DerivedSignal<T>;
92
+ /**
93
+ * Creates a side effect that runs when its dependencies change.
94
+ *
95
+ * Effects automatically track which signals they read and re-run whenever
96
+ * those signals change. They're perfect for syncing state with external
97
+ * systems, logging, or triggering side effects.
98
+ *
99
+ * @param fn - The effect function to run
100
+ * @param options - Optional configuration
101
+ * @returns A cleanup function to stop the effect
102
+ *
103
+ * @example Basic effect
104
+ * ```typescript
105
+ * const count = state(0)
106
+ *
107
+ * effect(() => {
108
+ * console.log(`Count changed to: ${count()}`)
109
+ * })
110
+ *
111
+ * count.set(1) // Logs: "Count changed to: 1"
112
+ * count.set(2) // Logs: "Count changed to: 2"
113
+ * ```
114
+ *
115
+ * @example Effect with cleanup
116
+ * ```typescript
117
+ * const isActive = state(true)
118
+ *
119
+ * effect(() => {
120
+ * if (isActive()) {
121
+ * const interval = setInterval(() => console.log('tick'), 1000)
122
+ * // Return cleanup function
123
+ * return () => clearInterval(interval)
124
+ * }
125
+ * })
126
+ * ```
127
+ *
128
+ * @example Fetching data
129
+ * ```typescript
130
+ * const userId = state(1)
131
+ * const user = state(null)
132
+ *
133
+ * effect(async () => {
134
+ * const id = userId()
135
+ * const response = await fetch(`/api/users/${id}`)
136
+ * user.set(await response.json())
137
+ * })
138
+ * ```
139
+ */
140
+ export declare function effect(fn: () => void | CleanupFn, options?: EffectOptions): CleanupFn;
141
+ /**
142
+ * Batches multiple signal updates into a single effect run.
143
+ *
144
+ * Use this when updating multiple signals at once to avoid redundant
145
+ * effect executions.
146
+ *
147
+ * @param fn - Function containing multiple signal updates
148
+ *
149
+ * @example
150
+ * ```typescript
151
+ * const firstName = state('John')
152
+ * const lastName = state('Doe')
153
+ *
154
+ * // Without batch: effect runs twice
155
+ * // With batch: effect runs once
156
+ * batch(() => {
157
+ * firstName.set('Jane')
158
+ * lastName.set('Smith')
159
+ * })
160
+ * ```
161
+ */
162
+ export declare function batch(fn: () => void): void;
163
+ /**
164
+ * Registers a callback to run when the component mounts (is inserted into the DOM).
165
+ *
166
+ * @param callback - Function to run on mount. Can return a cleanup function.
167
+ *
168
+ * @example
169
+ * ```typescript
170
+ * onMount(() => {
171
+ * console.log('Component is now in the DOM')
172
+ *
173
+ * // Optional: return cleanup function
174
+ * return () => console.log('Cleanup on unmount')
175
+ * })
176
+ * ```
177
+ *
178
+ * @example Fetching initial data
179
+ * ```typescript
180
+ * const data = state(null)
181
+ *
182
+ * onMount(async () => {
183
+ * data.set(await fetchInitialData())
184
+ * })
185
+ * ```
186
+ */
187
+ export declare function onMount(callback: LifecycleCallback): void;
188
+ /**
189
+ * Registers a callback to run when the component is destroyed (removed from the DOM).
190
+ *
191
+ * @param callback - Function to run on destroy
192
+ *
193
+ * @example
194
+ * ```typescript
195
+ * onDestroy(() => {
196
+ * console.log('Component is being removed')
197
+ * // Clean up subscriptions, timers, etc.
198
+ * })
199
+ * ```
200
+ */
201
+ export declare function onDestroy(callback: LifecycleCallback): void;
202
+ /**
203
+ * Checks if a value is a signal.
204
+ *
205
+ * @param value - Value to check
206
+ * @returns True if the value is a signal
207
+ *
208
+ * @example
209
+ * ```typescript
210
+ * const count = state(0)
211
+ * isSignal(count) // true
212
+ * isSignal(5) // false
213
+ * ```
214
+ */
215
+ export declare function isSignal(value: unknown): value is Signal<unknown>;
216
+ /**
217
+ * Checks if a value is a derived signal.
218
+ *
219
+ * @param value - Value to check
220
+ * @returns True if the value is a derived signal
221
+ */
222
+ export declare function isDerived(value: unknown): value is DerivedSignal<unknown>;
223
+ /**
224
+ * Unwraps a signal to get its raw value.
225
+ * If the value is not a signal, returns it as-is.
226
+ *
227
+ * @param value - A signal or plain value
228
+ * @returns The unwrapped value
229
+ *
230
+ * @example
231
+ * ```typescript
232
+ * const count = state(5)
233
+ * untrack(count) // 5
234
+ * untrack(10) // 10
235
+ * ```
236
+ */
237
+ export declare function untrack<T>(value: T | Signal<T> | DerivedSignal<T>): T;
238
+ /**
239
+ * Reads a signal's value without tracking it as a dependency.
240
+ *
241
+ * Use this when you need to read a signal inside an effect but don't want
242
+ * the effect to re-run when that signal changes.
243
+ *
244
+ * @param fn - Function to run without tracking
245
+ * @returns The function's return value
246
+ *
247
+ * @example
248
+ * ```typescript
249
+ * const count = state(0)
250
+ * const other = state(0)
251
+ *
252
+ * effect(() => {
253
+ * // This effect only re-runs when `count` changes
254
+ * console.log(count())
255
+ *
256
+ * // Reading `other` without tracking
257
+ * const otherValue = peek(() => other())
258
+ * })
259
+ * ```
260
+ */
261
+ export declare function peek<T>(fn: () => T): T;
262
+ /**
263
+ * A reactive state signal.
264
+ *
265
+ * Call it to read the value, use `.set()` to write, or `.update()` to transform.
266
+ *
267
+ * @example
268
+ * ```typescript
269
+ * const count = state(0)
270
+ * count() // Read: 0
271
+ * count.set(5) // Write: 5
272
+ * count.update(n => n + 1) // Update: 6
273
+ * ```
274
+ */
275
+ export declare interface Signal<T> {
276
+ (): T
277
+ set(value: T): void
278
+ update(fn: (current: T) => T): void
279
+ subscribe(callback: (value: T, prev: T) => void): () => void
280
+ readonly _isSignal: true
281
+ }
282
+ /**
283
+ * A derived (computed) signal that automatically updates when dependencies change.
284
+ *
285
+ * @example
286
+ * ```typescript
287
+ * const doubled = derived(() => count() * 2)
288
+ * doubled() // Read the computed value
289
+ * ```
290
+ */
291
+ export declare interface DerivedSignal<T> {
292
+ (): T
293
+ readonly _isDerived: true
294
+ }
295
+ /**
296
+ * Options for creating effects.
297
+ */
298
+ export declare interface EffectOptions {
299
+ immediate?: boolean
300
+ name?: string
301
+ }
302
+ /**
303
+ * Cleanup function returned by effects.
304
+ */
305
+ export type CleanupFn = () => void;
306
+ /**
307
+ * Lifecycle hook callback.
308
+ */
309
+ export type LifecycleCallback = () => void | CleanupFn | Promise<void>;