@praxisjs/decorators 0.2.0 → 0.4.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 (131) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/dist/component/component.d.ts +2 -2
  3. package/dist/component/component.d.ts.map +1 -1
  4. package/dist/component/component.js +5 -2
  5. package/dist/component/component.js.map +1 -1
  6. package/dist/component/index.d.ts +0 -1
  7. package/dist/component/index.d.ts.map +1 -1
  8. package/dist/component/index.js +0 -1
  9. package/dist/component/index.js.map +1 -1
  10. package/dist/component/lazy.d.ts +2 -2
  11. package/dist/component/lazy.d.ts.map +1 -1
  12. package/dist/component/lazy.js +8 -8
  13. package/dist/component/lazy.js.map +1 -1
  14. package/dist/component/virtual.d.ts +2 -2
  15. package/dist/component/virtual.d.ts.map +1 -1
  16. package/dist/component/virtual.js +45 -14
  17. package/dist/component/virtual.js.map +1 -1
  18. package/dist/events/emit.d.ts +2 -1
  19. package/dist/events/emit.d.ts.map +1 -1
  20. package/dist/events/emit.js +11 -16
  21. package/dist/events/emit.js.map +1 -1
  22. package/dist/events/helper.d.ts +2 -2
  23. package/dist/events/helper.d.ts.map +1 -1
  24. package/dist/events/helper.js.map +1 -1
  25. package/dist/events/on-command.d.ts +2 -1
  26. package/dist/events/on-command.d.ts.map +1 -1
  27. package/dist/events/on-command.js +30 -27
  28. package/dist/events/on-command.js.map +1 -1
  29. package/dist/functions/bind.d.ts +2 -1
  30. package/dist/functions/bind.d.ts.map +1 -1
  31. package/dist/functions/bind.js +10 -15
  32. package/dist/functions/bind.js.map +1 -1
  33. package/dist/functions/debounce.d.ts +2 -1
  34. package/dist/functions/debounce.d.ts.map +1 -1
  35. package/dist/functions/debounce.js +20 -24
  36. package/dist/functions/debounce.js.map +1 -1
  37. package/dist/functions/log.d.ts +2 -1
  38. package/dist/functions/log.d.ts.map +1 -1
  39. package/dist/functions/log.js +5 -6
  40. package/dist/functions/log.js.map +1 -1
  41. package/dist/functions/memo.d.ts +2 -1
  42. package/dist/functions/memo.d.ts.map +1 -1
  43. package/dist/functions/memo.js +5 -6
  44. package/dist/functions/memo.js.map +1 -1
  45. package/dist/functions/once.d.ts +2 -1
  46. package/dist/functions/once.d.ts.map +1 -1
  47. package/dist/functions/once.js +3 -5
  48. package/dist/functions/once.js.map +1 -1
  49. package/dist/functions/retry.d.ts +2 -1
  50. package/dist/functions/retry.d.ts.map +1 -1
  51. package/dist/functions/retry.js +3 -5
  52. package/dist/functions/retry.js.map +1 -1
  53. package/dist/functions/throttle.d.ts +2 -1
  54. package/dist/functions/throttle.d.ts.map +1 -1
  55. package/dist/functions/throttle.js +18 -22
  56. package/dist/functions/throttle.js.map +1 -1
  57. package/dist/functions/watch.d.ts +7 -7
  58. package/dist/functions/watch.d.ts.map +1 -1
  59. package/dist/functions/watch.js +31 -35
  60. package/dist/functions/watch.js.map +1 -1
  61. package/dist/functions/when.d.ts +2 -1
  62. package/dist/functions/when.d.ts.map +1 -1
  63. package/dist/functions/when.js +24 -24
  64. package/dist/functions/when.js.map +1 -1
  65. package/dist/index.d.ts +2 -2
  66. package/dist/index.d.ts.map +1 -1
  67. package/dist/index.js +2 -2
  68. package/dist/index.js.map +1 -1
  69. package/dist/properties/computed.d.ts +3 -0
  70. package/dist/properties/computed.d.ts.map +1 -0
  71. package/dist/properties/computed.js +15 -0
  72. package/dist/properties/computed.js.map +1 -0
  73. package/dist/properties/history.d.ts +3 -2
  74. package/dist/properties/history.d.ts.map +1 -1
  75. package/dist/properties/history.js +35 -27
  76. package/dist/properties/history.js.map +1 -1
  77. package/dist/properties/index.d.ts +1 -0
  78. package/dist/properties/index.d.ts.map +1 -1
  79. package/dist/properties/index.js +1 -0
  80. package/dist/properties/index.js.map +1 -1
  81. package/dist/properties/persisted.d.ts +3 -2
  82. package/dist/properties/persisted.d.ts.map +1 -1
  83. package/dist/properties/persisted.js +20 -23
  84. package/dist/properties/persisted.js.map +1 -1
  85. package/dist/properties/prop.d.ts +2 -1
  86. package/dist/properties/prop.d.ts.map +1 -1
  87. package/dist/properties/prop.js +24 -13
  88. package/dist/properties/prop.js.map +1 -1
  89. package/dist/properties/slot.d.ts +4 -8
  90. package/dist/properties/slot.d.ts.map +1 -1
  91. package/dist/properties/slot.js +34 -24
  92. package/dist/properties/slot.js.map +1 -1
  93. package/dist/properties/state.d.ts +2 -1
  94. package/dist/properties/state.d.ts.map +1 -1
  95. package/dist/properties/state.js +19 -19
  96. package/dist/properties/state.js.map +1 -1
  97. package/package.json +3 -4
  98. package/src/component/component.ts +9 -2
  99. package/src/component/index.ts +0 -1
  100. package/src/component/lazy.ts +10 -8
  101. package/src/component/virtual.tsx +71 -28
  102. package/src/events/emit.ts +15 -22
  103. package/src/events/helper.ts +5 -2
  104. package/src/events/on-command.ts +43 -44
  105. package/src/functions/bind.ts +14 -18
  106. package/src/functions/debounce.ts +23 -26
  107. package/src/functions/log.ts +11 -11
  108. package/src/functions/memo.ts +8 -9
  109. package/src/functions/once.ts +7 -10
  110. package/src/functions/retry.ts +7 -12
  111. package/src/functions/throttle.ts +21 -24
  112. package/src/functions/watch.ts +44 -48
  113. package/src/functions/when.ts +30 -32
  114. package/src/index.ts +11 -2
  115. package/src/properties/computed.ts +20 -0
  116. package/src/properties/history.ts +49 -32
  117. package/src/properties/index.ts +1 -0
  118. package/src/properties/persisted.ts +40 -31
  119. package/src/properties/prop.ts +30 -13
  120. package/src/properties/slot.ts +46 -50
  121. package/src/properties/state.ts +24 -18
  122. package/dist/component/lifecycle.d.ts +0 -3
  123. package/dist/component/lifecycle.d.ts.map +0 -1
  124. package/dist/component/lifecycle.js +0 -35
  125. package/dist/component/lifecycle.js.map +0 -1
  126. package/dist/component/memoize.d.ts +0 -5
  127. package/dist/component/memoize.d.ts.map +0 -1
  128. package/dist/component/memoize.js +0 -23
  129. package/dist/component/memoize.js.map +0 -1
  130. package/src/component/lifecycle.ts +0 -47
  131. package/src/component/memoize.ts +0 -31
