@fictjs/runtime 0.0.13 → 0.0.14
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/advanced.cjs +79 -0
- package/dist/advanced.cjs.map +1 -0
- package/dist/advanced.d.cts +50 -0
- package/dist/advanced.d.ts +50 -0
- package/dist/advanced.js +79 -0
- package/dist/advanced.js.map +1 -0
- package/dist/chunk-624QY53A.cjs +45 -0
- package/dist/chunk-624QY53A.cjs.map +1 -0
- package/dist/chunk-F3AIYQB7.js +45 -0
- package/dist/chunk-F3AIYQB7.js.map +1 -0
- package/dist/chunk-GJTYOFMO.cjs +109 -0
- package/dist/chunk-GJTYOFMO.cjs.map +1 -0
- package/dist/chunk-IUZXKAAY.js +109 -0
- package/dist/chunk-IUZXKAAY.js.map +1 -0
- package/dist/chunk-PMF6MWEV.cjs +3301 -0
- package/dist/chunk-PMF6MWEV.cjs.map +1 -0
- package/dist/chunk-RY4WDS6R.js +3301 -0
- package/dist/chunk-RY4WDS6R.js.map +1 -0
- package/dist/context-B7UYnfzM.d.ts +153 -0
- package/dist/context-UXySaqI_.d.cts +153 -0
- package/dist/effect-Auji1rz9.d.cts +350 -0
- package/dist/effect-Auji1rz9.d.ts +350 -0
- package/dist/index.cjs +98 -3558
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -1358
- package/dist/index.d.ts +5 -1358
- package/dist/index.dev.js +240 -1698
- package/dist/index.dev.js.map +1 -1
- package/dist/index.js +63 -3435
- package/dist/index.js.map +1 -1
- package/dist/internal.cjs +901 -0
- package/dist/internal.cjs.map +1 -0
- package/dist/internal.d.cts +158 -0
- package/dist/internal.d.ts +158 -0
- package/dist/internal.js +901 -0
- package/dist/internal.js.map +1 -0
- package/dist/{jsx-dev-runtime.d.ts → props-CrOMYbLv.d.cts} +107 -18
- package/dist/{jsx-dev-runtime.d.cts → props-ES0Ag_Wd.d.ts} +107 -18
- package/dist/scope-DKYzWfTn.d.cts +55 -0
- package/dist/scope-S6eAzBJZ.d.ts +55 -0
- package/package.json +11 -1
- package/src/advanced.ts +101 -0
- package/src/constants.ts +3 -26
- package/src/context.ts +300 -0
- package/src/delegated-events.ts +24 -0
- package/src/index.ts +41 -112
- package/src/internal.ts +130 -0
- package/src/props.ts +48 -46
- package/src/store.ts +47 -7
- package/src/versioned-signal.ts +3 -3
- package/dist/jsx-runtime.d.cts +0 -671
- package/dist/jsx-runtime.d.ts +0 -671
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { B as BaseProps, F as FictNode } from './effect-Auji1rz9.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Context API for Fict
|
|
5
|
+
*
|
|
6
|
+
* Provides a way to pass data through the component tree without having to pass
|
|
7
|
+
* props down manually at every level. Context is designed for:
|
|
8
|
+
*
|
|
9
|
+
* - SSR isolation (different request = different context values)
|
|
10
|
+
* - Multi-instance support (multiple app roots with different values)
|
|
11
|
+
* - Subtree scoping (override values in specific parts of the tree)
|
|
12
|
+
*
|
|
13
|
+
* ## Design Principles
|
|
14
|
+
*
|
|
15
|
+
* 1. **Reuses existing RootContext hierarchy** - Uses parent chain for value lookup,
|
|
16
|
+
* consistent with handleError/handleSuspend mechanisms.
|
|
17
|
+
*
|
|
18
|
+
* 2. **Zero extra root creation overhead** - Provider doesn't create new root,
|
|
19
|
+
* only mounts value on current root.
|
|
20
|
+
*
|
|
21
|
+
* 3. **Auto-aligned with insert/suspense boundaries** - Because they create child
|
|
22
|
+
* roots that inherit parent, context values propagate correctly.
|
|
23
|
+
*
|
|
24
|
+
* ## Usage
|
|
25
|
+
*
|
|
26
|
+
* ```tsx
|
|
27
|
+
* // Create context with default value
|
|
28
|
+
* const ThemeContext = createContext<'light' | 'dark'>('light')
|
|
29
|
+
*
|
|
30
|
+
* // Provide value to subtree
|
|
31
|
+
* function App() {
|
|
32
|
+
* return (
|
|
33
|
+
* <ThemeContext.Provider value="dark">
|
|
34
|
+
* <ThemedComponent />
|
|
35
|
+
* </ThemeContext.Provider>
|
|
36
|
+
* )
|
|
37
|
+
* }
|
|
38
|
+
*
|
|
39
|
+
* // Consume value
|
|
40
|
+
* function ThemedComponent() {
|
|
41
|
+
* const theme = useContext(ThemeContext)
|
|
42
|
+
* return <div class={theme}>...</div>
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* @module
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Context object created by createContext.
|
|
51
|
+
* Contains the Provider component and serves as a key for context lookup.
|
|
52
|
+
*/
|
|
53
|
+
interface Context<T> {
|
|
54
|
+
/** Unique identifier for this context */
|
|
55
|
+
readonly id: symbol;
|
|
56
|
+
/** Default value when no provider is found */
|
|
57
|
+
readonly defaultValue: T;
|
|
58
|
+
/** Provider component for supplying context values */
|
|
59
|
+
Provider: ContextProvider<T>;
|
|
60
|
+
/** Display name for debugging */
|
|
61
|
+
displayName?: string;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Props for the Context Provider component
|
|
65
|
+
*/
|
|
66
|
+
interface ProviderProps<T> extends BaseProps {
|
|
67
|
+
/** The value to provide to the subtree */
|
|
68
|
+
value: T;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Provider component type
|
|
72
|
+
*/
|
|
73
|
+
type ContextProvider<T> = (props: ProviderProps<T>) => FictNode;
|
|
74
|
+
/**
|
|
75
|
+
* Creates a new context with the given default value.
|
|
76
|
+
*
|
|
77
|
+
* Context provides a way to pass values through the component tree without
|
|
78
|
+
* explicit props drilling. It's especially useful for:
|
|
79
|
+
*
|
|
80
|
+
* - Theme data
|
|
81
|
+
* - Locale/i18n settings
|
|
82
|
+
* - Authentication state
|
|
83
|
+
* - Feature flags
|
|
84
|
+
* - Any data that many components at different nesting levels need
|
|
85
|
+
*
|
|
86
|
+
* @param defaultValue - The value to use when no Provider is found above in the tree
|
|
87
|
+
* @returns A context object with a Provider component
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```tsx
|
|
91
|
+
* // Create a theme context
|
|
92
|
+
* const ThemeContext = createContext<'light' | 'dark'>('light')
|
|
93
|
+
*
|
|
94
|
+
* // Use the provider
|
|
95
|
+
* function App() {
|
|
96
|
+
* return (
|
|
97
|
+
* <ThemeContext.Provider value="dark">
|
|
98
|
+
* <Content />
|
|
99
|
+
* </ThemeContext.Provider>
|
|
100
|
+
* )
|
|
101
|
+
* }
|
|
102
|
+
*
|
|
103
|
+
* // Consume the context
|
|
104
|
+
* function Content() {
|
|
105
|
+
* const theme = useContext(ThemeContext)
|
|
106
|
+
* return <div class={`theme-${theme}`}>Hello</div>
|
|
107
|
+
* }
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
declare function createContext<T>(defaultValue: T): Context<T>;
|
|
111
|
+
/**
|
|
112
|
+
* Reads the current value of a context.
|
|
113
|
+
*
|
|
114
|
+
* useContext looks up through the RootContext parent chain to find the
|
|
115
|
+
* nearest Provider for this context. If no Provider is found, returns
|
|
116
|
+
* the context's default value.
|
|
117
|
+
*
|
|
118
|
+
* @param context - The context object created by createContext
|
|
119
|
+
* @returns The current context value
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```tsx
|
|
123
|
+
* const ThemeContext = createContext('light')
|
|
124
|
+
*
|
|
125
|
+
* function ThemedButton() {
|
|
126
|
+
* const theme = useContext(ThemeContext)
|
|
127
|
+
* return <button class={theme === 'dark' ? 'btn-dark' : 'btn-light'}>Click</button>
|
|
128
|
+
* }
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
declare function useContext<T>(context: Context<T>): T;
|
|
132
|
+
/**
|
|
133
|
+
* Checks if a context value is currently provided in the tree.
|
|
134
|
+
*
|
|
135
|
+
* Useful for conditional behavior when a provider may or may not exist.
|
|
136
|
+
*
|
|
137
|
+
* @param context - The context object to check
|
|
138
|
+
* @returns true if a Provider exists above in the tree
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* ```tsx
|
|
142
|
+
* function OptionalTheme() {
|
|
143
|
+
* if (hasContext(ThemeContext)) {
|
|
144
|
+
* const theme = useContext(ThemeContext)
|
|
145
|
+
* return <div class={theme}>Themed content</div>
|
|
146
|
+
* }
|
|
147
|
+
* return <div>Default content</div>
|
|
148
|
+
* }
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
151
|
+
declare function hasContext<T>(context: Context<T>): boolean;
|
|
152
|
+
|
|
153
|
+
export { type Context as C, type ProviderProps as P, createContext as c, hasContext as h, useContext as u };
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { B as BaseProps, F as FictNode } from './effect-Auji1rz9.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Context API for Fict
|
|
5
|
+
*
|
|
6
|
+
* Provides a way to pass data through the component tree without having to pass
|
|
7
|
+
* props down manually at every level. Context is designed for:
|
|
8
|
+
*
|
|
9
|
+
* - SSR isolation (different request = different context values)
|
|
10
|
+
* - Multi-instance support (multiple app roots with different values)
|
|
11
|
+
* - Subtree scoping (override values in specific parts of the tree)
|
|
12
|
+
*
|
|
13
|
+
* ## Design Principles
|
|
14
|
+
*
|
|
15
|
+
* 1. **Reuses existing RootContext hierarchy** - Uses parent chain for value lookup,
|
|
16
|
+
* consistent with handleError/handleSuspend mechanisms.
|
|
17
|
+
*
|
|
18
|
+
* 2. **Zero extra root creation overhead** - Provider doesn't create new root,
|
|
19
|
+
* only mounts value on current root.
|
|
20
|
+
*
|
|
21
|
+
* 3. **Auto-aligned with insert/suspense boundaries** - Because they create child
|
|
22
|
+
* roots that inherit parent, context values propagate correctly.
|
|
23
|
+
*
|
|
24
|
+
* ## Usage
|
|
25
|
+
*
|
|
26
|
+
* ```tsx
|
|
27
|
+
* // Create context with default value
|
|
28
|
+
* const ThemeContext = createContext<'light' | 'dark'>('light')
|
|
29
|
+
*
|
|
30
|
+
* // Provide value to subtree
|
|
31
|
+
* function App() {
|
|
32
|
+
* return (
|
|
33
|
+
* <ThemeContext.Provider value="dark">
|
|
34
|
+
* <ThemedComponent />
|
|
35
|
+
* </ThemeContext.Provider>
|
|
36
|
+
* )
|
|
37
|
+
* }
|
|
38
|
+
*
|
|
39
|
+
* // Consume value
|
|
40
|
+
* function ThemedComponent() {
|
|
41
|
+
* const theme = useContext(ThemeContext)
|
|
42
|
+
* return <div class={theme}>...</div>
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* @module
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Context object created by createContext.
|
|
51
|
+
* Contains the Provider component and serves as a key for context lookup.
|
|
52
|
+
*/
|
|
53
|
+
interface Context<T> {
|
|
54
|
+
/** Unique identifier for this context */
|
|
55
|
+
readonly id: symbol;
|
|
56
|
+
/** Default value when no provider is found */
|
|
57
|
+
readonly defaultValue: T;
|
|
58
|
+
/** Provider component for supplying context values */
|
|
59
|
+
Provider: ContextProvider<T>;
|
|
60
|
+
/** Display name for debugging */
|
|
61
|
+
displayName?: string;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Props for the Context Provider component
|
|
65
|
+
*/
|
|
66
|
+
interface ProviderProps<T> extends BaseProps {
|
|
67
|
+
/** The value to provide to the subtree */
|
|
68
|
+
value: T;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Provider component type
|
|
72
|
+
*/
|
|
73
|
+
type ContextProvider<T> = (props: ProviderProps<T>) => FictNode;
|
|
74
|
+
/**
|
|
75
|
+
* Creates a new context with the given default value.
|
|
76
|
+
*
|
|
77
|
+
* Context provides a way to pass values through the component tree without
|
|
78
|
+
* explicit props drilling. It's especially useful for:
|
|
79
|
+
*
|
|
80
|
+
* - Theme data
|
|
81
|
+
* - Locale/i18n settings
|
|
82
|
+
* - Authentication state
|
|
83
|
+
* - Feature flags
|
|
84
|
+
* - Any data that many components at different nesting levels need
|
|
85
|
+
*
|
|
86
|
+
* @param defaultValue - The value to use when no Provider is found above in the tree
|
|
87
|
+
* @returns A context object with a Provider component
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```tsx
|
|
91
|
+
* // Create a theme context
|
|
92
|
+
* const ThemeContext = createContext<'light' | 'dark'>('light')
|
|
93
|
+
*
|
|
94
|
+
* // Use the provider
|
|
95
|
+
* function App() {
|
|
96
|
+
* return (
|
|
97
|
+
* <ThemeContext.Provider value="dark">
|
|
98
|
+
* <Content />
|
|
99
|
+
* </ThemeContext.Provider>
|
|
100
|
+
* )
|
|
101
|
+
* }
|
|
102
|
+
*
|
|
103
|
+
* // Consume the context
|
|
104
|
+
* function Content() {
|
|
105
|
+
* const theme = useContext(ThemeContext)
|
|
106
|
+
* return <div class={`theme-${theme}`}>Hello</div>
|
|
107
|
+
* }
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
declare function createContext<T>(defaultValue: T): Context<T>;
|
|
111
|
+
/**
|
|
112
|
+
* Reads the current value of a context.
|
|
113
|
+
*
|
|
114
|
+
* useContext looks up through the RootContext parent chain to find the
|
|
115
|
+
* nearest Provider for this context. If no Provider is found, returns
|
|
116
|
+
* the context's default value.
|
|
117
|
+
*
|
|
118
|
+
* @param context - The context object created by createContext
|
|
119
|
+
* @returns The current context value
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```tsx
|
|
123
|
+
* const ThemeContext = createContext('light')
|
|
124
|
+
*
|
|
125
|
+
* function ThemedButton() {
|
|
126
|
+
* const theme = useContext(ThemeContext)
|
|
127
|
+
* return <button class={theme === 'dark' ? 'btn-dark' : 'btn-light'}>Click</button>
|
|
128
|
+
* }
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
declare function useContext<T>(context: Context<T>): T;
|
|
132
|
+
/**
|
|
133
|
+
* Checks if a context value is currently provided in the tree.
|
|
134
|
+
*
|
|
135
|
+
* Useful for conditional behavior when a provider may or may not exist.
|
|
136
|
+
*
|
|
137
|
+
* @param context - The context object to check
|
|
138
|
+
* @returns true if a Provider exists above in the tree
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* ```tsx
|
|
142
|
+
* function OptionalTheme() {
|
|
143
|
+
* if (hasContext(ThemeContext)) {
|
|
144
|
+
* const theme = useContext(ThemeContext)
|
|
145
|
+
* return <div class={theme}>Themed content</div>
|
|
146
|
+
* }
|
|
147
|
+
* return <div>Default content</div>
|
|
148
|
+
* }
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
151
|
+
declare function hasContext<T>(context: Context<T>): boolean;
|
|
152
|
+
|
|
153
|
+
export { type Context as C, type ProviderProps as P, createContext as c, hasContext as h, useContext as u };
|
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
/** Any DOM node that can be rendered */
|
|
2
|
+
type DOMElement = Node;
|
|
3
|
+
/** Cleanup function type */
|
|
4
|
+
type Cleanup = () => void;
|
|
5
|
+
/** Fict Virtual Node - represents a component or element in the virtual tree */
|
|
6
|
+
interface FictVNode {
|
|
7
|
+
/** Element type: tag name, Fragment symbol, or component function */
|
|
8
|
+
type: string | symbol | ((props: Record<string, unknown>) => FictNode);
|
|
9
|
+
/** Props passed to the element/component */
|
|
10
|
+
props: Record<string, unknown> | null;
|
|
11
|
+
/** Optional key for list rendering optimization */
|
|
12
|
+
key?: string | undefined;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Fict Node - represents any renderable value
|
|
16
|
+
* This type covers all possible values that can appear in JSX
|
|
17
|
+
*/
|
|
18
|
+
type FictNode = FictVNode | FictNode[] | Node | string | number | boolean | null | undefined;
|
|
19
|
+
/** Props that all components receive */
|
|
20
|
+
interface BaseProps {
|
|
21
|
+
/** Optional key for list rendering */
|
|
22
|
+
key?: string | number;
|
|
23
|
+
/** Optional children */
|
|
24
|
+
children?: FictNode | FictNode[];
|
|
25
|
+
}
|
|
26
|
+
/** A Fict component function */
|
|
27
|
+
type Component<P extends Record<string, unknown> = Record<string, unknown>> = (props: P & BaseProps) => FictNode;
|
|
28
|
+
/** Props with children */
|
|
29
|
+
type PropsWithChildren<P = unknown> = P & {
|
|
30
|
+
children?: FictNode | FictNode[];
|
|
31
|
+
};
|
|
32
|
+
interface ErrorInfo {
|
|
33
|
+
source: 'render' | 'effect' | 'event' | 'renderChild' | 'cleanup';
|
|
34
|
+
componentName?: string;
|
|
35
|
+
eventName?: string;
|
|
36
|
+
}
|
|
37
|
+
/** Event handler type for type-safe event handling */
|
|
38
|
+
type EventHandler<E extends Event = Event> = (event: E) => void;
|
|
39
|
+
/** Ref callback type */
|
|
40
|
+
type RefCallback<T extends Element = HTMLElement> = (element: T) => void;
|
|
41
|
+
/** Ref object type (for future use with createRef) */
|
|
42
|
+
interface RefObject<T extends Element = HTMLElement> {
|
|
43
|
+
current: T | null;
|
|
44
|
+
}
|
|
45
|
+
/** Ref type that can be either callback or object */
|
|
46
|
+
type Ref<T extends Element = HTMLElement> = RefCallback<T> | RefObject<T>;
|
|
47
|
+
/** CSS style value - can be string or number (number becomes px) */
|
|
48
|
+
type StyleValue = string | number;
|
|
49
|
+
/** CSS style object */
|
|
50
|
+
type CSSStyleObject = {
|
|
51
|
+
[K in keyof CSSStyleDeclaration]?: StyleValue;
|
|
52
|
+
} & Record<string, StyleValue>;
|
|
53
|
+
/** Style prop type - can be string or object */
|
|
54
|
+
type StyleProp = string | CSSStyleObject | null | undefined;
|
|
55
|
+
/** Class object for conditional classes */
|
|
56
|
+
type ClassObject = Record<string, boolean | undefined | null>;
|
|
57
|
+
/** Class prop type - can be string or object */
|
|
58
|
+
type ClassProp = string | ClassObject | null | undefined;
|
|
59
|
+
interface SuspenseToken {
|
|
60
|
+
then: Promise<unknown>['then'];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Fict Reactive DOM Binding System
|
|
65
|
+
*
|
|
66
|
+
* This module provides the core mechanisms for reactive DOM updates.
|
|
67
|
+
* It bridges the gap between Fict's reactive system (signals, effects)
|
|
68
|
+
* and the DOM, enabling fine-grained updates without a virtual DOM.
|
|
69
|
+
*
|
|
70
|
+
* Design Philosophy:
|
|
71
|
+
* - Values wrapped in functions `() => T` are treated as reactive
|
|
72
|
+
* - Static values are applied once without tracking
|
|
73
|
+
* - The compiler transforms JSX expressions to use these primitives
|
|
74
|
+
*/
|
|
75
|
+
|
|
76
|
+
/** A reactive value that can be either static or a getter function */
|
|
77
|
+
type MaybeReactive<T> = T | (() => T);
|
|
78
|
+
/** Internal type for createElement function reference */
|
|
79
|
+
type CreateElementFn = (node: FictNode) => Node;
|
|
80
|
+
/** Handle returned by conditional/list bindings for cleanup */
|
|
81
|
+
interface BindingHandle {
|
|
82
|
+
/** Marker node(s) used for positioning */
|
|
83
|
+
marker: Comment | DocumentFragment;
|
|
84
|
+
/** Flush pending content - call after markers are inserted into DOM */
|
|
85
|
+
flush?: () => void;
|
|
86
|
+
/** Dispose function to clean up the binding */
|
|
87
|
+
dispose: Cleanup;
|
|
88
|
+
}
|
|
89
|
+
/** Managed child node with its dispose function */
|
|
90
|
+
/**
|
|
91
|
+
* Check if a value is reactive (a getter function)
|
|
92
|
+
* Note: Event handlers (functions that take arguments) are NOT reactive values
|
|
93
|
+
*/
|
|
94
|
+
declare function isReactive(value: unknown): value is () => unknown;
|
|
95
|
+
/**
|
|
96
|
+
* Unwrap a potentially reactive value to get the actual value
|
|
97
|
+
*/
|
|
98
|
+
declare function unwrap<T>(value: MaybeReactive<T>): T;
|
|
99
|
+
/**
|
|
100
|
+
* Invoke an event handler or handler accessor in a safe way.
|
|
101
|
+
* Supports handlers that return another handler and handlers that expect an
|
|
102
|
+
* optional data payload followed by the event.
|
|
103
|
+
*/
|
|
104
|
+
declare function callEventHandler(handler: EventListenerOrEventListenerObject | null | undefined, event: Event, node?: EventTarget | null, data?: unknown): void;
|
|
105
|
+
/**
|
|
106
|
+
* Create a text node that reactively updates when the value changes.
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```ts
|
|
110
|
+
* // Static text
|
|
111
|
+
* createTextBinding("Hello")
|
|
112
|
+
*
|
|
113
|
+
* // Reactive text (compiler output)
|
|
114
|
+
* createTextBinding(() => $count())
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
declare function createTextBinding(value: MaybeReactive<unknown>): Text;
|
|
118
|
+
/**
|
|
119
|
+
* Bind a reactive value to an existing text node.
|
|
120
|
+
* This is a convenience function for binding to existing DOM nodes.
|
|
121
|
+
*/
|
|
122
|
+
declare function bindText(textNode: Text, getValue: () => unknown): Cleanup;
|
|
123
|
+
/** Attribute setter function type */
|
|
124
|
+
type AttributeSetter = (el: Element, key: string, value: unknown) => void;
|
|
125
|
+
/**
|
|
126
|
+
* Create a reactive attribute binding on an element.
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```ts
|
|
130
|
+
* // Static attribute
|
|
131
|
+
* createAttributeBinding(button, 'disabled', false, setAttribute)
|
|
132
|
+
*
|
|
133
|
+
* // Reactive attribute (compiler output)
|
|
134
|
+
* createAttributeBinding(button, 'disabled', () => !$isValid(), setAttribute)
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
declare function createAttributeBinding(el: Element, key: string, value: MaybeReactive<unknown>, setter: AttributeSetter): void;
|
|
138
|
+
/**
|
|
139
|
+
* Bind a reactive value to an element's attribute.
|
|
140
|
+
*/
|
|
141
|
+
declare function bindAttribute(el: Element, key: string, getValue: () => unknown): Cleanup;
|
|
142
|
+
/**
|
|
143
|
+
* Bind a reactive value to an element's property.
|
|
144
|
+
*/
|
|
145
|
+
declare function bindProperty(el: Element, key: string, getValue: () => unknown): Cleanup;
|
|
146
|
+
/**
|
|
147
|
+
* Apply styles to an element, supporting reactive style objects/strings.
|
|
148
|
+
*/
|
|
149
|
+
declare function createStyleBinding(el: Element, value: MaybeReactive<string | Record<string, string | number> | null | undefined>): void;
|
|
150
|
+
/**
|
|
151
|
+
* Bind a reactive style value to an existing element.
|
|
152
|
+
*/
|
|
153
|
+
declare function bindStyle(el: Element, getValue: () => string | Record<string, string | number> | null | undefined): Cleanup;
|
|
154
|
+
/**
|
|
155
|
+
* Apply class to an element, supporting reactive class values.
|
|
156
|
+
*/
|
|
157
|
+
declare function createClassBinding(el: Element, value: MaybeReactive<string | Record<string, boolean> | null | undefined>): void;
|
|
158
|
+
/**
|
|
159
|
+
* Bind a reactive class value to an existing element.
|
|
160
|
+
*/
|
|
161
|
+
declare function bindClass(el: Element, getValue: () => string | Record<string, boolean> | null | undefined): Cleanup;
|
|
162
|
+
/**
|
|
163
|
+
* Exported classList function for direct use (compatible with dom-expressions)
|
|
164
|
+
*/
|
|
165
|
+
declare function classList(node: Element, value: Record<string, boolean> | null | undefined, prev?: Record<string, boolean>): Record<string, boolean>;
|
|
166
|
+
/**
|
|
167
|
+
* Insert reactive content into a parent element.
|
|
168
|
+
* This is a simpler API than createChildBinding for basic cases.
|
|
169
|
+
*
|
|
170
|
+
* @param parent - The parent element to insert into
|
|
171
|
+
* @param getValue - Function that returns the value to render
|
|
172
|
+
* @param markerOrCreateElement - Optional marker node to insert before, or createElementFn
|
|
173
|
+
* @param createElementFn - Optional function to create DOM elements (when marker is provided)
|
|
174
|
+
*/
|
|
175
|
+
declare function insert(parent: ParentNode & Node, getValue: () => FictNode, markerOrCreateElement?: Node | CreateElementFn, createElementFn?: CreateElementFn): Cleanup;
|
|
176
|
+
/**
|
|
177
|
+
* Create a reactive child binding that updates when the child value changes.
|
|
178
|
+
* This is used for dynamic expressions like `{show && <Modal />}` or `{items.map(...)}`.
|
|
179
|
+
*
|
|
180
|
+
* @example
|
|
181
|
+
* ```ts
|
|
182
|
+
* // Reactive child (compiler output for {count})
|
|
183
|
+
* createChildBinding(parent, () => $count(), createElement)
|
|
184
|
+
*
|
|
185
|
+
* // Reactive conditional (compiler output for {show && <Modal />})
|
|
186
|
+
* createChildBinding(parent, () => $show() && jsx(Modal, {}), createElement)
|
|
187
|
+
* ```
|
|
188
|
+
*/
|
|
189
|
+
declare function createChildBinding(parent: ParentNode & Node, getValue: () => FictNode, createElementFn: CreateElementFn): BindingHandle;
|
|
190
|
+
declare global {
|
|
191
|
+
interface Element {
|
|
192
|
+
_$host?: Element;
|
|
193
|
+
[key: `$$${string}`]: EventListener | [EventListener, unknown] | undefined;
|
|
194
|
+
[key: `$$${string}Data`]: unknown;
|
|
195
|
+
}
|
|
196
|
+
interface Document extends Record<string, unknown> {
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Initialize event delegation for a set of event names.
|
|
201
|
+
* Events will be handled at the document level and dispatched to the appropriate handlers.
|
|
202
|
+
*
|
|
203
|
+
* @param eventNames - Array of event names to delegate
|
|
204
|
+
* @param doc - The document to attach handlers to (default: window.document)
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* ```ts
|
|
208
|
+
* // Called automatically by the compiler for delegated events
|
|
209
|
+
* delegateEvents(['click', 'input', 'keydown'])
|
|
210
|
+
* ```
|
|
211
|
+
*/
|
|
212
|
+
declare function delegateEvents(eventNames: string[], doc?: Document): void;
|
|
213
|
+
/**
|
|
214
|
+
* Clear all delegated event handlers from a document.
|
|
215
|
+
*
|
|
216
|
+
* @param doc - The document to clear handlers from (default: window.document)
|
|
217
|
+
*/
|
|
218
|
+
declare function clearDelegatedEvents(doc?: Document): void;
|
|
219
|
+
/**
|
|
220
|
+
* Add an event listener to an element.
|
|
221
|
+
* If the event is in DelegatedEvents, it uses event delegation for better performance.
|
|
222
|
+
*
|
|
223
|
+
* @param node - The element to add the listener to
|
|
224
|
+
* @param name - The event name (lowercase)
|
|
225
|
+
* @param handler - The event handler or [handler, data] tuple
|
|
226
|
+
* @param delegate - Whether to use delegation (auto-detected based on event name)
|
|
227
|
+
*/
|
|
228
|
+
declare function addEventListener(node: Element, name: string, handler: EventListener | [EventListener, unknown] | null | undefined, delegate?: boolean): void;
|
|
229
|
+
/**
|
|
230
|
+
* Bind an event listener to an element.
|
|
231
|
+
* Uses event delegation for better performance when applicable.
|
|
232
|
+
*
|
|
233
|
+
* @example
|
|
234
|
+
* ```ts
|
|
235
|
+
* // Static event
|
|
236
|
+
* bindEvent(button, 'click', handleClick)
|
|
237
|
+
*
|
|
238
|
+
* // Reactive event (compiler output)
|
|
239
|
+
* bindEvent(button, 'click', () => $handler())
|
|
240
|
+
*
|
|
241
|
+
* // With modifiers
|
|
242
|
+
* bindEvent(button, 'click', handler, { capture: true, passive: true, once: true })
|
|
243
|
+
* ```
|
|
244
|
+
*/
|
|
245
|
+
declare function bindEvent(el: Element, eventName: string, handler: EventListenerOrEventListenerObject | null | undefined, options?: boolean | AddEventListenerOptions): Cleanup;
|
|
246
|
+
/**
|
|
247
|
+
* Bind a ref to an element.
|
|
248
|
+
* Supports both callback refs and ref objects.
|
|
249
|
+
*
|
|
250
|
+
* @param el - The element to bind the ref to
|
|
251
|
+
* @param ref - Either a callback function, a ref object, or a reactive getter
|
|
252
|
+
* @returns Cleanup function
|
|
253
|
+
*
|
|
254
|
+
* @example
|
|
255
|
+
* ```ts
|
|
256
|
+
* // Callback ref
|
|
257
|
+
* bindRef(el, (element) => { store.input = element })
|
|
258
|
+
*
|
|
259
|
+
* // Ref object
|
|
260
|
+
* const inputRef = createRef()
|
|
261
|
+
* bindRef(el, inputRef)
|
|
262
|
+
*
|
|
263
|
+
* // Reactive ref (compiler output)
|
|
264
|
+
* bindRef(el, () => props.ref)
|
|
265
|
+
* ```
|
|
266
|
+
*/
|
|
267
|
+
declare function bindRef(el: Element, ref: unknown): Cleanup;
|
|
268
|
+
/**
|
|
269
|
+
* Apply spread props to an element with reactive updates.
|
|
270
|
+
* This handles dynamic spread like `<div {...props}>`.
|
|
271
|
+
*
|
|
272
|
+
* @param node - The element to apply props to
|
|
273
|
+
* @param props - The props object (may have reactive getters)
|
|
274
|
+
* @param isSVG - Whether this is an SVG element
|
|
275
|
+
* @param skipChildren - Whether to skip children handling
|
|
276
|
+
* @returns The previous props for tracking changes
|
|
277
|
+
*
|
|
278
|
+
* @example
|
|
279
|
+
* ```ts
|
|
280
|
+
* // Compiler output for <div {...props} />
|
|
281
|
+
* spread(el, props, false, false)
|
|
282
|
+
* ```
|
|
283
|
+
*/
|
|
284
|
+
declare function spread(node: Element, props?: Record<string, unknown>, isSVG?: boolean, skipChildren?: boolean): Record<string, unknown>;
|
|
285
|
+
/**
|
|
286
|
+
* Assign props to a node, tracking previous values for efficient updates.
|
|
287
|
+
* This is the core prop assignment logic used by spread.
|
|
288
|
+
*
|
|
289
|
+
* @param node - The element to assign props to
|
|
290
|
+
* @param props - New props object
|
|
291
|
+
* @param isSVG - Whether this is an SVG element
|
|
292
|
+
* @param skipChildren - Whether to skip children handling
|
|
293
|
+
* @param prevProps - Previous props for comparison
|
|
294
|
+
* @param skipRef - Whether to skip ref handling
|
|
295
|
+
*/
|
|
296
|
+
declare function assign(node: Element, props: Record<string, unknown>, isSVG?: boolean, skipChildren?: boolean, prevProps?: Record<string, unknown>, skipRef?: boolean): void;
|
|
297
|
+
/**
|
|
298
|
+
* Create a conditional rendering binding.
|
|
299
|
+
* Efficiently renders one of two branches based on a condition.
|
|
300
|
+
*
|
|
301
|
+
* This is an optimized version for `{condition ? <A /> : <B />}` patterns
|
|
302
|
+
* where both branches are known statically.
|
|
303
|
+
*
|
|
304
|
+
* @example
|
|
305
|
+
* ```ts
|
|
306
|
+
* // Compiler output for {show ? <A /> : <B />}
|
|
307
|
+
* createConditional(
|
|
308
|
+
* () => $show(),
|
|
309
|
+
* () => jsx(A, {}),
|
|
310
|
+
* () => jsx(B, {}),
|
|
311
|
+
* createElement
|
|
312
|
+
* )
|
|
313
|
+
* ```
|
|
314
|
+
*/
|
|
315
|
+
declare function createConditional(condition: () => boolean, renderTrue: () => FictNode, createElementFn: CreateElementFn, renderFalse?: () => FictNode): BindingHandle;
|
|
316
|
+
/**
|
|
317
|
+
* Create a show/hide binding that uses CSS display instead of DOM manipulation.
|
|
318
|
+
* More efficient than conditional when the content is expensive to create.
|
|
319
|
+
*
|
|
320
|
+
* @example
|
|
321
|
+
* ```ts
|
|
322
|
+
* createShow(container, () => $visible())
|
|
323
|
+
* ```
|
|
324
|
+
*/
|
|
325
|
+
declare function createShow(el: Element & {
|
|
326
|
+
style: CSSStyleDeclaration;
|
|
327
|
+
}, condition: () => boolean, displayValue?: string): void;
|
|
328
|
+
/**
|
|
329
|
+
* Create a portal that renders content into a different DOM container.
|
|
330
|
+
*
|
|
331
|
+
* @example
|
|
332
|
+
* ```ts
|
|
333
|
+
* createPortal(
|
|
334
|
+
* document.body,
|
|
335
|
+
* () => jsx(Modal, { children: 'Hello' }),
|
|
336
|
+
* createElement
|
|
337
|
+
* )
|
|
338
|
+
* ```
|
|
339
|
+
*/
|
|
340
|
+
declare function createPortal(container: ParentNode & Node, render: () => FictNode, createElementFn: CreateElementFn): BindingHandle;
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Effect callback run synchronously; async callbacks are not tracked after the first await.
|
|
344
|
+
* TypeScript will reject `async () => {}` here—split async work or read signals before awaiting.
|
|
345
|
+
*/
|
|
346
|
+
type Effect = () => void | Cleanup;
|
|
347
|
+
declare function createEffect(fn: Effect): () => void;
|
|
348
|
+
declare function createRenderEffect(fn: Effect): () => void;
|
|
349
|
+
|
|
350
|
+
export { bindRef as A, type BaseProps as B, type Cleanup as C, type DOMElement as D, type Effect as E, type FictNode as F, insert as G, createConditional as H, spread as I, assign as J, classList as K, delegateEvents as L, clearDelegatedEvents as M, addEventListener as N, type MaybeReactive as O, type PropsWithChildren as P, type BindingHandle as Q, type RefObject as R, type SuspenseToken as S, type CreateElementFn as T, type AttributeSetter as U, createChildBinding as a, createAttributeBinding as b, createTextBinding as c, createStyleBinding as d, createClassBinding as e, createShow as f, createRenderEffect as g, createEffect as h, isReactive as i, createPortal as j, type FictVNode as k, type Component as l, type Ref as m, type RefCallback as n, type StyleProp as o, type ClassProp as p, type EventHandler as q, type ErrorInfo as r, bindText as s, bindAttribute as t, unwrap as u, bindStyle as v, bindClass as w, bindEvent as x, callEventHandler as y, bindProperty as z };
|