@toyz/loom 0.3.0 → 0.5.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/dist/app.d.ts +4 -1
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +9 -9
- package/dist/app.js.map +1 -1
- package/dist/decorators/create.d.ts +16 -25
- package/dist/decorators/create.d.ts.map +1 -1
- package/dist/decorators/create.js +25 -34
- package/dist/decorators/create.js.map +1 -1
- package/dist/decorators/events.d.ts +10 -8
- package/dist/decorators/events.d.ts.map +1 -1
- package/dist/decorators/events.js +53 -43
- package/dist/decorators/events.js.map +1 -1
- package/dist/decorators/symbols.d.ts +4 -0
- package/dist/decorators/symbols.d.ts.map +1 -1
- package/dist/decorators/symbols.js +4 -0
- package/dist/decorators/symbols.js.map +1 -1
- package/dist/di/decorators.d.ts +15 -15
- package/dist/di/decorators.d.ts.map +1 -1
- package/dist/di/decorators.js +23 -33
- package/dist/di/decorators.js.map +1 -1
- package/dist/di/watch.d.ts +1 -7
- package/dist/di/watch.d.ts.map +1 -1
- package/dist/di/watch.js +17 -20
- package/dist/di/watch.js.map +1 -1
- package/dist/element/decorators.d.ts +26 -10
- package/dist/element/decorators.d.ts.map +1 -1
- package/dist/element/decorators.js +75 -31
- package/dist/element/decorators.js.map +1 -1
- package/dist/element/element.d.ts.map +1 -1
- package/dist/element/element.js +15 -3
- package/dist/element/element.js.map +1 -1
- package/dist/element/form.d.ts +63 -0
- package/dist/element/form.d.ts.map +1 -0
- package/dist/element/form.js +167 -0
- package/dist/element/form.js.map +1 -0
- package/dist/element/icon.d.ts +3 -3
- package/dist/element/icon.d.ts.map +1 -1
- package/dist/element/icon.js +131 -74
- package/dist/element/icon.js.map +1 -1
- package/dist/element/index.d.ts +8 -1
- package/dist/element/index.d.ts.map +1 -1
- package/dist/element/index.js +9 -1
- package/dist/element/index.js.map +1 -1
- package/dist/element/lazy.d.ts +31 -0
- package/dist/element/lazy.d.ts.map +1 -0
- package/dist/element/lazy.js +71 -0
- package/dist/element/lazy.js.map +1 -0
- package/dist/element/lifecycle.d.ts +27 -29
- package/dist/element/lifecycle.d.ts.map +1 -1
- package/dist/element/lifecycle.js +60 -79
- package/dist/element/lifecycle.js.map +1 -1
- package/dist/element/slots.d.ts +23 -0
- package/dist/element/slots.d.ts.map +1 -0
- package/dist/element/slots.js +54 -0
- package/dist/element/slots.js.map +1 -0
- package/dist/element/timing.d.ts +10 -7
- package/dist/element/timing.d.ts.map +1 -1
- package/dist/element/timing.js +67 -52
- package/dist/element/timing.js.map +1 -1
- package/dist/element/transition.d.ts +32 -0
- package/dist/element/transition.d.ts.map +1 -0
- package/dist/element/transition.js +70 -0
- package/dist/element/transition.js.map +1 -0
- package/dist/element/virtual.js +235 -194
- package/dist/element/virtual.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/router/decorators.d.ts +9 -38
- package/dist/router/decorators.d.ts.map +1 -1
- package/dist/router/decorators.js +7 -52
- package/dist/router/decorators.js.map +1 -1
- package/dist/router/index.d.ts +1 -0
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +2 -0
- package/dist/router/index.js.map +1 -1
- package/dist/router/link.d.ts +4 -4
- package/dist/router/link.d.ts.map +1 -1
- package/dist/router/link.js +134 -72
- package/dist/router/link.js.map +1 -1
- package/dist/router/outlet.d.ts +2 -2
- package/dist/router/outlet.d.ts.map +1 -1
- package/dist/router/outlet.js +188 -138
- package/dist/router/outlet.js.map +1 -1
- package/dist/router/route-lifecycle.d.ts +28 -0
- package/dist/router/route-lifecycle.d.ts.map +1 -0
- package/dist/router/route-lifecycle.js +47 -0
- package/dist/router/route-lifecycle.js.map +1 -0
- package/dist/router/route.d.ts +1 -1
- package/dist/router/route.d.ts.map +1 -1
- package/dist/router/router.d.ts +5 -0
- package/dist/router/router.d.ts.map +1 -1
- package/dist/router/router.js +41 -4
- package/dist/router/router.js.map +1 -1
- package/dist/store/decorators.d.ts +39 -15
- package/dist/store/decorators.d.ts.map +1 -1
- package/dist/store/decorators.js +167 -79
- package/dist/store/decorators.js.map +1 -1
- package/dist/store/index.d.ts +1 -1
- package/dist/store/index.d.ts.map +1 -1
- package/dist/store/index.js +1 -1
- package/dist/store/index.js.map +1 -1
- package/dist/store/watch.d.ts +12 -11
- package/dist/store/watch.d.ts.map +1 -1
- package/dist/store/watch.js +20 -15
- package/dist/store/watch.js.map +1 -1
- package/dist/testing.d.ts +55 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +99 -0
- package/dist/testing.js.map +1 -0
- package/dist/transform/transform.d.ts +7 -3
- package/dist/transform/transform.d.ts.map +1 -1
- package/dist/transform/transform.js +17 -9
- package/dist/transform/transform.js.map +1 -1
- package/dist/transform/typed.d.ts +1 -1
- package/dist/transform/typed.d.ts.map +1 -1
- package/dist/transform/typed.js.map +1 -1
- package/package.json +5 -1
package/dist/di/decorators.js
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Loom — DI decorators
|
|
2
|
+
* Loom — DI decorators (TC39 Stage 3)
|
|
3
3
|
*
|
|
4
4
|
* @service — Auto-instantiated singleton, registered on app.start()
|
|
5
|
-
* @inject —
|
|
5
|
+
* @inject — Auto-accessor dependency injection (property mode only)
|
|
6
6
|
* @factory — Method decorator, return value registered as a provider
|
|
7
|
+
*
|
|
8
|
+
* Note: TC39 does not support parameter decorators.
|
|
9
|
+
* Use @inject as a property accessor: `@inject(Foo) accessor foo!: Foo;`
|
|
7
10
|
*/
|
|
8
|
-
import { INJECT_PARAMS } from "../decorators/symbols";
|
|
9
11
|
import { app } from "../app";
|
|
10
12
|
import { createDecorator } from "../decorators/create";
|
|
11
13
|
/**
|
|
12
14
|
* Auto-instantiated singleton. Registered on app.start().
|
|
13
|
-
* Constructor @inject params are resolved automatically.
|
|
14
15
|
*
|
|
15
16
|
* ```ts
|
|
16
17
|
* @service
|
|
@@ -21,51 +22,40 @@ export const service = createDecorator((ctor) => {
|
|
|
21
22
|
app.registerService(ctor);
|
|
22
23
|
}, { class: true });
|
|
23
24
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* Property: @inject(Foo) foo!: Foo;
|
|
27
|
-
* Constructor: constructor(@inject(Config) config: Config)
|
|
28
|
-
* Factory arg: createChat(@inject(NatsConn) nc: NatsConn)
|
|
25
|
+
* Property-mode dependency injection via auto-accessor.
|
|
26
|
+
* Resolves lazily from the DI container on first access.
|
|
29
27
|
*
|
|
30
|
-
*
|
|
28
|
+
* ```ts
|
|
29
|
+
* @inject(AuthService) accessor auth!: AuthService;
|
|
30
|
+
* ```
|
|
31
31
|
*/
|
|
32
32
|
export function inject(key) {
|
|
33
|
-
return (
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
// Property decorator → lazy getter (define-time)
|
|
44
|
-
Object.defineProperty(target, propOrMethod, {
|
|
45
|
-
get() {
|
|
46
|
-
return app.get(key);
|
|
47
|
-
},
|
|
48
|
-
configurable: true,
|
|
49
|
-
});
|
|
50
|
-
}
|
|
33
|
+
return (_target, _context) => {
|
|
34
|
+
return {
|
|
35
|
+
get() {
|
|
36
|
+
return app.get(key);
|
|
37
|
+
},
|
|
38
|
+
set(_val) {
|
|
39
|
+
// Injection is read-only
|
|
40
|
+
},
|
|
41
|
+
};
|
|
51
42
|
};
|
|
52
43
|
}
|
|
53
44
|
/**
|
|
54
45
|
* Method decorator on @service classes.
|
|
55
46
|
* Return value is registered as a provider on app.start().
|
|
56
|
-
* Supports @inject on parameters. Async methods are awaited.
|
|
57
47
|
*
|
|
58
48
|
* ```ts
|
|
59
49
|
* @service
|
|
60
50
|
* class Boot {
|
|
61
51
|
* @factory(ChatServiceNatsClient)
|
|
62
|
-
* createChat(
|
|
63
|
-
* return new ChatServiceNatsClient(
|
|
52
|
+
* createChat() {
|
|
53
|
+
* return new ChatServiceNatsClient(app.get(NatsConnection));
|
|
64
54
|
* }
|
|
65
55
|
* }
|
|
66
56
|
* ```
|
|
67
57
|
*/
|
|
68
|
-
export const factory = createDecorator((
|
|
69
|
-
app.registerFactory(key,
|
|
58
|
+
export const factory = createDecorator((method, methodName, key) => {
|
|
59
|
+
app.registerFactory(key, { method: methodName, fn: method });
|
|
70
60
|
});
|
|
71
61
|
//# sourceMappingURL=decorators.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decorators.js","sourceRoot":"","sources":["../../src/di/decorators.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"decorators.js","sourceRoot":"","sources":["../../src/di/decorators.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,eAAe,CAAK,CAAC,IAAI,EAAE,EAAE;IAClD,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AAEpB;;;;;;;GAOG;AACH,MAAM,UAAU,MAAM,CAAc,GAAkC;IACpE,OAAO,CACL,OAA8C,EAC9C,QAAgD,EACT,EAAE;QACzC,OAAO;YACL,GAAG;gBACD,OAAO,GAAG,CAAC,GAAG,CAAI,GAAG,CAAC,CAAC;YACzB,CAAC;YACD,GAAG,CAAC,IAAO;gBACT,yBAAyB;YAC3B,CAAC;SACF,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,eAAe,CAAkB,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE;IAClF,GAAG,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;AAC/D,CAAC,CAAC,CAAC"}
|
package/dist/di/watch.d.ts
CHANGED
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Loom — DI @watch
|
|
3
|
-
*
|
|
4
|
-
* Form 3: Watch a DI-resolved service (or a reactive property on it).
|
|
5
|
-
* Resolves via app.get() at connectedCallback time.
|
|
6
|
-
*/
|
|
7
1
|
/**
|
|
8
2
|
* React to changes on a DI-resolved service.
|
|
9
3
|
*
|
|
@@ -19,5 +13,5 @@
|
|
|
19
13
|
* onTheme(value: string, prev: string) { ... }
|
|
20
14
|
* ```
|
|
21
15
|
*/
|
|
22
|
-
export declare function watch(service: new (...args:
|
|
16
|
+
export declare function watch(service: new (...args: unknown[]) => unknown, prop?: string): (method: Function, context: ClassMethodDecoratorContext) => void;
|
|
23
17
|
//# sourceMappingURL=watch.d.ts.map
|
package/dist/di/watch.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/di/watch.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/di/watch.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,EAAE,IAAI,CAAC,EAAE,MAAM,IACvE,QAAQ,QAAQ,EAAE,SAAS,2BAA2B,UAmB/D"}
|
package/dist/di/watch.js
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Loom — DI @watch
|
|
3
|
-
*
|
|
4
|
-
* Form 3: Watch a DI-resolved service (or a reactive property on it).
|
|
5
|
-
* Resolves via app.get() at connectedCallback time.
|
|
6
|
-
*/
|
|
7
1
|
import { app } from "../app";
|
|
2
|
+
import { CONNECT_HOOKS } from "../decorators/symbols";
|
|
8
3
|
/**
|
|
9
4
|
* React to changes on a DI-resolved service.
|
|
10
5
|
*
|
|
@@ -21,21 +16,23 @@ import { app } from "../app";
|
|
|
21
16
|
* ```
|
|
22
17
|
*/
|
|
23
18
|
export function watch(service, prop) {
|
|
24
|
-
return (
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
19
|
+
return (method, context) => {
|
|
20
|
+
context.addInitializer(function () {
|
|
21
|
+
if (!this[CONNECT_HOOKS])
|
|
22
|
+
this[CONNECT_HOOKS] = [];
|
|
23
|
+
this[CONNECT_HOOKS].push((el) => {
|
|
24
|
+
const svc = app.get(service);
|
|
25
|
+
const reactive = prop ? svc[prop] : svc;
|
|
26
|
+
if (typeof reactive?.subscribe !== "function") {
|
|
27
|
+
throw new Error(`[loom] @watch: ${service.name}${prop ? "." + prop : ""} is not a Reactive`);
|
|
28
|
+
}
|
|
29
|
+
const unsub = reactive.subscribe((v, p) => {
|
|
30
|
+
method.call(el, v, p);
|
|
31
|
+
el.scheduleUpdate?.();
|
|
32
|
+
});
|
|
33
|
+
return unsub;
|
|
36
34
|
});
|
|
37
|
-
|
|
38
|
-
};
|
|
35
|
+
});
|
|
39
36
|
};
|
|
40
37
|
}
|
|
41
38
|
//# sourceMappingURL=watch.js.map
|
package/dist/di/watch.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/di/watch.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/di/watch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,KAAK,CAAC,OAA4C,EAAE,IAAa;IAC/E,OAAO,CAAC,MAAgB,EAAE,OAAoC,EAAE,EAAE;QAChE,OAAO,CAAC,cAAc,CAAC;YACrB,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC;gBAAE,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,CAAC;YACnD,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,EAAO,EAAE,EAAE;gBACnC,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAE,GAA+B,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;gBACrE,IAAI,OAAQ,QAAqC,EAAE,SAAS,KAAK,UAAU,EAAE,CAAC;oBAC5E,MAAM,IAAI,KAAK,CACb,kBAAkB,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,oBAAoB,CAC5E,CAAC;gBACJ,CAAC;gBACD,MAAM,KAAK,GAAI,QAAoC,CAAC,SAAS,CAAC,CAAC,CAAU,EAAE,CAAU,EAAE,EAAE;oBACvF,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;oBACtB,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC;gBACxB,CAAC,CAAC,CAAC;gBACH,OAAO,KAAK,CAAC;YACf,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Loom — Element decorators
|
|
2
|
+
* Loom — Element decorators (TC39 Stage 3)
|
|
3
3
|
*
|
|
4
4
|
* @component — Register a class as a custom element
|
|
5
|
-
* @query — Lazy shadow DOM querySelector
|
|
6
|
-
* @queryAll — Lazy shadow DOM querySelectorAll
|
|
5
|
+
* @query — Lazy shadow DOM querySelector (auto-accessor)
|
|
6
|
+
* @queryAll — Lazy shadow DOM querySelectorAll (auto-accessor)
|
|
7
|
+
* @styles — Adopt CSSStyleSheets on connect (class decorator)
|
|
7
8
|
*/
|
|
8
9
|
/**
|
|
9
10
|
* Register a class as a custom element. Wires @prop observed attributes
|
|
@@ -14,19 +15,34 @@
|
|
|
14
15
|
* class MyCounter extends LoomElement { ... }
|
|
15
16
|
* ```
|
|
16
17
|
*/
|
|
17
|
-
export declare const component: (tag: string) => (
|
|
18
|
+
export declare const component: (tag: string) => (value: Function, context: ClassDecoratorContext) => void;
|
|
18
19
|
/**
|
|
19
|
-
* Lazy shadow DOM querySelector.
|
|
20
|
+
* Lazy shadow DOM querySelector (auto-accessor).
|
|
20
21
|
* ```ts
|
|
21
|
-
* @query(".submit-btn") submitBtn!: HTMLButtonElement;
|
|
22
|
+
* @query(".submit-btn") accessor submitBtn!: HTMLButtonElement;
|
|
22
23
|
* ```
|
|
23
24
|
*/
|
|
24
|
-
export declare
|
|
25
|
+
export declare function query<V>(selector: string): <This extends object>(_target: ClassAccessorDecoratorTarget<This, V>, _context: ClassAccessorDecoratorContext<This, V>) => ClassAccessorDecoratorResult<This, V>;
|
|
25
26
|
/**
|
|
26
|
-
* Lazy shadow DOM querySelectorAll.
|
|
27
|
+
* Lazy shadow DOM querySelectorAll (auto-accessor).
|
|
27
28
|
* ```ts
|
|
28
|
-
* @queryAll("input") inputs!: HTMLInputElement[];
|
|
29
|
+
* @queryAll("input") accessor inputs!: HTMLInputElement[];
|
|
29
30
|
* ```
|
|
30
31
|
*/
|
|
31
|
-
export declare
|
|
32
|
+
export declare function queryAll<V>(selector: string): <This extends object>(_target: ClassAccessorDecoratorTarget<This, V>, _context: ClassAccessorDecoratorContext<This, V>) => ClassAccessorDecoratorResult<This, V>;
|
|
33
|
+
/**
|
|
34
|
+
* Auto-adopt one or more CSSStyleSheets when the element connects.
|
|
35
|
+
* Accepts sheets created with the `css` tagged template.
|
|
36
|
+
*
|
|
37
|
+
* ```ts
|
|
38
|
+
* const myStyles = css`...`;
|
|
39
|
+
*
|
|
40
|
+
* @component("my-el")
|
|
41
|
+
* @styles(myStyles)
|
|
42
|
+
* class MyEl extends LoomElement { ... }
|
|
43
|
+
* ```
|
|
44
|
+
*
|
|
45
|
+
* Multiple `@styles()` calls stack (all sheets are adopted).
|
|
46
|
+
*/
|
|
47
|
+
export declare function styles(...sheets: CSSStyleSheet[]): (value: Function, _context: ClassDecoratorContext) => void;
|
|
32
48
|
//# sourceMappingURL=decorators.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../../src/element/decorators.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../../src/element/decorators.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH;;;;;;;;GAQG;AACH,eAAO,MAAM,SAAS,4EAyCH,CAAC;AAGpB;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,IAC/B,IAAI,SAAS,MAAM,EACzB,SAAS,4BAA4B,CAAC,IAAI,EAAE,CAAC,CAAC,EAC9C,UAAU,6BAA6B,CAAC,IAAI,EAAE,CAAC,CAAC,KAC/C,4BAA4B,CAAC,IAAI,EAAE,CAAC,CAAC,CAOzC;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,IAClC,IAAI,SAAS,MAAM,EACzB,SAAS,4BAA4B,CAAC,IAAI,EAAE,CAAC,CAAC,EAC9C,UAAU,6BAA6B,CAAC,IAAI,EAAE,CAAC,CAAC,KAC/C,4BAA4B,CAAC,IAAI,EAAE,CAAC,CAAC,CAOzC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,MAAM,CAAC,GAAG,MAAM,EAAE,aAAa,EAAE,IACvC,OAAO,QAAQ,EAAE,UAAU,qBAAqB,UAWzD"}
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Loom — Element decorators
|
|
2
|
+
* Loom — Element decorators (TC39 Stage 3)
|
|
3
3
|
*
|
|
4
4
|
* @component — Register a class as a custom element
|
|
5
|
-
* @query — Lazy shadow DOM querySelector
|
|
6
|
-
* @queryAll — Lazy shadow DOM querySelectorAll
|
|
5
|
+
* @query — Lazy shadow DOM querySelector (auto-accessor)
|
|
6
|
+
* @queryAll — Lazy shadow DOM querySelectorAll (auto-accessor)
|
|
7
|
+
* @styles — Adopt CSSStyleSheets on connect (class decorator)
|
|
7
8
|
*/
|
|
8
|
-
import { PROPS } from "../decorators/symbols";
|
|
9
|
+
import { PROPS, TRANSFORMS } from "../decorators/symbols";
|
|
9
10
|
import { app } from "../app";
|
|
10
11
|
import { createDecorator } from "../decorators/create";
|
|
12
|
+
import { pendingProps } from "../store/decorators";
|
|
11
13
|
/**
|
|
12
14
|
* Register a class as a custom element. Wires @prop observed attributes
|
|
13
15
|
* and attributeChangedCallback auto-parsing.
|
|
@@ -18,7 +20,13 @@ import { createDecorator } from "../decorators/create";
|
|
|
18
20
|
* ```
|
|
19
21
|
*/
|
|
20
22
|
export const component = createDecorator((ctor, tag) => {
|
|
23
|
+
// Flush pendingProps from @prop decorators (member decorators run before class decorators)
|
|
21
24
|
const propMap = ctor[PROPS] ?? new Map();
|
|
25
|
+
for (const { key } of pendingProps) {
|
|
26
|
+
propMap.set(key.toLowerCase(), key);
|
|
27
|
+
}
|
|
28
|
+
pendingProps.length = 0; // clear staging area
|
|
29
|
+
ctor[PROPS] = propMap;
|
|
22
30
|
// Wire observedAttributes from @prop fields
|
|
23
31
|
Object.defineProperty(ctor, "observedAttributes", {
|
|
24
32
|
get: () => [...propMap.keys()],
|
|
@@ -28,13 +36,20 @@ export const component = createDecorator((ctor, tag) => {
|
|
|
28
36
|
ctor.prototype.attributeChangedCallback = function (name, _old, val) {
|
|
29
37
|
const field = propMap.get(name);
|
|
30
38
|
if (field && val !== null) {
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
else
|
|
37
|
-
this[field]
|
|
39
|
+
const transforms = ctor[TRANSFORMS];
|
|
40
|
+
const transform = transforms?.get(field);
|
|
41
|
+
if (transform) {
|
|
42
|
+
this[field] = transform(val);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
const current = this[field];
|
|
46
|
+
if (typeof current === "number")
|
|
47
|
+
this[field] = Number(val);
|
|
48
|
+
else if (typeof current === "boolean")
|
|
49
|
+
this[field] = val !== null && val !== "false";
|
|
50
|
+
else
|
|
51
|
+
this[field] = val;
|
|
52
|
+
}
|
|
38
53
|
}
|
|
39
54
|
origCallback?.call(this, name, _old, val);
|
|
40
55
|
};
|
|
@@ -42,31 +57,60 @@ export const component = createDecorator((ctor, tag) => {
|
|
|
42
57
|
ctor.__loom_tag = tag;
|
|
43
58
|
}, { class: true });
|
|
44
59
|
/**
|
|
45
|
-
* Lazy shadow DOM querySelector.
|
|
60
|
+
* Lazy shadow DOM querySelector (auto-accessor).
|
|
46
61
|
* ```ts
|
|
47
|
-
* @query(".submit-btn") submitBtn!: HTMLButtonElement;
|
|
62
|
+
* @query(".submit-btn") accessor submitBtn!: HTMLButtonElement;
|
|
48
63
|
* ```
|
|
49
64
|
*/
|
|
50
|
-
export
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
65
|
+
export function query(selector) {
|
|
66
|
+
return (_target, _context) => {
|
|
67
|
+
return {
|
|
68
|
+
get() {
|
|
69
|
+
return this.shadow.querySelector(selector);
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
}
|
|
58
74
|
/**
|
|
59
|
-
* Lazy shadow DOM querySelectorAll.
|
|
75
|
+
* Lazy shadow DOM querySelectorAll (auto-accessor).
|
|
60
76
|
* ```ts
|
|
61
|
-
* @queryAll("input") inputs!: HTMLInputElement[];
|
|
77
|
+
* @queryAll("input") accessor inputs!: HTMLInputElement[];
|
|
62
78
|
* ```
|
|
63
79
|
*/
|
|
64
|
-
export
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
80
|
+
export function queryAll(selector) {
|
|
81
|
+
return (_target, _context) => {
|
|
82
|
+
return {
|
|
83
|
+
get() {
|
|
84
|
+
return Array.from(this.shadow.querySelectorAll(selector));
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Auto-adopt one or more CSSStyleSheets when the element connects.
|
|
91
|
+
* Accepts sheets created with the `css` tagged template.
|
|
92
|
+
*
|
|
93
|
+
* ```ts
|
|
94
|
+
* const myStyles = css`...`;
|
|
95
|
+
*
|
|
96
|
+
* @component("my-el")
|
|
97
|
+
* @styles(myStyles)
|
|
98
|
+
* class MyEl extends LoomElement { ... }
|
|
99
|
+
* ```
|
|
100
|
+
*
|
|
101
|
+
* Multiple `@styles()` calls stack (all sheets are adopted).
|
|
102
|
+
*/
|
|
103
|
+
export function styles(...sheets) {
|
|
104
|
+
return (value, _context) => {
|
|
105
|
+
const orig = value.prototype.connectedCallback;
|
|
106
|
+
value.prototype.connectedCallback = function () {
|
|
107
|
+
const existing = this.shadow.adoptedStyleSheets;
|
|
108
|
+
const newSheets = sheets.filter((s) => !existing.includes(s));
|
|
109
|
+
if (newSheets.length > 0) {
|
|
110
|
+
this.shadow.adoptedStyleSheets = [...existing, ...newSheets];
|
|
111
|
+
}
|
|
112
|
+
orig?.call(this);
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
}
|
|
72
116
|
//# sourceMappingURL=decorators.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decorators.js","sourceRoot":"","sources":["../../src/element/decorators.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"decorators.js","sourceRoot":"","sources":["../../src/element/decorators.ts"],"names":[],"mappings":"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"}
|
|
@@ -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;AAKjD,8BAAsB,WAAY,SAAQ,WAAW;IACnD,iEAAiE;IACjE,SAAS,KAAK,GAAG,yBAAkB;IAEnC,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC;IAC7B,OAAO,CAAC,QAAQ,CAAsB;;IAStC,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;
|
|
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;AAKjD,8BAAsB,WAAY,SAAQ,WAAW;IACnD,iEAAiE;IACjE,SAAS,KAAK,GAAG,yBAAkB;IAEnC,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC;IAC7B,OAAO,CAAC,QAAQ,CAAsB;;IAStC,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;IA4BtB;;;OAGG;IACH,KAAK,IAAI,IAAI;CAKd"}
|
package/dist/element/element.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { bus } from "../bus";
|
|
2
2
|
import { adoptCSS } from "../css";
|
|
3
|
-
import { COMPUTED_DIRTY, REACTIVES } from "../decorators/symbols";
|
|
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
6
|
export class LoomElement extends HTMLElement {
|
|
@@ -54,8 +54,13 @@ export class LoomElement extends HTMLElement {
|
|
|
54
54
|
}
|
|
55
55
|
// ── Lifecycle ──
|
|
56
56
|
connectedCallback() {
|
|
57
|
-
//
|
|
58
|
-
|
|
57
|
+
// Run decorator-registered connect hooks (from @mount, @interval, @watch, etc.)
|
|
58
|
+
for (const hook of (this[CONNECT_HOOKS] ?? [])) {
|
|
59
|
+
const cleanup = hook(this);
|
|
60
|
+
if (typeof cleanup === "function")
|
|
61
|
+
this.cleanups.push(cleanup);
|
|
62
|
+
}
|
|
63
|
+
// Trigger initial render for reactive components
|
|
59
64
|
const hasReactives = (this[REACTIVES]?.length ?? 0) > 0;
|
|
60
65
|
const overridesUpdate = this.update !== LoomElement.prototype.update;
|
|
61
66
|
if (hasReactives || overridesUpdate)
|
|
@@ -108,6 +113,13 @@ export class LoomElement extends HTMLElement {
|
|
|
108
113
|
if (!this._hasUpdated) {
|
|
109
114
|
this._hasUpdated = true;
|
|
110
115
|
this.firstUpdated();
|
|
116
|
+
// Run decorator-registered first-updated hooks (from @form, etc.)
|
|
117
|
+
// These fire after the first morph(), so shadow DOM content exists.
|
|
118
|
+
for (const hook of (this[FIRST_UPDATED_HOOKS] ?? [])) {
|
|
119
|
+
const cleanup = hook(this);
|
|
120
|
+
if (typeof cleanup === "function")
|
|
121
|
+
this.cleanups.push(cleanup);
|
|
122
|
+
}
|
|
111
123
|
}
|
|
112
124
|
});
|
|
113
125
|
}
|
|
@@ -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,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"element.js","sourceRoot":"","sources":["../../src/element/element.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loom — @form<T> property decorator
|
|
3
|
+
*
|
|
4
|
+
* DOM-independent form state management with validation, transforms,
|
|
5
|
+
* dirty tracking, and explicit template binding.
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* @form<LoginForm>({
|
|
9
|
+
* email: { transform: toTrimmed, validate: v => v.includes("@") || "Invalid email" },
|
|
10
|
+
* password: { validate: v => v.length >= 8 || "Min 8 chars" },
|
|
11
|
+
* remember: { transform: toBoolean },
|
|
12
|
+
* })
|
|
13
|
+
* accessor login!: FormState<LoginForm>;
|
|
14
|
+
*
|
|
15
|
+
* update() {
|
|
16
|
+
* const f = this.login;
|
|
17
|
+
* return (
|
|
18
|
+
* <form>
|
|
19
|
+
* <input value={f.data.email} onInput={f.bind("email")} />
|
|
20
|
+
* <input value={f.data.password} onInput={f.bind("password")} />
|
|
21
|
+
* <button disabled={!f.valid}>Submit</button>
|
|
22
|
+
* </form>
|
|
23
|
+
* );
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export interface FieldSchema<V = unknown> {
|
|
28
|
+
/** Transform raw string value before storing (reuses @transform functions) */
|
|
29
|
+
transform?: (raw: string) => V;
|
|
30
|
+
/** Return true if valid, or an error string */
|
|
31
|
+
validate?: (value: V) => true | string;
|
|
32
|
+
}
|
|
33
|
+
export type FormSchema<T> = {
|
|
34
|
+
[K in keyof T]?: FieldSchema<T[K]>;
|
|
35
|
+
};
|
|
36
|
+
export interface FormState<T> {
|
|
37
|
+
/** Current transformed values */
|
|
38
|
+
readonly data: T;
|
|
39
|
+
/** Field → error message (only populated for invalid fields) */
|
|
40
|
+
readonly errors: Partial<Record<keyof T, string>>;
|
|
41
|
+
/** True when all validated fields pass */
|
|
42
|
+
readonly valid: boolean;
|
|
43
|
+
/** True when any field has changed from initial values */
|
|
44
|
+
readonly dirty: boolean;
|
|
45
|
+
/** Reset all fields to their initial values */
|
|
46
|
+
reset(): void;
|
|
47
|
+
/** Manually trigger validation on all fields, returns validity */
|
|
48
|
+
validate(): boolean;
|
|
49
|
+
/** Returns an onInput event handler bound to a specific field */
|
|
50
|
+
bind(field: keyof T): (e: Event) => void;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Create a FormState<T> instance — pure reactive data, no DOM dependency.
|
|
54
|
+
*/
|
|
55
|
+
export declare function createFormState<T extends object>(schema: FormSchema<T>, scheduleUpdate: () => void): FormState<T>;
|
|
56
|
+
/**
|
|
57
|
+
* @form<T>(schema) — Auto-accessor decorator
|
|
58
|
+
*
|
|
59
|
+
* Creates a FormState<T> eagerly at class initialization.
|
|
60
|
+
* No DOM dependency — use `.bind(field)` in your template for explicit binding.
|
|
61
|
+
*/
|
|
62
|
+
export declare function form<T extends object>(schema: FormSchema<T>): <This extends object>(_target: ClassAccessorDecoratorTarget<This, FormState<T>>, context: ClassAccessorDecoratorContext<This, FormState<T>>) => ClassAccessorDecoratorResult<This, FormState<T>>;
|
|
63
|
+
//# sourceMappingURL=form.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form.d.ts","sourceRoot":"","sources":["../../src/element/form.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAIH,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,OAAO,CAAC;IACpB,iEAAiE;IACjE,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC;CAC1C;AAgBD;;GAEG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,EAC9C,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,EACrB,cAAc,EAAE,MAAM,IAAI,GACzB,SAAS,CAAC,CAAC,CAAC,CAyGd;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"}
|