@pb33f/cowboy-components 0.8.0 → 0.10.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 (125) hide show
  1. package/README.md +2 -0
  2. package/dist/{_basePickBy-DtTwxTrV.js → _basePickBy-D0MVaff7.js} +2 -2
  3. package/dist/{_baseUniq-C5Y4WFmx.js → _baseUniq-DVhBEtEZ.js} +1 -1
  4. package/dist/{arc-a-7w7y90.js → arc-DfidlRZC.js} +1 -1
  5. package/dist/{architecture-U656AL7Q-c_zxypEp.js → architecture-U656AL7Q-2l0oI7kq.js} +1 -1
  6. package/dist/{architectureDiagram-VXUJARFQ-CIhQJ6xS.js → architectureDiagram-VXUJARFQ-CluOaK7l.js} +3 -3
  7. package/dist/{blockDiagram-VD42YOAC-BLl5ID-l.js → blockDiagram-VD42YOAC-RbyzthW7.js} +5 -5
  8. package/dist/{c4Diagram-YG6GDRKO-BOGfb13x.js → c4Diagram-YG6GDRKO-Bx8eR5aW.js} +2 -2
  9. package/dist/{channel-DYeI56io.js → channel-Dsjz0D5Z.js} +1 -1
  10. package/dist/{chunk-4BX2VUAB-BeHGB7ON.js → chunk-4BX2VUAB-Dk4r_XjO.js} +1 -1
  11. package/dist/{chunk-55IACEB6-DgHUzWsw.js → chunk-55IACEB6-O_k-h5nN.js} +1 -1
  12. package/dist/{chunk-B4BG7PRW-Vs7GiQMf.js → chunk-B4BG7PRW-DVDQ5atJ.js} +4 -4
  13. package/dist/{chunk-DI55MBZ5-CHjdGXx0.js → chunk-DI55MBZ5-CeD8zHDH.js} +3 -3
  14. package/dist/{chunk-FMBD7UC4-D-H9-bHN.js → chunk-FMBD7UC4-_BECV2vM.js} +1 -1
  15. package/dist/{chunk-QN33PNHL-D7uE2r1Y.js → chunk-QN33PNHL-BZt9yPgN.js} +1 -1
  16. package/dist/{chunk-QZHKN3VN-Cp3sUp7e.js → chunk-QZHKN3VN-VPFLLErx.js} +1 -1
  17. package/dist/{chunk-TZMSLE5B-BmXGcXo9.js → chunk-TZMSLE5B-DRZQTDqv.js} +1 -1
  18. package/dist/{classDiagram-v2-WZHVMYZB-9ilqiDEi.js → classDiagram-2ON5EDUG-Pjlv98sa.js} +2 -2
  19. package/dist/{classDiagram-2ON5EDUG-9ilqiDEi.js → classDiagram-v2-WZHVMYZB-Pjlv98sa.js} +2 -2
  20. package/dist/{clone-CybyMoa0.js → clone-CXHEQoEn.js} +1 -1
  21. package/dist/components/charts/beefy-chart.d.ts +1 -0
  22. package/dist/components/charts/beefy-chart.js +6 -1
  23. package/dist/components/charts/chart-colors.d.ts +8 -0
  24. package/dist/components/charts/chart-colors.js +46 -1
  25. package/dist/components/charts/doughnut-chart.js +10 -5
  26. package/dist/components/credit-ticker/credit-ticker.js +2 -6
  27. package/dist/components/editor/editor.js +17 -23
  28. package/dist/components/editor/schemas/openapi32.json +1666 -0
  29. package/dist/components/github/github-workspace-view.css.js +1 -0
  30. package/dist/components/github/github-workspace-view.d.ts +2 -0
  31. package/dist/components/github/github-workspace-view.js +14 -8
  32. package/dist/components/http-method/http-method.css.js +6 -0
  33. package/dist/components/manage-ruleset/manage-ruleset.css.js +1 -1
  34. package/dist/components/manage-ruleset/manage-ruleset.js +1 -1
  35. package/dist/components/manage-ruleset/rule-input.d.ts +1 -0
  36. package/dist/components/manage-ruleset/rule-input.js +9 -0
  37. package/dist/components/model-renderer/change.css.js +11 -1
  38. package/dist/components/model-renderer/rendered-node.css.js +1 -1
  39. package/dist/components/model-tree/tree.css.js +4 -1
  40. package/dist/components/model-tree/tree.js +11 -1
  41. package/dist/components/paginator/paginator.css.js +1 -1
  42. package/dist/components/problem-list/problem-list.css.js +3 -3
  43. package/dist/components/problem-list/problem-list.d.ts +2 -0
  44. package/dist/components/problem-list/problem-list.js +19 -0
  45. package/dist/components/problems-overview/problems-overview.css.js +2 -1
  46. package/dist/components/problems-overview/problems-overview.js +7 -6
  47. package/dist/components/terminal-emulator/terminal-emulator.css.js +1 -1
  48. package/dist/components/the-doctor/doctor-editor-panel.js +1 -0
  49. package/dist/components/the-doctor/doctor-navigator-panel.css.js +1 -1
  50. package/dist/components/the-doctor/doctor-sidebar-panel.css.js +1 -1
  51. package/dist/components/the-doctor/sparks.d.ts +3 -0
  52. package/dist/components/the-doctor/sparks.js +22 -4
  53. package/dist/components/the-doctor/the-doctor.css.js +4 -4
  54. package/dist/components/the-doctor/the-doctor.d.ts +1 -0
  55. package/dist/components/the-doctor/the-doctor.js +25 -24
  56. package/dist/components/the-doctor/upload-archive.css.js +6 -0
  57. package/dist/components/the-doctor/upload-archive.js +2 -0
  58. package/dist/components/time-vortex/history-picker.css.js +18 -1
  59. package/dist/components/time-vortex/history-picker.js +18 -0
  60. package/dist/components/time-vortex/tardis-control.css.js +20 -2
  61. package/dist/components/time-vortex/tardis-control.d.ts +1 -0
  62. package/dist/components/time-vortex/tardis-control.js +29 -3
  63. package/dist/components/toast/toast-manager.js +9 -6
  64. package/dist/components/visualizer/equalizer.css.js +1 -1
  65. package/dist/components/workspaces/workspace-view.css.js +1 -1
  66. package/dist/controllers/broker-controller.d.ts +1 -0
  67. package/dist/controllers/broker-controller.js +12 -7
  68. package/dist/controllers/diagnostic-controller.d.ts +7 -0
  69. package/dist/controllers/diagnostic-controller.js +101 -45
  70. package/dist/controllers/github-controller.js +45 -35
  71. package/dist/controllers/rolodex-controller.js +3 -5
  72. package/dist/controllers/spec-controller.d.ts +1 -0
  73. package/dist/controllers/spec-controller.js +15 -1
  74. package/dist/controllers/state-controller.js +10 -9
  75. package/dist/controllers/timeline-controller.js +1 -1
  76. package/dist/{cose-bilkent-S5V4N54A-2TG-C-n3.js → cose-bilkent-S5V4N54A-BgwjXRSW.js} +1 -1
  77. package/dist/{cowboy-components-BcyXo9oX.js → cowboy-components-BRANjWMG.js} +18882 -18621
  78. package/dist/cowboy-components.css +1 -1
  79. package/dist/cowboy-components.umd.cjs +1588 -1499
  80. package/dist/css/chroma-synxtax.css.js +14 -14
  81. package/dist/css/cowboy-components.css +11 -1
  82. package/dist/css/pb33f-theme.css +47 -8
  83. package/dist/css/scrollbar.css.js +1 -1
  84. package/dist/{dagre-6UL2VRFP-BIlmTbhO.js → dagre-6UL2VRFP-BzQ5nLXU.js} +6 -6
  85. package/dist/{diagram-PSM6KHXK-CeWby24E.js → diagram-PSM6KHXK-CdohCqjr.js} +4 -4
  86. package/dist/{diagram-QEK2KX5R-DGonyVCK.js → diagram-QEK2KX5R-BP_3efmD.js} +3 -3
  87. package/dist/{diagram-S2PKOQOG-mGn-y1uX.js → diagram-S2PKOQOG-BftsBKuz.js} +3 -3
  88. package/dist/{erDiagram-Q2GNP2WA-BlBBw4Mz.js → erDiagram-Q2GNP2WA-fSbCC-Ow.js} +4 -4
  89. package/dist/events/doctor.d.ts +1 -0
  90. package/dist/events/doctor.js +1 -0
  91. package/dist/{flowDiagram-NV44I4VS-BlLzzy1C.js → flowDiagram-NV44I4VS-CCPxaTIx.js} +5 -5
  92. package/dist/{ganttDiagram-LVOFAZNH-BoQtPC8k.js → ganttDiagram-LVOFAZNH-Cb2dn6QY.js} +2 -2
  93. package/dist/{gitGraph-F6HP7TQM-CShNSlrW.js → gitGraph-F6HP7TQM-B-Up3f_K.js} +1 -1
  94. package/dist/{gitGraphDiagram-NY62KEGX-BdpWBgHy.js → gitGraphDiagram-NY62KEGX-DdaCm8WP.js} +4 -4
  95. package/dist/{graph-D9HS4Ahd.js → graph-BSko0AhB.js} +2 -2
  96. package/dist/helpers/filename-colorizer.js +4 -2
  97. package/dist/info-NVLQJR56-BNIO2OjW.js +5 -0
  98. package/dist/{infoDiagram-F6ZHWCRC-DmhhbuMJ.js → infoDiagram-F6ZHWCRC-DoDRDWc6.js} +2 -2
  99. package/dist/interfaces/doctor-interfaces.d.ts +7 -0
  100. package/dist/{journeyDiagram-XKPGCS4Q-CpkhK8vl.js → journeyDiagram-XKPGCS4Q-B8rBrT3-.js} +4 -4
  101. package/dist/{kanban-definition-3W4ZIXB7-BFbucfYE.js → kanban-definition-3W4ZIXB7-qXzC-ucZ.js} +2 -2
  102. package/dist/{layout-B8H1_UrM.js → layout-crJEPmAx.js} +4 -4
  103. package/dist/{linear-Bo0rJUSQ.js → linear-C9sTEJtE.js} +1 -1
  104. package/dist/{mermaid-parser.core-BPror82d.js → mermaid-parser.core-quOEU4Mi.js} +11 -11
  105. package/dist/{mindmap-definition-VGOIOE7T-VAn-EShH.js → mindmap-definition-VGOIOE7T-BGn7cQVA.js} +3 -3
  106. package/dist/model/timeline.d.ts +3 -0
  107. package/dist/{packet-BFZMPI3H-CXPCK9Q2.js → packet-BFZMPI3H-BKreTkjY.js} +1 -1
  108. package/dist/pie-7BOR55EZ-DUWhTPH8.js +5 -0
  109. package/dist/{pieDiagram-ADFJNKIX-C0kdlQqn.js → pieDiagram-ADFJNKIX-BeLJhCCS.js} +4 -4
  110. package/dist/{quadrantDiagram-AYHSOK5B-CRVq6wY3.js → quadrantDiagram-AYHSOK5B-z-oixLGm.js} +2 -2
  111. package/dist/radar-NHE76QYJ-DXE9hYwD.js +5 -0
  112. package/dist/{requirementDiagram-UZGBJVZJ-B8ZGgMKn.js → requirementDiagram-UZGBJVZJ-Bso8sdSb.js} +3 -3
  113. package/dist/{sankeyDiagram-TZEHDZUN-CWAUJJue.js → sankeyDiagram-TZEHDZUN-BqcEpr7O.js} +1 -1
  114. package/dist/{sequenceDiagram-WL72ISMW-nz81a4Cq.js → sequenceDiagram-WL72ISMW-DTAwlNVG.js} +3 -3
  115. package/dist/services/linting-service.d.ts +1 -0
  116. package/dist/services/linting-service.js +22 -0
  117. package/dist/{stateDiagram-FKZM4ZOC-3PFzJlcG.js → stateDiagram-FKZM4ZOC-EGdzJIDA.js} +4 -4
  118. package/dist/{stateDiagram-v2-4FDKWEC3-Bp46vM6_.js → stateDiagram-v2-4FDKWEC3-DZo5Qb9X.js} +2 -2
  119. package/dist/{timeline-definition-IT6M3QCI-utm7jTLb.js → timeline-definition-IT6M3QCI-BjX2TakV.js} +2 -2
  120. package/dist/{treemap-KMMF4GRG-BvEKHn43.js → treemap-KMMF4GRG-D8sK0Tmc.js} +1 -1
  121. package/dist/{xychartDiagram-PRI3JC2R-twqDKWMX.js → xychartDiagram-PRI3JC2R-CWx19mhU.js} +2 -2
  122. package/package.json +1 -1
  123. package/dist/info-NVLQJR56-Bpi6I8up.js +0 -5
  124. package/dist/pie-7BOR55EZ-CMcuUZ_S.js +0 -5
  125. package/dist/radar-NHE76QYJ-CX_Gyp4h.js +0 -5
