@resourcexjs/core 2.20.0 → 2.22.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.
package/dist/index.d.ts CHANGED
@@ -853,6 +853,14 @@ declare class CASRegistry implements Registry {
853
853
  remove(rxi: RXI): Promise<void>;
854
854
  list(options?: SearchOptions): Promise<RXI[]>;
855
855
  /**
856
+ * Get a single file from a resource by filename.
857
+ * Looks up the file's digest in the manifest, then retrieves the blob directly.
858
+ * Much cheaper than get() — no archive reassembly needed.
859
+ *
860
+ * @returns File content as Buffer, or null if resource or file not found.
861
+ */
862
+ getFile(rxi: RXI, file: string): Promise<Buffer | null>;
863
+ /**
856
864
  * Get stored manifest metadata without extracting file contents.
857
865
  * Useful for freshness checks (accessing updatedAt) without the cost of blob retrieval.
858
866
  */
@@ -867,6 +875,18 @@ declare class CASRegistry implements Registry {
867
875
  */
868
876
  gc(): Promise<number>;
869
877
  /**
878
+ * Append files to an existing resource without re-archiving.
879
+ *
880
+ * Leverages per-file CAS storage: only new files are written to blob store,
881
+ * then the manifest's file map is extended and the digest recomputed.
882
+ *
883
+ * @param rxi - Resource identifier (name + tag)
884
+ * @param newFiles - Files to append: relative path → content
885
+ * @returns Updated StoredRXM
886
+ * @throws RegistryError if resource not found
887
+ */
888
+ append(rxi: RXI, newFiles: Record<string, Buffer>): Promise<StoredRXM>;
889
+ /**
870
890
  * Check if a digest exists in the blob store.
871
891
  * Useful for "instant upload" - skip uploading if server already has it.
872
892
  */
package/dist/index.js CHANGED
@@ -15348,6 +15348,16 @@ class CASRegistry {
15348
15348
  tag: m.tag
15349
15349
  }));
15350
15350
  }
15351
+ async getFile(rxi, file2) {
15352
+ const tag = await this.resolveTag(rxi.name, rxi.tag ?? "latest", rxi.registry);
15353
+ const storedRxm = await this.rxmStore.get(rxi.name, tag, rxi.registry);
15354
+ if (!storedRxm)
15355
+ return null;
15356
+ const digest = storedRxm.files[file2];
15357
+ if (!digest)
15358
+ return null;
15359
+ return this.rxaStore.get(digest);
15360
+ }
15351
15361
  async getStoredManifest(rxi) {
15352
15362
  const tag = await this.resolveTag(rxi.name, rxi.tag ?? "latest", rxi.registry);
15353
15363
  return this.rxmStore.get(rxi.name, tag, rxi.registry);
@@ -15382,6 +15392,26 @@ class CASRegistry {
15382
15392
  }
15383
15393
  return deleted;
15384
15394
  }
15395
+ async append(rxi, newFiles) {
15396
+ const tag = await this.resolveTag(rxi.name, rxi.tag ?? "latest", rxi.registry);
15397
+ const existing = await this.rxmStore.get(rxi.name, tag, rxi.registry);
15398
+ if (!existing) {
15399
+ throw new RegistryError(`Resource not found: ${format(rxi)}`);
15400
+ }
15401
+ const mergedFiles = { ...existing.files };
15402
+ for (const [filename, content] of Object.entries(newFiles)) {
15403
+ mergedFiles[filename] = await this.rxaStore.put(content);
15404
+ }
15405
+ const digest = await computeArchiveDigest(mergedFiles);
15406
+ const updated = {
15407
+ ...existing,
15408
+ digest,
15409
+ files: mergedFiles,
15410
+ updatedAt: new Date
15411
+ };
15412
+ await this.rxmStore.put(updated);
15413
+ return updated;
15414
+ }
15385
15415
  async hasBlob(digest) {
15386
15416
  return this.rxaStore.has(digest);
15387
15417
  }
@@ -15740,4 +15770,4 @@ export {
15740
15770
  CASRegistry
15741
15771
  };
15742
15772
 
15743
- //# debugId=72D5E1C3B1B1B3BE64756E2164756E21
15773
+ //# debugId=22A475515B34B19264756E2164756E21