gonia 0.2.2 → 0.2.4
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/directives/slot.js +2 -2
- package/dist/inject.d.ts +9 -6
- package/dist/inject.js +5 -8
- package/dist/server/render.js +34 -6
- package/dist/types.d.ts +5 -5
- package/dist/vite/plugin.js +3 -1
- package/package.json +1 -1
package/dist/directives/slot.js
CHANGED
|
@@ -70,8 +70,8 @@ export const slot = function slot($expr, $element, $eval, $slotContent) {
|
|
|
70
70
|
transclude();
|
|
71
71
|
}
|
|
72
72
|
};
|
|
73
|
-
slot.$inject = ['$expr', '$element', '$eval'
|
|
74
|
-
directive('g-slot', slot);
|
|
73
|
+
slot.$inject = ['$expr', '$element', '$eval'];
|
|
74
|
+
directive('g-slot', slot, { using: [SlotContentContext] });
|
|
75
75
|
/**
|
|
76
76
|
* Process native <slot> elements.
|
|
77
77
|
*
|
package/dist/inject.d.ts
CHANGED
|
@@ -14,9 +14,10 @@
|
|
|
14
14
|
import type { ContextKey } from './context-registry.js';
|
|
15
15
|
import type { Expression, EvalFn } from './types.js';
|
|
16
16
|
/**
|
|
17
|
-
* An injectable dependency
|
|
17
|
+
* An injectable dependency name.
|
|
18
|
+
* For ContextKey injection, use the `using` option on directive registration.
|
|
18
19
|
*/
|
|
19
|
-
export type Injectable = string
|
|
20
|
+
export type Injectable = string;
|
|
20
21
|
/**
|
|
21
22
|
* Check if a value is a ContextKey.
|
|
22
23
|
*/
|
|
@@ -25,7 +26,7 @@ export declare function isContextKey(value: unknown): value is ContextKey<unknow
|
|
|
25
26
|
* A function with optional `$inject` annotation.
|
|
26
27
|
*/
|
|
27
28
|
interface InjectableFunction extends Function {
|
|
28
|
-
$inject?: readonly
|
|
29
|
+
$inject?: readonly string[];
|
|
29
30
|
}
|
|
30
31
|
/**
|
|
31
32
|
* Get the list of injectable dependencies for a function.
|
|
@@ -43,10 +44,12 @@ interface InjectableFunction extends Function {
|
|
|
43
44
|
* const myDirective = (expr, ctx, el, http, userService) => {};
|
|
44
45
|
* getInjectables(myDirective); // ['expr', 'ctx', 'el', 'http', 'userService']
|
|
45
46
|
*
|
|
46
|
-
* // Production - explicit
|
|
47
|
-
* myDirective.$inject = ['$element',
|
|
48
|
-
* getInjectables(myDirective); // ['$element',
|
|
47
|
+
* // Production - explicit $inject array (survives minification)
|
|
48
|
+
* myDirective.$inject = ['$element', '$scope'];
|
|
49
|
+
* getInjectables(myDirective); // ['$element', '$scope']
|
|
49
50
|
* ```
|
|
51
|
+
*
|
|
52
|
+
* For ContextKey injection, use the `using` option on directive registration.
|
|
50
53
|
*/
|
|
51
54
|
export declare function getInjectables(fn: InjectableFunction): Injectable[];
|
|
52
55
|
/**
|
package/dist/inject.js
CHANGED
|
@@ -33,10 +33,12 @@ export function isContextKey(value) {
|
|
|
33
33
|
* const myDirective = (expr, ctx, el, http, userService) => {};
|
|
34
34
|
* getInjectables(myDirective); // ['expr', 'ctx', 'el', 'http', 'userService']
|
|
35
35
|
*
|
|
36
|
-
* // Production - explicit
|
|
37
|
-
* myDirective.$inject = ['$element',
|
|
38
|
-
* getInjectables(myDirective); // ['$element',
|
|
36
|
+
* // Production - explicit $inject array (survives minification)
|
|
37
|
+
* myDirective.$inject = ['$element', '$scope'];
|
|
38
|
+
* getInjectables(myDirective); // ['$element', '$scope']
|
|
39
39
|
* ```
|
|
40
|
+
*
|
|
41
|
+
* For ContextKey injection, use the `using` option on directive registration.
|
|
40
42
|
*/
|
|
41
43
|
export function getInjectables(fn) {
|
|
42
44
|
if ('$inject' in fn && Array.isArray(fn.$inject)) {
|
|
@@ -85,11 +87,6 @@ function parseFunctionParams(fn) {
|
|
|
85
87
|
export function resolveDependencies(fn, expr, element, evalFn, config, using) {
|
|
86
88
|
const inject = getInjectables(fn);
|
|
87
89
|
const args = inject.map(dep => {
|
|
88
|
-
// Handle ContextKey injection
|
|
89
|
-
if (isContextKey(dep)) {
|
|
90
|
-
return config.resolveContext(dep);
|
|
91
|
-
}
|
|
92
|
-
// Handle string-based injection
|
|
93
90
|
switch (dep) {
|
|
94
91
|
case '$expr':
|
|
95
92
|
return expr;
|
package/dist/server/render.js
CHANGED
|
@@ -7,7 +7,8 @@ import { Window } from 'happy-dom';
|
|
|
7
7
|
import { Mode, DirectivePriority, getDirective } from '../types.js';
|
|
8
8
|
import { createContext } from '../context.js';
|
|
9
9
|
import { processNativeSlot } from '../directives/slot.js';
|
|
10
|
-
import {
|
|
10
|
+
import { registerProvider, resolveFromProviders, resolveFromDIProviders } from '../providers.js';
|
|
11
|
+
import { createElementScope, getElementScope } from '../scope.js';
|
|
11
12
|
import { FOR_PROCESSED_ATTR, FOR_TEMPLATE_ATTR } from '../directives/for.js';
|
|
12
13
|
import { IF_PROCESSED_ATTR } from '../directives/if.js';
|
|
13
14
|
import { resolveDependencies as resolveInjectables } from '../inject.js';
|
|
@@ -83,15 +84,32 @@ export function registerDirective(registry, name, fn) {
|
|
|
83
84
|
export function registerService(name, service) {
|
|
84
85
|
services.set(name, service);
|
|
85
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* Find the nearest scope by walking up the DOM tree.
|
|
89
|
+
* Falls back to rootState if no element scope found.
|
|
90
|
+
*
|
|
91
|
+
* @internal
|
|
92
|
+
*/
|
|
93
|
+
function findServerScope(el, rootState) {
|
|
94
|
+
let current = el;
|
|
95
|
+
while (current) {
|
|
96
|
+
const scope = getElementScope(current);
|
|
97
|
+
if (scope) {
|
|
98
|
+
return scope;
|
|
99
|
+
}
|
|
100
|
+
current = current.parentElement;
|
|
101
|
+
}
|
|
102
|
+
return rootState;
|
|
103
|
+
}
|
|
86
104
|
/**
|
|
87
105
|
* Create resolver config for server-side dependency resolution.
|
|
88
106
|
*
|
|
89
107
|
* @internal
|
|
90
108
|
*/
|
|
91
|
-
function createServerResolverConfig(el, rootState) {
|
|
109
|
+
function createServerResolverConfig(el, scopeState, rootState) {
|
|
92
110
|
return {
|
|
93
111
|
resolveContext: (key) => resolveContext(el, key),
|
|
94
|
-
resolveState: () =>
|
|
112
|
+
resolveState: () => scopeState,
|
|
95
113
|
resolveRootState: () => rootState,
|
|
96
114
|
resolveCustom: (name) => {
|
|
97
115
|
// Look up in ancestor DI providers first (provide option)
|
|
@@ -293,13 +311,23 @@ export async function render(html, state, registry) {
|
|
|
293
311
|
continue;
|
|
294
312
|
}
|
|
295
313
|
else {
|
|
296
|
-
|
|
314
|
+
// Determine scope for this directive
|
|
315
|
+
let scopeState;
|
|
316
|
+
if (item.directive.$context?.length) {
|
|
317
|
+
// Directives with $context get their own scope to populate
|
|
318
|
+
const parentScope = findServerScope(item.el, state);
|
|
319
|
+
scopeState = createElementScope(item.el, parentScope);
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
// Other directives use nearest ancestor scope or root
|
|
323
|
+
scopeState = findServerScope(item.el, state);
|
|
324
|
+
}
|
|
325
|
+
const config = createServerResolverConfig(item.el, scopeState, state);
|
|
297
326
|
const args = resolveInjectables(item.directive, item.expr, item.el, ctx.eval.bind(ctx), config, item.using);
|
|
298
327
|
await item.directive(...args);
|
|
299
328
|
// Register as context provider if directive declares $context
|
|
300
329
|
if (item.directive.$context?.length) {
|
|
301
|
-
|
|
302
|
-
registerProvider(item.el, item.directive, localState);
|
|
330
|
+
registerProvider(item.el, item.directive, scopeState);
|
|
303
331
|
}
|
|
304
332
|
}
|
|
305
333
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
* @packageDocumentation
|
|
5
5
|
*/
|
|
6
6
|
import type { ContextKey } from './context-registry.js';
|
|
7
|
-
import type { Injectable } from './inject.js';
|
|
8
7
|
/**
|
|
9
8
|
* Execution mode for the framework.
|
|
10
9
|
*/
|
|
@@ -160,14 +159,15 @@ export interface DirectiveMeta<T = InjectableRegistry> {
|
|
|
160
159
|
*
|
|
161
160
|
* @example
|
|
162
161
|
* ```ts
|
|
163
|
-
* // String-based injection
|
|
164
162
|
* myDirective.$inject = ['$element', '$scope'];
|
|
163
|
+
* ```
|
|
165
164
|
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
165
|
+
* For typed context keys, use the `using` option on directive registration:
|
|
166
|
+
* ```ts
|
|
167
|
+
* directive('my-directive', myDirective, { using: [SlotContentContext] });
|
|
168
168
|
* ```
|
|
169
169
|
*/
|
|
170
|
-
$inject?: readonly
|
|
170
|
+
$inject?: readonly string[];
|
|
171
171
|
/**
|
|
172
172
|
* Names this directive exposes as context to descendants.
|
|
173
173
|
*
|
package/dist/vite/plugin.js
CHANGED
|
@@ -351,7 +351,9 @@ export function gonia(options = {}) {
|
|
|
351
351
|
detected.delete(name);
|
|
352
352
|
}
|
|
353
353
|
// Generate imports if we found directives and haven't already
|
|
354
|
-
|
|
354
|
+
// Skip HTML files - they're scanned for detection but imports go in JS
|
|
355
|
+
const isHtmlFile = /\.html$/.test(id);
|
|
356
|
+
if (detected.size > 0 && !injectedModules.has(id) && !isHtmlFile) {
|
|
355
357
|
// Check if this file already imports from gonia/directives
|
|
356
358
|
const hasGoniaImport = code.includes("from 'gonia/directives'") ||
|
|
357
359
|
code.includes('from "gonia/directives"');
|