@@ -36,13 +36,30 @@ export default css `
36
36
  border-left: 3px solid var(--warn-color);
37
37
  padding-left: 5px;
38
38
  }
39
-
39
+
40
40
  .ephemeral-icon {
41
41
  color: var(--warn-color);
42
42
  font-size: 1.4rem;
43
43
  background-color: var(--background-color);
44
44
  }
45
45
 
46
+ .corrupt {
47
+ border-left: 3px solid var(--error-color);
48
+ padding-left: 5px;
49
+ color: var(--error-color);
50
+ }
51
+
52
+ .corrupt-icon {
53
+ color: var(--error-color);
54
+ font-size: 1.4rem;
55
+ background-color: var(--background-color);
56
+ }
57
+
58
+ .corrupt-title {
59
+ font-size: 0.8rem;
60
+ color: var(--error-color);
61
+ }
62
+
46
63
 
47
64
  .selected-bar {
48
65
  border-left: 3px solid var(--primary-color)!important;
@@ -98,6 +98,24 @@ let HistoryPicker = class HistoryPicker extends LitElement {
98
98
  <div class="tardis-timeline scroller">
99
99
  <pb33f-timeline skinny>
100
100
  ${this.specSummary?.map((spec, index) => {
101
+ const isCorrupt = spec.corrupt === true;
102
+ if (isCorrupt) {
103
+ return html `
104
+ <pb33f-timeline-item id="change-${spec.changeId}" skinny @click="${() => {
105
+ this.loadSpecSummary(spec);
106
+ }}">
107
+ <sl-icon slot="icon" name="exclamation-triangle" class="corrupt-icon" aria-hidden="true"></sl-icon>
108
+ <div id="timebar-${spec.changeId}" slot="time" class="time corrupt">
109
+ <sl-relative-time date="${spec.created}" format="long"></sl-relative-time>
110
+ </div>
111
+ <div slot="content">
112
+ <div id="changebar-${spec.changeId}" class="change corrupt">
113
+ <span class="corrupt-title">Corrupted Change</span>
114
+ </div>
115
+ </div>
116
+ </pb33f-timeline-item>
117
+ `;
118
+ }
101
119
  const isPr = spec.gitPrNumber !== undefined && spec.gitPrNumber !== null;
102
120
  const isEphemeral = spec.isEphemeral !== undefined && spec.isEphemeral;
103
121
  let heartBreaker = false;
@@ -192,7 +192,7 @@ export default css `
192
192
  }
