@kubb/studio 5.4.1 → 5.4.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/index.cjs CHANGED
@@ -725,7 +725,7 @@ function resolveAgentCapacity(env = process.env) {
725
725
  }
726
726
  //#endregion
727
727
  //#region package.json
728
- var version = "5.4.1";
728
+ var version = "5.4.3";
729
729
  //#endregion
730
730
  //#region src/operations/resolveConfig.ts
731
731
  /**
@@ -1726,20 +1726,35 @@ function createGenerationStore({ storage, maxCount, maxMb, ttlMs, now = Date.now
1726
1726
  await storage.writeItem(INDEX_KEY, JSON.stringify(entries));
1727
1727
  },
1728
1728
  /**
1729
- * Reads the requested paths the set holds, skipping any it does not.
1729
+ * Reads the requested paths the set holds, skipping any it does not, one page of lines when `limit` is given.
1730
1730
  */
1731
- async read({ generation, source, paths }) {
1731
+ async read({ generation, source, paths, cursor = 0, limit }) {
1732
1732
  const kept = new Set(generation[source]?.paths);
1733
1733
  const files = {};
1734
+ const pages = {};
1734
1735
  await inParallel({
1735
1736
  items: paths.filter((path) => kept.has(path)),
1736
1737
  limit: READ_CONCURRENCY,
1737
1738
  run: async (path) => {
1738
1739
  const content = await storage.readItem(`${dirOf(generation.jobId)}${source}/${path}`);
1739
- if (content !== null) files[path] = content;
1740
+ if (content === null) return;
1741
+ if (limit === void 0) {
1742
+ files[path] = content;
1743
+ return;
1744
+ }
1745
+ const lines = content.split(/\r\n|\r|\n/);
1746
+ const end = Math.min(cursor + limit, lines.length);
1747
+ files[path] = lines.slice(cursor, end).join("\n");
1748
+ pages[path] = {
1749
+ nextCursor: end < lines.length ? end : null,
1750
+ totalLines: lines.length
1751
+ };
1740
1752
  }
1741
1753
  });
1742
- return files;
1754
+ return limit === void 0 ? { files } : {
1755
+ files,
1756
+ pages
1757
+ };
1743
1758
  }
1744
1759
  };
1745
1760
  }
@@ -2405,6 +2420,11 @@ function planEnd(close) {
2405
2420
  retry: true
2406
2421
  };
2407
2422
  }
2423
+ function isValidPage({ cursor, limit }) {
2424
+ if (limit === void 0) return cursor === void 0;
2425
+ if (cursor !== void 0 && (!Number.isSafeInteger(cursor) || cursor < 0)) return false;
2426
+ return Number.isSafeInteger(limit) && limit >= 1 && limit <= 2e3;
2427
+ }
2408
2428
  /**
2409
2429
  * One agent-to-Studio RPC transport: opening it, keeping it alive, and serving remote methods.
2410
2430
  * `runConnection` owns the lifetime and retry of each attempt.
@@ -2820,7 +2840,7 @@ var StudioSession = class {
2820
2840
  const missing = generation.missingDependencies.filter((dependency) => !bundled.has(dependency));
2821
2841
  if (missing.length) return this.#refuse(`Ignored snapshot: missing dependencies: ${missing.join(", ")}`, `Missing dependencies: ${missing.join(", ")}`);
2822
2842
  try {
2823
- const files = await this.#generations.read({
2843
+ const { files } = await this.#generations.read({
2824
2844
  generation,
2825
2845
  source: "output",
2826
2846
  paths: generation.output.paths
@@ -2865,18 +2885,21 @@ var StudioSession = class {
2865
2885
  if (typeof data.jobId !== "string" || !data.jobId) return this.#refuse("Ignored files: the message named no job", "The request named no generation job");
2866
2886
  const generation = await this.#generations.get(data.jobId);
2867
2887
  if (!generation) return this.#refuse(`Ignored files: job ${data.jobId} is not kept on this agent`, require_protocol.GENERATION_GONE_MESSAGE);
2888
+ if (!isValidPage(data)) return this.#refuse("Ignored files: the message carried an invalid page", `The cursor must be a whole line from 0 and come with a limit of 1 to ${require_protocol.MAX_PAGE_LINES} lines`);
2868
2889
  const source = data.source === "disk" ? "disk" : "output";
2869
2890
  if (!generation[source]) return this.#refuse("Ignored files: that job has no snapshot of the files on disk", "This agent kept no snapshot of the files on disk for that job");
2870
- const files = await this.#generations.read({
2891
+ const result = await this.#generations.read({
2871
2892
  generation,
2872
2893
  source,
2873
- paths
2894
+ paths,
2895
+ cursor: data.cursor,
2896
+ limit: data.limit
2874
2897
  });
2875
2898
  await this.#hooks.callHook("studio:command:end", {
2876
2899
  command,
2877
- info: `read ${Object.keys(files).length}/${paths.length} requested file${paths.length === 1 ? "" : "s"}`
2900
+ info: `read ${Object.keys(result.files).length}/${paths.length} requested file${paths.length === 1 ? "" : "s"}`
2878
2901
  });
2879
- return { files };
2902
+ return result;
2880
2903
  }
2881
2904
  };
2882
2905
  //#endregion