@ng-prism/plugin-perf 22.5.0 → 22.7.0-beta.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.
@@ -1,4 +1,5 @@
1
1
  import { ChangeDetectionStrategy, Component, computed, input, signal } from '@angular/core';
2
+ import { PrismButtonComponent, PrismPanelToolbarComponent, PrismTabsComponent } from '@ng-prism/core';
2
3
  import { BundleSectionComponent } from './bundle/bundle-section.component.js';
3
4
  import { MemorySectionComponent } from './memory/memory-section.component.js';
4
5
  import { PerfMemoryService } from './memory/perf-memory.service.js';
@@ -6,81 +7,66 @@ import { DEFAULT_THRESHOLDS } from './perf.types.js';
6
7
  import { PerfRenderService } from './render/perf-render.service.js';
7
8
  import { RenderSectionComponent } from './render/render-section.component.js';
8
9
  import * as i0 from "@angular/core";
9
- function PerfPanelComponent_Conditional_9_Conditional_0_Template(rf, ctx) { if (rf & 1) {
10
- const _r2 = i0.ɵɵgetCurrentView();
11
- i0.ɵɵelementStart(0, "button", 10);
12
- i0.ɵɵlistener("click", function PerfPanelComponent_Conditional_9_Conditional_0_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.renderService.stopRecording()); });
13
- i0.ɵɵtext(1, " \u23F8 Pause ");
10
+ function PerfPanelComponent_Conditional_4_Conditional_2_Template(rf, ctx) { if (rf & 1) {
11
+ const _r3 = i0.ɵɵgetCurrentView();
12
+ i0.ɵɵelementStart(0, "button", 9);
13
+ i0.ɵɵlistener("click", function PerfPanelComponent_Conditional_4_Conditional_2_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.renderService.stopRecording()); });
14
+ i0.ɵɵtext(1, " Pause ");
14
15
  i0.ɵɵelementEnd();
16
+ } if (rf & 2) {
17
+ const ctx_r1 = i0.ɵɵnextContext(2);
18
+ i0.ɵɵproperty("title", ctx_r1.profileTitle());
15
19
  } }
16
- function PerfPanelComponent_Conditional_9_Conditional_1_Template(rf, ctx) { if (rf & 1) {
20
+ function PerfPanelComponent_Conditional_4_Conditional_3_Template(rf, ctx) { if (rf & 1) {
17
21
  const _r4 = i0.ɵɵgetCurrentView();
18
- i0.ɵɵelementStart(0, "button", 10);
19
- i0.ɵɵlistener("click", function PerfPanelComponent_Conditional_9_Conditional_1_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.renderService.startRecording()); });
20
- i0.ɵɵtext(1, " \u25B6 Profile ");
21
- i0.ɵɵelementEnd();
22
- } }
23
- function PerfPanelComponent_Conditional_9_Conditional_4_Template(rf, ctx) { if (rf & 1) {
24
- i0.ɵɵelementStart(0, "span", 11);
25
- i0.ɵɵelement(1, "span", 12);
26
- i0.ɵɵtext(2);
22
+ i0.ɵɵelementStart(0, "button", 9);
23
+ i0.ɵɵlistener("click", function PerfPanelComponent_Conditional_4_Conditional_3_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.renderService.startRecording()); });
24
+ i0.ɵɵtext(1, " Profile ");
27
25
  i0.ɵɵelementEnd();
28
26
  } if (rf & 2) {
29
- const ctx_r2 = i0.ɵɵnextContext(2);
30
- i0.ɵɵadvance(2);
31
- i0.ɵɵtextInterpolate1(" live \u00B7 ", ctx_r2.renderService.sampleCount(), " samples ");
27
+ const ctx_r1 = i0.ɵɵnextContext(2);
28
+ i0.ɵɵproperty("title", ctx_r1.profileTitle());
32
29
  } }
33
- function PerfPanelComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
30
+ function PerfPanelComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
34
31
  const _r1 = i0.ɵɵgetCurrentView();
35
- i0.ɵɵconditionalCreate(0, PerfPanelComponent_Conditional_9_Conditional_0_Template, 2, 0, "button", 9)(1, PerfPanelComponent_Conditional_9_Conditional_1_Template, 2, 0, "button", 9);
36
- i0.ɵɵelementStart(2, "button", 10);
37
- i0.ɵɵlistener("click", function PerfPanelComponent_Conditional_9_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.renderService.clear()); });
38
- i0.ɵɵtext(3, " \u2715 Clear ");
32
+ i0.ɵɵelementStart(0, "button", 7);
33
+ i0.ɵɵlistener("click", function PerfPanelComponent_Conditional_4_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.renderService.clear()); });
34
+ i0.ɵɵtext(1, " Clear ");
39
35
  i0.ɵɵelementEnd();
