gonia 0.0.1 → 0.0.2

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 CHANGED
@@ -5,7 +5,7 @@ A lightweight, SSR-first reactive UI library for building web applications with
5
5
  ## Features
6
6
 
7
7
  - **SSR-First Architecture** - Server-side rendering with seamless client hydration
8
- - **Declarative Directives** - Vue-inspired template syntax (`c-text`, `c-for`, `c-if`, etc.)
8
+ - **Declarative Directives** - Vue-inspired template syntax (`g-text`, `g-for`, `g-if`, etc.)
9
9
  - **Fine-Grained Reactivity** - Efficient updates without virtual DOM diffing
10
10
  - **Zero Dependencies** - Core library has no runtime dependencies (linkedom for SSR only)
11
11
  - **TypeScript Native** - Full type safety with excellent IDE support
@@ -34,7 +34,7 @@ registerDirective(registry, 'class', cclass);
34
34
 
35
35
  // Render HTML with state
36
36
  const html = await render(
37
- '<ul><li c-for="item in items" c-text="item"></li></ul>',
37
+ '<ul><li g-for="item in items" g-text="item"></li></ul>',
38
38
  { items: ['Apple', 'Banana', 'Cherry'] },
39
39
  registry
40
40
  );
@@ -76,8 +76,8 @@ directive('my-app', myApp, { scope: true });
76
76
 
77
77
  ```html
78
78
  <my-app>
79
- <p c-text="count"></p>
80
- <button c-on="click: increment">+1</button>
79
+ <p g-text="count"></p>
80
+ <button g-on="click: increment">+1</button>
81
81
  </my-app>
82
82
  ```
83
83
 
@@ -85,13 +85,13 @@ directive('my-app', myApp, { scope: true });
85
85
 
86
86
  | Directive | Description | Example |
87
87
  |-----------|-------------|---------|
88
- | `c-text` | Set text content | `<span c-text="message"></span>` |
89
- | `c-show` | Toggle visibility | `<div c-show="isVisible">...</div>` |
90
- | `c-if` | Conditional render | `<p c-if="hasError">Error!</p>` |
91
- | `c-for` | Loop iteration | `<li c-for="item in items">...</li>` |
92
- | `c-class` | Dynamic classes | `<div c-class="{ active: isActive }">` |
93
- | `c-model` | Two-way binding | `<input c-model="name">` |
94
- | `c-on` | Event handling | `<button c-on="click: handleClick">` |
88
+ | `g-text` | Set text content | `<span g-text="message"></span>` |
89
+ | `g-show` | Toggle visibility | `<div g-show="isVisible">...</div>` |
90
+ | `g-if` | Conditional render | `<p g-if="hasError">Error!</p>` |
91
+ | `g-for` | Loop iteration | `<li g-for="item in items">...</li>` |
92
+ | `g-class` | Dynamic classes | `<div g-class="{ active: isActive }">` |
93
+ | `g-model` | Two-way binding | `<input g-model="name">` |
94
+ | `g-on` | Event handling | `<button g-on="click: handleClick">` |
95
95
 
96
96
  ## Vite Integration
97
97
 
