@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.
- package/README.md +16 -11
- package/dist/a11y.d.ts +2 -1
- package/dist/analyzer.d.ts +4 -0
- package/dist/app-shell.d.ts +72 -0
- package/dist/app.d.ts +1 -0
- package/dist/broadcasting.d.ts +77 -0
- package/dist/build-assets.d.ts +32 -0
- package/dist/build-mode-detector.d.ts +26 -0
- package/dist/build.d.ts +31 -0
- package/dist/builtins/icon.d.ts +7 -0
- package/dist/builtins/index.d.ts +21 -0
- package/dist/builtins/stx-image.d.ts +2 -0
- package/dist/builtins/stx-link.d.ts +2 -0
- package/dist/builtins/stx-loading-indicator.d.ts +2 -0
- package/dist/bundle-analyzer/index.d.ts +2 -0
- package/dist/bundle-analyzer.js +20 -20
- package/dist/caching.d.ts +27 -0
- package/dist/cli.js +3941 -2609
- package/dist/client-helpers.d.ts +7 -3
- package/dist/client-script-bundler.d.ts +27 -0
- package/dist/client-script.d.ts +5 -1
- package/dist/client.d.ts +1 -0
- package/dist/component-hmr.d.ts +1 -0
- package/dist/component-processing.d.ts +107 -0
- package/dist/component-registry.d.ts +54 -0
- package/dist/component-renderer.d.ts +18 -0
- package/dist/components/StxImage.stx +12 -0
- package/dist/components/StxLink.stx +18 -8
- package/dist/composables/index.d.ts +7 -0
- package/dist/composables/use-broadcast-channel.d.ts +1 -0
- package/dist/composables/use-channel.d.ts +67 -0
- package/dist/composables/use-intersection-observer.d.ts +2 -0
- package/dist/composables/use-keyboard.d.ts +1 -0
- package/dist/composables/use-mouse.d.ts +1 -0
- package/dist/composables/use-router.d.ts +4 -0
- package/dist/composables/use-websocket.d.ts +1 -0
- package/dist/composables.d.ts +2 -0
- package/dist/composition-api.d.ts +1 -0
- package/dist/computed.d.ts +1 -0
- package/dist/config.d.ts +12 -1
- package/dist/craft-bridge.d.ts +6 -3
- package/dist/craft-components.d.ts +1 -0
- package/dist/craft.js +39 -33
- package/dist/deploy/index.d.ts +1 -0
- package/dist/dev-server/crosswind.d.ts +2 -5
- package/dist/dev-server/native-window.d.ts +19 -1
- package/dist/dev-server/serve-app.d.ts +15 -0
- package/dist/dev-server/serve-file.d.ts +3 -0
- package/dist/dev-server/serve-markdown.d.ts +3 -0
- package/dist/dev-server/serve-multi.d.ts +5 -0
- package/dist/dev-server/types.d.ts +2 -0
- package/dist/dev-server.d.ts +6 -40
- package/dist/devtools.d.ts +1 -0
- package/dist/directive-api.d.ts +1 -1
- package/dist/document-shell.d.ts +33 -0
- package/dist/error-boundaries.d.ts +1 -0
- package/dist/events.d.ts +1 -0
- package/dist/expressions.d.ts +38 -0
- package/dist/forms-validation.d.ts +2 -0
- package/dist/head.d.ts +1 -0
- package/dist/hot-reload.d.ts +1 -0
- package/dist/hydration-runtime.d.ts +1 -0
- package/dist/hydration.d.ts +1 -0
- package/dist/i18n.d.ts +3 -1
- package/dist/image-optimization/build-plugin.d.ts +1 -0
- package/dist/index.d.ts +22 -1
- package/dist/index.js +5569 -4182
- package/dist/inline-assets.d.ts +28 -0
- package/dist/internal-markdown.d.ts +0 -4
- package/dist/jsx-runtime.d.ts +1 -0
- package/dist/keep-alive.d.ts +1 -0
- package/dist/manifest.d.ts +41 -0
- package/dist/markdown.d.ts +1 -0
- package/dist/media/client/blur-up.d.ts +1 -0
- package/dist/media/client/lazy-load.d.ts +1 -0
- package/dist/media/client/upload-handler.d.ts +1 -0
- package/dist/media/shared/cache.d.ts +2 -0
- package/dist/media/video/index.d.ts +1 -0
- package/dist/media/video/processor/thumbnail.d.ts +1 -0
- package/dist/misc-directives.d.ts +49 -0
- package/dist/parser/directive-parser.d.ts +13 -0
- package/dist/performance-utils.d.ts +2 -0
- package/dist/placeholder.d.ts +45 -0
- package/dist/plugin-system.d.ts +32 -2
- package/dist/process.d.ts +11 -1
- package/dist/production-builder.d.ts +42 -0
- package/dist/production-server.d.ts +19 -0
- package/dist/props.d.ts +1 -0
- package/dist/pwa.js +3883 -2679
- package/dist/reactive.d.ts +2 -16
- package/dist/reactivity.d.ts +1 -0
- package/dist/router.d.ts +1 -1
- package/dist/runtime-injection.d.ts +20 -0
- package/dist/runtime.d.ts +2 -2
- package/dist/script-classifier.d.ts +35 -0
- package/dist/script-validation.d.ts +16 -0
- package/dist/server-bindings.d.ts +7 -0
- package/dist/server-components.d.ts +4 -0
- package/dist/signal-processing.d.ts +109 -0
- package/dist/signals-api.d.ts +309 -0
- package/dist/signals.d.ts +2 -309
- package/dist/spa-shell.d.ts +1 -0
- package/dist/ssg.js +3862 -2655
- package/dist/ssr.d.ts +1 -0
- package/dist/state-management.d.ts +27 -0
- package/dist/store-imports.d.ts +24 -0
- package/dist/store-loader.d.ts +16 -0
- package/dist/story/bun-test.d.ts +1 -0
- package/dist/story/compiled-output.d.ts +1 -0
- package/dist/story/interactions.d.ts +1 -0
- package/dist/story/renderer.d.ts +2 -0
- package/dist/story/setup.d.ts +1 -0
- package/dist/story/ui/code-panel.d.ts +1 -0
- package/dist/stx.d.ts +437 -0
- package/dist/style-scoping.d.ts +23 -0
- package/dist/template-compiler.d.ts +31 -0
- package/dist/template-hydrator.d.ts +18 -0
- package/dist/transitions.d.ts +1 -0
- package/dist/types/config-types.d.ts +62 -0
- package/dist/validator.d.ts +1 -0
- package/dist/variable-extractor.d.ts +1 -1
- package/dist/view-composers.d.ts +1 -0
- package/dist/virtual-scrolling.d.ts +1 -0
- package/dist/visual-testing.js +2 -2
- package/dist/web-components.d.ts +1 -0
- package/dist/x-element.d.ts +1 -0
- package/package.json +72 -7
- package/stx.d.ts +437 -0
package/dist/reactive.d.ts
CHANGED
|
@@ -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
|
package/dist/reactivity.d.ts
CHANGED
|
@@ -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
|
|
12
|
+
export declare function useStore<T = unknown>(name: string): StoreRef<T>;
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
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>;
|