@praxisjs/devtools 0.2.34 → 0.3.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 (65) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/assets/uno.generated.css +5 -0
  3. package/dist/assets/logo.svg.js +4 -0
  4. package/dist/assets/tailwind-v4.css.js +4 -0
  5. package/dist/assets/uno.generated.css.js +4 -0
  6. package/dist/core/event-bus.js +21 -0
  7. package/dist/core/profiler.js +79 -0
  8. package/dist/core/registry.js +147 -0
  9. package/dist/decorators/debug.js +126 -0
  10. package/dist/decorators/trace.js +45 -0
  11. package/dist/icons/ellipsis-vertical.js +38 -0
  12. package/dist/icons/panel-bottom.js +28 -0
  13. package/dist/icons/panel-left.js +28 -0
  14. package/dist/icons/panel-right.js +28 -0
  15. package/dist/icons/panel-top.js +28 -0
  16. package/dist/icons/x.js +22 -0
  17. package/dist/index.d.ts +96 -3
  18. package/dist/index.js +10 -1157
  19. package/dist/plugins/components/components/component-detail.js +53 -0
  20. package/dist/plugins/components/components/component-row.js +22 -0
  21. package/dist/plugins/components/components/detail-row.js +15 -0
  22. package/dist/plugins/components/components/detail-section.js +14 -0
  23. package/dist/plugins/components/components/status-dot.js +15 -0
  24. package/dist/plugins/components/components-tab.js +54 -0
  25. package/dist/plugins/components/index.js +9 -0
  26. package/dist/plugins/performance/index.js +9 -0
  27. package/dist/plugins/performance/performance-tab.js +62 -0
  28. package/dist/plugins/signals/components/signal-detail.js +29 -0
  29. package/dist/plugins/signals/components/signal-row.js +17 -0
  30. package/dist/plugins/signals/index.js +9 -0
  31. package/dist/plugins/signals/signals-tab.js +53 -0
  32. package/dist/plugins/timeline/components/badge.js +16 -0
  33. package/dist/plugins/timeline/components/timeline-row.js +33 -0
  34. package/dist/plugins/timeline/constants.js +54 -0
  35. package/dist/plugins/timeline/index.js +9 -0
  36. package/dist/plugins/timeline/timeline-tab.js +46 -0
  37. package/dist/ui/dev-tools.js +74 -0
  38. package/dist/ui/panel.js +106 -0
  39. package/dist/ui/shared/empty-state.js +14 -0
  40. package/dist/ui/shared/icon-button.js +17 -0
  41. package/dist/ui/shared/panel-section.js +14 -0
  42. package/dist/ui/shared/search-input.js +17 -0
  43. package/dist/ui/shared/side-panel.js +15 -0
  44. package/dist/utils/format-time.js +7 -0
  45. package/dist/utils/format-value.js +14 -0
  46. package/package.json +14 -6
  47. package/src/core/profiler.ts +162 -0
  48. package/src/core/registry.ts +23 -21
  49. package/src/decorators/debug.ts +96 -32
  50. package/src/decorators/index.ts +1 -0
  51. package/src/decorators/trace.ts +27 -4
  52. package/src/index.ts +5 -0
  53. package/src/plugins/performance/index.ts +9 -0
  54. package/src/plugins/performance/performance-tab.tsx +111 -0
  55. package/src/ui/dev-tools.tsx +5 -0
  56. package/src/__tests__/debug.test.ts +0 -333
  57. package/src/__tests__/event-bus.test.ts +0 -123
  58. package/src/__tests__/format-time.test.ts +0 -52
  59. package/src/__tests__/format-value.test.ts +0 -46
  60. package/src/__tests__/plugins.test.ts +0 -101
  61. package/src/__tests__/registry.test.ts +0 -386
  62. package/src/__tests__/trace.test.ts +0 -200
  63. package/tsconfig.json +0 -21
  64. package/uno.config.ts +0 -57
  65. package/vite.config.ts +0 -38
