@galaxy-tool-util/core 0.2.0 → 1.0.0

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.
Files changed (72) hide show
  1. package/README.md +33 -0
  2. package/dist/cache/cache-index.d.ts +16 -12
  3. package/dist/cache/cache-index.d.ts.map +1 -1
  4. package/dist/cache/cache-index.js +34 -55
  5. package/dist/cache/cache-index.js.map +1 -1
  6. package/dist/cache/cache-key.d.ts +2 -1
  7. package/dist/cache/cache-key.d.ts.map +1 -1
  8. package/dist/cache/cache-key.js +7 -3
  9. package/dist/cache/cache-key.js.map +1 -1
  10. package/dist/cache/index.d.ts +5 -1
  11. package/dist/cache/index.d.ts.map +1 -1
  12. package/dist/cache/index.js +3 -1
  13. package/dist/cache/index.js.map +1 -1
  14. package/dist/cache/node.d.ts +30 -0
  15. package/dist/cache/node.d.ts.map +1 -0
  16. package/dist/cache/node.js +37 -0
  17. package/dist/cache/node.js.map +1 -0
  18. package/dist/cache/storage/filesystem.d.ts +17 -0
  19. package/dist/cache/storage/filesystem.d.ts.map +1 -0
  20. package/dist/cache/storage/filesystem.js +61 -0
  21. package/dist/cache/storage/filesystem.js.map +1 -0
  22. package/dist/cache/storage/indexeddb.d.ts +21 -0
  23. package/dist/cache/storage/indexeddb.d.ts.map +1 -0
  24. package/dist/cache/storage/indexeddb.js +87 -0
  25. package/dist/cache/storage/indexeddb.js.map +1 -0
  26. package/dist/cache/storage/interface.d.ts +17 -0
  27. package/dist/cache/storage/interface.d.ts.map +1 -0
  28. package/dist/cache/storage/interface.js +2 -0
  29. package/dist/cache/storage/interface.js.map +1 -0
  30. package/dist/cache/tool-cache-defaults.d.ts +7 -0
  31. package/dist/cache/tool-cache-defaults.d.ts.map +1 -0
  32. package/dist/cache/tool-cache-defaults.js +7 -0
  33. package/dist/cache/tool-cache-defaults.js.map +1 -0
  34. package/dist/cache/tool-cache.d.ts +16 -21
  35. package/dist/cache/tool-cache.d.ts.map +1 -1
  36. package/dist/cache/tool-cache.js +33 -47
  37. package/dist/cache/tool-cache.js.map +1 -1
  38. package/dist/client/index.d.ts +2 -0
  39. package/dist/client/index.d.ts.map +1 -1
  40. package/dist/client/index.js +1 -0
  41. package/dist/client/index.js.map +1 -1
  42. package/dist/client/toolshed.d.ts +1 -1
  43. package/dist/client/toolshed.js +1 -1
  44. package/dist/client/trs.d.ts +32 -0
  45. package/dist/client/trs.d.ts.map +1 -0
  46. package/dist/client/trs.js +66 -0
  47. package/dist/client/trs.js.map +1 -0
  48. package/dist/config-node.d.ts +7 -0
  49. package/dist/config-node.d.ts.map +1 -0
  50. package/dist/config-node.js +14 -0
  51. package/dist/config-node.js.map +1 -0
  52. package/dist/config.d.ts +75 -0
  53. package/dist/config.d.ts.map +1 -0
  54. package/dist/config.js +60 -0
  55. package/dist/config.js.map +1 -0
  56. package/dist/index.d.ts +14 -9
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +11 -8
  59. package/dist/index.js.map +1 -1
  60. package/dist/node.d.ts +12 -0
  61. package/dist/node.d.ts.map +1 -0
  62. package/dist/node.js +11 -0
  63. package/dist/node.js.map +1 -0
  64. package/dist/tool-info.d.ts +10 -3
  65. package/dist/tool-info.d.ts.map +1 -1
  66. package/dist/tool-info.js +34 -16
  67. package/dist/tool-info.js.map +1 -1
  68. package/package.json +18 -6
  69. package/dist/models/parsed-tool.d.ts +0 -46
  70. package/dist/models/parsed-tool.d.ts.map +0 -1
  71. package/dist/models/parsed-tool.js +0 -41
  72. package/dist/models/parsed-tool.js.map +0 -1
package/README.md CHANGED
@@ -8,6 +8,39 @@ Galaxy tool cache, ToolShed client, and ParsedTool models.
8
8
  npm install @galaxy-tool-util/core
