ed-mcp 0.5.0 → 0.5.1
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/index.js +62 -22
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -28752,7 +28752,7 @@ async function canonical(p) {
|
|
|
28752
28752
|
}
|
|
28753
28753
|
|
|
28754
28754
|
// src/version.ts
|
|
28755
|
-
var VERSION = "0.5.
|
|
28755
|
+
var VERSION = "0.5.1";
|
|
28756
28756
|
|
|
28757
28757
|
// src/config.ts
|
|
28758
28758
|
var ConfigError = class extends Error {
|
|
@@ -32201,12 +32201,32 @@ var SweepCache = class {
|
|
|
32201
32201
|
find(centre, radiusLy) {
|
|
32202
32202
|
this.dropExpired();
|
|
32203
32203
|
const hit = this.sweeps.find(
|
|
32204
|
-
(s) => distanceLy(s.centre, centre) + radiusLy <= s.
|
|
32204
|
+
(s) => distanceLy(s.centre, centre) + radiusLy <= s.coveredLy + 1e-9
|
|
32205
32205
|
);
|
|
32206
32206
|
return hit?.systems.filter((s) => distanceLy(s.coords, centre) <= radiusLy);
|
|
32207
32207
|
}
|
|
32208
|
-
add(centre, radiusLy, systems) {
|
|
32209
|
-
this.sweeps.
|
|
32208
|
+
add(centre, radiusLy, systems, key) {
|
|
32209
|
+
const storedAt = key ? this.sweeps.find((s) => s.resume?.key === key)?.storedAt : void 0;
|
|
32210
|
+
if (key) this.sweeps = this.sweeps.filter((s) => s.resume?.key !== key);
|
|
32211
|
+
this.push({ centre, coveredLy: radiusLy, systems, storedAt: storedAt ?? this.now() });
|
|
32212
|
+
}
|
|
32213
|
+
savePartial(p) {
|
|
32214
|
+
const storedAt = this.sweeps.find((s) => s.resume?.key === p.key)?.storedAt ?? this.now();
|
|
32215
|
+
this.sweeps = this.sweeps.filter((s) => s.resume?.key !== p.key);
|
|
32216
|
+
this.push({
|
|
32217
|
+
centre: p.centre,
|
|
32218
|
+
coveredLy: p.coveredLy,
|
|
32219
|
+
systems: p.systems,
|
|
32220
|
+
storedAt,
|
|
32221
|
+
resume: p
|
|
32222
|
+
});
|
|
32223
|
+
}
|
|
32224
|
+
partial(key) {
|
|
32225
|
+
this.dropExpired();
|
|
32226
|
+
return this.sweeps.find((s) => s.resume?.key === key)?.resume;
|
|
32227
|
+
}
|
|
32228
|
+
push(s) {
|
|
32229
|
+
this.sweeps.push(s);
|
|
32210
32230
|
while (this.sweeps.length > this.maxSweeps) this.sweeps.shift();
|
|
32211
32231
|
}
|
|
32212
32232
|
clear() {
|
|
@@ -32216,7 +32236,7 @@ var SweepCache = class {
|
|
|
32216
32236
|
}
|
|
32217
32237
|
stats() {
|
|
32218
32238
|
this.dropExpired();
|
|
32219
|
-
const oldest = this.sweeps
|
|
32239
|
+
const oldest = this.sweeps.length ? Math.min(...this.sweeps.map((s) => s.storedAt)) : void 0;
|
|
32220
32240
|
return {
|
|
32221
32241
|
name: this.name,
|
|
32222
32242
|
entries: this.sweeps.length,
|
|
@@ -32430,25 +32450,27 @@ var SpanshClient = class {
|
|
|
32430
32450
|
);
|
|
32431
32451
|
return detail.record.needs_permit ?? null;
|
|
32432
32452
|
}
|
|
32433
|
-
/** Populated systems within radiusLy of near. Stops paging at opts.deadline; a partial result is
|
|
32453
|
+
/** Populated systems within radiusLy of near. Stops paging at opts.deadline; a partial result is cached and the next call resumes it. */
|
|
32434
32454
|
async populatedSystems(near, radiusLy, opts = {}) {
|
|
32435
32455
|
const centre = (await this.system(near, 0)).coords;
|
|
32436
32456
|
const cached2 = this.sweepCache.find(centre, radiusLy);
|
|
32437
|
-
if (cached2)
|
|
32457
|
+
if (cached2)
|
|
32458
|
+
return { centre, systems: cached2, total: cached2.length, partial: false, coveredLy: radiusLy };
|
|
32438
32459
|
const key = `${near.toLowerCase()}:${radiusLy}`;
|
|
32439
32460
|
let running = this.sweeps.get(key);
|
|
32440
32461
|
if (!running) {
|
|
32441
|
-
running = this.sweepPages(near, radiusLy, centre, opts).finally(
|
|
32462
|
+
running = this.sweepPages(near, radiusLy, centre, key, opts).finally(
|
|
32442
32463
|
() => this.sweeps.delete(key)
|
|
32443
32464
|
);
|
|
32444
32465
|
this.sweeps.set(key, running);
|
|
32445
32466
|
}
|
|
32446
32467
|
return running;
|
|
32447
32468
|
}
|
|
32448
|
-
async sweepPages(near, radiusLy, centre, opts) {
|
|
32449
|
-
const
|
|
32450
|
-
const
|
|
32451
|
-
|
|
32469
|
+
async sweepPages(near, radiusLy, centre, key, opts) {
|
|
32470
|
+
const resume = this.sweepCache.partial(key);
|
|
32471
|
+
const systems = resume ? [...resume.systems] : [];
|
|
32472
|
+
const seen = new Set(systems.map((s) => s.id64));
|
|
32473
|
+
let total = resume?.total ?? 0;
|
|
32452
32474
|
let partial2 = false;
|
|
32453
32475
|
for (let page2 = 0; ; page2++) {
|
|
32454
32476
|
if (page2 > 0 && opts.deadline !== void 0 && this.now() >= opts.deadline) {
|
|
@@ -32457,7 +32479,8 @@ var SpanshClient = class {
|
|
|
32457
32479
|
}
|
|
32458
32480
|
const body = {
|
|
32459
32481
|
filters: {
|
|
32460
|
-
|
|
32482
|
+
// Resuming by distance, not page: Spansh's list can shift between calls an hour apart.
|
|
32483
|
+
distance: { min: resume?.coveredLy ?? 0, max: radiusLy },
|
|
32461
32484
|
population: { comparison: "<=>", value: [1, 1e11] }
|
|
32462
32485
|
},
|
|
32463
32486
|
sort: [{ distance: { direction: "asc" } }],
|
|
@@ -32476,7 +32499,7 @@ var SpanshClient = class {
|
|
|
32476
32499
|
}
|
|
32477
32500
|
throw err;
|
|
32478
32501
|
}
|
|
32479
|
-
total = res.count;
|
|
32502
|
+
if (!resume) total = res.count;
|
|
32480
32503
|
const results = res.results ?? [];
|
|
32481
32504
|
for (const raw of results) {
|
|
32482
32505
|
const s = mapSystem(raw);
|
|
@@ -32487,8 +32510,17 @@ var SpanshClient = class {
|
|
|
32487
32510
|
}
|
|
32488
32511
|
if (results.length < SWEEP_PAGE_SIZE) break;
|
|
32489
32512
|
}
|
|
32490
|
-
if (!partial2)
|
|
32491
|
-
|
|
32513
|
+
if (!partial2) {
|
|
32514
|
+
this.sweepCache.add(centre, radiusLy, systems, key);
|
|
32515
|
+
return { centre, systems, total, partial: partial2, coveredLy: radiusLy };
|
|
32516
|
+
}
|
|
32517
|
+
const last = systems[systems.length - 1];
|
|
32518
|
+
const coveredLy = Math.max(
|
|
32519
|
+
resume?.coveredLy ?? 0,
|
|
32520
|
+
last ? distanceLy(last.coords, centre) - 0.01 : 0
|
|
32521
|
+
);
|
|
32522
|
+
this.sweepCache.savePartial({ key, centre, coveredLy, systems, total });
|
|
32523
|
+
return { centre, systems, total, partial: partial2, coveredLy };
|
|
32492
32524
|
}
|
|
32493
32525
|
async route(q, opts = {}) {
|
|
32494
32526
|
const form = new URLSearchParams({
|
|
@@ -46726,6 +46758,7 @@ function systemsByState(systems, centre, radiusLy, q) {
|
|
|
46726
46758
|
// src/tools/systems.ts
|
|
46727
46759
|
var TIME_LIMIT_MS2 = 2e4;
|
|
46728
46760
|
var MASSACRE_MARGIN_LY = 2 * SOURCE_RANGE_LY;
|
|
46761
|
+
var partialNote = (coveredLy) => `Spansh returned systems out to ${Math.floor(coveredLy * 10) / 10} ly within the time limit. Call again to continue the search.`;
|
|
46729
46762
|
var STALE_HOURS = 72;
|
|
46730
46763
|
var FAR_STAR_LS = 1e3;
|
|
46731
46764
|
var Radius = external_exports.number().min(1).max(50).default(50);
|
|
@@ -46809,12 +46842,17 @@ function registerSystemTools(server, deps) {
|
|
|
46809
46842
|
const sweep = await deps.spansh.populatedSystems(near, a.radius_ly, {
|
|
46810
46843
|
deadline: now() + TIME_LIMIT_MS2
|
|
46811
46844
|
});
|
|
46812
|
-
const matches2 = systemsByState(
|
|
46845
|
+
const matches2 = systemsByState(
|
|
46846
|
+
sweep.systems,
|
|
46847
|
+
sweep.centre,
|
|
46848
|
+
Math.min(a.radius_ly, sweep.coveredLy),
|
|
46849
|
+
q
|
|
46850
|
+
);
|
|
46813
46851
|
const shown = matches2.slice(0, a.limit);
|
|
46814
46852
|
const stale = shown.filter((m) => (ageHours2(m.system) ?? 0) > STALE_HOURS).length;
|
|
46815
46853
|
if (stale) notes.push(`${stale} results have data more than ${STALE_HOURS / 24} days old.`);
|
|
46816
46854
|
if (sweep.partial) {
|
|
46817
|
-
notes.push(
|
|
46855
|
+
notes.push(partialNote(sweep.coveredLy));
|
|
46818
46856
|
}
|
|
46819
46857
|
return {
|
|
46820
46858
|
near,
|
|
@@ -46822,6 +46860,7 @@ function registerSystemTools(server, deps) {
|
|
|
46822
46860
|
travel: describeRules(rules).travel,
|
|
46823
46861
|
total_matches: matches2.length,
|
|
46824
46862
|
partial: sweep.partial,
|
|
46863
|
+
...sweep.partial ? { covered_ly: Math.floor(sweep.coveredLy * 10) / 10 } : {},
|
|
46825
46864
|
systems: shown.map((m) => {
|
|
46826
46865
|
const s = m.system;
|
|
46827
46866
|
const war = m.factions.some(
|
|
@@ -46886,7 +46925,9 @@ function registerSystemTools(server, deps) {
|
|
|
46886
46925
|
deadline: now() + TIME_LIMIT_MS2
|
|
46887
46926
|
});
|
|
46888
46927
|
const { targets, leftOutSpread } = massacreTargets(sweep.systems, sweep.centre, {
|
|
46889
|
-
|
|
46928
|
+
// Past covered_ly - margin a source could have a pirate neighbour that was not fetched.
|
|
46929
|
+
// A negative radius lists nothing, not even a target at distance 0.
|
|
46930
|
+
radiusLy: sweep.partial ? Math.min(a.radius_ly, sweep.coveredLy - MASSACRE_MARGIN_LY) : a.radius_ly,
|
|
46890
46931
|
maxStarLs: a.max_star_ls
|
|
46891
46932
|
});
|
|
46892
46933
|
notes.push(
|
|
@@ -46898,15 +46939,14 @@ function registerSystemTools(server, deps) {
|
|
|
46898
46939
|
);
|
|
46899
46940
|
}
|
|
46900
46941
|
if (sweep.partial) {
|
|
46901
|
-
notes.push(
|
|
46902
|
-
"Spansh did not return every system in time: a source can look primary when a pirate faction near the edge was missed."
|
|
46903
|
-
);
|
|
46942
|
+
notes.push(partialNote(sweep.coveredLy));
|
|
46904
46943
|
}
|
|
46905
46944
|
return {
|
|
46906
46945
|
near,
|
|
46907
46946
|
searched: sweep.systems.length,
|
|
46908
46947
|
left_out_spread: leftOutSpread,
|
|
46909
46948
|
partial: sweep.partial,
|
|
46949
|
+
...sweep.partial ? { covered_ly: Math.floor(sweep.coveredLy * 10) / 10 } : {},
|
|
46910
46950
|
travel: describeRules(rules).travel,
|
|
46911
46951
|
targets: targets.slice(0, a.limit).map((t) => ({
|
|
46912
46952
|
target_faction: t.faction,
|