@@ -0,0 +1,28 @@
1
+ import { _$element as e, _$template as t } from "@praxisjs/runtime";
2
+ import { StatelessComponent as n } from "@praxisjs/core";
3
+ import { Component as r } from "@praxisjs/decorators";
4
+ //#region src/icons/panel-top.tsx
5
+ var i = /* @__PURE__ */ t(() => e("svg", {
6
+ xmlns: "http://www.w3.org/2000/svg",
7
+ width: "24",
8
+ height: "24",
9
+ viewBox: "0 0 24 24",
10
+ fill: "none",
11
+ stroke: "currentColor",
12
+ "stroke-width": "2",
13
+ "stroke-linecap": "round",
14
+ "stroke-linejoin": "round",
15
+ class: "lucide lucide-panel-top-icon lucide-panel-top"
16
+ }, [e("rect", {
17
+ width: "18",
18
+ height: "18",
19
+ x: "3",
20
+ y: "3",
21
+ rx: "2"
22
+ }, null), e("path", { d: "M3 9h18" }, null)])), a = @r() class extends n {
23
+ render() {
24
+ return i();
25
+ }
26
+ };
27
+ //#endregion
28
+ export { a as PanelTopIcon };
@@ -0,0 +1,22 @@
1
+ import { _$element as e, _$template as t } from "@praxisjs/runtime";
2
+ import { StatelessComponent as n } from "@praxisjs/core";
3
+ import { Component as r } from "@praxisjs/decorators";
4
+ //#region src/icons/x.tsx
5
+ var i = /* @__PURE__ */ t(() => e("svg", {
6
+ xmlns: "http://www.w3.org/2000/svg",
7
+ width: "24",
8
+ height: "24",
9
+ viewBox: "0 0 24 24",
10
+ fill: "none",
11
+ stroke: "currentColor",
12
+ "stroke-width": "2",
13
+ "stroke-linecap": "round",
14
+ "stroke-linejoin": "round",
15
+ class: "lucide lucide-x-icon lucide-x"
16
+ }, [e("path", { d: "M18 6 6 18" }, null), e("path", { d: "m6 6 12 12" }, null)])), a = @r() class extends n {
17
+ render() {
18
+ return i();
19
+ }
20
+ };
21
+ //#endregion
22
+ export { a as XIcon };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,8 @@
1
1
  import { ComponentElement } from '@praxisjs/shared';
2
+ import { ComputedNode } from '@praxisjs/core/internal';
3
+ import { EffectNode } from '@praxisjs/core/internal';
4
+ import { ReactiveNode } from '@praxisjs/core/internal';
5
+ import { ReactiveObserver } from '@praxisjs/core/internal';
2
6
  import { RootComponent } from '@praxisjs/core/internal';
3
7
 
