@praxisjs/decorators 0.4.2 → 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.
Files changed (190) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/dist/__tests__/component.test.d.ts +2 -0
  3. package/dist/__tests__/component.test.d.ts.map +1 -0
  4. package/dist/__tests__/component.test.js +146 -0
  5. package/dist/__tests__/component.test.js.map +1 -0
  6. package/dist/__tests__/compose.test.d.ts +2 -0
  7. package/dist/__tests__/compose.test.d.ts.map +1 -0
  8. package/dist/__tests__/compose.test.js +171 -0
  9. package/dist/__tests__/compose.test.js.map +1 -0
  10. package/dist/__tests__/events.test.d.ts +2 -0
  11. package/dist/__tests__/events.test.d.ts.map +1 -0
  12. package/dist/__tests__/events.test.js +216 -0
  13. package/dist/__tests__/events.test.js.map +1 -0
  14. package/dist/__tests__/functions.test.js +283 -31
  15. package/dist/__tests__/functions.test.js.map +1 -1
  16. package/dist/__tests__/lazy.test.d.ts +2 -0
  17. package/dist/__tests__/lazy.test.d.ts.map +1 -0
  18. package/dist/__tests__/lazy.test.js +163 -0
  19. package/dist/__tests__/lazy.test.js.map +1 -0
  20. package/dist/__tests__/memo.test.js +71 -22
  21. package/dist/__tests__/memo.test.js.map +1 -1
  22. package/dist/__tests__/properties.test.js +191 -1
  23. package/dist/__tests__/properties.test.js.map +1 -1
  24. package/dist/__tests__/resource.test.d.ts +2 -0
  25. package/dist/__tests__/resource.test.d.ts.map +1 -0
  26. package/dist/__tests__/resource.test.js +103 -0
  27. package/dist/__tests__/resource.test.js.map +1 -0
  28. package/dist/__tests__/slot.test.d.ts +2 -0
  29. package/dist/__tests__/slot.test.d.ts.map +1 -0
  30. package/dist/__tests__/slot.test.js +147 -0
  31. package/dist/__tests__/slot.test.js.map +1 -0
  32. package/dist/__tests__/virtual.test.d.ts +2 -0
  33. package/dist/__tests__/virtual.test.d.ts.map +1 -0
  34. package/dist/__tests__/virtual.test.js +242 -0
  35. package/dist/__tests__/virtual.test.js.map +1 -0
  36. package/dist/component/component.d.ts +1 -1
  37. package/dist/component/component.d.ts.map +1 -1
  38. package/dist/component/component.js +15 -10
  39. package/dist/component/component.js.map +1 -1
  40. package/dist/component/lazy.d.ts +1 -1
  41. package/dist/component/lazy.d.ts.map +1 -1
  42. package/dist/component/lazy.js +29 -27
  43. package/dist/component/lazy.js.map +1 -1
  44. package/dist/component/virtual.d.ts +1 -1
  45. package/dist/component/virtual.d.ts.map +1 -1
  46. package/dist/component/virtual.js +46 -50
  47. package/dist/component/virtual.js.map +1 -1
  48. package/dist/create-class-decorator.d.ts +16 -0
  49. package/dist/create-class-decorator.d.ts.map +1 -0
  50. package/dist/create-class-decorator.js +35 -0
  51. package/dist/create-class-decorator.js.map +1 -0
  52. package/dist/create-field-decorator.d.ts +14 -0
  53. package/dist/create-field-decorator.d.ts.map +1 -0
  54. package/dist/create-field-decorator.js +37 -0
  55. package/dist/create-field-decorator.js.map +1 -0
  56. package/dist/create-getter-decorator.d.ts +18 -0
  57. package/dist/create-getter-decorator.d.ts.map +1 -0
  58. package/dist/create-getter-decorator.js +15 -0
  59. package/dist/create-getter-decorator.js.map +1 -0
  60. package/dist/create-lifecycle-method-decorator.d.ts +6 -0
  61. package/dist/create-lifecycle-method-decorator.d.ts.map +1 -0
  62. package/dist/create-lifecycle-method-decorator.js +22 -0
  63. package/dist/create-lifecycle-method-decorator.js.map +1 -0
  64. package/dist/create-method-decorator.d.ts +6 -0
  65. package/dist/create-method-decorator.d.ts.map +1 -0
  66. package/dist/create-method-decorator.js +14 -0
  67. package/dist/create-method-decorator.js.map +1 -0
  68. package/dist/events/emit.d.ts +1 -1
  69. package/dist/events/emit.d.ts.map +1 -1
  70. package/dist/events/emit.js +24 -29
  71. package/dist/events/emit.js.map +1 -1
  72. package/dist/events/on-command.d.ts +1 -2
  73. package/dist/events/on-command.d.ts.map +1 -1
  74. package/dist/events/on-command.js +15 -32
  75. package/dist/events/on-command.js.map +1 -1
  76. package/dist/functions/bind.d.ts +1 -2
  77. package/dist/functions/bind.d.ts.map +1 -1
  78. package/dist/functions/bind.js +4 -11
  79. package/dist/functions/bind.js.map +1 -1
  80. package/dist/functions/debounce.d.ts +1 -2
  81. package/dist/functions/debounce.d.ts.map +1 -1
  82. package/dist/functions/debounce.js +12 -20
  83. package/dist/functions/debounce.js.map +1 -1
  84. package/dist/functions/log.d.ts +1 -2
  85. package/dist/functions/log.d.ts.map +1 -1
  86. package/dist/functions/log.js +40 -38
  87. package/dist/functions/log.js.map +1 -1
  88. package/dist/functions/memo.d.ts +1 -2
  89. package/dist/functions/memo.d.ts.map +1 -1
  90. package/dist/functions/memo.js +15 -27
  91. package/dist/functions/memo.js.map +1 -1
  92. package/dist/functions/once.d.ts +1 -2
  93. package/dist/functions/once.d.ts.map +1 -1
  94. package/dist/functions/once.js +14 -12
  95. package/dist/functions/once.js.map +1 -1
  96. package/dist/functions/retry.d.ts +1 -2
  97. package/dist/functions/retry.d.ts.map +1 -1
  98. package/dist/functions/retry.js +23 -20
  99. package/dist/functions/retry.js.map +1 -1
  100. package/dist/functions/throttle.d.ts +1 -2
  101. package/dist/functions/throttle.d.ts.map +1 -1
  102. package/dist/functions/throttle.js +9 -16
  103. package/dist/functions/throttle.js.map +1 -1
  104. package/dist/functions/watch.d.ts +1 -1
  105. package/dist/functions/watch.d.ts.map +1 -1
  106. package/dist/functions/watch.js +25 -31
  107. package/dist/functions/watch.js.map +1 -1
  108. package/dist/functions/when.d.ts +1 -2
  109. package/dist/functions/when.d.ts.map +1 -1
  110. package/dist/functions/when.js +10 -26
  111. package/dist/functions/when.js.map +1 -1
  112. package/dist/index.d.ts +6 -1
  113. package/dist/index.d.ts.map +1 -1
  114. package/dist/index.js +6 -1
  115. package/dist/index.js.map +1 -1
  116. package/dist/properties/compose.d.ts +3 -0
  117. package/dist/properties/compose.d.ts.map +1 -0
  118. package/dist/properties/compose.js +40 -0
  119. package/dist/properties/compose.js.map +1 -0
  120. package/dist/properties/computed.d.ts +1 -2
  121. package/dist/properties/computed.d.ts.map +1 -1
  122. package/dist/properties/computed.js +10 -9
  123. package/dist/properties/computed.js.map +1 -1
  124. package/dist/properties/history.d.ts.map +1 -1
  125. package/dist/properties/history.js +37 -32
  126. package/dist/properties/history.js.map +1 -1
  127. package/dist/properties/index.d.ts +2 -0
  128. package/dist/properties/index.d.ts.map +1 -1
  129. package/dist/properties/index.js +2 -0
  130. package/dist/properties/index.js.map +1 -1
  131. package/dist/properties/persisted.d.ts +1 -2
  132. package/dist/properties/persisted.d.ts.map +1 -1
  133. package/dist/properties/persisted.js +13 -29
  134. package/dist/properties/persisted.js.map +1 -1
  135. package/dist/properties/prop.d.ts +1 -2
  136. package/dist/properties/prop.d.ts.map +1 -1
  137. package/dist/properties/prop.js +21 -25
  138. package/dist/properties/prop.js.map +1 -1
  139. package/dist/properties/resource.d.ts +14 -0
  140. package/dist/properties/resource.d.ts.map +1 -0
  141. package/dist/properties/resource.js +27 -0
  142. package/dist/properties/resource.js.map +1 -0
  143. package/dist/properties/slot.d.ts +1 -2
  144. package/dist/properties/slot.d.ts.map +1 -1
  145. package/dist/properties/slot.js +15 -20
  146. package/dist/properties/slot.js.map +1 -1
  147. package/dist/properties/state.d.ts +1 -2
  148. package/dist/properties/state.d.ts.map +1 -1
  149. package/dist/properties/state.js +13 -18
  150. package/dist/properties/state.js.map +1 -1
  151. package/package.json +2 -2
  152. package/src/__tests__/component.test.ts +166 -0
  153. package/src/__tests__/compose.test.ts +202 -0
  154. package/src/__tests__/events.test.ts +268 -0
  155. package/src/__tests__/functions.test.ts +368 -30
  156. package/src/__tests__/lazy.test.ts +218 -0
  157. package/src/__tests__/memo.test.ts +89 -22
  158. package/src/__tests__/properties.test.ts +249 -1
  159. package/src/__tests__/resource.test.ts +113 -0
  160. package/src/__tests__/slot.test.ts +179 -0
  161. package/src/__tests__/virtual.test.ts +260 -0
  162. package/src/component/component.ts +27 -12
  163. package/src/component/lazy.ts +33 -35
  164. package/src/component/virtual.tsx +62 -75
  165. package/src/create-class-decorator.ts +61 -0
  166. package/src/create-field-decorator.ts +66 -0
  167. package/src/create-getter-decorator.ts +52 -0
  168. package/src/create-lifecycle-method-decorator.ts +38 -0
  169. package/src/create-method-decorator.ts +26 -0
  170. package/src/events/emit.ts +22 -33
  171. package/src/events/on-command.ts +22 -47
  172. package/src/functions/bind.ts +4 -15
  173. package/src/functions/debounce.ts +11 -26
  174. package/src/functions/log.ts +40 -43
  175. package/src/functions/memo.ts +15 -45
  176. package/src/functions/once.ts +13 -16
  177. package/src/functions/retry.ts +21 -22
  178. package/src/functions/throttle.ts +9 -23
  179. package/src/functions/watch.ts +27 -34
  180. package/src/functions/when.ts +11 -36
  181. package/src/index.ts +28 -0
  182. package/src/properties/compose.ts +53 -0
  183. package/src/properties/computed.ts +11 -13
  184. package/src/properties/history.ts +42 -41
  185. package/src/properties/index.ts +2 -0
  186. package/src/properties/persisted.ts +17 -58
  187. package/src/properties/prop.ts +21 -31
  188. package/src/properties/resource.ts +34 -0
  189. package/src/properties/slot.ts +17 -30
  190. package/src/properties/state.ts +14 -24
