@inglorious/web 5.0.1 → 6.0.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/README.md +43 -74
- package/package.json +13 -3
- package/src/directives/choose.js +1 -0
- package/src/directives/class-map.js +1 -0
- package/src/directives/ref.js +1 -0
- package/src/directives/repeat.js +1 -0
- package/src/directives/style-map.js +1 -0
- package/src/directives/unsafe-html.js +1 -0
- package/src/directives/when.js +1 -0
- package/src/index.js +0 -13
- package/src/mount.js +2 -4
- package/src/static.js +1 -0
- package/types/directives/choose.d.ts +1 -0
- package/types/directives/class-map.d.ts +1 -0
- package/types/directives/ref.d.ts +1 -0
- package/types/directives/repeat.d.ts +1 -0
- package/types/directives/style-map.d.ts +1 -0
- package/types/directives/unsafe-html.d.ts +1 -0
- package/types/directives/when.d.ts +1 -0
- package/types/index.d.ts +0 -3
- package/types/lit-html.d.ts +1 -9
- package/types/static.d.ts +1 -0
- package/types/store.d.ts +0 -15
package/README.md
CHANGED
|
@@ -283,7 +283,8 @@ First, set up your store with entity types. For each type you want to render, ad
|
|
|
283
283
|
|
|
284
284
|
```javascript
|
|
285
285
|
// store.js
|
|
286
|
-
import { createStore
|
|
286
|
+
import { createStore } from "@inglorious/store"
|
|
287
|
+
import { html } from "@inglorious/web"
|
|
287
288
|
|
|
288
289
|
const types = {
|
|
289
290
|
counter: {
|
|
@@ -503,7 +504,7 @@ test("completed todo has completed class", () => {
|
|
|
503
504
|
#### Integration Test: Full Store
|
|
504
505
|
|
|
505
506
|
```javascript
|
|
506
|
-
import { createStore } from "@inglorious/
|
|
507
|
+
import { createStore } from "@inglorious/store"
|
|
507
508
|
import { Counter } from "./types/counter.js"
|
|
508
509
|
|
|
509
510
|
test("full user interaction flow", () => {
|
|
@@ -527,7 +528,7 @@ test("full user interaction flow", () => {
|
|
|
527
528
|
#### Testing Computed State
|
|
528
529
|
|
|
529
530
|
```javascript
|
|
530
|
-
import { compute } from "@inglorious/store"
|
|
531
|
+
import { compute } from "@inglorious/store/select"
|
|
531
532
|
|
|
532
533
|
test("filtered todos excludes completed", () => {
|
|
533
534
|
const todos = [
|
|
@@ -852,7 +853,6 @@ export const App = {
|
|
|
852
853
|
create(entity) {
|
|
853
854
|
entity.title = "Todos"
|
|
854
855
|
},
|
|
855
|
-
|
|
856
856
|
render(entity, api) {
|
|
857
857
|
return html`
|
|
858
858
|
<div>
|
|
@@ -916,7 +916,7 @@ To enable DevTools, add the middleware provided by `createDevtools()`.
|
|
|
916
916
|
|
|
917
917
|
```javascript
|
|
918
918
|
// middlewares.js
|
|
919
|
-
import { createDevtools } from "@inglorious/
|
|
919
|
+
import { createDevtools } from "@inglorious/store/client/devtools"
|
|
920
920
|
|
|
921
921
|
export const middlewares = []
|
|
922
922
|
|
|
@@ -930,7 +930,7 @@ if (import.meta.env.DEV) {
|
|
|
930
930
|
|
|
931
931
|
```javascript
|
|
932
932
|
// store.js
|
|
933
|
-
import { createStore } from "@inglorious/
|
|
933
|
+
import { createStore } from "@inglorious/store"
|
|
934
934
|
import { middlewares } from "./middlewares.js"
|
|
935
935
|
|
|
936
936
|
export const store = createStore({
|
|
@@ -962,14 +962,13 @@ To enable the router, add it to your store's types and create a `router` entity.
|
|
|
962
962
|
|
|
963
963
|
```javascript
|
|
964
964
|
// store.js
|
|
965
|
-
import { createStore
|
|
965
|
+
import { createStore } from "@inglorious/store"
|
|
966
|
+
import { html } from "@inglorious/web"
|
|
966
967
|
import { Router, setRoutes } from "@inglorious/web/router"
|
|
967
968
|
|
|
968
969
|
const types = {
|
|
969
970
|
// 1. Add the router type to your store's types
|
|
970
|
-
Router,
|
|
971
|
-
|
|
972
|
-
// 2. Define types for your pages
|
|
971
|
+
Router, // 2. Define types for your pages
|
|
973
972
|
HomePage: {
|
|
974
973
|
render: () => html`<h1>Welcome Home!</h1>`,
|
|
975
974
|
},
|
|
@@ -1062,8 +1061,7 @@ const entities = {
|
|
|
1062
1061
|
export const store = createStore({ types, entities })
|
|
1063
1062
|
|
|
1064
1063
|
setRoutes({
|
|
1065
|
-
"/": "homePage",
|
|
1066
|
-
// Lazy load: returns a Promise resolving to a module
|
|
1064
|
+
"/": "homePage", // Lazy load: returns a Promise resolving to a module
|
|
1067
1065
|
"/admin": () => import("./pages/admin.js"),
|
|
1068
1066
|
})
|
|
1069
1067
|
```
|
|
@@ -1115,19 +1113,15 @@ export const requireAuth = (type) => ({
|
|
|
1115
1113
|
|
|
1116
1114
|
```javascript
|
|
1117
1115
|
// store.js
|
|
1118
|
-
import { createStore } from "@inglorious/
|
|
1116
|
+
import { createStore } from "@inglorious/store"
|
|
1119
1117
|
import { Router } from "@inglorious/web/router"
|
|
1120
1118
|
import { requireAuth } from "./guards/require-auth.js"
|
|
1121
1119
|
import { AdminPage } from "./pages/admin.js"
|
|
1122
1120
|
import { LoginPage } from "./pages/login.js"
|
|
1123
1121
|
|
|
1124
1122
|
const types = {
|
|
1125
|
-
Router,
|
|
1126
|
-
|
|
1127
|
-
// Public page - no guard
|
|
1128
|
-
LoginPage,
|
|
1129
|
-
|
|
1130
|
-
// Protected page - composed with requireAuth guard
|
|
1123
|
+
Router, // Public page - no guard
|
|
1124
|
+
LoginPage, // Protected page - composed with requireAuth guard
|
|
1131
1125
|
AdminPage: [AdminPage, requireAuth],
|
|
1132
1126
|
}
|
|
1133
1127
|
|
|
@@ -1173,9 +1167,7 @@ You can compose multiple guards for fine-grained control:
|
|
|
1173
1167
|
```javascript
|
|
1174
1168
|
const types = {
|
|
1175
1169
|
// Require authentication AND admin role
|
|
1176
|
-
AdminPage: [AdminPage, requireAuth, requireAdmin],
|
|
1177
|
-
|
|
1178
|
-
// Require authentication AND resource ownership
|
|
1170
|
+
AdminPage: [AdminPage, requireAuth, requireAdmin], // Require authentication AND resource ownership
|
|
1179
1171
|
UserProfile: [UserProfile, requireAuth, requireOwnership],
|
|
1180
1172
|
}
|
|
1181
1173
|
```
|
|
@@ -1196,9 +1188,7 @@ const logging = (type) => ({
|
|
|
1196
1188
|
render(entity, api) {
|
|
1197
1189
|
console.log(`Rendering ${entity.id}`)
|
|
1198
1190
|
return type.render(entity, api)
|
|
1199
|
-
},
|
|
1200
|
-
|
|
1201
|
-
// Intercept any event
|
|
1191
|
+
}, // Intercept any event
|
|
1202
1192
|
someEvent(entity, payload, api) {
|
|
1203
1193
|
console.log(`Event triggered on ${entity.id}`)
|
|
1204
1194
|
type.someEvent?.(entity, payload, api)
|
|
@@ -1247,7 +1237,7 @@ For ready-made UI primitives (controls, data display, navigation, feedback, layo
|
|
|
1247
1237
|
Include `form` in your `types` and create an entity for the form (use any id you like — `form` is used below for clarity):
|
|
1248
1238
|
|
|
1249
1239
|
```javascript
|
|
1250
|
-
import { createStore } from "@inglorious/
|
|
1240
|
+
import { createStore } from "@inglorious/store"
|
|
1251
1241
|
import { Form } from "@inglorious/web/form"
|
|
1252
1242
|
|
|
1253
1243
|
const types = { Form }
|
|
@@ -1334,11 +1324,9 @@ export const DataGrid = {
|
|
|
1334
1324
|
</div>
|
|
1335
1325
|
`
|
|
1336
1326
|
},
|
|
1337
|
-
|
|
1338
1327
|
renderRow(entity, row, api) {
|
|
1339
1328
|
return html`<div class="data-grid-row">${row.name}</div>`
|
|
1340
1329
|
},
|
|
1341
|
-
|
|
1342
1330
|
rowClick(entity, row) {
|
|
1343
1331
|
entity.selectedRow = row
|
|
1344
1332
|
},
|
|
@@ -1441,14 +1429,11 @@ import "@shoelace-style/shoelace/dist/components/color-picker/color-picker.js"
|
|
|
1441
1429
|
|
|
1442
1430
|
const types = {
|
|
1443
1431
|
// App-specific type - full store integration
|
|
1444
|
-
ProductTable,
|
|
1445
|
-
|
|
1446
|
-
// Web Component - for specialized UI
|
|
1432
|
+
ProductTable, // Web Component - for specialized UI
|
|
1447
1433
|
ThemeEditor: {
|
|
1448
1434
|
colorChange(entity, color) {
|
|
1449
1435
|
entity.primaryColor = color
|
|
1450
1436
|
},
|
|
1451
|
-
|
|
1452
1437
|
render(entity, api) {
|
|
1453
1438
|
return html`
|
|
1454
1439
|
<div>
|
|
@@ -1482,13 +1467,11 @@ const types = {
|
|
|
1482
1467
|
`
|
|
1483
1468
|
},
|
|
1484
1469
|
},
|
|
1485
|
-
|
|
1486
1470
|
Header: {
|
|
1487
1471
|
render(entity, api) {
|
|
1488
1472
|
return html`<header>${entity.title}</header>`
|
|
1489
1473
|
},
|
|
1490
1474
|
},
|
|
1491
|
-
|
|
1492
1475
|
Content: {
|
|
1493
1476
|
render(entity, api) {
|
|
1494
1477
|
return html`<main>${entity.text}</main>`
|
|
@@ -1518,7 +1501,6 @@ const Header = {
|
|
|
1518
1501
|
create(entity) {
|
|
1519
1502
|
entity.title = "Welcome"
|
|
1520
1503
|
},
|
|
1521
|
-
|
|
1522
1504
|
render(entity, api) {
|
|
1523
1505
|
return html`<header>${entity.title}</header>`
|
|
1524
1506
|
},
|
|
@@ -1560,51 +1542,38 @@ The `renderFn` receives a powerful `api` object that contains all methods from t
|
|
|
1560
1542
|
|
|
1561
1543
|
This method is the cornerstone of entity-based rendering. It looks up an entity by its `id`, finds its corresponding type definition, and calls the `render(entity, api)` method on that type. When you pass `typeName` and `Type`, it will lazily register the type with `api.setType(typeName, Type)` if the type is not already present.
|
|
1562
1544
|
|
|
1563
|
-
###
|
|
1545
|
+
### Package Entry Points
|
|
1546
|
+
|
|
1547
|
+
`@inglorious/web` keeps its root entry point intentionally small:
|
|
1548
|
+
|
|
1549
|
+
```javascript
|
|
1550
|
+
import { mount, html, svg } from "@inglorious/web"
|
|
1551
|
+
```
|
|
1564
1552
|
|
|
1565
|
-
|
|
1553
|
+
Import everything else from the package that owns it, or from an explicit `@inglorious/web` subpath:
|
|
1566
1554
|
|
|
1567
1555
|
```javascript
|
|
1568
|
-
import {
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
choose,
|
|
1582
|
-
classMap,
|
|
1583
|
-
ref,
|
|
1584
|
-
repeat,
|
|
1585
|
-
styleMap,
|
|
1586
|
-
unsafeHTML,
|
|
1587
|
-
when,
|
|
1588
|
-
} from "@inglorious/web"
|
|
1589
|
-
|
|
1590
|
-
// Subpath imports for tree-shaking
|
|
1591
|
-
import {
|
|
1592
|
-
Form,
|
|
1593
|
-
getFieldError,
|
|
1594
|
-
getFieldValue,
|
|
1595
|
-
isFieldTouched,
|
|
1596
|
-
} from "@inglorious/web/form"
|
|
1597
|
-
import {
|
|
1598
|
-
Router,
|
|
1599
|
-
getRoutes,
|
|
1600
|
-
getRoute,
|
|
1601
|
-
setRoutes,
|
|
1602
|
-
addRoute,
|
|
1603
|
-
removeRoute,
|
|
1604
|
-
} from "@inglorious/web/router"
|
|
1556
|
+
import { createStore } from "@inglorious/store"
|
|
1557
|
+
import { handleAsync } from "@inglorious/store/async"
|
|
1558
|
+
import { withOptimistic } from "@inglorious/store/optimistic"
|
|
1559
|
+
import { compute, createSelector } from "@inglorious/store/select"
|
|
1560
|
+
import { createDevtools } from "@inglorious/store/client/devtools"
|
|
1561
|
+
|
|
1562
|
+
import { classMap } from "@inglorious/web/directives/class-map"
|
|
1563
|
+
import { ref, createRef } from "@inglorious/web/directives/ref"
|
|
1564
|
+
import { repeat } from "@inglorious/web/directives/repeat"
|
|
1565
|
+
import { styleMap } from "@inglorious/web/directives/style-map"
|
|
1566
|
+
import { unsafeHTML } from "@inglorious/web/directives/unsafe-html"
|
|
1567
|
+
import { when } from "@inglorious/web/directives/when"
|
|
1568
|
+
import { staticHtml, unsafeStatic } from "@inglorious/web/static"
|
|
1605
1569
|
import { render, trigger } from "@inglorious/web/test"
|
|
1570
|
+
|
|
1571
|
+
import { Form } from "@inglorious/web/form"
|
|
1572
|
+
import { Router, setRoutes } from "@inglorious/web/router"
|
|
1606
1573
|
```
|
|
1607
1574
|
|
|
1575
|
+
This keeps `lit-html` as an internal implementation detail while still giving applications stable, tree-shakeable import paths.
|
|
1576
|
+
|
|
1608
1577
|
---
|
|
1609
1578
|
|
|
1610
1579
|
## Error Handling
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inglorious/web",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.0",
|
|
4
4
|
"description": "A new web framework that leverages the power of the Inglorious Store combined with the performance and simplicity of lit-html.",
|
|
5
5
|
"author": "IceOnFire <antony.mistretta@gmail.com> (https://ingloriouscoderz.it)",
|
|
6
6
|
"license": "MIT",
|
|
@@ -26,6 +26,10 @@
|
|
|
26
26
|
"types": "./types/index.d.ts",
|
|
27
27
|
"import": "./src/index.js"
|
|
28
28
|
},
|
|
29
|
+
"./directives/*": {
|
|
30
|
+
"types": "./types/directives/*.d.ts",
|
|
31
|
+
"import": "./src/directives/*.js"
|
|
32
|
+
},
|
|
29
33
|
"./form": {
|
|
30
34
|
"types": "./types/form.d.ts",
|
|
31
35
|
"import": "./src/form/index.js"
|
|
@@ -35,6 +39,10 @@
|
|
|
35
39
|
"types": "./types/router.d.ts",
|
|
36
40
|
"import": "./src/router/index.js"
|
|
37
41
|
},
|
|
42
|
+
"./static": {
|
|
43
|
+
"types": "./types/static.d.ts",
|
|
44
|
+
"import": "./src/static.js"
|
|
45
|
+
},
|
|
38
46
|
"./test": {
|
|
39
47
|
"import": "./src/test.js"
|
|
40
48
|
}
|
|
@@ -51,8 +59,10 @@
|
|
|
51
59
|
"dependencies": {
|
|
52
60
|
"@lit-labs/ssr-client": "^1.1.8",
|
|
53
61
|
"lit-html": "^3.3.1",
|
|
54
|
-
"@inglorious/utils": "3.8.0"
|
|
55
|
-
|
|
62
|
+
"@inglorious/utils": "3.8.0"
|
|
63
|
+
},
|
|
64
|
+
"peerDependencies": {
|
|
65
|
+
"@inglorious/store": "11.0.0"
|
|
56
66
|
},
|
|
57
67
|
"devDependencies": {
|
|
58
68
|
"prettier": "^3.6.2",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { choose } from "lit-html/directives/choose.js"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { classMap } from "lit-html/directives/class-map.js"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createRef, ref } from "lit-html/directives/ref.js"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { repeat } from "lit-html/directives/repeat.js"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { styleMap } from "lit-html/directives/style-map.js"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { unsafeHTML } from "lit-html/directives/unsafe-html.js"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { when } from "lit-html/directives/when.js"
|
package/src/index.js
CHANGED
|
@@ -1,15 +1,2 @@
|
|
|
1
1
|
export { mount } from "./mount.js"
|
|
2
|
-
export { createStore } from "@inglorious/store"
|
|
3
|
-
export { createDevtools } from "@inglorious/store/client/devtools.js"
|
|
4
|
-
export { compute } from "@inglorious/store/select.js"
|
|
5
|
-
export { createSelector } from "@inglorious/store/select.js"
|
|
6
|
-
export { trigger } from "@inglorious/store/test.js"
|
|
7
2
|
export { html, svg } from "lit-html"
|
|
8
|
-
export { choose } from "lit-html/directives/choose.js"
|
|
9
|
-
export { classMap } from "lit-html/directives/class-map.js"
|
|
10
|
-
export { ref } from "lit-html/directives/ref.js"
|
|
11
|
-
export { repeat } from "lit-html/directives/repeat.js"
|
|
12
|
-
export { styleMap } from "lit-html/directives/style-map.js"
|
|
13
|
-
export { unsafeHTML } from "lit-html/directives/unsafe-html.js"
|
|
14
|
-
export { when } from "lit-html/directives/when.js"
|
|
15
|
-
export { html as staticHtml, unsafeStatic } from "lit-html/static.js"
|
package/src/mount.js
CHANGED
|
@@ -10,15 +10,13 @@ import { html, render } from "lit-html"
|
|
|
10
10
|
* @param {Store} store - The application state store.
|
|
11
11
|
* @param {(api: Api) => TemplateResult | null} renderFn - The root render function.
|
|
12
12
|
* @param {HTMLElement | DocumentFragment} element - The DOM element to mount the template to.
|
|
13
|
-
* @param {Object} [options] - Mount options.
|
|
14
|
-
* @param {boolean} [options.hydrate=true] - Whether to hydrate the existing DOM.
|
|
15
13
|
* @returns {() => void} An unsubscribe function
|
|
16
14
|
*/
|
|
17
|
-
export async function mount(store, renderFn, element
|
|
15
|
+
export async function mount(store, renderFn, element) {
|
|
18
16
|
const api = { ...store._api }
|
|
19
17
|
api.render = createRender(api)
|
|
20
18
|
|
|
21
|
-
const shouldHydrate =
|
|
19
|
+
const shouldHydrate = element.hasChildNodes()
|
|
22
20
|
|
|
23
21
|
// If we need to hydrate, load the heavy lifting only now
|
|
24
22
|
if (shouldHydrate) {
|
package/src/static.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { html as staticHtml, unsafeStatic } from "lit-html/static.js"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { choose } from "lit-html/directives/choose"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { classMap } from "lit-html/directives/class-map"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createRef, ref } from "lit-html/directives/ref"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { repeat } from "lit-html/directives/repeat"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { styleMap } from "lit-html/directives/style-map"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { unsafeHTML } from "lit-html/directives/unsafe-html"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { when } from "lit-html/directives/when"
|
package/types/index.d.ts
CHANGED
package/types/lit-html.d.ts
CHANGED
|
@@ -1,9 +1 @@
|
|
|
1
|
-
export { html, TemplateResult } from "lit-html"
|
|
2
|
-
|
|
3
|
-
export { choose } from "lit-html/directives/choose"
|
|
4
|
-
export { classMap } from "lit-html/directives/class-map"
|
|
5
|
-
export { ref } from "lit-html/directives/ref"
|
|
6
|
-
export { repeat } from "lit-html/directives/repeat"
|
|
7
|
-
export { styleMap } from "lit-html/directives/style-map"
|
|
8
|
-
export { unsafeHTML } from "lit-html/directives/unsafe-html"
|
|
9
|
-
export { when } from "lit-html/directives/when"
|
|
1
|
+
export { html, svg, TemplateResult } from "lit-html"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { html as staticHtml, unsafeStatic } from "lit-html/static"
|
package/types/store.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export {
|
|
2
|
-
BaseEntity,
|
|
3
|
-
EntitiesState,
|
|
4
|
-
Event,
|
|
5
|
-
Middleware,
|
|
6
|
-
createStore,
|
|
7
|
-
TypesConfig,
|
|
8
|
-
} from "@inglorious/store"
|
|
9
|
-
|
|
10
|
-
export { compute } from "@inglorious/store/select"
|
|
11
|
-
export { createSelector } from "@inglorious/store/select"
|
|
12
|
-
export { trigger } from "@inglorious/store/test"
|
|
13
|
-
|
|
14
|
-
export { createDevtools } from "@inglorious/store/client/devtools"
|
|
15
|
-
export { multiplayerMiddleware } from "@inglorious/store/client/multiplayer-middleware"
|