@stacksjs/stx
Version:
A performant UI Framework. Powered by Bun.
268 lines • 7.48 kB
TypeScript
/**
* Create a new component instance context.
* Called internally when a component script starts executing.
*/
export declare function createComponentInstance(element?: Element): ComponentInstance;
/**
* Set the current component instance context.
*/
export declare function setCurrentInstance(instance: ComponentInstance | null): void;
/**
* Get the current component instance context.
*/
export declare function getCurrentInstance(): ComponentInstance | null;
/**
* Register a callback to run when the component is mounted to the DOM.
*
* @example
* ```html
* <script client>
* import { onMount } from 'stx'
*
* onMount(() => {
* console.log('Component mounted!')
*
* // Return cleanup function (optional)
* return () => {
* console.log('Cleanup on unmount')
* }
* })
* </script>
* ```
*/
export declare function onMount(hook: LifecycleHook): void;
/**
* Register a callback to run when the component is destroyed/unmounted.
*
* @example
* ```html
* <script client>
* import { onMount, onDestroy } from 'stx'
*
* onMount(() => {
* const interval = setInterval(() => console.log('tick'), 1000)
*
* onDestroy(() => {
* clearInterval(interval)
* })
* })
* </script>
* ```
*/
export declare function onDestroy(hook: CleanupFn): void;
/**
* Register a callback to run when the component updates.
*
* @example
* ```html
* <script client>
* import { onUpdate } from 'stx'
*
* onUpdate(() => {
* console.log('Component updated!')
* })
* </script>
* ```
*/
export declare function onUpdate(hook: LifecycleHook): void;
/**
* Create a ref for holding a DOM element reference.
*
* @example
* ```html
* <script client>
* import { ref, onMount } from 'stx'
*
* const inputRef = ref<HTMLInputElement>()
*
* onMount(() => {
* inputRef.value?.focus()
* })
* </script>
*
* <input type="text" @ref="inputRef" />
* ```
*/
export declare function ref<T = HTMLElement>(initialValue?: T | null): Ref<T>;
/**
* Create a named ref that can be bound via @ref="name" in templates.
*/
export declare function namedRef<T = HTMLElement>(name: string, initialValue?: T | null): Ref<T>;
/**
* Watch a reactive source and run a callback when it changes.
*
* @example
* ```html
* <script client>
* import { watch } from 'stx'
* import { counterStore } from '@stores'
*
* watch(
* () => counterStore.count,
* (newVal, oldVal) => {
* console.log(`Count changed: ${oldVal} → ${newVal}`)
* }
* )
* </script>
* ```
*/
export declare function watch<T>(source: WatchSource<T>, callback: WatchCallback<T>, options?: { immediate?: boolean }): () => void;
/**
* Create a computed value that updates when dependencies change.
*
* @example
* ```html
* <script client>
* import { computed } from 'stx'
* import { counterStore } from '@stores'
*
* const doubleCount = computed(() => counterStore.count * 2)
*
* // Access value
* console.log(doubleCount.value)
* </script>
* ```
*/
export declare function computed<T>(getter: () => T): { readonly value: T };
/**
* Initialize a component and run its setup.
* This is called by the STX runtime when a component is created.
*/
export declare function setupComponent(element: Element, setup: () => void): ComponentInstance;
/**
* Mount a component instance - runs onMount hooks.
*/
export declare function mountComponent(instance: ComponentInstance): void;
/**
* Update a component instance - runs onUpdate hooks.
*/
export declare function updateComponent(instance: ComponentInstance): void;
/**
* Destroy a component instance - runs cleanup and onDestroy hooks.
*/
export declare function destroyComponent(instance: ComponentInstance): void;
/**
* Generate the client-side runtime script for lifecycle management.
*/
export declare function generateLifecycleRuntime(): string;
/**
* Create a typed injection key.
*
* @example
* ```typescript
* const ThemeKey = createInjectionKey<{ mode: 'dark' | 'light' }>('theme')
* ```
*/
export declare function createInjectionKey<T>(description?: string): InjectionKey<T>;
/**
* Provide a value that can be injected by descendant components.
*
* @example
* ```html
* <script server>
* import { provide } from 'stx'
*
* // Provide a theme object
* provide('theme', { mode: 'dark', accent: 'purple' })
*
* // Or with a typed key
* import { ThemeKey } from './injection-keys'
* provide(ThemeKey, { mode: 'dark', accent: 'purple' })
* </script>
* ```
*/
export declare function provide<T>(key: string | InjectionKey<T>, value: T): void;
/**
* Inject a value provided by an ancestor component.
*
* @example
* ```html
* <script client>
* import { inject } from 'stx'
*
* // Inject with default value
* const theme = inject('theme', { mode: 'light', accent: 'blue' })
*
* // Inject required value (throws if not provided)
* const auth = inject('auth')
* </script>
* ```
*/
export declare function inject<T>(key: string | InjectionKey<T>): T | undefined;
export declare function inject<T>(key: string | InjectionKey<T>, defaultValue: T): T;
export declare function inject<T>(key: string | InjectionKey<T>, defaultValue?: T): T | undefined;
/**
* Create a new injection scope.
* Called internally when entering a component.
*/
export declare function pushInjectionScope(): void;
/**
* Exit the current injection scope.
* Called internally when leaving a component.
*/
export declare function popInjectionScope(): void;
/**
* Run a function within a new injection scope.
* Useful for component rendering.
*/
export declare function withInjectionScope<T>(fn: () => T | Promise<T>): Promise<T>;
/**
* Clear all injections (for testing).
*/
export declare function clearInjections(): void;
/**
* Alias for onMount - matches common naming conventions.
*/
export declare const onMounted: unknown;
/**
* Alias for onDestroy - matches Vue naming.
*/
export declare const onUnmounted: unknown;
/**
* Alias for onUpdate - matches Vue naming.
*/
export declare const onUpdated: unknown;
/** Built-in injection key for theme */
export declare const ThemeKey: unknown;
/** Built-in injection key for router */
export declare const RouterKey: (createInjectionKey<{
currentRoute: string
navigate: (path: string)) => unknown;
/** Built-in injection key for i18n */
export declare const I18nKey: (createInjectionKey<{
locale: string
t: (key: string)) => unknown;
export declare interface Ref<T> {
value: T | null
current: T | null
}
export declare interface ComponentInstance {
id: string
element: Element | null
mountHooks: LifecycleHook[]
destroyHooks: CleanupFn[]
updateHooks: LifecycleHook[]
refs: Map<string, Ref<any>>
watchers: Array<{ stop: () => void }>
isMounted: boolean
}
/**
* STX Composables
*
* Vue-inspired composable utilities for STX components:
* - Lifecycle hooks (onMount, onDestroy, onUpdate)
* - Refs for DOM element references
* - Watch and computed for reactivity
*
* @module composables
*/
// =============================================================================
// Types
// =============================================================================
export type LifecycleHook = () => void | (() => void)
export type CleanupFn = () => void
export type WatchCallback<T> = (newValue: T, oldValue: T | undefined) => void | CleanupFn
export type WatchSource<T> = () => T
/** Symbol for injection keys */
export type InjectionKey<T> = symbol & { __type?: T }
export { ref as createRef };