@toyz/loom 0.9.0 → 0.11.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 +38 -11
- package/dist/element/element.d.ts +3 -0
- package/dist/element/element.d.ts.map +1 -1
- package/dist/element/element.js +21 -0
- package/dist/element/element.js.map +1 -1
- package/dist/element/form.d.ts +3 -1
- package/dist/element/form.d.ts.map +1 -1
- package/dist/element/form.js +33 -24
- package/dist/element/form.js.map +1 -1
- package/dist/element/icon.d.ts +1 -3
- package/dist/element/icon.d.ts.map +1 -1
- package/dist/element/icon.js +20 -34
- package/dist/element/icon.js.map +1 -1
- package/dist/element/index.d.ts +0 -1
- package/dist/element/index.d.ts.map +1 -1
- package/dist/element/index.js +3 -0
- package/dist/element/index.js.map +1 -1
- package/dist/element/timing.d.ts +0 -15
- package/dist/element/timing.d.ts.map +1 -1
- package/dist/element/timing.js +22 -12
- package/dist/element/timing.js.map +1 -1
- package/dist/element/virtual.d.ts +46 -41
- package/dist/element/virtual.d.ts.map +1 -1
- package/dist/element/virtual.js +170 -101
- package/dist/element/virtual.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/jsx-runtime.d.ts.map +1 -1
- package/dist/jsx-runtime.js +85 -6
- package/dist/jsx-runtime.js.map +1 -1
- package/dist/morph.d.ts +4 -0
- package/dist/morph.d.ts.map +1 -1
- package/dist/morph.js +25 -0
- package/dist/morph.js.map +1 -1
- package/dist/query/decorators.d.ts.map +1 -1
- package/dist/query/decorators.js +10 -2
- package/dist/query/decorators.js.map +1 -1
- package/dist/store/decorators.d.ts.map +1 -1
- package/dist/store/decorators.js +18 -28
- package/dist/store/decorators.js.map +1 -1
- package/dist/store/reactive.d.ts +12 -0
- package/dist/store/reactive.d.ts.map +1 -1
- package/dist/store/reactive.js +26 -0
- package/dist/store/reactive.js.map +1 -1
- package/dist/trace.d.ts +93 -0
- package/dist/trace.d.ts.map +1 -0
- package/dist/trace.js +176 -0
- package/dist/trace.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -25,17 +25,37 @@ It powers [placing.space](https://placing.space) in production — a real-time c
|
|
|
25
25
|
|
|
26
26
|
## Features
|
|
27
27
|
|
|
28
|
-
- **`@component`** — register custom elements in one line
|
|
28
|
+
- **`@component` / `@styles`** — register custom elements and scoped styles in one line
|
|
29
29
|
- **`@reactive` / `@prop`** — fine-grained reactivity that only re-renders what changed
|
|
30
30
|
- **`@computed` / `@watch`** — derived state and side effects
|
|
31
|
-
- **`@on` / `@emit`** — declarative event handling
|
|
31
|
+
- **`@on` / `@emit`** — declarative event handling via typed event bus
|
|
32
32
|
- **JSX + DOM morphing** — write JSX, get surgical DOM patches (no virtual DOM)
|
|
33
|
-
- **`@inject` / `@service`** — dependency injection container
|
|
34
|
-
- **Hash & history router** — `@route`, `@guard`, `<loom-outlet>`
|
|
33
|
+
- **`@inject` / `@service` / `@factory`** — full dependency injection container
|
|
34
|
+
- **Hash & history router** — `@route`, `@guard`, `@group`, `<loom-outlet>`, `<loom-link>`
|
|
35
|
+
- **`@api` / `@intercept`** — declarative data fetching with SWR, retry, and Result combinators
|
|
36
|
+
- **`@lazy`** — code-split components with one decorator
|
|
37
|
+
- **`@catch_` / `@suspend`** — error boundaries and async loading state
|
|
38
|
+
- **`@interval` / `@timeout` / `@debounce` / `@throttle` / `@animationFrame`** — auto-cleaned timing
|
|
39
|
+
- **`@mount` / `@unmount`** — lifecycle hooks
|
|
40
|
+
- **`@form`** — declarative form binding with validation
|
|
41
|
+
- **`@transform`** — typed value transforms for props and route params
|
|
42
|
+
- **`Reactive<T>` / `CollectionStore<T>`** — observable state with `LocalAdapter` persistence
|
|
35
43
|
- **`css\`\``** — adopted stylesheets with zero FOUC
|
|
36
44
|
- **`<loom-virtual>`** — virtualized list for huge datasets
|
|
45
|
+
- **`createDecorator`** — build your own decorators with the same factory Loom uses
|
|
37
46
|
- **Zero dependencies** — just TypeScript and the platform
|
|
38
47
|
|
|
48
|
+
## Create a Project
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npm create @toyz/loom my-app
|
|
52
|
+
cd my-app
|
|
53
|
+
npm install
|
|
54
|
+
npm run dev
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Or install manually:
|
|
58
|
+
|
|
39
59
|
## Install
|
|
40
60
|
|
|
41
61
|
```bash
|
|
@@ -44,20 +64,27 @@ npm install @toyz/loom
|
|
|
44
64
|
|
|
45
65
|
## Quick Start
|
|
46
66
|
|
|
47
|
-
```
|
|
48
|
-
import { LoomElement, component, reactive, css } from "@toyz/loom";
|
|
67
|
+
```tsx
|
|
68
|
+
import { LoomElement, component, reactive, css, styles } from "@toyz/loom";
|
|
49
69
|
|
|
50
|
-
const
|
|
51
|
-
button {
|
|
52
|
-
|
|
70
|
+
const counterStyles = css`
|
|
71
|
+
button {
|
|
72
|
+
padding: 0.5rem 1rem;
|
|
73
|
+
border-radius: 6px;
|
|
74
|
+
cursor: pointer;
|
|
75
|
+
}
|
|
76
|
+
span {
|
|
77
|
+
font-weight: bold;
|
|
78
|
+
margin-left: 0.5rem;
|
|
79
|
+
}
|
|
53
80
|
`;
|
|
54
81
|
|
|
55
82
|
@component("click-counter")
|
|
83
|
+
@styles(counterStyles)
|
|
56
84
|
class ClickCounter extends LoomElement {
|
|
57
|
-
@reactive count = 0;
|
|
85
|
+
@reactive accessor count = 0;
|
|
58
86
|
|
|
59
87
|
update() {
|
|
60
|
-
this.shadow.adoptedStyleSheets = [styles];
|
|
61
88
|
return (
|
|
62
89
|
<button onClick={() => this.count++}>
|
|
63
90
|
Clicks: <span>{this.count}</span>
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { type Constructor, type Handler } from "../bus";
|
|
2
2
|
import { type LoomEvent } from "../event";
|
|
3
3
|
import { type CSSValue } from "../css";
|
|
4
|
+
import { type TraceDeps } from "../trace";
|
|
4
5
|
export declare abstract class LoomElement extends HTMLElement {
|
|
5
6
|
/** Access the LoomApp instance for inline provider resolution */
|
|
6
7
|
protected get app(): import("..").LoomApp;
|
|
7
8
|
protected shadow: ShadowRoot;
|
|
8
9
|
private cleanups;
|
|
10
|
+
/** @internal — dependency tracking for traced template projection */
|
|
11
|
+
__traceDeps: TraceDeps | null;
|
|
9
12
|
constructor();
|
|
10
13
|
/** Adopt styles — supports both tagged template and string */
|
|
11
14
|
protected css(text: string): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"element.d.ts","sourceRoot":"","sources":["../../src/element/element.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,WAAW,EAAE,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AAC7D,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,KAAK,QAAQ,EAAY,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"element.d.ts","sourceRoot":"","sources":["../../src/element/element.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,WAAW,EAAE,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AAC7D,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,KAAK,QAAQ,EAAY,MAAM,QAAQ,CAAC;AAIjD,OAAO,EAAqF,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAE7H,8BAAsB,WAAY,SAAQ,WAAW;IACnD,iEAAiE;IACjE,SAAS,KAAK,GAAG,yBAAkB;IAEnC,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC;IAC7B,OAAO,CAAC,QAAQ,CAAsB;IACtC,qEAAqE;IACrE,WAAW,EAAE,SAAS,GAAG,IAAI,CAAQ;;IASrC,8DAA8D;IAC9D,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IACjC,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI;IAQzE;;;;OAIG;IACH,WAAW,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI;IAU1C,8DAA8D;IAC9D,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI;IAMtE,yBAAyB;IACzB,SAAS,CAAC,IAAI,CAAC,CAAC,SAAS,SAAS,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAMnD,sDAAsD;IACtD,KAAK,CAAC,KAAK,EAAE,MAAM,IAAI,GAAG,IAAI;IAM9B,uCAAuC;IACvC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,OAAO,GAAG,WAAW,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI;IAInE,0CAA0C;IAC1C,SAAS,CAAC,EAAE,CAAC,CAAC,SAAS,OAAO,GAAG,WAAW,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE;IAM/D,iBAAiB,IAAI,IAAI;IAazB,oBAAoB,IAAI,IAAI;IAQ5B;;;OAGG;IACH,MAAM,IAAI,IAAI,GAAG,IAAI,EAAE,GAAG,IAAI;IAE9B;;;OAGG;IACH,YAAY,IAAI,IAAI;IAEpB;;;OAGG;IACH,YAAY,IAAI,OAAO;IAMvB,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,WAAW,CAAS;IAE5B,0DAA0D;IAC1D,cAAc,IAAI,IAAI;IAoDtB;;;OAGG;IACH,KAAK,IAAI,IAAI;CAKd"}
|
package/dist/element/element.js
CHANGED
|
@@ -3,11 +3,14 @@ import { adoptCSS } from "../css";
|
|
|
3
3
|
import { COMPUTED_DIRTY, REACTIVES, CONNECT_HOOKS, FIRST_UPDATED_HOOKS } from "../decorators/symbols";
|
|
4
4
|
import { morph } from "../morph";
|
|
5
5
|
import { app } from "../app";
|
|
6
|
+
import { startTrace, endTrace, hasDirtyDeps, canFastPatch, applyBindings, refreshSnapshots } from "../trace";
|
|
6
7
|
export class LoomElement extends HTMLElement {
|
|
7
8
|
/** Access the LoomApp instance for inline provider resolution */
|
|
8
9
|
get app() { return app; }
|
|
9
10
|
shadow;
|
|
10
11
|
cleanups = [];
|
|
12
|
+
/** @internal — dependency tracking for traced template projection */
|
|
13
|
+
__traceDeps = null;
|
|
11
14
|
constructor() {
|
|
12
15
|
super();
|
|
13
16
|
this.shadow = this.attachShadow({ mode: "open" });
|
|
@@ -101,15 +104,33 @@ export class LoomElement extends HTMLElement {
|
|
|
101
104
|
this._updateScheduled = false;
|
|
102
105
|
if (!this.shouldUpdate())
|
|
103
106
|
return;
|
|
107
|
+
// Tier 1 — SKIP: no traced dependency changed
|
|
108
|
+
if (this.__traceDeps && !hasDirtyDeps(this.__traceDeps))
|
|
109
|
+
return;
|
|
110
|
+
// Tier 2 — FAST PATCH: all dirty deps have bindings
|
|
111
|
+
if (this.__traceDeps && canFastPatch(this.__traceDeps)) {
|
|
112
|
+
// Dirty @computed caches (they may depend on a fast-patched reactive)
|
|
113
|
+
for (const dirtyKey of this[COMPUTED_DIRTY] ?? []) {
|
|
114
|
+
this[dirtyKey] = true;
|
|
115
|
+
}
|
|
116
|
+
applyBindings(this.__traceDeps);
|
|
117
|
+
refreshSnapshots(this.__traceDeps);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
// Tier 3 — FULL MORPH: structural change or first render
|
|
104
121
|
// Dirty all @computed caches
|
|
105
122
|
for (const dirtyKey of this[COMPUTED_DIRTY] ?? []) {
|
|
106
123
|
this[dirtyKey] = true;
|
|
107
124
|
}
|
|
125
|
+
// Trace reactive reads during update()
|
|
126
|
+
startTrace();
|
|
108
127
|
const result = this.update();
|
|
109
128
|
// Auto-morph if update() returned DOM nodes
|
|
110
129
|
if (result != null) {
|
|
111
130
|
morph(this.shadow, result);
|
|
112
131
|
}
|
|
132
|
+
// Capture/refresh dependency tracking + bindings
|
|
133
|
+
this.__traceDeps = endTrace();
|
|
113
134
|
if (!this._hasUpdated) {
|
|
114
135
|
this._hasUpdated = true;
|
|
115
136
|
this.firstUpdated();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"element.js","sourceRoot":"","sources":["../../src/element/element.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAkC,MAAM,QAAQ,CAAC;AAE7D,OAAO,EAAiB,QAAQ,EAAE,MAAM,QAAQ,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACtG,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"element.js","sourceRoot":"","sources":["../../src/element/element.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAkC,MAAM,QAAQ,CAAC;AAE7D,OAAO,EAAiB,QAAQ,EAAE,MAAM,QAAQ,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACtG,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAkB,MAAM,UAAU,CAAC;AAE7H,MAAM,OAAgB,WAAY,SAAQ,WAAW;IACnD,iEAAiE;IACjE,IAAc,GAAG,KAAK,OAAO,GAAG,CAAC,CAAC,CAAC;IAEzB,MAAM,CAAa;IACrB,QAAQ,GAAmB,EAAE,CAAC;IACtC,qEAAqE;IACrE,WAAW,GAAqB,IAAI,CAAC;IAErC;QACE,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IACpD,CAAC;IAOS,GAAG,CACX,aAA4C,EAC5C,GAAG,MAAkB;QAErB,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,CAAC,CAAC;IAClD,CAAC;IAED;;;;OAIG;IACH,WAAW,CAAC,MAAuB;QACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC;QAChD,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,kBAAkB,GAAG,CAAC,GAAG,QAAQ,EAAE,GAAG,SAAS,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,sBAAsB;IAEtB,8DAA8D;IACpD,EAAE,CAAI,IAAoB,EAAE,OAAmB;QACvD,MAAM,KAAK,GAAG,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACpC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,yBAAyB;IACf,IAAI,CAAsB,KAAQ;QAC1C,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,CAAC;IAED,yBAAyB;IAEzB,sDAAsD;IACtD,KAAK,CAAC,KAAiB;QACrB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;IAED,oBAAoB;IAEpB,uCAAuC;IAC7B,CAAC,CAAkC,GAAW;QACtD,OAAO,IAAI,CAAC,MAAM,CAAC,aAAa,CAAI,GAAG,CAAC,CAAC;IAC3C,CAAC;IAED,0CAA0C;IAChC,EAAE,CAAkC,GAAW;QACvD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAI,GAAG,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,kBAAkB;IAElB,iBAAiB;QACf,gFAAgF;QAChF,KAAK,MAAM,IAAI,IAAI,CAAE,IAAY,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YACxD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3B,IAAI,OAAO,OAAO,KAAK,UAAU;gBAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACjE,CAAC;QAED,iDAAiD;QACjD,MAAM,YAAY,GAAG,CAAE,IAAY,CAAC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACjE,MAAM,eAAe,GAAG,IAAI,CAAC,MAAM,KAAK,WAAW,CAAC,SAAS,CAAC,MAAM,CAAC;QACrE,IAAI,YAAY,IAAI,eAAe;YAAE,IAAI,CAAC,cAAc,EAAE,CAAC;IAC7D,CAAC;IAED,oBAAoB;QAClB,oEAAoE;QACpE,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;IACrB,CAAC;IAED,+CAA+C;IAE/C;;;OAGG;IACH,MAAM,KAA2B,CAAC;IAElC;;;OAGG;IACH,YAAY,KAAW,CAAC;IAExB;;;OAGG;IACH,YAAY;QACV,OAAO,IAAI,CAAC;IACd,CAAC;IAED,2BAA2B;IAEnB,gBAAgB,GAAG,KAAK,CAAC;IACzB,WAAW,GAAG,KAAK,CAAC;IAE5B,0DAA0D;IAC1D,cAAc;QACZ,IAAI,IAAI,CAAC,gBAAgB;YAAE,OAAO;QAClC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAC7B,cAAc,CAAC,GAAG,EAAE;YAClB,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;YAC9B,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;gBAAE,OAAO;YAEjC,8CAA8C;YAC9C,IAAI,IAAI,CAAC,WAAW,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC;gBAAE,OAAO;YAEhE,oDAAoD;YACpD,IAAI,IAAI,CAAC,WAAW,IAAI,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;gBACvD,sEAAsE;gBACtE,KAAK,MAAM,QAAQ,IAAK,IAAY,CAAC,cAAc,CAAC,IAAI,EAAE,EAAE,CAAC;oBAC1D,IAAY,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;gBACjC,CAAC;gBACD,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBAChC,gBAAgB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBACnC,OAAO;YACT,CAAC;YAED,yDAAyD;YACzD,6BAA6B;YAC7B,KAAK,MAAM,QAAQ,IAAK,IAAY,CAAC,cAAc,CAAC,IAAI,EAAE,EAAE,CAAC;gBAC1D,IAAY,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;YACjC,CAAC;YAED,uCAAuC;YACvC,UAAU,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YAE7B,4CAA4C;YAC5C,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;gBACnB,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAC7B,CAAC;YAED,iDAAiD;YACjD,IAAI,CAAC,WAAW,GAAG,QAAQ,EAAE,CAAC;YAE9B,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;gBACtB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;gBACxB,IAAI,CAAC,YAAY,EAAE,CAAC;gBACpB,kEAAkE;gBAClE,oEAAoE;gBACpE,KAAK,MAAM,IAAI,IAAI,CAAE,IAAY,CAAC,mBAAmB,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;oBAC9D,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;oBAC3B,IAAI,OAAO,OAAO,KAAK,UAAU;wBAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACjE,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,KAAK;QACH,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAC3B,CAAC;CACF"}
|
package/dist/element/form.d.ts
CHANGED
|
@@ -48,7 +48,9 @@ export interface FormState<T> {
|
|
|
48
48
|
bind(field: keyof T): (e: Event) => void;
|
|
49
49
|
}
|
|
50
50
|
/**
|
|
51
|
-
* Create a FormState<T> instance —
|
|
51
|
+
* Create a FormState<T> instance — backed by Reactive primitives.
|
|
52
|
+
* All state reads go through Reactive.value (traceable),
|
|
53
|
+
* all mutations go through Reactive.set()/notify() (fires subscribers).
|
|
52
54
|
*/
|
|
53
55
|
export declare function createFormState<T extends object>(schema: FormSchema<T>, scheduleUpdate: () => void): FormState<T>;
|
|
54
56
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form.d.ts","sourceRoot":"","sources":["../../src/element/form.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"form.d.ts","sourceRoot":"","sources":["../../src/element/form.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAMvC,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,OAAO;IACtC,8EAA8E;IAC9E,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,CAAC,CAAC;IAC/B,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,GAAG,MAAM,CAAC;CACxC;AAED,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI;KACzB,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CACnC,CAAC;AAEF,MAAM,WAAW,SAAS,CAAC,CAAC;IAC1B,iCAAiC;IACjC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IACjB,gEAAgE;IAChE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IAClD,0CAA0C;IAC1C,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,0DAA0D;IAC1D,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,+CAA+C;IAC/C,KAAK,IAAI,IAAI,CAAC;IACd,kEAAkE;IAClE,QAAQ,IAAI,UAAU,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IAC5D,iEAAiE;IACjE,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC;CAC1C;AAgBD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,EAC9C,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,EACrB,cAAc,EAAE,MAAM,IAAI,GACzB,SAAS,CAAC,CAAC,CAAC,CAgHd;AAID;;;;;GAKG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,MAAM,EACnC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,IAEb,IAAI,SAAS,MAAM,EACzB,SAAS,4BAA4B,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,EACzD,SAAS,6BAA6B,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,KACzD,4BAA4B,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAgBpD"}
|
package/dist/element/form.js
CHANGED
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
* ```
|
|
23
23
|
*/
|
|
24
24
|
import { LoomResult } from "../result";
|
|
25
|
+
import { Reactive } from "../store/reactive";
|
|
25
26
|
// ── Helpers ──
|
|
26
27
|
/**
|
|
27
28
|
* Read a form element's value, handling checkboxes.
|
|
@@ -34,67 +35,77 @@ function readInputValue(input) {
|
|
|
34
35
|
}
|
|
35
36
|
// ── Core ──
|
|
36
37
|
/**
|
|
37
|
-
* Create a FormState<T> instance —
|
|
38
|
+
* Create a FormState<T> instance — backed by Reactive primitives.
|
|
39
|
+
* All state reads go through Reactive.value (traceable),
|
|
40
|
+
* all mutations go through Reactive.set()/notify() (fires subscribers).
|
|
38
41
|
*/
|
|
39
42
|
export function createFormState(schema, scheduleUpdate) {
|
|
40
43
|
// Initialize all fields to empty string (or transform of empty)
|
|
41
44
|
const initial = {};
|
|
42
|
-
const
|
|
43
|
-
const errors = {};
|
|
44
|
-
const touched = new Set();
|
|
45
|
-
let validatedAll = false;
|
|
45
|
+
const initData = {};
|
|
46
46
|
for (const key of Object.keys(schema)) {
|
|
47
47
|
const fieldSchema = schema[key];
|
|
48
48
|
const raw = "";
|
|
49
49
|
const transformed = fieldSchema?.transform ? fieldSchema.transform(raw) : raw;
|
|
50
50
|
initial[key] = transformed;
|
|
51
|
-
|
|
51
|
+
initData[key] = transformed;
|
|
52
52
|
}
|
|
53
|
-
|
|
53
|
+
// Reactive-backed state
|
|
54
|
+
const currentR = new Reactive({ ...initData });
|
|
55
|
+
const errorsR = new Reactive({});
|
|
56
|
+
const validR = new Reactive(true);
|
|
57
|
+
const touched = new Set();
|
|
58
|
+
let validatedAll = false;
|
|
54
59
|
// Compute initial validity (without surfacing errors)
|
|
60
|
+
let initValid = true;
|
|
55
61
|
for (const key of Object.keys(schema)) {
|
|
56
62
|
const fieldSchema = schema[key];
|
|
57
63
|
if (fieldSchema?.validate) {
|
|
58
|
-
const result = fieldSchema.validate(
|
|
64
|
+
const result = fieldSchema.validate(initData[key]);
|
|
59
65
|
if (result !== true)
|
|
60
|
-
|
|
66
|
+
initValid = false;
|
|
61
67
|
}
|
|
62
68
|
}
|
|
69
|
+
validR.set(initValid);
|
|
63
70
|
// Validation — only surfaces errors for touched fields (or all if validate() was called)
|
|
64
71
|
function runValidation() {
|
|
72
|
+
const current = currentR.value;
|
|
73
|
+
const newErrors = {};
|
|
65
74
|
let allValid = true;
|
|
66
75
|
for (const key of Object.keys(schema)) {
|
|
67
76
|
const fieldSchema = schema[key];
|
|
68
77
|
if (fieldSchema?.validate) {
|
|
69
78
|
const result = fieldSchema.validate(current[key]);
|
|
70
79
|
if (result === true) {
|
|
71
|
-
|
|
80
|
+
// valid — no error
|
|
72
81
|
}
|
|
73
82
|
else {
|
|
74
83
|
allValid = false;
|
|
75
84
|
// Only surface error if field was touched or validate() was called
|
|
76
85
|
if (touched.has(key) || validatedAll) {
|
|
77
|
-
|
|
86
|
+
newErrors[key] = result;
|
|
78
87
|
}
|
|
79
88
|
}
|
|
80
89
|
}
|
|
81
90
|
}
|
|
82
|
-
|
|
91
|
+
errorsR.set(newErrors);
|
|
92
|
+
validR.set(allValid);
|
|
83
93
|
return allValid;
|
|
84
94
|
}
|
|
85
95
|
// Bind handlers cache
|
|
86
96
|
const bindCache = new Map();
|
|
87
97
|
const state = {
|
|
88
98
|
get data() {
|
|
89
|
-
return
|
|
99
|
+
return currentR.value;
|
|
90
100
|
},
|
|
91
101
|
get errors() {
|
|
92
|
-
return
|
|
102
|
+
return errorsR.value;
|
|
93
103
|
},
|
|
94
104
|
get valid() {
|
|
95
|
-
return
|
|
105
|
+
return validR.value;
|
|
96
106
|
},
|
|
97
107
|
get dirty() {
|
|
108
|
+
const current = currentR.value;
|
|
98
109
|
for (const key of Object.keys(schema)) {
|
|
99
110
|
if (current[key] !== initial[key])
|
|
100
111
|
return true;
|
|
@@ -102,15 +113,11 @@ export function createFormState(schema, scheduleUpdate) {
|
|
|
102
113
|
return false;
|
|
103
114
|
},
|
|
104
115
|
reset() {
|
|
105
|
-
|
|
106
|
-
current[key] = initial[key];
|
|
107
|
-
}
|
|
116
|
+
currentR.set({ ...initial });
|
|
108
117
|
touched.clear();
|
|
109
118
|
validatedAll = false;
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
delete errors[key];
|
|
113
|
-
}
|
|
119
|
+
errorsR.set({});
|
|
120
|
+
validR.set(true);
|
|
114
121
|
scheduleUpdate();
|
|
115
122
|
},
|
|
116
123
|
validate() {
|
|
@@ -118,8 +125,8 @@ export function createFormState(schema, scheduleUpdate) {
|
|
|
118
125
|
const valid = runValidation();
|
|
119
126
|
scheduleUpdate();
|
|
120
127
|
if (valid)
|
|
121
|
-
return LoomResult.ok(
|
|
122
|
-
return LoomResult.err({ ...
|
|
128
|
+
return LoomResult.ok(currentR.value);
|
|
129
|
+
return LoomResult.err({ ...errorsR.value });
|
|
123
130
|
},
|
|
124
131
|
bind(field) {
|
|
125
132
|
const key = field;
|
|
@@ -129,7 +136,9 @@ export function createFormState(schema, scheduleUpdate) {
|
|
|
129
136
|
const raw = readInputValue(input);
|
|
130
137
|
const fieldSchema = schema[field];
|
|
131
138
|
const transformed = fieldSchema?.transform ? fieldSchema.transform(raw) : raw;
|
|
139
|
+
const current = currentR.value;
|
|
132
140
|
current[key] = transformed;
|
|
141
|
+
currentR.notify();
|
|
133
142
|
touched.add(key);
|
|
134
143
|
runValidation();
|
|
135
144
|
scheduleUpdate();
|
package/dist/element/form.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form.js","sourceRoot":"","sources":["../../src/element/form.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"form.js","sourceRoot":"","sources":["../../src/element/form.ts"],"names":[],"mappings":"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"}
|
package/dist/element/icon.d.ts
CHANGED
|
@@ -27,9 +27,7 @@ export declare class LoomIcon extends LoomElement {
|
|
|
27
27
|
static has(name: string): boolean;
|
|
28
28
|
/** List all registered icon names. */
|
|
29
29
|
static get names(): string[];
|
|
30
|
-
|
|
31
|
-
attributeChangedCallback(name: string, _old: string | null, val: string | null): void;
|
|
32
|
-
connectedCallback(): void;
|
|
30
|
+
private syncVars;
|
|
33
31
|
update(): SVGSVGElement | HTMLSpanElement;
|
|
34
32
|
}
|
|
35
33
|
//# sourceMappingURL=icon.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icon.d.ts","sourceRoot":"","sources":["../../src/element/icon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"icon.d.ts","sourceRoot":"","sources":["../../src/element/icon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AA8BxC,qBAEa,QAAS,SAAQ,WAAW;IAEvC,2DAA2D;IACrD,QAAQ,CAAC,IAAI,SAAM;IAEzB,qBAAqB;IACf,QAAQ,CAAC,IAAI,SAAM;IAEzB,+BAA+B;IACzB,QAAQ,CAAC,KAAK,SAAkB;IAEtC,mFAAmF;IACnF,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAIrD,uCAAuC;IACvC,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAMvD,sCAAsC;IACtC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIjC,sCAAsC;IACtC,MAAM,KAAK,KAAK,IAAI,MAAM,EAAE,CAE3B;IAID,OAAO,CAAC,QAAQ;IAKhB,MAAM;CAaP"}
|
package/dist/element/icon.js
CHANGED
|
@@ -11,6 +11,13 @@
|
|
|
11
11
|
* // Use anywhere in JSX
|
|
12
12
|
* <loom-icon name="bolt" size={20} color="var(--accent)" />
|
|
13
13
|
*/
|
|
14
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
15
|
+
var useValue = arguments.length > 2;
|
|
16
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
17
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
18
|
+
}
|
|
19
|
+
return useValue ? value : void 0;
|
|
20
|
+
};
|
|
14
21
|
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
15
22
|
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
16
23
|
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
@@ -38,16 +45,10 @@ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn,
|
|
|
38
45
|
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
39
46
|
done = true;
|
|
40
47
|
};
|
|
41
|
-
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
42
|
-
var useValue = arguments.length > 2;
|
|
43
|
-
for (var i = 0; i < initializers.length; i++) {
|
|
44
|
-
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
45
|
-
}
|
|
46
|
-
return useValue ? value : void 0;
|
|
47
|
-
};
|
|
48
48
|
import { LoomElement } from "./element";
|
|
49
|
-
import { component } from "./decorators";
|
|
49
|
+
import { component, styles } from "./decorators";
|
|
50
50
|
import { prop } from "../store/decorators";
|
|
51
|
+
import { watch } from "../store/watch";
|
|
51
52
|
import { css } from "../css";
|
|
52
53
|
const baseStyles = css `
|
|
53
54
|
:host {
|
|
@@ -72,11 +73,12 @@ const baseStyles = css `
|
|
|
72
73
|
/** Icon path data registry (name → SVG inner content) */
|
|
73
74
|
const registry = new Map();
|
|
74
75
|
let LoomIcon = (() => {
|
|
75
|
-
let _classDecorators = [component("loom-icon")];
|
|
76
|
+
let _classDecorators = [component("loom-icon"), styles(baseStyles)];
|
|
76
77
|
let _classDescriptor;
|
|
77
78
|
let _classExtraInitializers = [];
|
|
78
79
|
let _classThis;
|
|
79
80
|
let _classSuper = LoomElement;
|
|
81
|
+
let _instanceExtraInitializers = [];
|
|
80
82
|
let _name_decorators;
|
|
81
83
|
let _name_initializers = [];
|
|
82
84
|
let _name_extraInitializers = [];
|
|
@@ -86,6 +88,7 @@ let LoomIcon = (() => {
|
|
|
86
88
|
let _color_decorators;
|
|
87
89
|
let _color_initializers = [];
|
|
88
90
|
let _color_extraInitializers = [];
|
|
91
|
+
let _syncVars_decorators;
|
|
89
92
|
var LoomIcon = class extends _classSuper {
|
|
90
93
|
static { _classThis = this; }
|
|
91
94
|
static {
|
|
@@ -93,15 +96,17 @@ let LoomIcon = (() => {
|
|
|
93
96
|
_name_decorators = [prop];
|
|
94
97
|
_size_decorators = [prop];
|
|
95
98
|
_color_decorators = [prop];
|
|
99
|
+
_syncVars_decorators = [watch("size"), watch("color")];
|
|
96
100
|
__esDecorate(this, null, _name_decorators, { kind: "accessor", name: "name", static: false, private: false, access: { has: obj => "name" in obj, get: obj => obj.name, set: (obj, value) => { obj.name = value; } }, metadata: _metadata }, _name_initializers, _name_extraInitializers);
|
|
97
101
|
__esDecorate(this, null, _size_decorators, { kind: "accessor", name: "size", static: false, private: false, access: { has: obj => "size" in obj, get: obj => obj.size, set: (obj, value) => { obj.size = value; } }, metadata: _metadata }, _size_initializers, _size_extraInitializers);
|
|
98
102
|
__esDecorate(this, null, _color_decorators, { kind: "accessor", name: "color", static: false, private: false, access: { has: obj => "color" in obj, get: obj => obj.color, set: (obj, value) => { obj.color = value; } }, metadata: _metadata }, _color_initializers, _color_extraInitializers);
|
|
103
|
+
__esDecorate(this, null, _syncVars_decorators, { kind: "method", name: "syncVars", static: false, private: false, access: { has: obj => "syncVars" in obj, get: obj => obj.syncVars }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
99
104
|
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
100
105
|
LoomIcon = _classThis = _classDescriptor.value;
|
|
101
106
|
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
102
107
|
__runInitializers(_classThis, _classExtraInitializers);
|
|
103
108
|
}
|
|
104
|
-
#name_accessor_storage = __runInitializers(this, _name_initializers, "");
|
|
109
|
+
#name_accessor_storage = (__runInitializers(this, _instanceExtraInitializers), __runInitializers(this, _name_initializers, ""));
|
|
105
110
|
/** Icon name (must be registered via LoomIcon.register) */
|
|
106
111
|
get name() { return this.#name_accessor_storage; }
|
|
107
112
|
set name(value) { this.#name_accessor_storage = value; }
|
|
@@ -131,35 +136,16 @@ let LoomIcon = (() => {
|
|
|
131
136
|
static get names() {
|
|
132
137
|
return Array.from(registry.keys());
|
|
133
138
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
// before calling us. We just sync the CSS custom properties immediately.
|
|
138
|
-
if (name === "size" && val !== null) {
|
|
139
|
-
this.style.setProperty("--_s", `${val}px`);
|
|
140
|
-
}
|
|
141
|
-
else if (name === "color" && val !== null) {
|
|
142
|
-
this.style.setProperty("--_c", val);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
connectedCallback() {
|
|
146
|
-
// Set CSS vars from current attributes before first paint
|
|
147
|
-
const s = this.getAttribute("size");
|
|
148
|
-
const c = this.getAttribute("color");
|
|
149
|
-
this.style.setProperty("--_s", `${s ?? this.size}px`);
|
|
150
|
-
if (c)
|
|
151
|
-
this.style.setProperty("--_c", c);
|
|
152
|
-
super.connectedCallback();
|
|
139
|
+
syncVars() {
|
|
140
|
+
this.style.setProperty("--_s", `${this.size}px`);
|
|
141
|
+
this.style.setProperty("--_c", this.color);
|
|
153
142
|
}
|
|
154
143
|
update() {
|
|
155
|
-
this.shadow.adoptedStyleSheets = [baseStyles];
|
|
156
144
|
this.style.setProperty("--_s", `${this.size}px`);
|
|
157
145
|
this.style.setProperty("--_c", this.color);
|
|
158
146
|
const inner = registry.get(this.name);
|
|
159
|
-
if (!inner)
|
|
160
|
-
|
|
161
|
-
return placeholder;
|
|
162
|
-
}
|
|
147
|
+
if (!inner)
|
|
148
|
+
return document.createElement("span");
|
|
163
149
|
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
164
150
|
svg.setAttribute("viewBox", "0 0 24 24");
|
|
165
151
|
svg.setAttribute("aria-hidden", "true");
|
package/dist/element/icon.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icon.js","sourceRoot":"","sources":["../../src/element/icon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"icon.js","sourceRoot":"","sources":["../../src/element/icon.ts"],"names":[],"mappings":"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"}
|
package/dist/element/index.d.ts
CHANGED
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
* LoomElement base class, built-in elements, and element decorators.
|
|
5
5
|
*/
|
|
6
6
|
export { LoomElement } from "./element";
|
|
7
|
-
export type { VirtualListOptions } from "./virtual";
|
|
8
7
|
export { component, query, queryAll, styles } from "./decorators";
|
|
9
8
|
export { catch_, suspend, mount, unmount } from "./lifecycle";
|
|
10
9
|
export { interval, timeout, debounce, throttle, animationFrame } from "./timing";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/element/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/element/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAOxC,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAGlE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAG9D,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAGjF,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAGjE,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAG1C,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAG/B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/element/index.js
CHANGED
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
*/
|
|
6
6
|
// Base element
|
|
7
7
|
export { LoomElement } from "./element";
|
|
8
|
+
// Built-in elements — import explicitly to opt-in to side effects
|
|
9
|
+
// e.g. import { LoomVirtual } from "@toyz/loom/element/virtual"
|
|
10
|
+
// e.g. import { LoomIcon } from "@toyz/loom/element/icon"
|
|
8
11
|
// Element decorators
|
|
9
12
|
export { component, query, queryAll, styles } from "./decorators";
|
|
10
13
|
// Lifecycle decorators
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/element/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAe;AACf,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/element/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAe;AACf,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,kEAAkE;AAClE,gEAAgE;AAChE,0DAA0D;AAE1D,qBAAqB;AACrB,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAElE,uBAAuB;AACvB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE9D,oBAAoB;AACpB,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAEjF,iBAAiB;AACjB,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAG9B,yBAAyB;AACzB,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAG9B,iBAAiB;AACjB,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE/B,uBAAuB;AACvB,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/element/timing.d.ts
CHANGED
|
@@ -48,21 +48,6 @@ export declare function debounce(ms: number): (method: Function, context: ClassM
|
|
|
48
48
|
* ```
|
|
49
49
|
*/
|
|
50
50
|
export declare function throttle(ms: number): (method: Function, context: ClassMethodDecoratorContext) => (this: any, ...args: unknown[]) => void;
|
|
51
|
-
/**
|
|
52
|
-
* Centralized rAF loop via RenderLoop. Method receives (deltaTime, timestamp).
|
|
53
|
-
* Use layer to control execution order (lower = earlier).
|
|
54
|
-
*
|
|
55
|
-
* ```ts
|
|
56
|
-
* @animationFrame(10) // layer 10
|
|
57
|
-
* draw(dt: number, t: number) { ... }
|
|
58
|
-
*
|
|
59
|
-
* @animationFrame() // default layer 0
|
|
60
|
-
* physics(dt: number) { ... }
|
|
61
|
-
*
|
|
62
|
-
* @animationFrame // also valid
|
|
63
|
-
* render(dt: number) { ... }
|
|
64
|
-
* ```
|
|
65
|
-
*/
|
|
66
51
|
export declare function animationFrame(layer?: number): (method: Function, context: ClassMethodDecoratorContext) => void;
|
|
67
52
|
export declare function animationFrame(method: Function, context: ClassMethodDecoratorContext): void;
|
|
68
53
|
//# sourceMappingURL=timing.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timing.d.ts","sourceRoot":"","sources":["../../src/element/timing.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH;;;;;;;;GAQG;AACH,eAAO,MAAM,QAAQ,kFAKnB,CAAC;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,OAAO,kFAKlB,CAAC;AAEH;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,IACzB,QAAQ,QAAQ,EAAE,SAAS,2BAA2B,YAIjC,GAAG,WAAW,OAAO,EAAE,UAerD;AAED;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,IACzB,QAAQ,QAAQ,EAAE,SAAS,2BAA2B,YAKjC,GAAG,WAAW,OAAO,EAAE,UAyBrD;
|
|
1
|
+
{"version":3,"file":"timing.d.ts","sourceRoot":"","sources":["../../src/element/timing.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH;;;;;;;;GAQG;AACH,eAAO,MAAM,QAAQ,kFAKnB,CAAC;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,OAAO,kFAKlB,CAAC;AAEH;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,IACzB,QAAQ,QAAQ,EAAE,SAAS,2BAA2B,YAIjC,GAAG,WAAW,OAAO,EAAE,UAerD;AAED;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,IACzB,QAAQ,QAAQ,EAAE,SAAS,2BAA2B,YAKjC,GAAG,WAAW,OAAO,EAAE,UAyBrD;AAuBD,wBAAgB,cAAc,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,2BAA2B,KAAK,IAAI,CAAC;AACjH,wBAAgB,cAAc,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,2BAA2B,GAAG,IAAI,CAAC"}
|
package/dist/element/timing.js
CHANGED
|
@@ -108,24 +108,34 @@ export function throttle(ms) {
|
|
|
108
108
|
return replacement;
|
|
109
109
|
};
|
|
110
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* Centralized rAF loop via RenderLoop. Method receives (deltaTime, timestamp).
|
|
113
|
+
* Use layer to control execution order (lower = earlier).
|
|
114
|
+
*
|
|
115
|
+
* ```ts
|
|
116
|
+
* @animationFrame(10) // layer 10
|
|
117
|
+
* draw(dt: number, t: number) { ... }
|
|
118
|
+
*
|
|
119
|
+
* @animationFrame() // default layer 0
|
|
120
|
+
* physics(dt: number) { ... }
|
|
121
|
+
*
|
|
122
|
+
* @animationFrame // also valid
|
|
123
|
+
* render(dt: number) { ... }
|
|
124
|
+
* ```
|
|
125
|
+
*/
|
|
126
|
+
const _af = createDecorator((method, _key, layer) => {
|
|
127
|
+
return (el) => {
|
|
128
|
+
return renderLoop.add(layer, (dt, t) => method.call(el, dt, t));
|
|
129
|
+
};
|
|
130
|
+
});
|
|
111
131
|
export function animationFrame(methodOrLayer, context) {
|
|
112
132
|
// Called as @animationFrame (no parens) — method is first arg
|
|
113
133
|
if (typeof methodOrLayer === "function" && context) {
|
|
114
|
-
|
|
134
|
+
_af(0)(methodOrLayer, context);
|
|
115
135
|
return;
|
|
116
136
|
}
|
|
117
137
|
// Called as @animationFrame() or @animationFrame(layer)
|
|
118
138
|
const layer = typeof methodOrLayer === "number" ? methodOrLayer : 0;
|
|
119
|
-
return (
|
|
120
|
-
}
|
|
121
|
-
/** Internal: wire rAF lifecycle via addInitializer */
|
|
122
|
-
function wireAnimationFrame(method, context, layer) {
|
|
123
|
-
context.addInitializer(function () {
|
|
124
|
-
if (!this[CONNECT_HOOKS])
|
|
125
|
-
this[CONNECT_HOOKS] = [];
|
|
126
|
-
this[CONNECT_HOOKS].push((el) => {
|
|
127
|
-
return renderLoop.add(layer, (dt, t) => method.call(el, dt, t));
|
|
128
|
-
});
|
|
129
|
-
});
|
|
139
|
+
return _af(layer);
|
|
130
140
|
}
|
|
131
141
|
//# sourceMappingURL=timing.js.map
|