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.
Files changed (54) hide show
  1. package/README.md +119 -0
  2. package/dist/client/hydrate.d.ts +54 -0
  3. package/dist/client/hydrate.js +445 -0
  4. package/dist/client/index.d.ts +7 -0
  5. package/dist/client/index.js +6 -0
  6. package/dist/context.d.ts +40 -0
  7. package/dist/context.js +69 -0
  8. package/dist/directives/class.d.ts +21 -0
  9. package/dist/directives/class.js +42 -0
  10. package/dist/directives/for.d.ts +29 -0
  11. package/dist/directives/for.js +265 -0
  12. package/dist/directives/html.d.ts +16 -0
  13. package/dist/directives/html.js +19 -0
  14. package/dist/directives/if.d.ts +25 -0
  15. package/dist/directives/if.js +133 -0
  16. package/dist/directives/index.d.ts +15 -0
  17. package/dist/directives/index.js +15 -0
  18. package/dist/directives/model.d.ts +27 -0
  19. package/dist/directives/model.js +134 -0
  20. package/dist/directives/on.d.ts +21 -0
  21. package/dist/directives/on.js +54 -0
  22. package/dist/directives/show.d.ts +15 -0
  23. package/dist/directives/show.js +19 -0
  24. package/dist/directives/slot.d.ts +48 -0
  25. package/dist/directives/slot.js +99 -0
  26. package/dist/directives/template.d.ts +55 -0
  27. package/dist/directives/template.js +147 -0
  28. package/dist/directives/text.d.ts +15 -0
  29. package/dist/directives/text.js +18 -0
  30. package/dist/expression.d.ts +60 -0
  31. package/dist/expression.js +96 -0
  32. package/dist/index.d.ts +19 -0
  33. package/dist/index.js +16 -0
  34. package/dist/inject.d.ts +42 -0
  35. package/dist/inject.js +63 -0
  36. package/dist/providers.d.ts +96 -0
  37. package/dist/providers.js +146 -0
  38. package/dist/reactivity.d.ts +95 -0
  39. package/dist/reactivity.js +219 -0
  40. package/dist/scope.d.ts +43 -0
  41. package/dist/scope.js +112 -0
  42. package/dist/server/index.d.ts +7 -0
  43. package/dist/server/index.js +6 -0
  44. package/dist/server/render.d.ts +61 -0
  45. package/dist/server/render.js +243 -0
  46. package/dist/templates.d.ts +92 -0
  47. package/dist/templates.js +124 -0
  48. package/dist/types.d.ts +362 -0
  49. package/dist/types.js +110 -0
  50. package/dist/vite/index.d.ts +6 -0
  51. package/dist/vite/index.js +6 -0
  52. package/dist/vite/plugin.d.ts +30 -0
  53. package/dist/vite/plugin.js +127 -0
  54. 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
+ }
@@ -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';
@@ -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 {};