@kubb/studio 5.4.2 → 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.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { t as __name } from "./rolldown-runtime-CRm0XQPb.js";
2
- import { AGENT_INSTANCE_HEADER, AgentCloseCode, GENERATION_GONE_MESSAGE, generationEventTypes } from "./protocol.js";
2
+ import { AGENT_INSTANCE_HEADER, AgentCloseCode, GENERATION_GONE_MESSAGE, MAX_PAGE_LINES, generationEventTypes } from "./protocol.js";
3
3
  import { createRequire } from "node:module";
4
4
  import { createHash, hash, randomBytes, randomUUID } from "node:crypto";
5
5
  import { setTimeout as setTimeout$1 } from "node:timers/promises";
@@ -695,7 +695,7 @@ function resolveAgentCapacity(env = process.env) {
695
695
  }
696
696
  //#endregion
697
697
  //#region package.json
698
- var version = "5.4.2";
698
+ var version = "5.4.3";
699
699
  //#endregion
700
700
  //#region src/operations/resolveConfig.ts
701
701
  /**
@@ -1696,20 +1696,35 @@ function createGenerationStore({ storage, maxCount, maxMb, ttlMs, now = Date.now
1696
1696
  await storage.writeItem(INDEX_KEY, JSON.stringify(entries));
1697
1697
  },
1698
1698
  /**
1699
- * Reads the requested paths the set holds, skipping any it does not.
1699
+ * Reads the requested paths the set holds, skipping any it does not, one page of lines when `limit` is given.
1700
1700
  */
1701
- async read({ generation, source, paths }) {
1701
+ async read({ generation, source, paths, cursor = 0, limit }) {
1702
1702
  const kept = new Set(generation[source]?.paths);
1703
1703
  const files = {};
1704
+ const pages = {};
1704
1705
  await inParallel({
1705
1706
  items: paths.filter((path) => kept.has(path)),
1706
1707
  limit: READ_CONCURRENCY,
1707
1708
  run: async (path) => {
1708
1709
  const content = await storage.readItem(`${dirOf(generation.jobId)}${source}/${path}`);
1709
- if (content !== null) files[path] = content;
1710
+ if (content === null) return;
1711
+ if (limit === void 0) {
1712
+ files[path] = content;
1713
+ return;
1714
+ }
1715
+ const lines = content.split(/\r\n|\r|\n/);
1716
+ const end = Math.min(cursor + limit, lines.length);
1717
+ files[path] = lines.slice(cursor, end).join("\n");
1718
+ pages[path] = {
1719
+ nextCursor: end < lines.length ? end : null,
1720
+ totalLines: lines.length
1721
+ };
1710
1722
  }
1711
1723
  });
1712
- return files;
1724
+ return limit === void 0 ? { files } : {
1725
+ files,
1726
+ pages
1727
+ };
1713
1728
  }
1714
1729
  };
1715
1730
  }
@@ -2375,6 +2390,11 @@ function planEnd(close) {
2375
2390
  retry: true
2376
2391
  };
2377
2392
  }
2393
+ function isValidPage({ cursor, limit }) {
2394
+ if (limit === void 0) return cursor === void 0;
2395
+ if (cursor !== void 0 && (!Number.isSafeInteger(cursor) || cursor < 0)) return false;
2396
+ return Number.isSafeInteger(limit) && limit >= 1 && limit <= 2e3;
2397
+ }
2378
2398
  /**
2379
2399
  * One agent-to-Studio RPC transport: opening it, keeping it alive, and serving remote methods.
2380
2400
  * `runConnection` owns the lifetime and retry of each attempt.
@@ -2790,7 +2810,7 @@ var StudioSession = class {
2790
2810
  const missing = generation.missingDependencies.filter((dependency) => !bundled.has(dependency));
2791
2811
  if (missing.length) return this.#refuse(`Ignored snapshot: missing dependencies: ${missing.join(", ")}`, `Missing dependencies: ${missing.join(", ")}`);
2792
2812
  try {
2793
- const files = await this.#generations.read({
2813
+ const { files } = await this.#generations.read({
2794
2814
  generation,
2795
2815
  source: "output",
2796
2816
  paths: generation.output.paths
@@ -2835,18 +2855,21 @@ var StudioSession = class {
2835
2855
  if (typeof data.jobId !== "string" || !data.jobId) return this.#refuse("Ignored files: the message named no job", "The request named no generation job");
2836
2856
  const generation = await this.#generations.get(data.jobId);
2837
2857
  if (!generation) return this.#refuse(`Ignored files: job ${data.jobId} is not kept on this agent`, GENERATION_GONE_MESSAGE);
2858
+ 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 ${MAX_PAGE_LINES} lines`);
2838
2859
  const source = data.source === "disk" ? "disk" : "output";
2839
2860
  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");
2840
- const files = await this.#generations.read({
2861
+ const result = await this.#generations.read({
2841
2862
  generation,
2842
2863
  source,
2843
- paths
2864
+ paths,
2865
+ cursor: data.cursor,
2866
+ limit: data.limit
2844
2867
  });
2845
2868
  await this.#hooks.callHook("studio:command:end", {
2846
2869
  command,
2847
- info: `read ${Object.keys(files).length}/${paths.length} requested file${paths.length === 1 ? "" : "s"}`
2870
+ info: `read ${Object.keys(result.files).length}/${paths.length} requested file${paths.length === 1 ? "" : "s"}`
2848
2871
  });
2849
- return { files };
2872
+ return result;
2850
2873
  }
2851
2874
  };
2852
2875
  //#endregion