193
193
 
194
194
  .timeline-view::-webkit-scrollbar-track {
195
- background-color: black;
195
+ background-color: var(--terminal-background);
196
196
  }
197
197
 
198
198
  .timeline-view::-webkit-scrollbar-thumb {
@@ -219,7 +219,7 @@ export default css `
219
219
  }
220
220
 
221
221
  .markdown-report::-webkit-scrollbar-track {
222
- background-color: black;
222
+ background-color: var(--terminal-background);
223
223
  }
224
224
 
225
225
  .markdown-report::-webkit-scrollbar-thumb {
@@ -432,6 +432,24 @@ export default css `
432
432
  font-family: var(--font-stack-bold), sans-serif;
433
433
  }
434
434
 
435
+ .corrupt-banner {
436
+ background-color: var(--error-color);
437
+ padding: 5px;
438
+ color: var(--background-color);
439
+ font-size: 0.8rem;
440
+ }
441
+
442
+ .corrupt-banner strong {
443
+ font-family: var(--font-stack-bold), sans-serif;
444
+ color: var(--background-color);
445
+ }
446
+
447
+ .corrupt-link {
448
+ color: var(--background-color);
449
+ text-decoration: underline;
450
+ cursor: pointer;
451
+ }
452
+
435
453
  @media (max-width: 1024px) {
436
454
  .markdown-report .metadata-sidebar {
437
455
  float: none;
@@ -42,6 +42,7 @@ export declare class TardisControl extends Colorful {
42
42
  connectedCallback(): void;
43
43
  disconnectedCallback(): void;
44
44
  private handleEphemeralExpired;
45
+ private openCorruptInfo;
45
46
  firstUpdated(): void;
46
47
  updated(changedProperties: Map<string, unknown>): void;
47
48
  explorerNodeClicked(evt: CustomEvent<NodeClickedEvent>): void;
@@ -21,7 +21,8 @@ import { TimelineView } from "./timeline-view.js";
21
21
  import panelsCss from "../../css/panels.css.js";
22
22
  import scrollbarCss from "../../css/scrollbar.css.js";
23
23
  import { ToastType } from "../../model/toast.js";
24
- import { AddToast, ExplorerNodeClicked, LoadRenderedNodeIntoInspector, ShowTimelineSummary } from "../../events/doctor.js";
24
+ import { AddToast, ExplorerNodeClicked, LoadRenderedNodeIntoInspector, OpenDrawer, ShowTimelineSummary } from "../../events/doctor.js";
25
+ import { DrawerContentType } from "../../model/drawer-content.js";
25
26
  import { CountdownController } from "../../controllers/countdown-controller.js";
26
27
  import '../charts/beefy-chart.js';
27
28
  import '../charts/doughnut-chart.js';
@@ -81,6 +82,24 @@ let TardisControl = class TardisControl extends Colorful {
81
82
  composed: true,
82
83
  }));
83
84
  }
