lithent 1.21.4 → 1.21.5
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/dist/lithent-agent-addon.md +2 -2
- package/dist/{lithent-skills.md → skills/SKILL.md} +18 -1
- package/dist/skills/constraints/mistakes.md +15 -0
- package/dist/skills/constraints/rules.md +16 -0
- package/dist/skills/constraints/troubleshooting.md +13 -0
- package/dist/skills/examples/quick-examples.md +195 -0
- package/dist/skills/reference/children-type.md +25 -0
- package/dist/skills/reference/lstore-inference.md +19 -0
- package/dist/skills/reference/props-types.md +28 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Lithent Agent Addon
|
|
2
2
|
|
|
3
|
-
> Version: 1.21.
|
|
3
|
+
> Version: 1.21.5
|
|
4
4
|
|
|
5
5
|
You are a coding agent with Lithent virtual DOM guidance enabled.
|
|
6
6
|
|
|
@@ -120,7 +120,7 @@ COMMON MISTAKES TO CATCH:
|
|
|
120
120
|
REFERENCE MATERIALS (NOT PART OF BEHAVIORAL RULES):
|
|
121
121
|
|
|
122
122
|
For detailed code examples and API usage, refer to:
|
|
123
|
-
node_modules/lithent/dist/
|
|
123
|
+
node_modules/lithent/dist/skills/SKILL.md
|
|
124
124
|
|
|
125
125
|
This reference material provides comprehensive examples, patterns,
|
|
126
126
|
and import references that complement the behavioral guidelines above.
|
|
@@ -1,6 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lithent
|
|
3
|
+
title: Lithent Agent Skills
|
|
4
|
+
version: 1.21.5
|
|
5
|
+
description: AI agent skills for working with the Lithent library.
|
|
6
|
+
additional_materials:
|
|
7
|
+
- constraints/
|
|
8
|
+
- reference/
|
|
9
|
+
- examples/
|
|
10
|
+
---
|
|
11
|
+
|
|
1
12
|
# Lithent Agent Skills
|
|
2
13
|
|
|
3
|
-
> Version: 1.21.
|
|
14
|
+
> Version: 1.21.5
|
|
4
15
|
|
|
5
16
|
This file provides AI agent skills for working with the Lithent library.
|
|
6
17
|
|
|
@@ -363,3 +374,9 @@ import { fTags, fFragment, fMount } from 'lithent/ftags';
|
|
|
363
374
|
// HTM
|
|
364
375
|
import { lTag } from 'lithent/tag';
|
|
365
376
|
```
|
|
377
|
+
|
|
378
|
+
## Additional materials (optional)
|
|
379
|
+
|
|
380
|
+
- `constraints/` (rules, mistakes, troubleshooting)
|
|
381
|
+
- `reference/` (props types, children types, lstore inference)
|
|
382
|
+
- `examples/` (quick examples)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Common Mistakes
|
|
3
|
+
category: constraints
|
|
4
|
+
version: 1.21.5
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Common Mistakes
|
|
8
|
+
|
|
9
|
+
- Destructuring props in the mounter and expecting primitive values to update.
|
|
10
|
+
- Using `props.children` instead of the `children` argument.
|
|
11
|
+
- Swapping argument order for `mount` or `lmount`.
|
|
12
|
+
- Calling `state`/`lstate` outside the mounter (e.g., in updaters/handlers).
|
|
13
|
+
- Using `state` with `lmount` or `lstate` with `mount`.
|
|
14
|
+
- Creating `store`/`lstore` inside components (new store per render).
|
|
15
|
+
- Mutating arrays or nested objects directly instead of replacing references.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Rules
|
|
3
|
+
category: constraints
|
|
4
|
+
version: 1.21.5
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Rules
|
|
8
|
+
|
|
9
|
+
- Use `state` with `mount` and pass `renew` as the second argument.
|
|
10
|
+
- Use `lstate` with `lmount` (no `renew` argument is needed).
|
|
11
|
+
- Call `state`/`lstate` only inside the mounter (not in updaters or handlers).
|
|
12
|
+
- Use `store` with `mount`, `lstore` with `lmount`, and create stores outside components.
|
|
13
|
+
- `store` is shallow‑reactive: replace first‑level properties or arrays to update.
|
|
14
|
+
- Don’t rely on `props.children`; use the separate `children` argument.
|
|
15
|
+
- Argument order is `mount(renew, props, children)` and `lmount(props, children)`.
|
|
16
|
+
- Avoid destructuring props in the mounter if you need live updates.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Troubleshooting
|
|
3
|
+
category: constraints
|
|
4
|
+
version: 1.21.5
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Troubleshooting
|
|
8
|
+
|
|
9
|
+
- **Props look stale:** avoid destructuring props in the mounter; read `props.x` directly or use the updater’s props argument.
|
|
10
|
+
- **Children missing:** use the `children` argument (not `props.children`); remember children are only passed to the mounter.
|
|
11
|
+
- **Updates not rendering:** don’t mutate arrays/objects in place—assign a new array or replace first‑level properties.
|
|
12
|
+
- **State doesn’t react:** `state` requires `mount` + `renew`; `lstate` requires `lmount` and is mounter‑only.
|
|
13
|
+
- **Stores reset unexpectedly:** define `store`/`lstore` outside components and reuse them.
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Quick Examples
|
|
3
|
+
category: examples
|
|
4
|
+
version: 1.21.5
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Quick Examples
|
|
8
|
+
|
|
9
|
+
## Manual Counter (mount + state)
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
import { mount } from 'lithent';
|
|
13
|
+
import { state } from 'lithent/helper';
|
|
14
|
+
|
|
15
|
+
const Counter = mount((renew) => {
|
|
16
|
+
const count = state(0, renew);
|
|
17
|
+
return () => <button onClick={() => count.value++}>{count.value}</button>;
|
|
18
|
+
});
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Light Counter (lmount + lstate)
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import { lmount } from 'lithent';
|
|
25
|
+
import { lstate } from 'lithent/helper';
|
|
26
|
+
|
|
27
|
+
const Counter = lmount(() => {
|
|
28
|
+
const count = lstate(0);
|
|
29
|
+
return () => <button onClick={() => count.value++}>{count.value}</button>;
|
|
30
|
+
});
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Computed + Effect
|
|
34
|
+
|
|
35
|
+
```tsx
|
|
36
|
+
import { lmount } from 'lithent';
|
|
37
|
+
import { lstate, computed, effect } from 'lithent/helper';
|
|
38
|
+
|
|
39
|
+
const Profile = lmount(() => {
|
|
40
|
+
const first = lstate('Ada');
|
|
41
|
+
const last = lstate('Lovelace');
|
|
42
|
+
const full = computed(() => `${first.value} ${last.value}`);
|
|
43
|
+
|
|
44
|
+
effect(() => {
|
|
45
|
+
console.log('Name changed:', full.value);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
return () => <p>{full.value}</p>;
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Lifecycle Hooks (mount / update)
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
import { mount, mountCallback, updateCallback, mountReadyCallback } from 'lithent';
|
|
56
|
+
import { state } from 'lithent/helper';
|
|
57
|
+
|
|
58
|
+
const Widget = mount((renew) => {
|
|
59
|
+
const count = state(0, renew);
|
|
60
|
+
|
|
61
|
+
// Runs after DOM mount
|
|
62
|
+
mountCallback(() => {
|
|
63
|
+
console.log('mounted');
|
|
64
|
+
return () => console.log('unmounted');
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Runs right after virtual DOM creation (before DOM mount)
|
|
68
|
+
mountReadyCallback(() => {
|
|
69
|
+
console.log('mountReady');
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// Runs before every update; returned function runs after DOM update
|
|
73
|
+
updateCallback(() => {
|
|
74
|
+
console.log('before update');
|
|
75
|
+
return () => console.log('after update');
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
return () => (
|
|
79
|
+
<button onClick={() => count.value++}>
|
|
80
|
+
Count: {count.value}
|
|
81
|
+
</button>
|
|
82
|
+
);
|
|
83
|
+
});
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Ref
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
import { mount, ref } from 'lithent';
|
|
90
|
+
|
|
91
|
+
const FocusInput = mount((renew) => {
|
|
92
|
+
const inputRef = ref<HTMLInputElement>(null);
|
|
93
|
+
return () => (
|
|
94
|
+
<div>
|
|
95
|
+
<input ref={inputRef} />
|
|
96
|
+
<button onClick={() => inputRef.value?.focus()}>Focus</button>
|
|
97
|
+
</div>
|
|
98
|
+
);
|
|
99
|
+
});
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Portal
|
|
103
|
+
|
|
104
|
+
```tsx
|
|
105
|
+
import { mount, portal } from 'lithent';
|
|
106
|
+
|
|
107
|
+
const Modal = mount((renew, props: { onClose: () => void }) => {
|
|
108
|
+
return () => portal(
|
|
109
|
+
<div class="modal" onClick={props.onClose}>Close</div>,
|
|
110
|
+
document.body
|
|
111
|
+
);
|
|
112
|
+
});
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Context (mount + lmount)
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
import { mount, lmount } from 'lithent';
|
|
119
|
+
import { createContext, createLContext } from 'lithent/helper';
|
|
120
|
+
|
|
121
|
+
const ThemeContext = createContext<{ theme: string }>();
|
|
122
|
+
const LThemeContext = createLContext<{ theme: string }>();
|
|
123
|
+
|
|
124
|
+
const ThemeProvider = mount((renew, _props, children) => {
|
|
125
|
+
return () => (
|
|
126
|
+
<ThemeContext.Provider value={{ theme: 'dark' }}>
|
|
127
|
+
{children}
|
|
128
|
+
</ThemeContext.Provider>
|
|
129
|
+
);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
const LThemeProvider = lmount((_props, children) => {
|
|
133
|
+
return () => (
|
|
134
|
+
<LThemeContext.Provider value={{ theme: 'dark' }}>
|
|
135
|
+
{children}
|
|
136
|
+
</LThemeContext.Provider>
|
|
137
|
+
);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
const Consumer = lmount(() => {
|
|
141
|
+
const { theme } = LThemeContext.useContext();
|
|
142
|
+
return () => <p>{theme}</p>;
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Store (store + lstore)
|
|
147
|
+
|
|
148
|
+
```tsx
|
|
149
|
+
import { mount, lmount } from 'lithent';
|
|
150
|
+
import { store, lstore } from 'lithent/helper';
|
|
151
|
+
|
|
152
|
+
const userStore = store({ name: '', loggedIn: false });
|
|
153
|
+
const userLStore = lstore({ name: '', loggedIn: false });
|
|
154
|
+
|
|
155
|
+
const User = mount((renew) => {
|
|
156
|
+
const user = userStore(renew);
|
|
157
|
+
return () => <p>{user.name}</p>;
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
const UserLite = lmount(() => {
|
|
161
|
+
const user = userLStore();
|
|
162
|
+
return () => <p>{user.name}</p>;
|
|
163
|
+
});
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Performance (cacheUpdate + nextTickRender)
|
|
167
|
+
|
|
168
|
+
```ts
|
|
169
|
+
import { cacheUpdate, nextTickRender } from 'lithent/helper';
|
|
170
|
+
|
|
171
|
+
cacheUpdate(() => {
|
|
172
|
+
a.value = 1;
|
|
173
|
+
b.value = 2;
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
nextTickRender(() => {
|
|
177
|
+
items.value = [...items.value, ...more];
|
|
178
|
+
});
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Children Helpers
|
|
182
|
+
|
|
183
|
+
```tsx
|
|
184
|
+
import { mount } from 'lithent';
|
|
185
|
+
import { unwrapChildren } from 'lithent/helper';
|
|
186
|
+
|
|
187
|
+
const Card = mount((renew, props: { title: string }, children) => {
|
|
188
|
+
return () => (
|
|
189
|
+
<div class="card">
|
|
190
|
+
<h3>{props.title}</h3>
|
|
191
|
+
{unwrapChildren(children)}
|
|
192
|
+
</div>
|
|
193
|
+
);
|
|
194
|
+
});
|
|
195
|
+
```
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Children Type
|
|
3
|
+
category: reference
|
|
4
|
+
version: 1.21.5
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Children Type
|
|
8
|
+
|
|
9
|
+
- Lithent does **not** use `props.children`. Use the separate `children` argument.
|
|
10
|
+
- Argument order: `mount(renew, props, children)` and `lmount(props, children)`.
|
|
11
|
+
- Children are always `WDom[]`, even with a single child.
|
|
12
|
+
- Children are only provided to the mounter; use closure inside the updater.
|
|
13
|
+
|
|
14
|
+
```tsx
|
|
15
|
+
import { mount, WDom } from 'lithent';
|
|
16
|
+
|
|
17
|
+
const Panel = mount<{ title: string }>((renew, props, children: WDom[]) => {
|
|
18
|
+
return () => (
|
|
19
|
+
<section>
|
|
20
|
+
<h2>{props.title}</h2>
|
|
21
|
+
{children}
|
|
22
|
+
</section>
|
|
23
|
+
);
|
|
24
|
+
});
|
|
25
|
+
```
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: lstore Type Inference
|
|
3
|
+
category: reference
|
|
4
|
+
version: 1.21.5
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# lstore Type Inference
|
|
8
|
+
|
|
9
|
+
- Defining stores as **objects** is usually better than primitives.
|
|
10
|
+
- Grouping related fields improves type inference and clarity.
|
|
11
|
+
|
|
12
|
+
```tsx
|
|
13
|
+
import { lstore } from 'lithent/helper';
|
|
14
|
+
|
|
15
|
+
const userStore = lstore({
|
|
16
|
+
name: '',
|
|
17
|
+
loggedIn: false,
|
|
18
|
+
});
|
|
19
|
+
```
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Props Types
|
|
3
|
+
category: reference
|
|
4
|
+
version: 1.21.5
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Props Types
|
|
8
|
+
|
|
9
|
+
- Props are the **second** argument to the mounter and the **first** argument to the updater.
|
|
10
|
+
- The same props reference is preserved for the component’s lifetime.
|
|
11
|
+
- For TypeScript, define the props type via a `mount`/`lmount` generic.
|
|
12
|
+
- If you destructure props in the mounter, primitive values are copied and won’t update.
|
|
13
|
+
Prefer `props.property` or the updater’s props argument for fresh values.
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import { mount } from 'lithent';
|
|
17
|
+
|
|
18
|
+
type Props = { count: number };
|
|
19
|
+
|
|
20
|
+
const Counter = mount<Props>((renew, props) => {
|
|
21
|
+
return (updaterProps) => (
|
|
22
|
+
<div>
|
|
23
|
+
<p>props: {props.count}</p>
|
|
24
|
+
<p>updater: {updaterProps.count}</p>
|
|
25
|
+
</div>
|
|
26
|
+
);
|
|
27
|
+
});
|
|
28
|
+
```
|
package/package.json
CHANGED