@fiber-pay/cli 0.1.0-rc.2 → 0.1.0-rc.3

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
@@ -2032,7 +2032,7 @@ import { existsSync as existsSync6 } from "fs";
2032
2032
  import { Command as Command6 } from "commander";
2033
2033
 
2034
2034
  // src/lib/log-files.ts
2035
- import { existsSync as existsSync5, readFileSync as readFileSync5 } from "fs";
2035
+ import { closeSync, createReadStream, existsSync as existsSync5, openSync, readSync, statSync } from "fs";
2036
2036
  import { join as join4 } from "path";
2037
2037
  function resolvePersistedLogPaths(dataDir, meta) {
2038
2038
  return {
@@ -2068,9 +2068,80 @@ function readLastLines(filePath, maxLines) {
2068
2068
  if (!existsSync5(filePath)) {
2069
2069
  return [];
2070
2070
  }
2071
- const content = readFileSync5(filePath, "utf-8");
2072
- const lines = content.split(/\r?\n/).filter((line) => line.length > 0);
2073
- return lines.slice(-maxLines);
2071
+ if (!Number.isFinite(maxLines) || maxLines <= 0) {
2072
+ return [];
2073
+ }
2074
+ let fd;
2075
+ try {
2076
+ fd = openSync(filePath, "r");
2077
+ const size = statSync(filePath).size;
2078
+ if (size <= 0) {
2079
+ return [];
2080
+ }
2081
+ const chunkSize = 64 * 1024;
2082
+ let position = size;
2083
+ const chunks = [];
2084
+ let newlineCount = 0;
2085
+ while (position > 0 && newlineCount <= maxLines) {
2086
+ const start = Math.max(0, position - chunkSize);
2087
+ const bytesToRead = position - start;
2088
+ const buffer = Buffer.alloc(bytesToRead);
2089
+ const bytesRead = readSync(fd, buffer, 0, bytesToRead, start);
2090
+ const chunk = buffer.toString("utf8", 0, bytesRead);
2091
+ chunks.unshift(chunk);
2092
+ for (let index = 0; index < chunk.length; index += 1) {
2093
+ if (chunk.charCodeAt(index) === 10) {
2094
+ newlineCount += 1;
2095
+ }
2096
+ }
2097
+ position = start;
2098
+ }
2099
+ const content = chunks.join("");
2100
+ const lines = content.split(/\r?\n/).filter((line) => line.length > 0);
2101
+ return lines.slice(-maxLines);
2102
+ } finally {
2103
+ if (fd !== void 0) {
2104
+ try {
2105
+ closeSync(fd);
2106
+ } catch {
2107
+ }
2108
+ }
2109
+ }
2110
+ }
2111
+ async function readAppendedLines(filePath, offset, remainder = "") {
2112
+ if (!existsSync5(filePath)) {
2113
+ return { lines: [], nextOffset: 0, remainder: "" };
2114
+ }
2115
+ const size = statSync(filePath).size;
2116
+ const safeOffset = size < offset ? 0 : offset;
2117
+ if (safeOffset >= size) {
2118
+ return { lines: [], nextOffset: size, remainder };
2119
+ }
2120
+ const stream = createReadStream(filePath, {
2121
+ encoding: "utf8",
2122
+ start: safeOffset,
2123
+ end: size - 1
2124
+ });
2125
+ const lines = [];
2126
+ let pending = remainder;
2127
+ let bytesReadTotal = 0;
2128
+ for await (const chunk of stream) {
2129
+ const chunkText = String(chunk);
2130
+ bytesReadTotal += Buffer.byteLength(chunkText, "utf8");
2131
+ const merged = `${pending}${chunkText}`;
2132
+ const parts = merged.split(/\r?\n/);
2133
+ pending = parts.pop() ?? "";
2134
+ for (const line of parts) {
2135
+ if (line.length > 0) {
2136
+ lines.push(line);
2137
+ }
2138
+ }
2139
+ }
2140
+ return {
2141
+ lines,
2142
+ nextOffset: safeOffset + bytesReadTotal,
2143
+ remainder: pending
2144
+ };
2074
2145
  }
2075
2146
 
2076
2147
  // src/commands/job.ts
@@ -2388,7 +2459,7 @@ ${title}: ${filePath}`);
2388
2459
  }
2389
2460
 
2390
2461
  // src/commands/logs.ts
2391
- import { existsSync as existsSync7 } from "fs";
2462
+ import { existsSync as existsSync7, statSync as statSync2 } from "fs";
2392
2463
  import { formatRuntimeAlert } from "@fiber-pay/runtime";
2393
2464
  import { Command as Command7 } from "commander";
2394
2465
  var ALLOWED_SOURCES = /* @__PURE__ */ new Set([
@@ -2550,7 +2621,8 @@ Following logs (interval: ${intervalMs}ms). Press Ctrl+C to stop.`);
2550
2621
  {
2551
2622
  title: entry.title,
2552
2623
  path: entry.path,
2553
- seenLines: entry.exists ? entry.lines.length : 0
2624
+ offset: entry.exists ? statSync2(entry.path).size : 0,
2625
+ remainder: ""
2554
2626
  }
2555
2627
  ])
