ladrillosjs 2.0.0-beta.6 → 2.0.0-beta.8
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/LICENSE +21 -0
- package/README.md +126 -46
- package/dist/core/builtins/lazyElement.d.ts +35 -0
- package/dist/core/cache/expressionCache.d.ts +15 -0
- package/dist/core/component/bindingParser.d.ts +2 -0
- package/dist/core/component/cache.d.ts +22 -0
- package/dist/core/component/extract.d.ts +2 -0
- package/dist/core/component/loader.d.ts +10 -0
- package/dist/core/component/webcomponent.d.ts +29 -0
- package/dist/core/configure.d.ts +28 -0
- package/dist/core/css/cssParser/cssParser.d.ts +3 -0
- package/dist/core/diff/listDiff.d.ts +99 -0
- package/dist/core/directives/directiveProcessor.d.ts +58 -0
- package/dist/core/events/eventBus.d.ts +136 -0
- package/dist/core/helpers/frameworkHelpers.d.ts +38 -0
- package/dist/core/html/htmlparser.d.ts +19 -0
- package/dist/core/js/moduleExecutor.d.ts +118 -0
- package/dist/core/js/reactivity.d.ts +52 -0
- package/dist/core/js/scriptParser.d.ts +52 -0
- package/dist/core/ladrillos.d.ts +68 -0
- package/dist/core/lazy/index.d.ts +6 -0
- package/dist/core/lazy/lazyLoader.d.ts +22 -0
- package/dist/core/lazy/lazyStrategies.d.ts +73 -0
- package/dist/core/scheduler/batchScheduler.d.ts +97 -0
- package/dist/core.d.ts +10 -9
- package/dist/core.js +2 -1
- package/dist/core.js.map +1 -0
- package/dist/events.js +1 -1
- package/dist/index.d.ts +11 -9
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -0
- package/dist/lazy.d.ts +1 -1
- package/dist/lazy.js +1 -1
- package/dist/{shared-DGGk2qBc.js → shared-D-P0qKQY.js} +2 -1
- package/dist/shared-D-P0qKQY.js.map +1 -0
- package/dist/shared-DmVkrquj.js +2 -0
- package/dist/shared-DmVkrquj.js.map +1 -0
- package/dist/shared-yJteVv_p.js +3 -0
- package/dist/shared-yJteVv_p.js.map +1 -0
- package/dist/types/index.d.ts +171 -0
- package/dist/utils/devWarnings.d.ts +133 -0
- package/dist/utils/directives.d.ts +149 -0
- package/dist/utils/jsevents.d.ts +4 -0
- package/dist/utils/keyModifiers.d.ts +106 -0
- package/dist/utils/regex.d.ts +5 -0
- package/dist/utils/sandbox.d.ts +25 -0
- package/package.json +46 -15
- package/dist/shared-Dru_qCE_.js +0 -1
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LadrillosJS Global Event Bus
|
|
3
|
+
*
|
|
4
|
+
* Provides cross-component communication without prop drilling.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* - $emit("event-name", data) - Emit an event to all listeners
|
|
8
|
+
* - $listen("event-name", callback) - Listen for events from any component
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```html
|
|
12
|
+
* <!-- Component A: Emitting events -->
|
|
13
|
+
* <script>
|
|
14
|
+
* const login = () => {
|
|
15
|
+
* $emit("user-logged-in", { userId: 123, username: "john" });
|
|
16
|
+
* };
|
|
17
|
+
* </script>
|
|
18
|
+
*
|
|
19
|
+
* <!-- Component B: Listening for events -->
|
|
20
|
+
* <script>
|
|
21
|
+
* let isLoggedIn = false;
|
|
22
|
+
* let username = "";
|
|
23
|
+
*
|
|
24
|
+
* $listen("user-logged-in", (user) => {
|
|
25
|
+
* isLoggedIn = true;
|
|
26
|
+
* username = user.username;
|
|
27
|
+
* });
|
|
28
|
+
* </script>
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
/**
|
|
32
|
+
* Event listener callback function type
|
|
33
|
+
*/
|
|
34
|
+
export type EventListener<T = unknown> = (data: T) => void;
|
|
35
|
+
/**
|
|
36
|
+
* Public alias for EventListener (for external API)
|
|
37
|
+
*/
|
|
38
|
+
export type EventCallback<T = unknown> = EventListener<T>;
|
|
39
|
+
/**
|
|
40
|
+
* Internal listener registration with metadata for cleanup
|
|
41
|
+
*/
|
|
42
|
+
interface ListenerRegistration {
|
|
43
|
+
callback: EventListener;
|
|
44
|
+
componentId?: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Unsubscribe function returned by $listen
|
|
48
|
+
*/
|
|
49
|
+
export type Unsubscribe = () => void;
|
|
50
|
+
/**
|
|
51
|
+
* Global event bus interface for type safety
|
|
52
|
+
*/
|
|
53
|
+
interface GlobalEventBus {
|
|
54
|
+
listeners: Map<string, Set<ListenerRegistration>>;
|
|
55
|
+
componentListeners: Map<string, Set<{
|
|
56
|
+
event: string;
|
|
57
|
+
registration: ListenerRegistration;
|
|
58
|
+
}>>;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Extend globalThis to include our event bus
|
|
62
|
+
*/
|
|
63
|
+
declare global {
|
|
64
|
+
var __ladrillosEventBus: GlobalEventBus | undefined;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Emit an event to all registered listeners.
|
|
68
|
+
*
|
|
69
|
+
* @param eventName - The name of the event to emit
|
|
70
|
+
* @param data - Optional data to pass to listeners
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```js
|
|
74
|
+
* $emit("user-logged-in", { userId: 123, username: "john" });
|
|
75
|
+
* $emit("show-modal");
|
|
76
|
+
* $emit("item-added", { id: 1, name: "Product" });
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export declare function $emit<T = unknown>(eventName: string, data?: T): void;
|
|
80
|
+
/**
|
|
81
|
+
* Listen for events from any component.
|
|
82
|
+
*
|
|
83
|
+
* @param eventName - The name of the event to listen for
|
|
84
|
+
* @param callback - Function to call when the event is emitted
|
|
85
|
+
* @param componentId - Optional component ID for automatic cleanup
|
|
86
|
+
* @returns Unsubscribe function to remove the listener
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```js
|
|
90
|
+
* // Basic usage
|
|
91
|
+
* $listen("user-logged-in", (user) => {
|
|
92
|
+
* console.log(`Welcome, ${user.username}!`);
|
|
93
|
+
* isLoggedIn = true;
|
|
94
|
+
* });
|
|
95
|
+
*
|
|
96
|
+
* // With unsubscribe
|
|
97
|
+
* const unsubscribe = $listen("notifications", handleNotification);
|
|
98
|
+
* // Later: unsubscribe();
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
export declare function $listen<T = unknown>(eventName: string, callback: EventListener<T>, componentId?: string): Unsubscribe;
|
|
102
|
+
/**
|
|
103
|
+
* Remove all listeners registered by a specific component.
|
|
104
|
+
* Called automatically when a component is disconnected from the DOM.
|
|
105
|
+
*
|
|
106
|
+
* @param componentId - The component's unique ID
|
|
107
|
+
*/
|
|
108
|
+
export declare function cleanupComponentListeners(componentId: string): void;
|
|
109
|
+
/**
|
|
110
|
+
* Remove all event listeners (useful for testing)
|
|
111
|
+
*/
|
|
112
|
+
export declare function clearAllListeners(): void;
|
|
113
|
+
/**
|
|
114
|
+
* Get the count of listeners for an event (useful for debugging)
|
|
115
|
+
*/
|
|
116
|
+
export declare function getListenerCount(eventName: string): number;
|
|
117
|
+
/**
|
|
118
|
+
* Check if an event has any listeners
|
|
119
|
+
*/
|
|
120
|
+
export declare function hasListeners(eventName: string): boolean;
|
|
121
|
+
/**
|
|
122
|
+
* Creates event bus helpers bound to a specific component.
|
|
123
|
+
* This enables automatic cleanup when the component is disconnected.
|
|
124
|
+
*
|
|
125
|
+
* @param componentId - The unique ID of the component
|
|
126
|
+
* @returns Object containing bound $emit and $listen functions
|
|
127
|
+
*/
|
|
128
|
+
export declare function createEventBusHelpers(componentId: string): {
|
|
129
|
+
$emit: <T = unknown>(eventName: string, data?: T) => void;
|
|
130
|
+
$listen: <T = unknown>(eventName: string, callback: EventListener<T>) => Unsubscribe;
|
|
131
|
+
};
|
|
132
|
+
/**
|
|
133
|
+
* Names of event bus helpers (for Function parameter lists)
|
|
134
|
+
*/
|
|
135
|
+
export declare const eventBusHelperNames: string[];
|
|
136
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ComponentConfig, RegisterComponentsResult } from '../ladrillos';
|
|
2
|
+
import { LazyStrategy } from '../lazy';
|
|
3
|
+
/**
|
|
4
|
+
* Wraps a Map in a Proxy to allow cleaner dot notation access.
|
|
5
|
+
* Supports both $refs.inputEl and $refs.get("inputEl") syntax.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* const $refs = createRefsProxy(new Map());
|
|
9
|
+
* $refs.set("input", document.querySelector("input"));
|
|
10
|
+
* $refs.input.focus(); // Works!
|
|
11
|
+
* $refs.get("input").focus(); // Also works!
|
|
12
|
+
*/
|
|
13
|
+
export declare function createRefsProxy<T extends HTMLElement = HTMLElement>(map: Map<string, T>): Map<string, T> & Record<string, T>;
|
|
14
|
+
/**
|
|
15
|
+
* Creates framework helpers bound to a specific component's base URL.
|
|
16
|
+
* This ensures relative paths like "./buttons.html" resolve correctly
|
|
17
|
+
* relative to the component that calls registerComponent.
|
|
18
|
+
*
|
|
19
|
+
* @param componentUrl - The absolute URL of the component (e.g., "http://localhost/header/header.html")
|
|
20
|
+
* @returns Object containing bound helper functions
|
|
21
|
+
*/
|
|
22
|
+
export declare function createFrameworkHelpers(componentUrl: string): {
|
|
23
|
+
registerComponent: (name: string, path: string, useShadowDOM?: boolean, lazy?: boolean | LazyStrategy) => Promise<void>;
|
|
24
|
+
registerComponents: (configs: ComponentConfig[] | Record<string, string | Omit<ComponentConfig, "name">>) => Promise<RegisterComponentsResult>;
|
|
25
|
+
$use: (path: string, useShadowDOM?: boolean, lazy?: boolean | LazyStrategy) => Promise<void>;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Names of all framework helpers (for Function parameter lists)
|
|
29
|
+
*/
|
|
30
|
+
export declare const frameworkHelperNames: string[];
|
|
31
|
+
/**
|
|
32
|
+
* Default helpers for entry point usage (resolve relative to page URL).
|
|
33
|
+
* Inside components, use createFrameworkHelpers(componentUrl) instead.
|
|
34
|
+
*/
|
|
35
|
+
export declare function getFrameworkHelperValues(): ((...args: any[]) => any)[];
|
|
36
|
+
export declare const registerComponent: (name: string, path: string, useShadowDOM?: boolean, lazy?: boolean | LazyStrategy) => Promise<void>;
|
|
37
|
+
export declare const registerComponents: (configs: ComponentConfig[] | Record<string, string | Omit<ComponentConfig, "name">>) => Promise<RegisterComponentsResult>;
|
|
38
|
+
export declare const $use: (path: string, useShadowDOM?: boolean, lazy?: boolean | LazyStrategy) => Promise<void>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { BindingDescriptor } from '../../types';
|
|
2
|
+
type TemplateLoadResult = {
|
|
3
|
+
bindings: BindingDescriptor[];
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Injects the template HTML into the host element and scans for data bindings.
|
|
7
|
+
* Returns a list of all bindings found in text nodes and attributes.
|
|
8
|
+
*
|
|
9
|
+
* Directive scanning ($for / $if / $show / $bind) is performed separately
|
|
10
|
+
* by `scanDirectivesWithRefs` in the web component lifecycle.
|
|
11
|
+
*
|
|
12
|
+
* <lazy> elements are preprocessed here in a detached <template> fragment so
|
|
13
|
+
* their children never get connected (and thus never fire connectedCallback /
|
|
14
|
+
* drain their light DOM) before lazy detaches them. Without this, components
|
|
15
|
+
* inside <lazy> that read `$host.__originalHTML` would see an empty string on
|
|
16
|
+
* the second connect after lazy reveals them.
|
|
17
|
+
*/
|
|
18
|
+
export declare const loadTemplate: (host: HTMLElement | ShadowRoot, template: string) => TemplateLoadResult;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { ScriptElement, ExternalScriptElement } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Rewrites relative imports in module code to absolute URLs.
|
|
4
|
+
*
|
|
5
|
+
* NOTE: When using a dev server like Vite, TypeScript imports work because
|
|
6
|
+
* the server transpiles .ts files on-the-fly. Without a dev server, you need
|
|
7
|
+
* to use .js files or pre-compile your TypeScript.
|
|
8
|
+
*
|
|
9
|
+
* @param code - The module script content
|
|
10
|
+
* @param baseUrl - The URL to resolve relative paths against (component's URL)
|
|
11
|
+
* @returns The code with rewritten imports
|
|
12
|
+
*/
|
|
13
|
+
export declare function rewriteImports(code: string, baseUrl: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Executes a single inline module script.
|
|
16
|
+
*
|
|
17
|
+
* @param script - The script element containing module code
|
|
18
|
+
* @param componentUrl - The component's URL for resolving relative imports
|
|
19
|
+
* @param componentId - Unique ID for tracking blob URLs
|
|
20
|
+
* @returns Promise that resolves when the module has executed
|
|
21
|
+
*/
|
|
22
|
+
export declare function executeModuleScript(script: ScriptElement, componentUrl: string, componentId?: string): Promise<unknown>;
|
|
23
|
+
/**
|
|
24
|
+
* Executes an external module script.
|
|
25
|
+
* For external scripts, we fetch the content, auto-export all declarations,
|
|
26
|
+
* and execute it via blob URL with injected framework helpers.
|
|
27
|
+
*
|
|
28
|
+
* If the script has the 'external' attribute, it's loaded as a plain
|
|
29
|
+
* external script without any framework processing (no helpers, no auto-exports).
|
|
30
|
+
*
|
|
31
|
+
* @param script - The external script element
|
|
32
|
+
* @param componentId - Optional component ID for event bus cleanup
|
|
33
|
+
* @param componentUrl - Optional component URL for path resolution
|
|
34
|
+
* @returns Promise that resolves with the module exports
|
|
35
|
+
*/
|
|
36
|
+
export declare function executeExternalScript(script: ExternalScriptElement, componentId?: string, componentUrl?: string): Promise<unknown>;
|
|
37
|
+
/**
|
|
38
|
+
* Loads external scripts marked with the 'external' attribute.
|
|
39
|
+
* These are third-party libraries (like highlight.js) that need to be loaded
|
|
40
|
+
* BEFORE the component's inline scripts run, since they may depend on globals
|
|
41
|
+
* provided by these libraries.
|
|
42
|
+
*
|
|
43
|
+
* @param externalScripts - External scripts from the component
|
|
44
|
+
* @returns Promise that resolves when all external scripts are loaded
|
|
45
|
+
*/
|
|
46
|
+
export declare function loadPlainExternalScripts(externalScripts: ExternalScriptElement[]): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Loads external stylesheets (<link rel="stylesheet">) into the component.
|
|
49
|
+
* For Shadow DOM components, fetches CSS content and injects directly into shadow root.
|
|
50
|
+
* For light DOM components, adds <link> to document head.
|
|
51
|
+
*
|
|
52
|
+
* @param externalStyles - External stylesheets from the component
|
|
53
|
+
* @param root - The component's root (shadow root or element itself)
|
|
54
|
+
* @param useShadowDOM - Whether the component uses Shadow DOM
|
|
55
|
+
* @returns Promise that resolves when all stylesheets are loaded
|
|
56
|
+
*/
|
|
57
|
+
export declare function loadExternalStyles(externalStyles: Array<{
|
|
58
|
+
href: string;
|
|
59
|
+
rel: string;
|
|
60
|
+
}>, root?: ShadowRoot | HTMLElement, useShadowDOM?: boolean): Promise<void>;
|
|
61
|
+
/**
|
|
62
|
+
* Executes all module scripts for a component.
|
|
63
|
+
* Handles both inline and external scripts (module and non-module).
|
|
64
|
+
*
|
|
65
|
+
* @param scripts - Inline scripts from the component
|
|
66
|
+
* @param externalScripts - External scripts from the component
|
|
67
|
+
* @param componentUrl - The component's URL for resolving imports
|
|
68
|
+
* @param componentId - Unique ID for cleanup tracking
|
|
69
|
+
* @returns Promise that resolves when all modules have executed
|
|
70
|
+
*/
|
|
71
|
+
export declare function executeAllModuleScripts(scripts: ScriptElement[], externalScripts: ExternalScriptElement[], componentUrl: string, componentId?: string): Promise<Map<number, unknown>>;
|
|
72
|
+
/**
|
|
73
|
+
* Cleans up blob URLs created for a component.
|
|
74
|
+
* Call this when a component is disconnected to prevent memory leaks.
|
|
75
|
+
*
|
|
76
|
+
* @param componentId - The component's unique ID
|
|
77
|
+
*/
|
|
78
|
+
export declare function cleanupModuleScripts(componentId: string): void;
|
|
79
|
+
/**
|
|
80
|
+
* Extracts import specifiers from module code.
|
|
81
|
+
* Useful for debugging or pre-fetching dependencies.
|
|
82
|
+
*
|
|
83
|
+
* @param code - The module script content
|
|
84
|
+
* @returns Array of import specifiers found in the code
|
|
85
|
+
*/
|
|
86
|
+
export declare function extractImportSpecifiers(code: string): string[];
|
|
87
|
+
/**
|
|
88
|
+
* Executes a module script and extracts declared variables for reactive state.
|
|
89
|
+
*
|
|
90
|
+
* This is the KEY function for reactivity support in module scripts.
|
|
91
|
+
* It:
|
|
92
|
+
* 1. Resolves all imports (wrapping arrays in reactive proxies)
|
|
93
|
+
* 2. Strips import statements from the code
|
|
94
|
+
* 3. Transforms variable access to go through the reactive state object
|
|
95
|
+
* 4. Executes the remaining code in a sandbox with imports available
|
|
96
|
+
* 5. Functions read/write directly to the reactive state for full reactivity
|
|
97
|
+
*
|
|
98
|
+
* The transformation ensures that functions declared in module scripts
|
|
99
|
+
* read/write from the reactive state, not from local closure variables.
|
|
100
|
+
* This makes `let x = 0; function inc() { x++; }` work reactively.
|
|
101
|
+
*
|
|
102
|
+
* @param reactiveState - The component's reactive state object. Module script
|
|
103
|
+
* functions will read/write directly to this object.
|
|
104
|
+
* @param onStateChange - Optional callback when imported arrays are mutated.
|
|
105
|
+
* This triggers directive updates (like $for loops).
|
|
106
|
+
*/
|
|
107
|
+
export declare function executeModuleScriptWithReactivity(script: ScriptElement, componentUrl: string, componentId?: string, refs?: Map<string, HTMLElement>, reactiveState?: Record<string, unknown>, onStateChange?: () => void, hostElement?: HTMLElement): Promise<Record<string, unknown>>;
|
|
108
|
+
/**
|
|
109
|
+
* Executes all module scripts with reactivity support.
|
|
110
|
+
* Returns merged state from all module scripts.
|
|
111
|
+
* @param refs - Optional refs Map that will be populated by scanDirectives later.
|
|
112
|
+
* Functions in module scripts can capture this reference.
|
|
113
|
+
* @param reactiveState - The component's reactive state object. Module script
|
|
114
|
+
* functions will read/write directly to this object.
|
|
115
|
+
* @param onStateChange - Optional callback when imported arrays are mutated.
|
|
116
|
+
* This triggers directive updates (like $for loops).
|
|
117
|
+
*/
|
|
118
|
+
export declare function executeModuleScriptsWithReactivity(scripts: ScriptElement[], externalScripts: ExternalScriptElement[], componentUrl: string, componentId?: string, refs?: Map<string, HTMLElement>, reactiveState?: Record<string, unknown>, onStateChange?: () => void, hostElement?: HTMLElement): Promise<Record<string, unknown>>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { BindingDescriptor } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Function signature for updating a single binding with new state
|
|
4
|
+
*/
|
|
5
|
+
type UpdateBindingFn = (binding: BindingDescriptor, state: Record<string, unknown>) => void;
|
|
6
|
+
/**
|
|
7
|
+
* Wraps an array in a Proxy that intercepts mutation methods.
|
|
8
|
+
* When any mutation method is called, the onMutate callback is triggered,
|
|
9
|
+
* which updates all directives (like $for loops).
|
|
10
|
+
*
|
|
11
|
+
* Example:
|
|
12
|
+
* const items = createReactiveArray(['a', 'b'], () => console.log('changed!'));
|
|
13
|
+
* items.push('c'); // Logs: "changed!"
|
|
14
|
+
* items[0] = 'x'; // Also triggers reactivity (index assignment)
|
|
15
|
+
*
|
|
16
|
+
* @param arr - The array to make reactive
|
|
17
|
+
* @param onMutate - Callback to trigger when the array is mutated
|
|
18
|
+
* @returns A reactive proxy of the array
|
|
19
|
+
*/
|
|
20
|
+
export declare function createReactiveArray<T>(arr: T[], onMutate: () => void): T[];
|
|
21
|
+
/**
|
|
22
|
+
* Creates a reactive state object that automatically updates the DOM
|
|
23
|
+
* when properties change.
|
|
24
|
+
*
|
|
25
|
+
* How it works:
|
|
26
|
+
* 1. Wraps the initial state in a Proxy
|
|
27
|
+
* 2. When a property is set, finds all bindings that depend on it
|
|
28
|
+
* 3. Re-evaluates those bindings and updates the DOM
|
|
29
|
+
*
|
|
30
|
+
* Supports dynamically adding new state keys (e.g., from module scripts).
|
|
31
|
+
* When a new key is added, it automatically finds bindings that depend on it.
|
|
32
|
+
*
|
|
33
|
+
* Example:
|
|
34
|
+
* const state = createReactiveState({ count: 0 }, bindings, updateFn);
|
|
35
|
+
* state.count++; // Automatically updates all {count} bindings in the DOM
|
|
36
|
+
* state.name = "hello"; // New key - finds and updates {name} bindings
|
|
37
|
+
*
|
|
38
|
+
* @param initialState - Initial state values extracted from component script
|
|
39
|
+
* @param bindings - All template bindings that might depend on state
|
|
40
|
+
* @param updateBinding - Function to re-evaluate and update a single binding
|
|
41
|
+
* @param onStateChange - Optional callback when any state property changes (for directives)
|
|
42
|
+
*/
|
|
43
|
+
export declare function createReactiveState(initialState: Record<string, unknown>, bindings: BindingDescriptor[], updateBinding: UpdateBindingFn, onStateChange?: () => void): Record<string, unknown>;
|
|
44
|
+
/**
|
|
45
|
+
* Creates the update function that re-evaluates a binding and updates the DOM.
|
|
46
|
+
* This should be called once when setting up reactivity, then passed to
|
|
47
|
+
* createReactiveState.
|
|
48
|
+
*
|
|
49
|
+
* @param evaluateExpression - Function to evaluate {expression} against state
|
|
50
|
+
*/
|
|
51
|
+
export declare function createBindingUpdater(evaluateExpression: (expr: string, context: Record<string, unknown>) => unknown): UpdateBindingFn;
|
|
52
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { BindingDescriptor, ScriptElement } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Main entry point for processing component scripts.
|
|
4
|
+
*
|
|
5
|
+
* 1. Extracts all variables and functions from <script> tags
|
|
6
|
+
* 2. Applies attribute overrides (attributes take precedence over defaults)
|
|
7
|
+
* 3. Creates attribute-only state entries (for attributes without script vars)
|
|
8
|
+
* 4. Creates a reactive state that auto-updates DOM on changes
|
|
9
|
+
* 5. Binds inline event handlers (onclick, etc.) to work with reactive state
|
|
10
|
+
* 6. Evaluates and applies template bindings like {name} or {greet()}
|
|
11
|
+
*
|
|
12
|
+
* @param host - The component's root element or shadow root
|
|
13
|
+
* @param scripts - Script elements from the component
|
|
14
|
+
* @param bindings - Template bindings to connect to state
|
|
15
|
+
* @param attributeOverrides - Attributes from HTML that override script defaults
|
|
16
|
+
* @param onStateChange - Optional callback when state changes (for directive updates)
|
|
17
|
+
* @param deferBindings - If true, don't apply bindings immediately (for module script support)
|
|
18
|
+
* @param componentUrl - The absolute URL of the component (for resolving relative paths in registerComponent)
|
|
19
|
+
* @param componentId - Optional unique ID for this component instance (for event bus cleanup)
|
|
20
|
+
* @param refs - Optional refs Map (for $refs access in scripts)
|
|
21
|
+
* @param templateBindings - Variable names from template bindings (for auto-prop access in scripts)
|
|
22
|
+
* @returns The reactive state object - changes trigger automatic DOM updates
|
|
23
|
+
*/
|
|
24
|
+
export declare function loadScripts(host: HTMLElement | ShadowRoot, scripts: ScriptElement[], bindings: BindingDescriptor[], attributeOverrides?: Record<string, unknown>, onStateChange?: () => void, deferBindings?: boolean, componentUrl?: string, componentId?: string, refs?: Map<string, HTMLElement>, templateBindings?: string[]): Promise<Record<string, unknown>>;
|
|
25
|
+
/**
|
|
26
|
+
* Apply bindings after all state is ready (including module scripts).
|
|
27
|
+
* This should be called after module scripts have been executed.
|
|
28
|
+
*/
|
|
29
|
+
export declare function applyBindingsDeferred(host: HTMLElement | ShadowRoot, bindings: BindingDescriptor[], state: Record<string, unknown>): void;
|
|
30
|
+
/**
|
|
31
|
+
* Extracts function definitions from script content.
|
|
32
|
+
* These will be re-created in the event handler context with current state values.
|
|
33
|
+
*
|
|
34
|
+
* @param content - The script content to extract functions from
|
|
35
|
+
* @param skipFunctions - Function names to skip (already in state as reactive functions)
|
|
36
|
+
*/
|
|
37
|
+
export declare function extractFunctionDefinitions(content: string, skipFunctions?: string[]): string;
|
|
38
|
+
/**
|
|
39
|
+
* Finds variable declarations: let x = ..., const y = ..., var z = ...
|
|
40
|
+
* Only returns TOP-LEVEL declarations — declarations inside callbacks,
|
|
41
|
+
* arrow function bodies, and other nested scopes are intentionally skipped
|
|
42
|
+
* so they remain real local variables after script transformation.
|
|
43
|
+
*
|
|
44
|
+
* Exported so webcomponent.ts can use it for observedAttributes.
|
|
45
|
+
*/
|
|
46
|
+
export declare function extractVariableNames(content: string): string[];
|
|
47
|
+
/**
|
|
48
|
+
* Creates and returns an expression evaluator function for use by directives.
|
|
49
|
+
* This allows directives to evaluate expressions like "item.name" or "count > 5"
|
|
50
|
+
* in the context of the component's state.
|
|
51
|
+
*/
|
|
52
|
+
export declare function createExpressionEvaluator(): (expr: string, context: Record<string, unknown>) => unknown;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { LadrillosComponent } from '../types';
|
|
2
|
+
import { LazyStrategy } from './lazy';
|
|
3
|
+
/**
|
|
4
|
+
* Component registration configuration
|
|
5
|
+
*/
|
|
6
|
+
export interface ComponentConfig {
|
|
7
|
+
name: string;
|
|
8
|
+
path: string;
|
|
9
|
+
useShadowDOM?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Lazy loading configuration:
|
|
12
|
+
* - `false` (default): Load immediately
|
|
13
|
+
* - `true`: Lazy load using default strategy (visible with 100px margin)
|
|
14
|
+
* - `LazyStrategy`: Custom lazy loading strategy
|
|
15
|
+
*/
|
|
16
|
+
lazy?: boolean | LazyStrategy;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Result of a batch component registration
|
|
20
|
+
*/
|
|
21
|
+
export interface RegisterComponentsResult {
|
|
22
|
+
/** Components that registered successfully */
|
|
23
|
+
success: string[];
|
|
24
|
+
/** Components that failed with their errors */
|
|
25
|
+
failed: Array<{
|
|
26
|
+
name: string;
|
|
27
|
+
error: Error;
|
|
28
|
+
}>;
|
|
29
|
+
/** Components that were skipped (already registered) */
|
|
30
|
+
skipped: string[];
|
|
31
|
+
}
|
|
32
|
+
declare class Ladrillos {
|
|
33
|
+
components: Record<string, LadrillosComponent>;
|
|
34
|
+
constructor();
|
|
35
|
+
registerComponent(name: string, path: string, useShadowDOM?: boolean, lazy?: boolean | LazyStrategy): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Register multiple components at once with parallel fetching.
|
|
38
|
+
*
|
|
39
|
+
* Benefits over sequential registration:
|
|
40
|
+
* - Parallel network requests via Promise.allSettled
|
|
41
|
+
* - Early deduplication check (skips already registered)
|
|
42
|
+
* - Batched custom element definitions
|
|
43
|
+
* - Returns detailed results for error handling
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```js
|
|
47
|
+
* // Array syntax
|
|
48
|
+
* await ladrillos.registerComponents([
|
|
49
|
+
* { name: 'my-header', path: './header.html' },
|
|
50
|
+
* { name: 'my-footer', path: './footer.html', useShadowDOM: false }
|
|
51
|
+
* ]);
|
|
52
|
+
*
|
|
53
|
+
* // Object syntax
|
|
54
|
+
* await ladrillos.registerComponents({
|
|
55
|
+
* 'my-header': './header.html',
|
|
56
|
+
* 'my-footer': { path: './footer.html', useShadowDOM: false }
|
|
57
|
+
* });
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
registerComponents(configs: ComponentConfig[] | Record<string, string | Omit<ComponentConfig, "name">>): Promise<RegisterComponentsResult>;
|
|
61
|
+
/**
|
|
62
|
+
* Force load a lazy component programmatically.
|
|
63
|
+
* Useful for preloading components before they're visible.
|
|
64
|
+
*/
|
|
65
|
+
loadLazyComponent(name: string): Promise<LadrillosComponent | undefined>;
|
|
66
|
+
}
|
|
67
|
+
export declare const ladrillos: Ladrillos;
|
|
68
|
+
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lazy Loading Module
|
|
3
|
+
* Re-exports all lazy loading utilities
|
|
4
|
+
*/
|
|
5
|
+
export { type LazyStrategy, type LazyStrategyFactory, lazyOnIdle, lazyOnVisible, lazyOnMedia, lazyOnInteraction, lazyOnDelay, defaultLazyStrategy, } from './lazyStrategies';
|
|
6
|
+
export { initLazyLoader, registerLazyComponent, isLazyComponent, forceLoadLazyComponent, getLazyComponentTagName, } from './lazyLoader';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { LadrillosComponent } from '../../types';
|
|
2
|
+
import { LazyStrategy } from './lazyStrategies';
|
|
3
|
+
/**
|
|
4
|
+
* Initialize the lazy loading system with the components registry
|
|
5
|
+
*/
|
|
6
|
+
export declare function initLazyLoader(registry: Record<string, LadrillosComponent>): void;
|
|
7
|
+
/**
|
|
8
|
+
* Register a component for lazy loading
|
|
9
|
+
*/
|
|
10
|
+
export declare function registerLazyComponent(name: string, absolutePath: string, useShadowDOM: boolean, strategy: LazyStrategy): void;
|
|
11
|
+
/**
|
|
12
|
+
* Check if a component is registered for lazy loading
|
|
13
|
+
*/
|
|
14
|
+
export declare function isLazyComponent(name: string): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Force load a lazy component (for programmatic loading)
|
|
17
|
+
*/
|
|
18
|
+
export declare function forceLoadLazyComponent(name: string): Promise<LadrillosComponent | undefined>;
|
|
19
|
+
/**
|
|
20
|
+
* Get the real tag name for a loaded lazy component
|
|
21
|
+
*/
|
|
22
|
+
export declare function getLazyComponentTagName(name: string): string | undefined;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lazy Loading Strategies for LadrillosJS
|
|
3
|
+
*
|
|
4
|
+
* control over when lazy components are loaded.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* A lazy loading strategy function.
|
|
8
|
+
* @param load - Call this to trigger component loading
|
|
9
|
+
* @param element - The placeholder element being observed
|
|
10
|
+
* @returns Optional teardown function for cleanup
|
|
11
|
+
*/
|
|
12
|
+
export type LazyStrategy = (load: () => void, element: Element) => (() => void) | void;
|
|
13
|
+
/**
|
|
14
|
+
* Factory function that creates a LazyStrategy with options
|
|
15
|
+
*/
|
|
16
|
+
export type LazyStrategyFactory<T = undefined> = T extends undefined ? () => LazyStrategy : (options?: T) => LazyStrategy;
|
|
17
|
+
/**
|
|
18
|
+
* Load when the browser is idle.
|
|
19
|
+
* Uses requestIdleCallback with a timeout fallback.
|
|
20
|
+
*
|
|
21
|
+
* @param timeout - Max wait time in ms before forcing load (default: 10000)
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* { name: 'analytics', path: './analytics.html', lazy: lazyOnIdle(5000) }
|
|
25
|
+
*/
|
|
26
|
+
export declare const lazyOnIdle: LazyStrategyFactory<number>;
|
|
27
|
+
/**
|
|
28
|
+
* Load when element becomes visible in viewport.
|
|
29
|
+
* Uses IntersectionObserver for efficient visibility detection.
|
|
30
|
+
*
|
|
31
|
+
* @param options - IntersectionObserver options (rootMargin, threshold, etc.)
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* // Load when 100px before entering viewport
|
|
35
|
+
* { name: 'footer', path: './footer.html', lazy: lazyOnVisible({ rootMargin: '100px' }) }
|
|
36
|
+
*/
|
|
37
|
+
export declare const lazyOnVisible: LazyStrategyFactory<IntersectionObserverInit>;
|
|
38
|
+
/**
|
|
39
|
+
* Load when specified media query matches.
|
|
40
|
+
* Useful for mobile-only or desktop-only components.
|
|
41
|
+
*
|
|
42
|
+
* @param query - CSS media query string
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* { name: 'mobile-nav', path: './mobile-nav.html', lazy: lazyOnMedia('(max-width: 768px)') }
|
|
46
|
+
*/
|
|
47
|
+
export declare const lazyOnMedia: LazyStrategyFactory<string>;
|
|
48
|
+
/**
|
|
49
|
+
* Load when user interacts with the element.
|
|
50
|
+
* Replays the triggering event after component loads for seamless UX.
|
|
51
|
+
*
|
|
52
|
+
* @param events - Event type(s) to listen for (default: ['click', 'focusin'])
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* { name: 'modal', path: './modal.html', lazy: lazyOnInteraction('click') }
|
|
56
|
+
* { name: 'form', path: './form.html', lazy: lazyOnInteraction(['focus', 'click']) }
|
|
57
|
+
*/
|
|
58
|
+
export declare const lazyOnInteraction: LazyStrategyFactory<string | string[]>;
|
|
59
|
+
/**
|
|
60
|
+
* Load after a specified delay.
|
|
61
|
+
* Simple time-based loading for non-critical components.
|
|
62
|
+
*
|
|
63
|
+
* @param ms - Delay in milliseconds
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* { name: 'chat-widget', path: './chat.html', lazy: lazyOnDelay(3000) }
|
|
67
|
+
*/
|
|
68
|
+
export declare const lazyOnDelay: LazyStrategyFactory<number>;
|
|
69
|
+
/**
|
|
70
|
+
* Default lazy strategy - loads when visible with 100px root margin
|
|
71
|
+
* for smooth loading before element enters viewport
|
|
72
|
+
*/
|
|
73
|
+
export declare const defaultLazyStrategy: LazyStrategy;
|