@madewithremy/admin 0.1.13 → 0.1.15

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 CHANGED
@@ -361,6 +361,7 @@ var dataSources_exports = {};
361
361
  __export(dataSources_exports, {
362
362
  DEFAULT_WAIT_TIMEOUT_MS: () => DEFAULT_WAIT_TIMEOUT_MS,
363
363
  DOCUMENTS_IDS_MAX: () => DOCUMENTS_IDS_MAX,
364
+ FAILURES_PAGE: () => FAILURES_PAGE,
364
365
  addDocument: () => addDocument,
365
366
  allDocuments: () => allDocuments,
366
367
  configGet: () => configGet,
@@ -392,6 +393,8 @@ function sleep(ms) {
392
393
  // src/poll.ts
393
394
  async function pollUntil(read, isSettled, options) {
394
395
  const start2 = Date.now();
396
+ let movedAt = start2;
397
+ let lastKey;
395
398
  let transientSince = null;
396
399
  while (true) {
397
400
  let value;
@@ -415,7 +418,14 @@ async function pollUntil(read, isSettled, options) {
415
418
  if (isSettled(value)) {
416
419
  return { settled: true, value };
417
420
  }
418
- if (Date.now() - start2 > options.timeoutMs) {
421
+ if (options.progressKey) {
422
+ const key = options.progressKey(value);
423
+ if (key !== lastKey) {
424
+ lastKey = key;
425
+ movedAt = Date.now();
426
+ }
427
+ }
428
+ if (Date.now() - movedAt > options.timeoutMs) {
419
429
  return { settled: false, value };
420
430
  }
421
431
  if (options.describe) {
@@ -431,6 +441,34 @@ function timedOut(timeoutMs, still) {
431
441
  return `Timed out after ${Math.round(timeoutMs / 1e3)}s ${still}`;
432
442
  }
433
443
 
444
+ // src/output.ts
445
+ var PRETTY = process.stdout.isTTY === true;
446
+ function describeEta(eta, now = Date.now()) {
447
+ if (!eta) {
448
+ return null;
449
+ }
450
+ const minutes = Math.max(1, Math.round((Date.parse(eta) - now) / 6e4));
451
+ if (minutes < 90) {
452
+ return `about ${minutes} min left`;
453
+ }
454
+ const hours = Math.round(minutes / 60 * 10) / 10;
455
+ return `about ${hours} h left`;
456
+ }
457
+ function renderProgress(p, start2, extra) {
458
+ const count = p.total !== null ? `${p.done.toLocaleString()}/${p.total.toLocaleString()} ${p.unit}` : p.done > 0 ? `${p.done.toLocaleString()} ${p.unit}` : null;
459
+ const rate = p.ratePerMinute !== null && p.ratePerMinute > 0 ? `${Math.round(p.ratePerMinute).toLocaleString()}/min` : null;
460
+ const parts = [
461
+ `${p.phase}\u2026`,
462
+ count,
463
+ rate,
464
+ describeEta(p.etaAt),
465
+ extra ?? null,
466
+ p.stalled ? "no progress for 30 min" : null
467
+ ].filter((part) => Boolean(part));
468
+ const elapsed = start2 !== void 0 ? ` (${elapsedSeconds(start2)}s)` : "";
469
+ return `${parts.join(" \xB7 ")}${elapsed}`;
470
+ }
471
+
434
472
  // src/upload.ts
435
473
  async function uploadDirect(upload, bytes, filename) {
436
474
  const form = new FormData();
@@ -533,6 +571,7 @@ async function waitForIngest(ctx, params) {
533
571
  timeoutMs,
534
572
  pollMs: POLL_MS,
535
573
  describe: (tracked2, start2) => `ingesting\u2026 ${tracked2.length - pendingOf(tracked2).length}/${tracked2.length} done (${elapsedSeconds(start2)}s)`,
574
+ progressKey: (tracked2) => pendingOf(tracked2).length,
536
575
  onProgress
537
576
  }
538
577
  );
@@ -552,33 +591,49 @@ async function waitForIngest(ctx, params) {
552
591
  documents: tracked.map(summarize)
553
592
  };
554
593
  }
594
+ var FAILURES_PAGE = 50;
555
595
  async function waitForCandidate(ctx, params) {
556
596
  const timeoutMs = params.timeoutMs ?? DEFAULT_WAIT_TIMEOUT_MS;
557
- const pendingOf = (docs2) => docs2.filter((d) => d.status === "processing");
558
597
  const outcome = await pollUntil(
559
- () => allDocuments(ctx, { slug: params.slug, candidate: true }),
560
- (docs2) => pendingOf(docs2).length === 0,
598
+ async () => {
599
+ const { dataSources } = await list3(ctx);
600
+ const source = dataSources.find((s) => s.slug === params.slug);
601
+ if (!source) {
602
+ throw new Error(`Data source "${params.slug}" not found.`);
603
+ }
604
+ return source.candidate?.progress ?? null;
605
+ },
606
+ (progress) => progress === null || progress.processing === 0,
561
607
  {
562
608
  timeoutMs,
563
609
  pollMs: POLL_MS,
564
- describe: (docs2, start2) => `rebuilding\u2026 ${docs2.length - pendingOf(docs2).length}/${docs2.length} done (${elapsedSeconds(start2)}s)`,
610
+ describe: (progress, start2) => progress ? `rebuilding\u2026 ${progress.done}/${progress.total} done (${elapsedSeconds(start2)}s)` : `rebuilding\u2026 (${elapsedSeconds(start2)}s)`,
611
+ progressKey: (progress) => progress?.processing ?? null,
565
612
  onProgress: params.onProgress
566
613
  }
567
614
  );
568
- const docs = outcome.value;
615
+ const counts = outcome.value;
616
+ const failed = counts && counts.error > 0 ? (await documents(ctx, {
617
+ slug: params.slug,
618
+ candidate: true,
619
+ status: "error",
620
+ limit: FAILURES_PAGE
621
+ })).documents.map(summarize) : [];
569
622
  if (!outcome.settled) {
570
623
  return {
571
624
  status: "timeout",
572
- documents: docs.map(summarize),
625
+ counts,
626
+ documents: failed,
573
627
  error: timedOut(
574
628
  timeoutMs,
575
- `with ${pendingOf(docs).length} document(s) still building`
629
+ `with ${counts?.processing ?? 0} document(s) still building`
576
630
  )
577
631
  };
578
632
  }
579
633
  return {
580
- status: docs.some((d) => d.status === "error") ? "error" : "ready",
581
- documents: docs.map(summarize)
634
+ status: counts && counts.error > 0 ? "error" : "ready",
635
+ counts,
636
+ documents: failed
582
637
  };
583
638
  }
584
639
  var DOCUMENTS_IDS_MAX = 200;
@@ -591,7 +646,10 @@ function documents(ctx, params) {
591
646
  candidate: params.candidate || void 0,
592
647
  ids: params.ids?.length ? params.ids.join(",") : void 0,
593
648
  limit: params.limit,
594
- cursor: params.cursor
649
+ cursor: params.cursor,
650
+ order: params.order,
651
+ status: params.status,
652
+ filename: params.filename
595
653
  })}`
596
654
  );
597
655
  }
@@ -609,7 +667,10 @@ async function allDocuments(ctx, params) {
609
667
  candidate: params.candidate,
610
668
  ids,
611
669
  limit: 1e3,
612
- cursor
670
+ cursor,
671
+ order: params.order,
672
+ status: params.status,
673
+ filename: params.filename
613
674
  });
614
675
  out.push(...page.documents ?? []);
615
676
  cursor = page.nextCursor ?? void 0;
@@ -700,7 +761,10 @@ async function waitForMove(ctx, params) {
700
761
  {
701
762
  timeoutMs,
702
763
  pollMs: POLL_MS,
703
- describe: (source2, start2) => `moving\u2026 ${source2.migration.copied}/${source2.migration.total} documents (${elapsedSeconds(start2)}s)`,
764
+ describe: (source2, start2) => renderProgress(source2.migration.progress, start2),
765
+ // A corpus of any size moves as long as it keeps moving; the timeout
766
+ // bounds silence.
767
+ progressKey: (source2) => source2.migration?.copied ?? null,
704
768
  onProgress: params.onProgress
705
769
  }
706
770
  );
@@ -909,6 +973,9 @@ async function settle(ctx, params, isSettled) {
909
973
  timeoutMs,
910
974
  pollMs: POLL_MS2,
911
975
  describe: describeProgress,
976
+ // A load of any length is waited out while it moves; the timeout bounds
977
+ // silence. Planning moves by objects listed, a run by documents.
978
+ progressKey: (job2) => `${job2.state}:${job2.progress.done}`,
912
979
  onProgress: params.onProgress
913
980
  }
914
981
  );
@@ -944,14 +1011,15 @@ async function settle(ctx, params, isSettled) {
944
1011
  return { status: "done", job };
945
1012
  }
946
1013
  function describeProgress(job, start2) {
947
- const elapsed = `(${elapsedSeconds(start2)}s)`;
948
- if (job.state === "planning") {
949
- return job.enumerationDone ? `planning\u2026 reading a sample of ${job.counts.objectsSeen.toLocaleString()} objects ${elapsed}` : `planning\u2026 ${job.counts.objectsSeen.toLocaleString()} objects counted ${elapsed}`;
1014
+ if (job.state === "planning" && job.enumerationDone) {
1015
+ return renderProgress(
1016
+ { ...job.progress, phase: "planning" },
1017
+ start2,
1018
+ `reading a sample of ${job.counts.objectsSeen.toLocaleString()} objects`
1019
+ );
950
1020
  }
951
- const total = job.plan?.projected.documents ?? job.counts.objectsSeen;
952
- const processed = job.counts.documentsDone + job.counts.documentsSkipped + job.counts.documentsFailed;
953
- const spend = `$${job.estimatedDollars.toFixed(2)}${job.budgetDollars !== null ? ` of $${job.budgetDollars.toFixed(2)}` : ""}`;
954
- return `${job.state}\u2026 ${processed.toLocaleString()}/${total.toLocaleString()} documents \xB7 ${spend} ${elapsed}`;
1021
+ const spend = job.state === "planning" ? null : `$${job.estimatedDollars.toFixed(2)}${job.budgetDollars !== null ? ` of $${job.budgetDollars.toFixed(2)}` : ""}`;
1022
+ return renderProgress(job.progress, start2, spend);
955
1023
  }
956
1024
 
957
1025
  // src/ops/dataSourceConnectors.ts
@@ -1077,7 +1145,10 @@ async function waitForHydration(ctx, params) {
1077
1145
  {
1078
1146
  timeoutMs,
1079
1147
  pollMs: POLL_MS3,
1080
- describe: (source2, start2) => `loading\u2026 ${source2.hydration.copied}/${source2.hydration.total} documents (${elapsedSeconds(start2)}s)`,
1148
+ describe: (source2, start2) => renderProgress(source2.hydration.progress, start2),
1149
+ // A reload of any size is waited out while it moves; the timeout
1150
+ // bounds silence.
1151
+ progressKey: (source2) => source2.hydration?.copied ?? null,
1081
1152
  onProgress: params.onProgress
1082
1153
  }
1083
1154
  );
@@ -1862,6 +1933,7 @@ __export(infra_exports, {
1862
1933
  get: () => get7,
1863
1934
  hibernate: () => hibernate,
1864
1935
  list: () => list7,
1936
+ logs: () => logs,
1865
1937
  provision: () => provision,
1866
1938
  rename: () => rename,
1867
1939
  resize: () => resize,
@@ -1887,6 +1959,21 @@ function get7(ctx, params) {
1887
1959
  `${base6(ctx.appId)}/${encodeURIComponent(params.id)}`
1888
1960
  );
1889
1961
  }
1962
+ function logs(ctx, params) {
1963
+ const query3 = new URLSearchParams();
1964
+ if (params.after) {
1965
+ query3.set("after", params.after);
1966
+ }
1967
+ if (params.limit) {
1968
+ query3.set("limit", String(params.limit));
1969
+ }
1970
+ const search2 = query3.toString();
1971
+ return call(
1972
+ ctx,
1973
+ "GET",
1974
+ `${base6(ctx.appId)}/${encodeURIComponent(params.id)}/logs${search2 ? `?${search2}` : ""}`
1975
+ );
1976
+ }
1890
1977
  function provision(ctx, params) {
1891
1978
  return call(ctx, "POST", base6(ctx.appId), {
1892
1979
  offeringId: params.offeringId,
@@ -1940,7 +2027,14 @@ async function waitForPhase(ctx, params) {
1940
2027
  {
1941
2028
  timeoutMs,
1942
2029
  pollMs: POLL_MS5,
1943
- describe: (resource2, start2) => `${resource2.phase}${resource2.detail ? ` \xB7 ${resource2.detail}` : ""}${resource2.resizingTo ? ` \xB7 resizing to ${resource2.resizingTo.label}` : ""}\u2026 (${elapsedSeconds(start2)}s)`,
2030
+ describe: (resource2, start2) => resource2.progress ? renderProgress(
2031
+ resource2.progress,
2032
+ start2,
2033
+ resource2.resizingTo ? `resizing to ${resource2.resizingTo.label}` : null
2034
+ ) : `${resource2.phase}${resource2.detail ? ` \xB7 ${resource2.detail}` : ""}${resource2.resizingTo ? ` \xB7 resizing to ${resource2.resizingTo.label}` : ""}\u2026 (${elapsedSeconds(start2)}s)`,
2035
+ // A rebuild after a resume runs as long as it must; the timeout bounds
2036
+ // silence, and a phase or step change counts as movement.
2037
+ progressKey: (resource2) => `${resource2.phase}:${resource2.progress?.done ?? ""}:${resource2.detail ?? ""}`,
1944
2038
  onProgress: params.onProgress
1945
2039
  }
1946
2040
  );