9
9
  ```
10
10
 
11
+ ## Usage
12
+
13
+ The package ships two entry points:
14
+
15
+ - **`@galaxy-tool-util/core`** — universal (browser + Node). Models, schemas,
16
+ `ToolCache` (with injected storage), `IndexedDBCacheStorage`, `ToolInfoService`,
17
+ `cacheKey`, ToolShed/Galaxy clients, YAML config schemas.
18
+ - **`@galaxy-tool-util/core/node`** — Node-only helpers that pull in `fs`, `path`,
19
+ `os`: `FilesystemCacheStorage`, `getCacheDir`, `DEFAULT_CACHE_DIR`,
20
+ `CACHE_DIR_ENV_VAR`, `loadWorkflowToolConfig`, plus convenience factories
21
+ `makeNodeToolCache` and `makeNodeToolInfoService`.
22
+
23
+ ### Browser / Web Worker
24
+
25
+ ```ts
26
+ import { ToolCache, IndexedDBCacheStorage } from "@galaxy-tool-util/core";
27
+
28
+ const cache = new ToolCache({
29
+ storage: new IndexedDBCacheStorage("gxwf-tool-cache"),
30
+ });
31
+ ```
32
+
33
+ ### Node
34
+
35
+ ```ts
36
+ import { makeNodeToolCache } from "@galaxy-tool-util/core/node";
37
+
38
+ const cache = makeNodeToolCache(); // defaults to ~/.galaxy/tool_info_cache
39
+ ```
40
+
41
+ Bundlers targeting the browser will fail fast if `/node` is imported — by
42
+ design. Keep Node-only imports on the server side of your application.
43
+
11
44
  ## License
12
45
 
13
46
  MIT
@@ -1,3 +1,4 @@
1
+ import type { CacheStorage } from "./storage/interface.js";
1
2
  /** Metadata for a single cached tool entry. */
2
3
  export interface CacheIndexEntry {
3
4
  tool_id: string;
@@ -8,29 +9,32 @@ export interface CacheIndexEntry {
8
9
  /** ISO 8601 timestamp of when the tool was cached. */
9
10
  cached_at: string;
10
11
  }
11
- /** Serialized cache index structure (persisted as index.json). */
12
+ /** Serialized cache index structure. */
12
13
  export interface CacheIndexData {
13
14
  entries: Record<string, CacheIndexEntry>;
14
15
  }
15
16
  /**
16
- * Manages the cache index file (index.json) that tracks metadata about cached tools.
17
- * Supports lazy loading, add/remove, and listing operations.
17
+ * Manages the cache index that tracks metadata about cached tools.
18
+ * Backed by a {@link CacheStorage} works on both filesystem (Node.js) and
19
+ * IndexedDB (browser/Web Worker).
20
+ *
21
+ * Call `await load()` before using `has()` or `listAll()` if you need
22
+ * the persisted state. ToolCache calls load() automatically on first use.
18
23
  */
19
24
  export declare class CacheIndex {
20
- readonly cacheDir: string;
21
- private indexPath;
25
+ private readonly storage;
22
26
  private entries;
23
- constructor(cacheDir: string);
24
- private getEntries;
25
- private loadSync;
27
+ private loaded;
28
+ constructor(storage: CacheStorage);
26
29
  load(): Promise<void>;
27
- save(): Promise<void>;
30
+ private ensureLoaded;
31
+ private save;
28
32
  add(key: string, toolId: string, toolVersion: string, source: string, sourceUrl?: string): Promise<void>;
29
33
  remove(key: string): Promise<void>;
30
- has(key: string): boolean;
31
- listAll(): Array<CacheIndexEntry & {
34
+ has(key: string): Promise<boolean>;
35
+ listAll(): Promise<Array<CacheIndexEntry & {
32
36
  cache_key: string;
33
- }>;
37
+ }>>;
34
38
  clear(): Promise<void>;
35
39
  }
36
40
  //# sourceMappingURL=cache-index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cache-index.d.ts","sourceRoot":"","sources":["../../src/cache/cache-index.ts"],"names":[],"mappings":"AAIA,+CAA+C;AAC/C,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,kEAAkE;AAClE,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC1C;AAED;;;GAGG;AACH,qBAAa,UAAU;IAIT,QAAQ,CAAC,QAAQ,EAAE,MAAM;IAHrC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAgD;gBAE1C,QAAQ,EAAE,MAAM;IAIrC,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,QAAQ;IAcV,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAerB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAMrB,GAAG,CACP,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,SAAS,GAAE,MAAW,GACrB,OAAO,CAAC,IAAI,CAAC;IAWV,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQxC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB,OAAO,IAAI,KAAK,CAAC,eAAe,GAAG;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAOnD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAI7B"}
1
+ {"version":3,"file":"cache-index.d.ts","sourceRoot":"","sources":["../../src/cache/cache-index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAK3D,+CAA+C;AAC/C,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wCAAwC;AACxC,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC1C;AAED;;;;;;;GAOG;AACH,qBAAa,UAAU;IAIT,OAAO,CAAC,QAAQ,CAAC,OAAO;IAHpC,OAAO,CAAC,OAAO,CAAuC;IACtD,OAAO,CAAC,MAAM,CAAS;gBAEM,OAAO,EAAE,YAAY;IAE5C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAMb,YAAY;YAIZ,IAAI;IAKZ,GAAG,CACP,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,SAAS,GAAE,MAAW,GACrB,OAAO,CAAC,IAAI,CAAC;IAYV,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQlC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKlC,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC,eAAe,GAAG;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAQlE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAK7B"}
@@ -1,60 +1,36 @@
1
- import { readFile, writeFile, mkdir } from "node:fs/promises";
2
- import { existsSync, readFileSync } from "node:fs";
3
- import { join } from "node:path";
1
+ /** Reserved storage key for the index metadata object. */
2
+ const INDEX_KEY = "__index__";
4
3
  /**
5
- * Manages the cache index file (index.json) that tracks metadata about cached tools.
6
- * Supports lazy loading, add/remove, and listing operations.
4
+ * Manages the cache index that tracks metadata about cached tools.
5
+ * Backed by a {@link CacheStorage} works on both filesystem (Node.js) and
6
+ * IndexedDB (browser/Web Worker).
7
+ *
8
+ * Call `await load()` before using `has()` or `listAll()` if you need
9
+ * the persisted state. ToolCache calls load() automatically on first use.
7
10
  */
8
11
  export class CacheIndex {
9
- cacheDir;
10
- indexPath;
11
- entries = null;
12
- constructor(cacheDir) {
13
- this.cacheDir = cacheDir;
14
- this.indexPath = join(cacheDir, "index.json");
15
- }
16
- getEntries() {
17
- if (this.entries === null) {
18
- this.entries = this.loadSync();
19
- }
20
- return this.entries;
21
- }
22
- loadSync() {
23
- if (!existsSync(this.indexPath)) {
24
- return {};
25
- }
26
- try {
27
- const raw = readFileSync(this.indexPath, "utf-8");
28
- const data = JSON.parse(raw);
29
- return data.entries ?? {};
30
- }
31
- catch (err) {
32
- console.debug(`Failed to load cache index (sync): ${err}`);
33
- return {};
34
- }
12
+ storage;
13
+ entries = {};
14
+ loaded = false;
15
+ constructor(storage) {
16
+ this.storage = storage;
35
17
  }
36
18
  async load() {
37
- if (!existsSync(this.indexPath)) {
38
- this.entries = {};
39
- return;
40
- }
41
- try {
42
- const raw = await readFile(this.indexPath, "utf-8");
43
- const data = JSON.parse(raw);
44
- this.entries = data.entries ?? {};
45
- }
46
- catch (err) {
47
- console.debug(`Failed to load cache index: ${err}`);
48
- this.entries = {};
49
- }
19
+ const data = (await this.storage.load(INDEX_KEY));
20
+ this.entries = data?.entries ?? {};
21
+ this.loaded = true;
22
+ }
23
+ async ensureLoaded() {
24
+ if (!this.loaded)
25
+ await this.load();
50
26
  }
51
27
  async save() {
52
- await mkdir(this.cacheDir, { recursive: true });
53
- const data = { entries: this.getEntries() };
54
- await writeFile(this.indexPath, JSON.stringify(data, null, 2));
28
+ const data = { entries: this.entries };
29
+ await this.storage.save(INDEX_KEY, data);
55
30
  }
56
31
  async add(key, toolId, toolVersion, source, sourceUrl = "") {
57
- this.getEntries()[key] = {
32
+ await this.ensureLoaded();
33
+ this.entries[key] = {
58
34
  tool_id: toolId,
59
35
  tool_version: toolVersion,
60
36
  source,
@@ -64,23 +40,26 @@ export class CacheIndex {
64
40
  await this.save();
65
41
  }
66
42
  async remove(key) {
67
- const entries = this.getEntries();
68
- if (key in entries) {
69
- delete entries[key];
43
+ await this.ensureLoaded();
44
+ if (key in this.entries) {
45
+ delete this.entries[key];
70
46
  await this.save();
71
47
  }
72
48
  }
73
- has(key) {
74
- return key in this.getEntries();
49
+ async has(key) {
50
+ await this.ensureLoaded();
51
+ return key in this.entries;
75
52
  }
76
- listAll() {
77
- return Object.entries(this.getEntries()).map(([key, entry]) => ({
53
+ async listAll() {
54
+ await this.ensureLoaded();
55
+ return Object.entries(this.entries).map(([key, entry]) => ({
78
56
  cache_key: key,
79
57
  ...entry,
80
58
  }));
81
59
  }
82
60
  async clear() {
83
61
  this.entries = {};
62
+ this.loaded = true;
84
63
  await this.save();
85
64
  }
86
65
  }
@@ -1 +1 @@
1
- {"version":3,"file":"cache-index.js","sourceRoot":"","sources":["../../src/cache/cache-index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cache-index.js","sourceRoot":"","sources":["../../src/cache/cache-index.ts"],"names":[],"mappings":"AAEA,0DAA0D;AAC1D,MAAM,SAAS,GAAG,WAAW,CAAC;AAkB9B;;;;;;;GAOG;AACH,MAAM,OAAO,UAAU;IAIQ;IAHrB,OAAO,GAAoC,EAAE,CAAC;IAC9C,MAAM,GAAG,KAAK,CAAC;IAEvB,YAA6B,OAAqB;QAArB,YAAO,GAAP,OAAO,CAAc;IAAG,CAAC;IAEtD,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAA0B,CAAC;QAC3E,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,OAAO,IAAI,EAAE,CAAC;QACnC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACrB,CAAC;IAEO,KAAK,CAAC,YAAY;QACxB,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;IACtC,CAAC;IAEO,KAAK,CAAC,IAAI;QAChB,MAAM,IAAI,GAAmB,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;QACvD,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,GAAG,CACP,GAAW,EACX,MAAc,EACd,WAAmB,EACnB,MAAc,EACd,YAAoB,EAAE;QAEtB,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;QAC1B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG;YAClB,OAAO,EAAE,MAAM;YACf,YAAY,EAAE,WAAW;YACzB,MAAM;YACN,UAAU,EAAE,SAAS;YACrB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;QACF,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;IACpB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;QAC1B,IAAI,GAAG,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACzB,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QACpB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;QAC1B,OAAO,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,OAAO;QACX,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;QAC1B,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;YACzD,SAAS,EAAE,GAAG;YACd,GAAG,KAAK;SACT,CAAC,CAAC,CAAC;IACN,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QAClB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;IACpB,CAAC;CACF"}
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * Compute a deterministic cache key (SHA-256 hex) for a tool.
3
3
  * The key is derived from the ToolShed URL, TRS tool ID, and version.
4
+ * Uses the Web Crypto API (available in Node.js ≥15 and all modern browsers/Web Workers).
4
5
  */
5
- export declare function cacheKey(toolshedUrl: string, trsToolId: string, toolVersion: string): string;
6
+ export declare function cacheKey(toolshedUrl: string, trsToolId: string, toolVersion: string): Promise<string>;
6
7
  //# sourceMappingURL=cache-key.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cache-key.d.ts","sourceRoot":"","sources":["../../src/cache/cache-key.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAG5F"}
1
+ {"version":3,"file":"cache-key.d.ts","sourceRoot":"","sources":["../../src/cache/cache-key.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAsB,QAAQ,CAC5B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC,CAOjB"}
@@ -1,10 +1,14 @@
1
- import { createHash } from "node:crypto";
2
1
  /**
3
2
  * Compute a deterministic cache key (SHA-256 hex) for a tool.
4
3
  * The key is derived from the ToolShed URL, TRS tool ID, and version.
4
+ * Uses the Web Crypto API (available in Node.js ≥15 and all modern browsers/Web Workers).
5
5
  */
6
- export function cacheKey(toolshedUrl, trsToolId, toolVersion) {
6
+ export async function cacheKey(toolshedUrl, trsToolId, toolVersion) {
7
7
  const raw = `${toolshedUrl}/${trsToolId}/${toolVersion}`;
8
- return createHash("sha256").update(raw).digest("hex");
8
+ const encoded = new TextEncoder().encode(raw);
9
+ const hashBuffer = await globalThis.crypto.subtle.digest("SHA-256", encoded);
10
+ return Array.from(new Uint8Array(hashBuffer))
11
+ .map((b) => b.toString(16).padStart(2, "0"))
12
+ .join("");
9
13
  }
10
14
  //# sourceMappingURL=cache-key.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cache-key.js","sourceRoot":"","sources":["../../src/cache/cache-key.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,WAAmB,EAAE,SAAiB,EAAE,WAAmB;IAClF,MAAM,GAAG,GAAG,GAAG,WAAW,IAAI,SAAS,IAAI,WAAW,EAAE,CAAC;IACzD,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACxD,CAAC"}
1
+ {"version":3,"file":"cache-key.js","sourceRoot":"","sources":["../../src/cache/cache-key.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,WAAmB,EACnB,SAAiB,EACjB,WAAmB;IAEnB,MAAM,GAAG,GAAG,GAAG,WAAW,IAAI,SAAS,IAAI,WAAW,EAAE,CAAC;IACzD,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC9C,MAAM,UAAU,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAC7E,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC;SAC1C,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;SAC3C,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC"}
@@ -3,5 +3,9 @@ export type { ToolCoordinates } from "./tool-id.js";
3
3
  export { cacheKey } from "./cache-key.js";
4
4
  export { CacheIndex } from "./cache-index.js";
5
5
  export type { CacheIndexEntry, CacheIndexData } from "./cache-index.js";
6
- export { ToolCache, getCacheDir, DEFAULT_CACHE_DIR, CACHE_DIR_ENV_VAR, DEFAULT_TOOLSHED_URL, TOOLSHED_URL_ENV_VAR, } from "./tool-cache.js";
6
+ export { ToolCache } from "./tool-cache.js";
7
+ export type { ResolvedCoordinates } from "./tool-cache.js";
8
+ export { DEFAULT_TOOLSHED_URL, TOOLSHED_URL_ENV_VAR } from "./tool-cache-defaults.js";
9
+ export type { CacheStorage } from "./storage/interface.js";
10
+ export { IndexedDBCacheStorage } from "./storage/indexeddb.js";
7
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClE,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EACL,SAAS,EACT,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClE,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AACtF,YAAY,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC"}
@@ -1,5 +1,7 @@
1
1
  export { parseToolshedToolId, toolIdFromTrs } from "./tool-id.js";
2
2
  export { cacheKey } from "./cache-key.js";
3
3
  export { CacheIndex } from "./cache-index.js";
4
- export { ToolCache, getCacheDir, DEFAULT_CACHE_DIR, CACHE_DIR_ENV_VAR, DEFAULT_TOOLSHED_URL, TOOLSHED_URL_ENV_VAR, } from "./tool-cache.js";
4
+ export { ToolCache } from "./tool-cache.js";
5
+ export { DEFAULT_TOOLSHED_URL, TOOLSHED_URL_ENV_VAR } from "./tool-cache-defaults.js";
6
+ export { IndexedDBCacheStorage } from "./storage/indexeddb.js";
5
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EACL,SAAS,EACT,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAEtF,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,30 @@
1
+ import { ToolCache } from "./tool-cache.js";
2
+ import type { ToolInfoOptions, ToolSource } from "../tool-info.js";
3
+ import { ToolInfoService } from "../tool-info.js";
4
+ export { FilesystemCacheStorage } from "./storage/filesystem.js";
5
+ export { CACHE_DIR_ENV_VAR } from "./tool-cache-defaults.js";
6
+ /** Default cache directory: `~/.galaxy/tool_info_cache`. */
7
+ export declare const DEFAULT_CACHE_DIR: string;
8
+ /** Resolve cache directory: explicit override > env var > default. */
9
+ export declare function getCacheDir(override?: string): string;
10
+ /** Options for `makeNodeToolCache` — same as ToolCache minus `storage`, plus `cacheDir`. */
11
+ export interface NodeToolCacheOptions {
12
+ cacheDir?: string;
13
+ defaultToolshedUrl?: string;
14
+ }
15
+ /**
16
+ * Construct a ToolCache backed by the default filesystem storage.
17
+ * `cacheDir` resolves via {@link getCacheDir} (explicit > env var > default).
18
+ */
19
+ export declare function makeNodeToolCache(opts?: NodeToolCacheOptions): ToolCache;
20
+ /** Options for `makeNodeToolInfoService` — ToolInfoOptions without `storage`, plus `cacheDir`. */
21
+ export interface NodeToolInfoOptions extends Omit<ToolInfoOptions, "storage"> {
22
+ cacheDir?: string;
23
+ sources?: ToolSource[];
24
+ }
25
+ /**
26
+ * Construct a ToolInfoService backed by the default filesystem storage.
27
+ * `cacheDir` resolves via {@link getCacheDir}.
28
+ */
29
+ export declare function makeNodeToolInfoService(opts?: NodeToolInfoOptions): ToolInfoService;
30
+ //# sourceMappingURL=node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/cache/node.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,4DAA4D;AAC5D,eAAO,MAAM,iBAAiB,QAAgD,CAAC;AAE/E,sEAAsE;AACtE,wBAAgB,WAAW,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,4FAA4F;AAC5F,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,CAAC,EAAE,oBAAoB,GAAG,SAAS,CAMxE;AAED,kGAAkG;AAClG,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAAC,eAAe,EAAE,SAAS,CAAC;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,CAAC,EAAE,mBAAmB,GAAG,eAAe,CAMnF"}
@@ -0,0 +1,37 @@
1
+ import { join } from "node:path";
2
+ import { homedir } from "node:os";
3
+ import { FilesystemCacheStorage } from "./storage/filesystem.js";
4
+ import { ToolCache } from "./tool-cache.js";
5
+ import { CACHE_DIR_ENV_VAR } from "./tool-cache-defaults.js";
6
+ import { ToolInfoService } from "../tool-info.js";
7
+ export { FilesystemCacheStorage } from "./storage/filesystem.js";
8
+ export { CACHE_DIR_ENV_VAR } from "./tool-cache-defaults.js";
9
+ /** Default cache directory: `~/.galaxy/tool_info_cache`. */
10
+ export const DEFAULT_CACHE_DIR = join(homedir(), ".galaxy", "tool_info_cache");
11
+ /** Resolve cache directory: explicit override > env var > default. */
12
+ export function getCacheDir(override) {
13
+ return override ?? process.env[CACHE_DIR_ENV_VAR] ?? DEFAULT_CACHE_DIR;
14
+ }
15
+ /**
16
+ * Construct a ToolCache backed by the default filesystem storage.
17
+ * `cacheDir` resolves via {@link getCacheDir} (explicit > env var > default).
18
+ */
19
+ export function makeNodeToolCache(opts) {
20
+ const cacheDir = getCacheDir(opts?.cacheDir);
21
+ return new ToolCache({
22
+ storage: new FilesystemCacheStorage(cacheDir),
23
+ defaultToolshedUrl: opts?.defaultToolshedUrl,
24
+ });
25
+ }
26
+ /**
27
+ * Construct a ToolInfoService backed by the default filesystem storage.
28
+ * `cacheDir` resolves via {@link getCacheDir}.
29
+ */
30
+ export function makeNodeToolInfoService(opts) {
31
+ const cacheDir = getCacheDir(opts?.cacheDir);
32
+ return new ToolInfoService({
33
+ ...opts,
34
+ storage: new FilesystemCacheStorage(cacheDir),
35
+ });
36
+ }
37
+ //# sourceMappingURL=node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/cache/node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,4DAA4D;AAC5D,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,iBAAiB,CAAC,CAAC;AAE/E,sEAAsE;AACtE,MAAM,UAAU,WAAW,CAAC,QAAiB;IAC3C,OAAO,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,iBAAiB,CAAC;AACzE,CAAC;AAQD;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAA2B;IAC3D,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC7C,OAAO,IAAI,SAAS,CAAC;QACnB,OAAO,EAAE,IAAI,sBAAsB,CAAC,QAAQ,CAAC;QAC7C,kBAAkB,EAAE,IAAI,EAAE,kBAAkB;KAC7C,CAAC,CAAC;AACL,CAAC;AAQD;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAA0B;IAChE,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC7C,OAAO,IAAI,eAAe,CAAC;QACzB,GAAG,IAAI;QACP,OAAO,EAAE,IAAI,sBAAsB,CAAC,QAAQ,CAAC;KAC9C,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { CacheStorage } from "./interface.js";
2
+ /**
3
+ * Node.js filesystem-backed CacheStorage.
4
+ * Stores each entry as `<cacheDir>/<key>.json`.
5
+ * The internal `__index__` key maps to `index.json` for backward compatibility.
6
+ */
7
+ export declare class FilesystemCacheStorage implements CacheStorage {
8
+ readonly cacheDir: string;
9
+ constructor(cacheDir: string);
10
+ private keyToPath;
11
+ load(key: string): Promise<unknown | null>;
12
+ save(key: string, data: unknown): Promise<void>;
13
+ delete(key: string): Promise<void>;
14
+ list(): Promise<string[]>;
15
+ saveAll(entries: ReadonlyArray<[string, unknown]>): Promise<void>;
16
+ }
17
+ //# sourceMappingURL=filesystem.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filesystem.d.ts","sourceRoot":"","sources":["../../../src/cache/storage/filesystem.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AASnD;;;;GAIG;AACH,qBAAa,sBAAuB,YAAW,YAAY;IAC7C,QAAQ,CAAC,QAAQ,EAAE,MAAM;gBAAhB,QAAQ,EAAE,MAAM;IAErC,OAAO,CAAC,SAAS;IAKX,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAW1C,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAK/C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKlC,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAQzB,OAAO,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAMxE"}
@@ -0,0 +1,61 @@
1
+ import { readFile, writeFile, mkdir, unlink, readdir } from "node:fs/promises";
2
+ import { existsSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ /**
5
+ * Key used by CacheIndex to store the index metadata.
6
+ * Mapped to "index.json" on disk for backward compatibility with existing caches.
7
+ */
8
+ const INDEX_KEY = "__index__";
9
+ const INDEX_FILENAME = "index.json";
10
+ /**
11
+ * Node.js filesystem-backed CacheStorage.
12
+ * Stores each entry as `<cacheDir>/<key>.json`.
13
+ * The internal `__index__` key maps to `index.json` for backward compatibility.
14
+ */
15
+ export class FilesystemCacheStorage {
16
+ cacheDir;
17
+ constructor(cacheDir) {
18
+ this.cacheDir = cacheDir;
19
+ }
20
+ keyToPath(key) {
21
+ if (key === INDEX_KEY)
22
+ return join(this.cacheDir, INDEX_FILENAME);
23
+ return join(this.cacheDir, `${key}.json`);
24
+ }
25
+ async load(key) {
26
+ const path = this.keyToPath(key);
27
+ if (!existsSync(path))
28
+ return null;
29
+ try {
30
+ const raw = await readFile(path, "utf-8");
31
+ return JSON.parse(raw);
32
+ }
33
+ catch {
34
+ return null;
35
+ }
36
+ }
37
+ async save(key, data) {
38
+ await mkdir(this.cacheDir, { recursive: true });
39
+ await writeFile(this.keyToPath(key), JSON.stringify(data, null, 2));
40
+ }
41
+ async delete(key) {
42
+ const path = this.keyToPath(key);
43
+ if (existsSync(path))
44
+ await unlink(path);
45
+ }
46
+ async list() {
47
+ if (!existsSync(this.cacheDir))
48
+ return [];
49
+ const files = await readdir(this.cacheDir);
50
+ return files
51
+ .filter((f) => f.endsWith(".json") && f !== INDEX_FILENAME)
52
+ .map((f) => f.slice(0, -5));
53
+ }
54
+ async saveAll(entries) {
55
+ await mkdir(this.cacheDir, { recursive: true });
56
+ for (const [key, data] of entries) {
57
+ await writeFile(this.keyToPath(key), JSON.stringify(data, null, 2));
58
+ }
59
+ }
60
+ }
61
+ //# sourceMappingURL=filesystem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filesystem.js","sourceRoot":"","sources":["../../../src/cache/storage/filesystem.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC/E,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAIjC;;;GAGG;AACH,MAAM,SAAS,GAAG,WAAW,CAAC;AAC9B,MAAM,cAAc,GAAG,YAAY,CAAC;AAEpC;;;;GAIG;AACH,MAAM,OAAO,sBAAsB;IACZ;IAArB,YAAqB,QAAgB;QAAhB,aAAQ,GAAR,QAAQ,CAAQ;IAAG,CAAC;IAEjC,SAAS,CAAC,GAAW;QAC3B,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;QAClE,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,GAAG,OAAO,CAAC,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAW;QACpB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACnC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAC1C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAY,CAAC;QACpC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAW,EAAE,IAAa;QACnC,MAAM,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,MAAM,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACtE,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,UAAU,CAAC,IAAI,CAAC;YAAE,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC;YAAE,OAAO,EAAE,CAAC;QAC1C,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC3C,OAAO,KAAK;aACT,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,cAAc,CAAC;aAC1D,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,OAAyC;QACrD,MAAM,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,OAAO,EAAE,CAAC;YAClC,MAAM,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,21 @@
1
+ import type { CacheStorage } from "./interface.js";
2
+ /**
3
+ * IndexedDB-backed CacheStorage for browser and Web Worker contexts.
4
+ * Suitable for VS Code web extension language servers running as Web Workers.
5
+ *
6
+ * Storage quota: ~80% of free disk space per origin via the Storage Quota API.
7
+ * A large cache (10,000 tools × 50 KB avg) ≈ 500 MB — well within typical limits.
8
+ */
9
+ export declare class IndexedDBCacheStorage implements CacheStorage {
10
+ private readonly dbName;
11
+ private db;
12
+ constructor(dbName?: string);
13
+ private getDb;
14
+ load(key: string): Promise<unknown | null>;
15
+ save(key: string, data: unknown): Promise<void>;
16
+ delete(key: string): Promise<void>;
17
+ list(): Promise<string[]>;
18
+ /** Bulk insert using a single transaction — efficient for pre-populating from a bundled dataset. */
19
+ saveAll(entries: ReadonlyArray<[string, unknown]>): Promise<void>;
20
+ }
21
+ //# sourceMappingURL=indexeddb.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexeddb.d.ts","sourceRoot":"","sources":["../../../src/cache/storage/indexeddb.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAQnD;;;;;;GAMG;AACH,qBAAa,qBAAsB,YAAW,YAAY;IAG5C,OAAO,CAAC,QAAQ,CAAC,MAAM;IAFnC,OAAO,CAAC,EAAE,CAA4B;gBAET,MAAM,GAAE,MAAwB;IAE7D,OAAO,CAAC,KAAK;IAkBP,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAU1C,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAU/C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUlC,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAW/B,oGAAoG;IAC9F,OAAO,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAYxE"}
@@ -0,0 +1,87 @@
1
+ /** Stable database name — increment version suffix on schema changes. */
2
+ const DEFAULT_DB_NAME = "galaxy-tool-cache-v1";
3
+ const STORE_NAME = "data";
4
+ /** Reserved key used by CacheIndex to store the index metadata object. */
5
+ const INDEX_KEY = "__index__";
6
+ /**
7
+ * IndexedDB-backed CacheStorage for browser and Web Worker contexts.
8
+ * Suitable for VS Code web extension language servers running as Web Workers.
9
+ *
10
+ * Storage quota: ~80% of free disk space per origin via the Storage Quota API.
11
+ * A large cache (10,000 tools × 50 KB avg) ≈ 500 MB — well within typical limits.
12
+ */
13
+ export class IndexedDBCacheStorage {
14
+ dbName;
15
+ db = null;
16
+ constructor(dbName = DEFAULT_DB_NAME) {
17
+ this.dbName = dbName;
18
+ }
19
+ getDb() {
20
+ if (this.db !== null)
21
+ return Promise.resolve(this.db);
22
+ return new Promise((resolve, reject) => {
23
+ const req = indexedDB.open(this.dbName, 1);
24
+ req.onupgradeneeded = (e) => {
25
+ const db = e.target.result;
26
+ if (!db.objectStoreNames.contains(STORE_NAME)) {
27
+ db.createObjectStore(STORE_NAME);
28
+ }
29
+ };
30
+ req.onsuccess = (e) => {
31
+ this.db = e.target.result;
32
+ resolve(this.db);
33
+ };
34
+ req.onerror = () => reject(req.error);
35
+ });
36
+ }
37
+ async load(key) {
38
+ const db = await this.getDb();
39
+ return new Promise((resolve, reject) => {
40
+ const tx = db.transaction(STORE_NAME, "readonly");
41
+ const req = tx.objectStore(STORE_NAME).get(key);
42
+ req.onsuccess = () => resolve(req.result ?? null);
43
+ req.onerror = () => reject(req.error);
44
+ });
45
+ }
46
+ async save(key, data) {
47
+ const db = await this.getDb();
48
+ return new Promise((resolve, reject) => {
49
+ const tx = db.transaction(STORE_NAME, "readwrite");
50
+ tx.objectStore(STORE_NAME).put(data, key);
51
+ tx.oncomplete = () => resolve();
52
+ tx.onerror = () => reject(tx.error);
53
+ });
54
+ }
55
+ async delete(key) {
56
+ const db = await this.getDb();
57
+ return new Promise((resolve, reject) => {
58
+ const tx = db.transaction(STORE_NAME, "readwrite");
59
+ tx.objectStore(STORE_NAME).delete(key);
60
+ tx.oncomplete = () => resolve();
61
+ tx.onerror = () => reject(tx.error);
62
+ });
63
+ }
64
+ async list() {
65
+ const db = await this.getDb();
66
+ return new Promise((resolve, reject) => {
67
+ const tx = db.transaction(STORE_NAME, "readonly");
68
+ const req = tx.objectStore(STORE_NAME).getAllKeys();
69
+ req.onsuccess = () => resolve(req.result.filter((k) => k !== INDEX_KEY));
70
+ req.onerror = () => reject(req.error);
71
+ });
72
+ }
73
+ /** Bulk insert using a single transaction — efficient for pre-populating from a bundled dataset. */
74
+ async saveAll(entries) {
75
+ const db = await this.getDb();
76
+ return new Promise((resolve, reject) => {
77
+ const tx = db.transaction(STORE_NAME, "readwrite");
78
+ const store = tx.objectStore(STORE_NAME);
79
+ for (const [key, data] of entries) {
80
+ store.put(data, key);
81
+ }
82
+ tx.oncomplete = () => resolve();
83
+ tx.onerror = () => reject(tx.error);
84
+ });
85
+ }
86
+ }
87
+ //# sourceMappingURL=indexeddb.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexeddb.js","sourceRoot":"","sources":["../../../src/cache/storage/indexeddb.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Pluggable storage backend for the tool cache.
3
+ * Implementations: FilesystemCacheStorage (Node.js), IndexedDBCacheStorage (browser/Web Worker).
4
+ */
5
+ export interface CacheStorage {
6
+ /** Load a value by key. Returns null if not found. */
7
+ load(key: string): Promise<unknown | null>;
8
+ /** Persist a value under key. Creates storage if needed. */
9
+ save(key: string, data: unknown): Promise<void>;
10
+ /** Remove a key. No-op if not found. */
11
+ delete(key: string): Promise<void>;
12
+ /** List all tool keys (excludes internal metadata keys). */
13
+ list(): Promise<string[]>;
14
+ /** Optional bulk insert — single transaction for efficiency (e.g. pre-populating from bundle). */
15
+ saveAll?(entries: ReadonlyArray<[string, unknown]>): Promise<void>;
16
+ }
17
+ //# sourceMappingURL=interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../src/cache/storage/interface.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,sDAAsD;IACtD,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAC3C,4DAA4D;IAC5D,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,wCAAwC;IACxC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,4DAA4D;IAC5D,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1B,kGAAkG;IAClG,OAAO,CAAC,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpE"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interface.js","sourceRoot":"","sources":["../../../src/cache/storage/interface.ts"],"names":[],"mappings":""}