@praxisjs/decorators 0.4.3 → 0.6.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 (192) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/dist/__tests__/component.test.js +10 -1
  3. package/dist/__tests__/component.test.js.map +1 -1
  4. package/dist/__tests__/compose.test.d.ts +2 -0
  5. package/dist/__tests__/compose.test.d.ts.map +1 -0
  6. package/dist/__tests__/compose.test.js +171 -0
  7. package/dist/__tests__/compose.test.js.map +1 -0
  8. package/dist/__tests__/events.test.js +26 -0
  9. package/dist/__tests__/events.test.js.map +1 -1
  10. package/dist/__tests__/functions.test.js +205 -47
  11. package/dist/__tests__/functions.test.js.map +1 -1
  12. package/dist/__tests__/lazy.test.js +5 -7
  13. package/dist/__tests__/lazy.test.js.map +1 -1
  14. package/dist/__tests__/memo.test.js +114 -25
  15. package/dist/__tests__/memo.test.js.map +1 -1
  16. package/dist/__tests__/properties.test.js +193 -0
  17. package/dist/__tests__/properties.test.js.map +1 -1
  18. package/dist/__tests__/resource.test.d.ts +2 -0
  19. package/dist/__tests__/resource.test.d.ts.map +1 -0
  20. package/dist/__tests__/resource.test.js +127 -0
  21. package/dist/__tests__/resource.test.js.map +1 -0
  22. package/dist/__tests__/slot.test.js +32 -0
  23. package/dist/__tests__/slot.test.js.map +1 -1
  24. package/dist/__tests__/until.test.d.ts +2 -0
  25. package/dist/__tests__/until.test.d.ts.map +1 -0
  26. package/dist/__tests__/until.test.js +88 -0
  27. package/dist/__tests__/until.test.js.map +1 -0
  28. package/dist/__tests__/virtual.test.js +164 -15
  29. package/dist/__tests__/virtual.test.js.map +1 -1
  30. package/dist/component/component.d.ts +1 -1
  31. package/dist/component/component.d.ts.map +1 -1
  32. package/dist/component/component.js +15 -10
  33. package/dist/component/component.js.map +1 -1
  34. package/dist/component/lazy.d.ts.map +1 -1
  35. package/dist/component/lazy.js +29 -30
  36. package/dist/component/lazy.js.map +1 -1
  37. package/dist/component/virtual.d.ts.map +1 -1
  38. package/dist/component/virtual.js +49 -50
  39. package/dist/component/virtual.js.map +1 -1
  40. package/dist/create-class-decorator.d.ts +16 -0
  41. package/dist/create-class-decorator.d.ts.map +1 -0
  42. package/dist/create-class-decorator.js +35 -0
  43. package/dist/create-class-decorator.js.map +1 -0
  44. package/dist/create-field-decorator.d.ts +14 -0
  45. package/dist/create-field-decorator.d.ts.map +1 -0
  46. package/dist/create-field-decorator.js +37 -0
  47. package/dist/create-field-decorator.js.map +1 -0
  48. package/dist/create-getter-decorator.d.ts +18 -0
  49. package/dist/create-getter-decorator.d.ts.map +1 -0
  50. package/dist/create-getter-decorator.js +15 -0
  51. package/dist/create-getter-decorator.js.map +1 -0
  52. package/dist/create-lifecycle-method-decorator.d.ts +6 -0
  53. package/dist/create-lifecycle-method-decorator.d.ts.map +1 -0
  54. package/dist/create-lifecycle-method-decorator.js +22 -0
  55. package/dist/create-lifecycle-method-decorator.js.map +1 -0
  56. package/dist/create-method-decorator.d.ts +6 -0
  57. package/dist/create-method-decorator.d.ts.map +1 -0
  58. package/dist/create-method-decorator.js +14 -0
  59. package/dist/create-method-decorator.js.map +1 -0
  60. package/dist/events/emit.d.ts +1 -1
  61. package/dist/events/emit.d.ts.map +1 -1
  62. package/dist/events/emit.js +24 -29
  63. package/dist/events/emit.js.map +1 -1
  64. package/dist/events/on-command.d.ts +1 -2
  65. package/dist/events/on-command.d.ts.map +1 -1
  66. package/dist/events/on-command.js +15 -32
  67. package/dist/events/on-command.js.map +1 -1
  68. package/dist/functions/bind.d.ts +1 -2
  69. package/dist/functions/bind.d.ts.map +1 -1
  70. package/dist/functions/bind.js +4 -11
  71. package/dist/functions/bind.js.map +1 -1
  72. package/dist/functions/debounce.d.ts.map +1 -1
  73. package/dist/functions/debounce.js +21 -20
  74. package/dist/functions/debounce.js.map +1 -1
  75. package/dist/functions/index.d.ts +1 -0
  76. package/dist/functions/index.d.ts.map +1 -1
  77. package/dist/functions/index.js +1 -0
  78. package/dist/functions/index.js.map +1 -1
  79. package/dist/functions/log.d.ts +1 -2
  80. package/dist/functions/log.d.ts.map +1 -1
  81. package/dist/functions/log.js +40 -38
  82. package/dist/functions/log.js.map +1 -1
  83. package/dist/functions/memo.d.ts +1 -2
  84. package/dist/functions/memo.d.ts.map +1 -1
  85. package/dist/functions/memo.js +29 -27
  86. package/dist/functions/memo.js.map +1 -1
  87. package/dist/functions/once.d.ts +1 -2
  88. package/dist/functions/once.d.ts.map +1 -1
  89. package/dist/functions/once.js +14 -12
  90. package/dist/functions/once.js.map +1 -1
  91. package/dist/functions/retry.d.ts +1 -2
  92. package/dist/functions/retry.d.ts.map +1 -1
  93. package/dist/functions/retry.js +23 -20
  94. package/dist/functions/retry.js.map +1 -1
  95. package/dist/functions/throttle.d.ts +1 -2
  96. package/dist/functions/throttle.d.ts.map +1 -1
  97. package/dist/functions/throttle.js +11 -17
  98. package/dist/functions/throttle.js.map +1 -1
  99. package/dist/functions/until.d.ts +2 -0
  100. package/dist/functions/until.d.ts.map +1 -0
  101. package/dist/functions/until.js +17 -0
  102. package/dist/functions/until.js.map +1 -0
  103. package/dist/functions/watch.d.ts +1 -1
  104. package/dist/functions/watch.d.ts.map +1 -1
  105. package/dist/functions/watch.js +25 -39
  106. package/dist/functions/watch.js.map +1 -1
  107. package/dist/functions/when.d.ts +1 -2
  108. package/dist/functions/when.d.ts.map +1 -1
  109. package/dist/functions/when.js +10 -26
  110. package/dist/functions/when.js.map +1 -1
  111. package/dist/index.d.ts +7 -2
  112. package/dist/index.d.ts.map +1 -1
  113. package/dist/index.js +7 -2
  114. package/dist/index.js.map +1 -1
  115. package/dist/properties/compose.d.ts +3 -0
  116. package/dist/properties/compose.d.ts.map +1 -0
  117. package/dist/properties/compose.js +40 -0
  118. package/dist/properties/compose.js.map +1 -0
  119. package/dist/properties/computed.d.ts +1 -2
  120. package/dist/properties/computed.d.ts.map +1 -1
  121. package/dist/properties/computed.js +10 -9
  122. package/dist/properties/computed.js.map +1 -1
  123. package/dist/properties/history.d.ts.map +1 -1
  124. package/dist/properties/history.js +37 -32
  125. package/dist/properties/history.js.map +1 -1
  126. package/dist/properties/index.d.ts +2 -0
  127. package/dist/properties/index.d.ts.map +1 -1
  128. package/dist/properties/index.js +2 -0
  129. package/dist/properties/index.js.map +1 -1
  130. package/dist/properties/persisted.d.ts +1 -2
  131. package/dist/properties/persisted.d.ts.map +1 -1
  132. package/dist/properties/persisted.js +13 -29
  133. package/dist/properties/persisted.js.map +1 -1
  134. package/dist/properties/prop.d.ts +1 -2
  135. package/dist/properties/prop.d.ts.map +1 -1
  136. package/dist/properties/prop.js +21 -25
  137. package/dist/properties/prop.js.map +1 -1
  138. package/dist/properties/resource.d.ts +14 -0
  139. package/dist/properties/resource.d.ts.map +1 -0
  140. package/dist/properties/resource.js +27 -0
  141. package/dist/properties/resource.js.map +1 -0
  142. package/dist/properties/slot.d.ts +1 -2
  143. package/dist/properties/slot.d.ts.map +1 -1
  144. package/dist/properties/slot.js +15 -20
  145. package/dist/properties/slot.js.map +1 -1
  146. package/dist/properties/state.d.ts +1 -2
  147. package/dist/properties/state.d.ts.map +1 -1
  148. package/dist/properties/state.js +13 -18
  149. package/dist/properties/state.js.map +1 -1
  150. package/package.json +2 -2
  151. package/src/__tests__/component.test.ts +10 -0
  152. package/src/__tests__/compose.test.ts +202 -0
  153. package/src/__tests__/events.test.ts +32 -0
  154. package/src/__tests__/functions.test.ts +257 -46
  155. package/src/__tests__/lazy.test.ts +3 -5
  156. package/src/__tests__/memo.test.ts +143 -25
  157. package/src/__tests__/properties.test.ts +233 -0
  158. package/src/__tests__/resource.test.ts +141 -0
  159. package/src/__tests__/slot.test.ts +38 -0
  160. package/src/__tests__/until.test.ts +113 -0
  161. package/src/__tests__/virtual.test.ts +135 -7
  162. package/src/component/component.ts +27 -12
  163. package/src/component/lazy.ts +33 -37
  164. package/src/component/virtual.tsx +67 -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 +21 -23
  174. package/src/functions/index.ts +1 -0
  175. package/src/functions/log.ts +40 -43
  176. package/src/functions/memo.ts +28 -42
  177. package/src/functions/once.ts +13 -16
  178. package/src/functions/retry.ts +21 -22
  179. package/src/functions/throttle.ts +11 -24
  180. package/src/functions/until.ts +19 -0
  181. package/src/functions/watch.ts +27 -43
  182. package/src/functions/when.ts +11 -36
  183. package/src/index.ts +29 -0
  184. package/src/properties/compose.ts +53 -0
  185. package/src/properties/computed.ts +11 -13
  186. package/src/properties/history.ts +42 -41
  187. package/src/properties/index.ts +2 -0
  188. package/src/properties/persisted.ts +17 -58
  189. package/src/properties/prop.ts +21 -31
  190. package/src/properties/resource.ts +34 -0
  191. package/src/properties/slot.ts +17 -30
  192. package/src/properties/state.ts +14 -24
