gonia 0.0.1
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 +119 -0
- package/dist/client/hydrate.d.ts +54 -0
- package/dist/client/hydrate.js +445 -0
- package/dist/client/index.d.ts +7 -0
- package/dist/client/index.js +6 -0
- package/dist/context.d.ts +40 -0
- package/dist/context.js +69 -0
- package/dist/directives/class.d.ts +21 -0
- package/dist/directives/class.js +42 -0
- package/dist/directives/for.d.ts +29 -0
- package/dist/directives/for.js +265 -0
- package/dist/directives/html.d.ts +16 -0
- package/dist/directives/html.js +19 -0
- package/dist/directives/if.d.ts +25 -0
- package/dist/directives/if.js +133 -0
- package/dist/directives/index.d.ts +15 -0
- package/dist/directives/index.js +15 -0
- package/dist/directives/model.d.ts +27 -0
- package/dist/directives/model.js +134 -0
- package/dist/directives/on.d.ts +21 -0
- package/dist/directives/on.js +54 -0
- package/dist/directives/show.d.ts +15 -0
- package/dist/directives/show.js +19 -0
- package/dist/directives/slot.d.ts +48 -0
- package/dist/directives/slot.js +99 -0
- package/dist/directives/template.d.ts +55 -0
- package/dist/directives/template.js +147 -0
- package/dist/directives/text.d.ts +15 -0
- package/dist/directives/text.js +18 -0
- package/dist/expression.d.ts +60 -0
- package/dist/expression.js +96 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +16 -0
- package/dist/inject.d.ts +42 -0
- package/dist/inject.js +63 -0
- package/dist/providers.d.ts +96 -0
- package/dist/providers.js +146 -0
- package/dist/reactivity.d.ts +95 -0
- package/dist/reactivity.js +219 -0
- package/dist/scope.d.ts +43 -0
- package/dist/scope.js +112 -0
- package/dist/server/index.d.ts +7 -0
- package/dist/server/index.js +6 -0
- package/dist/server/render.d.ts +61 -0
- package/dist/server/render.js +243 -0
- package/dist/templates.d.ts +92 -0
- package/dist/templates.js +124 -0
- package/dist/types.d.ts +362 -0
- package/dist/types.js +110 -0
- package/dist/vite/index.d.ts +6 -0
- package/dist/vite/index.js +6 -0
- package/dist/vite/plugin.d.ts +30 -0
- package/dist/vite/plugin.js +127 -0
- package/package.json +67 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Expression parsing utilities.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* Parses expression strings (from HTML attributes) to find root identifiers.
|
|
6
|
+
* Used for reactive dependency tracking - only access state keys that
|
|
7
|
+
* the expression actually references.
|
|
8
|
+
*
|
|
9
|
+
* @packageDocumentation
|
|
10
|
+
*/
|
|
11
|
+
const JS_KEYWORDS = new Set([
|
|
12
|
+
'true', 'false', 'null', 'undefined', 'this',
|
|
13
|
+
'typeof', 'instanceof', 'new', 'in', 'of',
|
|
14
|
+
'if', 'else', 'for', 'while', 'do', 'switch',
|
|
15
|
+
'case', 'break', 'continue', 'return', 'throw',
|
|
16
|
+
'try', 'catch', 'finally', 'delete', 'void',
|
|
17
|
+
'var', 'let', 'const', 'function', 'class',
|
|
18
|
+
'async', 'await', 'yield', 'import', 'export',
|
|
19
|
+
'default', 'extends', 'super', 'static',
|
|
20
|
+
'Math', 'Number', 'String', 'Boolean', 'Array', 'Object',
|
|
21
|
+
'Date', 'JSON', 'console', 'window', 'document'
|
|
22
|
+
]);
|
|
23
|
+
/**
|
|
24
|
+
* Find root identifiers in an expression.
|
|
25
|
+
*
|
|
26
|
+
* @remarks
|
|
27
|
+
* These are the top-level variable references that need to come from state.
|
|
28
|
+
* Used to enable precise reactive dependency tracking.
|
|
29
|
+
*
|
|
30
|
+
* @param expr - The expression string to parse
|
|
31
|
+
* @returns Array of root identifier names
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* findRoots('user.name') // ['user']
|
|
36
|
+
* findRoots('user.name + item.count') // ['user', 'item']
|
|
37
|
+
* findRoots('"hello.world"') // []
|
|
38
|
+
* findRoots('items.filter(x => x.active)') // ['items', 'x']
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export function findRoots(expr) {
|
|
42
|
+
const cleaned = expr
|
|
43
|
+
.replace(/'(?:[^'\\]|\\.)*'/g, '""')
|
|
44
|
+
.replace(/"(?:[^"\\]|\\.)*"/g, '""')
|
|
45
|
+
.replace(/`(?:[^`\\$]|\\.|\$(?!\{))*`/g, '""');
|
|
46
|
+
const matches = cleaned.match(/(?<![.\w$])\b[a-zA-Z_$][a-zA-Z0-9_$]*\b/g) || [];
|
|
47
|
+
const roots = [...new Set(matches.filter(m => !JS_KEYWORDS.has(m)))];
|
|
48
|
+
return roots;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Parse interpolation syntax in a string.
|
|
52
|
+
*
|
|
53
|
+
* @remarks
|
|
54
|
+
* Splits a template string with `{{ expr }}` markers into segments
|
|
55
|
+
* of static text and expressions. Used by directives like c-href
|
|
56
|
+
* that support inline interpolation.
|
|
57
|
+
*
|
|
58
|
+
* @param template - The template string with interpolation markers
|
|
59
|
+
* @returns Array of segments
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* parseInterpolation('/users/{{ user.id }}/profile')
|
|
64
|
+
* // [
|
|
65
|
+
* // { type: 'static', value: '/users/' },
|
|
66
|
+
* // { type: 'expr', value: 'user.id' },
|
|
67
|
+
* // { type: 'static', value: '/profile' }
|
|
68
|
+
* // ]
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
export function parseInterpolation(template) {
|
|
72
|
+
const segments = [];
|
|
73
|
+
const regex = /\{\{\s*(.*?)\s*\}\}/g;
|
|
74
|
+
let lastIndex = 0;
|
|
75
|
+
let match;
|
|
76
|
+
while ((match = regex.exec(template)) !== null) {
|
|
77
|
+
if (match.index > lastIndex) {
|
|
78
|
+
segments.push({
|
|
79
|
+
type: 'static',
|
|
80
|
+
value: template.slice(lastIndex, match.index)
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
segments.push({
|
|
84
|
+
type: 'expr',
|
|
85
|
+
value: match[1]
|
|
86
|
+
});
|
|
87
|
+
lastIndex = regex.lastIndex;
|
|
88
|
+
}
|
|
89
|
+
if (lastIndex < template.length) {
|
|
90
|
+
segments.push({
|
|
91
|
+
type: 'static',
|
|
92
|
+
value: template.slice(lastIndex)
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
return segments;
|
|
96
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cubist.js - A modern framework inspired by AngularJS 1.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* SSR-first design with HTML attributes as directives.
|
|
6
|
+
* Fine-grained reactivity without virtual DOM diffing.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
export { Mode, Expression, Context, Directive, directive, getDirective, getDirectiveNames, clearDirectives } from './types.js';
|
|
11
|
+
export type { DirectiveMeta } from './types.js';
|
|
12
|
+
export { createContext, createChildContext } from './context.js';
|
|
13
|
+
export { reactive, effect, createScope, createEffectScope } from './reactivity.js';
|
|
14
|
+
export type { EffectScope } from './reactivity.js';
|
|
15
|
+
export { createTemplateRegistry, createMemoryRegistry, createServerRegistry } from './templates.js';
|
|
16
|
+
export type { TemplateRegistry } from './templates.js';
|
|
17
|
+
export { findRoots, parseInterpolation } from './expression.js';
|
|
18
|
+
export { getInjectables } from './inject.js';
|
|
19
|
+
export * as directives from './directives/index.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cubist.js - A modern framework inspired by AngularJS 1.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* SSR-first design with HTML attributes as directives.
|
|
6
|
+
* Fine-grained reactivity without virtual DOM diffing.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
export { Mode, directive, getDirective, getDirectiveNames, clearDirectives } from './types.js';
|
|
11
|
+
export { createContext, createChildContext } from './context.js';
|
|
12
|
+
export { reactive, effect, createScope, createEffectScope } from './reactivity.js';
|
|
13
|
+
export { createTemplateRegistry, createMemoryRegistry, createServerRegistry } from './templates.js';
|
|
14
|
+
export { findRoots, parseInterpolation } from './expression.js';
|
|
15
|
+
export { getInjectables } from './inject.js';
|
|
16
|
+
export * as directives from './directives/index.js';
|
package/dist/inject.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dependency injection utilities.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* Supports two patterns:
|
|
6
|
+
* 1. Explicit `$inject` array (minification-safe, production)
|
|
7
|
+
* 2. Function parameter parsing (dev convenience, breaks when minified)
|
|
8
|
+
*
|
|
9
|
+
* Build tools should auto-generate `$inject` arrays for production builds,
|
|
10
|
+
* similar to how ngAnnotate worked with AngularJS.
|
|
11
|
+
*
|
|
12
|
+
* @packageDocumentation
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* A function with optional `$inject` annotation.
|
|
16
|
+
*/
|
|
17
|
+
interface InjectableFunction extends Function {
|
|
18
|
+
$inject?: readonly string[];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Get the list of injectable dependencies for a function.
|
|
22
|
+
*
|
|
23
|
+
* @remarks
|
|
24
|
+
* Checks for explicit `$inject` first, falls back to parsing params.
|
|
25
|
+
* In production, always use `$inject` to survive minification.
|
|
26
|
+
*
|
|
27
|
+
* @param fn - The function to inspect
|
|
28
|
+
* @returns Array of dependency names
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* // Development - parsed from params
|
|
33
|
+
* const myDirective = (expr, ctx, el, http, userService) => {};
|
|
34
|
+
* getInjectables(myDirective); // ['expr', 'ctx', 'el', 'http', 'userService']
|
|
35
|
+
*
|
|
36
|
+
* // Production - explicit annotation
|
|
37
|
+
* myDirective.$inject = ['http', 'userService'];
|
|
38
|
+
* getInjectables(myDirective); // ['http', 'userService']
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export declare function getInjectables(fn: InjectableFunction): string[];
|
|
42
|
+
export {};
|
package/dist/inject.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dependency injection utilities.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* Supports two patterns:
|
|
6
|
+
* 1. Explicit `$inject` array (minification-safe, production)
|
|
7
|
+
* 2. Function parameter parsing (dev convenience, breaks when minified)
|
|
8
|
+
*
|
|
9
|
+
* Build tools should auto-generate `$inject` arrays for production builds,
|
|
10
|
+
* similar to how ngAnnotate worked with AngularJS.
|
|
11
|
+
*
|
|
12
|
+
* @packageDocumentation
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Get the list of injectable dependencies for a function.
|
|
16
|
+
*
|
|
17
|
+
* @remarks
|
|
18
|
+
* Checks for explicit `$inject` first, falls back to parsing params.
|
|
19
|
+
* In production, always use `$inject` to survive minification.
|
|
20
|
+
*
|
|
21
|
+
* @param fn - The function to inspect
|
|
22
|
+
* @returns Array of dependency names
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* // Development - parsed from params
|
|
27
|
+
* const myDirective = (expr, ctx, el, http, userService) => {};
|
|
28
|
+
* getInjectables(myDirective); // ['expr', 'ctx', 'el', 'http', 'userService']
|
|
29
|
+
*
|
|
30
|
+
* // Production - explicit annotation
|
|
31
|
+
* myDirective.$inject = ['http', 'userService'];
|
|
32
|
+
* getInjectables(myDirective); // ['http', 'userService']
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export function getInjectables(fn) {
|
|
36
|
+
if ('$inject' in fn && Array.isArray(fn.$inject)) {
|
|
37
|
+
return fn.$inject;
|
|
38
|
+
}
|
|
39
|
+
return parseFunctionParams(fn);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Parse function parameters from function.toString().
|
|
43
|
+
*
|
|
44
|
+
* @remarks
|
|
45
|
+
* Handles regular functions, arrow functions, async functions,
|
|
46
|
+
* and default parameter values.
|
|
47
|
+
*
|
|
48
|
+
* @internal
|
|
49
|
+
*/
|
|
50
|
+
function parseFunctionParams(fn) {
|
|
51
|
+
const str = fn.toString();
|
|
52
|
+
const match = str.match(/^[^(]*\(([^)]*)\)/);
|
|
53
|
+
if (!match)
|
|
54
|
+
return [];
|
|
55
|
+
const params = match[1];
|
|
56
|
+
if (!params.trim())
|
|
57
|
+
return [];
|
|
58
|
+
return params
|
|
59
|
+
.split(',')
|
|
60
|
+
.map(p => p.trim())
|
|
61
|
+
.map(p => p.replace(/\s*=.*$/, ''))
|
|
62
|
+
.filter(Boolean);
|
|
63
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context and DI provider system for sharing state and services across directive descendants.
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
import { Directive } from './types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Get or create local state for an element.
|
|
9
|
+
*
|
|
10
|
+
* @remarks
|
|
11
|
+
* Each directive instance gets its own isolated state object.
|
|
12
|
+
* The state is reactive.
|
|
13
|
+
*
|
|
14
|
+
* @param el - The element to get state for
|
|
15
|
+
* @returns A reactive state object
|
|
16
|
+
*
|
|
17
|
+
* @internal
|
|
18
|
+
*/
|
|
19
|
+
export declare function getLocalState(el: Element): Record<string, unknown>;
|
|
20
|
+
/**
|
|
21
|
+
* Register a context provider for an element.
|
|
22
|
+
*
|
|
23
|
+
* @remarks
|
|
24
|
+
* Called after a directive with `$context` has executed.
|
|
25
|
+
* Stores the directive and its state so descendants can find it.
|
|
26
|
+
*
|
|
27
|
+
* @param el - The element providing context
|
|
28
|
+
* @param directive - The directive that provides context
|
|
29
|
+
* @param state - The directive's local state
|
|
30
|
+
*
|
|
31
|
+
* @internal
|
|
32
|
+
*/
|
|
33
|
+
export declare function registerProvider(el: Element, directive: Directive, state: Record<string, unknown>): void;
|
|
34
|
+
/**
|
|
35
|
+
* Register DI providers for an element.
|
|
36
|
+
*
|
|
37
|
+
* @remarks
|
|
38
|
+
* Called when a directive with `provide` option is processed.
|
|
39
|
+
* Stores the provider map so descendants can resolve from it.
|
|
40
|
+
*
|
|
41
|
+
* @param el - The element providing DI overrides
|
|
42
|
+
* @param provideMap - Map of name to value
|
|
43
|
+
*
|
|
44
|
+
* @internal
|
|
45
|
+
*/
|
|
46
|
+
export declare function registerDIProviders(el: Element, provideMap: Record<string, unknown>): void;
|
|
47
|
+
/**
|
|
48
|
+
* Resolve a DI provider value from ancestor elements.
|
|
49
|
+
*
|
|
50
|
+
* @remarks
|
|
51
|
+
* Walks up the DOM tree to find the nearest ancestor with a
|
|
52
|
+
* `provide` map containing the requested name.
|
|
53
|
+
*
|
|
54
|
+
* @param el - The element requesting the value
|
|
55
|
+
* @param name - The name to look up
|
|
56
|
+
* @returns The provided value, or undefined if not found
|
|
57
|
+
*
|
|
58
|
+
* @internal
|
|
59
|
+
*/
|
|
60
|
+
export declare function resolveFromDIProviders(el: Element, name: string): unknown | undefined;
|
|
61
|
+
/**
|
|
62
|
+
* Resolve a context value from ancestor elements.
|
|
63
|
+
*
|
|
64
|
+
* @remarks
|
|
65
|
+
* Walks up the DOM tree to find the nearest ancestor whose
|
|
66
|
+
* directive declares `$context` containing the requested name.
|
|
67
|
+
*
|
|
68
|
+
* @param el - The element requesting the value
|
|
69
|
+
* @param name - The name to look up
|
|
70
|
+
* @returns The provider's state, or undefined if not found
|
|
71
|
+
*
|
|
72
|
+
* @internal
|
|
73
|
+
*/
|
|
74
|
+
export declare function resolveFromProviders(el: Element, name: string): Record<string, unknown> | undefined;
|
|
75
|
+
/**
|
|
76
|
+
* Clear local state for an element.
|
|
77
|
+
*
|
|
78
|
+
* @remarks
|
|
79
|
+
* Called when an element is removed or re-rendered.
|
|
80
|
+
*
|
|
81
|
+
* @param el - The element to clear state for
|
|
82
|
+
*
|
|
83
|
+
* @internal
|
|
84
|
+
*/
|
|
85
|
+
export declare function clearLocalState(el: Element): void;
|
|
86
|
+
/**
|
|
87
|
+
* Clear providers for an element.
|
|
88
|
+
*
|
|
89
|
+
* @remarks
|
|
90
|
+
* Called when an element is removed or re-rendered.
|
|
91
|
+
*
|
|
92
|
+
* @param el - The element to clear providers for
|
|
93
|
+
*
|
|
94
|
+
* @internal
|
|
95
|
+
*/
|
|
96
|
+
export declare function clearProvider(el: Element): void;
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context and DI provider system for sharing state and services across directive descendants.
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
import { reactive } from './reactivity.js';
|
|
7
|
+
/**
|
|
8
|
+
* Local state stored per element.
|
|
9
|
+
*
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
const localStates = new WeakMap();
|
|
13
|
+
const contextProviders = new WeakMap();
|
|
14
|
+
/**
|
|
15
|
+
* DI provider maps stored per element (provide option).
|
|
16
|
+
* Maps element -> { name: value }
|
|
17
|
+
*
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
const diProviders = new WeakMap();
|
|
21
|
+
/**
|
|
22
|
+
* Get or create local state for an element.
|
|
23
|
+
*
|
|
24
|
+
* @remarks
|
|
25
|
+
* Each directive instance gets its own isolated state object.
|
|
26
|
+
* The state is reactive.
|
|
27
|
+
*
|
|
28
|
+
* @param el - The element to get state for
|
|
29
|
+
* @returns A reactive state object
|
|
30
|
+
*
|
|
31
|
+
* @internal
|
|
32
|
+
*/
|
|
33
|
+
export function getLocalState(el) {
|
|
34
|
+
let state = localStates.get(el);
|
|
35
|
+
if (!state) {
|
|
36
|
+
state = reactive({});
|
|
37
|
+
localStates.set(el, state);
|
|
38
|
+
}
|
|
39
|
+
return state;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Register a context provider for an element.
|
|
43
|
+
*
|
|
44
|
+
* @remarks
|
|
45
|
+
* Called after a directive with `$context` has executed.
|
|
46
|
+
* Stores the directive and its state so descendants can find it.
|
|
47
|
+
*
|
|
48
|
+
* @param el - The element providing context
|
|
49
|
+
* @param directive - The directive that provides context
|
|
50
|
+
* @param state - The directive's local state
|
|
51
|
+
*
|
|
52
|
+
* @internal
|
|
53
|
+
*/
|
|
54
|
+
export function registerProvider(el, directive, state) {
|
|
55
|
+
contextProviders.set(el, { directive, state });
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Register DI providers for an element.
|
|
59
|
+
*
|
|
60
|
+
* @remarks
|
|
61
|
+
* Called when a directive with `provide` option is processed.
|
|
62
|
+
* Stores the provider map so descendants can resolve from it.
|
|
63
|
+
*
|
|
64
|
+
* @param el - The element providing DI overrides
|
|
65
|
+
* @param provideMap - Map of name to value
|
|
66
|
+
*
|
|
67
|
+
* @internal
|
|
68
|
+
*/
|
|
69
|
+
export function registerDIProviders(el, provideMap) {
|
|
70
|
+
diProviders.set(el, provideMap);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Resolve a DI provider value from ancestor elements.
|
|
74
|
+
*
|
|
75
|
+
* @remarks
|
|
76
|
+
* Walks up the DOM tree to find the nearest ancestor with a
|
|
77
|
+
* `provide` map containing the requested name.
|
|
78
|
+
*
|
|
79
|
+
* @param el - The element requesting the value
|
|
80
|
+
* @param name - The name to look up
|
|
81
|
+
* @returns The provided value, or undefined if not found
|
|
82
|
+
*
|
|
83
|
+
* @internal
|
|
84
|
+
*/
|
|
85
|
+
export function resolveFromDIProviders(el, name) {
|
|
86
|
+
let current = el.parentElement;
|
|
87
|
+
while (current) {
|
|
88
|
+
const provideMap = diProviders.get(current);
|
|
89
|
+
if (provideMap && name in provideMap) {
|
|
90
|
+
return provideMap[name];
|
|
91
|
+
}
|
|
92
|
+
current = current.parentElement;
|
|
93
|
+
}
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Resolve a context value from ancestor elements.
|
|
98
|
+
*
|
|
99
|
+
* @remarks
|
|
100
|
+
* Walks up the DOM tree to find the nearest ancestor whose
|
|
101
|
+
* directive declares `$context` containing the requested name.
|
|
102
|
+
*
|
|
103
|
+
* @param el - The element requesting the value
|
|
104
|
+
* @param name - The name to look up
|
|
105
|
+
* @returns The provider's state, or undefined if not found
|
|
106
|
+
*
|
|
107
|
+
* @internal
|
|
108
|
+
*/
|
|
109
|
+
export function resolveFromProviders(el, name) {
|
|
110
|
+
let current = el.parentElement;
|
|
111
|
+
while (current) {
|
|
112
|
+
const info = contextProviders.get(current);
|
|
113
|
+
if (info?.directive.$context?.includes(name)) {
|
|
114
|
+
return info.state;
|
|
115
|
+
}
|
|
116
|
+
current = current.parentElement;
|
|
117
|
+
}
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Clear local state for an element.
|
|
122
|
+
*
|
|
123
|
+
* @remarks
|
|
124
|
+
* Called when an element is removed or re-rendered.
|
|
125
|
+
*
|
|
126
|
+
* @param el - The element to clear state for
|
|
127
|
+
*
|
|
128
|
+
* @internal
|
|
129
|
+
*/
|
|
130
|
+
export function clearLocalState(el) {
|
|
131
|
+
localStates.delete(el);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Clear providers for an element.
|
|
135
|
+
*
|
|
136
|
+
* @remarks
|
|
137
|
+
* Called when an element is removed or re-rendered.
|
|
138
|
+
*
|
|
139
|
+
* @param el - The element to clear providers for
|
|
140
|
+
*
|
|
141
|
+
* @internal
|
|
142
|
+
*/
|
|
143
|
+
export function clearProvider(el) {
|
|
144
|
+
contextProviders.delete(el);
|
|
145
|
+
diProviders.delete(el);
|
|
146
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fine-grained reactivity system using Proxies.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* Each directive becomes its own effect, tracking only the state it accesses.
|
|
6
|
+
* Changes trigger only the affected effects - no component re-renders, no diffing.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
type Effect = () => void;
|
|
11
|
+
/**
|
|
12
|
+
* A scope that groups effects for collective disposal.
|
|
13
|
+
*
|
|
14
|
+
* @remarks
|
|
15
|
+
* Used for cleanup when elements are removed or re-rendered.
|
|
16
|
+
* All effects created within a scope can be stopped at once.
|
|
17
|
+
*/
|
|
18
|
+
export interface EffectScope {
|
|
19
|
+
/**
|
|
20
|
+
* Run a function within this scope.
|
|
21
|
+
* Any effects created will be tracked by this scope.
|
|
22
|
+
*/
|
|
23
|
+
run<T>(fn: () => T): T;
|
|
24
|
+
/**
|
|
25
|
+
* Stop all effects in this scope.
|
|
26
|
+
*/
|
|
27
|
+
stop(): void;
|
|
28
|
+
/**
|
|
29
|
+
* Whether the scope has been stopped.
|
|
30
|
+
*/
|
|
31
|
+
active: boolean;
|
|
32
|
+
}
|
|
33
|
+
export declare function createEffectScope(): EffectScope;
|
|
34
|
+
/**
|
|
35
|
+
* Make an object deeply reactive.
|
|
36
|
+
*
|
|
37
|
+
* @remarks
|
|
38
|
+
* Property access is tracked when inside an effect. Mutations trigger
|
|
39
|
+
* all effects that depend on the changed property.
|
|
40
|
+
*
|
|
41
|
+
* @typeParam T - Object type
|
|
42
|
+
* @param target - The object to make reactive
|
|
43
|
+
* @returns A reactive proxy of the object
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* const state = reactive({ count: 0 });
|
|
48
|
+
* effect(() => console.log(state.count));
|
|
49
|
+
* state.count = 1; // logs: 1
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export declare function reactive<T extends object>(target: T): T;
|
|
53
|
+
/**
|
|
54
|
+
* Create a reactive effect.
|
|
55
|
+
*
|
|
56
|
+
* @remarks
|
|
57
|
+
* The function runs immediately, tracking dependencies.
|
|
58
|
+
* It re-runs automatically whenever those dependencies change.
|
|
59
|
+
*
|
|
60
|
+
* @param fn - The effect function to run
|
|
61
|
+
* @returns A cleanup function to stop the effect
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* const state = reactive({ count: 0 });
|
|
66
|
+
* const stop = effect(() => {
|
|
67
|
+
* console.log('Count:', state.count);
|
|
68
|
+
* });
|
|
69
|
+
* state.count = 1; // logs: Count: 1
|
|
70
|
+
* stop(); // effect no longer runs
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export declare function effect(fn: Effect): () => void;
|
|
74
|
+
/**
|
|
75
|
+
* Create a child reactive scope.
|
|
76
|
+
*
|
|
77
|
+
* @remarks
|
|
78
|
+
* Used by structural directives like c-for to create per-item contexts.
|
|
79
|
+
* The child scope inherits from the parent, with additions taking precedence.
|
|
80
|
+
*
|
|
81
|
+
* @typeParam T - Parent object type
|
|
82
|
+
* @param parent - The parent reactive object
|
|
83
|
+
* @param additions - Additional properties for this scope
|
|
84
|
+
* @returns A new reactive scope that inherits from parent
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```ts
|
|
88
|
+
* const parent = reactive({ items: [1, 2, 3] });
|
|
89
|
+
* const child = createScope(parent, { item: 1, index: 0 });
|
|
90
|
+
* child.item; // 1
|
|
91
|
+
* child.items; // [1, 2, 3] (from parent)
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
export declare function createScope<T extends object>(parent: T, additions: Record<string, unknown>): T & Record<string, unknown>;
|
|
95
|
+
export {};
|