package/CHANGELOG.md CHANGED
@@ -1,5 +1,48 @@
1
1
  # @praxisjs/decorators
2
2
 
3
+ ## 0.5.0
4
+
5
+ ### Minor Changes
6
+
7
+ - feaa478: Add decorator factory helpers and new built-in decorators.
8
+
9
+ **Decorator factories** — low-level building blocks for authoring custom decorators:
10
+
11
+ - `createFieldDecorator` / `FieldBehavior` / `FieldBinding`
12
+ - `createClassDecorator` / `ClassBehavior` / `ClassEnhancement`
13
+ - `createMethodDecorator` / `MethodBehavior`
14
+ - `createLifecycleMethodDecorator` / `LifecycleMethodBehavior`
15
+ - `createGetterDecorator` / `GetterBehavior`
16
+ - `createGetterObserverDecorator` / `GetterObserverBehavior`
17
+
18
+ **New built-in decorators:**
19
+
20
+ - `@Compose` — mixes a `Composable` class into a component, binding its reactive properties and lifecycle hooks
21
+ - `@Resource` — declares an async resource on a component field, replacing the standalone `resource()` function from `@praxisjs/core`
22
+
23
+ ### Patch Changes
24
+
25
+ - Updated dependencies [3372878]
26
+ - @praxisjs/core@1.0.0
27
+
28
+ ## 0.4.3
29
+
30
+ ### Patch Changes
31
+
32
+ - ea59035: Fix three bugs in `Lazy`, `Virtual`, and `Watch` decorators
33
+
34
+ **`Lazy` / `Virtual` — incompatible type constraint**
35
+ Both decorators constrained their generic to `new (...args: any[]) => RootComponent`, where the bare `RootComponent` defaults to `RootComponent<Record<string, never>>`. This made the constraint incompatible with `StatefulComponent`, whose `_rawProps` is typed as `Record<string, unknown>`, causing a TypeScript error at the call site. Changed the constraint to `RootComponent<Record<string, any>>` so any component subclass is accepted.
36
+
37
+ **`Lazy` — infinite recursion on render after becoming visible**
38
+ `_originalRender` was initialized to `this.render.bind(this)`, which at instance-creation time resolves to `LazyWrapper.render` (the override itself). Calling `render()` after the component became visible would then recurse infinitely. Fixed by capturing `constructor.prototype.render` — the parent class's render method — instead.
39
+
40
+ **`Watch` — reactive effect leaked after component unmount**
41
+ The decorator created a reactive `effect()` on `onMount` but never called the returned stop function on unmount. This caused the effect to keep running and the handler to keep firing even after the component was unmounted, resulting in a memory leak and stale callbacks. The decorator now hooks into `onUnmount` to stop the effect and preserves any existing `onUnmount` implementation on the instance.
42
+
43
+ - Updated dependencies [d11a10a]
44
+ - @praxisjs/core@0.4.2
45
+
3
46
  ## 0.4.2