2556
2628
  );
@@ -2565,26 +2637,41 @@ Following logs (interval: ${intervalMs}ms). Press Ctrl+C to stop.`);
2565
2637
  console.log("\nStopped following logs.");
2566
2638
  resolve2();
2567
2639
  };
2640
+ let polling = false;
2568
2641
  const timer = setInterval(() => {
2569
- for (const target of targets) {
2570
- const state = states.get(target.source);
2571
- if (!state) continue;
2572
- if (!existsSync7(state.path)) {
2573
- continue;
2574
- }
2575
- const allLines = readLastLines(state.path, Number.MAX_SAFE_INTEGER);
2576
- const total = allLines.length;
2577
- const fromIndex = total < state.seenLines ? 0 : state.seenLines;
2578
- const newLines = allLines.slice(fromIndex);
2579
- if (newLines.length === 0) {
2580
- continue;
2581
- }
2582
- for (const line of newLines) {
2583
- const output = target.source === "runtime" ? formatRuntimeAlertHuman(line) : line;
2584
- console.log(`[${state.title}] ${output}`);
2585
- }
2586
- state.seenLines = total;
2642
+ if (polling) {
2643
+ return;
2587
2644
  }
2645
+ polling = true;
2646
+ void (async () => {
2647
+ for (const target of targets) {
2648
+ const state = states.get(target.source);
2649
+ if (!state) continue;
2650
+ if (!existsSync7(state.path)) {
2651
+ state.offset = 0;
2652
+ state.remainder = "";
2653
+ continue;
2654
+ }
2655
+ const result = await readAppendedLines(state.path, state.offset, state.remainder);
2656
+ const newLines = result.lines;
2657
+ if (newLines.length === 0) {
2658
+ state.offset = result.nextOffset;
2659
+ state.remainder = result.remainder;
2660
+ continue;
2661
+ }
2662
+ for (const line of newLines) {
2663
+ const output = target.source === "runtime" ? formatRuntimeAlertHuman(line) : line;
2664
+ console.log(`[${state.title}] ${output}`);
2665
+ }
2666
+ state.offset = result.nextOffset;
2667
+ state.remainder = result.remainder;
2668
+ }
2669
+ })().catch((error) => {
2670
+ const message = error instanceof Error ? error.message : "Failed to read appended logs";
2671
+ console.error(`Error: ${message}`);
2672
+ }).finally(() => {
2673
+ polling = false;
2674
+ });
2588
2675
  }, intervalMs);
2589
2676
  process.on("SIGINT", stop);
2590
2677
  process.on("SIGTERM", stop);
@@ -2703,12 +2790,12 @@ import { startRuntimeService } from "@fiber-pay/runtime";
2703
2790
  import { createKeyManager } from "@fiber-pay/sdk";
2704
2791
 
2705
2792
  // src/lib/bootnode.ts
2706
- import { existsSync as existsSync9, readFileSync as readFileSync6 } from "fs";
2793
+ import { existsSync as existsSync9, readFileSync as readFileSync5 } from "fs";
2707
2794
  import { parse as parseYaml } from "yaml";
2708
2795
  function extractBootnodeAddrs(configFilePath) {
2709
2796
  if (!existsSync9(configFilePath)) return [];
2710
2797
  try {
2711
- const content = readFileSync6(configFilePath, "utf-8");
2798
+ const content = readFileSync5(configFilePath, "utf-8");
2712
2799
  const doc = parseYaml(content);
2713
2800
  const addrs = doc?.fiber?.bootnode_addrs;
2714
2801
  if (!Array.isArray(addrs)) return [];
@@ -4488,8 +4575,8 @@ function createRuntimeCommand(config) {
4488
4575
  import { Command as Command12 } from "commander";
4489
4576
 
4490
4577
  // src/lib/build-info.ts
4491
- var CLI_VERSION = "0.1.0-rc.2";
4492
- var CLI_COMMIT = "d44bf1937f40ea65c0a1e63ed3bc17d732248fb0";
4578
+ var CLI_VERSION = "0.1.0-rc.3";
4579
+ var CLI_COMMIT = "6f39077caade6d3a307db28b8d3e9cfdee7eaf99";
4493
4580
 
4494
4581
  // src/commands/version.ts
4495
4582
  function createVersionCommand() {