@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/CHANGELOG.md +16 -0
- package/dist/index.d.ts +11 -4
- package/dist/index.js +427 -408
- package/package.json +5 -5
- package/src/decorators/debug.ts +56 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@praxisjs/devtools",
|
|
3
|
-
"version": "0.2.
|
|
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.
|
|
16
|
-
"@praxisjs/decorators": "0.
|
|
17
|
-
"@praxisjs/jsx": "0.2.
|
|
18
|
-
"@praxisjs/runtime": "0.2.
|
|
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": {
|
package/src/decorators/debug.ts
CHANGED
|
@@ -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
|
|
35
|
-
* @Debug()
|
|
36
|
-
*
|
|
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
|
-
|
|
54
|
+
export function Debug(options: DebugOptions = {}): DebugDecorator {
|
|
55
|
+
const impl = function (
|
|
44
56
|
value: unknown,
|
|
45
|
-
context:
|
|
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
|
}
|