4
8
  export declare interface ComponentEntry {
@@ -14,8 +18,14 @@ export declare interface ComponentEntry {
14
18
  export declare const ComponentsPlugin: DevtoolsPlugin;
15
19
 
16
20
  /**
17
- * Tracks state, computed values, and methods in the devtools panel.
18
- * Supports @State() fields, @Computed() getters, and methods.
21
+ * Tracks state, props, computed values and methods in the devtools panel.
22
+ *
23
+ * - Fields with an accessor (`@State`, `@Prop`, `@Persisted`, …) are observed reactively, so a
24
+ * change is reported whatever caused it, including a parent passing a new prop.
25
+ * - Fields holding a `computed()` report each new value.
26
+ * - `@Computed()` getters report each new value.
27
+ * - Methods report every call with its arguments, result and duration; for a method that returns a
28
+ * promise, when the promise settles.
19
29
  */
20
30
  export declare function Debug(options?: DebugOptions): DebugDecorator;
21
31
 
@@ -26,7 +36,18 @@ declare interface DebugDecorator {
26
36
  }
27
37
 
28
38
  export declare interface DebugOptions {
39
+ /** Name shown in the panel. Defaults to the member name. */
29
40
  label?: string;
41
+ /**
42
+ * Also logs every change (fields, getters) or call (methods) to the console. `"trace"` logs with
43
+ * a stack trace, which shows what caused it.
44
+ */
45
+ log?: boolean | "trace";
46
+ /**
47
+ * Pauses in the debugger on a change or call. A function decides per change: it receives the new
48
+ * and the previous value (for methods, the arguments and `undefined`).
49
+ */
50
+ break?: boolean | ((next: unknown, prev: unknown) => boolean);
30
51
  }
31
52
 
32
53
  export declare const DevTools: {
@@ -68,12 +89,71 @@ export declare interface LifecycleEvent {
68
89
  timestamp: number;
69
90
  }
70
91
 
92
+ export declare interface OwnerStats {
93
+ /** Constructor name of the component the effects belong to, or "(no component)". */
94
+ name: string;
95
+ effectRuns: number;
96
+ effectMs: number;
97
+ /** Slowest single effect run, in ms. */
98
+ maxMs: number;
99
+ }
100
+
101
+ export declare const PerformancePlugin: DevtoolsPlugin;
102
+
103
+ /**
104
+ * Records what the reactive graph does while recording: signal writes, computed recomputations
105
+ * and effect runs, with their cost, grouped by the component that created each effect. It installs
106
+ * itself as the graph's observer only while recording, so it costs nothing otherwise.
107
+ */
108
+ export declare class Profiler implements ReactiveObserver {
109
+ readonly bus: EventBus;
110
+ private recording;
111
+ private startedAt;
112
+ private stoppedAt;
113
+ private writes;
114
+ private effectRuns;
115
+ private effectMs;
116
+ private computeRuns;
117
+ private computeMs;
118
+ private readonly byOwner;
119
+ private previous;
120
+ private notifyScheduled;
121
+ private mutedDepth;
122
+ get isRecording(): boolean;
123
+ /** Runs `fn` without recording what it causes: the devtools panel updating itself. */
124
+ muted<T>(fn: () => T): T;
125
+ start(): void;
126
+ stop(): void;
127
+ reset(): void;
128
+ write(_node: ReactiveNode): void;
129
+ compute(_node: ComputedNode, ms: number): void;
130
+ effect(_node: EffectNode, ms: number, owner: object | undefined): void;
131
+ /** Totals plus per-component stats merged by component name, busiest first. */
132
+ snapshot(): ProfileSnapshot;
133
+ private changed;
134
+ }
135
+
136
+ export declare interface ProfileSnapshot {
137
+ recording: boolean;
138
+ /** Milliseconds covered by the recording so far. */
139
+ duration: number;
140
+ writes: number;
141
+ effectRuns: number;
142
+ effectMs: number;
143
+ computeRuns: number;
144
+ computeMs: number;
145
+ /** Per component, busiest first. */
146
+ owners: OwnerStats[];
147
+ }
148
+
71
149
  export declare class Registry {
72
150
  private static _instance;
73
151
  static get instance(): Registry;
74
152
  readonly bus: EventBus;
153
+ readonly profiler: Profiler;
75
154
  private readonly instanceIds;
76
155
  private readonly signals;
156
+ private readonly signalsByComponent;
77
157
  private readonly components;
78
158
  private readonly timeline;
79
159
  private getInstanceId;
@@ -114,6 +194,19 @@ export declare type TimelineEventType = 'signal:change' | 'component:render' | '
114
194
 
115
195
  export declare const TimelinePlugin: DevtoolsPlugin;
116
196
 
117
- export declare function Trace(): <T extends new (...args: any[]) => RootComponent<Record<string, any>>>(constructor: T, _context: ClassDecoratorContext) => T;
197
+ export declare function Trace(options?: TraceOptions): <T extends new (...args: any[]) => RootComponent<Record<string, any>>>(constructor: T, context: ClassDecoratorContext) => T;
198
+
199
+ /**
200
+ * Instruments a component class to report renders and lifecycle events
201
+ * to the devtools panel.
202
+ *
203
+ * @Trace({ slow: 4 }) // also warn when a render takes more than 4 ms
204
+ * @Component()
205
+ * class MyComponent extends StatefulComponent { ... }
206
+ */
207
+ export declare interface TraceOptions {
208
+ /** Warns in the console when a render of this component takes longer than this many ms. */
209
+ slow?: number;
210
+ }
118
211
 
119
212
  export { }