@muhkoo/connect 0.15.0-alpha.4 → 0.15.0-alpha.5
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/browser/blockEngine.worker.js.map +1 -1
- package/dist/browser/index.js +352 -59
- package/dist/browser/index.js.map +1 -1
- package/dist/connect.d.ts +190 -15
- package/dist/connect.workers.d.ts +55 -2
- package/dist/server/index.js +352 -59
- package/dist/server/index.js.map +1 -1
- package/dist/workers/index.js +62 -1
- package/dist/workers/index.js.map +1 -1
- package/package.json +1 -1
package/dist/server/index.js
CHANGED
|
@@ -2742,6 +2742,106 @@ class BroadcastChannel {
|
|
|
2742
2742
|
}
|
|
2743
2743
|
}
|
|
2744
2744
|
|
|
2745
|
+
/**
|
|
2746
|
+
* `HttpError` — thrown for any non-2xx accelerator response.
|
|
2747
|
+
*
|
|
2748
|
+
* In a module of its own so that `PaymentRequiredError` can extend it while
|
|
2749
|
+
* `HttpClient`, which throws both, imports `PaymentRequiredError`: with the
|
|
2750
|
+
* class in `HttpClient.ts`, the two modules would import each other, and
|
|
2751
|
+
* whichever loaded second would extend a class not yet defined. `HttpClient`
|
|
2752
|
+
* re-exports it, so `import { HttpError } from "./HttpClient"` still works.
|
|
2753
|
+
*/
|
|
2754
|
+
/** Thrown for any non-2xx accelerator response. Carries the HTTP status. */
|
|
2755
|
+
class HttpError extends Error {
|
|
2756
|
+
status;
|
|
2757
|
+
body;
|
|
2758
|
+
constructor(message, status, body) {
|
|
2759
|
+
super(message);
|
|
2760
|
+
this.status = status;
|
|
2761
|
+
this.body = body;
|
|
2762
|
+
this.name = "HttpError";
|
|
2763
|
+
}
|
|
2764
|
+
}
|
|
2765
|
+
|
|
2766
|
+
/**
|
|
2767
|
+
* `PaymentRequiredError` — a write the accelerator refused for payment
|
|
2768
|
+
* (accelerator spec 2026-10-06-paid-accounts-and-past-due, "Interfaces and
|
|
2769
|
+
* contracts").
|
|
2770
|
+
*
|
|
2771
|
+
* The accelerator answers such a write with a 402 whose body carries one of
|
|
2772
|
+
* three codes:
|
|
2773
|
+
* - `user_plan_required`: the app takes paid Muhkoo plans only, and the
|
|
2774
|
+
* signed-in user is on Free;
|
|
2775
|
+
* - `user_payment_past_due`: the user's own Muhkoo payment is past due. Only
|
|
2776
|
+
* first-party apps are told this; every other app is told
|
|
2777
|
+
* `user_plan_required` instead;
|
|
2778
|
+
* - `owner_payment_past_due`: the app owner's payment is past due, so the
|
|
2779
|
+
* app stores nothing new for anyone.
|
|
2780
|
+
* Reads, sign-in and deletes still work in all three cases.
|
|
2781
|
+
*
|
|
2782
|
+
* Every other 402 — the Free-tier refusals that carry `quotaExceeded`,
|
|
2783
|
+
* `requiresPaidTier` or `freeTierFull` — has no `code`, and stays a plain
|
|
2784
|
+
* `HttpError`, as before.
|
|
2785
|
+
*/
|
|
2786
|
+
const CODES = new Set([
|
|
2787
|
+
"user_plan_required",
|
|
2788
|
+
"user_payment_past_due",
|
|
2789
|
+
"owner_payment_past_due",
|
|
2790
|
+
]);
|
|
2791
|
+
/** True for one of the three {@link PaymentRequiredCode}s. */
|
|
2792
|
+
function isPaymentRequiredCode(value) {
|
|
2793
|
+
return typeof value === "string" && CODES.has(value);
|
|
2794
|
+
}
|
|
2795
|
+
/** `url` when it is an absolute http(s) URL, else undefined: an app may put it straight into a link. */
|
|
2796
|
+
function absoluteHttpUrl(url) {
|
|
2797
|
+
return typeof url === "string" && /^https?:\/\/[^/]/i.test(url) ? url : undefined;
|
|
2798
|
+
}
|
|
2799
|
+
/** Thrown for a 402 whose body carries one of the three {@link PaymentRequiredCode}s. */
|
|
2800
|
+
class PaymentRequiredError extends HttpError {
|
|
2801
|
+
/** Why the write was refused. */
|
|
2802
|
+
code;
|
|
2803
|
+
/**
|
|
2804
|
+
* Where to send the user: the portal's upgrade page or its billing page,
|
|
2805
|
+
* as an absolute URL. Set only when the server sent an absolute http(s)
|
|
2806
|
+
* URL. The relative `upgradeUrl` of the Free-tier refusals is never here:
|
|
2807
|
+
* those are not this error.
|
|
2808
|
+
*/
|
|
2809
|
+
upgradeUrl;
|
|
2810
|
+
constructor(message, code, body, upgradeUrl) {
|
|
2811
|
+
super(message, 402, body);
|
|
2812
|
+
this.name = "PaymentRequiredError";
|
|
2813
|
+
this.code = code;
|
|
2814
|
+
if (upgradeUrl !== undefined)
|
|
2815
|
+
this.upgradeUrl = upgradeUrl;
|
|
2816
|
+
}
|
|
2817
|
+
}
|
|
2818
|
+
/**
|
|
2819
|
+
* The error to throw for a refused response: a {@link PaymentRequiredError}
|
|
2820
|
+
* for a 402 whose body carries one of the three codes, and null for anything
|
|
2821
|
+
* else, so the caller throws what it threw before. `body` is the parsed JSON,
|
|
2822
|
+
* or the raw text of the response, which is parsed here.
|
|
2823
|
+
*/
|
|
2824
|
+
function paymentRequiredFrom(status, body) {
|
|
2825
|
+
if (status !== 402)
|
|
2826
|
+
return null;
|
|
2827
|
+
let parsed = body;
|
|
2828
|
+
if (typeof parsed === "string") {
|
|
2829
|
+
try {
|
|
2830
|
+
parsed = JSON.parse(parsed);
|
|
2831
|
+
}
|
|
2832
|
+
catch {
|
|
2833
|
+
return null;
|
|
2834
|
+
}
|
|
2835
|
+
}
|
|
2836
|
+
if (!parsed || typeof parsed !== "object")
|
|
2837
|
+
return null;
|
|
2838
|
+
const { code, error, upgradeUrl } = parsed;
|
|
2839
|
+
if (!isPaymentRequiredCode(code))
|
|
2840
|
+
return null;
|
|
2841
|
+
const message = typeof error === "string" && error ? error : `Payment required (${code})`;
|
|
2842
|
+
return new PaymentRequiredError(message, code, parsed, absoluteHttpUrl(upgradeUrl));
|
|
2843
|
+
}
|
|
2844
|
+
|
|
2745
2845
|
function _loadWasmModule (sync, filepath, src, imports) {
|
|
2746
2846
|
function _instantiateOrCompile(source, imports, stream) {
|
|
2747
2847
|
var instantiateFunc = WebAssembly.instantiate;
|
|
@@ -5261,14 +5361,19 @@ function nonceHexToFieldString(nonceHex) {
|
|
|
5261
5361
|
*/
|
|
5262
5362
|
async function parseOrThrow$1(response, label) {
|
|
5263
5363
|
if (!response.ok) {
|
|
5264
|
-
let
|
|
5364
|
+
let text = "";
|
|
5265
5365
|
try {
|
|
5266
|
-
|
|
5267
|
-
detail = text ? `: ${text}` : "";
|
|
5366
|
+
text = await response.text();
|
|
5268
5367
|
}
|
|
5269
5368
|
catch {
|
|
5270
5369
|
// ignore — we'll just use the status code
|
|
5271
5370
|
}
|
|
5371
|
+
// A put refused for payment: its own class. Every other failure is the
|
|
5372
|
+
// plain Error it always was.
|
|
5373
|
+
const refused = paymentRequiredFrom(response.status, text);
|
|
5374
|
+
if (refused)
|
|
5375
|
+
throw refused;
|
|
5376
|
+
const detail = text ? `: ${text}` : "";
|
|
5272
5377
|
throw new Error(`PersonalSpaceClient ${label} failed (${response.status})${detail}`);
|
|
5273
5378
|
}
|
|
5274
5379
|
return (await response.json());
|
|
@@ -5916,6 +6021,8 @@ class ShardClient {
|
|
|
5916
6021
|
baseUrl;
|
|
5917
6022
|
pathPrefix;
|
|
5918
6023
|
fetchFn;
|
|
6024
|
+
/** What a PUT goes through: {@link ShardClientOptions.fetchWithRecovery} when given, else {@link fetchFn}. */
|
|
6025
|
+
putFn;
|
|
5919
6026
|
cache;
|
|
5920
6027
|
/** Hashes waiting for the next batch, each with everyone awaiting it and its size if a caller gave it. */
|
|
5921
6028
|
pendingShards;
|
|
@@ -5940,6 +6047,7 @@ class ShardClient {
|
|
|
5940
6047
|
throw new Error("ShardClient: `globalThis.fetch` is unavailable; pass an explicit fetch.");
|
|
5941
6048
|
}
|
|
5942
6049
|
this.fetchFn = f.bind(globalThis);
|
|
6050
|
+
this.putFn = opts.fetchWithRecovery ?? this.fetchFn;
|
|
5943
6051
|
this.cache = opts.cache;
|
|
5944
6052
|
// Coalescing state. `batchSupported` latches false against a deployment
|
|
5945
6053
|
// without the batch route, so we degrade once rather than per request.
|
|
@@ -5983,7 +6091,7 @@ class ShardClient {
|
|
|
5983
6091
|
}
|
|
5984
6092
|
let response;
|
|
5985
6093
|
try {
|
|
5986
|
-
response = await this.
|
|
6094
|
+
response = await this.putFn(url, {
|
|
5987
6095
|
method: "PUT",
|
|
5988
6096
|
headers: { "content-type": "application/octet-stream" },
|
|
5989
6097
|
// BufferSource is what fetch's body expects; a Uint8Array satisfies it.
|
|
@@ -6001,7 +6109,10 @@ class ShardClient {
|
|
|
6001
6109
|
}
|
|
6002
6110
|
if (!response.ok) {
|
|
6003
6111
|
const text = await safeText(response);
|
|
6004
|
-
|
|
6112
|
+
// Refused for payment: its own class, which the offline queue keeps
|
|
6113
|
+
// and an app can tell from any other failure.
|
|
6114
|
+
throw paymentRequiredFrom(response.status, text)
|
|
6115
|
+
?? new Error(`ShardClient.putShard(${hash}) failed (${response.status}): ${text}`);
|
|
6005
6116
|
}
|
|
6006
6117
|
let dedup = false;
|
|
6007
6118
|
try {
|
|
@@ -6053,14 +6164,15 @@ class ShardClient {
|
|
|
6053
6164
|
/** PUT the shard bytes to origin, verifying the server accepted them.
|
|
6054
6165
|
* Used by the background-upload path; throws on network/HTTP failure. */
|
|
6055
6166
|
async uploadToOrigin(url, hash, bytes) {
|
|
6056
|
-
const response = await this.
|
|
6167
|
+
const response = await this.putFn(url, {
|
|
6057
6168
|
method: "PUT",
|
|
6058
6169
|
headers: { "content-type": "application/octet-stream" },
|
|
6059
6170
|
body: bytes,
|
|
6060
6171
|
});
|
|
6061
6172
|
if (!response.ok) {
|
|
6062
6173
|
const text = await safeText(response);
|
|
6063
|
-
throw
|
|
6174
|
+
throw paymentRequiredFrom(response.status, text)
|
|
6175
|
+
?? new Error(`ShardClient.putShard(${hash}) failed (${response.status}): ${text}`);
|
|
6064
6176
|
}
|
|
6065
6177
|
}
|
|
6066
6178
|
/**
|
|
@@ -6723,6 +6835,10 @@ async function parseOrThrow(response, op) {
|
|
|
6723
6835
|
// non-JSON body
|
|
6724
6836
|
}
|
|
6725
6837
|
if (!response.ok) {
|
|
6838
|
+
// A manifest write refused for payment (a gated Space write): its own class.
|
|
6839
|
+
const refused = paymentRequiredFrom(response.status, parsed);
|
|
6840
|
+
if (refused)
|
|
6841
|
+
throw refused;
|
|
6726
6842
|
const msg = parsed && typeof parsed === "object" && "error" in parsed
|
|
6727
6843
|
? String(parsed.error)
|
|
6728
6844
|
: `${response.status} ${response.statusText}`;
|
|
@@ -6739,7 +6855,7 @@ async function parseOrThrow(response, op) {
|
|
|
6739
6855
|
* expect (and isn't serving a stale cached bundle). Keep this in sync with
|
|
6740
6856
|
* `package.json` `version`.
|
|
6741
6857
|
*/
|
|
6742
|
-
const VERSION = "0.15.0-alpha.
|
|
6858
|
+
const VERSION = "0.15.0-alpha.5";
|
|
6743
6859
|
|
|
6744
6860
|
/**
|
|
6745
6861
|
* `HttpClient` — the one place the unified {@link Client} talks to the
|
|
@@ -6784,17 +6900,6 @@ function reqPath(input) {
|
|
|
6784
6900
|
return "?";
|
|
6785
6901
|
}
|
|
6786
6902
|
}
|
|
6787
|
-
/** Thrown for any non-2xx accelerator response. Carries the HTTP status. */
|
|
6788
|
-
class HttpError extends Error {
|
|
6789
|
-
status;
|
|
6790
|
-
body;
|
|
6791
|
-
constructor(message, status, body) {
|
|
6792
|
-
super(message);
|
|
6793
|
-
this.status = status;
|
|
6794
|
-
this.body = body;
|
|
6795
|
-
this.name = "HttpError";
|
|
6796
|
-
}
|
|
6797
|
-
}
|
|
6798
6903
|
class HttpClient {
|
|
6799
6904
|
baseUrl;
|
|
6800
6905
|
/** Origin of {@link baseUrl} — credentials are only attached same-origin. */
|
|
@@ -6923,7 +7028,9 @@ class HttpClient {
|
|
|
6923
7028
|
const msg = parsed && typeof parsed === "object" && "error" in parsed
|
|
6924
7029
|
? String(parsed.error)
|
|
6925
7030
|
: `${res.status} ${res.statusText}`;
|
|
6926
|
-
|
|
7031
|
+
// A refusal for payment is its own class, so an app can tell it from
|
|
7032
|
+
// any other 4xx; every other error is the HttpError it always was.
|
|
7033
|
+
throw paymentRequiredFrom(res.status, parsed) ?? new HttpError(msg, res.status, parsed);
|
|
6927
7034
|
}
|
|
6928
7035
|
return parsed;
|
|
6929
7036
|
}
|
|
@@ -9667,6 +9774,7 @@ class StorageNamespace {
|
|
|
9667
9774
|
baseUrl: this.deps.baseUrl,
|
|
9668
9775
|
pathPrefix: "/api/shards",
|
|
9669
9776
|
fetch: this.deps.http.fetch,
|
|
9777
|
+
fetchWithRecovery: this.deps.http.fetchWithRecovery,
|
|
9670
9778
|
cache: this.deps.shardCache,
|
|
9671
9779
|
deferUpload: this.deps.deferShardUpload,
|
|
9672
9780
|
});
|
|
@@ -9685,6 +9793,59 @@ class StorageNamespace {
|
|
|
9685
9793
|
}
|
|
9686
9794
|
}
|
|
9687
9795
|
|
|
9796
|
+
/**
|
|
9797
|
+
* `POST /api/storage/commit` and `/api/storage/release`: take or drop a
|
|
9798
|
+
* reference to a manifest's shards.
|
|
9799
|
+
*
|
|
9800
|
+
* The commit is what meters a file's bytes to the app and reference-counts
|
|
9801
|
+
* its shards, so garbage collection keeps them; the release drops that
|
|
9802
|
+
* reference. The body is `{ hashes, bytes }` and nothing else. The accelerator
|
|
9803
|
+
* keys its reference ledger on the caller, the app, the bytes and the sorted
|
|
9804
|
+
* hashes, so this body must not change: a commit sent in another shape would
|
|
9805
|
+
* take a second reference instead of finding the first.
|
|
9806
|
+
*
|
|
9807
|
+
* Shared by `Space` (`putFile`, `commitFile`, `releaseFile`) and by
|
|
9808
|
+
* `client.vfs`, which takes and drops references here directly. A reference
|
|
9809
|
+
* names only shards and needs no Space; opening the content space to take one
|
|
9810
|
+
* created that space for a user who had never written a file, which a
|
|
9811
|
+
* paid-only app refuses for a Free user (accelerator spec
|
|
9812
|
+
* 2026-10-06-paid-accounts-and-past-due, D12).
|
|
9813
|
+
*
|
|
9814
|
+
* Internal: not re-exported from any barrel.
|
|
9815
|
+
*/
|
|
9816
|
+
/**
|
|
9817
|
+
* Commit or release `manifest`'s shards through `fetchFn`, which should be
|
|
9818
|
+
* `HttpClient.fetchWithRecovery`, so a dead session is re-established once
|
|
9819
|
+
* rather than refused three times. Best-effort: tries three times, or once
|
|
9820
|
+
* for a 401, then warns and returns, without failing the caller's write.
|
|
9821
|
+
*/
|
|
9822
|
+
async function commitManifest(fetchFn, httpBaseUrl, manifest, action) {
|
|
9823
|
+
const hashes = manifest.chunks.flatMap((c) => c.shardHashes);
|
|
9824
|
+
if (hashes.length === 0)
|
|
9825
|
+
return;
|
|
9826
|
+
const body = JSON.stringify({ hashes, bytes: manifest.size });
|
|
9827
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
9828
|
+
try {
|
|
9829
|
+
const res = await fetchFn(`${httpBaseUrl}/api/storage/${action}`, {
|
|
9830
|
+
method: "POST", headers: { "Content-Type": "application/json" }, body,
|
|
9831
|
+
});
|
|
9832
|
+
if (res.ok)
|
|
9833
|
+
return;
|
|
9834
|
+
// A 401 that `fetchFn`'s recovery could not fix. Another try
|
|
9835
|
+
// would only run that recovery again (`auth.zk.recover()`, and
|
|
9836
|
+
// `onSessionExpired` for the app) and be refused again.
|
|
9837
|
+
if (res.status === 401)
|
|
9838
|
+
break;
|
|
9839
|
+
}
|
|
9840
|
+
catch { /* retry */ }
|
|
9841
|
+
await new Promise((r) => setTimeout(r, 400 * (attempt + 1)));
|
|
9842
|
+
}
|
|
9843
|
+
// Best-effort: a missed commit leaves the shards to orphan-GC (still not
|
|
9844
|
+
// durable-unmetered long-term); a missed release just delays GC. Reconciled
|
|
9845
|
+
// by the platform sweep. Don't fail the caller's write on a metering hiccup.
|
|
9846
|
+
console.warn(`[muhkoo] storage ${action} did not confirm for ${hashes.length} shard(s)`);
|
|
9847
|
+
}
|
|
9848
|
+
|
|
9688
9849
|
/**
|
|
9689
9850
|
* SpaceCipher — pure crypto for the fan-out group-encryption layer.
|
|
9690
9851
|
*
|
|
@@ -11068,25 +11229,10 @@ class Space {
|
|
|
11068
11229
|
}
|
|
11069
11230
|
/** Commit/release a manifest's shards with the accelerator (metering + refcount). */
|
|
11070
11231
|
async commitShards(manifest, action) {
|
|
11071
|
-
|
|
11072
|
-
|
|
11073
|
-
|
|
11074
|
-
|
|
11075
|
-
for (let attempt = 0; attempt < 3; attempt++) {
|
|
11076
|
-
try {
|
|
11077
|
-
const res = await this.deps.fetch(`${this.deps.httpBaseUrl}/api/storage/${action}`, {
|
|
11078
|
-
method: "POST", headers: { "Content-Type": "application/json" }, body,
|
|
11079
|
-
});
|
|
11080
|
-
if (res.ok)
|
|
11081
|
-
return;
|
|
11082
|
-
}
|
|
11083
|
-
catch { /* retry */ }
|
|
11084
|
-
await new Promise((r) => setTimeout(r, 400 * (attempt + 1)));
|
|
11085
|
-
}
|
|
11086
|
-
// Best-effort: a missed commit leaves the shards to orphan-GC (still not
|
|
11087
|
-
// durable-unmetered long-term); a missed release just delays GC. Reconciled
|
|
11088
|
-
// by the platform sweep. Don't fail the caller's write on a metering hiccup.
|
|
11089
|
-
console.warn(`[muhkoo] storage ${action} did not confirm for ${hashes.length} shard(s)`);
|
|
11232
|
+
// Through the client's 401 recovery when there is one: the commit refuses
|
|
11233
|
+
// a dead session with 401, and three tries with the same token only
|
|
11234
|
+
// delayed the warning.
|
|
11235
|
+
await commitManifest(this.deps.fetchWithRecovery ?? this.deps.fetch, this.deps.httpBaseUrl, manifest, action);
|
|
11090
11236
|
}
|
|
11091
11237
|
fileStorage(backgroundUpload = false) {
|
|
11092
11238
|
// Global, content-addressed shard store — same store `client.storage`
|
|
@@ -11097,6 +11243,7 @@ class Space {
|
|
|
11097
11243
|
baseUrl: this.deps.httpBaseUrl,
|
|
11098
11244
|
pathPrefix: "/api/shards",
|
|
11099
11245
|
fetch: this.deps.fetch,
|
|
11246
|
+
fetchWithRecovery: this.deps.fetchWithRecovery,
|
|
11100
11247
|
cache: this.deps.shardCache,
|
|
11101
11248
|
deferUpload: this.deps.deferShardUpload,
|
|
11102
11249
|
peers: this.peerNet?.exchange,
|
|
@@ -11500,6 +11647,7 @@ class MessageNamespace {
|
|
|
11500
11647
|
wsBaseUrl: this.deps.wsBaseUrl,
|
|
11501
11648
|
httpBaseUrl: this.deps.http.baseUrl,
|
|
11502
11649
|
fetch: this.deps.http.fetch,
|
|
11650
|
+
fetchWithRecovery: this.deps.http.fetchWithRecovery,
|
|
11503
11651
|
myId: () => this.myId(),
|
|
11504
11652
|
fetchTicket: () => this.fetchTicket(),
|
|
11505
11653
|
});
|
|
@@ -13821,6 +13969,7 @@ class SpaceNamespace {
|
|
|
13821
13969
|
wsBaseUrl: this.deps.wsBaseUrl,
|
|
13822
13970
|
httpBaseUrl: this.deps.http.baseUrl,
|
|
13823
13971
|
fetch: this.deps.http.fetch,
|
|
13972
|
+
fetchWithRecovery: this.deps.http.fetchWithRecovery,
|
|
13824
13973
|
myId: () => memberId,
|
|
13825
13974
|
fetchTicket: () => this.fetchTicket(),
|
|
13826
13975
|
historyPolicy,
|
|
@@ -13876,6 +14025,7 @@ class SpaceNamespace {
|
|
|
13876
14025
|
wsBaseUrl: this.deps.wsBaseUrl,
|
|
13877
14026
|
httpBaseUrl: this.deps.http.baseUrl,
|
|
13878
14027
|
fetch: this.deps.http.fetch,
|
|
14028
|
+
fetchWithRecovery: this.deps.http.fetchWithRecovery,
|
|
13879
14029
|
myId: () => memberId,
|
|
13880
14030
|
fetchTicket: () => this.fetchTicket(),
|
|
13881
14031
|
keyring,
|
|
@@ -14251,6 +14401,66 @@ class AccessTokensNamespace {
|
|
|
14251
14401
|
}
|
|
14252
14402
|
}
|
|
14253
14403
|
|
|
14404
|
+
/**
|
|
14405
|
+
* `client.app` — what the signed-in user may do in this app (accelerator spec
|
|
14406
|
+
* 2026-10-06-paid-accounts-and-past-due, B6 and B8).
|
|
14407
|
+
*
|
|
14408
|
+
* An app's owner can turn on "Paid Muhkoo accounts only" in the portal. The
|
|
14409
|
+
* accelerator then refuses a Free user's writes that add data, with a 402 the
|
|
14410
|
+
* SDK throws as `PaymentRequiredError`. Reads, sign-in and deletes still work.
|
|
14411
|
+
* The same refusal reaches every user of an app whose owner's payment is past
|
|
14412
|
+
* due, whether or not the setting is on.
|
|
14413
|
+
*
|
|
14414
|
+
* `access()` asks up front, so an app can show the right screen before the
|
|
14415
|
+
* first refusal.
|
|
14416
|
+
*/
|
|
14417
|
+
class AppNamespace {
|
|
14418
|
+
deps;
|
|
14419
|
+
constructor(deps) {
|
|
14420
|
+
this.deps = deps;
|
|
14421
|
+
}
|
|
14422
|
+
/**
|
|
14423
|
+
* Whether the signed-in user may add data in this app and, if not, why
|
|
14424
|
+
* and where to send them. Needs the app key and a session; a stale session
|
|
14425
|
+
* is re-established once, as for every request. The route is never
|
|
14426
|
+
* refused for payment. Throws `HttpError` for anything else, among them a
|
|
14427
|
+
* 401 without a session and a 404 from an accelerator older than the
|
|
14428
|
+
* route.
|
|
14429
|
+
*
|
|
14430
|
+
* Each `allowed: true` also sends any writes the offline queue kept after
|
|
14431
|
+
* a refusal for payment, without waiting for them. Call it after sign-in,
|
|
14432
|
+
* and again when the user comes back from the portal.
|
|
14433
|
+
*/
|
|
14434
|
+
async access() {
|
|
14435
|
+
const body = await this.deps.http.get("/api/app/access");
|
|
14436
|
+
const access = {
|
|
14437
|
+
paidAccountsOnly: body?.paidAccountsOnly === true,
|
|
14438
|
+
// Fail open on a malformed answer: the server enforces the gate
|
|
14439
|
+
// whatever this says, so a wrong "allowed" costs a refused write,
|
|
14440
|
+
// and a wrong "not allowed" would lock the user out for nothing.
|
|
14441
|
+
allowed: body?.allowed !== false,
|
|
14442
|
+
};
|
|
14443
|
+
if (!access.allowed) {
|
|
14444
|
+
if (isPaymentRequiredCode(body?.reason))
|
|
14445
|
+
access.reason = body.reason;
|
|
14446
|
+
const upgradeUrl = absoluteHttpUrl(body?.upgradeUrl);
|
|
14447
|
+
if (upgradeUrl)
|
|
14448
|
+
access.upgradeUrl = upgradeUrl;
|
|
14449
|
+
}
|
|
14450
|
+
else if (this.deps.onAllowed) {
|
|
14451
|
+
// A drain that fails, or a callback that throws, must not turn a
|
|
14452
|
+
// good answer into an error: the writes stay queued for the next
|
|
14453
|
+
// reconnect.
|
|
14454
|
+
Promise.resolve()
|
|
14455
|
+
.then(() => this.deps.onAllowed())
|
|
14456
|
+
.catch((err) => {
|
|
14457
|
+
console.warn("[client.app] sending the kept writes failed (they stay queued):", err);
|
|
14458
|
+
});
|
|
14459
|
+
}
|
|
14460
|
+
return access;
|
|
14461
|
+
}
|
|
14462
|
+
}
|
|
14463
|
+
|
|
14254
14464
|
/**
|
|
14255
14465
|
* POST /api/auth/identity (SpecA §4.1 as amended by CS-7). An unknown name
|
|
14256
14466
|
* answers a deterministic decoy, so a lookup never says whether an account
|
|
@@ -20158,9 +20368,14 @@ class ConnectivityManager {
|
|
|
20158
20368
|
* mutation by re-invoking the real namespace method (with an `isReplay` flag so
|
|
20159
20369
|
* it doesn't re-enqueue). `drain()` replays entries in HLC order:
|
|
20160
20370
|
* - success → remove the entry;
|
|
20161
|
-
* -
|
|
20162
|
-
*
|
|
20163
|
-
*
|
|
20371
|
+
* - refused for payment (`PaymentRequiredError`: the app takes paid plans
|
|
20372
|
+
* only, or someone's payment is past due) → keep it and everything after
|
|
20373
|
+
* it, stop, and surface a `SYNC_ERROR` with `dropped: false`. The server
|
|
20374
|
+
* accepts it once the user or the app owner pays, so it waits for the next
|
|
20375
|
+
* reconnect, or for `client.app.access()` to report the app allowed;
|
|
20376
|
+
* - permanent failure (any other 4xx, or a Space whose member list refuses
|
|
20377
|
+
* this user) → drop it and surface a `SYNC_ERROR` (a write the server will
|
|
20378
|
+
* never accept must not wedge the queue forever);
|
|
20164
20379
|
* - transient/network failure → stop draining and leave the rest for the next
|
|
20165
20380
|
* reconnect.
|
|
20166
20381
|
*
|
|
@@ -20185,14 +20400,34 @@ class OutboundQueue {
|
|
|
20185
20400
|
register(domain, replayer) {
|
|
20186
20401
|
this.replayers.set(domain, replayer);
|
|
20187
20402
|
}
|
|
20188
|
-
/**
|
|
20403
|
+
/**
|
|
20404
|
+
* Record a mutation for later replay; resolves with its assigned seq.
|
|
20405
|
+
* Stamped with the signed-in user's commitment, so that it is only ever
|
|
20406
|
+
* sent under their session (see {@link waiting}).
|
|
20407
|
+
*/
|
|
20189
20408
|
enqueue(entry) {
|
|
20190
|
-
|
|
20409
|
+
const who = entry.commitment ?? this.opts.commitment?.();
|
|
20410
|
+
return this.store.enqueue(who ? { ...entry, commitment: who } : entry);
|
|
20191
20411
|
}
|
|
20192
|
-
/** Number of writes still awaiting sync. */
|
|
20412
|
+
/** Number of writes still awaiting sync, every user's. */
|
|
20193
20413
|
async pending() {
|
|
20194
20414
|
return (await this.store.queued()).length;
|
|
20195
20415
|
}
|
|
20416
|
+
/**
|
|
20417
|
+
* The writes a drain would send now, in order: the signed-in user's, and
|
|
20418
|
+
* any an older SDK queued without saying whose they are. Every tab of an
|
|
20419
|
+
* origin shares this queue, and every replayer builds its request from
|
|
20420
|
+
* the session signed in when it runs, so another user's write sent now
|
|
20421
|
+
* would land in this user's space, or overwrite their data. It stays
|
|
20422
|
+
* queued, as it is, until its own user signs in on this device again.
|
|
20423
|
+
*/
|
|
20424
|
+
async waiting() {
|
|
20425
|
+
return (await this.store.queued()).filter((entry) => this.sendable(entry));
|
|
20426
|
+
}
|
|
20427
|
+
/** True for an entry this drain may send: the signed-in user's, or one with no user. */
|
|
20428
|
+
sendable(entry) {
|
|
20429
|
+
return !entry.commitment || entry.commitment === this.opts.commitment?.();
|
|
20430
|
+
}
|
|
20196
20431
|
/**
|
|
20197
20432
|
* Replay queued mutations in HLC order. Coalesces concurrent calls into a
|
|
20198
20433
|
* single in-flight drain. Stops on the first transient failure, leaving the
|
|
@@ -20214,21 +20449,36 @@ class OutboundQueue {
|
|
|
20214
20449
|
*/
|
|
20215
20450
|
async drainOnce() {
|
|
20216
20451
|
const who = this.opts.commitment?.();
|
|
20217
|
-
if (!this.opts.tryLock || !who)
|
|
20218
|
-
|
|
20452
|
+
if (!this.opts.tryLock || !who) {
|
|
20453
|
+
await this.runDrain();
|
|
20454
|
+
return;
|
|
20455
|
+
}
|
|
20219
20456
|
await this.opts.tryLock(`muhkoo:offline-drain:${who}`, async () => {
|
|
20220
20457
|
// A tab that found this one draining skipped its own drain, and
|
|
20221
20458
|
// what it queued after this pass read the queue was left to this
|
|
20222
|
-
// tab. So drain until a pass leaves nothing; a
|
|
20223
|
-
// still stops it, by throwing.
|
|
20459
|
+
// tab. So drain until a pass leaves nothing of this user's; a
|
|
20460
|
+
// transient failure still stops it, by throwing. So does a write
|
|
20461
|
+
// refused for payment, which stays queued: another pass would
|
|
20462
|
+
// only be refused again, at once and without end. Another user's
|
|
20463
|
+
// writes never leave, so counting them would loop for ever too.
|
|
20224
20464
|
do {
|
|
20225
|
-
await this.runDrain()
|
|
20226
|
-
|
|
20465
|
+
if (!(await this.runDrain()))
|
|
20466
|
+
return;
|
|
20467
|
+
} while ((await this.waiting()).length > 0);
|
|
20227
20468
|
});
|
|
20228
20469
|
}
|
|
20470
|
+
/**
|
|
20471
|
+
* One pass over the queue. False when a write refused for payment stopped
|
|
20472
|
+
* it, which leaves that write and everything after it queued.
|
|
20473
|
+
*/
|
|
20229
20474
|
async runDrain() {
|
|
20230
20475
|
const entries = await this.store.queued();
|
|
20231
20476
|
for (const entry of entries) {
|
|
20477
|
+
// Another user's write, theirs to send under their own session.
|
|
20478
|
+
// Asked per entry, so a sign-out in the middle of a pass stops
|
|
20479
|
+
// the rest of it going out under the next user's session.
|
|
20480
|
+
if (!this.sendable(entry))
|
|
20481
|
+
continue;
|
|
20232
20482
|
const replayer = this.replayers.get(entry.domain);
|
|
20233
20483
|
if (!replayer) {
|
|
20234
20484
|
// No handler registered (namespace not wired) — drop it rather
|
|
@@ -20245,6 +20495,22 @@ class OutboundQueue {
|
|
|
20245
20495
|
});
|
|
20246
20496
|
}
|
|
20247
20497
|
catch (err) {
|
|
20498
|
+
// Asked before `isPermanent`, which would drop it as a 4xx.
|
|
20499
|
+
if (err instanceof PaymentRequiredError) {
|
|
20500
|
+
// The user's plan, or a payment past due: the server will
|
|
20501
|
+
// accept this write once that changes. Keep it, and keep
|
|
20502
|
+
// every write after it in order; a delete queued after an
|
|
20503
|
+
// upload never goes first. Stop rather than send the rest,
|
|
20504
|
+
// which the server would refuse for the same reason.
|
|
20505
|
+
EventCore.emit(EventCoreEvents.SYNC_ERROR, {
|
|
20506
|
+
domain: entry.domain,
|
|
20507
|
+
method: entry.method,
|
|
20508
|
+
error: err.message,
|
|
20509
|
+
code: err.code,
|
|
20510
|
+
dropped: false,
|
|
20511
|
+
});
|
|
20512
|
+
return false;
|
|
20513
|
+
}
|
|
20248
20514
|
if (isPermanent(err)) {
|
|
20249
20515
|
await this.store.dequeue(entry.seq);
|
|
20250
20516
|
EventCore.emit(EventCoreEvents.SYNC_ERROR, {
|
|
@@ -20259,12 +20525,14 @@ class OutboundQueue {
|
|
|
20259
20525
|
throw err;
|
|
20260
20526
|
}
|
|
20261
20527
|
}
|
|
20528
|
+
return true;
|
|
20262
20529
|
}
|
|
20263
20530
|
}
|
|
20264
20531
|
/** A 4xx is the server permanently refusing the write, and so is a Space whose
|
|
20265
20532
|
* member list does not admit this user (design §4.5.12): the relay refuses
|
|
20266
20533
|
* their frames. Anything else, a locked session included, is worth retrying
|
|
20267
|
-
* on the next reconnect.
|
|
20534
|
+
* on the next reconnect. A refusal for payment is a 4xx that is not
|
|
20535
|
+
* permanent; `runDrain` keeps it before asking this. */
|
|
20268
20536
|
function isPermanent(err) {
|
|
20269
20537
|
if (err instanceof AdmissionDeniedError)
|
|
20270
20538
|
return true;
|
|
@@ -20537,6 +20805,22 @@ class OfflineManager {
|
|
|
20537
20805
|
args: { hash },
|
|
20538
20806
|
});
|
|
20539
20807
|
}
|
|
20808
|
+
/**
|
|
20809
|
+
* Replay the queue now, as a reconnect does, if anything is waiting in it.
|
|
20810
|
+
* `client.app.access()` calls this each time it reports the app allowed,
|
|
20811
|
+
* so writes kept after a refusal for payment go out once the user or the
|
|
20812
|
+
* app owner has paid, without waiting for the next reconnect. One drain per
|
|
20813
|
+
* call, never on a timer. With nothing of the signed-in user's queued it
|
|
20814
|
+
* does not drain at all, so the app sees no "syncing". A drain also runs the
|
|
20815
|
+
* catch-up tasks (Space history paging), as a reconnect does.
|
|
20816
|
+
*/
|
|
20817
|
+
async resume() {
|
|
20818
|
+
if (!this.enabled)
|
|
20819
|
+
return;
|
|
20820
|
+
if ((await this.queue.waiting()).length === 0)
|
|
20821
|
+
return;
|
|
20822
|
+
await this.sync.run();
|
|
20823
|
+
}
|
|
20540
20824
|
/** Resolve once the clock + node id are loaded. */
|
|
20541
20825
|
ready() {
|
|
20542
20826
|
return this.bootPromise;
|
|
@@ -21086,6 +21370,8 @@ class Client {
|
|
|
21086
21370
|
functions;
|
|
21087
21371
|
/** Access tokens — `client.accessTokens.create(appId, …)`, etc. */
|
|
21088
21372
|
accessTokens;
|
|
21373
|
+
/** This app — `client.app.access()`: may the signed-in user add data here? */
|
|
21374
|
+
app;
|
|
21089
21375
|
/** Offline cache + sync — `client.offline.status`, `client.offline.snapshot`, etc. */
|
|
21090
21376
|
offline;
|
|
21091
21377
|
session;
|
|
@@ -21265,12 +21551,15 @@ class Client {
|
|
|
21265
21551
|
// the capability path, so it keeps working for a file whose
|
|
21266
21552
|
// handle was shared from someone else's filesystem.
|
|
21267
21553
|
read: async (manifest) => (await this.storage.readByManifest(manifest)).data,
|
|
21268
|
-
|
|
21269
|
-
|
|
21270
|
-
|
|
21271
|
-
|
|
21272
|
-
|
|
21273
|
-
|
|
21554
|
+
// A reference names only shards, so taking or dropping one needs
|
|
21555
|
+
// no Space. Opening the content space here created it for a user
|
|
21556
|
+
// who had never written a file: a checkout, a copy, a delete, or
|
|
21557
|
+
// Cloud Drive's move of its pre-VFS files. A paid-only app refuses
|
|
21558
|
+
// that creation for a Free user (accelerator spec
|
|
21559
|
+
// 2026-10-06-paid-accounts-and-past-due, D12). Same body as
|
|
21560
|
+
// `Space.commitFile`, so it is the same reference.
|
|
21561
|
+
release: (manifest) => commitManifest(this.http.fetchWithRecovery, this.baseUrl, manifest, "release"),
|
|
21562
|
+
retain: (manifest) => commitManifest(this.http.fetchWithRecovery, this.baseUrl, manifest, "commit"),
|
|
21274
21563
|
},
|
|
21275
21564
|
});
|
|
21276
21565
|
// Sealed into the SAME personal store as the VFS metadata, so a project
|
|
@@ -21339,6 +21628,9 @@ class Client {
|
|
|
21339
21628
|
this.agents = new AgentsNamespace({ http: this.http });
|
|
21340
21629
|
this.functions = new FunctionsNamespace({ http: this.http, fnHostSuffix: options.functionsHostSuffix });
|
|
21341
21630
|
this.accessTokens = new AccessTokensNamespace({ http: this.http });
|
|
21631
|
+
// Each "allowed" sends what the offline queue kept after a refusal for
|
|
21632
|
+
// payment, without waiting for the next reconnect.
|
|
21633
|
+
this.app = new AppNamespace({ http: this.http, onAllowed: () => this.offline.resume() });
|
|
21342
21634
|
// Replay deferred shard uploads on reconnect. The bytes live in the
|
|
21343
21635
|
// Cache API keyed by hash; re-PUT them through a (defer-free) shard
|
|
21344
21636
|
// client so a failure surfaces as transient and the entry stays queued.
|
|
@@ -21347,6 +21639,7 @@ class Client {
|
|
|
21347
21639
|
baseUrl: this.baseUrl,
|
|
21348
21640
|
pathPrefix: "/api/shards",
|
|
21349
21641
|
fetch: this.http.fetch,
|
|
21642
|
+
fetchWithRecovery: this.http.fetchWithRecovery,
|
|
21350
21643
|
cache: this.offline.fileCache,
|
|
21351
21644
|
});
|
|
21352
21645
|
this.offline.registerReplayer("file", async (entry) => {
|
|
@@ -21758,5 +22051,5 @@ var bundledLoader = /*#__PURE__*/Object.freeze({
|
|
|
21758
22051
|
default: loadRsWasm
|
|
21759
22052
|
});
|
|
21760
22053
|
|
|
21761
|
-
export { ACCESS_TOKEN_SCOPES, AES_GCM_IV_BYTES$1 as AES_GCM_IV_BYTES, AES_GCM_KEY_BYTES, AES_GCM_TAG_BYTES$1 as AES_GCM_TAG_BYTES, AccessTokensNamespace, AdmissionDeniedError, AgentsNamespace, AuthClient, AuthHttpError, AuthNamespace, AuthPublicInput, Authenticator, BlockEngine, BroadcastChannel, BroadcastChannelEvents, ChannelExistsError, ChannelNotFoundError, ChunkCipher, CircuitIntegrityError, Client, ConnectivityManager, DEFAULT_AUTH_BASE_URL, DEFAULT_BASE_URL, DEFAULT_BRANCH, DEFAULT_FN_HOST_SUFFIX, DEVICE_IDENTITY_STORAGE_KEY, DEVICE_KEY_DB_NAME, DbCache, DbNamespace, DbTable, DevicePairingError, DeviceRevokedError, DeviceStoreUnavailableError, DoubleRatchet, DoubleRatchetCipher, DoubleRatchetManager, EncryptedSession, EventCore, EventCoreEvents, Field, Field as FieldElement, FileStorage, FunctionsNamespace, HLC, HashKnowledge, HostedAuth, HttpClient, HttpError, IdentityLockedError, IdentityUnavailableError, IndexedDbStore, KEEPER_MEMBER_ID$1 as KEEPER_MEMBER_ID, KeyStore, KeyringClient, KeyringHttpError, KvCache, KvNamespace, LocalEngineHost, LocalStorageSessionStore, Logger, MemorySessionStore, Message, Message as MessageDefault, MessageNamespace, MuhkooAgent, MuhkooDB, MuhkooFunction, MuhkooSpace, NOT_MEMBER_CLOSE_CODE, NOT_MEMBER_RECHECK_MS, NoopStore, OfflineLockedError, OfflineManager, OutboundQueue, P2P_SUBJECT, PAIRING_CODE_ALPHABET, PAIRING_CODE_LENGTH, PBKDF2_DEFAULT_ITERATIONS, PINNED_CIRCUIT_DIGESTS, PREIMAGE_POK_VERIFICATION_KEY, Packet, PasskeyOriginError, PeerExchange, PeerNetwork, PersonalSpaceClient, Poseidon, PreimagePoK, ROOT_ID, Ready, ReauthRequiredError, ReedSolomonCodec, Repo, Retry, Space as Room, SerializeMessage, SessionState, ShardCache, ShardClient, SharedSpaceClient, SnapshotNamespace, Space, SpaceCache, SpaceKeyring, SpaceNamespace, SpacePacketCipher, SpaceSignaler, SpaceTrustError, StorageNamespace, SyncEngine, VERSION, VFS_ROOT_INFO, VaultProtocolMismatchError, VaultUnavailableError, VcsError, VcsNamespace, VfsConflictError, VfsCorruptRecordError, VfsLimitError, VfsLockedError, VfsNamespace, VfsNotFoundError, WSTransport, WebRtcTransport, WorkerEngineHost, ZERO_HLC, ZkAuth, _accountId, _formatBytes, _messageId, _objectId, _packetId, _socketId, _userId, appLogger$1 as appLogger, assertType, base58Decode, base58Encode, buildCommitment, canonicalUserCode, clearDeviceIdentity, compareHlc, compilePrograms, concatBytes$1 as concatBytes, configureDeviceStore, createPasskeyWithPrf, decodeFromHex, decorators, decryptAesGcm, defaultCircuitUrls, defaultRpId, defaultSessionStore, deleteBeatsWrite, deleteRegister, deriveAesKeyFromPassphrase, deriveBitsHkdf, deriveIdentity, deriveIdentityFromSeed, deriveMasterSeedFromPassword, deserialize, deviceFingerprint, deviceIdentityIsEphemeral, deviceIdentityKey, dirKey, ejectAgentPrompt, ejectAgentTools, emptyMap, emptyRegister, encodeToHex, encryptAesGcm, evaluatePasskeyPrf, exportPublicKeyBase64, exportPublicKeyHex, formatUserCode, fromBase64$2 as fromBase64, fromBase64Url, fromHex, generateAuthProof, generateChecksum, generateDevicePairingKeypair, generateId, generatePkce, getIPAddress, getId, getMuhkooAppDescriptor, getSubtle, hasDeviceIdentity, headKey, historyKey, initBn128Wasm, initRsWasm, initializeCircuits, isNewer, isNumber, isOfflineCapable, isP2pCapable, isProvisional, isSameOriginPath, loadDeviceIdentity, log, manifestToStat, materializeRow, merge3, merge3Text, mergeKey, mergeMap, mergeMessage, mergeRegister, messageKey, objectKey, pack, padHandle, pairingVerificationCode, passkeyPrfCapable, passkeySupported, passkeyUsableFromOrigin, persistDeviceIdentity, poseidonHash, protocol, provisionalHandle, quickVerify, randomBytes, randomState, refKey, refsIndexKey, rpIdUsableForOrigin, sealSeed, sealSeedToDevice, serialize, shardHash, signMessage, stableStringify, toBase64$2 as toBase64, toBase64Url, toField, toHex, tombstoneRow, unpack, unsealSeed, unsealSeedFromDevice, unwrapWithPassphrase, utf8Decode, utf8Encode, verify, verifyChecksum, verifyGroth16, verifyHashKnowledge, verifyPreimagePoK, wrapWithPassphrase, writeBeatsTombstone, writeColumns, writeRegister };
|
|
22054
|
+
export { ACCESS_TOKEN_SCOPES, AES_GCM_IV_BYTES$1 as AES_GCM_IV_BYTES, AES_GCM_KEY_BYTES, AES_GCM_TAG_BYTES$1 as AES_GCM_TAG_BYTES, AccessTokensNamespace, AdmissionDeniedError, AgentsNamespace, AppNamespace, AuthClient, AuthHttpError, AuthNamespace, AuthPublicInput, Authenticator, BlockEngine, BroadcastChannel, BroadcastChannelEvents, ChannelExistsError, ChannelNotFoundError, ChunkCipher, CircuitIntegrityError, Client, ConnectivityManager, DEFAULT_AUTH_BASE_URL, DEFAULT_BASE_URL, DEFAULT_BRANCH, DEFAULT_FN_HOST_SUFFIX, DEVICE_IDENTITY_STORAGE_KEY, DEVICE_KEY_DB_NAME, DbCache, DbNamespace, DbTable, DevicePairingError, DeviceRevokedError, DeviceStoreUnavailableError, DoubleRatchet, DoubleRatchetCipher, DoubleRatchetManager, EncryptedSession, EventCore, EventCoreEvents, Field, Field as FieldElement, FileStorage, FunctionsNamespace, HLC, HashKnowledge, HostedAuth, HttpClient, HttpError, IdentityLockedError, IdentityUnavailableError, IndexedDbStore, KEEPER_MEMBER_ID$1 as KEEPER_MEMBER_ID, KeyStore, KeyringClient, KeyringHttpError, KvCache, KvNamespace, LocalEngineHost, LocalStorageSessionStore, Logger, MemorySessionStore, Message, Message as MessageDefault, MessageNamespace, MuhkooAgent, MuhkooDB, MuhkooFunction, MuhkooSpace, NOT_MEMBER_CLOSE_CODE, NOT_MEMBER_RECHECK_MS, NoopStore, OfflineLockedError, OfflineManager, OutboundQueue, P2P_SUBJECT, PAIRING_CODE_ALPHABET, PAIRING_CODE_LENGTH, PBKDF2_DEFAULT_ITERATIONS, PINNED_CIRCUIT_DIGESTS, PREIMAGE_POK_VERIFICATION_KEY, Packet, PasskeyOriginError, PaymentRequiredError, PeerExchange, PeerNetwork, PersonalSpaceClient, Poseidon, PreimagePoK, ROOT_ID, Ready, ReauthRequiredError, ReedSolomonCodec, Repo, Retry, Space as Room, SerializeMessage, SessionState, ShardCache, ShardClient, SharedSpaceClient, SnapshotNamespace, Space, SpaceCache, SpaceKeyring, SpaceNamespace, SpacePacketCipher, SpaceSignaler, SpaceTrustError, StorageNamespace, SyncEngine, VERSION, VFS_ROOT_INFO, VaultProtocolMismatchError, VaultUnavailableError, VcsError, VcsNamespace, VfsConflictError, VfsCorruptRecordError, VfsLimitError, VfsLockedError, VfsNamespace, VfsNotFoundError, WSTransport, WebRtcTransport, WorkerEngineHost, ZERO_HLC, ZkAuth, _accountId, _formatBytes, _messageId, _objectId, _packetId, _socketId, _userId, appLogger$1 as appLogger, assertType, base58Decode, base58Encode, buildCommitment, canonicalUserCode, clearDeviceIdentity, compareHlc, compilePrograms, concatBytes$1 as concatBytes, configureDeviceStore, createPasskeyWithPrf, decodeFromHex, decorators, decryptAesGcm, defaultCircuitUrls, defaultRpId, defaultSessionStore, deleteBeatsWrite, deleteRegister, deriveAesKeyFromPassphrase, deriveBitsHkdf, deriveIdentity, deriveIdentityFromSeed, deriveMasterSeedFromPassword, deserialize, deviceFingerprint, deviceIdentityIsEphemeral, deviceIdentityKey, dirKey, ejectAgentPrompt, ejectAgentTools, emptyMap, emptyRegister, encodeToHex, encryptAesGcm, evaluatePasskeyPrf, exportPublicKeyBase64, exportPublicKeyHex, formatUserCode, fromBase64$2 as fromBase64, fromBase64Url, fromHex, generateAuthProof, generateChecksum, generateDevicePairingKeypair, generateId, generatePkce, getIPAddress, getId, getMuhkooAppDescriptor, getSubtle, hasDeviceIdentity, headKey, historyKey, initBn128Wasm, initRsWasm, initializeCircuits, isNewer, isNumber, isOfflineCapable, isP2pCapable, isProvisional, isSameOriginPath, loadDeviceIdentity, log, manifestToStat, materializeRow, merge3, merge3Text, mergeKey, mergeMap, mergeMessage, mergeRegister, messageKey, objectKey, pack, padHandle, pairingVerificationCode, passkeyPrfCapable, passkeySupported, passkeyUsableFromOrigin, persistDeviceIdentity, poseidonHash, protocol, provisionalHandle, quickVerify, randomBytes, randomState, refKey, refsIndexKey, rpIdUsableForOrigin, sealSeed, sealSeedToDevice, serialize, shardHash, signMessage, stableStringify, toBase64$2 as toBase64, toBase64Url, toField, toHex, tombstoneRow, unpack, unsealSeed, unsealSeedFromDevice, unwrapWithPassphrase, utf8Decode, utf8Encode, verify, verifyChecksum, verifyGroth16, verifyHashKnowledge, verifyPreimagePoK, wrapWithPassphrase, writeBeatsTombstone, writeColumns, writeRegister };
|
|
21762
22055
|
//# sourceMappingURL=index.js.map
|