liteforge 0.7.6 → 0.7.7

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.
Files changed (2) hide show
  1. package/README.md +113 -182
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,13 +1,12 @@
1
1
  # liteforge
2
2
 
3
- **Signals-based frontend framework — No Virtual DOM, JSX, zero dependencies.**
3
+ Signals-based frontend framework — No Virtual DOM, JSX, zero dependencies.
4
4
 
5
5
  ```bash
6
- pnpm add liteforge
6
+ npm install liteforge @liteforge/vite-plugin
7
7
  ```
8
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.
9
+ > `liteforge` re-exports `@liteforge/core` and `@liteforge/runtime`. Use it as the single entry point for signals, effects, and component primitives. All other features are available as separate `@liteforge/*` packages.
11
10
 
12
11
  ---
13
12
 
@@ -24,39 +23,34 @@ pnpm add liteforge
24
23
  ## Quick Start
25
24
 
26
25
  ```bash
27
- pnpm add liteforge
28
- pnpm add -D vite typescript
26
+ npm install liteforge @liteforge/vite-plugin
29
27
  ```
30
28
 
31
29
  **`vite.config.ts`**
32
30
  ```ts
33
- import { defineConfig } from 'vite';
34
- import liteforge from 'liteforge/vite-plugin';
31
+ import { defineConfig } from 'vite'
32
+ import { liteforge } from '@liteforge/vite-plugin'
35
33
 
36
34
  export default defineConfig({
37
- plugins: [liteforge()],
38
- });
35
+ plugins: [liteforge()]
36
+ })
39
37
  ```
40
38
 
41
39
  **`src/main.tsx`**
42
40
  ```tsx
43
- import { createApp } from 'liteforge';
44
- import { routerPlugin } from 'liteforge/router';
45
- import App from './App.js';
41
+ import { createApp } from 'liteforge'
42
+ import { App } from './App'
46
43
 
47
- await createApp({ root: App, target: '#app' })
48
- .use(routerPlugin({ routes }))
49
- .mount();
44
+ createApp({ root: App, target: '#app' }).mount()
50
45
  ```
51
46
 
52
47
  **`src/App.tsx`**
53
48
  ```tsx
54
- import { createComponent, Show } from 'liteforge';
55
- import { signal } from 'liteforge';
49
+ import { createComponent, signal, Show } from 'liteforge'
56
50
 
57
51
  export const App = createComponent({
58
52
  component() {
59
- const count = signal(0);
53
+ const count = signal(0)
60
54
  return (
61
55
  <div>
62
56
  <h1>{() => count()}</h1>
@@ -65,82 +59,49 @@ export const App = createComponent({
65
59
  <p>Over 5!</p>
66
60
  </Show>
67
61
  </div>
68
- );
69
- },
70
- });
62
+ )
63
+ }
64
+ })
71
65
  ```
72
66
 
73
67
  ---
74
68
 
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
69
  ## Reactivity
113
70
 
114
71
  ```ts
115
- import { signal, computed, effect, batch } from 'liteforge';
72
+ import { signal, computed, effect, batch, onCleanup } from 'liteforge'
116
73
 
117
- const count = signal(0);
118
- const double = computed(() => count() * 2);
74
+ const count = signal(0)
75
+ const double = computed(() => count() * 2)
119
76
 
120
77
  effect(() => {
121
- console.log(double()); // auto-tracks dependencies
122
- });
78
+ console.log(double()) // auto-tracks dependencies
79
+ })
123
80
 
124
- count.set(5); // → logs 10
125
- count.update(n => n + 1); // → logs 12
81
+ count.set(5) // → logs 10
82
+ count.update(n => n + 1) // → logs 12
126
83
 
127
84
  batch(() => { // deferred notifications
128
- count.set(1);
129
- });
85
+ count.set(1)
86
+ })
87
+
88
+ onCleanup(() => { // runs when the enclosing effect/component is destroyed
89
+ console.log('cleaned up')
90
+ })
130
91
  ```
131
92
 
132
93
  ## Components
133
94
 
134
95
  ```tsx
135
- import { createComponent, Show, For } from 'liteforge';
136
- import { signal } from 'liteforge';
96
+ import { createComponent, Show, For } from 'liteforge'
137
97
 
138
98
  export const UserList = createComponent({
139
99
  async load() {
140
- const users = await fetch('/api/users').then(r => r.json());
141
- return { users };
100
+ const users = await fetch('/api/users').then(r => r.json())
101
+ return { users }
142
102
  },
143
103
  placeholder: () => <div class="skeleton" />,
104
+ error: ({ error, retry }) => <button onclick={retry}>Retry</button>,
144
105
  component({ data }) {
145
106
  return (
146
107
  <ul>
@@ -148,112 +109,59 @@ export const UserList = createComponent({
148
109
  {user => <li>{user.name}</li>}
149
110
  </For>
150
111
  </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
- });
112
+ )
113
+ }
114
+ })
198
115
  ```
199
116
 
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
- });
117
+ **Component lifecycle:** `setup()` → `placeholder` → `load()` → `component()` → `mounted()` → `destroyed()`
210
118
 
