@secondlayer/cli 1.4.0 → 1.4.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/cli.js CHANGED
@@ -6363,7 +6363,7 @@ var init_responselike = __esm(() => {
6363
6363
 
6364
6364
  // ../../node_modules/json-buffer/index.js
6365
6365
  var require_json_buffer = __commonJS((exports) => {
6366
- exports.stringify = function stringify2(o) {
6366
+ exports.stringify = function stringify(o) {
6367
6367
  if (typeof o == "undefined")
6368
6368
  return o;
6369
6369
  if (o && Buffer.isBuffer(o))
@@ -6385,9 +6385,9 @@ var require_json_buffer = __commonJS((exports) => {
6385
6385
  if (o[k] == undefined)
6386
6386
  s += "null";
6387
6387
  else
6388
- s += stringify2(o[k]);
6388
+ s += stringify(o[k]);
6389
6389
  } else if (o[k] !== undefined) {
6390
- s += stringify2(k) + ":" + stringify2(o[k]);
6390
+ s += stringify(k) + ":" + stringify(o[k]);
6391
6391
  }
6392
6392
  }
6393
6393
  }
@@ -7331,7 +7331,7 @@ var init_FormDataEncoder = __esm(() => {
7331
7331
  }
7332
7332
  }
7333
7333
  }
7334
- [(_FormDataEncoder_CRLF = new WeakMap, _FormDataEncoder_CRLF_BYTES = new WeakMap, _FormDataEncoder_CRLF_BYTES_LENGTH = new WeakMap, _FormDataEncoder_DASHES = new WeakMap, _FormDataEncoder_encoder = new WeakMap, _FormDataEncoder_footer = new WeakMap, _FormDataEncoder_form = new WeakMap, _FormDataEncoder_options = new WeakMap, _FormDataEncoder_instances = new WeakSet, _FormDataEncoder_getFieldHeader = function _FormDataEncoder_getFieldHeader2(name, value) {
7334
+ [(_FormDataEncoder_CRLF = new WeakMap, _FormDataEncoder_CRLF_BYTES = new WeakMap, _FormDataEncoder_CRLF_BYTES_LENGTH = new WeakMap, _FormDataEncoder_DASHES = new WeakMap, _FormDataEncoder_encoder = new WeakMap, _FormDataEncoder_footer = new WeakMap, _FormDataEncoder_form = new WeakMap, _FormDataEncoder_options = new WeakMap, _FormDataEncoder_instances = new WeakSet, _FormDataEncoder_getFieldHeader = function _FormDataEncoder_getFieldHeader(name, value) {
7335
7335
  let header = "";
7336
7336
  header += `${__classPrivateFieldGet(this, _FormDataEncoder_DASHES, "f")}${this.boundary}${__classPrivateFieldGet(this, _FormDataEncoder_CRLF, "f")}`;
7337
7337
  header += `Content-Disposition: form-data; name="${escapeName(name)}"`;
@@ -7344,7 +7344,7 @@ var init_FormDataEncoder = __esm(() => {
7344
7344
  header += `${__classPrivateFieldGet(this, _FormDataEncoder_CRLF, "f")}Content-Length: ${isFile(value) ? value.size : value.byteLength}`;
7345
7345
  }
7346
7346
  return __classPrivateFieldGet(this, _FormDataEncoder_encoder, "f").encode(`${header}${__classPrivateFieldGet(this, _FormDataEncoder_CRLF, "f").repeat(2)}`);
7347
- }, _FormDataEncoder_getContentLength = function _FormDataEncoder_getContentLength2() {
7347
+ }, _FormDataEncoder_getContentLength = function _FormDataEncoder_getContentLength() {
7348
7348
  let length = 0;
7349
7349
  for (const [name, raw] of __classPrivateFieldGet(this, _FormDataEncoder_form, "f")) {
7350
7350
  const value = isFile(raw) ? raw : __classPrivateFieldGet(this, _FormDataEncoder_encoder, "f").encode(normalizeValue(raw));
@@ -21143,23 +21143,23 @@ var require_ansis = __commonJS((exports, module) => {
21143
21143
  }, s2 = t2, c2 = l2;
21144
21144
  return e2 && (s2 = e2.o + t2, c2 = l2 + e2.c), n(o2, r), o2.p = { open: t2, close: l2, o: s2, c: c2, p: e2 }, o2.open = s2, o2.close = c2, o2;
21145
21145
  };
21146
- var w = new function e2(t2 = f) {
21147
- let s2 = { Ansis: e2, level: t2, isSupported: () => a2, strip: (e3) => e3.replace(/[›][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, i), extend(e3) {
21148
- for (let t3 in e3) {
21149
- let r2 = e3[t3], l2 = (typeof r2)[0];
21146
+ var w = new function e(t2 = f) {
21147
+ let s2 = { Ansis: e, level: t2, isSupported: () => a2, strip: (e2) => e2.replace(/[›][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, i), extend(e2) {
21148
+ for (let t3 in e2) {
21149
+ let r2 = e2[t3], l2 = (typeof r2)[0];
21150
21150
  l2 === "s" ? (c2(t3, T(...p(r2))), c2(_(t3), v(...p(r2)))) : c2(t3, r2, l2 === "f");
21151
21151
  }
21152
21152
  return r = o({}, O), n(s2, r), s2;
21153
- } }, c2 = (e3, t3, r2) => {
21154
- O[e3] = { get() {
21155
- let n2 = r2 ? (...e4) => m(this, t3(...e4)) : m(this, t3);
21156
- return l(this, e3, { value: n2 }), n2;
21153
+ } }, c2 = (e2, t3, r2) => {
21154
+ O[e2] = { get() {
21155
+ let n2 = r2 ? (...e3) => m(this, t3(...e3)) : m(this, t3);
21156
+ return l(this, e2, { value: n2 }), n2;
21157
21157
  } };
21158
- }, a2 = t2 > 0, w2 = (e3, t3) => a2 ? { open: `\x1B[${e3}m`, close: `\x1B[${t3}m` } : g, y = (e3) => (t3) => e3(...p(t3)), R = (e3, t3) => (r2, l2, n2) => w2(`${e3}8;2;${r2};${l2};${n2}`, t3), $ = (e3, t3) => (r2, l2, n2) => w2(((e4, t4, r3) => d(u(e4, t4, r3)))(r2, l2, n2) + e3, t3), x = (e3) => (t3, r2, l2) => e3(u(t3, r2, l2)), T = R(3, h), v = R(4, b2), C = (e3) => w2("38;5;" + e3, h), E = (e3) => w2("48;5;" + e3, b2);
21159
- t2 === 2 ? (T = x(C), v = x(E)) : t2 === 1 && (T = $(0, h), v = $(10, b2), C = (e3) => w2(d(e3), h), E = (e3) => w2(d(e3) + 10, b2));
21160
- let M, I = { fg: C, bg: E, rgb: T, bgRgb: v, hex: y(T), bgHex: y(v), visible: g, reset: w2(0, 0), bold: w2(1, 22), dim: w2(2, 22), italic: w2(3, 23), underline: w2(4, 24), inverse: w2(7, 27), hidden: w2(8, 28), strikethrough: w2(9, 29) }, _ = (e3) => "bg" + e3[0].toUpperCase() + e3.slice(1), k = "Bright";
21161
- return "black,red,green,yellow,blue,magenta,cyan,white,gray".split(",").map((e3, t3) => {
21162
- M = _(e3), 8 > t3 ? (I[e3 + k] = w2(90 + t3, h), I[M + k] = w2(100 + t3, b2)) : t3 = 60, I[e3] = w2(30 + t3, h), I[M] = w2(40 + t3, b2);
21158
+ }, a2 = t2 > 0, w2 = (e2, t3) => a2 ? { open: `\x1B[${e2}m`, close: `\x1B[${t3}m` } : g, y = (e2) => (t3) => e2(...p(t3)), R = (e2, t3) => (r2, l2, n2) => w2(`${e2}8;2;${r2};${l2};${n2}`, t3), $ = (e2, t3) => (r2, l2, n2) => w2(((e3, t4, r3) => d(u(e3, t4, r3)))(r2, l2, n2) + e2, t3), x = (e2) => (t3, r2, l2) => e2(u(t3, r2, l2)), T = R(3, h), v = R(4, b2), C = (e2) => w2("38;5;" + e2, h), E = (e2) => w2("48;5;" + e2, b2);
21159
+ t2 === 2 ? (T = x(C), v = x(E)) : t2 === 1 && (T = $(0, h), v = $(10, b2), C = (e2) => w2(d(e2), h), E = (e2) => w2(d(e2) + 10, b2));
21160
+ let M, I = { fg: C, bg: E, rgb: T, bgRgb: v, hex: y(T), bgHex: y(v), visible: g, reset: w2(0, 0), bold: w2(1, 22), dim: w2(2, 22), italic: w2(3, 23), underline: w2(4, 24), inverse: w2(7, 27), hidden: w2(8, 28), strikethrough: w2(9, 29) }, _ = (e2) => "bg" + e2[0].toUpperCase() + e2.slice(1), k = "Bright";
21161
+ return "black,red,green,yellow,blue,magenta,cyan,white,gray".split(",").map((e2, t3) => {
21162
+ M = _(e2), 8 > t3 ? (I[e2 + k] = w2(90 + t3, h), I[M + k] = w2(100 + t3, b2)) : t3 = 60, I[e2] = w2(30 + t3, h), I[M] = w2(40 + t3, b2);
21163
21163
  }), s2.extend(I);
21164
21164
  };
21165
21165
  module.exports = w, w.default = w;
@@ -32954,7 +32954,7 @@ var {
32954
32954
  // package.json
32955
32955
  var package_default = {
32956
32956
  name: "@secondlayer/cli",
32957
- version: "1.4.0",
32957
+ version: "1.4.1",
32958
32958
  description: "CLI for streams, views, and real-time blockchain indexing on Stacks",
32959
32959
  type: "module",
32960
32960
  bin: {
@@ -32995,10 +32995,10 @@ var package_default = {
32995
32995
  license: "MIT",
32996
32996
  dependencies: {
32997
32997
  "@inquirer/prompts": "^8.2.0",
32998
- "@secondlayer/sdk": "^0.4.0",
32999
- "@secondlayer/shared": "^0.2.3",
33000
- "@secondlayer/stacks": "^0.0.4",
33001
- "@secondlayer/views": "^0.2.3",
32998
+ "@secondlayer/sdk": "^0.4.1",
32999
+ "@secondlayer/shared": "^0.3.0",
33000
+ "@secondlayer/stacks": "^0.1.0",
33001
+ "@secondlayer/views": "^0.2.4",
33002
33002
  "@biomejs/js-api": "^0.7.0",
33003
33003
  "@biomejs/wasm-nodejs": "^1.9.0",
33004
33004
  esbuild: "^0.19.0",
@@ -34573,12 +34573,13 @@ init_config();
34573
34573
  init_output();
34574
34574
  import { StacksNodeClient } from "@secondlayer/shared/node";
34575
34575
  import { HiroClient } from "@secondlayer/shared/node/hiro-client";
34576
+ import { LocalClient } from "@secondlayer/shared/node/local-client";
34576
34577
  import { findGaps, countMissingBlocks } from "@secondlayer/shared/db/queries/integrity";
34577
34578
  import { getDb } from "@secondlayer/shared/db";
34578
34579
  import { confirm as confirm4 } from "@inquirer/prompts";
34579
34580
  var DEV_DATABASE_URL = "postgres://postgres:postgres@localhost:5432/streams_dev";
34580
34581
  function registerSyncCommand(program2) {
34581
- program2.command("sync").description("Fetch missing blocks and index them").option("--from <block>", "Start block height").option("--to <block>", "End block height").option("--gaps", "Auto-detect and fill all gaps").option("--concurrency <n>", "Parallel fetch limit (default: 1 for hiro, 5 for node)").option("--delay <ms>", "Delay between batches in ms (default: 500 for hiro, 0 for node)").option("--source <source>", "Data source: auto, hiro, node", "auto").option("-y, --yes", "Skip confirmation prompt").action(async function() {
34582
+ program2.command("sync").description("Fetch missing blocks and index them").option("--from <block>", "Start block height").option("--to <block>", "End block height").option("--gaps", "Auto-detect and fill all gaps").option("--concurrency <n>", "Parallel fetch limit (default: 1 for hiro, 5 for node)").option("--delay <ms>", "Delay between batches in ms (default: 500 for hiro, 0 for node)").option("--source <source>", "Data source: auto, local, hiro, node", "auto").option("-y, --yes", "Skip confirmation prompt").action(async function() {
34582
34583
  const opts = this.opts();
34583
34584
  const config = await loadConfig();
34584
34585
  const indexerUrl = process.env.INDEXER_URL || `http://localhost:${config.ports.indexer}`;
@@ -34586,28 +34587,45 @@ function registerSyncCommand(program2) {
34586
34587
  try {
34587
34588
  const nodeClient = new StacksNodeClient;
34588
34589
  const hiroClient = new HiroClient;
34590
+ const localClient = new LocalClient;
34589
34591
  let useHiro = opts.source === "hiro";
34590
34592
  let useNode = opts.source === "node";
34593
+ let useLocal = opts.source === "local";
34591
34594
  if (opts.source === "auto" || !opts.source) {
34592
- const nodeHealthy = await nodeClient.isHealthy();
34593
- if (nodeHealthy) {
34594
- const testBlock = await nodeClient.getBlock(1).catch(() => null);
34595
- if (testBlock) {
34596
- useNode = true;
34597
- info("Using local Stacks node for backfill");
34595
+ if (!process.env.DATABASE_URL) {
34596
+ process.env.DATABASE_URL = DEV_DATABASE_URL;
34597
+ }
34598
+ const db = getDb();
34599
+ const localTip = await localClient.getChainTip(db);
34600
+ if (localTip > 0) {
34601
+ useLocal = true;
34602
+ info(`Using local DB for backfill (tip: block ${localTip})`);
34603
+ } else {
34604
+ const nodeHealthy = await nodeClient.isHealthy();
34605
+ if (nodeHealthy) {
34606
+ const testBlock = await nodeClient.getBlock(1).catch(() => null);
34607
+ if (testBlock) {
34608
+ useNode = true;
34609
+ info("Using local Stacks node for backfill");
34610
+ } else {
34611
+ useHiro = true;
34612
+ info("Node can't serve block data, using Hiro public API");
34613
+ }
34598
34614
  } else {
34599
34615
  useHiro = true;
34600
- info("Node can't serve block data, using Hiro public API");
34616
+ info("Node not reachable, using Hiro public API");
34601
34617
  }
34602
- } else {
34603
- useHiro = true;
34604
- info("Node not reachable, using Hiro public API");
34605
34618
  }
34606
34619
  }
34607
34620
  if (concurrency === 0) {
34608
- concurrency = useHiro ? 1 : 5;
34621
+ concurrency = useLocal ? 10 : useHiro ? 1 : 5;
34609
34622
  }
34610
- if (useHiro) {
34623
+ if (useLocal) {
34624
+ if (!process.env.DATABASE_URL) {
34625
+ process.env.DATABASE_URL = DEV_DATABASE_URL;
34626
+ }
34627
+ info("Source: local DB");
34628
+ } else if (useHiro) {
34611
34629
  const hiroHealthy = await hiroClient.isHealthy();
34612
34630
  if (!hiroHealthy) {
34613
34631
  error(`Cannot reach Hiro API at ${hiroClient.getApiUrl()}`);
@@ -34662,7 +34680,7 @@ Examples:`));
34662
34680
  const totalBlocks = ranges.reduce((sum, r) => sum + (r.end - r.start + 1), 0);
34663
34681
  if (!opts.yes) {
34664
34682
  console.log("");
34665
- const sourceLabel = useHiro ? "Hiro API" : "local node";
34683
+ const sourceLabel = useLocal ? "local DB" : useHiro ? "Hiro API" : "local node";
34666
34684
  console.log(`This will fetch ${yellow(totalBlocks.toString())} blocks from ${sourceLabel}.`);
34667
34685
  if (useHiro) {
34668
34686
  console.log(dim("Note: Hiro API fetches are slower due to per-tx event lookups."));
@@ -34693,7 +34711,10 @@ Examples:`));
34693
34711
  const batch = heights.slice(i, i + concurrency);
34694
34712
  const results = await Promise.allSettled(batch.map(async (height) => {
34695
34713
  let block;
34696
- if (useHiro) {
34714
+ if (useLocal) {
34715
+ const db = getDb();
34716
+ block = await localClient.getBlockForReplay(db, height);
34717
+ } else if (useHiro) {
34697
34718
  block = await hiroClient.getBlockForIndexer(height);
34698
34719
  } else {
34699
34720
  block = await nodeClient.getBlock(height);
@@ -37144,5 +37165,5 @@ registerWhoamiCommand(program);
37144
37165
  registerWebhookCommand(program);
37145
37166
  program.parse();
37146
37167
 
37147
- //# debugId=BCBDF4D8864271A764756E2164756E21
37168
+ //# debugId=E0C86F93180D107264756E2164756E21
37148
37169
  //# sourceMappingURL=cli.js.map