@muhkoo/connect 0.10.5-alpha.0 → 0.10.7-alpha.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.
@@ -5057,7 +5057,7 @@ function base64UrlDecode(s) {
5057
5057
  * expect (and isn't serving a stale cached bundle). Keep this in sync with
5058
5058
  * `package.json` `version`.
5059
5059
  */
5060
- const VERSION = "0.10.5-alpha.0";
5060
+ const VERSION = "0.10.7-alpha.0";
5061
5061
 
5062
5062
  /**
5063
5063
  * `HttpClient` — the one place the unified {@link Client} talks to the
@@ -7599,12 +7599,53 @@ class Space {
7599
7599
  }
7600
7600
  // -- room-scoped files (no websocket needed) -------------------------------
7601
7601
  async putFile(file, metadata, opts = {}) {
7602
- return this.fileStorage(opts.backgroundUpload)
7602
+ const result = await this.fileStorage(opts.backgroundUpload)
7603
7603
  .writeFileToShards({ data: file, metadata, onProgress: opts.onProgress });
7604
+ // Declare this manifest's shards to the accelerator: attributes the stored
7605
+ // bytes to the owning app (so storage is never unmetered) and reference-
7606
+ // counts the shards for GC. Public shard hashes only — the per-chunk keys
7607
+ // stay inside the manifest, which the caller keeps in a vault/Space.
7608
+ await this.commitShards(result.manifest, "commit");
7609
+ return result;
7604
7610
  }
7605
7611
  async getFile(manifest) {
7606
7612
  return this.fileStorage().readFileFromShards(manifest);
7607
7613
  }
7614
+ /** Declare a file's shards (ref++ + meter) for a manifest already stored —
7615
+ * used to back-fill accounting for files written before commit existed, or to
7616
+ * register a manifest received via sharing. `putFile` already commits new
7617
+ * writes automatically; this is the explicit form. */
7618
+ async commitFile(manifest) {
7619
+ await this.commitShards(manifest, "commit");
7620
+ }
7621
+ /** Release a file's shards (ref--) when the owner deletes or unshares it. At
7622
+ * zero references a shard enters a retention window, then is GC'd. Idempotent-
7623
+ * ish: safe to call once per manifest the owner drops. */
7624
+ async releaseFile(manifest) {
7625
+ await this.commitShards(manifest, "release");
7626
+ }
7627
+ /** Commit/release a manifest's shards with the accelerator (metering + refcount). */
7628
+ async commitShards(manifest, action) {
7629
+ const hashes = manifest.chunks.flatMap((c) => c.shardHashes);
7630
+ if (hashes.length === 0)
7631
+ return;
7632
+ const body = JSON.stringify({ hashes, bytes: manifest.size });
7633
+ for (let attempt = 0; attempt < 3; attempt++) {
7634
+ try {
7635
+ const res = await this.deps.fetch(`${this.deps.httpBaseUrl}/api/storage/${action}`, {
7636
+ method: "POST", headers: { "Content-Type": "application/json" }, body,
7637
+ });
7638
+ if (res.ok)
7639
+ return;
7640
+ }
7641
+ catch { /* retry */ }
7642
+ await new Promise((r) => setTimeout(r, 400 * (attempt + 1)));
7643
+ }
7644
+ // Best-effort: a missed commit leaves the shards to orphan-GC (still not
7645
+ // durable-unmetered long-term); a missed release just delays GC. Reconciled
7646
+ // by the platform sweep. Don't fail the caller's write on a metering hiccup.
7647
+ console.warn(`[muhkoo] storage ${action} did not confirm for ${hashes.length} shard(s)`);
7648
+ }
7608
7649
  fileStorage(backgroundUpload = false) {
7609
7650
  // Global, content-addressed shard store — same store `client.storage`
7610
7651
  // uses, so a file shared into a channel resolves from anywhere by