85
+ openCorruptInfo(e) {
86
+ e.preventDefault();
87
+ this.dispatchEvent(new CustomEvent(OpenDrawer, {
88
+ bubbles: true,
89
+ composed: true,
90
+ detail: {
91
+ type: DrawerContentType.MARKDOWN,
92
+ title: 'CORRUPTED CHANGE',
93
+ body: `<p>Any data submitted in the early days of doctor preview was subject to a <strong>number of bugs</strong>.</p>
94
+ <p>Not everything was correctly stored, some of it was lost and unrecoverable and is not available.</p>
95
+ <p>The alpha version of the doctor was released on <strong>February 8th 2026</strong></p>
96
+ <p>Changes made on or after then is correctly stored and available permanently, all elements of the change.</p>
97
+ <p>It was never working correctly in the preview, even though you may have not have known it.</p>
98
+ <p>Sorry!</p>
99
+ <p>- quobix</p>`
100
+ }
101
+ }));
102
+ }
84
103
  firstUpdated() {
85
104
  // Don't auto-fetch - let the doctor control when we start
86
105
  // The doctor will call fetchHistory() when it's ready
@@ -329,16 +348,23 @@ let TardisControl = class TardisControl extends Colorful {
329
348
  <div style="position: relative; width: 100%" slot="end"> ${changeSummary}</div>
330
349
  </sl-split-panel>`;
331
350
  }
351
+ const isCorrupt = this.specSummary?.corrupt === true;
332
352
  const isPr = this.specSummary?.gitPrNumber !== undefined && this.specSummary.gitPrNumber !== null;
333
353
  const isEphemeral = this.specSummary?.isEphemeral !== undefined && this.specSummary.isEphemeral;
334
354
  let warningBanner = html ``;
335
- if (isPr) {
355
+ if (isCorrupt) {
356
+ warningBanner = html `
357
+ <div class="corrupt-banner">
358
+ <strong>CHANGE CORRUPTED</strong> [<a href="#" class="corrupt-link" @click="${this.openCorruptInfo}">LEARN WHY</a>]
359
+ </div>`;
360
+ }
361
+ else if (isPr) {
336
362
  warningBanner = html `
337
363
  <div class="pr-banner">
338
364
  PR: <a href="${this.specSummary?.gitPrUrl}" class="pr-url" target="_blank">#${this.specSummary?.gitPrNumber}: ${this.specSummary?.gitPrTitle}</a>
339
365
  </div>`;
340
366
  }
341
- if (!isPr && isEphemeral && this.countdownController && !this.countdownController.isExpired) {
367
+ else if (isEphemeral && this.countdownController && !this.countdownController.isExpired) {
342
368
  const criticalClass = this.countdownController.isCritical ? 'critical' : '';
343
369
  warningBanner = html `
344
370
  <div class="warn-banner ${criticalClass}">
@@ -6,6 +6,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
6
6
  };
7
7
  import { customElement, property } from "lit/decorators.js";
8
8
  import { html, LitElement } from "lit";
9
+ import { repeat } from "lit/directives/repeat.js";
9
10
  import { ToastComponent } from "./toast-component.js";
10
11
  import { AddToast, ToastExpired } from "../../events/doctor.js";
11
12
  import { typedEventHandler } from "../../helpers/typed-events.js";
@@ -52,17 +53,19 @@ let ToastManager = class ToastManager extends LitElement {
52
53
  }
53
54
  updated() {
54
55
  this.toasts?.forEach(toast => {
55
- const timeoutId = window.setTimeout(() => {
56
- this.activateTimeoutIds.delete(timeoutId);
57
- toast.activate();
58
- }, 200);
59
- this.activateTimeoutIds.add(timeoutId);
56
+ if (!toast.isActive) {
57
+ const timeoutId = window.setTimeout(() => {
58
+ this.activateTimeoutIds.delete(timeoutId);
59
+ toast.activate();
60
+ }, 200);
61
+ this.activateTimeoutIds.add(timeoutId);
62
+ }
60
63
  });
61
64
  }
62
65
  render() {
63
66
  return html `
64
67
  <div class="toast-manager">
65
- ${this.toasts?.map(toast => html `${toast}`)}
68
+ ${repeat(this.toasts ?? [], toast => toast.toast.id, toast => html `${toast}`)}
66
69
  </div>
67
70
  `;
68
71
  }
@@ -162,7 +162,7 @@ export default css `
162
162
  }
163
163
 
164
164
  .search-panel::-webkit-scrollbar-track {
165
- background-color: black;
165
+ background-color: var(--terminal-background);
166
166
  }
167
167
 
168
168
  .search-panel::-webkit-scrollbar-thumb {
@@ -21,7 +21,7 @@ export default css `
21
21
  }