40
- i0.ɵɵconditionalCreate(4, PerfPanelComponent_Conditional_9_Conditional_4_Template, 3, 1, "span", 11);
36
+ i0.ɵɵconditionalCreate(2, PerfPanelComponent_Conditional_4_Conditional_2_Template, 2, 1, "button", 8)(3, PerfPanelComponent_Conditional_4_Conditional_3_Template, 2, 1, "button", 8);
41
37
  } if (rf & 2) {
42
- const ctx_r2 = i0.ɵɵnextContext();
43
- i0.ɵɵconditional(ctx_r2.renderService.isRecording() ? 0 : 1);
44
- i0.ɵɵadvance(4);
45
- i0.ɵɵconditional(ctx_r2.renderService.isRecording() ? 4 : -1);
38
+ const ctx_r1 = i0.ɵɵnextContext();
39
+ i0.ɵɵadvance(2);
40
+ i0.ɵɵconditional(ctx_r1.renderService.isRecording() ? 2 : 3);
46
41
  } }
47
- function PerfPanelComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
42
+ function PerfPanelComponent_Conditional_5_Template(rf, ctx) { if (rf & 1) {
48
43
  const _r5 = i0.ɵɵgetCurrentView();
49
- i0.ɵɵelementStart(0, "button", 10);
50
- i0.ɵɵlistener("click", function PerfPanelComponent_Conditional_10_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.captureMemorySnapshots()); });
51
- i0.ɵɵtext(1, " \u25B6 Snapshot ");
44
+ i0.ɵɵelementStart(0, "button", 7);
45
+ i0.ɵɵlistener("click", function PerfPanelComponent_Conditional_5_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.memoryService.clear()); });
46
+ i0.ɵɵtext(1, " Clear ");
52
47
  i0.ɵɵelementEnd();
53
48
  i0.ɵɵelementStart(2, "button", 10);
54
- i0.ɵɵlistener("click", function PerfPanelComponent_Conditional_10_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.memoryService.clear()); });
55
- i0.ɵɵtext(3, " \u2715 Clear ");
49
+ i0.ɵɵlistener("click", function PerfPanelComponent_Conditional_5_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.captureMemorySnapshots()); });
50
+ i0.ɵɵtext(3, " Snapshot ");
56
51
  i0.ɵɵelementEnd();
57
52
  } }