211
- users.data() // Signal: User[] | undefined
212
- users.isLoading() // Signal: boolean
119
+ ## Control Flow
213
120
 
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>
121
+ ```tsx
122
+ import { Show, For, Switch, Match } from 'liteforge'
123
+
124
+ // Conditional rendering
125
+ <Show when={() => isLoggedIn()}>
126
+ <Dashboard />
127
+ </Show>
128
+
129
+ // List rendering
130
+ <For each={() => items()}>
131
+ {(item) => <li>{item.name}</li>}
132
+ </For>
133
+
134
+ // Switch / pattern matching
135
+ <Switch fallback={<NotFound />}>
136
+ <Match when={() => route() === 'home'}><Home /></Match>
137
+ <Match when={() => route() === 'about'}><About /></Match>
138
+ </Switch>
238
139
  ```
239
140
 
240
141
  ## Plugin System
241
142
 
143
+ Additional capabilities are added via plugins in `createApp`:
144
+
242
145
  ```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 }))
146
+ import { createApp } from 'liteforge'
147
+ import { routerPlugin } from '@liteforge/router'
148
+ import { modalPlugin } from '@liteforge/modal'
149
+ import { toastPlugin } from '@liteforge/toast'
150
+ import { clientPlugin, queryIntegration } from '@liteforge/client'
151
+ import { devtoolsPlugin } from '@liteforge/devtools'
152
+ import { App } from './App'
153
+
154
+ createApp({ root: App, target: '#app' })
155
+ .use(routerPlugin({ routes: [...] }))
251
156
  .use(modalPlugin())
252
- .use(queryPlugin())
157
+ .use(toastPlugin({ position: 'bottom-right' }))
158
+ .use(clientPlugin({ baseUrl: '/api', query: queryIntegration() }))
253
159
  .use(devtoolsPlugin())
254
- .mount();
160
+ .mount()
255
161
  ```
256
162
 
163
+ Plugins registered via `.use()` are installed in order before the app mounts. Each plugin can provide values into the app context via `context.provide()` and returns an optional cleanup function.
164
+
257
165
  ---
258
166
 
259
167
  ## JSX
@@ -261,10 +169,10 @@ await createApp({ root: App, target: '#app' })
261
169
  LiteForge JSX compiles to direct DOM operations — no diffing, no virtual tree.
262
170
 
263
171
  ```tsx
264
- // Reactive: wrap in () =>
172
+ // Reactive text — wrap in () =>
265
173
  <span>{() => count()}</span>
266
174
 
267
- // Event handler: no wrapper needed
175
+ // Event handler no wrapper needed
268
176
  <button onclick={() => count.update(n => n + 1)}>Click</button>
269
177
 
270
178
  // Dynamic attribute
@@ -276,25 +184,48 @@ LiteForge JSX compiles to direct DOM operations — no diffing, no virtual tree.
276
184
 
277
185
  ---
278
186
 
279
- ## Architecture
187
+ ## Install What You Need
188
+
189
+ All packages are zero-dependency and published independently:
190
+
191
+ | Package | Description |
192
+ |---------|-------------|
193
+ | `liteforge` | Umbrella: core + runtime |
194
+ | `@liteforge/core` | `signal`, `computed`, `effect`, `batch`, `onCleanup` |
195
+ | `@liteforge/runtime` | `createComponent`, `createApp`, `Show`, `For`, `Switch`, plugin system |
196
+ | `@liteforge/vite-plugin` | JSX transform, signal-safe getter wrapping, HMR |
197
+ | `@liteforge/router` | Client-side routing with guards, middleware, lazy loading |
198
+ | `@liteforge/store` | Signal-based state management with devtools integration |
199
+ | `@liteforge/query` | `createQuery`, `createMutation`, query cache |
200
+ | `@liteforge/form` | Type-safe forms with Zod validation |
201
+ | `@liteforge/table` | Data tables with sorting, filtering, pagination, selection |
202
+ | `@liteforge/calendar` | Full scheduling calendar — 4 views, drag & drop, resources |
203
+ | `@liteforge/modal` | Modal dialogs with `confirm`/`alert`/`prompt` presets |
204
+ | `@liteforge/toast` | Toast notifications |
205
+ | `@liteforge/tooltip` | Tooltip directive and component |
206
+ | `@liteforge/client` | HTTP client with resources, interceptors, query integration |
207
+ | `@liteforge/devtools` | 5-tab debug panel with time-travel |
280
208
 
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
209
+ ---
210
+
211
+ ## Types
212
+
213
+ ```ts
214
+ import type {
215
+ Signal,
216
+ ReadonlySignal,
217
+ Computed,
218
+ ComponentFactory,
219
+ ComponentDefinition,
220
+ AppBuilder,
221
+ LiteForgePlugin,
222
+ PluginContext,
223
+ PluginRegistry
224
+ } from 'liteforge'
294
225
  ```
295
226
 
296
227
  ---
297
228
 
298
229
  ## License
299
230
 
300
- MIT © [SchildW3rk](https://github.com/SchildW3rk)
231
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "liteforge",
3
- "version": "0.7.6",
3
+ "version": "0.7.7",
4
4
  "description": "LiteForge — signals-based frontend framework. Re-exports @liteforge/core and @liteforge/runtime.",
5
5
  "author": "SchildW3rk <contact@schildw3rk.dev>",
6
6
  "license": "MIT",