@liteforge/runtime 0.1.0
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 +216 -0
- package/dist/app.d.ts +38 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +266 -0
- package/dist/app.js.map +1 -0
- package/dist/component.d.ts +45 -0
- package/dist/component.d.ts.map +1 -0
- package/dist/component.js +295 -0
- package/dist/component.js.map +1 -0
- package/dist/context.d.ts +66 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +121 -0
- package/dist/context.js.map +1 -0
- package/dist/control-flow.d.ts +119 -0
- package/dist/control-flow.d.ts.map +1 -0
- package/dist/control-flow.js +452 -0
- package/dist/control-flow.js.map +1 -0
- package/dist/h.d.ts +53 -0
- package/dist/h.d.ts.map +1 -0
- package/dist/h.js +282 -0
- package/dist/h.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/template.d.ts +65 -0
- package/dist/template.d.ts.map +1 -0
- package/dist/template.js +237 -0
- package/dist/template.js.map +1 -0
- package/dist/types.d.ts +434 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/package.json +61 -0
package/dist/h.js
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LiteForge h() Function
|
|
3
|
+
*
|
|
4
|
+
* The hyperscript function that creates DOM elements from JSX.
|
|
5
|
+
* Handles both HTML elements and components, with support for
|
|
6
|
+
* reactive props and children via getter functions.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* // HTML element
|
|
11
|
+
* h('div', { class: 'container' }, 'Hello')
|
|
12
|
+
*
|
|
13
|
+
* // Reactive prop
|
|
14
|
+
* h('div', { class: () => theme() }, 'Text')
|
|
15
|
+
*
|
|
16
|
+
* // Component
|
|
17
|
+
* h(MyComponent, { name: 'John' })
|
|
18
|
+
*
|
|
19
|
+
* // Fragment
|
|
20
|
+
* h(Fragment, null, h('div', null, 'A'), h('div', null, 'B'))
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
import { effect } from '@liteforge/core';
|
|
24
|
+
import { isComponentFactory } from './component.js';
|
|
25
|
+
// =============================================================================
|
|
26
|
+
// Fragment Symbol
|
|
27
|
+
// =============================================================================
|
|
28
|
+
/**
|
|
29
|
+
* Fragment represents a list of children without a wrapper element.
|
|
30
|
+
* Use with h(Fragment, null, ...children) or JSX <>...</>
|
|
31
|
+
*/
|
|
32
|
+
export const Fragment = Symbol.for('liteforge.fragment');
|
|
33
|
+
// =============================================================================
|
|
34
|
+
// Main h() Function
|
|
35
|
+
// =============================================================================
|
|
36
|
+
/**
|
|
37
|
+
* Create a DOM node from JSX-like arguments.
|
|
38
|
+
*
|
|
39
|
+
* @param tag - Element name, Component, or Fragment
|
|
40
|
+
* @param props - Props object or null
|
|
41
|
+
* @param children - Child nodes
|
|
42
|
+
*/
|
|
43
|
+
export function h(tag, props, ...children) {
|
|
44
|
+
// Fragment: return a document fragment with children
|
|
45
|
+
if (tag === Fragment) {
|
|
46
|
+
return createFragment(children);
|
|
47
|
+
}
|
|
48
|
+
// Component function
|
|
49
|
+
if (typeof tag === 'function') {
|
|
50
|
+
return createComponentNode(tag, props, children);
|
|
51
|
+
}
|
|
52
|
+
// HTML element
|
|
53
|
+
return createElement(tag, props, children);
|
|
54
|
+
}
|
|
55
|
+
// =============================================================================
|
|
56
|
+
// Fragment Creation
|
|
57
|
+
// =============================================================================
|
|
58
|
+
/**
|
|
59
|
+
* Create a DocumentFragment from children
|
|
60
|
+
*/
|
|
61
|
+
function createFragment(children) {
|
|
62
|
+
const fragment = document.createDocumentFragment();
|
|
63
|
+
appendChildren(fragment, children);
|
|
64
|
+
return fragment;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Create a node from a component (Factory, RenderFunction, or simple function)
|
|
68
|
+
*/
|
|
69
|
+
function createComponentNode(component, props, children) {
|
|
70
|
+
// Resolve props - for components, we pass props as-is (getters stay as getters)
|
|
71
|
+
// The component is responsible for handling reactivity
|
|
72
|
+
const resolvedProps = props ?? {};
|
|
73
|
+
// Add children to props if provided
|
|
74
|
+
if (children.length > 0) {
|
|
75
|
+
resolvedProps.children = children.length === 1 ? children[0] : children;
|
|
76
|
+
}
|
|
77
|
+
// If it's a ComponentFactory (created with createComponent)
|
|
78
|
+
if (isComponentFactory(component)) {
|
|
79
|
+
const factory = component;
|
|
80
|
+
const instance = factory(resolvedProps);
|
|
81
|
+
// Create a container to mount into
|
|
82
|
+
const container = document.createDocumentFragment();
|
|
83
|
+
instance.mount(container);
|
|
84
|
+
// Return the mounted node
|
|
85
|
+
const node = instance.getNode();
|
|
86
|
+
return node ?? document.createComment('empty-component');
|
|
87
|
+
}
|
|
88
|
+
// If it's a render function (no props) or simple function component (with props)
|
|
89
|
+
// Try calling with props first, if it fails or returns wrong type, try without
|
|
90
|
+
const fn = component;
|
|
91
|
+
// Check function arity to determine call pattern
|
|
92
|
+
if (fn.length === 0) {
|
|
93
|
+
// RenderFunction - no arguments
|
|
94
|
+
const result = fn();
|
|
95
|
+
return result instanceof Node ? result : document.createTextNode(String(result ?? ''));
|
|
96
|
+
}
|
|
97
|
+
// SimpleFunctionComponent - takes props
|
|
98
|
+
const result = fn(resolvedProps);
|
|
99
|
+
return result instanceof Node ? result : document.createTextNode(String(result ?? ''));
|
|
100
|
+
}
|
|
101
|
+
// =============================================================================
|
|
102
|
+
// HTML Element Creation
|
|
103
|
+
// =============================================================================
|
|
104
|
+
/**
|
|
105
|
+
* Create an HTML element with props and children
|
|
106
|
+
*/
|
|
107
|
+
function createElement(tag, props, children) {
|
|
108
|
+
const element = document.createElement(tag);
|
|
109
|
+
// Apply props
|
|
110
|
+
if (props !== null) {
|
|
111
|
+
applyProps(element, props);
|
|
112
|
+
}
|
|
113
|
+
// Append children
|
|
114
|
+
appendChildren(element, children);
|
|
115
|
+
return element;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Apply props to an element, setting up effects for reactive props
|
|
119
|
+
*/
|
|
120
|
+
function applyProps(element, props) {
|
|
121
|
+
if (props === null)
|
|
122
|
+
return;
|
|
123
|
+
for (const [key, value] of Object.entries(props)) {
|
|
124
|
+
// Skip null/undefined
|
|
125
|
+
if (value === null || value === undefined) {
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
// Event handlers (onClick, onInput, etc.)
|
|
129
|
+
if (key.startsWith('on') && key.length > 2) {
|
|
130
|
+
const eventName = key.slice(2).toLowerCase();
|
|
131
|
+
if (typeof value === 'function') {
|
|
132
|
+
element.addEventListener(eventName, value);
|
|
133
|
+
}
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
// ref prop - special handling (not reactive)
|
|
137
|
+
if (key === 'ref' && typeof value === 'function') {
|
|
138
|
+
value(element);
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
// Reactive prop (function that returns value)
|
|
142
|
+
if (typeof value === 'function') {
|
|
143
|
+
const getter = value;
|
|
144
|
+
effect(() => {
|
|
145
|
+
const resolved = getter();
|
|
146
|
+
setProp(element, key, resolved);
|
|
147
|
+
});
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
// Static prop
|
|
151
|
+
setProp(element, key, value);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Set a single prop on an element
|
|
156
|
+
*/
|
|
157
|
+
function setProp(element, key, value) {
|
|
158
|
+
// Handle null/undefined - remove attribute
|
|
159
|
+
if (value === null || value === undefined) {
|
|
160
|
+
element.removeAttribute(key);
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
// Data attributes and aria attributes - always stringify (including false)
|
|
164
|
+
if (key.startsWith('data-') || key.startsWith('aria-')) {
|
|
165
|
+
element.setAttribute(key, String(value));
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
// Boolean false - remove attribute (for boolean HTML attributes like disabled)
|
|
169
|
+
if (value === false) {
|
|
170
|
+
element.removeAttribute(key);
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
// Boolean true - set empty attribute (for boolean HTML attributes)
|
|
174
|
+
if (value === true) {
|
|
175
|
+
element.setAttribute(key, '');
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
// class prop
|
|
179
|
+
if (key === 'class' || key === 'className') {
|
|
180
|
+
element.setAttribute('class', String(value));
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
// style prop (can be string or object)
|
|
184
|
+
if (key === 'style') {
|
|
185
|
+
if (typeof value === 'string') {
|
|
186
|
+
element.setAttribute('style', value);
|
|
187
|
+
}
|
|
188
|
+
else if (typeof value === 'object' && value !== null) {
|
|
189
|
+
Object.assign(element.style, value);
|
|
190
|
+
}
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
// DOM properties vs attributes
|
|
194
|
+
// For known DOM properties, set directly
|
|
195
|
+
if (key in element) {
|
|
196
|
+
try {
|
|
197
|
+
element[key] = value;
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
// Fall through to setAttribute
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
// Default: set as attribute
|
|
205
|
+
element.setAttribute(key, String(value));
|
|
206
|
+
}
|
|
207
|
+
// =============================================================================
|
|
208
|
+
// Children Handling
|
|
209
|
+
// =============================================================================
|
|
210
|
+
/**
|
|
211
|
+
* Append children to a parent node
|
|
212
|
+
*/
|
|
213
|
+
function appendChildren(parent, children) {
|
|
214
|
+
for (const child of children) {
|
|
215
|
+
appendChild(parent, child);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Append a single child to a parent node
|
|
220
|
+
*/
|
|
221
|
+
function appendChild(parent, child) {
|
|
222
|
+
// Skip null/undefined/false
|
|
223
|
+
if (child === null || child === undefined || child === false || child === true) {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
// Array of children
|
|
227
|
+
if (Array.isArray(child)) {
|
|
228
|
+
appendChildren(parent, child);
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
// Node
|
|
232
|
+
if (child instanceof Node) {
|
|
233
|
+
parent.appendChild(child);
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
// Reactive child (function)
|
|
237
|
+
if (typeof child === 'function') {
|
|
238
|
+
// Create a placeholder and marker for reactive content
|
|
239
|
+
const marker = document.createComment('reactive');
|
|
240
|
+
parent.appendChild(marker);
|
|
241
|
+
let currentNode = null;
|
|
242
|
+
effect(() => {
|
|
243
|
+
const value = child();
|
|
244
|
+
const newNode = resolveChildToNode(value);
|
|
245
|
+
// Replace existing node
|
|
246
|
+
if (currentNode !== null && currentNode.parentNode) {
|
|
247
|
+
if (newNode !== null) {
|
|
248
|
+
currentNode.parentNode.replaceChild(newNode, currentNode);
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
currentNode.parentNode.removeChild(currentNode);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
else if (newNode !== null && marker.parentNode) {
|
|
255
|
+
marker.parentNode.insertBefore(newNode, marker.nextSibling);
|
|
256
|
+
}
|
|
257
|
+
currentNode = newNode;
|
|
258
|
+
});
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
// String/number - create text node
|
|
262
|
+
parent.appendChild(document.createTextNode(String(child)));
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Resolve a child value to a Node
|
|
266
|
+
*/
|
|
267
|
+
function resolveChildToNode(child) {
|
|
268
|
+
if (child === null || child === undefined || child === false || child === true) {
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
if (child instanceof Node) {
|
|
272
|
+
return child;
|
|
273
|
+
}
|
|
274
|
+
if (Array.isArray(child)) {
|
|
275
|
+
const fragment = document.createDocumentFragment();
|
|
276
|
+
appendChildren(fragment, child);
|
|
277
|
+
return fragment;
|
|
278
|
+
}
|
|
279
|
+
// String/number
|
|
280
|
+
return document.createTextNode(String(child));
|
|
281
|
+
}
|
|
282
|
+
//# sourceMappingURL=h.js.map
|
package/dist/h.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"h.js","sourceRoot":"","sources":["../src/h.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @liteforge/runtime
|
|
3
|
+
*
|
|
4
|
+
* DOM runtime for LiteForge: components, context, lifecycle, and control flow.
|
|
5
|
+
*/
|
|
6
|
+
export type { PropType, PropDefinition, PropsSchema, ExtractProps, ComponentDefinition, ComponentFactory, ComponentInstance, UseFn, ContextValues, ProviderFn, SetupArgs, LoadArgs, PlaceholderArgs, ErrorArgs, ComponentArgs, MountedArgs, DestroyedArgs, AppConfig, AppInstance, Plugin, AnyStore, RouterLike, Falsy, ShowProps, ForProps, SwitchProps, MatchCase, MatchProps, DynamicProps, Child, FunctionComponent, HTMLAttributes, } from './types.js';
|
|
7
|
+
export { use, hasContext } from './context.js';
|
|
8
|
+
export { pushContext, popContext, initAppContext, clearContext, getContextDepth, withContext, createBoundUse, } from './context.js';
|
|
9
|
+
export { createComponent, isComponentFactory } from './component.js';
|
|
10
|
+
export { createApp } from './app.js';
|
|
11
|
+
export { Show, For, Switch, Match, Dynamic } from './control-flow.js';
|
|
12
|
+
export type { ShowConfig, ForConfig, SwitchConfig, MatchConfig, MatchCase as MatchCaseInternal, DynamicConfig } from './control-flow.js';
|
|
13
|
+
export { h, Fragment } from './h.js';
|
|
14
|
+
export { _template, _insert, _setProp, _addEventListener } from './template.js';
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,YAAY,EAEV,QAAQ,EACR,cAAc,EACd,WAAW,EACX,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EAEjB,KAAK,EACL,aAAa,EACb,UAAU,EAEV,SAAS,EACT,QAAQ,EACR,eAAe,EACf,SAAS,EACT,aAAa,EACb,WAAW,EACX,aAAa,EAEb,SAAS,EACT,WAAW,EACX,MAAM,EACN,QAAQ,EACR,UAAU,EAEV,KAAK,EACL,SAAS,EACT,QAAQ,EACR,WAAW,EACX,SAAS,EACT,UAAU,EACV,YAAY,EAEZ,KAAK,EACL,iBAAiB,EACjB,cAAc,GACf,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG/C,OAAO,EACL,WAAW,EACX,UAAU,EACV,cAAc,EACd,YAAY,EACZ,eAAe,EACf,WAAW,EACX,cAAc,GACf,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAGrE,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAGrC,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACtE,YAAY,EACV,UAAU,EACV,SAAS,EACT,YAAY,EACZ,WAAW,EACX,SAAS,IAAI,iBAAiB,EAC9B,aAAa,EACd,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAGrC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @liteforge/runtime
|
|
3
|
+
*
|
|
4
|
+
* DOM runtime for LiteForge: components, context, lifecycle, and control flow.
|
|
5
|
+
*/
|
|
6
|
+
// Context
|
|
7
|
+
export { use, hasContext } from './context.js';
|
|
8
|
+
// For internal/testing use
|
|
9
|
+
export { pushContext, popContext, initAppContext, clearContext, getContextDepth, withContext, createBoundUse, } from './context.js';
|
|
10
|
+
// Component
|
|
11
|
+
export { createComponent, isComponentFactory } from './component.js';
|
|
12
|
+
// App
|
|
13
|
+
export { createApp } from './app.js';
|
|
14
|
+
// Control Flow
|
|
15
|
+
export { Show, For, Switch, Match, Dynamic } from './control-flow.js';
|
|
16
|
+
// h() function and Fragment for JSX
|
|
17
|
+
export { h, Fragment } from './h.js';
|
|
18
|
+
// Template runtime for compile-time optimizations
|
|
19
|
+
export { _template, _insert, _setProp, _addEventListener } from './template.js';
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA4CH,UAAU;AACV,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,2BAA2B;AAC3B,OAAO,EACL,WAAW,EACX,UAAU,EACV,cAAc,EACd,YAAY,EACZ,eAAe,EACf,WAAW,EACX,cAAc,GACf,MAAM,cAAc,CAAC;AAEtB,YAAY;AACZ,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAErE,MAAM;AACN,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAErC,eAAe;AACf,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAUtE,oCAAoC;AACpC,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAErC,kDAAkD;AAClD,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template Runtime
|
|
3
|
+
*
|
|
4
|
+
* Provides runtime support for template extraction optimization.
|
|
5
|
+
* Templates are cloneable HTML structures that avoid repeated createElement calls.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Creates a template factory from an HTML string.
|
|
9
|
+
* The template is parsed once and cloned on each call.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* const _tmpl = _template('<div class="card"><h1></h1><p>Static text</p></div>');
|
|
14
|
+
*
|
|
15
|
+
* function Card() {
|
|
16
|
+
* const el = _tmpl(); // Clone the template
|
|
17
|
+
* // ... add dynamic content
|
|
18
|
+
* return el;
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare function _template(html: string): () => Node;
|
|
23
|
+
/**
|
|
24
|
+
* Value types that can be inserted into a template slot
|
|
25
|
+
*/
|
|
26
|
+
type InsertValue = string | number | boolean | null | undefined | Node | InsertValue[];
|
|
27
|
+
/**
|
|
28
|
+
* Inserts dynamic content into a template slot.
|
|
29
|
+
* Supports: strings, numbers, nodes, arrays, and reactive getters.
|
|
30
|
+
*
|
|
31
|
+
* If value is a function, it creates an effect to reactively update the content.
|
|
32
|
+
*
|
|
33
|
+
* @param parent - The parent node to insert into
|
|
34
|
+
* @param value - The value to insert (or a getter function)
|
|
35
|
+
* @param marker - Optional marker node for positioning (inserts before marker)
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* const el = _tmpl();
|
|
40
|
+
* const h2 = el.firstChild;
|
|
41
|
+
*
|
|
42
|
+
* // Static insert
|
|
43
|
+
* _insert(h2, 'Hello');
|
|
44
|
+
*
|
|
45
|
+
* // Reactive insert
|
|
46
|
+
* _insert(h2, () => name());
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare function _insert(parent: Node, value: (() => InsertValue) | InsertValue, marker?: Node): void;
|
|
50
|
+
/**
|
|
51
|
+
* Sets a property on an element, handling special cases.
|
|
52
|
+
* Used for dynamic props that were excluded from the template.
|
|
53
|
+
*
|
|
54
|
+
* @param el - The element to set the property on
|
|
55
|
+
* @param name - Property name
|
|
56
|
+
* @param value - Property value (or getter function for reactive)
|
|
57
|
+
*/
|
|
58
|
+
export declare function _setProp(el: Element, name: string, value: unknown): void;
|
|
59
|
+
/**
|
|
60
|
+
* Adds an event listener to an element.
|
|
61
|
+
* Simple wrapper for consistency in generated code.
|
|
62
|
+
*/
|
|
63
|
+
export declare function _addEventListener(el: Element, event: string, handler: EventListener): void;
|
|
64
|
+
export {};
|
|
65
|
+
//# sourceMappingURL=template.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../src/template.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,IAAI,CAkBlD;AAMD;;GAEG;AACH,KAAK,WAAW,GACZ,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,SAAS,GACT,IAAI,GACJ,WAAW,EAAE,CAAC;AAElB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,OAAO,CACrB,MAAM,EAAE,IAAI,EACZ,KAAK,EAAE,CAAC,MAAM,WAAW,CAAC,GAAG,WAAW,EACxC,MAAM,CAAC,EAAE,IAAI,GACZ,IAAI,CAmFN;AAMD;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CACtB,EAAE,EAAE,OAAO,EACX,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,GACb,IAAI,CAYN;AAwED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,EAAE,EAAE,OAAO,EACX,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,aAAa,GACrB,IAAI,CAEN"}
|
package/dist/template.js
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template Runtime
|
|
3
|
+
*
|
|
4
|
+
* Provides runtime support for template extraction optimization.
|
|
5
|
+
* Templates are cloneable HTML structures that avoid repeated createElement calls.
|
|
6
|
+
*/
|
|
7
|
+
import { effect } from '@liteforge/core';
|
|
8
|
+
// =============================================================================
|
|
9
|
+
// _template()
|
|
10
|
+
// =============================================================================
|
|
11
|
+
/**
|
|
12
|
+
* Creates a template factory from an HTML string.
|
|
13
|
+
* The template is parsed once and cloned on each call.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* const _tmpl = _template('<div class="card"><h1></h1><p>Static text</p></div>');
|
|
18
|
+
*
|
|
19
|
+
* function Card() {
|
|
20
|
+
* const el = _tmpl(); // Clone the template
|
|
21
|
+
* // ... add dynamic content
|
|
22
|
+
* return el;
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export function _template(html) {
|
|
27
|
+
let tpl = null;
|
|
28
|
+
return () => {
|
|
29
|
+
if (!tpl) {
|
|
30
|
+
tpl = document.createElement('template');
|
|
31
|
+
tpl.innerHTML = html;
|
|
32
|
+
}
|
|
33
|
+
// Get the first child of the content (the root element)
|
|
34
|
+
const content = tpl.content.firstChild;
|
|
35
|
+
if (!content) {
|
|
36
|
+
throw new Error('Template is empty');
|
|
37
|
+
}
|
|
38
|
+
// Deep clone the entire subtree
|
|
39
|
+
return content.cloneNode(true);
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Inserts dynamic content into a template slot.
|
|
44
|
+
* Supports: strings, numbers, nodes, arrays, and reactive getters.
|
|
45
|
+
*
|
|
46
|
+
* If value is a function, it creates an effect to reactively update the content.
|
|
47
|
+
*
|
|
48
|
+
* @param parent - The parent node to insert into
|
|
49
|
+
* @param value - The value to insert (or a getter function)
|
|
50
|
+
* @param marker - Optional marker node for positioning (inserts before marker)
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```ts
|
|
54
|
+
* const el = _tmpl();
|
|
55
|
+
* const h2 = el.firstChild;
|
|
56
|
+
*
|
|
57
|
+
* // Static insert
|
|
58
|
+
* _insert(h2, 'Hello');
|
|
59
|
+
*
|
|
60
|
+
* // Reactive insert
|
|
61
|
+
* _insert(h2, () => name());
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export function _insert(parent, value, marker) {
|
|
65
|
+
// Track current nodes for cleanup on reactive updates
|
|
66
|
+
let currentNodes = [];
|
|
67
|
+
/**
|
|
68
|
+
* Remove all currently inserted nodes
|
|
69
|
+
*/
|
|
70
|
+
function cleanup() {
|
|
71
|
+
for (const node of currentNodes) {
|
|
72
|
+
if (node.parentNode) {
|
|
73
|
+
node.parentNode.removeChild(node);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
currentNodes = [];
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Insert a value into the DOM
|
|
80
|
+
*/
|
|
81
|
+
function insertValue(val) {
|
|
82
|
+
cleanup();
|
|
83
|
+
if (val === null || val === undefined || val === false || val === true) {
|
|
84
|
+
// Skip null, undefined, and booleans
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (Array.isArray(val)) {
|
|
88
|
+
// Insert array items
|
|
89
|
+
for (const item of val) {
|
|
90
|
+
insertSingle(item);
|
|
91
|
+
}
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
insertSingle(val);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Insert a single non-array value
|
|
98
|
+
*/
|
|
99
|
+
function insertSingle(val) {
|
|
100
|
+
if (val === null || val === undefined || val === false || val === true) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if (Array.isArray(val)) {
|
|
104
|
+
for (const item of val) {
|
|
105
|
+
insertSingle(item);
|
|
106
|
+
}
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
let node;
|
|
110
|
+
if (val instanceof Node) {
|
|
111
|
+
node = val;
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
// Convert to text node
|
|
115
|
+
node = document.createTextNode(String(val));
|
|
116
|
+
}
|
|
117
|
+
// Insert the node
|
|
118
|
+
if (marker) {
|
|
119
|
+
parent.insertBefore(node, marker);
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
parent.appendChild(node);
|
|
123
|
+
}
|
|
124
|
+
currentNodes.push(node);
|
|
125
|
+
}
|
|
126
|
+
// Check if value is a getter function (reactive)
|
|
127
|
+
if (typeof value === 'function') {
|
|
128
|
+
// Create effect for reactive updates
|
|
129
|
+
effect(() => {
|
|
130
|
+
const val = value();
|
|
131
|
+
insertValue(val);
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
// Static insert
|
|
136
|
+
insertValue(value);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// =============================================================================
|
|
140
|
+
// _setProp()
|
|
141
|
+
// =============================================================================
|
|
142
|
+
/**
|
|
143
|
+
* Sets a property on an element, handling special cases.
|
|
144
|
+
* Used for dynamic props that were excluded from the template.
|
|
145
|
+
*
|
|
146
|
+
* @param el - The element to set the property on
|
|
147
|
+
* @param name - Property name
|
|
148
|
+
* @param value - Property value (or getter function for reactive)
|
|
149
|
+
*/
|
|
150
|
+
export function _setProp(el, name, value) {
|
|
151
|
+
// Handle reactive values
|
|
152
|
+
if (typeof value === 'function' && !name.startsWith('on')) {
|
|
153
|
+
// It's a getter - create effect
|
|
154
|
+
effect(() => {
|
|
155
|
+
const val = value();
|
|
156
|
+
applyProp(el, name, val);
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
// Static value or event handler
|
|
161
|
+
applyProp(el, name, value);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Apply a property value to an element
|
|
166
|
+
*/
|
|
167
|
+
function applyProp(el, name, value) {
|
|
168
|
+
// Handle event listeners
|
|
169
|
+
if (name.startsWith('on') && name.length > 2) {
|
|
170
|
+
const eventName = name.slice(2).toLowerCase();
|
|
171
|
+
if (typeof value === 'function') {
|
|
172
|
+
el.addEventListener(eventName, value);
|
|
173
|
+
}
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
// Handle class
|
|
177
|
+
if (name === 'class' || name === 'className') {
|
|
178
|
+
if (value === null || value === undefined) {
|
|
179
|
+
el.removeAttribute('class');
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
el.className = String(value);
|
|
183
|
+
}
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
// Handle style
|
|
187
|
+
if (name === 'style') {
|
|
188
|
+
if (typeof value === 'string') {
|
|
189
|
+
el.style.cssText = value;
|
|
190
|
+
}
|
|
191
|
+
else if (typeof value === 'object' && value !== null) {
|
|
192
|
+
const style = el.style;
|
|
193
|
+
for (const [key, val] of Object.entries(value)) {
|
|
194
|
+
style.setProperty(key, String(val));
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
// Handle data-* attributes
|
|
200
|
+
if (name.startsWith('data-')) {
|
|
201
|
+
if (value === null || value === undefined) {
|
|
202
|
+
el.removeAttribute(name);
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
el.setAttribute(name, String(value));
|
|
206
|
+
}
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
// Handle boolean attributes
|
|
210
|
+
if (typeof value === 'boolean') {
|
|
211
|
+
if (value) {
|
|
212
|
+
el.setAttribute(name, '');
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
el.removeAttribute(name);
|
|
216
|
+
}
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
// Handle null/undefined - remove attribute
|
|
220
|
+
if (value === null || value === undefined) {
|
|
221
|
+
el.removeAttribute(name);
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
// Default: set as attribute
|
|
225
|
+
el.setAttribute(name, String(value));
|
|
226
|
+
}
|
|
227
|
+
// =============================================================================
|
|
228
|
+
// _addEventListener()
|
|
229
|
+
// =============================================================================
|
|
230
|
+
/**
|
|
231
|
+
* Adds an event listener to an element.
|
|
232
|
+
* Simple wrapper for consistency in generated code.
|
|
233
|
+
*/
|
|
234
|
+
export function _addEventListener(el, event, handler) {
|
|
235
|
+
el.addEventListener(event, handler);
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=template.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template.js","sourceRoot":"","sources":["../src/template.ts"],"names":[],"mappings":"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"}
|