@@ -1 +1 @@
1
- {"version":3,"file":"persisted.d.ts","sourceRoot":"","sources":["../../src/properties/persisted.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,yBAAyB,CAAC;AAkCjC,wBAAgB,SAAS,CAAC,CAAC,EACzB,GAAG,CAAC,EAAE,MAAM,EACZ,OAAO,GAAE,sBAAsB,CAAC,CAAC,CAAM,IAGrC,QAAQ,SAAS,EACjB,SAAS,0BAA0B,CAAC,iBAAiB,CAAC,KACrD,IAAI,CAsCR"}
1
+ {"version":3,"file":"persisted.d.ts","sourceRoot":"","sources":["../../src/properties/persisted.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAwBvF,wBAAgB,SAAS,CAAC,CAAC,EACzB,GAAG,CAAC,EAAE,MAAM,EACZ,OAAO,GAAE,sBAAsB,CAAC,CAAC,CAAM,gHAgBxC"}
@@ -1,16 +1,9 @@
1
- import { persistedSignal, } from "@praxisjs/core/internal";
1
+ import { persistedSignal } from "@praxisjs/core/internal";
2
+ import { createFieldDecorator } from "../create-field-decorator";
2
3
  const signalMap = new WeakMap();
3
- const initMap = new WeakMap();
4
- function markInitialized(instance, propKey) {
5
- if (!initMap.has(instance)) {
6
- initMap.set(instance, new Set());
7
- }
8
- initMap.get(instance).add(propKey);
9
- }
10
4
  function getOrCreateSignal(instance, storageKey, initialValue, options) {
11
- if (!signalMap.has(instance)) {
5
+ if (!signalMap.has(instance))
12
6
  signalMap.set(instance, new Map());
13
- }
14
7
  const map = signalMap.get(instance);
15
8
  if (!map.has(storageKey)) {
16
9
  map.set(storageKey, persistedSignal(storageKey, initialValue, options));
@@ -18,26 +11,17 @@ function getOrCreateSignal(instance, storageKey, initialValue, options) {
18
11
  return map.get(storageKey);
19
12
  }
20
13
  export function Persisted(key, options = {}) {
21
- return function (_value, context) {
22
- context.addInitializer(function () {
23
- const instance = this;
24
- const propertyKey = context.name;
25
- const storageKey = key ?? propertyKey;
26
- const initialValue = instance[propertyKey];
27
- Reflect.deleteProperty(instance, propertyKey);
28
- markInitialized(instance, propertyKey);
14
+ return createFieldDecorator({
15
+ bind(instance, name, initialValue) {
16
+ const storageKey = key ?? name;
29
17
  getOrCreateSignal(instance, storageKey, initialValue, options);
30
- Object.defineProperty(instance, propertyKey, {
31
- get() {
32
- return getOrCreateSignal(instance, storageKey, undefined, options)();
33
- },
34
- set(value) {
35
- getOrCreateSignal(instance, storageKey, undefined, options).set(value);
18
+ return {
19
+ descriptor: {
20
+ get: () => getOrCreateSignal(instance, storageKey, undefined, options)(),
21
+ set: (value) => { getOrCreateSignal(instance, storageKey, undefined, options).set(value); },
36
22
  },
37
- enumerable: true,
38
- configurable: true,
39
- });
40
- });
41
- };
23
+ };
24
+ },
25
+ });
42
26
  }
43
27
  //# sourceMappingURL=persisted.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"persisted.js","sourceRoot":"","sources":["../../src/properties/persisted.ts"],"names":[],"mappings":"AACA,OAAO,EACL,eAAe,GAEhB,MAAM,yBAAyB,CAAC;AAGjC,MAAM,SAAS,GAAG,IAAI,OAAO,EAAwC,CAAC;AACtE,MAAM,OAAO,GAAG,IAAI,OAAO,EAAuB,CAAC;AAEnD,SAAS,eAAe,CAAC,QAAgB,EAAE,OAAe;IACxD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;IACnC,CAAC;IACA,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AACtD,CAAC;AAED,SAAS,iBAAiB,CACxB,QAAgB,EAChB,UAAkB,EAClB,YAAe,EACf,OAAkC;IAElC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;IACrC,CAAC;IACD,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAiC,CAAC;IAEpE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;QACzB,GAAG,CAAC,GAAG,CACL,UAAU,EACV,eAAe,CAAC,UAAU,EAAE,YAAY,EAAE,OAAO,CAAoB,CACtE,CAAC;IACJ,CAAC;IAED,OAAO,GAAG,CAAC,GAAG,CAAC,UAAU,CAAc,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,SAAS,CACvB,GAAY,EACZ,UAAqC,EAAE;IAEvC,OAAO,UACL,MAAiB,EACjB,OAAsD;QAEtD,OAAO,CAAC,cAAc,CAAC;YACrB,MAAM,QAAQ,GAAG,IAAc,CAAC;YAChC,MAAM,WAAW,GAAG,OAAO,CAAC,IAAc,CAAC;YAC3C,MAAM,UAAU,GAAG,GAAG,IAAI,WAAW,CAAC;YACtC,MAAM,YAAY,GAAI,QAAoC,CACxD,WAAW,CACP,CAAC;YAEP,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;YAE9C,eAAe,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;YACvC,iBAAiB,CAAC,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;YAE/D,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,WAAW,EAAE;gBAC3C,GAAG;oBACD,OAAO,iBAAiB,CACtB,QAAQ,EACR,UAAU,EACV,SAAc,EACd,OAAO,CACR,EAAE,CAAC;gBACN,CAAC;gBAED,GAAG,CAAC,KAAQ;oBACV,iBAAiB,CACf,QAAQ,EACR,UAAU,EACV,SAAc,EACd,OAAO,CACR,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBACf,CAAC;gBAED,UAAU,EAAE,IAAI;gBAChB,YAAY,EAAE,IAAI;aACnB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"persisted.js","sourceRoot":"","sources":["../../src/properties/persisted.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAA+B,MAAM,yBAAyB,CAAC;AAGvF,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEjE,MAAM,SAAS,GAAG,IAAI,OAAO,EAAwC,CAAC;AAEtE,SAAS,iBAAiB,CACxB,QAAgB,EAChB,UAAkB,EAClB,YAAe,EACf,OAAkC;IAElC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC;QAAE,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;IACjE,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAiC,CAAC;IACpE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;QACzB,GAAG,CAAC,GAAG,CACL,UAAU,EACV,eAAe,CAAC,UAAU,EAAE,YAAY,EAAE,OAAO,CAAoB,CACtE,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC,GAAG,CAAC,UAAU,CAAc,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,SAAS,CACvB,GAAY,EACZ,UAAqC,EAAE;IAEvC,OAAO,oBAAoB,CAAC;QAC1B,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,YAAY;YAC/B,MAAM,UAAU,GAAG,GAAG,IAAI,IAAI,CAAC;YAC/B,iBAAiB,CAAC,QAAQ,EAAE,UAAU,EAAE,YAAiB,EAAE,OAAO,CAAC,CAAC;YACpE,OAAO;gBACL,UAAU,EAAE;oBACV,GAAG,EAAE,GAAG,EAAE,CACR,iBAAiB,CAAI,QAAQ,EAAE,UAAU,EAAE,SAAc,EAAE,OAAO,CAAC,EAAE;oBACvE,GAAG,EAAE,CAAC,KAAQ,EAAE,EAAE,GACd,iBAAiB,CAAI,QAAQ,EAAE,UAAU,EAAE,SAAc,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;iBACtF;aACF,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -1,3 +1,2 @@
1
- import type { StatefulComponent } from "@praxisjs/core";
2
- export declare function Prop(): (_value: undefined, context: ClassFieldDecoratorContext<StatefulComponent>) => void;
1
+ export declare function Prop(): (_value: undefined, context: ClassFieldDecoratorContext<import("@praxisjs/core").StatefulComponent>) => void;
3
2
  //# sourceMappingURL=prop.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prop.d.ts","sourceRoot":"","sources":["../../src/properties/prop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,wBAAgB,IAAI,KAEhB,QAAQ,SAAS,EACjB,SAAS,0BAA0B,CAAC,iBAAiB,CAAC,KACrD,IAAI,CA4BR"}
1
+ {"version":3,"file":"prop.d.ts","sourceRoot":"","sources":["../../src/properties/prop.ts"],"names":[],"mappings":"AAEA,wBAAgB,IAAI,iHAsBnB"}
@@ -1,29 +1,25 @@
1
+ import { createFieldDecorator } from "../create-field-decorator";
1
2
  export function Prop() {
2
- return function (_value, context) {
3
- context.addInitializer(function () {
4
- const instance = this;
5
- const name = context.name;
6
- const raw = instance;
7
- const defaultValue = raw[name];
8
- Reflect.deleteProperty(raw, name);
9
- instance._defaults[name] = defaultValue;
10
- Object.defineProperty(instance, name, {
11
- get() {
12
- const fromParent = this._rawProps[name];
13
- if (fromParent !== undefined) {
14
- return typeof fromParent === "function"
15
- ? fromParent()
16
- : fromParent;
17
- }
18
- return this._defaults[name];
3
+ return createFieldDecorator({
4
+ bind(instance, name, initialValue) {
5
+ instance._defaults[name] = initialValue;
6
+ return {
7
+ descriptor: {
8
+ get() {
9
+ const fromParent = (instance._rawProps)[name];
10
+ if (fromParent !== undefined) {
11
+ return typeof fromParent === "function"
12
+ ? fromParent()
13
+ : fromParent;
14
+ }
15
+ return instance._defaults[name];
16
+ },
17
+ set(value) {
18
+ instance._defaults[name] = value;
19
+ },
19
20
  },
20
- set(value) {
21
- this._defaults[name] = value;
22
- },
23
- enumerable: true,
24
- configurable: true,
25
- });
26
- });
27
- };
21
+ };
22
+ },
23
+ });
28
24
  }
29
25
  //# sourceMappingURL=prop.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"prop.js","sourceRoot":"","sources":["../../src/properties/prop.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,IAAI;IAClB,OAAO,UACL,MAAiB,EACjB,OAAsD;QAEtD,OAAO,CAAC,cAAc,CAAC;YACrB,MAAM,QAAQ,GAAG,IAAyB,CAAC;YAC3C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAc,CAAC;YACpC,MAAM,GAAG,GAAG,QAA8C,CAAC;YAC3D,MAAM,YAAY,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;YAC/B,OAAO,CAAC,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YAElC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC;YAExC,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,IAAI,EAAE;gBACpC,GAAG;oBACD,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;oBACxC,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;wBAC7B,OAAO,OAAO,UAAU,KAAK,UAAU;4BACrC,CAAC,CAAE,UAA4B,EAAE;4BACjC,CAAC,CAAC,UAAU,CAAC;oBACjB,CAAC;oBACD,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;gBAC9B,CAAC;gBACD,GAAG,CAA0B,KAAc;oBACzC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;gBAC/B,CAAC;gBACD,UAAU,EAAE,IAAI;gBAChB,YAAY,EAAE,IAAI;aACnB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"prop.js","sourceRoot":"","sources":["../../src/properties/prop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEjE,MAAM,UAAU,IAAI;IAClB,OAAO,oBAAoB,CAAC;QAC1B,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,YAAY;YAC/B,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC;YACxC,OAAO;gBACL,UAAU,EAAE;oBACV,GAAG;wBACD,MAAM,UAAU,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC;wBAC9C,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;4BAC7B,OAAO,OAAO,UAAU,KAAK,UAAU;gCACrC,CAAC,CAAE,UAA4B,EAAE;gCACjC,CAAC,CAAC,UAAU,CAAC;wBACjB,CAAC;wBACD,OAAO,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;oBAClC,CAAC;oBACD,GAAG,CAAC,KAAc;wBAChB,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;oBACnC,CAAC;iBACF;aACF,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { type Resource as ResourceInstance, type ResourceOptions } from "@praxisjs/core/internal";
2
+ export type { ResourceInstance, ResourceOptions };
3
+ /**
4
+ * Binds an async resource to the field. The field holds a Resource<T> object
5
+ * with reactive data, pending, error, and status signals, plus refetch/cancel/mutate methods.
6
+ *
7
+ * class MyComponent extends StatefulComponent {
8
+ * @Resource(() => api.getUsers())
9
+ * users!: ResourceInstance<User[]>;
10
+ * // access: this.users.data(), this.users.pending(), this.users.refetch()
11
+ * }
12
+ */
13
+ export declare function Resource<T>(fetcher: () => Promise<T>, options?: ResourceOptions<T>): (_value: undefined, context: ClassFieldDecoratorContext<import("@praxisjs/core").StatefulComponent>) => void;
14
+ //# sourceMappingURL=resource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../../src/properties/resource.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,QAAQ,IAAI,gBAAgB,EACjC,KAAK,eAAe,EACrB,MAAM,yBAAyB,CAAC;AAIjC,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,CAAC;AAElD;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,GAAE,eAAe,CAAC,CAAC,CAAM,gHAatF"}
@@ -0,0 +1,27 @@
1
+ import { resource, } from "@praxisjs/core/internal";
2
+ import { createFieldDecorator } from "../create-field-decorator";
3
+ /**
4
+ * Binds an async resource to the field. The field holds a Resource<T> object
5
+ * with reactive data, pending, error, and status signals, plus refetch/cancel/mutate methods.
6
+ *
7
+ * class MyComponent extends StatefulComponent {
8
+ * @Resource(() => api.getUsers())
9
+ * users!: ResourceInstance<User[]>;
10
+ * // access: this.users.data(), this.users.pending(), this.users.refetch()
11
+ * }
12
+ */
13
+ export function Resource(fetcher, options = {}) {
14
+ return createFieldDecorator({
15
+ bind(_instance, _name, _initialValue) {
16
+ const r = resource(fetcher, options);
17
+ return {
18
+ descriptor: {
19
+ get() { return r; },
20
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
21
+ set() { },
22
+ },
23
+ };
24
+ },
25
+ });
26
+ }
27
+ //# sourceMappingURL=resource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource.js","sourceRoot":"","sources":["../../src/properties/resource.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,GAGT,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,oBAAoB,EAAqB,MAAM,2BAA2B,CAAC;AAIpF;;;;;;;;;GASG;AACH,MAAM,UAAU,QAAQ,CAAI,OAAyB,EAAE,UAA8B,EAAE;IACrF,OAAO,oBAAoB,CAAC;QAC1B,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,aAAa;YAClC,MAAM,CAAC,GAAG,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACrC,OAAO;gBACL,UAAU,EAAE;oBACV,GAAG,KAA0B,OAAO,CAAC,CAAC,CAAC,CAAC;oBACxC,gEAAgE;oBAChE,GAAG,KAAU,CAAC;iBACf;aACF,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -1,5 +1,4 @@
1
- import type { StatefulComponent } from "@praxisjs/core";
2
1
  export declare function initSlots(instance: object, children: unknown): void;
3
2
  export declare function getSlot(instance: object, name: string): unknown[];
4
- export declare function Slot(name?: string): (_value: undefined, context: ClassFieldDecoratorContext<StatefulComponent>) => void;
3
+ export declare function Slot(name?: string): (_value: undefined, context: ClassFieldDecoratorContext<import("@praxisjs/core").StatefulComponent>) => void;
5
4
  //# sourceMappingURL=slot.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"slot.d.ts","sourceRoot":"","sources":["../../src/properties/slot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAgCxD,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI,CAEnE;AAED,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE,CAEjE;AAED,wBAAgB,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,IAE9B,QAAQ,SAAS,EACjB,SAAS,0BAA0B,CAAC,iBAAiB,CAAC,KACrD,IAAI,CA0BR"}
1
+ {"version":3,"file":"slot.d.ts","sourceRoot":"","sources":["../../src/properties/slot.ts"],"names":[],"mappings":"AA+BA,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI,CAEnE;AAED,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE,CAEjE;AAED,wBAAgB,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,gHAkBjC"}
@@ -1,3 +1,4 @@
1
+ import { createFieldDecorator } from "../create-field-decorator";
1
2
  const slotsMap = new WeakMap();
2
3
  function resolveSlots(children) {
3
4
  const slots = new Map();
@@ -9,7 +10,6 @@ function resolveSlots(children) {
9
10
  ? children.flat(Infinity)
10
11
  : [children];
11
12
  for (const child of arr) {
12
- // Named slots via `slot` attribute on DOM elements
13
13
  if (child instanceof Element) {
14
14
  const slotName = child.getAttribute("slot");
15
15
  if (slotName) {
@@ -32,25 +32,20 @@ export function getSlot(instance, name) {
32
32
  return slotsMap.get(instance)?.get(name) ?? [];
33
33
  }
34
34
  export function Slot(name) {
35
- return function (_value, context) {
36
- context.addInitializer(function () {
37
- const instance = this;
38
- const propKey = context.name;
39
- const slotName = name ?? (propKey === "default" ? "default" : propKey);
40
- Reflect.deleteProperty(instance, propKey);
41
- Object.defineProperty(instance, propKey, {
42
- get() {
43
- return getSlot(this, slotName);
35
+ return createFieldDecorator({
36
+ bind(instance, propName, _initialValue) {
37
+ const slotName = name ?? (propName === "default" ? "default" : propName);
38
+ return {
39
+ descriptor: {
40
+ get: () => getSlot(instance, slotName),
41
+ set: (_value) => {
42
+ if (process.env.NODE_ENV !== "production") {
43
+ console.warn(`[Slot] "${propName}" is a slot and cannot be assigned directly. Slots are filled by the parent component.`);
44
+ }
45
+ },
44
46
  },
45
- set(_value) {
46
- if (process.env.NODE_ENV !== "production") {
47
- console.warn(`[Slot] "${propKey}" is a slot and cannot be assigned directly. Slots are filled by the parent component.`);
48
- }
49
- },
50
- enumerable: true,
51
- configurable: true,
52
- });
53
- });
54
- };
47
+ };
48
+ },
49
+ });
55
50
  }
56
51
  //# sourceMappingURL=slot.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"slot.js","sourceRoot":"","sources":["../../src/properties/slot.ts"],"names":[],"mappings":"AAEA,MAAM,QAAQ,GAAG,IAAI,OAAO,EAAkC,CAAC;AAE/D,SAAS,YAAY,CAAC,QAAiB;IACrC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAqB,CAAC;IAC3C,MAAM,WAAW,GAAc,EAAE,CAAC;IAClC,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAElC,IAAI,QAAQ,IAAI,IAAI;QAAE,OAAO,KAAK,CAAC;IAEnC,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;QACjC,CAAC,CAAE,QAAsB,CAAC,IAAI,CAAC,QAAQ,CAAC;QACxC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAEf,KAAK,MAAM,KAAK,IAAI,GAAG,EAAE,CAAC;QACxB,mDAAmD;QACnD,IAAI,KAAK,YAAY,OAAO,EAAE,CAAC;YAC7B,MAAM,QAAQ,GAAG,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;YAC5C,IAAI,QAAQ,EAAE,CAAC;gBACb,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;gBAC9B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC;oBAAE,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;gBACjD,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC/C,SAAS;YACX,CAAC;QACH,CAAC;QACD,IAAI,KAAK,IAAI,IAAI;YAAE,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7C,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,QAAgB,EAAE,QAAiB;IAC3D,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,QAAgB,EAAE,IAAY;IACpD,OAAO,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,IAAa;IAChC,OAAO,UACL,MAAiB,EACjB,OAAsD;QAEtD,OAAO,CAAC,cAAc,CAAC;YACrB,MAAM,QAAQ,GAAG,IAAyB,CAAC;YAC3C,MAAM,OAAO,GAAG,OAAO,CAAC,IAAc,CAAC;YACvC,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;YAEvE,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAE1C,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE;gBACvC,GAAG;oBACD,OAAO,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;gBACjC,CAAC;gBAED,GAAG,CAAC,MAAe;oBACjB,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;wBAC1C,OAAO,CAAC,IAAI,CACV,WAAW,OAAO,wFAAwF,CAC3G,CAAC;oBACJ,CAAC;gBACH,CAAC;gBAED,UAAU,EAAE,IAAI;gBAChB,YAAY,EAAE,IAAI;aACnB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"slot.js","sourceRoot":"","sources":["../../src/properties/slot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEjE,MAAM,QAAQ,GAAG,IAAI,OAAO,EAAkC,CAAC;AAE/D,SAAS,YAAY,CAAC,QAAiB;IACrC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAqB,CAAC;IAC3C,MAAM,WAAW,GAAc,EAAE,CAAC;IAClC,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAElC,IAAI,QAAQ,IAAI,IAAI;QAAE,OAAO,KAAK,CAAC;IAEnC,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;QACjC,CAAC,CAAE,QAAsB,CAAC,IAAI,CAAC,QAAQ,CAAC;QACxC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAEf,KAAK,MAAM,KAAK,IAAI,GAAG,EAAE,CAAC;QACxB,IAAI,KAAK,YAAY,OAAO,EAAE,CAAC;YAC7B,MAAM,QAAQ,GAAG,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;YAC5C,IAAI,QAAQ,EAAE,CAAC;gBACb,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;gBAC9B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC;oBAAE,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;gBACjD,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC/C,SAAS;YACX,CAAC;QACH,CAAC;QACD,IAAI,KAAK,IAAI,IAAI;YAAE,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7C,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,QAAgB,EAAE,QAAiB;IAC3D,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,QAAgB,EAAE,IAAY;IACpD,OAAO,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,IAAa;IAChC,OAAO,oBAAoB,CAAC;QAC1B,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,aAAa;YACpC,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;YACzE,OAAO;gBACL,UAAU,EAAE;oBACV,GAAG,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC;oBACtC,GAAG,EAAE,CAAC,MAAe,EAAE,EAAE;wBACvB,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;4BAC1C,OAAO,CAAC,IAAI,CACV,WAAW,QAAQ,wFAAwF,CAC5G,CAAC;wBACJ,CAAC;oBACH,CAAC;iBACF;aACF,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -1,3 +1,2 @@
1
- import type { StatefulComponent } from "@praxisjs/core";
2
- export declare function State(): (_value: undefined, context: ClassFieldDecoratorContext<StatefulComponent>) => void;
1
+ export declare function State(): (_value: undefined, context: ClassFieldDecoratorContext<import("@praxisjs/core").StatefulComponent>) => void;
3
2
  //# sourceMappingURL=state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/properties/state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAGxD,wBAAgB,KAAK,KAEjB,QAAQ,SAAS,EACjB,SAAS,0BAA0B,CAAC,iBAAiB,CAAC,KACrD,IAAI,CAsBR"}
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/properties/state.ts"],"names":[],"mappings":"AAIA,wBAAgB,KAAK,iHAepB"}
@@ -1,24 +1,19 @@
1
1
  import { signal } from "@praxisjs/core/internal";
2
+ import { createFieldDecorator } from "../create-field-decorator";
2
3
  export function State() {
3
- return function (_value, context) {
4
- context.addInitializer(function () {
5
- const instance = this;
6
- const name = context.name;
7
- const initialValue = instance[name];
8
- Reflect.deleteProperty(instance, name);
4
+ return createFieldDecorator({
5
+ bind(instance, _name, initialValue) {
9
6
  const sig = signal(initialValue);
10
- Object.defineProperty(instance, name, {
11
- get() {
12
- return sig();
7
+ return {
8
+ descriptor: {
9
+ get: () => sig(),
10
+ set: (value) => {
11
+ instance._stateDirty = true;
12
+ sig.set(value);
13
+ },
13
14
  },
14
- set(value) {
15
- instance._stateDirty = true;
16
- sig.set(value);
17
- },
18
- enumerable: true,
19
- configurable: true,
20
- });
21
- });
22
- };
15
+ };
16
+ },
17
+ });
23
18
  }
24
19
  //# sourceMappingURL=state.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/properties/state.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEjD,MAAM,UAAU,KAAK;IACnB,OAAO,UACL,MAAiB,EACjB,OAAsD;QAEtD,OAAO,CAAC,cAAc,CAAC;YACrB,MAAM,QAAQ,GAAG,IAAmD,CAAC;YACrE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAc,CAAC;YACpC,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;YACpC,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YAEvC,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;YAEjC,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,IAAI,EAAE;gBACpC,GAAG;oBACD,OAAO,GAAG,EAAE,CAAC;gBACf,CAAC;gBACD,GAAG,CAAC,KAAc;oBAChB,QAAQ,CAAC,WAAW,GAAG,IAAI,CAAC;oBAC5B,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBACjB,CAAC;gBACD,UAAU,EAAE,IAAI;gBAChB,YAAY,EAAE,IAAI;aACnB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/properties/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEjE,MAAM,UAAU,KAAK;IACnB,OAAO,oBAAoB,CAAC;QAC1B,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,YAAY;YAChC,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;YACjC,OAAO;gBACL,UAAU,EAAE;oBACV,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE;oBAChB,GAAG,EAAE,CAAC,KAAc,EAAE,EAAE;wBACtB,QAAQ,CAAC,WAAW,GAAG,IAAI,CAAC;wBAC5B,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;oBACjB,CAAC;iBACF;aACF,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@praxisjs/decorators",
3
- "version": "0.4.3",
3
+ "version": "0.6.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -15,7 +15,7 @@
15
15
  "typescript": "^5.9.3"
16
16
  },
17
17
  "dependencies": {
18
- "@praxisjs/core": "0.4.2",
18
+ "@praxisjs/core": "1.1.0",
19
19
  "@praxisjs/shared": "0.2.0"
20
20
  },
21
21
  "scripts": {
@@ -153,4 +153,14 @@ describe("Component decorator", () => {
153
153
  const Enhanced = Component()(MyComp, {} as ClassDecoratorContext);
154
154
  expect(Enhanced).not.toBe(MyComp);
155
155
  });
156
+
157
+ it("render() falls through to originalRender when enhancement has no render override", () => {
158
+ class MyComp extends StatefulComponent {
159
+ render() { return null; }
160
+ }
161
+ const Enhanced = Component()(MyComp, {} as ClassDecoratorContext);
162
+ const instance = new Enhanced();
163
+ // ComponentBehavior.create() returns {} (no render), so line 48 is hit
164
+ expect((instance as StatefulComponent).render()).toBeNull();
165
+ });
156
166
  });
@@ -0,0 +1,202 @@
1
+ import { describe, it, expect, vi } from "vitest";
2
+
3
+ import { StatefulComponent } from "@praxisjs/core";
4
+ import { signal } from "@praxisjs/core/internal";
5
+ import type { Composable } from "@praxisjs/core";
6
+
7
+ import { Compose } from "../properties/compose";
8
+
9
+ function fieldCtx(name: string) {
10
+ const initializers: Array<(this: unknown) => void> = [];
11
+ return {
12
+ ctx: {
13
+ name,
14
+ kind: "field" as const,
15
+ addInitializer(fn: (this: unknown) => void) {
16
+ initializers.push(fn);
17
+ },
18
+ } as ClassFieldDecoratorContext,
19
+ run(instance: unknown) {
20
+ initializers.forEach((fn) => { fn.call(instance); });
21
+ },
22
+ };
23
+ }
24
+
25
+ class TestComponent extends StatefulComponent {
26
+ render() { return null; }
27
+ }
28
+
29
+ // Simple composable returning plain values
30
+ class CounterComposable implements Composable {
31
+ count = 0;
32
+ setup() {
33
+ return { count: this.count, label: "counter" };
34
+ }
35
+ }
36
+
37
+ // Composable returning a signal (reactive property)
38
+ class ReactiveComposable implements Composable {
39
+ _count = signal(0);
40
+ setup() {
41
+ return { count: this._count };
42
+ }
43
+ }
44
+
45
+ // Composable with lifecycle hooks
46
+ class LifecycleComposable implements Composable {
47
+ onMount = vi.fn();
48
+ onUnmount = vi.fn();
49
+ setup() {
50
+ return { active: true };
51
+ }
52
+ }
53
+
54
+ // Composable that uses constructor args
55
+ class ArgsComposable implements Composable {
56
+ constructor(private multiplier: number) {}
57
+ setup() {
58
+ return { multiplier: this.multiplier };
59
+ }
60
+ }
61
+
62
+ // Composable returning a plain function (non-reactive) in its view
63
+ class PlainFnComposable {
64
+ setup() {
65
+ return { handler: () => 42 };
66
+ }
67
+ }
68
+
69
+ describe("@Compose decorator", () => {
70
+ it("creates a view getter on the field", () => {
71
+ const { ctx, run } = fieldCtx("counter");
72
+ Compose(CounterComposable)(undefined, ctx);
73
+
74
+ const instance = new TestComponent();
75
+ run(instance);
76
+
77
+ const view = (instance as unknown as Record<string, unknown>).counter as Record<string, unknown>;
78
+ expect(view).toBeDefined();
79
+ expect(view.count).toBe(0);
80
+ expect(view.label).toBe("counter");
81
+ });
82
+
83
+ it("reactive signal values are resolved via getter", () => {
84
+ const { ctx, run } = fieldCtx("reactive");
85
+ Compose(ReactiveComposable)(undefined, ctx);
86
+
87
+ const instance = new TestComponent();
88
+ run(instance);
89
+
90
+ const view = (instance as unknown as Record<string, unknown>).reactive as Record<string, unknown>;
91
+ expect(view.count).toBe(0);
92
+ });
93
+
94
+ it("calls onMount when component mounts", () => {
95
+ const { ctx, run } = fieldCtx("lc");
96
+ Compose(LifecycleComposable)(undefined, ctx);
97
+
98
+ const instance = new TestComponent();
99
+ run(instance);
100
+
101
+ const view = (instance as unknown as Record<string, unknown>).lc as Record<string, unknown>;
102
+ expect(view).toBeDefined();
103
+
104
+ // Trigger onMount
105
+ instance.onMount!();
106
+ const lc = new LifecycleComposable();
107
+ // The composable's onMount would have been called
108
+ // We verify the instance has an onMount wiring
109
+ expect(typeof instance.onMount).toBe("function");
110
+ });
111
+
112
+ it("calls onUnmount when component unmounts", () => {
113
+ const { ctx, run } = fieldCtx("lc2");
114
+ Compose(LifecycleComposable)(undefined, ctx);
115
+
116
+ const instance = new TestComponent();
117
+ run(instance);
118
+ expect(typeof instance.onUnmount).toBe("function");
119
+ });
120
+
121
+ it("invoking instance.onUnmount() executes the composable's onUnmount", () => {
122
+ const unmountSpy = vi.fn();
123
+
124
+ class SpyComposable {
125
+ onUnmount = unmountSpy;
126
+ setup() { return {}; }
127
+ }
128
+
129
+ const { ctx, run } = fieldCtx("spyComp");
130
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
131
+ Compose(SpyComposable as any)(undefined, ctx);
132
+
133
+ const instance = new TestComponent();
134
+ run(instance);
135
+
136
+ instance.onUnmount!();
137
+ expect(unmountSpy).toHaveBeenCalled();
138
+ });
139
+
140
+ it("passes constructor args to the composable", () => {
141
+ const { ctx, run } = fieldCtx("args");
142
+ Compose(ArgsComposable, 5)(undefined, ctx);
143
+
144
+ const instance = new TestComponent();
145
+ run(instance);
146
+
147
+ const view = (instance as unknown as Record<string, unknown>).args as Record<string, unknown>;
148
+ expect(view.multiplier).toBe(5);
149
+ });
150
+
151
+ it("resolves string constructor args from instance properties", () => {
152
+ const { ctx, run } = fieldCtx("resolved");
153
+ Compose(ArgsComposable, "myMultiplier")(undefined, ctx);
154
+
155
+ const instance = new TestComponent();
156
+ (instance as unknown as Record<string, unknown>).myMultiplier = 10;
157
+ run(instance);
158
+
159
+ const view = (instance as unknown as Record<string, unknown>).resolved as Record<string, unknown>;
160
+ expect(view.multiplier).toBe(10);
161
+ });
162
+
163
+ it("each instance gets its own composable view", () => {
164
+ const { ctx, run } = fieldCtx("c");
165
+ Compose(CounterComposable)(undefined, ctx);
166
+
167
+ const a = new TestComponent();
168
+ const b = new TestComponent();
169
+ run(a);
170
+ run(b);
171
+
172
+ const viewA = (a as unknown as Record<string, unknown>).c;
173
+ const viewB = (b as unknown as Record<string, unknown>).c;
174
+ expect(viewA).not.toBe(viewB);
175
+ });
176
+
177
+ it("plain function value in view is stored as-is (not treated as reactive)", () => {
178
+ const { ctx, run } = fieldCtx("pfn");
179
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
180
+ Compose(PlainFnComposable as any)(undefined, ctx);
181
+
182
+ const instance = new TestComponent();
183
+ run(instance);
184
+
185
+ const view = (instance as unknown as Record<string, unknown>).pfn as Record<string, unknown>;
186
+ // handler is a plain function — isReactive returns false, stored directly
187
+ expect(typeof view.handler).toBe("function");
188
+ expect((view.handler as () => number)()).toBe(42);
189
+ });
190
+
191
+ it("view getter always returns same view object", () => {
192
+ const { ctx, run } = fieldCtx("stable");
193
+ Compose(CounterComposable)(undefined, ctx);
194
+
195
+ const instance = new TestComponent();
196
+ run(instance);
197
+
198
+ const v1 = (instance as unknown as Record<string, unknown>).stable;
199
+ const v2 = (instance as unknown as Record<string, unknown>).stable;
200
+ expect(v1).toBe(v2);
201
+ });
202
+ });
@@ -213,6 +213,38 @@ describe("OnCommand decorator", () => {
213
213
  warn.mockRestore();
214
214
  });
215
215
 
216
+ it("uses 'unknown' as component name when constructor.name is undefined (missing-prop branch)", () => {
217
+ const { ctx, run } = methodCtx("onNoName");
218
+ OnCommand("missingProp")(vi.fn() as never, ctx as unknown as ClassMethodDecoratorContext<StatefulComponent>);
219
+
220
+ // Instance whose constructor.name is undefined to hit ?? "unknown"
221
+ const fakeInstance = Object.assign(new TestComponent(), {
222
+ constructor: { name: undefined },
223
+ });
224
+ run(fakeInstance);
225
+
226
+ const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
227
+ fakeInstance.onMount?.();
228
+ expect(warn).toHaveBeenCalledWith(expect.stringContaining("unknown"));
229
+ warn.mockRestore();
230
+ });
231
+
232
+ it("uses 'unknown' as component name when constructor.name is undefined (invalid-command branch)", () => {
233
+ const { ctx, run } = methodCtx("onNoName2");
234
+ OnCommand("badProp")(vi.fn() as never, ctx as unknown as ClassMethodDecoratorContext<StatefulComponent>);
235
+
236
+ // Instance with a non-command prop and undefined constructor.name
237
+ const fakeInstance = Object.assign(new TestComponent({ badProp: "not-a-command" }), {
238
+ constructor: { name: undefined },
239
+ });
240
+ run(fakeInstance);
241
+
242
+ const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
243
+ fakeInstance.onMount?.();
244
+ expect(warn).toHaveBeenCalledWith(expect.stringContaining("unknown"));
245
+ warn.mockRestore();
246
+ });
247
+
216
248
  it("preserves the original onMount and onUnmount implementations", () => {
217
249
  const { ctx, run } = methodCtx("onEvt");
218
250
  OnCommand("evt")(vi.fn() as never, ctx as unknown as ClassMethodDecoratorContext<StatefulComponent>);