querysub 0.516.0 → 0.517.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.
- package/package.json +1 -1
- package/src/4-deploy/edgeBootstrap.ts +9 -0
- package/src/diagnostics/logs/errorNotifications2/ErrorNotificationPage.tsx +1 -1
- package/src/diagnostics/logs/errorNotifications2/ErrorWarning.tsx +16 -3
- package/src/diagnostics/managementPages.tsx +18 -17
- package/src/library-components/EdgeNodeSelector.tsx +10 -1
package/package.json
CHANGED
|
@@ -475,6 +475,15 @@ async function edgeNodeFunction(config: {
|
|
|
475
475
|
// The url override wins over everything (including the IP domain default). If the host isn't in the list, it is ignored.
|
|
476
476
|
{
|
|
477
477
|
let overrideHost = new URL(document.location.href).searchParams.get("edgenode");
|
|
478
|
+
if (overrideHost) {
|
|
479
|
+
// The URLParam system rewrites search params JSON encoded (strings get quotation marks), so decode the same way it does
|
|
480
|
+
try {
|
|
481
|
+
let parsed = JSON.parse(overrideHost);
|
|
482
|
+
if (typeof parsed === "string") {
|
|
483
|
+
overrideHost = parsed;
|
|
484
|
+
}
|
|
485
|
+
} catch { }
|
|
486
|
+
}
|
|
478
487
|
if (overrideHost) {
|
|
479
488
|
let overrideNode = edgeNodes.find(x => x.host === overrideHost);
|
|
480
489
|
if (overrideNode) {
|
|
@@ -4,8 +4,9 @@ import { css } from "typesafecss";
|
|
|
4
4
|
import { SocketFunction } from "socket-function/SocketFunction";
|
|
5
5
|
import { ATag } from "../../../library-components/ATag";
|
|
6
6
|
import { managementPageURL, showingManagementURL } from "../../managementPages";
|
|
7
|
-
import { LogDatumRenderer } from "./ErrorNotificationPage";
|
|
7
|
+
import { getMatcher, LogDatumRenderer } from "./ErrorNotificationPage";
|
|
8
8
|
import { getErrorNotificationsManager } from "./errorWatcher";
|
|
9
|
+
import { LogDatum } from "../diskLogger";
|
|
9
10
|
import { TicketsController } from "../errorTickets/tickets";
|
|
10
11
|
import { STATE_HUES, ticketFilterURL } from "../errorTickets/TicketPage";
|
|
11
12
|
import { isTicketFinished, TicketState, TICKET_STATES } from "../errorTickets/ticketTypes";
|
|
@@ -49,9 +50,21 @@ export class ErrorWarning extends qreact.Component {
|
|
|
49
50
|
render() {
|
|
50
51
|
let ticketCounts = this.renderTicketCounts();
|
|
51
52
|
|
|
53
|
+
// Errors that already have a ticket in an open (not finished) state are hidden here — there's no point telling the user about a bug that is already under investigation
|
|
54
|
+
let openTicketPatterns: string[] = [];
|
|
55
|
+
for (let ticket of TicketsController(SocketFunction.browserNodeId()).getTickets() || []) {
|
|
56
|
+
if (isTicketFinished(ticket.state)) continue;
|
|
57
|
+
if (!ticket.suppressionPattern) continue;
|
|
58
|
+
openTicketPatterns.push(ticket.suppressionPattern);
|
|
59
|
+
}
|
|
60
|
+
const isCoveredByOpenTicket = (datum: LogDatum) => {
|
|
61
|
+
let errorBuffer = Buffer.from(JSON.stringify(datum));
|
|
62
|
+
return openTicketPatterns.some(pattern => getMatcher(pattern)(errorBuffer));
|
|
63
|
+
};
|
|
64
|
+
|
|
52
65
|
let errorWarning: preact.ComponentChild = undefined;
|
|
53
|
-
|
|
54
|
-
|
|
66
|
+
let firstError = !this.manager.state.isLoading && this.manager.state.unmatchedErrors.find(x => !isCoveredByOpenTicket(x)) || undefined;
|
|
67
|
+
if (firstError) {
|
|
55
68
|
errorWarning = <div className={css.hbox(4).alignItems("start").hsl(0, 0, 90).bord2(0, 0, 85).pad2(4, 2).hslcolor(0, 0, 0)}>
|
|
56
69
|
<ATag className={css.paddingTop(5).flexShrink0} values={[
|
|
57
70
|
showingManagementURL.getOverride(true),
|
|
@@ -80,6 +80,23 @@ export async function registerManagementPages2(config: {
|
|
|
80
80
|
let inputPages: typeof config.pages = [];
|
|
81
81
|
|
|
82
82
|
|
|
83
|
+
inputPages.push({
|
|
84
|
+
title: "Routing Table",
|
|
85
|
+
componentName: "AuthoritySpecPage",
|
|
86
|
+
controllerName: "AuthoritySpecPageController",
|
|
87
|
+
getModule: () => import("./misc-pages/AuthoritySpecPage"),
|
|
88
|
+
});
|
|
89
|
+
inputPages.push({
|
|
90
|
+
title: "LOG VIEWER",
|
|
91
|
+
componentName: "LogViewer3",
|
|
92
|
+
getModule: () => import("./logs/IndexedLogs/LogViewer3"),
|
|
93
|
+
});
|
|
94
|
+
inputPages.push({
|
|
95
|
+
title: "Tickets",
|
|
96
|
+
componentName: "TicketPage",
|
|
97
|
+
controllerName: "",
|
|
98
|
+
getModule: () => import("./logs/errorTickets/TicketPage"),
|
|
99
|
+
});
|
|
83
100
|
// IMPORTANT! The controller name has to be the name of the controller in the file. No human would just randomly put some junk there, but the AI keeps putting random junk there and being surprised when they get an error because that controller doesn't actually exist in that file.
|
|
84
101
|
inputPages.push({
|
|
85
102
|
title: "Machines",
|
|
@@ -111,12 +128,6 @@ export async function registerManagementPages2(config: {
|
|
|
111
128
|
controllerName: "SnapshotViewerController",
|
|
112
129
|
getModule: () => import("./misc-pages/SnapshotViewer"),
|
|
113
130
|
});
|
|
114
|
-
inputPages.push({
|
|
115
|
-
title: "Routing Table",
|
|
116
|
-
componentName: "AuthoritySpecPage",
|
|
117
|
-
controllerName: "AuthoritySpecPageController",
|
|
118
|
-
getModule: () => import("./misc-pages/AuthoritySpecPage"),
|
|
119
|
-
});
|
|
120
131
|
inputPages.push({
|
|
121
132
|
title: "DNS",
|
|
122
133
|
componentName: "DNSPage",
|
|
@@ -134,11 +145,6 @@ export async function registerManagementPages2(config: {
|
|
|
134
145
|
componentName: "FunctionCaptureAnalyzePage",
|
|
135
146
|
getModule: () => import("./misc-pages/FunctionCaptureAnalyzePage"),
|
|
136
147
|
});
|
|
137
|
-
inputPages.push({
|
|
138
|
-
title: "LOG VIEWER",
|
|
139
|
-
componentName: "LogViewer3",
|
|
140
|
-
getModule: () => import("./logs/IndexedLogs/LogViewer3"),
|
|
141
|
-
});
|
|
142
148
|
// It's really sad to comment out the life cycles page, but I'm just never going to use it, it's just too slow and too annoying. It's easier to get the AI to search stuff.
|
|
143
149
|
// inputPages.push({
|
|
144
150
|
// title: "Life Cycles",
|
|
@@ -152,12 +158,7 @@ export async function registerManagementPages2(config: {
|
|
|
152
158
|
controllerName: "",
|
|
153
159
|
getModule: () => import("./logs/errorNotifications2/ErrorNotificationPage"),
|
|
154
160
|
});
|
|
155
|
-
|
|
156
|
-
title: "Tickets",
|
|
157
|
-
componentName: "TicketPage",
|
|
158
|
-
controllerName: "",
|
|
159
|
-
getModule: () => import("./logs/errorTickets/TicketPage"),
|
|
160
|
-
});
|
|
161
|
+
|
|
161
162
|
// NOTE: Even if we never use this, it is needed if a server or site is bootstrapping. However, they should probably include this in their own header dynamically as well.
|
|
162
163
|
inputPages.push({
|
|
163
164
|
title: "Security",
|
|
@@ -17,12 +17,21 @@ export class EdgeNodeSelector extends qreact.Component<{}> {
|
|
|
17
17
|
let stats = globalThis.EDGE_NODE_STATS;
|
|
18
18
|
const booted = (globalThis as any).BOOTED_EDGE_NODE as EdgeNodeConfig | undefined;
|
|
19
19
|
if (!booted) return undefined;
|
|
20
|
+
// The URLParam system rewrites search params JSON encoded (strings get quotation marks), so read/write the same way it does
|
|
20
21
|
let forced = new URL(document.location.href).searchParams.get(EDGE_NODE_URL_PARAM) || "";
|
|
22
|
+
if (forced) {
|
|
23
|
+
try {
|
|
24
|
+
let parsed = JSON.parse(forced);
|
|
25
|
+
if (typeof parsed === "string") {
|
|
26
|
+
forced = parsed;
|
|
27
|
+
}
|
|
28
|
+
} catch { }
|
|
29
|
+
}
|
|
21
30
|
|
|
22
31
|
const setEdgeNode = (host: string) => {
|
|
23
32
|
let url = new URL(document.location.href);
|
|
24
33
|
if (host) {
|
|
25
|
-
url.searchParams.set(EDGE_NODE_URL_PARAM, host);
|
|
34
|
+
url.searchParams.set(EDGE_NODE_URL_PARAM, JSON.stringify(host));
|
|
26
35
|
} else {
|
|
27
36
|
url.searchParams.delete(EDGE_NODE_URL_PARAM);
|
|
28
37
|
}
|