22
22
 
23
23
  .workspace-area::-webkit-scrollbar-track {
24
- background-color: black;
24
+ background-color: var(--terminal-background);
25
25
  }
26
26
 
27
27
  .workspace-area::-webkit-scrollbar-thumb {
@@ -23,6 +23,7 @@ export declare class BrokerController extends EventTarget {
23
23
  private specStreamSubscription;
24
24
  private creditStreamSubscription;
25
25
  private errorStreamSubscription;
26
+ private _doctorStarted;
26
27
  constructor(deps: BrokerControllerDeps);
27
28
  connectToBroker(): void;
28
29
  doctorServiceHandler(): BusCallback<CommandResponse>;
@@ -13,6 +13,7 @@ export class BrokerController extends EventTarget {
13
13
  this.specStreamSubscription = null;
14
14
  this.creditStreamSubscription = null;
15
15
  this.errorStreamSubscription = null;
16
+ this._doctorStarted = false;
16
17
  this.deps = deps;
17
18
  this.bus = deps.bus;
18
19
  this.readyPromise = new Promise((resolve) => {
@@ -123,15 +124,18 @@ export class BrokerController extends EventTarget {
123
124
  });
124
125
  }
125
126
  startTheDoctor() {
126
- this.specStreamSubscription = this.specStreamChannel.subscribe(this.specStreamHandler());
127
- this.creditStreamSubscription = this.creditStreamChannel.subscribe(this.creditStreamHandler());
128
- this.errorStreamSubscription = this.errorChannel.subscribe(this.errorStreamHandler());
129
- this.mapChannels(SpecStreamChannel, CreditStreamChannel, WalletServiceChannel);
130
- this.deps.globalTaskController.init();
131
- this.deps.timelineController.init();
127
+ if (!this._doctorStarted) {
128
+ this.specStreamSubscription = this.specStreamChannel.subscribe(this.specStreamHandler());
129
+ this.creditStreamSubscription = this.creditStreamChannel.subscribe(this.creditStreamHandler());
130
+ this.errorStreamSubscription = this.errorChannel.subscribe(this.errorStreamHandler());
131
+ this.mapChannels(SpecStreamChannel, CreditStreamChannel, WalletServiceChannel);
132
+ this.deps.globalTaskController.init();
133
+ this.deps.timelineController.init();
134
+ this.deps.boostrap();
135
+ this._doctorStarted = true;
136
+ }
132
137
  this.confirmBrokerConnection();
133
138
  this.startBrokerHeartbeat();
134
- this.deps.boostrap();
135
139
  }
136
140
  specStreamHandler() {
137
141
  return (msg) => {
@@ -241,5 +245,6 @@ export class BrokerController extends EventTarget {
241
245
  this.creditStreamSubscription = null;
242
246
  this.errorStreamSubscription?.unsubscribe();
243
247
  this.errorStreamSubscription = null;
248
+ this._doctorStarted = false;
244
249
  }
245
250
  }
@@ -2,6 +2,7 @@ import type { DiagnosticControllerDeps } from "../interfaces/doctor-interfaces.j
2
2
  export declare class DiagnosticController extends EventTarget {
3
3
  private readonly deps;
4
4
  private oldScore;
5
+ private rebootGeneration;
5
6
  constructor(deps: DiagnosticControllerDeps);
6
7
  private createToast;
7
8
  private getMaxNodes;
@@ -14,7 +15,13 @@ export declare class DiagnosticController extends EventTarget {
14
15
  private handlePostLintOperations;
15
16
  private updateStatisticsAndNotify;
16
17
  private initializeExplorerIfNeeded;
18
+ private applyProblemsToUI;
19
+ private clearProblemState;
20
+ private resolveRootProblems;
21
+ private applyMarkersForViolations;
17
22
  private handleLintError;
18
23
  private handleArrayProblemResult;
19
24
  lintSpec(value: string, url?: string): Promise<void>;
25
+ loadStoredDiagnostics(): Promise<void>;
26
+ private applyPostLoadOperations;
20
27
  }
@@ -17,6 +17,7 @@ const NO_CREDIT_ERROR_URL = 'https://pb33f.io/errors/no-credit-remaining';
17
17
  export class DiagnosticController extends EventTarget {
18
18
  constructor(deps) {
19
19
  super();
20
+ this.rebootGeneration = 0;
20
21
  this.deps = deps;
21
22
  this.oldScore = 0;
22
23
  }
@@ -46,9 +47,6 @@ export class DiagnosticController extends EventTarget {
46
47
  this.deps.referenceMapBag?.reset();
47
48
  }
48
49
  }
49
- else {
50
- this.deps.hideUrlError();
51
- }
52
50
  let replaceResults = false;
53
51
  let currentPath = this.deps.rolodexActivePath;
54
52
  if (this.deps.rolodexActivePath === this.deps.rolodexRootPath || this.deps.rolodexActivePath === ROOT_PATH_ALIAS) {
@@ -85,11 +83,7 @@ export class DiagnosticController extends EventTarget {
85
83
  const r = [result];
86
84
  const lookupPath = normalizeRolodexPath(this.deps.rolodexActivePath);
87
85
  this.setMarkersWithRootProblems(r, lookupPath, rootProblems);
88
- this.deps.problemBag?.set(DocumentProblems, r);
89
- this.deps.problemList.problems = r;
90
- this.deps.problems = r;
91
- this.deps.updateSpecProblems(r);
92
- this.deps.problemsOverview.problems = this.deps.problemList.problemItems;
86
+ this.applyProblemsToUI(r);
93
87
  }
94
88
  handleParseError(result) {
95
89
  if (result.length === SINGLE_PROBLEM_COUNT && result[0].message.startsWith(PARSE_ERROR_PREFIX)) {
@@ -119,7 +113,7 @@ export class DiagnosticController extends EventTarget {
119
113
  this.deps.fetchRefMap(context.currentPath);
120
114
  }
121
115
  }
122
- async updateStatisticsAndNotify() {
116
+ async updateStatisticsAndNotify(suppressScoreToast = false) {
123
117
  try {
124
118
  const result = await LintingService.fetchStatistics();
125
119
  this.deps.diagnosticBag?.set(DiagnosticBag, result);
@@ -131,9 +125,9 @@ export class DiagnosticController extends EventTarget {
131
125
  }
132
126
  this.deps.problemsOverview.statistics = result;
133
127
  const settings = this.deps.settingsBag?.get(SettingsBag);
134
- if (!settings?.autoDiagnose) {
128
+ const newScore = result.statistics.overallScore;
129
+ if (!suppressScoreToast && !settings?.autoDiagnose) {
135
130
  if (this.deps.problemsOverview.statistics) {
136
- const newScore = result.statistics.overallScore;
137
131
  if (this.oldScore > newScore) {
138
132
  this.createToast(ToastType.SCOREDOWN, `Score went down by ${this.oldScore - newScore}%`, `Your score has decreased. It is now ${newScore}%`);
139
133
  }
@@ -142,11 +136,11 @@ export class DiagnosticController extends EventTarget {
142
136
  }
143
137
  }
144
138
  }
139
+ this.oldScore = newScore;
145
140
  }
146
141
  catch (e) {
142
+ this.deps.activity.hide();
147
143
  console.error("statistics service is down", e);
148
- const error = e;
149
- this.createToast(ToastType.ERROR, "Statistics request failed", error.detail);
150
144
  }
151
145
  }
152
146
  initializeExplorerIfNeeded() {
@@ -155,12 +149,44 @@ export class DiagnosticController extends EventTarget {
155
149
  this.deps.explorerBooted = true;
156
150
  }
157
151
  }
152
+ applyProblemsToUI(violations) {
153
+ this.deps.problemBag?.set(DocumentProblems, violations);
154
+ this.deps.problemList.problems = violations;
155
+ this.deps.problems = violations;
156
+ this.deps.updateSpecProblems(violations);
157
+ this.deps.problemsOverview.problems = this.deps.problemList.allProblemItems;
158
+ }
159
+ clearProblemState() {
160
+ this.deps.editor.clearAllMarkers();
161
+ this.deps.editor.breadcumb.isInvalid = false;
162
+ this.deps.editor.showBreadcrumb = false;
163
+ this.deps.problemList.isInvalid = false;
164
+ this.applyProblemsToUI([]);
165
+ }
166
+ resolveRootProblems() {
167
+ let rootProblems = this.deps.rolodexProblemMap.get(ROOT_PATH_ALIAS);
168
+ if (!this.deps.rolodexRoot) {
169
+ rootProblems = [];
170
+ }
171
+ return rootProblems;
172
+ }
173
+ applyMarkersForViolations(violations, rootProblems, replaceResults) {
174
+ const normalizedPath = normalizeRolodexPath(this.deps.rolodexActivePath);
175
+ if (this.deps.rolodexProblemMap.size > 0 && this.deps.rolodexProblemMap.has(normalizedPath)) {
176
+ this.setMarkersWithRootProblems(violations, normalizedPath, rootProblems);
177
+ }
178
+ else if (replaceResults) {
179
+ this.deps.editor.setMarkers(rootProblems && rootProblems.length > 0 ? rootProblems : []);
180
+ }
181
+ else {
182
+ return false;
183
+ }
184
+ return true;
185
+ }
158
186
  handleLintError(e, url) {
159
187
  this.deps.activity.hide();
160
188
  if (!url) {
161
- console.error("so sorry, the doctor cannot see you right now, the clinic is closed.");
162
189
  if (e) {
163
- console.error(e.detail);
164
190
  if (e.instance === NO_CREDIT_ERROR_URL) {
165
191
  this.deps.statusBar.visible = true;
166
192
  const text = this.deps.isAuthenticated
@@ -168,6 +194,9 @@ export class DiagnosticController extends EventTarget {
168
194
  : "Run out of credit, please authenticate for more or wait 24 hours.";
169
195
  this.createToast(ToastType.ERROR, "💰 Credit Exhausted!", text);
170
196
  }
197
+ else if (e.detail && e.detail.includes('read-only')) {
198
+ this.createToast(ToastType.WARNING, "Read-Only Workspace", e.detail);
199
+ }
171
200
  else {
172
201
  this.createToast(ToastType.ERROR, "Platform Error", e.detail);
173
202
  }
@@ -178,39 +207,19 @@ export class DiagnosticController extends EventTarget {
178
207
  }
179
208
  }
180
209
  handleArrayProblemResult(result, rootProblems, context) {
181
- let revive = true;
182
210
  if (result.length === EMPTY_PROBLEMS_COUNT) {
183
- this.deps.editor.clearAllMarkers();
184
- this.deps.editor.breadcumb.isInvalid = false;
185
- this.deps.editor.showBreadcrumb = false;
186
- revive = true;
187
- this.deps.problemList.isInvalid = false;
211
+ this.clearProblemState();
188
212
  }
189
213
  const isParseError = this.handleParseError(result);
190
214
  if (isParseError) {
191
215
  return { revive: false, shouldContinue: false };
192
216
  }
193
- const normalizedPath = normalizeRolodexPath(this.deps.rolodexActivePath);
194
- if (revive && this.deps.rolodexProblemMap.size > 0 && this.deps.rolodexProblemMap.has(normalizedPath)) {
195
- this.setMarkersWithRootProblems(result, normalizedPath, rootProblems);
196
- }
197
- else {
198
- if (context.replaceResults) {
199
- const markersToSet = rootProblems && rootProblems.length > 0
200
- ? rootProblems
201
- : [];
202
- this.deps.editor.setMarkers(markersToSet);
203
- }
204
- else {
205
- this.deps.fetchRefMap(context.currentPath);
206
- return { revive: true, shouldContinue: false };
207
- }
217
+ const markersApplied = this.applyMarkersForViolations(result, rootProblems, context.replaceResults);
218
+ if (!markersApplied) {
219
+ this.deps.fetchRefMap(context.currentPath);
220
+ return { revive: true, shouldContinue: false };
208
221
  }
209
- this.deps.problemBag?.set(DocumentProblems, result);
210
- this.deps.problemList.problems = result;
211
- this.deps.problems = result;
212
- this.deps.updateSpecProblems(result);
213
- this.deps.problemsOverview.problems = this.deps.problemList.problemItems;
222
+ this.applyProblemsToUI(result);
214
223
  if (this.deps.problemsOverview.statistics && result.length === SINGLE_PROBLEM_COUNT) {
215
224
  this.deps.problemsOverview.statistics.statistics.totalErrors = SINGLE_PROBLEM_COUNT;
216
225
  this.deps.problemsOverview.statistics.statistics.overallScore = UNPARSEABLE_SCORE;
@@ -228,10 +237,7 @@ export class DiagnosticController extends EventTarget {
228
237
  if (context.normalizedUrl) {
229
238
  this.deps.hideUrlError();
230
239
  }
231
- let rootProblems = this.deps.rolodexProblemMap.get(ROOT_PATH_ALIAS);
232
- if (!this.deps.rolodexRoot) {
233
- rootProblems = [];
234
- }
240
+ const rootProblems = this.resolveRootProblems();
235
241
  if (result && !Array.isArray(result)) {
236
242
  this.handleSingleProblemResult(result, rootProblems);
237
243
  }
@@ -252,4 +258,54 @@ export class DiagnosticController extends EventTarget {
252
258
  this.handleLintError(e, url);
253
259
  }
254
260
  }
261
+ async loadStoredDiagnostics() {
262
+ const generation = ++this.rebootGeneration;
263
+ this.deps.activity.show();
264
+ this.deps.editor.breadcumb.isInvalid = false;
265
+ try {
266
+ const [violationsResult] = await Promise.allSettled([
267
+ LintingService.fetchDiagnosisResults(),
268
+ this.fetchGraphAndHistory(),
269
+ ]);
270
+ if (this.rebootGeneration !== generation) {
271
+ return;
272
+ }
273
+ const violations = violationsResult.status === 'fulfilled' ? violationsResult.value : null;
274
+ if (violations !== null && violations.length > 0) {
275
+ this.deps.buildRolodexResultMap(violations);
276
+ if (this.handleParseError(violations)) {
277
+ this.applyPostLoadOperations('');
278
+ return;
279
+ }
280
+ const rootProblems = this.resolveRootProblems();
281
+ this.applyMarkersForViolations(violations, rootProblems, true);
282
+ this.applyProblemsToUI(violations);
283
+ this.deps.editor.revive();
284
+ }
285
+ else if (violations !== null) {
286
+ this.clearProblemState();
287
+ this.deps.editor.revive();
288
+ }
289
+ else {
290
+ this.deps.editor.clearAllMarkers();
291
+ this.applyProblemsToUI([]);
292
+ this.deps.editor.revive();
293
+ }
294
+ this.applyPostLoadOperations('');
295
+ }
296
+ catch (e) {
297
+ this.deps.activity.hide();
298
+ console.error("failed to load stored diagnostics", e);
299
+ }
300
+ }
301
+ applyPostLoadOperations(currentPath) {
302
+ if (this.deps.rolodexNeedsReset) {
303
+ this.deps.queryRolodex(currentPath);
304
+ }
305
+ else {
306
+ this.deps.fetchRefMap(currentPath);
307
+ }
308
+ this.initializeExplorerIfNeeded();
309
+ this.updateStatisticsAndNotify(true);
310
+ }
255
311
  }