4
47
 
5
48
  ### Patch Changes
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=component.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/component.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,146 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { StatefulComponent, StatelessComponent } from "@praxisjs/core";
3
+ import { Component } from "../component/component";
4
+ // ── Component decorator ───────────────────────────────────────────────────────
5
+ describe("Component decorator", () => {
6
+ it("sets __isComponent = true on the enhanced class", () => {
7
+ class MyComp extends StatefulComponent {
8
+ render() { return null; }
9
+ }
10
+ const Enhanced = Component()(MyComp, {});
11
+ expect(Enhanced.__isComponent).toBe(true);
12
+ });
13
+ it("preserves the original class name", () => {
14
+ class MyButton extends StatefulComponent {
15
+ render() { return null; }
16
+ }
17
+ const Enhanced = Component()(MyButton, {});
18
+ expect(Enhanced.name).toBe("MyButton");
19
+ });
20
+ it("marks __isStateless = false for StatefulComponent subclasses", () => {
21
+ class MyStateful extends StatefulComponent {
22
+ render() { return null; }
23
+ }
24
+ const Enhanced = Component()(MyStateful, {});
25
+ expect(Enhanced.__isStateless).toBe(false);
26
+ });
27
+ it("marks __isStateless = true for StatelessComponent subclasses", () => {
28
+ class MyStateless extends StatelessComponent {
29
+ render() { return null; }
30
+ }
31
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
32
+ const Enhanced = Component()(MyStateless, {});
33
+ expect(Enhanced.__isStateless).toBe(true);
34
+ });
35
+ it("enhanced class can still be instantiated", () => {
36
+ class Counter extends StatefulComponent {
37
+ render() { return null; }
38
+ }
39
+ const Enhanced = Component()(Counter, {});
40
+ const instance = new Enhanced();
41
+ expect(instance).toBeInstanceOf(Counter);
42
+ });
43
+ it("returns a subclass of the original constructor", () => {
44
+ class Base extends StatefulComponent {
45
+ render() { return null; }
46
+ }
47
+ const Enhanced = Component()(Base, {});
48
+ expect(Enhanced.prototype).toBeInstanceOf(Base);
49
+ });
50
+ // ── Happy paths ──────────────────────────────────────────────────────────────
51
+ it("forwards constructor args — props reach the base constructor", () => {
52
+ class WithProps extends StatefulComponent {
53
+ render() { return null; }
54
+ }
55
+ const Enhanced = Component()(WithProps, {});
56
+ const instance = new Enhanced({ greeting: "hello" });
57
+ expect(instance.props.greeting).toBe("hello");
58
+ });
59
+ it("instance methods from the original class remain accessible", () => {
60
+ class Greeter extends StatefulComponent {
61
+ greet() { return "hello"; }
62
+ render() { return null; }
63
+ }
64
+ const Enhanced = Component()(Greeter, {});
65
+ const instance = new Enhanced();
66
+ expect(instance.greet()).toBe("hello");
67
+ });
68
+ it("static properties of the original class are preserved on Enhanced", () => {
69
+ class WithStatic extends StatefulComponent {
70
+ static { this.version = "1.0"; }
71
+ render() { return null; }
72
+ }
73
+ const Enhanced = Component()(WithStatic, {});
74
+ expect(Enhanced.version).toBe("1.0");
75
+ });
76
+ // ── Edge cases ───────────────────────────────────────────────────────────────
77
+ it("applying Component() twice preserves name and flags", () => {
78
+ class MyComp extends StatefulComponent {
79
+ render() { return null; }
80
+ }
81
+ const E1 = Component()(MyComp, {});
82
+ const E2 = Component()(E1, {});
83
+ expect(E2.__isComponent).toBe(true);
84
+ expect(E2.__isStateless).toBe(false);
85
+ expect(E2.name).toBe("MyComp"); // name survives double-wrap
86
+ });
87
+ it("deep StatelessComponent inheritance — __isStateless is still true", () => {
88
+ class BaseStateless extends StatelessComponent {
89
+ render() { return null; }
90
+ }
91
+ class DeepChild extends BaseStateless {
92
+ render() { return null; }
93
+ }
94
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
95
+ const Enhanced = Component()(DeepChild, {});
96
+ expect(Enhanced.__isStateless).toBe(true);
97
+ });
98
+ it("anonymous class gets an empty name", () => {
99
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
100
+ const Enhanced = Component()(
101
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
102
+ class extends StatefulComponent {
103
+ render() { return null; }
104
+ }, {});
105
+ expect(Enhanced.name).toBe("");
106
+ });
107
+ it("__isComponent and __isStateless are static — not own properties of instances", () => {
108
+ class MyComp extends StatefulComponent {
109
+ render() { return null; }
110
+ }
111
+ const Enhanced = Component()(MyComp, {});
112
+ const instance = new Enhanced();
113
+ // Static fields live on the class, not on instances
114
+ expect(Object.prototype.hasOwnProperty.call(instance, "__isComponent")).toBe(false);
115
+ expect(Object.prototype.hasOwnProperty.call(instance, "__isStateless")).toBe(false);
116
+ });
117
+ it("subclassing Enhanced inherits __isComponent and __isStateless", () => {
118
+ class MyComp extends StatefulComponent {
119
+ render() { return null; }
120
+ }
121
+ const Enhanced = Component()(MyComp, {});
122
+ // `class Sub extends Enhanced` sets Object.getPrototypeOf(Sub) === Enhanced,
123
+ // making static fields visible through the chain. Simulate that here to
124
+ // avoid TS2510 (conflicting constructor return types in the intersection type).
125
+ const Sub = Object.create(Enhanced);
126
+ expect(Sub.__isComponent).toBe(true);
127
+ expect(Sub.__isStateless).toBe(false);
128
+ });
129
+ it("Enhanced is a different reference from the original constructor", () => {
130
+ class MyComp extends StatefulComponent {
131
+ render() { return null; }
132
+ }
133
+ const Enhanced = Component()(MyComp, {});
134
+ expect(Enhanced).not.toBe(MyComp);
135
+ });
136
+ it("render() falls through to originalRender when enhancement has no render override", () => {
137
+ class MyComp extends StatefulComponent {
138
+ render() { return null; }
139
+ }
140
+ const Enhanced = Component()(MyComp, {});
141
+ const instance = new Enhanced();
142
+ // ComponentBehavior.create() returns {} (no render), so line 48 is hit
143
+ expect(instance.render()).toBeNull();
144
+ });
145
+ });
146
+ //# sourceMappingURL=component.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component.test.js","sourceRoot":"","sources":["../../src/__tests__/component.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=compose.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compose.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/compose.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,171 @@
1
+ import { describe, it, expect, vi } from "vitest";
2
+ import { StatefulComponent } from "@praxisjs/core";
3
+ import { signal } from "@praxisjs/core/internal";
4
+ import { Compose } from "../properties/compose";
5
+ function fieldCtx(name) {
6
+ const initializers = [];
7
+ return {
8
+ ctx: {
9
+ name,
10
+ kind: "field",
11
+ addInitializer(fn) {
12
+ initializers.push(fn);
13
+ },
14
+ },
15
+ run(instance) {
16
+ initializers.forEach((fn) => { fn.call(instance); });
17
+ },
18
+ };
19
+ }
20
+ class TestComponent extends StatefulComponent {
21
+ render() { return null; }
22
+ }
23
+ // Simple composable returning plain values
24
+ class CounterComposable {
25
+ constructor() {
26
+ this.count = 0;
27
+ }
28
+ setup() {
29
+ return { count: this.count, label: "counter" };
30
+ }
31
+ }
32
+ // Composable returning a signal (reactive property)
33
+ class ReactiveComposable {
34
+ constructor() {
35
+ this._count = signal(0);
36
+ }
37
+ setup() {
38
+ return { count: this._count };
39
+ }
40
+ }
41
+ // Composable with lifecycle hooks
42
+ class LifecycleComposable {
43
+ constructor() {
44
+ this.onMount = vi.fn();
45
+ this.onUnmount = vi.fn();
46
+ }
47
+ setup() {
48
+ return { active: true };
49
+ }
50
+ }
51
+ // Composable that uses constructor args
52
+ class ArgsComposable {
53
+ constructor(multiplier) {
54
+ this.multiplier = multiplier;
55
+ }
56
+ setup() {
57
+ return { multiplier: this.multiplier };
58
+ }
59
+ }
60
+ // Composable returning a plain function (non-reactive) in its view
61
+ class PlainFnComposable {
62
+ setup() {
63
+ return { handler: () => 42 };
64
+ }
65
+ }
66
+ describe("@Compose decorator", () => {
67
+ it("creates a view getter on the field", () => {
68
+ const { ctx, run } = fieldCtx("counter");
69
+ Compose(CounterComposable)(undefined, ctx);
70
+ const instance = new TestComponent();
71
+ run(instance);
72
+ const view = instance.counter;
73
+ expect(view).toBeDefined();
74
+ expect(view.count).toBe(0);
75
+ expect(view.label).toBe("counter");
76
+ });
77
+ it("reactive signal values are resolved via getter", () => {
78
+ const { ctx, run } = fieldCtx("reactive");
79
+ Compose(ReactiveComposable)(undefined, ctx);
80
+ const instance = new TestComponent();
81
+ run(instance);
82
+ const view = instance.reactive;
83
+ expect(view.count).toBe(0);
84
+ });
85
+ it("calls onMount when component mounts", () => {
86
+ const { ctx, run } = fieldCtx("lc");
87
+ Compose(LifecycleComposable)(undefined, ctx);
88
+ const instance = new TestComponent();
89
+ run(instance);
90
+ const view = instance.lc;
91
+ expect(view).toBeDefined();
92
+ // Trigger onMount
93
+ instance.onMount();
94
+ const lc = new LifecycleComposable();
95
+ // The composable's onMount would have been called
96
+ // We verify the instance has an onMount wiring
97
+ expect(typeof instance.onMount).toBe("function");
98
+ });
99
+ it("calls onUnmount when component unmounts", () => {
100
+ const { ctx, run } = fieldCtx("lc2");
101
+ Compose(LifecycleComposable)(undefined, ctx);
102
+ const instance = new TestComponent();
103
+ run(instance);
104
+ expect(typeof instance.onUnmount).toBe("function");
105
+ });
106
+ it("invoking instance.onUnmount() executes the composable's onUnmount", () => {
107
+ const unmountSpy = vi.fn();
108
+ class SpyComposable {
109
+ constructor() {
110
+ this.onUnmount = unmountSpy;
111
+ }
112
+ setup() { return {}; }
113
+ }
114
+ const { ctx, run } = fieldCtx("spyComp");
115
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
116
+ Compose(SpyComposable)(undefined, ctx);
117
+ const instance = new TestComponent();
118
+ run(instance);
119
+ instance.onUnmount();
120
+ expect(unmountSpy).toHaveBeenCalled();
121
+ });
122
+ it("passes constructor args to the composable", () => {
123
+ const { ctx, run } = fieldCtx("args");
124
+ Compose(ArgsComposable, 5)(undefined, ctx);
125
+ const instance = new TestComponent();
126
+ run(instance);
127
+ const view = instance.args;
128
+ expect(view.multiplier).toBe(5);
129
+ });
130
+ it("resolves string constructor args from instance properties", () => {
131
+ const { ctx, run } = fieldCtx("resolved");
132
+ Compose(ArgsComposable, "myMultiplier")(undefined, ctx);
133
+ const instance = new TestComponent();
134
+ instance.myMultiplier = 10;
135
+ run(instance);
136
+ const view = instance.resolved;
137
+ expect(view.multiplier).toBe(10);
138
+ });
139
+ it("each instance gets its own composable view", () => {
140
+ const { ctx, run } = fieldCtx("c");
141
+ Compose(CounterComposable)(undefined, ctx);
142
+ const a = new TestComponent();
143
+ const b = new TestComponent();
144
+ run(a);
145
+ run(b);
146
+ const viewA = a.c;
147
+ const viewB = b.c;
148
+ expect(viewA).not.toBe(viewB);
149
+ });
150
+ it("plain function value in view is stored as-is (not treated as reactive)", () => {
151
+ const { ctx, run } = fieldCtx("pfn");
152
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
153
+ Compose(PlainFnComposable)(undefined, ctx);
154
+ const instance = new TestComponent();
155
+ run(instance);
156
+ const view = instance.pfn;
157
+ // handler is a plain function — isReactive returns false, stored directly
158
+ expect(typeof view.handler).toBe("function");
159
+ expect(view.handler()).toBe(42);
160
+ });
161
+ it("view getter always returns same view object", () => {
162
+ const { ctx, run } = fieldCtx("stable");
163
+ Compose(CounterComposable)(undefined, ctx);
164
+ const instance = new TestComponent();
165
+ run(instance);
166
+ const v1 = instance.stable;
167
+ const v2 = instance.stable;
168
+ expect(v1).toBe(v2);
169
+ });
170
+ });
171
+ //# sourceMappingURL=compose.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compose.test.js","sourceRoot":"","sources":["../../src/__tests__/compose.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=events.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/events.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,216 @@
1
+ import { describe, it, expect, vi } from "vitest";
2
+ import { StatefulComponent } from "@praxisjs/core";
3
+ import { createCommand } from "../events/command";
4
+ import { Emit } from "../events/emit";
5
+ import { readProp } from "../events/helper";
6
+ import { OnCommand } from "../events/on-command";
7
+ // ── Helpers ───────────────────────────────────────────────────────────────────
8
+ class TestComponent extends StatefulComponent {
9
+ render() { return null; }
10
+ }
11
+ function methodCtx(name) {
12
+ const initializers = [];
13
+ return {
14
+ ctx: {
15
+ name,
16
+ kind: "method",
17
+ addInitializer(fn) { initializers.push(fn); },
18
+ },
19
+ run(instance) { initializers.forEach((fn) => { fn.call(instance); }); },
20
+ };
21
+ }
22
+ // ── createCommand ─────────────────────────────────────────────────────────────
23
+ describe("createCommand", () => {
24
+ it("trigger calls all subscribed handlers with the argument", () => {
25
+ const cmd = createCommand();
26
+ const h1 = vi.fn();
27
+ const h2 = vi.fn();
28
+ cmd.subscribe(h1);
29
+ cmd.subscribe(h2);
30
+ cmd.trigger(42);
31
+ expect(h1).toHaveBeenCalledWith(42);
32
+ expect(h2).toHaveBeenCalledWith(42);
33
+ });
34
+ it("trigger does nothing when no handlers are subscribed", () => {
35
+ const cmd = createCommand();
36
+ expect(() => cmd.trigger("hello")).not.toThrow();
37
+ });
38
+ it("subscribe returns an unsubscribe function", () => {
39
+ const cmd = createCommand();
40
+ const handler = vi.fn();
41
+ const unsub = cmd.subscribe(handler);
42
+ unsub();
43
+ cmd.trigger();
44
+ expect(handler).not.toHaveBeenCalled();
45
+ });
46
+ it("void command can be triggered without args", () => {
47
+ const cmd = createCommand();
48
+ const handler = vi.fn();
49
+ cmd.subscribe(handler);
50
+ cmd.trigger(undefined);
51
+ expect(handler).toHaveBeenCalledOnce();
52
+ });
53
+ });
54
+ // ── readProp ──────────────────────────────────────────────────────────────────
55
+ describe("readProp", () => {
56
+ it("returns value from _rawProps when defined", () => {
57
+ const instance = new TestComponent({ myProp: "fromParent" });
58
+ expect(readProp(instance, "myProp")).toBe("fromParent");
59
+ });
60
+ it("falls back to _defaults when _rawProps does not define the prop", () => {
61
+ const instance = new TestComponent();
62
+ instance._defaults.myProp = "default";
63
+ expect(readProp(instance, "myProp")).toBe("default");
64
+ });
65
+ it("returns undefined when prop is not in either", () => {
66
+ const instance = new TestComponent();
67
+ expect(readProp(instance, "missing")).toBeUndefined();
68
+ });
69
+ });
70
+ // ── Emit ─────────────────────────────────────────────────────────────────────
71
+ describe("Emit decorator", () => {
72
+ it("calls the prop callback with the return value of the method", () => {
73
+ const { ctx, run } = methodCtx("handleInput");
74
+ const original = function (value) { return value.toUpperCase(); };
75
+ Emit("onChange")(original, ctx);
76
+ const callback = vi.fn();
77
+ const instance = new TestComponent({ onChange: callback });
78
+ run(instance);
79
+ const method = instance.handleInput;
80
+ method.call(instance, "hello");
81
+ expect(callback).toHaveBeenCalledWith("HELLO");
82
+ });
83
+ it("calls the prop callback with the method args when return value is undefined", () => {
84
+ const { ctx, run } = methodCtx("doSomething");
85
+ const original = function (a, b) { return undefined; };
86
+ Emit("onDo")(original, ctx);
87
+ const callback = vi.fn();
88
+ const instance = new TestComponent({ onDo: callback });
89
+ run(instance);
90
+ const method = instance.doSomething;
91
+ method.call(instance, 1, 2);
92
+ expect(callback).toHaveBeenCalledWith(1, 2);
93
+ });
94
+ it("calls the prop callback with no args when return is undefined and no args", () => {
95
+ const { ctx, run } = methodCtx("fire");
96
+ const original = function () { return undefined; };
97
+ Emit("onFire")(original, ctx);
98
+ const callback = vi.fn();
99
+ const instance = new TestComponent({ onFire: callback });
100
+ run(instance);
101
+ const method = instance.fire;
102
+ method.call(instance);
103
+ expect(callback).toHaveBeenCalledOnce();
104
+ expect(callback).toHaveBeenCalledWith();
105
+ });
106
+ it("does not throw when the prop callback is not a function", () => {
107
+ const { ctx, run } = methodCtx("submit");
108
+ const original = function () { return "result"; };
109
+ Emit("onSubmit")(original, ctx);
110
+ const instance = new TestComponent(); // no onSubmit prop
111
+ run(instance);
112
+ const method = instance.submit;
113
+ expect(() => method.call(instance)).not.toThrow();
114
+ });
115
+ it("still returns the original method's return value", () => {
116
+ const { ctx, run } = methodCtx("compute");
117
+ const original = function () { return 99; };
118
+ Emit("onResult")(original, ctx);
119
+ const callback = vi.fn();
120
+ const instance = new TestComponent({ onResult: callback });
121
+ run(instance);
122
+ const method = instance.compute;
123
+ const result = method.call(instance);
124
+ expect(result).toBe(99);
125
+ });
126
+ });
127
+ // ── OnCommand ─────────────────────────────────────────────────────────────────
128
+ describe("OnCommand decorator", () => {
129
+ it("subscribes to the command on mount and calls the method when triggered", () => {
130
+ const { ctx, run } = methodCtx("handleCmd");
131
+ const handler = vi.fn();
132
+ OnCommand("myCommand")(handler, ctx);
133
+ const cmd = createCommand();
134
+ const instance = new TestComponent({ myCommand: cmd });
135
+ run(instance);
136
+ instance.onMount?.();
137
+ cmd.trigger("payload");
138
+ expect(handler).toHaveBeenCalledWith("payload");
139
+ });
140
+ it("unsubscribes from the command on unmount", () => {
141
+ const { ctx, run } = methodCtx("onMsg");
142
+ const handler = vi.fn();
143
+ OnCommand("msg")(handler, ctx);
144
+ const cmd = createCommand();
145
+ const instance = new TestComponent({ msg: cmd });
146
+ run(instance);
147
+ instance.onMount?.();
148
+ instance.onUnmount?.();
149
+ cmd.trigger("after-unmount");
150
+ expect(handler).not.toHaveBeenCalled();
151
+ });
152
+ it("warns when the command prop is not provided", () => {
153
+ const { ctx, run } = methodCtx("onMissing");
154
+ OnCommand("missingProp")(vi.fn(), ctx);
155
+ const instance = new TestComponent(); // no missingProp
156
+ run(instance);
157
+ const warn = vi.spyOn(console, "warn").mockImplementation(() => { });
158
+ instance.onMount?.();
159
+ expect(warn).toHaveBeenCalledWith(expect.stringContaining("[OnCommand]"));
160
+ warn.mockRestore();
161
+ });
162
+ it("warns when the command prop is not a valid Command", () => {
163
+ const { ctx, run } = methodCtx("onBadCmd");
164
+ OnCommand("badProp")(vi.fn(), ctx);
165
+ const instance = new TestComponent({ badProp: "not-a-command" });
166
+ run(instance);
167
+ const warn = vi.spyOn(console, "warn").mockImplementation(() => { });
168
+ instance.onMount?.();
169
+ expect(warn).toHaveBeenCalledWith(expect.stringContaining("[OnCommand]"));
170
+ warn.mockRestore();
171
+ });
172
+ it("uses 'unknown' as component name when constructor.name is undefined (missing-prop branch)", () => {
173
+ const { ctx, run } = methodCtx("onNoName");
174
+ OnCommand("missingProp")(vi.fn(), ctx);
175
+ // Instance whose constructor.name is undefined to hit ?? "unknown"
176
+ const fakeInstance = Object.assign(new TestComponent(), {
177
+ constructor: { name: undefined },
178
+ });
179
+ run(fakeInstance);
180
+ const warn = vi.spyOn(console, "warn").mockImplementation(() => { });
181
+ fakeInstance.onMount?.();
182
+ expect(warn).toHaveBeenCalledWith(expect.stringContaining("unknown"));
183
+ warn.mockRestore();
184
+ });
185
+ it("uses 'unknown' as component name when constructor.name is undefined (invalid-command branch)", () => {
186
+ const { ctx, run } = methodCtx("onNoName2");
187
+ OnCommand("badProp")(vi.fn(), ctx);
188
+ // Instance with a non-command prop and undefined constructor.name
189
+ const fakeInstance = Object.assign(new TestComponent({ badProp: "not-a-command" }), {
190
+ constructor: { name: undefined },
191
+ });
192
+ run(fakeInstance);
193
+ const warn = vi.spyOn(console, "warn").mockImplementation(() => { });
194
+ fakeInstance.onMount?.();
195
+ expect(warn).toHaveBeenCalledWith(expect.stringContaining("unknown"));
196
+ warn.mockRestore();
197
+ });
198
+ it("preserves the original onMount and onUnmount implementations", () => {
199
+ const { ctx, run } = methodCtx("onEvt");
200
+ OnCommand("evt")(vi.fn(), ctx);
201
+ const cmd = createCommand();
202
+ const instance = new TestComponent({ evt: cmd });
203
+ run(instance);
204
+ const mountSpy = vi.fn();
205
+ const unmountSpy = vi.fn();
206
+ const prevMount = instance.onMount?.bind(instance);
207
+ const prevUnmount = instance.onUnmount?.bind(instance);
208
+ instance.onMount = function () { mountSpy(); prevMount?.(); };
209
+ instance.onUnmount = function () { unmountSpy(); prevUnmount?.(); };
210
+ instance.onMount();
211
+ instance.onUnmount();
212
+ expect(mountSpy).toHaveBeenCalled();
213
+ expect(unmountSpy).toHaveBeenCalled();
214
+ });
215
+ });
216
+ //# sourceMappingURL=events.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.test.js","sourceRoot":"","sources":["../../src/__tests__/events.test.ts"],"names":[],"mappings":"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"}