58
- function PerfPanelComponent_Conditional_11_Template(rf, ctx) { if (rf & 1) {
59
- i0.ɵɵelementStart(0, "span", 4);
60
- i0.ɵɵtext(1);
61
- i0.ɵɵelementEnd();
53
+ function PerfPanelComponent_Case_7_Template(rf, ctx) { if (rf & 1) {
54
+ i0.ɵɵelement(0, "perf-bundle-section", 4);
62
55
  } if (rf & 2) {
63
- const ctx_r2 = i0.ɵɵnextContext();
64
- i0.ɵɵadvance();
65
- i0.ɵɵtextInterpolate1(" ", ctx_r2.renderService.cdRunCount(), " CD runs ");
56
+ const ctx_r1 = i0.ɵɵnextContext();
57
+ i0.ɵɵproperty("metrics", ctx_r1.bundleMetrics())("warnKb", ctx_r1.thresholds.bundleWarnKb)("critKb", ctx_r1.thresholds.bundleCritKb);
66
58
  } }
67
- function PerfPanelComponent_Case_13_Template(rf, ctx) { if (rf & 1) {
68
- i0.ɵɵelement(0, "perf-bundle-section", 6);
59
+ function PerfPanelComponent_Case_8_Template(rf, ctx) { if (rf & 1) {
60
+ i0.ɵɵelement(0, "perf-render-section", 5);
69
61
  } if (rf & 2) {
70
- const ctx_r2 = i0.ɵɵnextContext();
71
- i0.ɵɵproperty("metrics", ctx_r2.bundleMetrics())("warnKb", ctx_r2.thresholds.bundleWarnKb)("critKb", ctx_r2.thresholds.bundleCritKb);
62
+ const ctx_r1 = i0.ɵɵnextContext();
63
+ i0.ɵɵproperty("renderService", ctx_r1.renderService)("warnMs", ctx_r1.thresholds.renderWarnMs)("critMs", ctx_r1.thresholds.renderCritMs);
72
64
  } }
73
- function PerfPanelComponent_Case_14_Template(rf, ctx) { if (rf & 1) {
74
- i0.ɵɵelement(0, "perf-render-section", 7);
65
+ function PerfPanelComponent_Case_9_Template(rf, ctx) { if (rf & 1) {
66
+ i0.ɵɵelement(0, "perf-memory-section", 6);
75
67
  } if (rf & 2) {
76
- const ctx_r2 = i0.ɵɵnextContext();
77
- i0.ɵɵproperty("renderService", ctx_r2.renderService)("warnMs", ctx_r2.thresholds.renderWarnMs)("critMs", ctx_r2.thresholds.renderCritMs);
78
- } }
79
- function PerfPanelComponent_Case_15_Template(rf, ctx) { if (rf & 1) {
80
- i0.ɵɵelement(0, "perf-memory-section", 8);
81
- } if (rf & 2) {
82
- const ctx_r2 = i0.ɵɵnextContext();
83
- i0.ɵɵproperty("memoryService", ctx_r2.memoryService);
68
+ const ctx_r1 = i0.ɵɵnextContext();
69
+ i0.ɵɵproperty("memoryService", ctx_r1.memoryService);
84
70
  } }
85
71
  export class PerfPanelComponent {
86
72
  activeComponent = input(null, /* @ts-ignore */
@@ -90,6 +76,28 @@ export class PerfPanelComponent {
90
76
  renderService = PerfRenderService.getInstance();
91
77
  memoryService = PerfMemoryService.getInstance();
92
78
  thresholds = DEFAULT_THRESHOLDS;
79
+ tabs = [
80
+ { id: 'bundle', label: 'Bundle' },
81
+ { id: 'render', label: 'Render' },
82
+ { id: 'memory', label: 'Memory' }
83
+ ];
84
+ selectTab(id) {
85
+ if (id === 'bundle' || id === 'render' || id === 'memory')
86
+ this.activeTab.set(id);
87
+ }
88
+ /** Recording state and change-detection runs: meta for the tooltip, not for the toolbar. */
89
+ profileTitle = computed(() => {
90
+ const parts = [];
91
+ if (this.renderService.isRecording())
92
+ parts.push(`Live · ${this.renderService.sampleCount()} samples`);
93
+ else
94
+ parts.push('Record render times');
95
+ const cd = this.renderService.cdRunCount();
96
+ if (cd > 0)
97
+ parts.push(`${cd} change detection runs`);
98
+ return parts.join(' · ');
99
+ }, /* @ts-ignore */
100
+ ...(ngDevMode ? [{ debugName: "profileTitle" }] : /* istanbul ignore next */ []));
93
101
  captureMemorySnapshots() {
94
102
  this.memoryService.takeSnapshot('before-create');
95
103
  setTimeout(() => this.memoryService.takeSnapshot('after-create'), 50);
@@ -100,47 +108,31 @@ export class PerfPanelComponent {
100
108
  }, /* @ts-ignore */
101
109
  ...(ngDevMode ? [{ debugName: "bundleMetrics" }] : /* istanbul ignore next */ []));
102
110
  static ɵfac = function PerfPanelComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || PerfPanelComponent)(); };
103
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: PerfPanelComponent, selectors: [["prism-perf-panel"]], inputs: { activeComponent: [1, "activeComponent"] }, decls: 16, vars: 10, consts: [[1, "prism-perf-panel"], [1, "prism-subtabs"], [1, "prism-st-tab", 3, "click"], [1, "prism-subtabs-actions"], [1, "prism-perf-cd-badge"], [1, "prism-perf-content"], [3, "metrics", "warnKb", "critKb"], [3, "renderService", "warnMs", "critMs"], [3, "memoryService"], [1, "prism-tool-btn"], [1, "prism-tool-btn", 3, "click"], [1, "prism-perf-status"], [1, "prism-perf-status-dot"]], template: function PerfPanelComponent_Template(rf, ctx) { if (rf & 1) {
104
- i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "button", 2);
105
- i0.ɵɵlistener("click", function PerfPanelComponent_Template_button_click_2_listener() { return ctx.activeTab.set("bundle"); });
106
- i0.ɵɵtext(3, " Bundle ");
107
- i0.ɵɵelementEnd();
108
- i0.ɵɵelementStart(4, "button", 2);
109
- i0.ɵɵlistener("click", function PerfPanelComponent_Template_button_click_4_listener() { return ctx.activeTab.set("render"); });
110
- i0.ɵɵtext(5, " Render ");
111
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: PerfPanelComponent, selectors: [["prism-perf-panel"]], inputs: { activeComponent: [1, "activeComponent"] }, decls: 10, vars: 5, consts: [[1, "prism-perf-panel"], ["toolbarStart", "", "size", "sm", "ariaLabel", "Performance views", 3, "activeChange", "items", "active"], ["toolbarEnd", "", 1, "prism-perf-actions"], [1, "prism-perf-content"], [3, "metrics", "warnKb", "critKb"], [3, "renderService", "warnMs", "critMs"], [3, "memoryService"], ["prismButton", "", "variant", "secondary", 3, "click"], ["prismButton", "", "variant", "primary", 3, "title"], ["prismButton", "", "variant", "primary", 3, "click", "title"], ["prismButton", "", "variant", "primary", 3, "click"]], template: function PerfPanelComponent_Template(rf, ctx) { if (rf & 1) {
112
+ i0.ɵɵelementStart(0, "div", 0)(1, "prism-panel-toolbar")(2, "prism-tabs", 1);
113
+ i0.ɵɵlistener("activeChange", function PerfPanelComponent_Template_prism_tabs_activeChange_2_listener($event) { return ctx.selectTab($event); });
111
114
  i0.ɵɵelementEnd();
112
- i0.ɵɵelementStart(6, "button", 2);
113
- i0.ɵɵlistener("click", function PerfPanelComponent_Template_button_click_6_listener() { return ctx.activeTab.set("memory"); });
114
- i0.ɵɵtext(7, " Memory ");
115
- i0.ɵɵelementEnd();
116
- i0.ɵɵelementStart(8, "div", 3);
117
- i0.ɵɵconditionalCreate(9, PerfPanelComponent_Conditional_9_Template, 5, 2);
118
- i0.ɵɵconditionalCreate(10, PerfPanelComponent_Conditional_10_Template, 4, 0);
119
- i0.ɵɵconditionalCreate(11, PerfPanelComponent_Conditional_11_Template, 2, 1, "span", 4);
115
+ i0.ɵɵelementStart(3, "div", 2);
116
+ i0.ɵɵconditionalCreate(4, PerfPanelComponent_Conditional_4_Template, 4, 1);
117
+ i0.ɵɵconditionalCreate(5, PerfPanelComponent_Conditional_5_Template, 4, 0);
120
118
  i0.ɵɵelementEnd()();
121
- i0.ɵɵelementStart(12, "div", 5);
122
- i0.ɵɵconditionalCreate(13, PerfPanelComponent_Case_13_Template, 1, 3, "perf-bundle-section", 6)(14, PerfPanelComponent_Case_14_Template, 1, 3, "perf-render-section", 7)(15, PerfPanelComponent_Case_15_Template, 1, 1, "perf-memory-section", 8);
119
+ i0.ɵɵelementStart(6, "div", 3);
120
+ i0.ɵɵconditionalCreate(7, PerfPanelComponent_Case_7_Template, 1, 3, "perf-bundle-section", 4)(8, PerfPanelComponent_Case_8_Template, 1, 3, "perf-render-section", 5)(9, PerfPanelComponent_Case_9_Template, 1, 1, "perf-memory-section", 6);
123
121
  i0.ɵɵelementEnd()();
124
122
  } if (rf & 2) {
125
- let tmp_6_0;
126
- i0.ɵɵadvance(2);
127
- i0.ɵɵclassProp("prism-st-tab--active", ctx.activeTab() === "bundle");
123
+ let tmp_4_0;
128
124
  i0.ɵɵadvance(2);
129
- i0.ɵɵclassProp("prism-st-tab--active", ctx.activeTab() === "render");
125
+ i0.ɵɵproperty("items", ctx.tabs)("active", ctx.activeTab());
130
126
  i0.ɵɵadvance(2);
131
- i0.ɵɵclassProp("prism-st-tab--active", ctx.activeTab() === "memory");
132
- i0.ɵɵadvance(3);
133
- i0.ɵɵconditional(ctx.activeTab() === "render" ? 9 : -1);
134
- i0.ɵɵadvance();
135
- i0.ɵɵconditional(ctx.activeTab() === "memory" ? 10 : -1);
127
+ i0.ɵɵconditional(ctx.activeTab() === "render" ? 4 : -1);
136
128
  i0.ɵɵadvance();
137
- i0.ɵɵconditional(ctx.renderService.cdRunCount() > 0 ? 11 : -1);
129
+ i0.ɵɵconditional(ctx.activeTab() === "memory" ? 5 : -1);
138
130
  i0.ɵɵadvance(2);
139
- i0.ɵɵconditional((tmp_6_0 = ctx.activeTab()) === "bundle" ? 13 : tmp_6_0 === "render" ? 14 : tmp_6_0 === "memory" ? 15 : -1);
140
- } }, dependencies: [BundleSectionComponent, RenderSectionComponent, MemorySectionComponent], styles: ["[_nghost-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.prism-perf-panel[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.prism-subtabs[_ngcontent-%COMP%] {\n position: sticky;\n top: 0;\n z-index: 2;\n display: flex;\n gap: 2px;\n padding: 10px 20px 0;\n background: var(--%NS%prism-bg-elevated);\n border-bottom: 1px solid var(--%NS%prism-border);\n}\n\n.prism-st-tab[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n gap: 6px;\n align-items: center;\n padding: 7px 12px;\n font-family: var(--%NS%font-sans);\n font-size: 12px;\n font-weight: 500;\n color: var(--%NS%prism-text-muted);\n cursor: pointer;\n background: transparent;\n border: none;\n border-radius: 6px 6px 0 0;\n transition: color var(--%NS%dur-fast);\n}\n\n.prism-st-tab[_ngcontent-%COMP%]:hover {\n color: var(--%NS%prism-text-2);\n}\n\n.prism-st-tab--active[_ngcontent-%COMP%] {\n color: var(--%NS%prism-text);\n}\n\n.prism-st-tab--%NS%active[_ngcontent-%COMP%]::after {\n position: absolute;\n right: 8px;\n bottom: -1px;\n left: 8px;\n height: 2px;\n content: '';\n background: var(--%NS%prism-primary);\n border-radius: 1px;\n}\n\n.prism-subtabs-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n margin-left: auto;\n}\n\n.prism-perf-cd-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: 24px;\n padding: 0 8px;\n font-family: var(--%NS%font-mono, 'JetBrains Mono', monospace);\n font-size: 11px;\n color: var(--%NS%prism-primary);\n background: color-mix(in srgb, var(--%NS%prism-primary) 12%, transparent);\n border: 1px solid color-mix(in srgb, var(--%NS%prism-primary) 25%, transparent);\n border-radius: 5px;\n}\n\n.prism-tool-btn[_ngcontent-%COMP%] {\n display: flex;\n gap: 5px;\n align-items: center;\n height: 24px;\n padding: 0 9px;\n font-family: var(--%NS%font-sans);\n font-size: 11.5px;\n font-weight: 500;\n color: var(--%NS%prism-text-muted);\n cursor: pointer;\n background: none;\n border: none;\n border-radius: 5px;\n transition: all 0.12s;\n}\n\n.prism-tool-btn[_ngcontent-%COMP%]:hover {\n color: var(--%NS%prism-text);\n background: color-mix(in srgb, var(--%NS%prism-primary) 8%, transparent);\n}\n\n.prism-perf-status[_ngcontent-%COMP%] {\n display: flex;\n gap: 5px;\n align-items: center;\n font-family: var(--%NS%font-mono);\n font-size: 11px;\n color: var(--%NS%prism-text-muted);\n}\n\n.prism-perf-status-dot[_ngcontent-%COMP%] {\n display: inline-block;\n width: 5px;\n height: 5px;\n background: var(--%NS%prism-success);\n border-radius: 50%;\n box-shadow: 0 0 6px var(--%NS%prism-success);\n animation: _ngcontent-%COMP%_prism-perf-pulse 2s ease-in-out infinite;\n}\n\n@keyframes _ngcontent-%COMP%_prism-perf-pulse {\n 0%,\n 100% {\n opacity: 1;\n }\n\n 50% {\n opacity: 0.4;\n }\n}\n\n.prism-perf-content[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n}"] });
131
+ i0.ɵɵconditional((tmp_4_0 = ctx.activeTab()) === "bundle" ? 7 : tmp_4_0 === "render" ? 8 : tmp_4_0 === "memory" ? 9 : -1);
132
+ } }, dependencies: [BundleSectionComponent, RenderSectionComponent, MemorySectionComponent, PrismPanelToolbarComponent, PrismTabsComponent, PrismButtonComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n height: 100%;\n}\n\n.prism-perf-panel[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.prism-perf-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.prism-perf-content[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n overflow: auto;\n}"] });
141
133
  }
142
134
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(PerfPanelComponent, [{
143
135
  type: Component,
144
- args: [{ selector: 'prism-perf-panel', standalone: true, imports: [BundleSectionComponent, RenderSectionComponent, MemorySectionComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"prism-perf-panel\">\n <div class=\"prism-subtabs\">\n <button\n class=\"prism-st-tab\"\n [class.prism-st-tab--active]=\"activeTab() === 'bundle'\"\n (click)=\"activeTab.set('bundle')\">\n Bundle\n </button>\n <button\n class=\"prism-st-tab\"\n [class.prism-st-tab--active]=\"activeTab() === 'render'\"\n (click)=\"activeTab.set('render')\">\n Render\n </button>\n <button\n class=\"prism-st-tab\"\n [class.prism-st-tab--active]=\"activeTab() === 'memory'\"\n (click)=\"activeTab.set('memory')\">\n Memory\n </button>\n <div class=\"prism-subtabs-actions\">\n @if (activeTab() === 'render') {\n @if (renderService.isRecording()) {\n <button\n class=\"prism-tool-btn\"\n (click)=\"renderService.stopRecording()\">\n &#9208; Pause\n </button>\n } @else {\n <button\n class=\"prism-tool-btn\"\n (click)=\"renderService.startRecording()\">\n &#9654; Profile\n </button>\n }\n <button\n class=\"prism-tool-btn\"\n (click)=\"renderService.clear()\">\n &#10005; Clear\n </button>\n @if (renderService.isRecording()) {\n <span class=\"prism-perf-status\"> <span class=\"prism-perf-status-dot\"></span> live &middot; {{ renderService.sampleCount() }} samples </span>\n }\n }\n @if (activeTab() === 'memory') {\n <button\n class=\"prism-tool-btn\"\n (click)=\"captureMemorySnapshots()\">\n &#9654; Snapshot\n </button>\n <button\n class=\"prism-tool-btn\"\n (click)=\"memoryService.clear()\">\n &#10005; Clear\n </button>\n }\n @if (renderService.cdRunCount() > 0) {\n <span class=\"prism-perf-cd-badge\"> {{ renderService.cdRunCount() }} CD runs </span>\n }\n </div>\n </div>\n\n <div class=\"prism-perf-content\">\n @switch (activeTab()) {\n @case ('bundle') {\n <perf-bundle-section\n [metrics]=\"bundleMetrics()\"\n [warnKb]=\"thresholds.bundleWarnKb\"\n [critKb]=\"thresholds.bundleCritKb\" />\n }\n @case ('render') {\n <perf-render-section\n [renderService]=\"renderService\"\n [warnMs]=\"thresholds.renderWarnMs\"\n [critMs]=\"thresholds.renderCritMs\" />\n }\n @case ('memory') {\n <perf-memory-section [memoryService]=\"memoryService\" />\n }\n }\n </div>\n</div>\n", styles: [":host {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.prism-perf-panel {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.prism-subtabs {\n position: sticky;\n top: 0;\n z-index: 2;\n display: flex;\n gap: 2px;\n padding: 10px 20px 0;\n background: var(--prism-bg-elevated);\n border-bottom: 1px solid var(--prism-border);\n}\n\n.prism-st-tab {\n position: relative;\n display: flex;\n gap: 6px;\n align-items: center;\n padding: 7px 12px;\n font-family: var(--font-sans);\n font-size: 12px;\n font-weight: 500;\n color: var(--prism-text-muted);\n cursor: pointer;\n background: transparent;\n border: none;\n border-radius: 6px 6px 0 0;\n transition: color var(--dur-fast);\n}\n\n.prism-st-tab:hover {\n color: var(--prism-text-2);\n}\n\n.prism-st-tab--active {\n color: var(--prism-text);\n}\n\n.prism-st-tab--active::after {\n position: absolute;\n right: 8px;\n bottom: -1px;\n left: 8px;\n height: 2px;\n content: '';\n background: var(--prism-primary);\n border-radius: 1px;\n}\n\n.prism-subtabs-actions {\n display: flex;\n gap: 8px;\n align-items: center;\n margin-left: auto;\n}\n\n.prism-perf-cd-badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: 24px;\n padding: 0 8px;\n font-family: var(--font-mono, 'JetBrains Mono', monospace);\n font-size: 11px;\n color: var(--prism-primary);\n background: color-mix(in srgb, var(--prism-primary) 12%, transparent);\n border: 1px solid color-mix(in srgb, var(--prism-primary) 25%, transparent);\n border-radius: 5px;\n}\n\n.prism-tool-btn {\n display: flex;\n gap: 5px;\n align-items: center;\n height: 24px;\n padding: 0 9px;\n font-family: var(--font-sans);\n font-size: 11.5px;\n font-weight: 500;\n color: var(--prism-text-muted);\n cursor: pointer;\n background: none;\n border: none;\n border-radius: 5px;\n transition: all 0.12s;\n}\n\n.prism-tool-btn:hover {\n color: var(--prism-text);\n background: color-mix(in srgb, var(--prism-primary) 8%, transparent);\n}\n\n.prism-perf-status {\n display: flex;\n gap: 5px;\n align-items: center;\n font-family: var(--font-mono);\n font-size: 11px;\n color: var(--prism-text-muted);\n}\n\n.prism-perf-status-dot {\n display: inline-block;\n width: 5px;\n height: 5px;\n background: var(--prism-success);\n border-radius: 50%;\n box-shadow: 0 0 6px var(--prism-success);\n animation: prism-perf-pulse 2s ease-in-out infinite;\n}\n\n@keyframes prism-perf-pulse {\n 0%,\n 100% {\n opacity: 1;\n }\n\n 50% {\n opacity: 0.4;\n }\n}\n\n.prism-perf-content {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n}\n"] }]
136
+ args: [{ selector: 'prism-perf-panel', standalone: true, imports: [BundleSectionComponent, RenderSectionComponent, MemorySectionComponent, PrismPanelToolbarComponent, PrismTabsComponent, PrismButtonComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"prism-perf-panel\">\n <prism-panel-toolbar>\n <prism-tabs\n toolbarStart\n size=\"sm\"\n ariaLabel=\"Performance views\"\n [items]=\"tabs\"\n [active]=\"activeTab()\"\n (activeChange)=\"selectTab($event)\" />\n <div\n toolbarEnd\n class=\"prism-perf-actions\">\n @if (activeTab() === 'render') {\n <button\n prismButton\n variant=\"secondary\"\n (click)=\"renderService.clear()\">\n Clear\n </button>\n @if (renderService.isRecording()) {\n <button\n prismButton\n variant=\"primary\"\n [title]=\"profileTitle()\"\n (click)=\"renderService.stopRecording()\">\n Pause\n </button>\n } @else {\n <button\n prismButton\n variant=\"primary\"\n [title]=\"profileTitle()\"\n (click)=\"renderService.startRecording()\">\n Profile\n </button>\n }\n }\n @if (activeTab() === 'memory') {\n <button\n prismButton\n variant=\"secondary\"\n (click)=\"memoryService.clear()\">\n Clear\n </button>\n <button\n prismButton\n variant=\"primary\"\n (click)=\"captureMemorySnapshots()\">\n Snapshot\n </button>\n }\n </div>\n </prism-panel-toolbar>\n\n <div class=\"prism-perf-content\">\n @switch (activeTab()) {\n @case ('bundle') {\n <perf-bundle-section\n [metrics]=\"bundleMetrics()\"\n [warnKb]=\"thresholds.bundleWarnKb\"\n [critKb]=\"thresholds.bundleCritKb\" />\n }\n @case ('render') {\n <perf-render-section\n [renderService]=\"renderService\"\n [warnMs]=\"thresholds.renderWarnMs\"\n [critMs]=\"thresholds.renderCritMs\" />\n }\n @case ('memory') {\n <perf-memory-section [memoryService]=\"memoryService\" />\n }\n }\n </div>\n</div>\n", styles: [":host {\n display: block;\n height: 100%;\n}\n\n.prism-perf-panel {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.prism-perf-actions {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.prism-perf-content {\n flex: 1;\n min-height: 0;\n overflow: auto;\n}\n"] }]
145
137
  }], null, { activeComponent: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeComponent", required: false }] }] }); })();
146
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PerfPanelComponent, { className: "PerfPanelComponent", filePath: "perf-panel.component.ts", lineNumber: 20 }); })();
138
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PerfPanelComponent, { className: "PerfPanelComponent", filePath: "perf-panel.component.ts", lineNumber: 21 }); })();
@@ -1 +1 @@
1
- {"version":3,"file":"perf-plugin.browser.d.ts","sourceRoot":"","sources":["../src/perf-plugin.browser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,wBAAgB,UAAU,CAAC,QAAQ,CAAC,EAAE,iBAAiB,GAAG,aAAa,CActE"}
1
+ {"version":3,"file":"perf-plugin.browser.d.ts","sourceRoot":"","sources":["../src/perf-plugin.browser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,wBAAgB,UAAU,CAAC,QAAQ,CAAC,EAAE,iBAAiB,GAAG,aAAa,CAatE"}
@@ -7,7 +7,6 @@ export function perfPlugin(_options) {
7
7
  label: 'Performance',
8
8
  icon: 'activity',
9
9
  loadComponent: () => import('./perf-panel.component.js').then((m) => m.PerfPanelComponent),
10
- position: 'bottom',
11
10
  placement: 'addon'
12
11
  }
13
12
  ]
@@ -1 +1 @@
1
- {"version":3,"file":"perf-plugin.d.ts","sourceRoot":"","sources":["../src/perf-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,wBAAgB,UAAU,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,aAAa,CA4BrE"}
1
+ {"version":3,"file":"perf-plugin.d.ts","sourceRoot":"","sources":["../src/perf-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,wBAAgB,UAAU,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,aAAa,CA6BrE"}
@@ -1,5 +1,6 @@
1
1
  import { scanBundle } from './bundle/bundle-scanner.js';
2
2
  export function perfPlugin(options) {
3
+ warnAboutDeprecatedOptions(options);
3
4
  return {
4
5
  name: '@ng-prism/plugin-perf',
5
6
  async onComponentScanned(component) {
@@ -19,9 +20,20 @@ export function perfPlugin(options) {
19
20
  {
20
21
  id: 'perf',
21
22
  label: 'Performance',
22
- loadComponent: () => import('./perf-panel.component.js').then((m) => m.PerfPanelComponent),
23
- position: 'bottom'
23
+ loadComponent: () => import('./perf-panel.component.js').then((m) => m.PerfPanelComponent)
24
24
  }
25
25
  ]
26
26
  };
27
27
  }
28
+ /** Runs in the builder only: the browser entry has its own factory. */
29
+ function warnAboutDeprecatedOptions(options) {
30
+ const deprecated = [
31
+ options?.thresholds !== undefined && 'thresholds',
32
+ options?.bundle?.excludeImports !== undefined && 'bundle.excludeImports',
33
+ options?.render !== undefined && 'render',
34
+ options?.memory !== undefined && 'memory'
35
+ ].filter((option) => option !== false);
36
+ for (const option of deprecated) {
37
+ console.warn(`⚠ ng-prism: perfPlugin() option "${option}" is deprecated and will be removed in 23.0.0. It has never had an effect; remove it.`);
38
+ }
39
+ }
@@ -0,0 +1,12 @@
1
+ import { type StatusTone } from '@ng-prism/core/plugin';
2
+ /**
3
+ * A perf figure graded against its budget, lower being better: within the
4
+ * warning bound it is OK, up to the critical bound a warning, above it critical.
5
+ * Same rule as every other key figure (`statusFor`), so the card's colour and
6
+ * its label cannot disagree.
7
+ */
8
+ export declare function perfStatus(value: number, warn: number, crit: number): {
9
+ tone: StatusTone;
10
+ label: 'OK' | 'Warning' | 'Critical';
11
+ };
12
+ //# sourceMappingURL=perf-status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"perf-status.d.ts","sourceRoot":"","sources":["../src/perf-status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAQnE;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,IAAI,GAAG,SAAS,GAAG,UAAU,CAAA;CAAE,CAIhI"}
@@ -0,0 +1,16 @@
1
+ import { statusFor } from '@ng-prism/core/plugin';
2
+ const LABEL = {
3
+ ok: 'OK',
4
+ warn: 'Warning',
5
+ danger: 'Critical'
6
+ };
7
+ /**
8
+ * A perf figure graded against its budget, lower being better: within the
9
+ * warning bound it is OK, up to the critical bound a warning, above it critical.
10
+ * Same rule as every other key figure (`statusFor`), so the card's colour and
11
+ * its label cannot disagree.
12
+ */
13
+ export function perfStatus(value, warn, crit) {
14
+ const tone = statusFor(value, { ok: warn, warn: crit, direction: 'lower' });
15
+ return { tone, label: LABEL[tone] };
16
+ }
@@ -14,15 +14,20 @@ export interface PerfThresholds {
14
14
  memoryLeakMb: number;
15
15
  }
16
16
  export interface PerfPluginOptions {
17
+ /** @deprecated Deprecated since 22.6.0, removed in 23.0.0. It has never had an effect: nothing reads it. The panel uses the built-in thresholds. */
17
18
  thresholds?: Partial<PerfThresholds>;
18
19
  bundle?: {
20
+ /** How deep the import tree of a component is followed. Default: 5. */
19
21
  maxTreeDepth?: number;
22
+ /** @deprecated Deprecated since 22.6.0, removed in 23.0.0. It has never had an effect: nothing reads it. */
20
23
  excludeImports?: string[];
21
24
  };
25
+ /** @deprecated Deprecated since 22.6.0, removed in 23.0.0. It has never had an effect: nothing reads it. */
22
26
  render?: {
23
27
  bufferSize?: number;
24
28
  autoStart?: boolean;
25
29
  };
30
+ /** @deprecated Deprecated since 22.6.0, removed in 23.0.0. It has never had an effect: nothing reads it. */
26
31
  memory?: {
27
32
  gcDelayMs?: number;
28
33
  };
@@ -1 +1 @@
1
- {"version":3,"file":"perf.types.d.ts","sourceRoot":"","sources":["../src/perf.types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAC9B,UAAU,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IACrC,MAAM,CAAC,EAAE;QACL,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;KAC7B,CAAC;IACF,MAAM,CAAC,EAAE;QACL,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,OAAO,CAAC;KACvB,CAAC;IACF,MAAM,CAAC,EAAE;QACL,SAAS,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;CACL;AAED,eAAO,MAAM,kBAAkB,EAAE,cAOhC,CAAC"}
1
+ {"version":3,"file":"perf.types.d.ts","sourceRoot":"","sources":["../src/perf.types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAC9B,oJAAoJ;IACpJ,UAAU,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IACrC,MAAM,CAAC,EAAE;QACL,uEAAuE;QACvE,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,4GAA4G;QAC5G,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;KAC7B,CAAC;IACF,4GAA4G;IAC5G,MAAM,CAAC,EAAE;QACL,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,OAAO,CAAC;KACvB,CAAC;IACF,4GAA4G;IAC5G,MAAM,CAAC,EAAE;QACL,SAAS,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;CACL;AAED,eAAO,MAAM,kBAAkB,EAAE,cAOhC,CAAC"}
@@ -1,12 +1,17 @@
1
+ import { type BadgeTone } from '@ng-prism/core';
1
2
  import type { PerfRenderService } from './perf-render.service.js';
2
3
  import * as i0 from "@angular/core";
3
4
  export declare class RenderSectionComponent {
4
5
  readonly renderService: import("@angular/core").InputSignal<PerfRenderService>;
5
6
  readonly warnMs: import("@angular/core").InputSignal<number>;
6
7
  readonly critMs: import("@angular/core").InputSignal<number>;
7
- readonly initialClass: import("@angular/core").Signal<"" | "crit" | "warn">;
8
8
  formatMs(value: number | null): string;
9
- colorFor(value: number | null): string;
9
+ /** A measured render time graded against the budget; `null` when there is nothing to grade. */
10
+ statusOf(value: number | null): {
11
+ tone: BadgeTone;
12
+ label: string;
13
+ } | null;
14
+ budgetTitle(what: string): string;
10
15
  static ɵfac: i0.ɵɵFactoryDeclaration<RenderSectionComponent, never>;
11
16
  static ɵcmp: i0.ɵɵComponentDeclaration<RenderSectionComponent, "perf-render-section", never, { "renderService": { "alias": "renderService"; "required": true; "isSignal": true; }; "warnMs": { "alias": "warnMs"; "required": false; "isSignal": true; }; "critMs": { "alias": "critMs"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
12
17
  }
@@ -1 +1 @@
1
- {"version":3,"file":"render-section.component.d.ts","sourceRoot":"","sources":["../../src/render/render-section.component.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;;AAGlE,qBAQa,sBAAsB;IAC/B,QAAQ,CAAC,aAAa,yDAAuC;IAC7D,QAAQ,CAAC,MAAM,8CAAY;IAC3B,QAAQ,CAAC,MAAM,8CAAa;IAE5B,QAAQ,CAAC,YAAY,uDAOlB;IAEH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM;IAKtC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM;yCAnB7B,sBAAsB;2CAAtB,sBAAsB;CAyBlC"}
1
+ {"version":3,"file":"render-section.component.d.ts","sourceRoot":"","sources":["../../src/render/render-section.component.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,SAAS,EAA2C,MAAM,gBAAgB,CAAC;AAEzF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;;AAGlE,qBAQa,sBAAsB;IAC/B,QAAQ,CAAC,aAAa,yDAAuC;IAC7D,QAAQ,CAAC,MAAM,8CAAY;IAC3B,QAAQ,CAAC,MAAM,8CAAa;IAE5B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM;IAKtC,+FAA+F;IAC/F,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAOzE,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;yCAlBxB,sBAAsB;2CAAtB,sBAAsB;CAqBlC"}