@@ -1,7 +1,9 @@
1
- import { type BaseComponent, effect } from "@praxisjs/core";
2
- import { type Computed, isComputed } from "@praxisjs/shared";
1
+ import type { StatefulComponent } from "@praxisjs/core";
2
+ import { effect } from "@praxisjs/core/internal";
3
+ import type { Computed } from "@praxisjs/shared";
4
+ import { isComputed } from "@praxisjs/shared/internal";
3
5
 
4
- type BaseComponentKeys = keyof BaseComponent;
6
+ type BaseComponentKeys = keyof StatefulComponent;
5
7
 
6
8
  type WatchableKeys<T> = {
7
9
  [K in Exclude<keyof T, BaseComponentKeys>]: T[K] extends (
@@ -29,15 +31,17 @@ type NoDuplicates<
29
31
  : Keys;
30
32
 
31
33
  type ValidateKeys<
32
- T extends BaseComponent,
34
+ T extends StatefulComponent,
33
35
  Keys extends ReadonlyArray<WatchableKeys<T>>,
34
36
  > = NoDuplicates<[...Keys]> extends Keys ? Keys : NoDuplicates<[...Keys]>;
35
37
 
36
38
  type Unwrap<T> =
37
39
  T extends Computed<infer U> ? U : T extends () => infer U ? U : T;
38
40
 
39
- export type WatchVal<T extends BaseComponent, K extends keyof T> = Unwrap<T[K]>;
40
- export type WatchVals<T extends BaseComponent, K extends keyof T> = {
41
+ export type WatchVal<T extends StatefulComponent, K extends keyof T> = Unwrap<
42
+ T[K]
43
+ >;
44
+ export type WatchVals<T extends StatefulComponent, K extends keyof T> = {
41
45
  [P in K]: Unwrap<T[P]>;
42
46
  };
43
47
 
@@ -46,54 +50,46 @@ function readValue(instance: Record<string, unknown>, key: string): unknown {
46
50
  return isComputed(raw) ? (raw as Computed<unknown>)() : raw;
47
51
  }
48
52
 
49
- function injectOnMount(
50
- target: object,
51
- fn: (this: Record<string, unknown>) => void,
52
- ): void {
53
- const t = target as { onMount?: () => void };
54
- const originalMethod = t.onMount;
55
- t.onMount = function (this: Record<string, unknown>) {
56
- originalMethod?.call(this);
57
- fn.call(this);
58
- };
59
- }
60
-
61
53
  export function Watch<
62
- T extends BaseComponent,
54
+ T extends StatefulComponent,
63
55
  const Keys extends ReadonlyArray<WatchableKeys<T>>,
64
56
  >(...propNames: ValidateKeys<T, Keys>) {
65
57
  return function (
66
- target: T,
67
- _key: string,
68
- descriptor: PropertyDescriptor,
69
- ): PropertyDescriptor {
58
+ value: (this: T, ...args: unknown[]) => void,
59
+ context: ClassMethodDecoratorContext<T>,
60
+ ): void {
70
61
  const props = propNames as unknown as string[];
71
- const method = descriptor.value as (this: Record<string, unknown>, ...args: unknown[]) => void;
72
62
 
73
- injectOnMount(target, function (this) {
74
- if (props.length === 1) {
75
- let oldVal = readValue(this, props[0]);
76
- effect(() => {
77
- const newVal = readValue(this, props[0]);
78
- if (!Object.is(newVal, oldVal)) {
79
- method.call(this, newVal, oldVal);
80
- oldVal = newVal;
81
- }
82
- });
83
- } else {
84
- const read = () =>
85
- Object.fromEntries(props.map((p) => [p, readValue(this, p)]));
86
- let oldVals = read();
87
- effect(() => {
88
- const newVals = read();
89
- if (props.some((p) => !Object.is(newVals[p], oldVals[p]))) {
90
- method.call(this, newVals, oldVals);
91
- oldVals = newVals;
92
- }
93
- });
94
- }
95
- });
63
+ context.addInitializer(function (this: unknown) {
64
+ const instance = this as T & Record<string, unknown>;
65
+ // eslint-disable-next-line @typescript-eslint/unbound-method
66
+ const originalOnMount = instance.onMount;
67
+
68
+ instance.onMount = function (this: T & Record<string, unknown>) {
69
+ originalOnMount?.call(this);
96
70
 
97
- return descriptor;
71
+ if (props.length === 1) {
72
+ let oldVal = readValue(this, props[0]);
73
+ effect(() => {
74
+ const newVal = readValue(this, props[0]);
75
+ if (!Object.is(newVal, oldVal)) {
76
+ value.call(this as T, newVal, oldVal);
77
+ oldVal = newVal;
78
+ }
79
+ });
80
+ } else {
81
+ const read = () =>
82
+ Object.fromEntries(props.map((p) => [p, readValue(this, p)]));
83
+ let oldVals = read();
84
+ effect(() => {
85
+ const newVals = read();
86
+ if (props.some((p) => !Object.is(newVals[p], oldVals[p]))) {
87
+ value.call(this as T, newVals, oldVals);
88
+ oldVals = newVals;
89
+ }
90
+ });
91
+ }
92
+ };
93
+ });
98
94
  };
99
95
  }
@@ -1,44 +1,42 @@
1
- import { type BaseComponent, when } from "@praxisjs/core";
2
- import { isComputed } from "@praxisjs/shared";
1
+ import type { StatefulComponent } from "@praxisjs/core";
2
+ import { when } from "@praxisjs/core/internal";
3
+ import type { Computed, Signal } from "@praxisjs/shared";
4
+ import { isComputed } from "@praxisjs/shared/internal";
3
5
 
4
6
  export function When(propName: string) {
5
7
  return function (
6
- target: object,
7
- _methodKey: string,
8
- descriptor: PropertyDescriptor,
9
- ): PropertyDescriptor {
10
- // eslint-disable-next-line @typescript-eslint/unbound-method
11
- const originalOnMount = (target as { onMount?(): void }).onMount;
12
- // eslint-disable-next-line @typescript-eslint/unbound-method
13
- const originalOnUnmount = (target as { onUnmount?(): void }).onUnmount;
14
-
15
- const method = descriptor.value as (value: unknown) => void;
8
+ value: (this: StatefulComponent, val: unknown) => void,
9
+ context: ClassMethodDecoratorContext<StatefulComponent>,
10
+ ): void {
16
11
  const cancels = new WeakMap<object, () => void>();
17
12
 
18
- (target as { onMount?(): void }).onMount = function (this: BaseComponent) {
19
- originalOnMount?.call(this);
13
+ context.addInitializer(function (this: unknown) {
14
+ const instance = this as StatefulComponent;
15
+ // eslint-disable-next-line @typescript-eslint/unbound-method
16
+ const originalOnMount = instance.onMount;
17
+ // eslint-disable-next-line @typescript-eslint/unbound-method
18
+ const originalOnUnmount = instance.onUnmount;
20
19
 
21
- const instance = this as unknown as Record<string, unknown>;
22
- const source = () => {
23
- const raw = instance[propName];
24
- return isComputed(raw) ? (raw as unknown as () => unknown)() : raw;
25
- };
20
+ instance.onMount = function (this: StatefulComponent) {
21
+ originalOnMount?.call(this);
26
22
 
27
- const cancel = when(source, (value) => {
28
- method.call(this, value);
29
- });
23
+ const raw = (this as unknown as Record<string, unknown>)[propName];
24
+ const source = isComputed(raw)
25
+ ? (raw as Computed<unknown>)
26
+ : (raw as Signal<unknown>);
30
27
 
31
- cancels.set(this, cancel);
32
- };
28
+ const cancel = when(source, (val) => {
29
+ value.call(this, val);
30
+ });
33
31
 
34
- (target as { onUnmount?(): void }).onUnmount = function (
35
- this: BaseComponent,
36
- ) {
37
- originalOnUnmount?.call(this);
38
- cancels.get(this)?.();
39
- cancels.delete(this);
40
- };
32
+ cancels.set(this, cancel);
33
+ };
41
34
 
42
- return descriptor;
35
+ instance.onUnmount = function (this: StatefulComponent) {
36
+ originalOnUnmount?.call(this);
37
+ cancels.get(this)?.();
38
+ cancels.delete(this);
39
+ };
40
+ });
43
41
  };
44
42
  }
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { Component, Memoize, Lazy, Virtual } from "./component";
1
+ export { Component, Lazy, Virtual } from "./component";
2
2
  export {
3
3
  Memo,
4
4
  Bind,
@@ -12,5 +12,14 @@ export {
12
12
  type WatchVal,
13
13
  type WatchVals,
14
14
  } from "./functions";
15
- export { Prop, State, Persisted, Slot, initSlots, History, type WithHistory } from "./properties";
15
+ export {
16
+ Prop,
17
+ State,
18
+ Computed,
19
+ Persisted,
20
+ Slot,
21
+ initSlots,
22
+ History,
23
+ type WithHistory,
24
+ } from "./properties";
16
25
  export { type Command, createCommand, Emit, OnCommand } from "./events";
@@ -0,0 +1,20 @@
1
+ import type { StatefulComponent } from "@praxisjs/core";
2
+ import { computed } from "@praxisjs/core/internal";
3
+
4
+ export function Computed() {
5
+ return function <This extends StatefulComponent, T>(
6
+ target: (this: This) => T,
7
+ _context: ClassGetterDecoratorContext<This, T>,
8
+ ): (this: This) => T {
9
+ const computedMap = new WeakMap<object, () => T>();
10
+
11
+ return function (this: This): T {
12
+ let c = computedMap.get(this);
13
+ if (!c) {
14
+ c = computed(() => target.call(this));
15
+ computedMap.set(this, c);
16
+ }
17
+ return c();
18
+ };
19
+ };
20
+ }
@@ -1,40 +1,57 @@
1
- import { type HistoryElement, history } from "@praxisjs/core";
1
+ import type { StatefulComponent } from "@praxisjs/core";
2
+ import { type HistoryElement, history } from "@praxisjs/core/internal";
3
+ import type { Signal } from "@praxisjs/shared";
2
4
 
3
- export type WithHistory<T, K extends keyof T> = Record<`${string & K}History`, HistoryElement<T[K]>>;
5
+ export type WithHistory<T, K extends keyof T> = Record<
6
+ `${string & K}History`,
7
+ HistoryElement<T[K]>
8
+ >;
4
9
 
5
10
  export function History(limit = 50) {
6
- return function (target: object, propertyKey: string): void {
7
- const historyKey = `${propertyKey}History`;
11
+ return function (
12
+ _value: undefined,
13
+ context: ClassFieldDecoratorContext<StatefulComponent>,
14
+ ): void {
8
15
  const histories = new WeakMap<object, HistoryElement<unknown>>();
9
16
 
10
- Object.defineProperty(target, historyKey, {
11
- get(this: Record<string, unknown>): HistoryElement<unknown> {
12
- if (!histories.has(this)) {
13
- const source = () => this[propertyKey];
14
-
15
- const h = history(source as () => unknown, limit);
16
-
17
- const originalUndo = () => { h.undo(); };
18
- const originalRedo = () => { h.redo(); };
19
-
20
- h.undo = () => {
21
- const prev = h.values()[h.values().length - 2];
22
- if (prev === undefined) return;
23
- originalUndo();
24
- this[propertyKey] = prev;
25
- };
26
-
27
- h.redo = () => {
28
- originalRedo();
29
- this[propertyKey] = h.current();
30
- };
31
-
32
- histories.set(this, h);
33
- }
34
- return histories.get(this) as HistoryElement<unknown>;
35
- },
36
- enumerable: false,
37
- configurable: true,
17
+ context.addInitializer(function (this: unknown) {
18
+ const instance = this as Record<string, unknown>;
19
+ const propertyKey = context.name as string;
20
+ const historyKey = `${propertyKey}History`;
21
+
22
+ Object.defineProperty(instance, historyKey, {
23
+ get(this: Record<string, unknown>): HistoryElement<unknown> {
24
+ if (!histories.has(this)) {
25
+ const source = () => this[propertyKey];
26
+
27
+ const h = history(source as Signal<unknown>, limit);
28
+
29
+ const originalUndo = () => {
30
+ h.undo();
31
+ };
32
+ const originalRedo = () => {
33
+ h.redo();
34
+ };
35
+
36
+ h.undo = () => {
37
+ const prev = h.values()[h.values().length - 2];
38
+ if (prev === undefined) return;
39
+ originalUndo();
40
+ this[propertyKey] = prev;
41
+ };
42
+
43
+ h.redo = () => {
44
+ originalRedo();
45
+ this[propertyKey] = h.current();
46
+ };
47
+
48
+ histories.set(this, h);
49
+ }
50
+ return histories.get(this) as HistoryElement<unknown>;
51
+ },
52
+ enumerable: false,
53
+ configurable: true,
54
+ });
38
55
  });
39
56
  };
40
57
  }
@@ -1,5 +1,6 @@
1
1
  export { Prop } from "./prop";
2
2
  export { State } from "./state";
3
+ export { Computed } from "./computed";
3
4
  export { Persisted } from "./persisted";
4
5
  export { Slot, initSlots } from "./slot";
5
6
  export { History, type WithHistory } from "./history";
@@ -1,13 +1,13 @@
1
- import { persistedSignal, type PersistedSignalOptions } from "@praxisjs/core";
1
+ import type { StatefulComponent } from "@praxisjs/core";
2
+ import {
3
+ persistedSignal,
4
+ type PersistedSignalOptions,
5
+ } from "@praxisjs/core/internal";
2
6
  import type { Signal } from "@praxisjs/shared";
3
7
 
4
8
  const signalMap = new WeakMap<object, Map<string, Signal<unknown>>>();
5
9
  const initMap = new WeakMap<object, Set<string>>();
6
10
 
7
- function isInitialized(instance: object, propKey: string): boolean {
8
- return initMap.get(instance)?.has(propKey) ?? false;
9
- }
10
-
11
11
  function markInitialized(instance: object, propKey: string): void {
12
12
  if (!initMap.has(instance)) {
13
13
  initMap.set(instance, new Set());
@@ -40,36 +40,45 @@ export function Persisted<T>(
40
40
  key?: string,
41
41
  options: PersistedSignalOptions<T> = {},
42
42
  ) {
43
- return function (target: object, propertyKey: string): void {
44
- const storageKey = key ?? propertyKey;
43
+ return function (
44
+ _value: undefined,
45
+ context: ClassFieldDecoratorContext<StatefulComponent>,
46
+ ): void {
47
+ context.addInitializer(function (this: unknown) {
48
+ const instance = this as object;
49
+ const propertyKey = context.name as string;
50
+ const storageKey = key ?? propertyKey;
51
+ const initialValue = (instance as Record<string, unknown>)[
52
+ propertyKey
53
+ ] as T;
54
+
55
+ Reflect.deleteProperty(instance, propertyKey);
45
56
 
46
- Object.defineProperty(target, propertyKey, {
47
- get(this: object): T {
48
- if (!isInitialized(this, propertyKey)) {
49
- return undefined as T;
50
- }
57
+ markInitialized(instance, propertyKey);
58
+ getOrCreateSignal(instance, storageKey, initialValue, options);
51
59
 
52
- return getOrCreateSignal<T>(
53
- this,
54
- storageKey,
55
- undefined as T,
56
- options,
57
- )();
58
- },
60
+ Object.defineProperty(instance, propertyKey, {
61
+ get(): T {
62
+ return getOrCreateSignal<T>(
63
+ instance,
64
+ storageKey,
65
+ undefined as T,
66
+ options,
67
+ )();
68
+ },
59
69
 
60
- set(this: object, value: T): void {
61
- if (!isInitialized(this, propertyKey)) {
62
- markInitialized(this, propertyKey);
63
- getOrCreateSignal(this, storageKey, value, options);
64
- return;
65
- }
66
- getOrCreateSignal<T>(this, storageKey, undefined as T, options).set(
67
- value,
68
- );
69
- },
70
+ set(value: T): void {
71
+ getOrCreateSignal<T>(
72
+ instance,
73
+ storageKey,
74
+ undefined as T,
75
+ options,
76
+ ).set(value);
77
+ },
70
78
 
71
- enumerable: true,
72
- configurable: true,
79
+ enumerable: true,
80
+ configurable: true,
81
+ });
73
82
  });
74
83
  };
75
84
  }
@@ -1,18 +1,35 @@
1
- import type { BaseComponent } from "@praxisjs/core";
1
+ import type { StatefulComponent } from "@praxisjs/core";
2
2
 
3
3
  export function Prop() {
4
- return function (target: object, propertyKey: string) {
5
- Object.defineProperty(target, propertyKey, {
6
- get(this: BaseComponent) {
7
- const fromParent = this._rawProps[propertyKey];
8
- if (fromParent !== undefined) return fromParent;
9
- return this._defaults[propertyKey];
10
- },
11
- set(this: BaseComponent, value: unknown) {
12
- this._defaults[propertyKey] = value;
13
- },
14
- enumerable: true,
15
- configurable: true,
4
+ return function (
5
+ _value: undefined,
6
+ context: ClassFieldDecoratorContext<StatefulComponent>,
7
+ ): void {
8
+ context.addInitializer(function (this: unknown) {
9
+ const instance = this as StatefulComponent;
10
+ const name = context.name as string;
11
+ const raw = instance as unknown as Record<string, unknown>;
12
+ const defaultValue = raw[name];
13
+ Reflect.deleteProperty(raw, name);
14
+
15
+ instance._defaults[name] = defaultValue;
16
+
17
+ Object.defineProperty(instance, name, {
18
+ get(this: StatefulComponent) {
19
+ const fromParent = this._rawProps[name];
20
+ if (fromParent !== undefined) {
21
+ return typeof fromParent === "function"
22
+ ? (fromParent as () => unknown)()
23
+ : fromParent;
24
+ }
25
+ return this._defaults[name];
26
+ },
27
+ set(this: StatefulComponent, value: unknown) {
28
+ this._defaults[name] = value;
29
+ },
30
+ enumerable: true,
31
+ configurable: true,
32
+ });
16
33
  });
17
34
  };
18
35
  }
@@ -1,75 +1,71 @@
1
- import type { BaseComponent } from "@praxisjs/core";
2
- import {
3
- type Children,
4
- type ChildrenInternal,
5
- flattenChildren,
6
- type VNode,
7
- } from "@praxisjs/shared";
1
+ import type { StatefulComponent } from "@praxisjs/core";
8
2
 
9
- const slotsMap = new WeakMap<object, Map<string, ChildrenInternal[]>>();
3
+ const slotsMap = new WeakMap<object, Map<string, unknown[]>>();
10
4
 
11
- export interface SlottedVNode extends VNode {
12
- slot?: string;
13
- }
14
-
15
- export function resolveSlots(
16
- children: ChildrenInternal | ChildrenInternal[] | undefined,
17
- ): Map<string, ChildrenInternal[]> {
18
- const slots = new Map<string, ChildrenInternal[]>();
19
- const defaultSlot: ChildrenInternal[] = [];
5
+ function resolveSlots(children: unknown): Map<string, unknown[]> {
6
+ const slots = new Map<string, unknown[]>();
7
+ const defaultSlot: unknown[] = [];
20
8
  slots.set("default", defaultSlot);
21
9
 
22
- if (!children) return slots;
10
+ if (children == null) return slots;
23
11
 
24
- const arr: ChildrenInternal[] = flattenChildren(children);
12
+ const arr = Array.isArray(children)
13
+ ? (children as unknown[]).flat(Infinity)
14
+ : [children];
25
15
 
26
- for (const child of arr as SlottedVNode[]) {
27
- const slotName = (child.props.slot as string | undefined) ?? child.slot;
28
-
29
- if (slotName) {
30
- if (!slots.has(slotName)) slots.set(slotName, []);
31
- (slots.get(slotName) as ChildrenInternal[]).push(
32
- child as ChildrenInternal,
33
- );
34
- } else {
35
- defaultSlot.push(child as ChildrenInternal);
16
+ for (const child of arr) {
17
+ // Named slots via `slot` attribute on DOM elements
18
+ if (child instanceof Element) {
19
+ const slotName = child.getAttribute("slot");
20
+ if (slotName) {
21
+ child.removeAttribute("slot");
22
+ if (!slots.has(slotName)) slots.set(slotName, []);
23
+ (slots.get(slotName) as unknown[]).push(child);
24
+ continue;
25
+ }
36
26
  }
27
+ if (child != null) defaultSlot.push(child);
37
28
  }
38
29
 
39
30
  return slots;
40
31
  }
41
32
 
42
- export function initSlots(
43
- instance: object,
44
- children: Children | undefined,
45
- ): void {
33
+ export function initSlots(instance: object, children: unknown): void {
46
34
  slotsMap.set(instance, resolveSlots(children));
47
35
  }
48
36
 
49
- export function getSlot(instance: object, name: string): ChildrenInternal[] {
37
+ export function getSlot(instance: object, name: string): unknown[] {
50
38
  return slotsMap.get(instance)?.get(name) ?? [];
51
39
  }
52
40
 
53
41
  export function Slot(name?: string) {
54
- return function (target: object, propertyKey: string): void {
55
- const slotName =
56
- name ?? (propertyKey === "default" ? "default" : propertyKey);
42
+ return function (
43
+ _value: undefined,
44
+ context: ClassFieldDecoratorContext<StatefulComponent>,
45
+ ): void {
46
+ context.addInitializer(function (this: unknown) {
47
+ const instance = this as StatefulComponent;
48
+ const propKey = context.name as string;
49
+ const slotName = name ?? (propKey === "default" ? "default" : propKey);
50
+
51
+ Reflect.deleteProperty(instance, propKey);
57
52
 
58
- Object.defineProperty(target, propertyKey, {
59
- get(this: BaseComponent): ChildrenInternal[] {
60
- return getSlot(this, slotName);
61
- },
53
+ Object.defineProperty(instance, propKey, {
54
+ get(this: StatefulComponent): unknown[] {
55
+ return getSlot(this, slotName);
56
+ },
62
57
 
63
- set(_value: unknown): void {
64
- if (process.env.NODE_ENV !== "production") {
65
- console.warn(
66
- `[Slot] "${propertyKey}" is a slot and cannot be assigned directly. Slots are filled by the parent component.`,
67
- );
68
- }
69
- },
58
+ set(_value: unknown): void {
59
+ if (process.env.NODE_ENV !== "production") {
60
+ console.warn(
61
+ `[Slot] "${propKey}" is a slot and cannot be assigned directly. Slots are filled by the parent component.`,
62
+ );
63
+ }
64
+ },
70
65
 
71
- enumerable: true,
72
- configurable: true,
66
+ enumerable: true,
67
+ configurable: true,
68
+ });
73
69
  });
74
70
  };
75
71
  }
@@ -1,24 +1,30 @@
1
- import { signal } from "@praxisjs/core";
2
- import type { ComponentInstance, Signal } from "@praxisjs/shared";
1
+ import type { StatefulComponent } from "@praxisjs/core";
2
+ import { signal } from "@praxisjs/core/internal";
3
3
 
4
4
  export function State() {
5
- return function (target: object, propertyKey: string) {
6
- const signalMap = new WeakMap<object, Signal<unknown>>();
5
+ return function (
6
+ _value: undefined,
7
+ context: ClassFieldDecoratorContext<StatefulComponent>,
8
+ ): void {
9
+ context.addInitializer(function (this: unknown) {
10
+ const instance = this as StatefulComponent & Record<string, unknown>;
11
+ const name = context.name as string;
12
+ const initialValue = instance[name];
13
+ Reflect.deleteProperty(instance, name);
7
14
 
8
- Object.defineProperty(target, propertyKey, {
9
- get(this: object) {
10
- if (!signalMap.has(this)) signalMap.set(this, signal(undefined));
11
- return (signalMap.get(this) as Signal<unknown>)();
12
- },
13
- set(this: object, value: unknown) {
14
- if (!signalMap.has(this)) signalMap.set(this, signal(value));
15
- else {
16
- (this as ComponentInstance)._stateDirty = true;
17
- (signalMap.get(this) as Signal<unknown>).set(value);
18
- }
19
- },
20
- enumerable: true,
21
- configurable: true,
15
+ const sig = signal(initialValue);
16
+
17
+ Object.defineProperty(instance, name, {
18
+ get() {
19
+ return sig();
20
+ },
21
+ set(value: unknown) {
22
+ instance._stateDirty = true;
23
+ sig.set(value);
24
+ },
25
+ enumerable: true,
26
+ configurable: true,
27
+ });
22
28
  });
23
29
  };
24
30
  }
@@ -1,3 +0,0 @@
1
- import { type BaseComponent } from "@praxisjs/core";
2
- export declare function LifeCycle<T extends new (...args: any[]) => BaseComponent>(constructor: T): T;
3
- //# sourceMappingURL=lifecycle.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../src/component/lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAmC,MAAM,gBAAgB,CAAC;AAuBrF,wBAAgB,SAAS,CAAC,CAAC,SAAS,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,aAAa,EACvE,WAAW,EAAE,CAAC,GACb,CAAC,CAqBH"}