liteforge 0.4.1 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +300 -0
- package/package.json +5 -5
package/README.md
ADDED
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
# liteforge
|
|
2
|
+
|
|
3
|
+
**Signals-based frontend framework — No Virtual DOM, JSX, zero dependencies.**
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
pnpm add liteforge
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
> Single meta-package that re-exports all `@liteforge/*` packages via sub-path exports.
|
|
10
|
+
> Use one import instead of managing 12 separate packages.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Core Principles
|
|
15
|
+
|
|
16
|
+
- **No Virtual DOM** — Fine-grained DOM updates via Signals & Effects
|
|
17
|
+
- **JSX Syntax** — Vite plugin transforms JSX to direct DOM operations at build time
|
|
18
|
+
- **Signals-based Reactivity** — Automatic dependency tracking, no manual subscriptions
|
|
19
|
+
- **Zero Runtime Dependencies** — Every package is self-contained
|
|
20
|
+
- **TypeScript-first** — Full strict mode throughout
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Quick Start
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pnpm add liteforge
|
|
28
|
+
pnpm add -D vite typescript
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**`vite.config.ts`**
|
|
32
|
+
```ts
|
|
33
|
+
import { defineConfig } from 'vite';
|
|
34
|
+
import liteforge from 'liteforge/vite-plugin';
|
|
35
|
+
|
|
36
|
+
export default defineConfig({
|
|
37
|
+
plugins: [liteforge()],
|
|
38
|
+
});
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**`src/main.tsx`**
|
|
42
|
+
```tsx
|
|
43
|
+
import { createApp } from 'liteforge';
|
|
44
|
+
import { routerPlugin } from 'liteforge/router';
|
|
45
|
+
import App from './App.js';
|
|
46
|
+
|
|
47
|
+
await createApp({ root: App, target: '#app' })
|
|
48
|
+
.use(routerPlugin({ routes }))
|
|
49
|
+
.mount();
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**`src/App.tsx`**
|
|
53
|
+
```tsx
|
|
54
|
+
import { createComponent, Show } from 'liteforge';
|
|
55
|
+
import { signal } from 'liteforge';
|
|
56
|
+
|
|
57
|
+
export const App = createComponent({
|
|
58
|
+
component() {
|
|
59
|
+
const count = signal(0);
|
|
60
|
+
return (
|
|
61
|
+
<div>
|
|
62
|
+
<h1>{() => count()}</h1>
|
|
63
|
+
<button onclick={() => count.update(n => n + 1)}>+1</button>
|
|
64
|
+
<Show when={() => count() > 5}>
|
|
65
|
+
<p>Over 5!</p>
|
|
66
|
+
</Show>
|
|
67
|
+
</div>
|
|
68
|
+
);
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Sub-path Imports
|
|
76
|
+
|
|
77
|
+
| Import | Contents |
|
|
78
|
+
|--------|----------|
|
|
79
|
+
| `liteforge` | `@liteforge/core` + `@liteforge/runtime` — signals, effects, components, JSX |
|
|
80
|
+
| `liteforge/router` | SPA router, guards, middleware, lazy routes, nested routes |
|
|
81
|
+
| `liteforge/store` | Global state management with time-travel |
|
|
82
|
+
| `liteforge/query` | Data fetching, caching, mutations |
|
|
83
|
+
| `liteforge/client` | HTTP client with interceptors, middleware, query integration |
|
|
84
|
+
| `liteforge/form` | Form management with Zod validation |
|
|
85
|
+
| `liteforge/table` | Data tables — sort, filter, pagination, selection |
|
|
86
|
+
| `liteforge/calendar` | Full scheduling calendar — 4 views, drag & drop, resources |
|
|
87
|
+
| `liteforge/modal` | Signal-based modal system with focus trap |
|
|
88
|
+
| `liteforge/devtools` | Debug panel — signal inspector, store explorer, time-travel |
|
|
89
|
+
| `liteforge/vite-plugin` | Vite plugin for JSX transform & HMR |
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Packages
|
|
94
|
+
|
|
95
|
+
| Package | Version | Description |
|
|
96
|
+
|---------|---------|-------------|
|
|
97
|
+
| `@liteforge/core` | 0.1.0 | `signal`, `computed`, `effect`, `batch`, `onCleanup` |
|
|
98
|
+
| `@liteforge/runtime` | 0.4.1 | `createComponent`, `createApp`, `Show`, `For`, `Switch`, plugin system |
|
|
99
|
+
| `@liteforge/router` | 0.3.0 | Router with guards, middleware, nested routes, lazy loading |
|
|
100
|
+
| `@liteforge/store` | 0.1.0 | `defineStore`, store registry, plugins, time-travel |
|
|
101
|
+
| `@liteforge/query` | 0.1.0 | `createQuery`, `createMutation`, query cache |
|
|
102
|
+
| `@liteforge/client` | 0.1.0 | `createClient`, `createResource`, interceptors |
|
|
103
|
+
| `@liteforge/form` | 0.1.0 | `createForm` with Zod, nested & array fields |
|
|
104
|
+
| `@liteforge/table` | 0.1.0 | `createTable` with sort, filter, pagination, selection |
|
|
105
|
+
| `@liteforge/calendar` | 0.1.0 | `createCalendar` — Day/Week/Month/Agenda, drag & drop |
|
|
106
|
+
| `@liteforge/modal` | 0.1.0 | `createModal`, `confirm`, `alert`, `prompt` presets |
|
|
107
|
+
| `@liteforge/devtools` | 0.1.0 | 5-tab debug panel with signal & store inspection |
|
|
108
|
+
| `@liteforge/vite-plugin` | 0.1.0 | JSX transform, template extraction, HMR |
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Reactivity
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
import { signal, computed, effect, batch } from 'liteforge';
|
|
116
|
+
|
|
117
|
+
const count = signal(0);
|
|
118
|
+
const double = computed(() => count() * 2);
|
|
119
|
+
|
|
120
|
+
effect(() => {
|
|
121
|
+
console.log(double()); // auto-tracks dependencies
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
count.set(5); // → logs 10
|
|
125
|
+
count.update(n => n + 1); // → logs 12
|
|
126
|
+
|
|
127
|
+
batch(() => { // deferred notifications
|
|
128
|
+
count.set(1);
|
|
129
|
+
});
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Components
|
|
133
|
+
|
|
134
|
+
```tsx
|
|
135
|
+
import { createComponent, Show, For } from 'liteforge';
|
|
136
|
+
import { signal } from 'liteforge';
|
|
137
|
+
|
|
138
|
+
export const UserList = createComponent({
|
|
139
|
+
async load() {
|
|
140
|
+
const users = await fetch('/api/users').then(r => r.json());
|
|
141
|
+
return { users };
|
|
142
|
+
},
|
|
143
|
+
placeholder: () => <div class="skeleton" />,
|
|
144
|
+
component({ data }) {
|
|
145
|
+
return (
|
|
146
|
+
<ul>
|
|
147
|
+
<For each={() => data.users}>
|
|
148
|
+
{user => <li>{user.name}</li>}
|
|
149
|
+
</For>
|
|
150
|
+
</ul>
|
|
151
|
+
);
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Router
|
|
157
|
+
|
|
158
|
+
```ts
|
|
159
|
+
import { createRouter, createBrowserHistory, defineGuard } from 'liteforge/router';
|
|
160
|
+
|
|
161
|
+
const auth = defineGuard(async ({ to }) => {
|
|
162
|
+
if (!isLoggedIn()) return '/login';
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
const router = createRouter({
|
|
166
|
+
history: createBrowserHistory(),
|
|
167
|
+
routes: [
|
|
168
|
+
{ path: '/', component: Home },
|
|
169
|
+
{ path: '/login', component: Login },
|
|
170
|
+
{ path: '/dashboard', component: Dashboard, guard: auth,
|
|
171
|
+
children: [
|
|
172
|
+
{ path: '/', component: Overview },
|
|
173
|
+
{ path: '/users', component: Users },
|
|
174
|
+
],
|
|
175
|
+
},
|
|
176
|
+
],
|
|
177
|
+
});
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Store
|
|
181
|
+
|
|
182
|
+
```ts
|
|
183
|
+
import { defineStore } from 'liteforge/store';
|
|
184
|
+
|
|
185
|
+
const userStore = defineStore('users', {
|
|
186
|
+
state: { list: [], loading: false },
|
|
187
|
+
getters: state => ({
|
|
188
|
+
count: () => state.list().length,
|
|
189
|
+
}),
|
|
190
|
+
actions: state => ({
|
|
191
|
+
async fetch() {
|
|
192
|
+
state.loading.set(true);
|
|
193
|
+
state.list.set(await api.getUsers());
|
|
194
|
+
state.loading.set(false);
|
|
195
|
+
},
|
|
196
|
+
}),
|
|
197
|
+
});
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Query
|
|
201
|
+
|
|
202
|
+
```ts
|
|
203
|
+
import { createQuery, createMutation } from 'liteforge/query';
|
|
204
|
+
|
|
205
|
+
const users = createQuery({
|
|
206
|
+
key: 'users',
|
|
207
|
+
fn: () => fetch('/api/users').then(r => r.json()),
|
|
208
|
+
staleTime: 5 * 60 * 1000,
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
users.data() // Signal: User[] | undefined
|
|
212
|
+
users.isLoading() // Signal: boolean
|
|
213
|
+
|
|
214
|
+
const addUser = createMutation({
|
|
215
|
+
fn: data => api.createUser(data),
|
|
216
|
+
invalidate: ['users'],
|
|
217
|
+
});
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## Form
|
|
221
|
+
|
|
222
|
+
```ts
|
|
223
|
+
import { createForm } from 'liteforge/form';
|
|
224
|
+
import { z } from 'zod';
|
|
225
|
+
|
|
226
|
+
const form = createForm({
|
|
227
|
+
schema: z.object({
|
|
228
|
+
name: z.string().min(2),
|
|
229
|
+
email: z.string().email(),
|
|
230
|
+
}),
|
|
231
|
+
initial: { name: '', email: '' },
|
|
232
|
+
onSubmit: async values => { await api.save(values); },
|
|
233
|
+
validateOn: 'blur',
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
form.field('name').value() // Signal<string>
|
|
237
|
+
form.field('name').error() // Signal<string | undefined>
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Plugin System
|
|
241
|
+
|
|
242
|
+
```ts
|
|
243
|
+
import { createApp } from 'liteforge';
|
|
244
|
+
import { routerPlugin } from 'liteforge/router';
|
|
245
|
+
import { modalPlugin } from 'liteforge/modal';
|
|
246
|
+
import { queryPlugin } from 'liteforge/query';
|
|
247
|
+
import { devtoolsPlugin } from 'liteforge/devtools';
|
|
248
|
+
|
|
249
|
+
await createApp({ root: App, target: '#app' })
|
|
250
|
+
.use(routerPlugin({ routes }))
|
|
251
|
+
.use(modalPlugin())
|
|
252
|
+
.use(queryPlugin())
|
|
253
|
+
.use(devtoolsPlugin())
|
|
254
|
+
.mount();
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## JSX
|
|
260
|
+
|
|
261
|
+
LiteForge JSX compiles to direct DOM operations — no diffing, no virtual tree.
|
|
262
|
+
|
|
263
|
+
```tsx
|
|
264
|
+
// Reactive: wrap in () =>
|
|
265
|
+
<span>{() => count()}</span>
|
|
266
|
+
|
|
267
|
+
// Event handler: no wrapper needed
|
|
268
|
+
<button onclick={() => count.update(n => n + 1)}>Click</button>
|
|
269
|
+
|
|
270
|
+
// Dynamic attribute
|
|
271
|
+
<div class={() => isActive() ? 'active' : 'inactive'} />
|
|
272
|
+
|
|
273
|
+
// Static attribute
|
|
274
|
+
<div class="container" />
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
## Architecture
|
|
280
|
+
|
|
281
|
+
```
|
|
282
|
+
core ──────────────────────────────────────────────────┐
|
|
283
|
+
signal · computed · effect · batch · onCleanup │
|
|
284
|
+
│
|
|
285
|
+
runtime ────────────────────────────────────────────────┤
|
|
286
|
+
createApp · createComponent · Show · For · Switch │
|
|
287
|
+
Plugin System · HMR │
|
|
288
|
+
├── liteforge (this package)
|
|
289
|
+
store · router · query · client · form │
|
|
290
|
+
table · calendar · modal · devtools ──────────────────┤
|
|
291
|
+
│
|
|
292
|
+
vite-plugin ────────────────────────────────────────────┘
|
|
293
|
+
JSX transform · template extraction · HMR injection
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## License
|
|
299
|
+
|
|
300
|
+
MIT © [SchildW3rk](https://github.com/SchildW3rk)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "liteforge",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "LiteForge — signals-based frontend framework. Single meta-package re-exporting all @liteforge/* packages.",
|
|
5
5
|
"author": "SchildW3rk <contact@schildw3rk.dev>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -85,15 +85,15 @@
|
|
|
85
85
|
"@liteforge/core": "0.1.0",
|
|
86
86
|
"@liteforge/runtime": "0.4.1",
|
|
87
87
|
"@liteforge/router": "0.3.0",
|
|
88
|
-
"@liteforge/store": "0.1.0",
|
|
89
88
|
"@liteforge/client": "1.0.0",
|
|
89
|
+
"@liteforge/store": "0.1.0",
|
|
90
90
|
"@liteforge/query": "1.0.0",
|
|
91
|
+
"@liteforge/form": "0.1.0",
|
|
91
92
|
"@liteforge/table": "0.1.1",
|
|
92
|
-
"@liteforge/modal": "1.0.0",
|
|
93
|
-
"@liteforge/calendar": "0.1.0",
|
|
94
93
|
"@liteforge/devtools": "1.0.0",
|
|
94
|
+
"@liteforge/modal": "1.0.0",
|
|
95
95
|
"@liteforge/vite-plugin": "0.4.1",
|
|
96
|
-
"@liteforge/
|
|
96
|
+
"@liteforge/calendar": "0.1.0"
|
|
97
97
|
},
|
|
98
98
|
"scripts": {
|
|
99
99
|
"build": "tsc -p tsconfig.build.json",
|