@@ -55,7 +55,7 @@ function getSelector(registry) {
55
55
  if (!cachedSelector) {
56
56
  const directiveSelectors = [];
57
57
  for (const name of registry.keys()) {
58
- directiveSelectors.push(`[c-${name}]`);
58
+ directiveSelectors.push(`[g-${name}]`);
59
59
  }
60
60
  // Also match native <slot> elements
61
61
  directiveSelectors.push('slot');
@@ -71,7 +71,7 @@ function getSelector(registry) {
71
71
  function getDirectivesForElement(el, registry) {
72
72
  const directives = [];
73
73
  for (const [name, directive] of registry) {
74
- const attr = el.getAttribute(`c-${name}`);
74
+ const attr = el.getAttribute(`g-${name}`);
75
75
  if (attr !== null) {
76
76
  directives.push({ name, directive, expr: attr });
77
77
  }
@@ -175,7 +175,7 @@ function resolveDependencies(directive, expr, el, ctx) {
175
175
  * @internal
176
176
  */
177
177
  function processElement(el, registry) {
178
- // Skip elements already processed by c-for (they have their own child scope)
178
+ // Skip elements already processed by g-for (they have their own child scope)
179
179
  if (el.hasAttribute(FOR_PROCESSED_ATTR)) {
180
180
  return;
181
181
  }
@@ -201,7 +201,7 @@ function processElement(el, registry) {
201
201
  }
202
202
  return result;
203
203
  };
204
- // STRUCTURAL directives (like c-for) take ownership of the element.
204
+ // STRUCTURAL directives (like g-for) take ownership of the element.
205
205
  // They remove the original and handle other directives on clones themselves.
206
206
  const isStructural = directive.priority === DirectivePriority.STRUCTURAL;
207
207
  if (chain instanceof Promise) {
@@ -259,7 +259,7 @@ export function registerDirective(registry, name, fn) {
259
259
  registry.set(name, fn);
260
260
  cachedSelector = null;
261
261
  if (document.body && initialized) {
262
- const selector = `[c-${name}]`;
262
+ const selector = `[g-${name}]`;
263
263
  for (const el of document.querySelectorAll(selector)) {
264
264
  processElement(el, registry);
265
265
  }
@@ -400,7 +400,7 @@ export async function init(registry) {
400
400
  const selector = getSelector(reg);
401
401
  // Process existing elements synchronously, collecting promises from async directives.
402
402
  // Note: We collect elements first, but some may be removed during processing
403
- // (e.g., c-for removes its template). Check isConnected before processing.
403
+ // (e.g., g-for removes its template). Check isConnected before processing.
404
404
  const elements = document.querySelectorAll(selector);
405
405
  const promises = [];
406
406
  for (const el of elements) {
@@ -14,8 +14,8 @@ import { Directive } from '../types.js';
14
14
  *
15
15
  * @example
16
16
  * ```html
17
- * <div c-class="{ active: isActive, 'text-red': hasError }">
18
- * <div c-class="{ [dynamicClass]: true }">
17
+ * <div g-class="{ active: isActive, 'text-red': hasError }">
18
+ * <div g-class="{ [dynamicClass]: true }">
19
19
  * ```
20
20
  */
21
21
  export declare const cclass: Directive<['$expr', '$element', '$eval']>;
@@ -15,8 +15,8 @@ import { effect } from '../reactivity.js';
15
15
  *
16
16
  * @example
17
17
  * ```html
18
- * <div c-class="{ active: isActive, 'text-red': hasError }">
19
- * <div c-class="{ [dynamicClass]: true }">
18
+ * <div g-class="{ active: isActive, 'text-red': hasError }">
19
+ * <div g-class="{ [dynamicClass]: true }">
20
20
  * ```
21
21
  */
22
22
  export const cclass = function cclass($expr, $element, $eval) {
@@ -39,4 +39,4 @@ export const cclass = function cclass($expr, $element, $eval) {
39
39
  });
40
40
  };
41
41
  cclass.$inject = ['$expr', '$element', '$eval'];
42
- directive('c-class', cclass);
42
+ directive('g-class', cclass);
@@ -4,10 +4,10 @@
4
4
  * @packageDocumentation
5
5
  */
6
6
  import { Directive } from '../types.js';
7
- /** Attribute used to mark elements processed by c-for */
8
- export declare const FOR_PROCESSED_ATTR = "data-c-for-processed";
7
+ /** Attribute used to mark elements processed by g-for */
8
+ export declare const FOR_PROCESSED_ATTR = "data-g-for-processed";
9
9
  /** Attribute used to mark template content that should be skipped during SSR */
10
- export declare const FOR_TEMPLATE_ATTR = "data-c-for-template";
10
+ export declare const FOR_TEMPLATE_ATTR = "data-g-for-template";
11
11
  /**
12
12
  * Iterate over array or object items.
13
13
  *
@@ -17,13 +17,13 @@ export declare const FOR_TEMPLATE_ATTR = "data-c-for-template";
17
17
  * For objects, provides value and key.
18
18
  *
19
19
  * On server: wraps template in <template> element, renders items after it.
20
- * On client: finds <template c-for>, extracts template, sets up reactive loop.
20
+ * On client: finds <template g-for>, extracts template, sets up reactive loop.
21
21
  *
22
22
  * @example
23
23
  * ```html
24
- * <li c-for="item in items" c-text="item.name"></li>
25
- * <li c-for="(item, index) in items" c-text="index + ': ' + item.name"></li>
26
- * <div c-for="(value, key) in object" c-text="key + ': ' + value"></div>
24
+ * <li g-for="item in items" g-text="item.name"></li>
25
+ * <li g-for="(item, index) in items" g-text="index + ': ' + item.name"></li>
26
+ * <div g-for="(value, key) in object" g-text="key + ': ' + value"></div>
27
27
  * ```
28
28
  */
29
29
  export declare const cfor: Directive<['$expr', '$element', '$eval', '$state', '$mode']>;
@@ -7,7 +7,7 @@ import { directive, DirectivePriority, Mode } from '../types.js';
7
7
  import { effect, createEffectScope, createScope } from '../reactivity.js';
8
8
  import { createContext } from '../context.js';
9
9
  /**
10
- * Parse a c-for expression.
10
+ * Parse a g-for expression.
11
11
  *
12
12
  * Supports:
13
13
  * - `item in items`
@@ -27,26 +27,26 @@ function parseForExpression(expr) {
27
27
  iterableName: match[3].trim()
28
28
  };
29
29
  }
30
- /** Attribute used to mark elements processed by c-for */
31
- export const FOR_PROCESSED_ATTR = 'data-c-for-processed';
30
+ /** Attribute used to mark elements processed by g-for */
31
+ export const FOR_PROCESSED_ATTR = 'data-g-for-processed';
32
32
  /** Attribute used to mark template content that should be skipped during SSR */
33
- export const FOR_TEMPLATE_ATTR = 'data-c-for-template';
33
+ export const FOR_TEMPLATE_ATTR = 'data-g-for-template';
34
34
  /**
35
35
  * Process directives on a cloned element within a child scope.
36
36
  */
37
37
  function processClonedElement(el, parentState, scopeAdditions, mode) {
38
- // Mark this element as processed by c-for so hydrate skips it
38
+ // Mark this element as processed by g-for so hydrate skips it
39
39
  el.setAttribute(FOR_PROCESSED_ATTR, '');
40
40
  const childScope = createScope(parentState, scopeAdditions);
41
41
  const childCtx = createContext(mode, childScope);
42
- // Process c-text directives
43
- const textAttr = el.getAttribute('c-text');
42
+ // Process g-text directives
43
+ const textAttr = el.getAttribute('g-text');
44
44
  if (textAttr) {
45
45
  const value = childCtx.eval(textAttr);
46
46
  el.textContent = String(value ?? '');
47
47
  }
48
- // Process c-class directives
49
- const classAttr = el.getAttribute('c-class');
48
+ // Process g-class directives
49
+ const classAttr = el.getAttribute('g-class');
50
50
  if (classAttr) {
51
51
  const classObj = childCtx.eval(classAttr);
52
52
  if (classObj && typeof classObj === 'object') {
@@ -60,15 +60,15 @@ function processClonedElement(el, parentState, scopeAdditions, mode) {
60
60
  }
61
61
  }
62
62
  }
63
- // Process c-show directives
64
- const showAttr = el.getAttribute('c-show');
63
+ // Process g-show directives
64
+ const showAttr = el.getAttribute('g-show');
65
65
  if (showAttr) {
66
66
  const value = childCtx.eval(showAttr);
67
67
  el.style.display = value ? '' : 'none';
68
68
  }
69
- // Process c-on directives (format: "event: handler") - client only
69
+ // Process g-on directives (format: "event: handler") - client only
70
70
  if (mode === Mode.CLIENT) {
71
- const onAttr = el.getAttribute('c-on');
71
+ const onAttr = el.getAttribute('g-on');
72
72
  if (onAttr) {
73
73
  setupEventHandler(el, onAttr, childCtx, childScope);
74
74
  }
@@ -85,7 +85,7 @@ function processClonedElement(el, parentState, scopeAdditions, mode) {
85
85
  function setupEventHandler(el, expr, ctx, state) {
86
86
  const colonIdx = expr.indexOf(':');
87
87
  if (colonIdx === -1) {
88
- console.error(`Invalid c-on expression: ${expr}. Expected "event: handler"`);
88
+ console.error(`Invalid g-on expression: ${expr}. Expected "event: handler"`);
89
89
  return;
90
90
  }
91
91
  const eventName = expr.slice(0, colonIdx).trim();
@@ -168,19 +168,19 @@ function removeSSRItems(templateEl) {
168
168
  * For objects, provides value and key.
169
169
  *
170
170
  * On server: wraps template in <template> element, renders items after it.
171
- * On client: finds <template c-for>, extracts template, sets up reactive loop.
171
+ * On client: finds <template g-for>, extracts template, sets up reactive loop.
172
172
  *
173
173
  * @example
174
174
  * ```html
175
- * <li c-for="item in items" c-text="item.name"></li>
176
- * <li c-for="(item, index) in items" c-text="index + ': ' + item.name"></li>
177
- * <div c-for="(value, key) in object" c-text="key + ': ' + value"></div>
175
+ * <li g-for="item in items" g-text="item.name"></li>
176
+ * <li g-for="(item, index) in items" g-text="index + ': ' + item.name"></li>
177
+ * <div g-for="(value, key) in object" g-text="key + ': ' + value"></div>
178
178
  * ```
179
179
  */
180
180
  export const cfor = function cfor($expr, $element, $eval, $state, $mode) {
181
181
  const parsed = parseForExpression($expr);
182
182
  if (!parsed) {
183
- console.error(`Invalid c-for expression: ${$expr}`);
183
+ console.error(`Invalid g-for expression: ${$expr}`);
184
184
  return;
185
185
  }
186
186
  const parent = $element.parentNode;
@@ -192,10 +192,10 @@ export const cfor = function cfor($expr, $element, $eval, $state, $mode) {
192
192
  if ($mode === Mode.SERVER) {
193
193
  // Create a <template> element to hold the original
194
194
  const templateWrapper = $element.ownerDocument.createElement('template');
195
- templateWrapper.setAttribute('c-for', $expr);
196
- // Clone the original element (without c-for attr) into the template
195
+ templateWrapper.setAttribute('g-for', $expr);
196
+ // Clone the original element (without g-for attr) into the template
197
197
  const templateContent = $element.cloneNode(true);
198
- templateContent.removeAttribute('c-for');
198
+ templateContent.removeAttribute('g-for');
199
199
  // Mark as template content so render loop skips it
200
200
  templateContent.setAttribute(FOR_TEMPLATE_ATTR, '');
201
201
  // Append directly to template element (linkedom doesn't support .content)
@@ -209,11 +209,11 @@ export const cfor = function cfor($expr, $element, $eval, $state, $mode) {
209
209
  }
210
210
  // Client-side: check if hydrating from SSR or fresh render
211
211
  if (isTemplateElement) {
212
- // Hydrating from SSR: element is <template c-for="...">
212
+ // Hydrating from SSR: element is <template g-for="...">
213
213
  const templateWrapper = $element;
214
214
  const templateContent = templateWrapper.content.firstElementChild;
215
215
  if (!templateContent) {
216
- console.error('c-for template element has no content');
216
+ console.error('g-for template element has no content');
217
217
  return;
218
218
  }
219
219
  // Remove SSR-rendered items
@@ -235,12 +235,12 @@ export const cfor = function cfor($expr, $element, $eval, $state, $mode) {
235
235
  });
236
236
  }
237
237
  else {
238
- // Fresh client render: element has c-for attribute directly
238
+ // Fresh client render: element has g-for attribute directly
239
239
  // Wrap in template element for consistency
240
240
  const templateWrapper = $element.ownerDocument.createElement('template');
241
- templateWrapper.setAttribute('c-for', $expr);
241
+ templateWrapper.setAttribute('g-for', $expr);
242
242
  const templateContent = $element.cloneNode(true);
243
- templateContent.removeAttribute('c-for');
243
+ templateContent.removeAttribute('g-for');
244
244
  templateWrapper.content.appendChild(templateContent);
245
245
  parent.replaceChild(templateWrapper, $element);
246
246
  // Set up reactive loop
@@ -262,4 +262,4 @@ export const cfor = function cfor($expr, $element, $eval, $state, $mode) {
262
262
  };
263
263
  cfor.$inject = ['$expr', '$element', '$eval', '$state', '$mode'];
264
264
  cfor.priority = DirectivePriority.STRUCTURAL;
265
- directive('c-for', cfor);
265
+ directive('g-for', cfor);
@@ -9,8 +9,8 @@ import { Directive } from '../types.js';
9
9
  *
10
10
  * @example
11
11
  * ```html
12
- * <div c-html="formattedContent"></div>
13
- * <div c-html="'<strong>' + title + '</strong>'"></div>
12
+ * <div g-html="formattedContent"></div>
13
+ * <div g-html="'<strong>' + title + '</strong>'"></div>
14
14
  * ```
15
15
  */
16
16
  export declare const html: Directive<['$expr', '$element', '$eval']>;
@@ -9,11 +9,11 @@ import { directive } from '../types.js';
9
9
  *
10
10
  * @example
11
11
  * ```html
12
- * <div c-html="formattedContent"></div>
13
- * <div c-html="'<strong>' + title + '</strong>'"></div>
12
+ * <div g-html="formattedContent"></div>
13
+ * <div g-html="'<strong>' + title + '</strong>'"></div>
14
14
  * ```
15
15
  */
16
16
  export const html = function html($expr, $element, $eval) {
17
17
  $element.innerHTML = String($eval($expr) ?? '');
18
18
  };
19
- directive('c-html', html);
19
+ directive('g-html', html);
@@ -4,13 +4,13 @@
4
4
  * @packageDocumentation
5
5
  */
6
6
  import { Directive } from '../types.js';
7
- /** Attribute used to mark elements processed by c-if */
8
- export declare const IF_PROCESSED_ATTR = "data-c-if-processed";
7
+ /** Attribute used to mark elements processed by g-if */
8
+ export declare const IF_PROCESSED_ATTR = "data-g-if-processed";
9
9
  /**
10
10
  * Conditionally render an element.
11
11
  *
12
12
  * @remarks
13
- * Unlike c-show which uses display:none, c-if completely removes
13
+ * Unlike g-show which uses display:none, g-if completely removes
14
14
  * the element from the DOM when the condition is falsy.
15
15
  *
16
16
  * On server: evaluates once and removes element if false.
@@ -18,8 +18,8 @@ export declare const IF_PROCESSED_ATTR = "data-c-if-processed";
18
18
  *
19
19
  * @example
20
20
  * ```html
21
- * <div c-if="isLoggedIn">Welcome back!</div>
22
- * <div c-if="items.length > 0">Has items</div>
21
+ * <div g-if="isLoggedIn">Welcome back!</div>
22
+ * <div g-if="items.length > 0">Has items</div>
23
23
  * ```
24
24
  */
25
25
  export declare const cif: Directive<['$expr', '$element', '$eval', '$state', '$mode']>;
@@ -7,8 +7,8 @@ import { directive, DirectivePriority, Mode } from '../types.js';
7
7
  import { effect } from '../reactivity.js';
8
8
  import { createContext } from '../context.js';
9
9
  import { createScope } from '../reactivity.js';
10
- /** Attribute used to mark elements processed by c-if */
11
- export const IF_PROCESSED_ATTR = 'data-c-if-processed';
10
+ /** Attribute used to mark elements processed by g-if */
11
+ export const IF_PROCESSED_ATTR = 'data-g-if-processed';
12
12
  /**
13
13
  * Process directives on a conditionally rendered element.
14
14
  */
@@ -16,14 +16,14 @@ function processConditionalElement(el, parentState, mode) {
16
16
  el.setAttribute(IF_PROCESSED_ATTR, '');
17
17
  const childScope = createScope(parentState, {});
18
18
  const childCtx = createContext(mode, childScope);
19
- // Process c-text directives
20
- const textAttr = el.getAttribute('c-text');
19
+ // Process g-text directives
20
+ const textAttr = el.getAttribute('g-text');
21
21
  if (textAttr) {
22
22
  const value = childCtx.eval(textAttr);
23
23
  el.textContent = String(value ?? '');
24
24
  }
25
- // Process c-class directives
26
- const classAttr = el.getAttribute('c-class');
25
+ // Process g-class directives
26
+ const classAttr = el.getAttribute('g-class');
27
27
  if (classAttr) {
28
28
  const classObj = childCtx.eval(classAttr);
29
29
  if (classObj && typeof classObj === 'object') {
@@ -37,15 +37,15 @@ function processConditionalElement(el, parentState, mode) {
37
37
  }
38
38
  }
39
39
  }
40
- // Process c-show directives
41
- const showAttr = el.getAttribute('c-show');
40
+ // Process g-show directives
41
+ const showAttr = el.getAttribute('g-show');
42
42
  if (showAttr) {
43
43
  const value = childCtx.eval(showAttr);
44
44
  el.style.display = value ? '' : 'none';
45
45
  }
46
- // Process c-on directives (format: "event: handler") - client only
46
+ // Process g-on directives (format: "event: handler") - client only
47
47
  if (mode === Mode.CLIENT) {
48
- const onAttr = el.getAttribute('c-on');
48
+ const onAttr = el.getAttribute('g-on');
49
49
  if (onAttr) {
50
50
  const colonIdx = onAttr.indexOf(':');
51
51
  if (colonIdx !== -1) {
@@ -69,7 +69,7 @@ function processConditionalElement(el, parentState, mode) {
69
69
  * Conditionally render an element.
70
70
  *
71
71
  * @remarks
72
- * Unlike c-show which uses display:none, c-if completely removes
72
+ * Unlike g-show which uses display:none, g-if completely removes
73
73
  * the element from the DOM when the condition is falsy.
74
74
  *
75
75
  * On server: evaluates once and removes element if false.
@@ -77,8 +77,8 @@ function processConditionalElement(el, parentState, mode) {
77
77
  *
78
78
  * @example
79
79
  * ```html
80
- * <div c-if="isLoggedIn">Welcome back!</div>
81
- * <div c-if="items.length > 0">Has items</div>
80
+ * <div g-if="isLoggedIn">Welcome back!</div>
81
+ * <div g-if="items.length > 0">Has items</div>
82
82
  * ```
83
83
  */
84
84
  export const cif = function cif($expr, $element, $eval, $state, $mode) {
@@ -94,16 +94,16 @@ export const cif = function cif($expr, $element, $eval, $state, $mode) {
94
94
  }
95
95
  else {
96
96
  // Process child directives
97
- $element.removeAttribute('c-if');
97
+ $element.removeAttribute('g-if');
98
98
  processConditionalElement($element, $state, $mode);
99
99
  }
100
100
  return;
101
101
  }
102
102
  // Client-side: set up reactive effect
103
- const placeholder = $element.ownerDocument.createComment(` c-if: ${$expr} `);
103
+ const placeholder = $element.ownerDocument.createComment(` g-if: ${$expr} `);
104
104
  parent.insertBefore(placeholder, $element);
105
105
  const template = $element.cloneNode(true);
106
- template.removeAttribute('c-if');
106
+ template.removeAttribute('g-if');
107
107
  $element.remove();
108
108
  let renderedElement = null;
109
109
  effect(() => {
@@ -130,4 +130,4 @@ export const cif = function cif($expr, $element, $eval, $state, $mode) {
130
130
  };
131
131
  cif.$inject = ['$expr', '$element', '$eval', '$state', '$mode'];
132
132
  cif.priority = DirectivePriority.STRUCTURAL;
133
- directive('c-if', cif);
133
+ directive('g-if', cif);
@@ -18,10 +18,10 @@ import { Directive } from '../types.js';
18
18
  *
19
19
  * @example
20
20
  * ```html
21
- * <input c-model="name">
22
- * <input type="checkbox" c-model="isActive">
23
- * <select c-model="selectedOption">
24
- * <textarea c-model="description"></textarea>
21
+ * <input g-model="name">
22
+ * <input type="checkbox" g-model="isActive">
23
+ * <select g-model="selectedOption">
24
+ * <textarea g-model="description"></textarea>
25
25
  * ```
26
26
  */
27
27
  export declare const model: Directive<['$expr', '$element', '$eval', '$rootState']>;
@@ -68,10 +68,10 @@ function getInputType(el) {
68
68
  *
69
69
  * @example
70
70
  * ```html
71
- * <input c-model="name">
72
- * <input type="checkbox" c-model="isActive">
73
- * <select c-model="selectedOption">
74
- * <textarea c-model="description"></textarea>
71
+ * <input g-model="name">
72
+ * <input type="checkbox" g-model="isActive">
73
+ * <select g-model="selectedOption">
74
+ * <textarea g-model="description"></textarea>
75
75
  * ```
76
76
  */
77
77
  export const model = function model($expr, $element, $eval, $rootState) {
@@ -131,4 +131,4 @@ export const model = function model($expr, $element, $eval, $rootState) {
131
131
  }
132
132
  };
133
133
  model.$inject = ['$expr', '$element', '$eval', '$rootState'];
134
- directive('c-model', model);
134
+ directive('g-model', model);
@@ -13,9 +13,9 @@ import { Directive } from '../types.js';
13
13
  *
14
14
  * @example
15
15
  * ```html
16
- * <button c-on="click: handleClick">Click me</button>
17
- * <form c-on="submit: save">
18
- * <input c-on="keydown: onKey">
16
+ * <button g-on="click: handleClick">Click me</button>
17
+ * <form g-on="submit: save">
18
+ * <input g-on="keydown: onKey">
19
19
  * ```
20
20
  */
21
21
  export declare const on: Directive<['$expr', '$element', '$eval', '$rootState']>;
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import { directive } from '../types.js';
7
7
  /**
8
- * Parse c-on expression: "event: handler" or "event: handler()"
8
+ * Parse g-on expression: "event: handler" or "event: handler()"
9
9
  */
10
10
  function parseOnExpression(expr) {
11
11
  const colonIdx = expr.indexOf(':');
@@ -28,15 +28,15 @@ function parseOnExpression(expr) {
28
28
  *
29
29
  * @example
30
30
  * ```html
31
- * <button c-on="click: handleClick">Click me</button>
32
- * <form c-on="submit: save">
33
- * <input c-on="keydown: onKey">
31
+ * <button g-on="click: handleClick">Click me</button>
32
+ * <form g-on="submit: save">
33
+ * <input g-on="keydown: onKey">
34
34
  * ```
35
35
  */
36
36
  export const on = function on($expr, $element, $eval, $rootState) {
37
37
  const parsed = parseOnExpression($expr);
38
38
  if (!parsed) {
39
- console.error(`Invalid c-on expression: ${$expr}. Expected "event: handler"`);
39
+ console.error(`Invalid g-on expression: ${$expr}. Expected "event: handler"`);
40
40
  return;
41
41
  }
42
42
  const { event: eventName, handler: handlerExpr } = parsed;
@@ -51,4 +51,4 @@ export const on = function on($expr, $element, $eval, $rootState) {
51
51
  $element.addEventListener(eventName, handler);
52
52
  };
53
53
  on.$inject = ['$expr', '$element', '$eval', '$rootState'];
54
- directive('c-on', on);
54
+ directive('g-on', on);
@@ -8,8 +8,8 @@ import { Directive } from '../types.js';
8
8
  *
9
9
  * @example
10
10
  * ```html
11
- * <div c-show="isVisible">Visible content</div>
12
- * <div c-show="items.length > 0">Has items</div>
11
+ * <div g-show="isVisible">Visible content</div>
12
+ * <div g-show="items.length > 0">Has items</div>
13
13
  * ```
14
14
  */
15
15
  export declare const show: Directive<['$expr', '$element', '$eval']>;
@@ -8,12 +8,12 @@ import { directive } from '../types.js';
8
8
  *
9
9
  * @example
10
10
  * ```html
11
- * <div c-show="isVisible">Visible content</div>
12
- * <div c-show="items.length > 0">Has items</div>
11
+ * <div g-show="isVisible">Visible content</div>
12
+ * <div g-show="items.length > 0">Has items</div>
13
13
  * ```
14
14
  */
15
15
  export const show = function show($expr, $element, $eval) {
16
16
  const value = $eval($expr);
17
17
  $element.style.display = value ? '' : 'none';
18
18
  };
19
- directive('c-show', show);
19
+ directive('g-show', show);
@@ -27,7 +27,7 @@ import { Directive } from '../types.js';
27
27
  *
28
28
  * Dynamic slot name:
29
29
  * ```html
30
- * <slot c-slot="activeTab"></slot>
30
+ * <slot g-slot="activeTab"></slot>
31
31
  * ```
32
32
  *
33
33
  * Default slot (no name):
@@ -41,7 +41,7 @@ export declare const slot: Directive<['$expr', '$element', '$eval']>;
41
41
  *
42
42
  * @remarks
43
43
  * This handles native `<slot>` elements in templates,
44
- * treating them the same as `c-slot` directives.
44
+ * treating them the same as `g-slot` directives.
45
45
  *
46
46
  * @internal
47
47
  */
@@ -29,7 +29,7 @@ import { findTemplateAncestor, getSavedContent } from './template.js';
29
29
  *
30
30
  * Dynamic slot name:
31
31
  * ```html
32
- * <slot c-slot="activeTab"></slot>
32
+ * <slot g-slot="activeTab"></slot>
33
33
  * ```
34
34
  *
35
35
  * Default slot (no name):
@@ -75,13 +75,13 @@ export const slot = function slot($expr, $element, $eval) {
75
75
  transclude();
76
76
  }
77
77
  };
78
- directive('c-slot', slot);
78
+ directive('g-slot', slot);
79
79
  /**
80
80
  * Process native <slot> elements.
81
81
  *
82
82
  * @remarks
83
83
  * This handles native `<slot>` elements in templates,
84
- * treating them the same as `c-slot` directives.
84
+ * treating them the same as `g-slot` directives.
85
85
  *
86
86
  * @internal
87
87
  */
@@ -40,7 +40,7 @@ export declare function findTemplateAncestor(el: Element): Element | null;
40
40
  *
41
41
  * @example
42
42
  * ```html
43
- * <div c-template="dialog">
43
+ * <div g-template="dialog">
44
44
  * <span slot="header">Title</span>
45
45
  * <p>Body content</p>
46
46
  * </div>
@@ -85,7 +85,7 @@ function extractSlotContent(el) {
85
85
  *
86
86
  * @example
87
87
  * ```html
88
- * <div c-template="dialog">
88
+ * <div g-template="dialog">
89
89
  * <span slot="header">Title</span>
90
90
  * <p>Body content</p>
91
91
  * </div>
@@ -136,7 +136,7 @@ export const template = async function template($expr, $element, $templates) {
136
136
  template.$inject = ['$expr', '$element', '$templates'];
137
137
  template.transclude = true;
138
138
  template.priority = DirectivePriority.TEMPLATE;
139
- directive('c-template', template);
139
+ directive('g-template', template);
140
140
  /**
141
141
  * Get the effect scope for an element.
142
142
  *
@@ -8,8 +8,8 @@ import { Directive } from '../types.js';
8
8
  *
9
9
  * @example
10
10
  * ```html
11
- * <span c-text="user.name"></span>
12
- * <span c-text="'Hello, ' + user.name + '!'"></span>
11
+ * <span g-text="user.name"></span>
12
+ * <span g-text="'Hello, ' + user.name + '!'"></span>
13
13
  * ```
14
14
  */
15
15
  export declare const text: Directive<['$expr', '$element', '$eval']>;
@@ -8,11 +8,11 @@ import { directive } from '../types.js';
8
8
  *
9
9
  * @example
10
10
  * ```html
11
- * <span c-text="user.name"></span>
12
- * <span c-text="'Hello, ' + user.name + '!'"></span>
11
+ * <span g-text="user.name"></span>
12
+ * <span g-text="'Hello, ' + user.name + '!'"></span>
13
13
  * ```
14
14
  */
15
15
  export const text = function text($expr, $element, $eval) {
16
16
  $element.textContent = String($eval($expr) ?? '');
17
17
  };
18
- directive('c-text', text);
18
+ directive('g-text', text);
@@ -75,7 +75,7 @@ export declare function effect(fn: Effect): () => void;
75
75
  * Create a child reactive scope.
76
76
  *
77
77
  * @remarks
78
- * Used by structural directives like c-for to create per-item contexts.
78
+ * Used by structural directives like g-for to create per-item contexts.
79
79
  * The child scope inherits from the parent, with additions taking precedence.
80
80
  *
81
81
  * @typeParam T - Parent object type
@@ -184,7 +184,7 @@ function cleanup(effectFn) {
184
184
  * Create a child reactive scope.
185
185
  *
186
186
  * @remarks
187
- * Used by structural directives like c-for to create per-item contexts.
187
+ * Used by structural directives like g-for to create per-item contexts.
188
188
  * The child scope inherits from the parent, with additions taking precedence.
189
189
  *
190
190
  * @typeParam T - Parent object type
@@ -51,11 +51,11 @@ export declare function registerService(name: string, service: unknown): void;
51
51
  * registry.set('text', textDirective);
52
52
  *
53
53
  * const html = await render(
54
- * '<span c-text="user.name"></span>',
54
+ * '<span g-text="user.name"></span>',
55
55
  * { user: { name: 'Alice' } },
56
56
  * registry
57
57
  * );
58
- * // '<span c-text="user.name">Alice</span>'
58
+ * // '<span g-text="user.name">Alice</span>'
59
59
  * ```
60
60
  */
61
61
  export declare function render(html: string, state: Record<string, unknown>, registry: DirectiveRegistry): Promise<string>;
@@ -21,7 +21,7 @@ const selectorCache = new WeakMap();
21
21
  function getSelector(registry) {
22
22
  let selector = selectorCache.get(registry);
23
23
  if (!selector) {
24
- const directiveSelectors = [...registry.keys()].map(n => `[c-${n}]`);
24
+ const directiveSelectors = [...registry.keys()].map(n => `[g-${n}]`);
25
25
  // Also match native <slot> elements
26
26
  directiveSelectors.push('slot');
27
27
  selector = directiveSelectors.join(',');
@@ -115,11 +115,11 @@ function resolveDependencies(directive, expr, el, ctx, rootState) {
115
115
  * registry.set('text', textDirective);
116
116
  *
117
117
  * const html = await render(
118
- * '<span c-text="user.name"></span>',
118
+ * '<span g-text="user.name"></span>',
119
119
  * { user: { name: 'Alice' } },
120
120
  * registry
121
121
  * );
122
- * // '<span c-text="user.name">Alice</span>'
122
+ * // '<span g-text="user.name">Alice</span>'
123
123
  * ```
124
124
  */
125
125
  export async function render(html, state, registry) {
@@ -148,7 +148,7 @@ export async function render(html, state, registry) {
148
148
  continue;
149
149
  }
150
150
  for (const [name, directive] of registry) {
151
- const attr = match.getAttribute(`c-${name}`);
151
+ const attr = match.getAttribute(`g-${name}`);
152
152
  if (attr !== null) {
153
153
  index.push({
154
154
  el: match,
@@ -189,25 +189,25 @@ export async function render(html, state, registry) {
189
189
  }
190
190
  // Process elements in tree order
191
191
  for (const el of elementOrder) {
192
- // Skip elements that were removed (e.g., by c-for cloning)
192
+ // Skip elements that were removed (e.g., by g-for cloning)
193
193
  if (!el.isConnected) {
194
194
  processed.add(el);
195
195
  continue;
196
196
  }
197
- // Skip elements already processed by structural directives (c-for, c-if)
197
+ // Skip elements already processed by structural directives (g-for, g-if)
198
198
  // These elements have their own scoped processing
199
199
  if (el.hasAttribute(FOR_PROCESSED_ATTR) || el.hasAttribute(IF_PROCESSED_ATTR)) {
200
200
  processed.add(el);
201
201
  continue;
202
202
  }
203
- // Skip template elements with c-for - these are template wrappers created by c-for
203
+ // Skip template elements with g-for - these are template wrappers created by g-for
204
204
  // and should not be processed as directives (they're for client hydration)
205
- if (el.tagName === 'TEMPLATE' && el.hasAttribute('c-for')) {
205
+ if (el.tagName === 'TEMPLATE' && el.hasAttribute('g-for')) {
206
206
  processed.add(el);
207
207
  continue;
208
208
  }
209
209
  // Skip template content elements - these are inside template wrappers
210
- // and their directives are processed by c-for when rendering items
210
+ // and their directives are processed by g-for when rendering items
211
211
  if (el.hasAttribute(FOR_TEMPLATE_ATTR)) {
212
212
  processed.add(el);
213
213
  continue;
@@ -217,7 +217,7 @@ export async function render(html, state, registry) {
217
217
  // Sort directives on this element by priority (higher first)
218
218
  directives.sort((a, b) => b.priority - a.priority);
219
219
  for (const item of directives) {
220
- // Check if element was disconnected by a previous directive (e.g., c-for replacing it)
220
+ // Check if element was disconnected by a previous directive (e.g., g-for replacing it)
221
221
  if (!item.el.isConnected) {
222
222
  break;
223
223
  }
package/dist/types.d.ts CHANGED
@@ -51,7 +51,7 @@ export interface InjectableRegistry {
51
51
  $state: Record<string, unknown>;
52
52
  /** Root reactive state object (shared across all elements) */
53
53
  $rootState: Record<string, unknown>;
54
- /** Template registry for c-template directive */
54
+ /** Template registry for g-template directive */
55
55
  $templates: {
56
56
  get(name: string): Promise<string>;
57
57
  };
@@ -111,10 +111,10 @@ export interface Context {
111
111
  *
112
112
  * @remarks
113
113
  * Higher priority directives run first. Structural directives
114
- * (like c-if, c-for) need to run before behavioral ones.
114
+ * (like g-if, g-for) need to run before behavioral ones.
115
115
  */
116
116
  export declare enum DirectivePriority {
117
- /** Structural directives that control DOM presence (c-if, c-for) */
117
+ /** Structural directives that control DOM presence (g-if, g-for) */
118
118
  STRUCTURAL = 1000,
119
119
  /** Template/transclusion directives */
120
120
  TEMPLATE = 500,
@@ -314,7 +314,7 @@ export interface DirectiveRegistration {
314
314
  * The function can be `null` for pure template directives that have no
315
315
  * runtime behavior.
316
316
  *
317
- * @param name - The directive name (e.g., 'c-text' or 'todo-app')
317
+ * @param name - The directive name (e.g., 'g-text' or 'todo-app')
318
318
  * @param fn - The directive function, or null for template-only directives
319
319
  * @param options - Registration options
320
320
  *
package/dist/types.js CHANGED
@@ -18,11 +18,11 @@ export var Mode;
18
18
  *
19
19
  * @remarks
20
20
  * Higher priority directives run first. Structural directives
21
- * (like c-if, c-for) need to run before behavioral ones.
21
+ * (like g-if, g-for) need to run before behavioral ones.
22
22
  */
23
23
  export var DirectivePriority;
24
24
  (function (DirectivePriority) {
25
- /** Structural directives that control DOM presence (c-if, c-for) */
25
+ /** Structural directives that control DOM presence (g-if, g-for) */
26
26
  DirectivePriority[DirectivePriority["STRUCTURAL"] = 1000] = "STRUCTURAL";
27
27
  /** Template/transclusion directives */
28
28
  DirectivePriority[DirectivePriority["TEMPLATE"] = 500] = "TEMPLATE";
@@ -42,7 +42,7 @@ const directiveRegistry = new Map();
42
42
  * The function can be `null` for pure template directives that have no
43
43
  * runtime behavior.
44
44
  *
45
- * @param name - The directive name (e.g., 'c-text' or 'todo-app')
45
+ * @param name - The directive name (e.g., 'g-text' or 'todo-app')
46
46
  * @param fn - The directive function, or null for template-only directives
47
47
  * @param options - Registration options
48
48
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gonia",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "A lightweight, SSR-first reactive UI library with declarative directives",
5
5
  "type": "module",
6
6
  "license": "MIT",