@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/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 SchildW3rk
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# @liteforge/runtime
|
|
2
|
+
|
|
3
|
+
DOM runtime for LiteForge: components, context, lifecycle, and control flow.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @liteforge/runtime @liteforge/core
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Peer dependency: `@liteforge/core >= 0.1.0`
|
|
12
|
+
|
|
13
|
+
## Overview
|
|
14
|
+
|
|
15
|
+
`@liteforge/runtime` provides the component model, app creation, context system, and control flow primitives for LiteForge applications.
|
|
16
|
+
|
|
17
|
+
## API
|
|
18
|
+
|
|
19
|
+
### createApp
|
|
20
|
+
|
|
21
|
+
Creates and mounts a LiteForge application.
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import { createApp } from '@liteforge/runtime'
|
|
25
|
+
import { App } from './App'
|
|
26
|
+
|
|
27
|
+
const app = createApp({
|
|
28
|
+
root: '#app', // CSS selector or HTMLElement
|
|
29
|
+
router: myRouter, // Optional: router instance
|
|
30
|
+
stores: [userStore], // Optional: stores to register
|
|
31
|
+
plugins: [devtools()], // Optional: plugins
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
app.mount(App)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### createComponent
|
|
38
|
+
|
|
39
|
+
Creates a component with lifecycle hooks and async data loading.
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
import { createComponent } from '@liteforge/runtime'
|
|
43
|
+
import { signal } from '@liteforge/core'
|
|
44
|
+
|
|
45
|
+
const UserProfile = createComponent({
|
|
46
|
+
// Define props with validation
|
|
47
|
+
props: {
|
|
48
|
+
userId: { type: String, required: true },
|
|
49
|
+
showEmail: { type: Boolean, default: false }
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
// Synchronous setup (runs immediately)
|
|
53
|
+
setup({ props, use }) {
|
|
54
|
+
const isEditing = signal(false)
|
|
55
|
+
return { isEditing }
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
// Async data loading (component waits for this)
|
|
59
|
+
async load({ props, setup, use }) {
|
|
60
|
+
const api = use('api')
|
|
61
|
+
const user = await api.get(`/users/${props.userId}`)
|
|
62
|
+
return { user }
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
// Shown while load() is pending
|
|
66
|
+
placeholder: () => <div class="skeleton" />,
|
|
67
|
+
|
|
68
|
+
// Shown if load() throws
|
|
69
|
+
error: ({ error, retry }) => (
|
|
70
|
+
<div>
|
|
71
|
+
<p>Error: {error.message}</p>
|
|
72
|
+
<button onclick={retry}>Retry</button>
|
|
73
|
+
</div>
|
|
74
|
+
),
|
|
75
|
+
|
|
76
|
+
// Main render function
|
|
77
|
+
component: ({ props, data, setup }) => (
|
|
78
|
+
<div>
|
|
79
|
+
<h1>{data.user.name}</h1>
|
|
80
|
+
{() => props.showEmail && <p>{data.user.email}</p>}
|
|
81
|
+
</div>
|
|
82
|
+
),
|
|
83
|
+
|
|
84
|
+
// After DOM insertion
|
|
85
|
+
mounted({ el }) {
|
|
86
|
+
el.classList.add('fade-in')
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
// Before removal
|
|
90
|
+
destroyed() {
|
|
91
|
+
console.log('Cleanup')
|
|
92
|
+
}
|
|
93
|
+
})
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Lifecycle Order:** `setup()` → `placeholder` renders → `load()` → `component` renders → `mounted()` → `destroyed()`
|
|
97
|
+
|
|
98
|
+
### use
|
|
99
|
+
|
|
100
|
+
Access registered services, stores, and the router.
|
|
101
|
+
|
|
102
|
+
```tsx
|
|
103
|
+
import { use } from '@liteforge/runtime'
|
|
104
|
+
|
|
105
|
+
// Inside a component
|
|
106
|
+
const MyComponent = createComponent({
|
|
107
|
+
component: () => {
|
|
108
|
+
const router = use('router')
|
|
109
|
+
const userStore = use('users')
|
|
110
|
+
|
|
111
|
+
return <button onclick={() => router.navigate('/')}>Home</button>
|
|
112
|
+
}
|
|
113
|
+
})
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Control Flow
|
|
117
|
+
|
|
118
|
+
#### Show
|
|
119
|
+
|
|
120
|
+
Conditionally renders content.
|
|
121
|
+
|
|
122
|
+
```tsx
|
|
123
|
+
import { Show } from '@liteforge/runtime'
|
|
124
|
+
|
|
125
|
+
<Show when={() => isLoggedIn()} fallback={<LoginPrompt />}>
|
|
126
|
+
<Dashboard />
|
|
127
|
+
</Show>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
#### For
|
|
131
|
+
|
|
132
|
+
Renders a list of items.
|
|
133
|
+
|
|
134
|
+
```tsx
|
|
135
|
+
import { For } from '@liteforge/runtime'
|
|
136
|
+
|
|
137
|
+
<For each={() => items()} fallback={<p>No items</p>}>
|
|
138
|
+
{(item, index) => (
|
|
139
|
+
<li>{index()}: {item.name}</li>
|
|
140
|
+
)}
|
|
141
|
+
</For>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
#### Switch / Match
|
|
145
|
+
|
|
146
|
+
Renders the first matching case.
|
|
147
|
+
|
|
148
|
+
```tsx
|
|
149
|
+
import { Switch, Match } from '@liteforge/runtime'
|
|
150
|
+
|
|
151
|
+
<Switch fallback={<NotFound />}>
|
|
152
|
+
<Match when={() => status() === 'loading'}>
|
|
153
|
+
<Spinner />
|
|
154
|
+
</Match>
|
|
155
|
+
<Match when={() => status() === 'error'}>
|
|
156
|
+
<ErrorMessage />
|
|
157
|
+
</Match>
|
|
158
|
+
<Match when={() => status() === 'success'}>
|
|
159
|
+
<Content />
|
|
160
|
+
</Match>
|
|
161
|
+
</Switch>
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
#### Dynamic
|
|
165
|
+
|
|
166
|
+
Dynamically renders a component based on a signal.
|
|
167
|
+
|
|
168
|
+
```tsx
|
|
169
|
+
import { Dynamic } from '@liteforge/runtime'
|
|
170
|
+
|
|
171
|
+
const currentView = signal(HomeView)
|
|
172
|
+
|
|
173
|
+
<Dynamic component={() => currentView()} props={{ user }} />
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### h and Fragment
|
|
177
|
+
|
|
178
|
+
The JSX factory functions (used by the Vite plugin).
|
|
179
|
+
|
|
180
|
+
```tsx
|
|
181
|
+
import { h, Fragment } from '@liteforge/runtime'
|
|
182
|
+
|
|
183
|
+
// Usually not called directly — JSX compiles to h() calls
|
|
184
|
+
const element = h('div', { class: 'container' },
|
|
185
|
+
h('p', null, 'Hello')
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
// Fragment for multiple root elements
|
|
189
|
+
const items = (
|
|
190
|
+
<>
|
|
191
|
+
<li>One</li>
|
|
192
|
+
<li>Two</li>
|
|
193
|
+
</>
|
|
194
|
+
)
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Types
|
|
198
|
+
|
|
199
|
+
```ts
|
|
200
|
+
import type {
|
|
201
|
+
ComponentDefinition,
|
|
202
|
+
ComponentFactory,
|
|
203
|
+
AppConfig,
|
|
204
|
+
AppInstance,
|
|
205
|
+
Plugin,
|
|
206
|
+
ShowProps,
|
|
207
|
+
ForProps,
|
|
208
|
+
SwitchProps,
|
|
209
|
+
MatchProps,
|
|
210
|
+
DynamicProps
|
|
211
|
+
} from '@liteforge/runtime'
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## License
|
|
215
|
+
|
|
216
|
+
MIT
|
package/dist/app.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LiteForge createApp
|
|
3
|
+
*
|
|
4
|
+
* Central app bootstrap: mounts root component, initializes stores,
|
|
5
|
+
* sets up context, router, plugins, and debug utilities.
|
|
6
|
+
*/
|
|
7
|
+
import type { AppConfig, AppInstance } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Create and bootstrap a LiteForge application.
|
|
10
|
+
*
|
|
11
|
+
* This is an async function that:
|
|
12
|
+
* 1. Resolves the target element
|
|
13
|
+
* 2. Builds the app context (custom context + router + stores)
|
|
14
|
+
* 3. Runs plugin beforeInit hooks
|
|
15
|
+
* 4. Initializes stores (calls initialize() if present)
|
|
16
|
+
* 5. Starts the router (if present)
|
|
17
|
+
* 6. Mounts the root component
|
|
18
|
+
* 7. Runs plugin afterMount hooks
|
|
19
|
+
* 8. Sets up debug utilities (if debug mode)
|
|
20
|
+
* 9. Calls onReady callback
|
|
21
|
+
*
|
|
22
|
+
* @param config - Application configuration
|
|
23
|
+
* @returns Promise resolving to the app instance
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* const app = await createApp({
|
|
28
|
+
* root: App,
|
|
29
|
+
* target: '#app',
|
|
30
|
+
* router: createAppRouter(),
|
|
31
|
+
* stores: [authStore, uiStore],
|
|
32
|
+
* context: { api: createApiClient() },
|
|
33
|
+
* debug: true,
|
|
34
|
+
* });
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare function createApp(config: AppConfig): Promise<AppInstance>;
|
|
38
|
+
//# sourceMappingURL=app.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,SAAS,EACT,WAAW,EAIZ,MAAM,YAAY,CAAC;AAoBpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,SAAS,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAuPvE"}
|
package/dist/app.js
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LiteForge createApp
|
|
3
|
+
*
|
|
4
|
+
* Central app bootstrap: mounts root component, initializes stores,
|
|
5
|
+
* sets up context, router, plugins, and debug utilities.
|
|
6
|
+
*/
|
|
7
|
+
import { initAppContext, clearContext, use } from './context.js';
|
|
8
|
+
import { isComponentFactory } from './component.js';
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// createApp Implementation
|
|
11
|
+
// ============================================================================
|
|
12
|
+
/**
|
|
13
|
+
* Create and bootstrap a LiteForge application.
|
|
14
|
+
*
|
|
15
|
+
* This is an async function that:
|
|
16
|
+
* 1. Resolves the target element
|
|
17
|
+
* 2. Builds the app context (custom context + router + stores)
|
|
18
|
+
* 3. Runs plugin beforeInit hooks
|
|
19
|
+
* 4. Initializes stores (calls initialize() if present)
|
|
20
|
+
* 5. Starts the router (if present)
|
|
21
|
+
* 6. Mounts the root component
|
|
22
|
+
* 7. Runs plugin afterMount hooks
|
|
23
|
+
* 8. Sets up debug utilities (if debug mode)
|
|
24
|
+
* 9. Calls onReady callback
|
|
25
|
+
*
|
|
26
|
+
* @param config - Application configuration
|
|
27
|
+
* @returns Promise resolving to the app instance
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* const app = await createApp({
|
|
32
|
+
* root: App,
|
|
33
|
+
* target: '#app',
|
|
34
|
+
* router: createAppRouter(),
|
|
35
|
+
* stores: [authStore, uiStore],
|
|
36
|
+
* context: { api: createApiClient() },
|
|
37
|
+
* debug: true,
|
|
38
|
+
* });
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export async function createApp(config) {
|
|
42
|
+
let rootInstance = null;
|
|
43
|
+
let rootNode = null;
|
|
44
|
+
let targetElement = null;
|
|
45
|
+
let isMounted = false;
|
|
46
|
+
const appContext = {};
|
|
47
|
+
const storesMap = {};
|
|
48
|
+
// Determine debug mode (auto-detect from Vite's import.meta.env.DEV)
|
|
49
|
+
const isDebug = config.debug ??
|
|
50
|
+
(typeof globalThis !== 'undefined' &&
|
|
51
|
+
globalThis.__DEV__ === true);
|
|
52
|
+
try {
|
|
53
|
+
// ========================================
|
|
54
|
+
// 1. Resolve target element
|
|
55
|
+
// ========================================
|
|
56
|
+
if (typeof config.target === 'string') {
|
|
57
|
+
targetElement = document.querySelector(config.target);
|
|
58
|
+
if (!targetElement) {
|
|
59
|
+
throw new Error(`Target element "${config.target}" not found`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
targetElement = config.target;
|
|
64
|
+
}
|
|
65
|
+
// ========================================
|
|
66
|
+
// 2. Build app context
|
|
67
|
+
// ========================================
|
|
68
|
+
// 2a. Custom context values
|
|
69
|
+
if (config.context) {
|
|
70
|
+
Object.assign(appContext, config.context);
|
|
71
|
+
}
|
|
72
|
+
// 2b. Router
|
|
73
|
+
if (config.router) {
|
|
74
|
+
appContext.router = config.router;
|
|
75
|
+
}
|
|
76
|
+
// 2c. Stores - register under $name and with store: prefix
|
|
77
|
+
if (config.stores) {
|
|
78
|
+
for (const store of config.stores) {
|
|
79
|
+
storesMap[store.$name] = store;
|
|
80
|
+
appContext[`store:${store.$name}`] = store;
|
|
81
|
+
// Also register directly by name for convenience
|
|
82
|
+
appContext[store.$name] = store;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// 2d. Plugin provide values
|
|
86
|
+
if (config.plugins) {
|
|
87
|
+
for (const plugin of config.plugins) {
|
|
88
|
+
if (plugin.provide) {
|
|
89
|
+
Object.assign(appContext, plugin.provide);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// ========================================
|
|
94
|
+
// 3. Plugin beforeInit hooks
|
|
95
|
+
// ========================================
|
|
96
|
+
if (config.plugins) {
|
|
97
|
+
for (const plugin of config.plugins) {
|
|
98
|
+
if (plugin.beforeInit) {
|
|
99
|
+
await plugin.beforeInit({ context: appContext });
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// Initialize app-level context (makes use() work)
|
|
104
|
+
initAppContext(appContext);
|
|
105
|
+
// ========================================
|
|
106
|
+
// 4. Initialize stores
|
|
107
|
+
// ========================================
|
|
108
|
+
if (config.stores) {
|
|
109
|
+
for (const store of config.stores) {
|
|
110
|
+
if ('initialize' in store && typeof store.initialize === 'function') {
|
|
111
|
+
if (isDebug) {
|
|
112
|
+
console.log(`[LiteForge] Initializing store: ${store.$name}`);
|
|
113
|
+
}
|
|
114
|
+
await store.initialize();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// ========================================
|
|
119
|
+
// 5. Start router
|
|
120
|
+
// ========================================
|
|
121
|
+
if (config.router && 'start' in config.router && typeof config.router.start === 'function') {
|
|
122
|
+
if (isDebug) {
|
|
123
|
+
console.log('[LiteForge] Starting router...');
|
|
124
|
+
}
|
|
125
|
+
await config.router.start();
|
|
126
|
+
}
|
|
127
|
+
// ========================================
|
|
128
|
+
// 6. Mount root component
|
|
129
|
+
// ========================================
|
|
130
|
+
const rootConfig = config.root;
|
|
131
|
+
if (isComponentFactory(rootConfig)) {
|
|
132
|
+
// It's a ComponentFactory from createComponent()
|
|
133
|
+
rootInstance = rootConfig({});
|
|
134
|
+
rootInstance.mount(targetElement);
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
// It's a simple render function () => Node
|
|
138
|
+
rootNode = rootConfig();
|
|
139
|
+
targetElement.appendChild(rootNode);
|
|
140
|
+
}
|
|
141
|
+
isMounted = true;
|
|
142
|
+
// ========================================
|
|
143
|
+
// 7. Plugin afterMount hooks
|
|
144
|
+
// ========================================
|
|
145
|
+
// Create app instance first so plugins can use it
|
|
146
|
+
// Note: We build the object conditionally to satisfy exactOptionalPropertyTypes
|
|
147
|
+
const app = Object.assign({
|
|
148
|
+
unmount,
|
|
149
|
+
use: createAppUse(appContext),
|
|
150
|
+
stores: storesMap,
|
|
151
|
+
}, config.router ? { router: config.router } : {});
|
|
152
|
+
if (config.plugins) {
|
|
153
|
+
for (const plugin of config.plugins) {
|
|
154
|
+
if (plugin.afterMount) {
|
|
155
|
+
await plugin.afterMount(app);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// ========================================
|
|
160
|
+
// 8. Debug utilities
|
|
161
|
+
// ========================================
|
|
162
|
+
if (isDebug && typeof window !== 'undefined') {
|
|
163
|
+
const debugUtils = {
|
|
164
|
+
router: config.router,
|
|
165
|
+
stores: storesMap,
|
|
166
|
+
snapshot: () => {
|
|
167
|
+
const result = {};
|
|
168
|
+
for (const [name, store] of Object.entries(storesMap)) {
|
|
169
|
+
result[name] = store.$snapshot();
|
|
170
|
+
}
|
|
171
|
+
return result;
|
|
172
|
+
},
|
|
173
|
+
unmount: () => app.unmount(),
|
|
174
|
+
context: appContext,
|
|
175
|
+
};
|
|
176
|
+
Object.defineProperty(window, '$lf', {
|
|
177
|
+
value: debugUtils,
|
|
178
|
+
configurable: true,
|
|
179
|
+
writable: false,
|
|
180
|
+
});
|
|
181
|
+
console.log('='.repeat(50));
|
|
182
|
+
console.log('[LiteForge] Application started in debug mode');
|
|
183
|
+
console.log(' $lf.stores — Store instances');
|
|
184
|
+
console.log(' $lf.router — Router instance');
|
|
185
|
+
console.log(' $lf.snapshot()— Full state snapshot');
|
|
186
|
+
console.log(' $lf.context — App context');
|
|
187
|
+
console.log(' $lf.unmount() — Unmount app');
|
|
188
|
+
console.log('='.repeat(50));
|
|
189
|
+
}
|
|
190
|
+
// ========================================
|
|
191
|
+
// 9. onReady callback
|
|
192
|
+
// ========================================
|
|
193
|
+
if (config.onReady) {
|
|
194
|
+
config.onReady(app);
|
|
195
|
+
}
|
|
196
|
+
return app;
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
// Handle bootstrap errors
|
|
200
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
201
|
+
if (config.onError) {
|
|
202
|
+
config.onError(err);
|
|
203
|
+
}
|
|
204
|
+
// Re-throw so the promise rejects
|
|
205
|
+
throw err;
|
|
206
|
+
}
|
|
207
|
+
// ========================================
|
|
208
|
+
// Internal Functions
|
|
209
|
+
// ========================================
|
|
210
|
+
function unmount() {
|
|
211
|
+
if (!isMounted)
|
|
212
|
+
return;
|
|
213
|
+
// Plugin beforeUnmount hooks
|
|
214
|
+
if (config.plugins) {
|
|
215
|
+
for (const plugin of config.plugins) {
|
|
216
|
+
if (plugin.beforeUnmount) {
|
|
217
|
+
const appForPlugin = Object.assign({
|
|
218
|
+
unmount,
|
|
219
|
+
use: createAppUse(appContext),
|
|
220
|
+
stores: storesMap,
|
|
221
|
+
}, config.router ? { router: config.router } : {});
|
|
222
|
+
plugin.beforeUnmount(appForPlugin);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
// Unmount root component
|
|
227
|
+
if (rootInstance) {
|
|
228
|
+
rootInstance.unmount();
|
|
229
|
+
rootInstance = null;
|
|
230
|
+
}
|
|
231
|
+
// Remove simple render function node
|
|
232
|
+
if (rootNode && rootNode.parentNode) {
|
|
233
|
+
rootNode.parentNode.removeChild(rootNode);
|
|
234
|
+
rootNode = null;
|
|
235
|
+
}
|
|
236
|
+
// Clear target element
|
|
237
|
+
if (targetElement) {
|
|
238
|
+
targetElement.innerHTML = '';
|
|
239
|
+
}
|
|
240
|
+
// Stop router
|
|
241
|
+
if (config.router && 'stop' in config.router && typeof config.router.stop === 'function') {
|
|
242
|
+
config.router.stop();
|
|
243
|
+
}
|
|
244
|
+
// Remove debug utilities from window
|
|
245
|
+
if (typeof window !== 'undefined' && '$lf' in window) {
|
|
246
|
+
delete window.$lf;
|
|
247
|
+
}
|
|
248
|
+
// Clear context
|
|
249
|
+
clearContext();
|
|
250
|
+
isMounted = false;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Create a bound use() function for the app instance.
|
|
255
|
+
* This allows accessing context from outside components.
|
|
256
|
+
*/
|
|
257
|
+
function createAppUse(appContext) {
|
|
258
|
+
return function appUse(key) {
|
|
259
|
+
if (key in appContext) {
|
|
260
|
+
return appContext[key];
|
|
261
|
+
}
|
|
262
|
+
// Fall back to global use() which checks the context stack
|
|
263
|
+
return use(key);
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
//# sourceMappingURL=app.js.map
|
package/dist/app.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LiteForge createComponent
|
|
3
|
+
*
|
|
4
|
+
* The central factory for creating reactive components with full lifecycle support.
|
|
5
|
+
*
|
|
6
|
+
* Lifecycle Flow:
|
|
7
|
+
* 1. setup() - Synchronous, create local signals
|
|
8
|
+
* 2. placeholder - Shown immediately (if load exists)
|
|
9
|
+
* 3. load() - Async data fetching
|
|
10
|
+
* 4. component() - Render (only when load resolved)
|
|
11
|
+
* 5. mounted() - After DOM insertion
|
|
12
|
+
* 6. destroyed() - On unmount
|
|
13
|
+
*/
|
|
14
|
+
import type { ComponentDefinition, ComponentFactory, PropDefinition, InputPropsFromSchema, Simplify } from './types.js';
|
|
15
|
+
/**
|
|
16
|
+
* Create a component factory from a component definition.
|
|
17
|
+
*
|
|
18
|
+
* @param definition - The component definition object
|
|
19
|
+
* @returns A component factory function
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* const MyComponent = createComponent({
|
|
24
|
+
* props: { name: { type: String, required: true } },
|
|
25
|
+
* setup({ props }) {
|
|
26
|
+
* const count = signal(0);
|
|
27
|
+
* return { count };
|
|
28
|
+
* },
|
|
29
|
+
* component({ props, setup }) {
|
|
30
|
+
* return <div>Hello {props.name}, count: {setup.count()}</div>;
|
|
31
|
+
* },
|
|
32
|
+
* });
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export declare function createComponent<Schema extends Record<string, PropDefinition<unknown>>, P extends {
|
|
36
|
+
[K in keyof Schema]: Schema[K] extends PropDefinition<infer T> ? T : never;
|
|
37
|
+
}, D = undefined, S = undefined>(definition: ComponentDefinition<P, D, S> & {
|
|
38
|
+
props: Schema;
|
|
39
|
+
}): ComponentFactory<P, Simplify<InputPropsFromSchema<Schema, P>>>;
|
|
40
|
+
export declare function createComponent<P extends Record<string, unknown> = Record<string, unknown>, D = undefined, S = undefined>(definition: ComponentDefinition<P, D, S>): ComponentFactory<P, P>;
|
|
41
|
+
/**
|
|
42
|
+
* Check if a value is a LiteForge component factory.
|
|
43
|
+
*/
|
|
44
|
+
export declare function isComponentFactory(value: unknown): value is ComponentFactory<Record<string, unknown>>;
|
|
45
|
+
//# sourceMappingURL=component.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../src/component.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAQH,OAAO,KAAK,EACV,mBAAmB,EACnB,gBAAgB,EAEhB,cAAc,EACd,oBAAoB,EACpB,QAAQ,EACT,MAAM,YAAY,CAAC;AAuBpB;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,wBAAgB,eAAe,CAC7B,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC,EACtD,CAAC,SAAS;KAAG,CAAC,IAAI,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,SAAS,cAAc,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK;CAAE,EACxF,CAAC,GAAG,SAAS,EACb,CAAC,GAAG,SAAS,EAEb,UAAU,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAC3D,gBAAgB,CAAC,CAAC,EAAE,QAAQ,CAAC,oBAAoB,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AAGlE,wBAAgB,eAAe,CAC7B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3D,CAAC,GAAG,SAAS,EACb,CAAC,GAAG,SAAS,EACb,UAAU,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAkTpE;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,gBAAgB,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAKrG"}
|