@hyperdrive.bot/fleet-server 0.3.101 → 0.3.102
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/dist/server/server/ingestion/service.d.ts +9 -0
- package/dist/server/server/ingestion/service.js +38 -4
- package/dist/server/web-ui/_expo/static/js/web/{index-cd94e627d4feefdc781faccc3da11ade.js → index-ea21f43eebd5b96bf3cb1be6496567ed.js} +7 -7
- package/dist/server/web-ui/_expo/static/js/web/index-ea21f43eebd5b96bf3cb1be6496567ed.js.br +0 -0
- package/dist/server/web-ui/_expo/static/js/web/index-ea21f43eebd5b96bf3cb1be6496567ed.js.gz +0 -0
- package/dist/server/web-ui/_expo/static/js/web/{index-cd94e627d4feefdc781faccc3da11ade.js.map.br → index-ea21f43eebd5b96bf3cb1be6496567ed.js.map.br} +0 -0
- package/dist/server/web-ui/_expo/static/js/web/{index-cd94e627d4feefdc781faccc3da11ade.js.map.gz → index-ea21f43eebd5b96bf3cb1be6496567ed.js.map.gz} +0 -0
- package/dist/server/web-ui/index.html +1 -1
- package/dist/server/web-ui/index.html.br +0 -0
- package/dist/server/web-ui/index.html.gz +0 -0
- package/package.json +6 -6
- package/dist/server/web-ui/_expo/static/js/web/index-cd94e627d4feefdc781faccc3da11ade.js.br +0 -0
- package/dist/server/web-ui/_expo/static/js/web/index-cd94e627d4feefdc781faccc3da11ade.js.gz +0 -0
|
@@ -66,6 +66,15 @@ export declare class IngestionService {
|
|
|
66
66
|
*/
|
|
67
67
|
connect(kind: SourceKind, appSlug: string): Promise<SourceConnectResult>;
|
|
68
68
|
list(): Promise<SourceSummary[]>;
|
|
69
|
+
/**
|
|
70
|
+
* sourceId -> number of filters watching it.
|
|
71
|
+
*
|
|
72
|
+
* Best-effort: a filter store that cannot be read must not blank the sources
|
|
73
|
+
* list, because the count is a decoration on a row whose real subject is the
|
|
74
|
+
* connection. Degrades to an empty map, so every row reports zero rather than
|
|
75
|
+
* the whole screen reporting nothing.
|
|
76
|
+
*/
|
|
77
|
+
private filterCounts;
|
|
69
78
|
/** Check one source and persist the verdict. Null when the source is gone. */
|
|
70
79
|
check(sourceId: string): Promise<SourceSummary | null>;
|
|
71
80
|
private hasConfiguredGateway;
|
|
@@ -130,11 +130,37 @@ export class IngestionService {
|
|
|
130
130
|
lastError: null,
|
|
131
131
|
});
|
|
132
132
|
this.startConnectPoll(source);
|
|
133
|
-
|
|
133
|
+
// 0 is correct and not a placeholder: a source created moments ago cannot
|
|
134
|
+
// have a filter bound to it yet.
|
|
135
|
+
return { source: this.toSummary(source, 0), redirectUrl: handoff.redirectUrl };
|
|
134
136
|
}
|
|
135
137
|
async list() {
|
|
136
138
|
const sources = await this.store.list();
|
|
137
|
-
|
|
139
|
+
// ONE filter read for the whole list, not one per source. `list()` is
|
|
140
|
+
// readdir + parse of every filter file, so calling it inside the map would
|
|
141
|
+
// make a nine-source list do nine full scans of the same directory.
|
|
142
|
+
const counts = await this.filterCounts();
|
|
143
|
+
return sources.map((source) => this.toSummary(source, counts.get(source.id) ?? 0));
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* sourceId -> number of filters watching it.
|
|
147
|
+
*
|
|
148
|
+
* Best-effort: a filter store that cannot be read must not blank the sources
|
|
149
|
+
* list, because the count is a decoration on a row whose real subject is the
|
|
150
|
+
* connection. Degrades to an empty map, so every row reports zero rather than
|
|
151
|
+
* the whole screen reporting nothing.
|
|
152
|
+
*/
|
|
153
|
+
async filterCounts() {
|
|
154
|
+
const counts = new Map();
|
|
155
|
+
try {
|
|
156
|
+
for (const filter of await this.filterStore.list()) {
|
|
157
|
+
counts.set(filter.sourceId, (counts.get(filter.sourceId) ?? 0) + 1);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
this.logger.warn({ err: error }, "Filter count unavailable; reporting zero per source");
|
|
162
|
+
}
|
|
163
|
+
return counts;
|
|
138
164
|
}
|
|
139
165
|
/** Check one source and persist the verdict. Null when the source is gone. */
|
|
140
166
|
async check(sourceId) {
|
|
@@ -144,7 +170,14 @@ export class IngestionService {
|
|
|
144
170
|
}
|
|
145
171
|
const health = await checkSource(source, this.healthDeps());
|
|
146
172
|
const updated = await this.persistHealth(sourceId, health);
|
|
147
|
-
|
|
173
|
+
if (!updated) {
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
// Counted, not defaulted: `check` returns an existing source, and reporting
|
|
177
|
+
// zero filters for a source that has some would let a re-check silently
|
|
178
|
+
// blank the row's work line.
|
|
179
|
+
const counts = await this.filterCounts();
|
|
180
|
+
return this.toSummary(updated, counts.get(updated.id) ?? 0);
|
|
148
181
|
}
|
|
149
182
|
hasConfiguredGateway() {
|
|
150
183
|
return SOURCE_CAPABLE_KINDS.some((kind) => this.resolveGateway(kind).configured);
|
|
@@ -421,7 +454,7 @@ export class IngestionService {
|
|
|
421
454
|
* StoredSource later reaches the wire the day it is added, with no diff on
|
|
422
455
|
* this file to review.
|
|
423
456
|
*/
|
|
424
|
-
toSummary(source) {
|
|
457
|
+
toSummary(source, filterCount = 0) {
|
|
425
458
|
return {
|
|
426
459
|
id: source.id,
|
|
427
460
|
kind: source.kind,
|
|
@@ -435,6 +468,7 @@ export class IngestionService {
|
|
|
435
468
|
updatedAt: source.updatedAt,
|
|
436
469
|
lastCheckedAt: source.lastCheckedAt,
|
|
437
470
|
lastError: source.lastError,
|
|
471
|
+
filterCount,
|
|
438
472
|
};
|
|
439
473
|
}
|
|
440
474
|
}
|