querysub 0.459.0 → 0.461.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 (35) hide show
  1. package/.claude/settings.local.json +2 -1
  2. package/package.json +2 -2
  3. package/src/-b-authorities/dnsAuthority.ts +23 -15
  4. package/src/-g-core-values/NodeCapabilities.ts +3 -0
  5. package/src/-h-path-value-serialize/PathValueSerializer.ts +11 -3
  6. package/src/0-path-value-core/PathRouter.ts +6 -0
  7. package/src/0-path-value-core/PathWatcher.ts +1 -1
  8. package/src/0-path-value-core/pathValueCore.ts +4 -7
  9. package/src/1-path-client/RemoteWatcher.ts +8 -3
  10. package/src/1-path-client/pathValueClientWatcher.ts +3 -0
  11. package/src/2-proxy/PathValueProxyWatcher.ts +1 -1
  12. package/src/2-proxy/TransactionDelayer.ts +1 -1
  13. package/src/3-path-functions/PathFunctionHelpers.ts +13 -8
  14. package/src/3-path-functions/PathFunctionRunner.ts +2 -0
  15. package/src/4-querysub/Querysub.ts +0 -1
  16. package/src/4-querysub/QuerysubController.ts +1 -7
  17. package/src/config.ts +9 -0
  18. package/src/config2.ts +7 -1
  19. package/src/deployManager/components/MachinePicker.tsx +40 -0
  20. package/src/deployManager/components/ServiceDetailPage.tsx +2 -5
  21. package/src/deployManager/components/ServicesListPage.tsx +2 -0
  22. package/src/deployManager/components/Tools.tsx +165 -0
  23. package/src/deployManager/setupMachineMain.ts +74 -23
  24. package/src/diagnostics/charts/Chart.tsx +240 -0
  25. package/src/diagnostics/grossStats/GrossStatsPage.tsx +48 -83
  26. package/src/diagnostics/logs/IndexedLogs/BufferIndex.ts +22 -35
  27. package/src/diagnostics/logs/IndexedLogs/BufferUnitIndex.ts +39 -47
  28. package/src/diagnostics/logs/IndexedLogs/IndexedLogs.ts +3 -3
  29. package/src/diagnostics/logs/IndexedLogs/MCPIndexedLogs.ts +18 -3
  30. package/src/diagnostics/logs/IndexedLogs/MCPIndexedLogsEntry.ts +1 -0
  31. package/src/diagnostics/managementPages.tsx +58 -58
  32. package/src/diagnostics/misc-pages/DNSPage.tsx +344 -0
  33. package/test.ts +46 -70
  34. package/src/diagnostics/AuditLogPage.tsx +0 -147
  35. package/src/diagnostics/NodeConnectionsPage.tsx +0 -167
