jails-js 6.9.8 → 6.9.9
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/ai/anti-patterns.md +102 -0
- package/ai/api.md +388 -0
- package/ai/architecture.md +79 -0
- package/ai/best-practices.md +183 -0
- package/ai/concepts.md +228 -0
- package/ai/directives.md +556 -0
- package/ai/examples.md +199 -0
- package/ai/faq.md +70 -0
- package/ai/glossary.md +28 -0
- package/ai/json/api.json +190 -0
- package/ai/json/directives.json +107 -0
- package/ai/json/patterns.json +69 -0
- package/ai/json/recipes.json +96 -0
- package/ai/llms.txt +96 -0
- package/ai/overview.md +45 -0
- package/ai/patterns.md +182 -0
- package/ai/recipes.md +393 -0
- package/package.json +24 -2
- package/readme.md +22 -9
- package/tsconfig.json +0 -1
- package/types.d.ts +3 -3
package/ai/recipes.md
ADDED
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
# Recipes
|
|
2
|
+
|
|
3
|
+
## Counter
|
|
4
|
+
|
|
5
|
+
Explanation: minimal local state update with delegated events and `html-inner`.
|
|
6
|
+
|
|
7
|
+
```html
|
|
8
|
+
<app-counter>
|
|
9
|
+
<button data-subtract>-</button>
|
|
10
|
+
<span html-inner="counter">0</span>
|
|
11
|
+
<button data-add>+</button>
|
|
12
|
+
</app-counter>
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
export default function appCounter({ main, on, state }) {
|
|
17
|
+
main(() => {
|
|
18
|
+
on('click', '[data-add]', add)
|
|
19
|
+
on('click', '[data-subtract]', subtract)
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
const add = () => {
|
|
23
|
+
state.set(s => {
|
|
24
|
+
s.counter += 1
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const subtract = () => {
|
|
29
|
+
state.set(s => {
|
|
30
|
+
s.counter -= 1
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export const model = {
|
|
36
|
+
counter: 0
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Rendering explanation: `html-inner="counter"` replaces fallback `0` after mount and updates after each `state.set()`.
|
|
41
|
+
|
|
42
|
+
Performance notes: one listener per event type at the component root; no per-button rebinding.
|
|
43
|
+
|
|
44
|
+
Common mistakes: omitting `state` from controller helpers; reading DOM text as source of truth instead of state.
|
|
45
|
+
|
|
46
|
+
## Loading and Error States
|
|
47
|
+
|
|
48
|
+
```html
|
|
49
|
+
<app-users>
|
|
50
|
+
<p html-if="loading">Loading</p>
|
|
51
|
+
<p html-if="error">{{ error.message }}</p>
|
|
52
|
+
<ul html-if="!loading && !error">
|
|
53
|
+
<li html-for="user in users">{{ user.name }}</li>
|
|
54
|
+
</ul>
|
|
55
|
+
</app-users>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
export default function appUsers({ main, state, dependencies }) {
|
|
60
|
+
const { http } = dependencies
|
|
61
|
+
|
|
62
|
+
main(() => {
|
|
63
|
+
load()
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
const load = () => {
|
|
67
|
+
state.set({ loading: true, error: null })
|
|
68
|
+
http.get('/users')
|
|
69
|
+
.then(users => state.set({ users, loading: false }))
|
|
70
|
+
.catch(error => state.set({ error, loading: false }))
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export const model = {
|
|
75
|
+
users: [],
|
|
76
|
+
loading: false,
|
|
77
|
+
error: null
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Rendering explanation: mutually exclusive `html-if` regions create/remove the visible branch.
|
|
82
|
+
|
|
83
|
+
Performance notes: fetch never runs from the template. The loop only renders when not loading and without error.
|
|
84
|
+
|
|
85
|
+
Common mistakes: storing formatted error strings only; keep the original error if handlers need it.
|
|
86
|
+
|
|
87
|
+
## Modal
|
|
88
|
+
|
|
89
|
+
```html
|
|
90
|
+
<app-modal>
|
|
91
|
+
<button data-open>Open</button>
|
|
92
|
+
<section html-if="open" role="dialog" aria-modal="true">
|
|
93
|
+
<h2>{{ title }}</h2>
|
|
94
|
+
<button data-close>Close</button>
|
|
95
|
+
</section>
|
|
96
|
+
</app-modal>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
export default function appModal({ main, on, state }) {
|
|
101
|
+
main(() => {
|
|
102
|
+
on('click', '[data-open]', () => state.set({ open: true }))
|
|
103
|
+
on('click', '[data-close]', () => state.set({ open: false }))
|
|
104
|
+
})
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export const model = {
|
|
108
|
+
open: false,
|
|
109
|
+
title: 'Dialog'
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Rendering explanation: modal DOM is created only when `open` is truthy and removed when false.
|
|
114
|
+
|
|
115
|
+
Performance notes: fine for small dialogs. For heavy dialog content that should preserve input state, use CSS visibility or place form controls under `html-static` as appropriate.
|
|
116
|
+
|
|
117
|
+
Common mistakes: expecting internal form values to persist across `html-if` removal.
|
|
118
|
+
|
|
119
|
+
## Tabs
|
|
120
|
+
|
|
121
|
+
```html
|
|
122
|
+
<app-tabs>
|
|
123
|
+
<nav>
|
|
124
|
+
<button data-tab="profile" html-class="activeTab === 'profile' ? 'active' : ''">Profile</button>
|
|
125
|
+
<button data-tab="billing" html-class="activeTab === 'billing' ? 'active' : ''">Billing</button>
|
|
126
|
+
</nav>
|
|
127
|
+
<section html-if="activeTab === 'profile'">Profile content</section>
|
|
128
|
+
<section html-if="activeTab === 'billing'">Billing content</section>
|
|
129
|
+
</app-tabs>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
export default function appTabs({ main, on, state }) {
|
|
134
|
+
main(() => {
|
|
135
|
+
on('click', '[data-tab]', select)
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
const select = e => {
|
|
139
|
+
state.set({ activeTab: e.delegateTarget.dataset.tab })
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export const model = {
|
|
144
|
+
activeTab: 'profile'
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Rendering explanation: button classes and panel branches derive from one state property.
|
|
149
|
+
|
|
150
|
+
Performance notes: no listener per tab panel. Avoid rendering large inactive panels repeatedly.
|
|
151
|
+
|
|
152
|
+
Common mistakes: reading `event.target.dataset.tab`; nested elements can make `event.target` wrong. Use `delegateTarget`.
|
|
153
|
+
|
|
154
|
+
## Accordion
|
|
155
|
+
|
|
156
|
+
```html
|
|
157
|
+
<app-accordion>
|
|
158
|
+
<article html-for="item in items">
|
|
159
|
+
<button data-toggle html-data-index="$index">{{ item.title }}</button>
|
|
160
|
+
<div html-if="openIndex === $index">{{ item.body }}</div>
|
|
161
|
+
</article>
|
|
162
|
+
</app-accordion>
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
export default function appAccordion({ main, on, state }) {
|
|
167
|
+
main(() => {
|
|
168
|
+
on('click', '[data-toggle]', toggle)
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
const toggle = e => {
|
|
172
|
+
const index = Number(e.delegateTarget.dataset.index)
|
|
173
|
+
state.set(s => {
|
|
174
|
+
s.openIndex = s.openIndex === index ? -1 : index
|
|
175
|
+
})
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export const model = {
|
|
180
|
+
openIndex: -1,
|
|
181
|
+
items: []
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Rendering explanation: each repeated item receives `$index`; only matching content branch renders.
|
|
186
|
+
|
|
187
|
+
Performance notes: for long accordions, do not put heavy widgets inside every body unless guarded or static.
|
|
188
|
+
|
|
189
|
+
Common mistakes: not converting dataset strings to numbers.
|
|
190
|
+
|
|
191
|
+
## Fetch API With Service Dependency
|
|
192
|
+
|
|
193
|
+
```ts
|
|
194
|
+
// main.ts
|
|
195
|
+
register('app-posts', appPosts, { http })
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
```ts
|
|
199
|
+
export default function appPosts({ main, state, dependencies }) {
|
|
200
|
+
const { http } = dependencies
|
|
201
|
+
|
|
202
|
+
main(() => {
|
|
203
|
+
load()
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
const load = async () => {
|
|
207
|
+
state.set({ loading: true })
|
|
208
|
+
const posts = await http.get('/posts')
|
|
209
|
+
state.set({ posts, loading: false })
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export const model = {
|
|
214
|
+
posts: [],
|
|
215
|
+
loading: false
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Rendering explanation: state changes drive any `html-if` and `html-for` bound to `loading` and `posts`.
|
|
220
|
+
|
|
221
|
+
Performance notes: dependency injection keeps generic components free of unused service code.
|
|
222
|
+
|
|
223
|
+
Common mistakes: importing app services inside reusable library components.
|
|
224
|
+
|
|
225
|
+
## Optimistic Updates
|
|
226
|
+
|
|
227
|
+
```ts
|
|
228
|
+
export default function appTodos({ main, on, state, dependencies }) {
|
|
229
|
+
const { todosApi } = dependencies
|
|
230
|
+
|
|
231
|
+
main(() => {
|
|
232
|
+
on('click', '[data-toggle]', toggle)
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
const toggle = async e => {
|
|
236
|
+
const id = e.delegateTarget.dataset.id
|
|
237
|
+
const previous = state.get().todos
|
|
238
|
+
const todos = previous.map(todo =>
|
|
239
|
+
todo.id === id ? { ...todo, done: !todo.done } : todo
|
|
240
|
+
)
|
|
241
|
+
await state.set({ todos })
|
|
242
|
+
|
|
243
|
+
try {
|
|
244
|
+
await todosApi.toggle(id)
|
|
245
|
+
} catch (error) {
|
|
246
|
+
state.set({ todos: previous, error })
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Rendering explanation: UI updates before the API resolves; rollback restores previous state on failure.
|
|
253
|
+
|
|
254
|
+
Performance notes: clone changed collections instead of mutating external references.
|
|
255
|
+
|
|
256
|
+
Common mistakes: losing the previous state snapshot before the optimistic write.
|
|
257
|
+
|
|
258
|
+
## Nested Templates
|
|
259
|
+
|
|
260
|
+
```html
|
|
261
|
+
<app-page>
|
|
262
|
+
<h1>Server-rendered heading</h1>
|
|
263
|
+
<template>
|
|
264
|
+
<section html-if="user">
|
|
265
|
+
Welcome, {{ user.name }}
|
|
266
|
+
</section>
|
|
267
|
+
</template>
|
|
268
|
+
</app-page>
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
Rendering explanation: native `<template>` prevents unresolved mustache markers from flashing before data exists.
|
|
272
|
+
|
|
273
|
+
Performance notes: use this for correctness of first paint; it is not a substitute for limiting render work.
|
|
274
|
+
|
|
275
|
+
Common mistakes: hiding content that should be visible at first paint.
|
|
276
|
+
|
|
277
|
+
## Debounced Input
|
|
278
|
+
|
|
279
|
+
```html
|
|
280
|
+
<app-search>
|
|
281
|
+
<input type="search" html-static>
|
|
282
|
+
<p html-if="loading">Searching</p>
|
|
283
|
+
<ul>
|
|
284
|
+
<li html-for="item in results">{{ item.label }}</li>
|
|
285
|
+
</ul>
|
|
286
|
+
</app-search>
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
```ts
|
|
290
|
+
export default function appSearch({ main, on, state, dependencies }) {
|
|
291
|
+
const { search } = dependencies
|
|
292
|
+
let timer
|
|
293
|
+
|
|
294
|
+
main(() => {
|
|
295
|
+
on('input', 'input[type=search]', schedule)
|
|
296
|
+
})
|
|
297
|
+
|
|
298
|
+
const schedule = e => {
|
|
299
|
+
const query = e.delegateTarget.value
|
|
300
|
+
clearTimeout(timer)
|
|
301
|
+
timer = setTimeout(() => run(query), 250)
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const run = async query => {
|
|
305
|
+
state.set({ loading: true })
|
|
306
|
+
const results = await search(query)
|
|
307
|
+
state.set({ results, loading: false })
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
export const model = {
|
|
312
|
+
results: [],
|
|
313
|
+
loading: false
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
Rendering explanation: input value is browser-owned through `html-static`; search results are Jails-owned state.
|
|
318
|
+
|
|
319
|
+
Performance notes: debounce avoids one network request and render per keystroke.
|
|
320
|
+
|
|
321
|
+
Common mistakes: binding input value to state when no other render logic needs it.
|
|
322
|
+
|
|
323
|
+
## Intersection Observer Lazy Rendering
|
|
324
|
+
|
|
325
|
+
```ts
|
|
326
|
+
export default function lazyPanel({ main, elm, state, unmount }) {
|
|
327
|
+
let observer
|
|
328
|
+
|
|
329
|
+
main(() => {
|
|
330
|
+
observer = new IntersectionObserver(entries => {
|
|
331
|
+
if (entries.some(entry => entry.isIntersecting)) {
|
|
332
|
+
state.set({ visible: true })
|
|
333
|
+
observer.disconnect()
|
|
334
|
+
}
|
|
335
|
+
})
|
|
336
|
+
observer.observe(elm)
|
|
337
|
+
})
|
|
338
|
+
|
|
339
|
+
unmount(() => {
|
|
340
|
+
if (observer) observer.disconnect()
|
|
341
|
+
})
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
export const model = {
|
|
345
|
+
visible: false
|
|
346
|
+
}
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
```html
|
|
350
|
+
<lazy-panel>
|
|
351
|
+
<section html-if="visible">Expensive content</section>
|
|
352
|
+
</lazy-panel>
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
Rendering explanation: expensive content is not created until the component enters the viewport.
|
|
356
|
+
|
|
357
|
+
Performance notes: cleanup prevents observers from retaining detached elements.
|
|
358
|
+
|
|
359
|
+
Common mistakes: forgetting `unmount()`.
|
|
360
|
+
|
|
361
|
+
## Virtual List Boundary
|
|
362
|
+
|
|
363
|
+
```html
|
|
364
|
+
<app-virtual-list>
|
|
365
|
+
<div class="virtual-list" html-static></div>
|
|
366
|
+
<p>Total: {{ total }}</p>
|
|
367
|
+
</app-virtual-list>
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
```ts
|
|
371
|
+
export default function appVirtualList({ main, elm, state, dependencies }) {
|
|
372
|
+
const { createVirtualList } = dependencies
|
|
373
|
+
const target = elm.querySelector('.virtual-list')
|
|
374
|
+
let list
|
|
375
|
+
|
|
376
|
+
main(() => {
|
|
377
|
+
list = createVirtualList(target, {
|
|
378
|
+
onCountChange: total => state.set({ total })
|
|
379
|
+
})
|
|
380
|
+
})
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
export const model = {
|
|
384
|
+
total: 0
|
|
385
|
+
}
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
Rendering explanation: the virtual list library owns its DOM; Jails renders surrounding counters/state.
|
|
389
|
+
|
|
390
|
+
Performance notes: `html-static` prevents Jails diffing a large, imperatively managed list.
|
|
391
|
+
|
|
392
|
+
Common mistakes: putting `html-for` inside a virtualized area managed by another library.
|
|
393
|
+
|
package/package.json
CHANGED
|
@@ -1,24 +1,39 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jails-js",
|
|
3
|
-
"version": "6.9.
|
|
3
|
+
"version": "6.9.9",
|
|
4
4
|
"description": "Jails - Elegant and Minimalistic Javascript Application Library",
|
|
5
5
|
"module": "./dist/index.js",
|
|
6
6
|
"main": "./dist/jails.js",
|
|
7
|
+
"types": "./types.d.ts",
|
|
7
8
|
"exports": {
|
|
9
|
+
|
|
8
10
|
"./html": {
|
|
9
11
|
"types": "./types.d.ts",
|
|
10
12
|
"import": "./html.js",
|
|
11
13
|
"require": "./html.js"
|
|
12
14
|
},
|
|
15
|
+
|
|
13
16
|
".": {
|
|
14
17
|
"types": "./types.d.ts",
|
|
15
18
|
"import": "./dist/index.js",
|
|
16
19
|
"require": "./dist/jails.js"
|
|
17
20
|
},
|
|
21
|
+
|
|
18
22
|
"./internal": {
|
|
19
23
|
"types": "./types.d.ts",
|
|
20
24
|
"default": "./types.d.ts"
|
|
21
|
-
}
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
"./ai/*": "./ai-docs/*",
|
|
28
|
+
"./schemas/*": "./ai-docs/schemas/*",
|
|
29
|
+
"./canonical/*": "./ai-docs/canonical/*"
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
"ai": {
|
|
33
|
+
"entry": "./ai-docs/LLM.md",
|
|
34
|
+
"schemas": "./ai-docs/schemas",
|
|
35
|
+
"examples": "./ai-docs/canonical",
|
|
36
|
+
"training": "./ai-docs/training/training.jsonl"
|
|
22
37
|
},
|
|
23
38
|
"scripts": {
|
|
24
39
|
"dev": "vite build --watch",
|
|
@@ -27,28 +42,35 @@
|
|
|
27
42
|
"publish-beta": "yarn build && npm version prerelease --preid=beta && npm publish --tag beta",
|
|
28
43
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
29
44
|
},
|
|
45
|
+
|
|
30
46
|
"repository": {
|
|
31
47
|
"type": "git",
|
|
32
48
|
"url": "git+https://github.com/jails-org/Jails.git"
|
|
33
49
|
},
|
|
50
|
+
|
|
34
51
|
"keywords": [
|
|
35
52
|
"Jails",
|
|
36
53
|
"Javascript",
|
|
37
54
|
"Component",
|
|
38
55
|
"Micro-Library"
|
|
39
56
|
],
|
|
57
|
+
|
|
40
58
|
"author": "javiani",
|
|
41
59
|
"license": "MIT",
|
|
60
|
+
|
|
42
61
|
"bugs": {
|
|
43
62
|
"url": "https://github.com/jails-org/Jails/issues"
|
|
44
63
|
},
|
|
64
|
+
|
|
45
65
|
"homepage": "https://github.com/jails-org/Jails",
|
|
66
|
+
|
|
46
67
|
"devDependencies": {
|
|
47
68
|
"@types/node": "^22.10.10",
|
|
48
69
|
"terser": "^5.37.0",
|
|
49
70
|
"typescript": "^5.7.3",
|
|
50
71
|
"vite": "^6.0.11"
|
|
51
72
|
},
|
|
73
|
+
|
|
52
74
|
"dependencies": {
|
|
53
75
|
"idiomorph": "^0.7.4"
|
|
54
76
|
}
|
package/readme.md
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
<p align="center">
|
|
2
|
-
<img width="200" src="https://github.com/user-attachments/assets/8b4dbfb9-f05e-4b83-8d42-8847038a97e2" alt="Jails" />
|
|
3
|
-
</p>
|
|
4
1
|
|
|
5
|
-
<h1 align="center">Jails</h1>
|
|
6
2
|
|
|
7
|
-
<
|
|
3
|
+
<p align="center" height="100">
|
|
4
|
+
<img width="250" alt="Jails - A minimalistic Micro Framework" src="https://github.com/user-attachments/assets/5e2eee1a-5f8f-4eed-abba-7422a5258245" />
|
|
5
|
+
|
|
6
|
+
</p>
|
|
7
|
+
|
|
8
|
+
<h1 align="center">An Elegant and Minimalistic<br /> Micro-Framework</h3>
|
|
8
9
|
|
|
9
10
|
<div align="center">
|
|
10
|
-
<
|
|
11
|
+
<br />
|
|
12
|
+
<br />
|
|
13
|
+
<table width="100%" align="center" border="0">
|
|
11
14
|
<tr><td align="center">🏝 Built for <br/><a href="https://www.patterns.dev/posts/islands-architecture/" target="_blank">Island Architecture</a></td</tr>
|
|
12
15
|
<td align="center">ƛ Inspired by <br/><a href="https://guide.elm-lang.org/architecture/" target="_blank">Elm Architecture</a></td>
|
|
13
16
|
<td align="center">🔗 Ready for <br/><a href="https://htmx.org/essays/hypermedia-driven-applications" target="_blank">hypermedia applications</a></td></tr>
|
|
@@ -28,9 +31,19 @@
|
|
|
28
31
|
The JavaScript ecosystem, including browsers and tools, has undergone significant evolution over the years. However, it's evident that many of the complexities introduced by frameworks today may not be essential for the majority of web applications. The prevailing trend in modern app development seems to prioritize expertise in frameworks over mastery of the language itself, often leading to a sense of being confined within the framework ecosystem.
|
|
29
32
|
|
|
30
33
|
Jails was designed to be:
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
+
|
|
35
|
+
<table width="100%" align="center" border="0">
|
|
36
|
+
<tr>
|
|
37
|
+
<th>🧩 Decoupled</th>
|
|
38
|
+
<th>⚡️ Lightweight</th>
|
|
39
|
+
<th>📦 Interoperable</th>
|
|
40
|
+
</tr>
|
|
41
|
+
<tr>
|
|
42
|
+
<td align="center">Backend-agnostic, our solution seamlessly integrates with any backend framework or back-end programming language.</td>
|
|
43
|
+
<td align="center">Lightweight, just around 5kb when gzipped. It enhances your application's performance by progressively, separating HTML from your JavaScript code. </td>
|
|
44
|
+
<td align="center">It seamlessly integrates and functions alongside any other vanilla UI or behavioral libraries. </td>
|
|
45
|
+
</tr>
|
|
46
|
+
</table>
|
|
34
47
|
|
|
35
48
|
<br clear="all" />
|
|
36
49
|
<br />
|
package/tsconfig.json
CHANGED
package/types.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export declare const templateConfig: (options: any) => void;
|
|
|
9
9
|
export declare const register: (name: string, module: any, dependencies?: any) => void
|
|
10
10
|
export declare const start: (target?: HTMLElement) => void;
|
|
11
11
|
export declare const subscribe:( subject: string, callback: (data:any) => void ) => Function
|
|
12
|
-
export declare const publish: ( subject: string, data
|
|
12
|
+
export declare const publish: ( subject: string, data ?:any ) => void
|
|
13
13
|
|
|
14
14
|
export type Component = {
|
|
15
15
|
|
|
@@ -24,11 +24,11 @@ export type Component = {
|
|
|
24
24
|
getRaw() : any
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
effect( callback: ( state: any ) => Promise<any> | void )
|
|
27
|
+
effect( callback: ( state: any ) => Promise<any> | void ): void
|
|
28
28
|
|
|
29
29
|
main( mainArgs: ( t: Component ) => void ): void
|
|
30
30
|
|
|
31
|
-
publish( name: string, value
|
|
31
|
+
publish( name: string, value?: any ) : void
|
|
32
32
|
|
|
33
33
|
subscribe( name: string, value: Function ) : Function
|
|
34
34
|
|