@neat.is/core 0.10.3 → 0.10.4

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.
@@ -33,13 +33,13 @@ import {
33
33
  startStalenessLoop,
34
34
  touchLastSeen,
35
35
  writeAtomically
36
- } from "./chunk-LNIVRE4L.js";
36
+ } from "./chunk-TUGYIRUT.js";
37
37
  import {
38
38
  assertBindAuthority,
39
39
  buildOtelReceiver,
40
40
  listenSteppingOtlp,
41
41
  readAuthEnv
42
- } from "./chunk-M7CGATVC.js";
42
+ } from "./chunk-EFBWQIKG.js";
43
43
 
44
44
  // src/daemon.ts
45
45
  import {
@@ -505,6 +505,7 @@ async function syncOneRepo(r, input) {
505
505
  detail: `extracted ${nodes} node${nodes === 1 ? "" : "s"}, ${edges} edge${edges === 1 ? "" : "s"}`,
506
506
  lastSyncAt: new Date(input.now?.() ?? Date.now()).toISOString()
507
507
  });
508
+ return true;
508
509
  } catch (err) {
509
510
  input.onError?.(label, err);
510
511
  await cpPostStatus(deps, r.owner, r.name, {
@@ -512,50 +513,76 @@ async function syncOneRepo(r, input) {
512
513
  detail: scrubToken(err.message).slice(0, 300)
513
514
  }).catch(() => {
514
515
  });
516
+ return false;
515
517
  } finally {
516
518
  if (dir) await rm(dir, { recursive: true, force: true }).catch(() => {
517
519
  });
518
520
  }
519
521
  }
520
- async function runRepoSyncPass(input) {
522
+ async function runRepoSyncPassCounted(input) {
523
+ const counts = { listed: false, synced: 0, failed: 0 };
521
524
  let repos;
522
525
  try {
523
526
  repos = await cpGet2(`/internal/projects/${input.deps.projectId}/repos`, input.deps);
524
527
  } catch (err) {
525
528
  input.onSkip?.("(all)", `control plane repo list unreadable \u2014 ${err.message}`);
526
- return false;
529
+ return counts;
527
530
  }
528
- if (!Array.isArray(repos)) return false;
531
+ if (!Array.isArray(repos)) return counts;
532
+ counts.listed = true;
529
533
  for (const r of repos) {
530
534
  if (!input.forceResync && !needsSync(r)) continue;
531
- await syncOneRepo(r, input);
535
+ if (await syncOneRepo(r, input)) counts.synced++;
536
+ else counts.failed++;
532
537
  }
533
- return true;
538
+ return counts;
534
539
  }
535
540
  async function startRepoSync(input) {
536
541
  const intervalMs = input.intervalMs ?? DEFAULT_SYNC_INTERVAL_MS;
542
+ const now = () => input.now?.() ?? Date.now();
537
543
  let stopped = false;
538
- let running = false;
544
+ let inFlight = null;
545
+ let again = false;
546
+ let lastPass;
539
547
  let bootResyncDone = false;
540
- const tick = async () => {
541
- if (stopped || running) return;
542
- running = true;
548
+ const run = async () => {
543
549
  try {
544
- const listed = await runRepoSyncPass({ ...input, forceResync: !bootResyncDone });
545
- if (listed) bootResyncDone = true;
550
+ do {
551
+ again = false;
552
+ const startedAt = new Date(now()).toISOString();
553
+ const counts = await runRepoSyncPassCounted({ ...input, forceResync: !bootResyncDone });
554
+ if (counts.listed) bootResyncDone = true;
555
+ lastPass = { ...counts, startedAt, finishedAt: new Date(now()).toISOString() };
556
+ } while (again && !stopped);
546
557
  } finally {
547
- running = false;
558
+ inFlight = null;
548
559
  }
549
560
  };
550
- void tick();
551
- const timer = setInterval(() => {
552
- void tick();
553
- }, intervalMs);
561
+ const tick = () => {
562
+ if (stopped || inFlight) return;
563
+ inFlight = run();
564
+ };
565
+ tick();
566
+ const timer = setInterval(tick, intervalMs);
554
567
  if (typeof timer.unref === "function") timer.unref();
555
- return () => {
568
+ const stop = () => {
556
569
  stopped = true;
557
570
  clearInterval(timer);
558
571
  };
572
+ return Object.assign(stop, {
573
+ syncNow: () => {
574
+ const summary = lastPass ? { lastPass } : {};
575
+ if (inFlight) {
576
+ again = true;
577
+ return { status: "queued", ...summary };
578
+ }
579
+ inFlight = run();
580
+ return { status: "started", ...summary };
581
+ },
582
+ settled: async () => {
583
+ while (inFlight) await inFlight;
584
+ }
585
+ });
559
586
  }
560
587
  async function maybeStartRepoSync(input) {
561
588
  const env = input.env ?? process.env;
@@ -1322,6 +1349,7 @@ async function bootstrapProject(entry, connectors = [], neatHome) {
1322
1349
  stopHostedConnectors,
1323
1350
  stopK8sSubstrate,
1324
1351
  stopRepoSync,
1352
+ ...stopRepoSync.syncNow ? { syncRepos: stopRepoSync.syncNow } : {},
1325
1353
  detachEvents,
1326
1354
  status: "active"
1327
1355
  };
@@ -1593,7 +1621,14 @@ async function startDaemon(opts = {}) {
1593
1621
  // through the same resolved home the slot bootstrap read it from, so a
1594
1622
  // daemon given an explicit NEAT_HOME serves status for the same file it
1595
1623
  // polls.
1596
- connectorsHome: home
1624
+ connectorsHome: home,
1625
+ // #1293 — "sync this project's repos now". Looked up per request: the
1626
+ // slot, and with it the trigger, appears once bootstrap has run.
1627
+ repoSync: (name) => slots.get(name)?.syncRepos,
1628
+ // OTLP answers on this listener too, so a host that routes a single
1629
+ // port still delivers a tenant app's spans. Bound late: the receiver
1630
+ // is built below, once the REST bind has succeeded.
1631
+ otlpReceiver: () => otlpApp ?? void 0
1597
1632
  });
1598
1633
  restAddress = await restApp.listen({ port: restPort, host });
1599
1634
  console.log(
@@ -1774,7 +1809,9 @@ async function startDaemon(opts = {}) {
1774
1809
  }
1775
1810
  });
1776
1811
  otlpAddress = await listenSteppingOtlp(otlpApp, otlpPort, host);
1777
- console.log(`neatd: OTLP listening on ${otlpAddress}/v1/traces`);
1812
+ console.log(
1813
+ `neatd: OTLP listening on http://${host}:${portFromListenAddress(otlpAddress, otlpPort)}/v1/traces (also at /v1/traces on the REST port)`
1814
+ );
1778
1815
  } catch (err) {
1779
1816
  for (const slot of slots.values()) {
1780
1817
  teardownSlot(slot);
@@ -1946,4 +1983,4 @@ export {
1946
1983
  resolveHost,
1947
1984
  startDaemon
1948
1985
  };
1949
- //# sourceMappingURL=chunk-DLQNMU3R.js.map
1986
+ //# sourceMappingURL=chunk-2OQVIBZZ.js.map