@@ -1,147 +0,0 @@
1
- import { SocketFunction } from "socket-function/SocketFunction";
2
- import { qreact } from "../4-dom/qreact";
3
- import { assertIsManagementUser } from "./managementPages";
4
- import { css } from "typesafecss";
5
- import { getSyncedController } from "../library-components/SyncedController";
6
- import { DebugLog, DebugLogController, getLogHistoryEquals, getLogHistoryIncludes } from "../0-path-value-core/auditLogs";
7
- import { remoteWatcher } from "../1-path-client/RemoteWatcher";
8
- import { getBrowserUrlNode, getOwnNodeId } from "../-f-node-discovery/NodeDiscovery";
9
- import { nextId, sort } from "socket-function/src/misc";
10
- import { t } from "../2-proxy/schema2";
11
- import { InputLabelURL } from "../library-components/InputLabel";
12
- import { URLParam } from "../library-components/URLParam";
13
- import { Table } from "../5-diagnostics/Table";
14
- import { ObjectDisplay } from "./logs/ObjectDisplay";
15
- import { PathRouter } from "../0-path-value-core/PathRouter";
16
-
17
- /**
18
- TODO:
19
- 1) Support watching multiple paths at once
20
- 2) Show extra metadata for the paths
21
- - Current value (raw, as in, don't sync it)
22
- - If it is synced
23
- - The authority of it
24
- - An expander which shows a table of the full history of values, with valid state, etc
25
- */
26
-
27
- type DebugLogWithSource = DebugLog & {
28
- sourceType: "local" | "remote";
29
- sourceNodeId: string;
30
- }
31
-
32
- let path = new URLParam("path", "");
33
- let includeDescendants = new URLParam("includeDescendants", false);
34
- export class AuditLogPage extends qreact.Component {
35
- loadId = nextId();
36
- state = t.state({
37
- loadedId: t.string
38
- });
39
- render() {
40
- let logs: DebugLogWithSource[] = [];
41
- let loaded = this.loadId === this.state.loadedId;
42
- if (loaded) {
43
- let obj = auditLogController(getBrowserUrlNode()).getPathHistory({
44
- path: path.value,
45
- includeDescendants: includeDescendants.value,
46
- });
47
- if (obj) {
48
- logs = obj.fullLogs;
49
- }
50
- }
51
- return (
52
- <div class={css.pad2(10).vbox(10).fillWidth}>
53
- <InputLabelURL
54
- label="Path"
55
- url={path}
56
- fillWidth
57
- onChange={() => this.loadId = nextId()}
58
- />
59
- <InputLabelURL
60
- label="Include Descendants"
61
- url={includeDescendants}
62
- checkbox
63
- onChange={() => this.loadId = nextId()}
64
- />
65
- {!loaded && <button onClick={() => this.state.loadedId = this.loadId}>Load</button>}
66
- <Table
67
- rows={logs}
68
- columns={{
69
- type: {},
70
- time: {},
71
- sourceType: {},
72
- sourceNodeId: {},
73
- values: {
74
- formatter(value) {
75
- return <ObjectDisplay value={value} />;
76
- },
77
- },
78
- }}
79
- />
80
- </div>
81
- );
82
- }
83
- }
84
-
85
-
86
- class AuditLogControllerBase {
87
- public async getPathHistory(config: {
88
- path: string;
89
- includeDescendants?: boolean;
90
- }) {
91
- let { path, includeDescendants } = config;
92
- let authorityNodeId = remoteWatcher.getExistingWatchRemoteNodeId(path);
93
- if (!authorityNodeId) {
94
- authorityNodeId = await PathRouter.getReadyAuthority(path)?.nodeId;
95
- }
96
- let logs: DebugLog[] = [];
97
- let remoteLogs: DebugLog[] = [];
98
- if (includeDescendants) {
99
- // Also look for the parent, so we can capture keys() syncs as well
100
- // (this should give us child paths too, because that's how includes works)
101
- logs = getLogHistoryIncludes(path);
102
- if (authorityNodeId) {
103
- remoteLogs = await DebugLogController.nodes[authorityNodeId].getLogHistoryEquals(path);
104
- }
105
- } else {
106
- logs = getLogHistoryEquals(path);
107
- if (authorityNodeId) {
108
- remoteLogs = await DebugLogController.nodes[authorityNodeId].getLogHistoryEquals(path);
109
- }
110
- }
111
-
112
- let fullLogs: DebugLogWithSource[] = [];
113
- let ownNodeId = getOwnNodeId();
114
- for (let log of logs) {
115
- fullLogs.push({
116
- ...log,
117
- sourceType: "local",
118
- sourceNodeId: ownNodeId,
119
- });
120
- }
121
- if (authorityNodeId) {
122
- for (let log of remoteLogs) {
123
- fullLogs.push({
124
- ...log,
125
- sourceType: "remote",
126
- sourceNodeId: authorityNodeId,
127
- });
128
- }
129
- }
130
- sort(fullLogs, x => x.time);
131
- return {
132
- fullLogs,
133
- };
134
- }
135
- }
136
-
137
- export const AuditLogController = SocketFunction.register(
138
- "AuditLogController-bf798faf-c803-4add-ac2c-99d0f44e753a",
139
- new AuditLogControllerBase(),
140
- () => ({
141
- getPathHistory: {},
142
- }),
143
- () => ({
144
- hooks: [assertIsManagementUser],
145
- })
146
- );
147
- export const auditLogController = getSyncedController(AuditLogController);
@@ -1,167 +0,0 @@
1
- import { SocketFunction } from "socket-function/SocketFunction";
2
- import { qreact } from "../4-dom/qreact";
3
- import { assertIsManagementUser } from "./managementPages";
4
- import { css } from "typesafecss";
5
- import { getSyncedController } from "../library-components/SyncedController";
6
- import { getAllNodeIds, getBrowserUrlNode } from "../-f-node-discovery/NodeDiscovery";
7
- import { debugGetAllCallFactories } from "socket-function/src/nodeCache";
8
- import { debugNodeId } from "../-c-identity/IdentityController";
9
- import { fastHash } from "../misc/hash";
10
- import { NodeCapabilitiesController } from "../-g-core-values/NodeCapabilities";
11
- import { sort } from "socket-function/src/misc";
12
-
13
-
14
-
15
- function getColorForNodeId(friendlyNodeId: string): string {
16
- let hash = fastHash(friendlyNodeId);
17
- let hue = hash % 360;
18
- return `hsl(${hue}, 70%, 60%)`;
19
- }
20
-
21
- export class NodeConnectionsPage extends qreact.Component {
22
- render() {
23
- let browserNode = getBrowserUrlNode();
24
- let controller = nodeConnectionsController(browserNode);
25
-
26
- let nodeIds = controller.getAllNodeIds();
27
- if (!nodeIds) {
28
- return <div class={css.pad2(10)}>Loading...</div>;
29
- }
30
-
31
- let connectableNodes: Array<{ nodeId: string; friendlyNodeId: string; entryPoint: string | undefined; connections: Array<{ nodeId: string; friendlyNodeId: string }> }> = [];
32
- let nonConnectableNodes: string[] = [];
33
-
34
- for (let nodeId of nodeIds) {
35
- try {
36
- let result = controller.getNodeConnections_forBrowser(nodeId);
37
- if (result) {
38
- let friendlyNodeId = debugNodeId(nodeId);
39
- let entryPoint: string | undefined;
40
- try {
41
- entryPoint = controller.getEntryPoint_forBrowser(nodeId);
42
- } catch (e) {
43
- entryPoint = undefined;
44
- }
45
- connectableNodes.push({
46
- nodeId,
47
- friendlyNodeId,
48
- entryPoint,
49
- connections: result.connections,
50
- });
51
- }
52
- } catch (e) {
53
- nonConnectableNodes.push(nodeId);
54
- }
55
- }
56
-
57
- return (
58
- <div class={css.pad2(10).vbox(20).fillWidth}>
59
- <h1>Connectable Nodes</h1>
60
- <div class={css.hbox(20).wrap.fillWidth}>
61
- {connectableNodes.map(node => {
62
- let color = getColorForNodeId(node.friendlyNodeId);
63
- return (
64
- <div class={css.vbox(5).pad2(10).maxHeight(400).overflowAuto.bord(1, { h: 0, s: 0, l: 80 })}>
65
- <div class={css.vbox(3)}>
66
- {node.entryPoint && (
67
- <div class={css.fontSize(14).fontWeight("bold")}>
68
- {node.entryPoint}
69
- </div>
70
- )}
71
- <div class={css.hbox(5)}>
72
- <span class={css.background(color).pad2(4, 2).fontWeight("bold")}>
73
- {node.friendlyNodeId}
74
- </span>
75
- <span class={css.color("gray").fontSize(12)}>
76
- ({node.nodeId})
77
- </span>
78
- </div>
79
- </div>
80
- <div class={css.vbox(3).paddingLeft(20)}>
81
- {node.connections.length === 0 && (
82
- <div class={css.color("gray")}>No connections</div>
83
- )}
84
- {node.connections.map(conn => {
85
- let connColor = getColorForNodeId(conn.friendlyNodeId);
86
- return (
87
- <div class={css.hbox(5)}>
88
- <span>→ Connected to:</span>
89
- <span class={css.background(connColor).pad2(4, 2).fontWeight("bold")}>
90
- {conn.friendlyNodeId}
91
- </span>
92
- <span class={css.color("gray").fontSize(12)}>
93
- ({conn.nodeId})
94
- </span>
95
- </div>
96
- );
97
- })}
98
- </div>
99
- </div>
100
- );
101
- })}
102
- </div>
103
-
104
- <div class={css.vbox(10).fillWidth}>
105
- <h1>Non-Connectable Nodes</h1>
106
- <div class={css.vbox(5).pad2(10).maxHeight(600).overflowAuto.bord(1, { h: 0, s: 0, l: 80 })}>
107
- {nonConnectableNodes.map(nodeId => {
108
- let friendlyNodeId = debugNodeId(nodeId);
109
- return (
110
- <div class={css.hbox(5)}>
111
- <span class={css.background("lightgray").pad2(4, 2).fontWeight("bold")}>
112
- {friendlyNodeId}
113
- </span>
114
- <span class={css.color("gray").fontSize(12)}>
115
- ({nodeId})
116
- </span>
117
- <span class={css.color("gray")}>- Can't connect</span>
118
- </div>
119
- );
120
- })}
121
- </div>
122
- </div>
123
- </div>
124
- );
125
- }
126
- }
127
-
128
- class NodeConnectionsControllerBase {
129
- public async getNodeConnections() {
130
- let factories = debugGetAllCallFactories();
131
- let connections = factories.filter(x => x.isConnected).map(factory => ({
132
- nodeId: factory.nodeId,
133
- friendlyNodeId: debugNodeId(factory.nodeId),
134
- }));
135
- return { connections };
136
- }
137
-
138
- public async getNodeConnections_forBrowser(nodeId: string) {
139
- let result = await NodeConnectionsController.nodes[nodeId].getNodeConnections();
140
- sort(result.connections, x => x.friendlyNodeId);
141
- return result;
142
- }
143
-
144
- public async getEntryPoint_forBrowser(nodeId: string) {
145
- return (await NodeCapabilitiesController.nodes[nodeId].getMetadata()).entryPoint;
146
- }
147
-
148
- public async getAllNodeIds() {
149
- return await getAllNodeIds();
150
- }
151
- }
152
-
153
- export const NodeConnectionsController = SocketFunction.register(
154
- "NodeConnectionsController-8f3e2a1b-4c5d-4f2e-9a3b-7c8d1e2f3a4b",
155
- new NodeConnectionsControllerBase(),
156
- () => ({
157
- getNodeConnections: {},
158
- getNodeConnections_forBrowser: {},
159
- getEntryPoint_forBrowser: {},
160
- getAllNodeIds: {},
161
- }),
162
- () => ({
163
- hooks: [assertIsManagementUser],
164
- })
165
- );
166
-
167
- export const nodeConnectionsController = getSyncedController(NodeConnectionsController);