@praxisjs/devtools 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@praxisjs/devtools",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -12,10 +12,10 @@
12
12
  },
13
13
  "dependencies": {
14
14
  "@unocss/reset": "^66.6.2",
15
- "@praxisjs/core": "0.3.0",
16
- "@praxisjs/decorators": "0.3.0",
17
- "@praxisjs/jsx": "0.2.0",
18
- "@praxisjs/runtime": "0.2.0",
15
+ "@praxisjs/core": "0.4.0",
16
+ "@praxisjs/decorators": "0.4.0",
17
+ "@praxisjs/jsx": "0.2.1",
18
+ "@praxisjs/runtime": "0.2.1",
19
19
  "@praxisjs/shared": "0.2.0"
20
20
  },
21
21
  "devDependencies": {
@@ -1,3 +1,5 @@
1
+ import { computed } from "@praxisjs/core/internal";
2
+
1
3
  import { Registry } from "../core/registry";
2
4
 
3
5
  export interface DebugOptions {
@@ -24,6 +26,15 @@ interface ComputedSlot {
24
26
  unsub: () => void;
25
27
  }
26
28
 
29
+ interface DebugDecorator {
30
+ (
31
+ value: (...args: unknown[]) => unknown,
32
+ context: ClassMethodDecoratorContext,
33
+ ): (...args: unknown[]) => unknown;
34
+ (value: unknown, context: ClassGetterDecoratorContext): void;
35
+ (value: undefined, context: ClassFieldDecoratorContext): void;
36
+ }
37
+
27
38
  /**
28
39
  * Tracks state, computed values, and methods in the devtools panel.
29
40
  *
@@ -31,18 +42,22 @@ interface ComputedSlot {
31
42
  * @Debug()
32
43
  * @State() count = 0;
33
44
  *
34
- * On computed class fields:
35
- * @Debug()
36
- * doubled = computed(() => this.count * 2);
45
+ * On @Computed() getters (stacked):
46
+ * @Debug({ label: "doubled" })
47
+ * @Computed()
48
+ * get doubled() { return this.count * 2; }
37
49
  *
38
50
  * On methods:
39
51
  * @Debug()
40
52
  * increment() { ... }
41
53
  */
42
- export function Debug(options: DebugOptions = {}) {
43
- return function (
54
+ export function Debug(options: DebugOptions = {}): DebugDecorator {
55
+ const impl = function (
44
56
  value: unknown,
45
- context: ClassMethodDecoratorContext | ClassFieldDecoratorContext,
57
+ context:
58
+ | ClassMethodDecoratorContext
59
+ | ClassGetterDecoratorContext
60
+ | ClassFieldDecoratorContext,
46
61
  ) {
47
62
  const label = options.label ?? (context.name as string);
48
63
 
@@ -78,6 +93,39 @@ export function Debug(options: DebugOptions = {}) {
78
93
  };
79
94
  }
80
95
 
96
+ // ── Getter decorator (@Computed() getters) ────────────────────────────
97
+ if (context.kind === "getter") {
98
+ const originalGetter = value as (this: object) => unknown;
99
+
100
+ context.addInitializer(function (this: unknown) {
101
+ const instance = this as object & Record<string, unknown>;
102
+ const componentName = (instance.constructor as { name: string }).name;
103
+
104
+ // Defer until the current synchronous class initialization (including
105
+ // field initializers like `count = 0`) has fully completed. Without
106
+ // this, accessing `this.doubled` here could read state signals before
107
+ // their field initializers have run, producing NaN or undefined.
108
+ queueMicrotask(() => {
109
+ const c = computed(() => originalGetter.call(instance));
110
+ let skipFirst = true;
111
+ let prevValue = c();
112
+
113
+ Registry.instance.registerSignal(instance, label, prevValue, componentName);
114
+
115
+ c.subscribe((newValue) => {
116
+ if (skipFirst) {
117
+ skipFirst = false;
118
+ return;
119
+ }
120
+ Registry.instance.updateSignal(instance, label, newValue, prevValue);
121
+ prevValue = newValue;
122
+ });
123
+ });
124
+ });
125
+
126
+ return;
127
+ }
128
+
81
129
  // ── Field decorator ───────────────────────────────────────────────────
82
130
  context.addInitializer(function (
83
131
  this: unknown,
@@ -183,4 +231,6 @@ export function Debug(options: DebugOptions = {}) {
183
231
  });
184
232
  });
185
233
  };
234
+
235
+ return impl as DebugDecorator;
186
236
  }