@muhkoo/connect 0.15.0-alpha.3 → 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/connect.d.ts CHANGED
@@ -1099,6 +1099,59 @@ declare class BroadcastChannel {
1099
1099
  private handleInboundFrame;
1100
1100
  }
1101
1101
 
1102
+ /**
1103
+ * `HttpError` — thrown for any non-2xx accelerator response.
1104
+ *
1105
+ * In a module of its own so that `PaymentRequiredError` can extend it while
1106
+ * `HttpClient`, which throws both, imports `PaymentRequiredError`: with the
1107
+ * class in `HttpClient.ts`, the two modules would import each other, and
1108
+ * whichever loaded second would extend a class not yet defined. `HttpClient`
1109
+ * re-exports it, so `import { HttpError } from "./HttpClient"` still works.
1110
+ */
1111
+ /** Thrown for any non-2xx accelerator response. Carries the HTTP status. */
1112
+ declare class HttpError extends Error {
1113
+ readonly status: number;
1114
+ readonly body?: unknown | undefined;
1115
+ constructor(message: string, status: number, body?: unknown | undefined);
1116
+ }
1117
+
1118
+ /**
1119
+ * `PaymentRequiredError` — a write the accelerator refused for payment
1120
+ * (accelerator spec 2026-10-06-paid-accounts-and-past-due, "Interfaces and
1121
+ * contracts").
1122
+ *
1123
+ * The accelerator answers such a write with a 402 whose body carries one of
1124
+ * three codes:
1125
+ * - `user_plan_required`: the app takes paid Muhkoo plans only, and the
1126
+ * signed-in user is on Free;
1127
+ * - `user_payment_past_due`: the user's own Muhkoo payment is past due. Only
1128
+ * first-party apps are told this; every other app is told
1129
+ * `user_plan_required` instead;
1130
+ * - `owner_payment_past_due`: the app owner's payment is past due, so the
1131
+ * app stores nothing new for anyone.
1132
+ * Reads, sign-in and deletes still work in all three cases.
1133
+ *
1134
+ * Every other 402 — the Free-tier refusals that carry `quotaExceeded`,
1135
+ * `requiresPaidTier` or `freeTierFull` — has no `code`, and stays a plain
1136
+ * `HttpError`, as before.
1137
+ */
1138
+
1139
+ /** Why a write was refused for payment. A wire contract: these strings never change. */
1140
+ type PaymentRequiredCode = "user_plan_required" | "user_payment_past_due" | "owner_payment_past_due";
1141
+ /** Thrown for a 402 whose body carries one of the three {@link PaymentRequiredCode}s. */
1142
+ declare class PaymentRequiredError extends HttpError {
1143
+ /** Why the write was refused. */
1144
+ readonly code: PaymentRequiredCode;
1145
+ /**
1146
+ * Where to send the user: the portal's upgrade page or its billing page,
1147
+ * as an absolute URL. Set only when the server sent an absolute http(s)
1148
+ * URL. The relative `upgradeUrl` of the Free-tier refusals is never here:
1149
+ * those are not this error.
1150
+ */
1151
+ readonly upgradeUrl?: string;
1152
+ constructor(message: string, code: PaymentRequiredCode, body?: unknown, upgradeUrl?: string);
1153
+ }
1154
+
1102
1155
  /**
1103
1156
  * Cloudflare-Workers-compatible Groth16 ZK proof verifier.
1104
1157
  *
@@ -2416,6 +2469,15 @@ interface ShardClientOptions {
2416
2469
  * Provided so callers can inject retries / auth / instrumentation.
2417
2470
  */
2418
2471
  fetch?: typeof fetch;
2472
+ /**
2473
+ * The same fetch with the client's silent re-authentication
2474
+ * (`HttpClient.fetchWithRecovery`), used for uploads only. A paid-only
2475
+ * app refuses a PUT made with a dead session with `401 session_required`;
2476
+ * through this, the session is re-established once and the PUT sent
2477
+ * again, which is safe because its bytes can be sent twice. Reads keep
2478
+ * {@link fetch}. Defaults to {@link fetch}.
2479
+ */
2480
+ fetchWithRecovery?: typeof fetch;
2419
2481
  /**
2420
2482
  * Optional offline byte cache. When present, GETs are served cache-first and
2421
2483
  * populated on success, and PUTs write the cache before the network so a
@@ -2462,6 +2524,8 @@ declare class ShardClient {
2462
2524
  private readonly baseUrl;
2463
2525
  private readonly pathPrefix;
2464
2526
  private readonly fetchFn;
2527
+ /** What a PUT goes through: {@link ShardClientOptions.fetchWithRecovery} when given, else {@link fetchFn}. */
2528
+ private readonly putFn;
2465
2529
  private readonly cache?;
2466
2530
  /** Hashes waiting for the next batch, each with everyone awaiting it and its size if a caller gave it. */
2467
2531
  private pendingShards;
@@ -3895,12 +3959,7 @@ interface HttpClientOptions {
3895
3959
  */
3896
3960
  onUnauthorized?: () => Promise<boolean>;
3897
3961
  }
3898
- /** Thrown for any non-2xx accelerator response. Carries the HTTP status. */
3899
- declare class HttpError extends Error {
3900
- readonly status: number;
3901
- readonly body?: unknown | undefined;
3902
- constructor(message: string, status: number, body?: unknown | undefined);
3903
- }
3962
+
3904
3963
  declare class HttpClient {
3905
3964
  readonly baseUrl: string;
3906
3965
  /** Origin of {@link baseUrl} — credentials are only attached same-origin. */
@@ -4052,6 +4111,14 @@ interface QueueEntry {
4052
4111
  method: string;
4053
4112
  /** Serializable arguments captured at enqueue time. */
4054
4113
  args: unknown;
4114
+ /**
4115
+ * Whose write it is: the commitment of the user signed in when it was
4116
+ * queued, stamped by `OutboundQueue.enqueue`. A drain sends only the
4117
+ * signed-in user's entries, because every replayer builds its request
4118
+ * from the session signed in when it runs. Absent on entries an older
4119
+ * SDK queued, which any drain sends, as before.
4120
+ */
4121
+ commitment?: string;
4055
4122
  }
4056
4123
  interface OfflineEntry<T> {
4057
4124
  key: string;
@@ -4091,35 +4158,92 @@ interface OfflineStore {
4091
4158
  * mutation by re-invoking the real namespace method (with an `isReplay` flag so
4092
4159
  * it doesn't re-enqueue). `drain()` replays entries in HLC order:
4093
4160
  * - success → remove the entry;
4094
- * - permanent failure (4xx, or a Space whose member list refuses this user)
4095
- * → drop it and surface a `SYNC_ERROR` (a write the server will never
4096
- * accept must not wedge the queue forever);
4161
+ * - refused for payment (`PaymentRequiredError`: the app takes paid plans
4162
+ * only, or someone's payment is past due) → keep it and everything after
4163
+ * it, stop, and surface a `SYNC_ERROR` with `dropped: false`. The server
4164
+ * accepts it once the user or the app owner pays, so it waits for the next
4165
+ * reconnect, or for `client.app.access()` to report the app allowed;
4166
+ * - permanent failure (any other 4xx, or a Space whose member list refuses
4167
+ * this user) → drop it and surface a `SYNC_ERROR` (a write the server will
4168
+ * never accept must not wedge the queue forever);
4097
4169
  * - transient/network failure → stop draining and leave the rest for the next
4098
4170
  * reconnect.
4099
4171
  *
4100
4172
  * Replays are idempotent by construction (kv/db are LWW-by-key, messages dedupe
4101
4173
  * by `clientId`, file PUTs are content-addressed), so re-running a partially
4102
4174
  * drained queue is safe.
4175
+ *
4176
+ * Every tab of an origin shares the queue. Given a `tryLock`, a drain runs
4177
+ * only while holding `muhkoo:offline-drain:<commitment>`, so two tabs coming
4178
+ * back online replay it once between them, not once each.
4103
4179
  */
4104
4180
 
4105
4181
  type Replayer = (entry: QueueEntry) => Promise<void>;
4182
+ /**
4183
+ * Run `fn` holding lock `name` if no one else holds it: true once it has
4184
+ * run, false - without running it - when another holder has it. Web Locks'
4185
+ * `ifAvailable` in a browser tab; see `core/crossTab.ts`.
4186
+ */
4187
+ type TryLock = (name: string, fn: () => Promise<void>) => Promise<boolean>;
4188
+ interface OutboundQueueOptions {
4189
+ /**
4190
+ * The lock that keeps two tabs from draining at once. Every tab of an
4191
+ * origin shares one IndexedDB queue, and each replayed all of it when it
4192
+ * came back online: two tabs, every queued write twice. Absent (Node,
4193
+ * tests), every drain runs, as before.
4194
+ */
4195
+ tryLock?: TryLock;
4196
+ /**
4197
+ * The signed-in user: stamps each enqueued write, picks which writes a
4198
+ * drain sends, and names the drain lock. With no one signed in, writes are
4199
+ * unstamped and the drain runs unlocked.
4200
+ */
4201
+ commitment?: () => string | null;
4202
+ }
4106
4203
  declare class OutboundQueue {
4107
4204
  private readonly store;
4205
+ private readonly opts;
4108
4206
  private readonly replayers;
4109
4207
  private draining;
4110
- constructor(store: OfflineStore);
4208
+ constructor(store: OfflineStore, opts?: OutboundQueueOptions);
4111
4209
  /** A domain registers how to replay its mutations. */
4112
4210
  register(domain: QueueEntry["domain"], replayer: Replayer): void;
4113
- /** Record a mutation for later replay; resolves with its assigned seq. */
4211
+ /**
4212
+ * Record a mutation for later replay; resolves with its assigned seq.
4213
+ * Stamped with the signed-in user's commitment, so that it is only ever
4214
+ * sent under their session (see {@link waiting}).
4215
+ */
4114
4216
  enqueue(entry: Omit<QueueEntry, "seq">): Promise<number>;
4115
- /** Number of writes still awaiting sync. */
4217
+ /** Number of writes still awaiting sync, every user's. */
4116
4218
  pending(): Promise<number>;
4219
+ /**
4220
+ * The writes a drain would send now, in order: the signed-in user's, and
4221
+ * any an older SDK queued without saying whose they are. Every tab of an
4222
+ * origin shares this queue, and every replayer builds its request from
4223
+ * the session signed in when it runs, so another user's write sent now
4224
+ * would land in this user's space, or overwrite their data. It stays
4225
+ * queued, as it is, until its own user signs in on this device again.
4226
+ */
4227
+ waiting(): Promise<QueueEntry[]>;
4228
+ /** True for an entry this drain may send: the signed-in user's, or one with no user. */
4229
+ private sendable;
4117
4230
  /**
4118
4231
  * Replay queued mutations in HLC order. Coalesces concurrent calls into a
4119
4232
  * single in-flight drain. Stops on the first transient failure, leaving the
4120
4233
  * remaining entries for the next attempt.
4121
4234
  */
4122
4235
  drain(): Promise<void>;
4236
+ /**
4237
+ * One drain, holding the device-wide drain lock where there is one. A
4238
+ * tab that finds another tab holding it leaves the queue to that one,
4239
+ * which is replaying it already and removes each entry as it lands - so
4240
+ * a drain after it finds only what it left.
4241
+ */
4242
+ private drainOnce;
4243
+ /**
4244
+ * One pass over the queue. False when a write refused for payment stopped
4245
+ * it, which leaves that write and everything after it queued.
4246
+ */
4123
4247
  private runDrain;
4124
4248
  }
4125
4249
 
@@ -4249,6 +4373,12 @@ interface OfflineManagerDeps {
4249
4373
  session: SessionState;
4250
4374
  /** Whether offline support is active (browser) vs a no-op (Node/Workers). */
4251
4375
  enabled: boolean;
4376
+ /**
4377
+ * The drain lock the tabs of this origin share - Web Locks in a browser
4378
+ * tab. Absent, every tab drains the shared queue itself, as before. See
4379
+ * `OutboundQueue`.
4380
+ */
4381
+ locks?: TryLock;
4252
4382
  }
4253
4383
  declare class OfflineManager {
4254
4384
  /** True in browsers with IndexedDB; false when running over a NoopStore. */
@@ -4272,6 +4402,16 @@ declare class OfflineManager {
4272
4402
  * replayer re-PUTs from the cache on reconnect.
4273
4403
  */
4274
4404
  deferShardUpload(hash: string): Promise<void>;
4405
+ /**
4406
+ * Replay the queue now, as a reconnect does, if anything is waiting in it.
4407
+ * `client.app.access()` calls this each time it reports the app allowed,
4408
+ * so writes kept after a refusal for payment go out once the user or the
4409
+ * app owner has paid, without waiting for the next reconnect. One drain per
4410
+ * call, never on a timer. With nothing of the signed-in user's queued it
4411
+ * does not drain at all, so the app sees no "syncing". A drain also runs the
4412
+ * catch-up tasks (Space history paging), as a reconnect does.
4413
+ */
4414
+ resume(): Promise<void>;
4275
4415
  /** Resolve once the clock + node id are loaded. */
4276
4416
  ready(): Promise<void>;
4277
4417
  /** Current connectivity state (`online` | `offline` | `syncing`). */
@@ -5412,6 +5552,12 @@ interface SpaceDeps {
5412
5552
  httpBaseUrl: string;
5413
5553
  /** Header-injecting fetch from the client's HttpClient. */
5414
5554
  fetch: typeof fetch;
5555
+ /**
5556
+ * The same fetch with the client's silent 401 recovery (`HttpClient.fetchWithRecovery`). File uploads
5557
+ * use it, so a PUT made with a dead session re-establishes the session once instead of failing.
5558
+ * Defaults to {@link fetch}.
5559
+ */
5560
+ fetchWithRecovery?: typeof fetch;
5415
5561
  /** Resolves the user id used for the ratchet / member id (signed-in username). */
5416
5562
  myId: () => string;
5417
5563
  /** Resolves a short-lived WS upgrade ticket (or null when keyless). */
@@ -6548,6 +6694,68 @@ declare class AccessTokensNamespace {
6548
6694
  private path;
6549
6695
  }
6550
6696
 
6697
+ /**
6698
+ * `client.app` — what the signed-in user may do in this app (accelerator spec
6699
+ * 2026-10-06-paid-accounts-and-past-due, B6 and B8).
6700
+ *
6701
+ * An app's owner can turn on "Paid Muhkoo accounts only" in the portal. The
6702
+ * accelerator then refuses a Free user's writes that add data, with a 402 the
6703
+ * SDK throws as `PaymentRequiredError`. Reads, sign-in and deletes still work.
6704
+ * The same refusal reaches every user of an app whose owner's payment is past
6705
+ * due, whether or not the setting is on.
6706
+ *
6707
+ * `access()` asks up front, so an app can show the right screen before the
6708
+ * first refusal.
6709
+ */
6710
+
6711
+ /** The answer of `GET /api/app/access`. */
6712
+ interface AppAccess {
6713
+ /** The owner has turned on "Paid Muhkoo accounts only" for this app. */
6714
+ paidAccountsOnly: boolean;
6715
+ /** The signed-in user may add data in this app now. */
6716
+ allowed: boolean;
6717
+ /**
6718
+ * Why not: the code a refused write carries. Read only when `allowed` is
6719
+ * false, and only when it is one of the three codes.
6720
+ */
6721
+ reason?: PaymentRequiredCode;
6722
+ /**
6723
+ * Where to send the user, as an absolute URL: the portal's upgrade page
6724
+ * for `user_plan_required`, with a way back to this app when the request
6725
+ * came from one of its registered redirect URIs, or its billing page for
6726
+ * `user_payment_past_due`. The accelerator sends it only for those two
6727
+ * reasons: the user can do nothing about the owner's payment. Read only
6728
+ * when `allowed` is false, and only when it is an absolute http(s) URL.
6729
+ */
6730
+ upgradeUrl?: string;
6731
+ }
6732
+ interface AppNamespaceDeps {
6733
+ http: HttpClient;
6734
+ /**
6735
+ * Called each time `access()` answers `allowed: true`. The Client sends
6736
+ * the writes its offline queue kept after a refusal for payment
6737
+ * (`OfflineManager.resume`). A throw or a rejection is logged and ignored.
6738
+ */
6739
+ onAllowed?: () => Promise<void>;
6740
+ }
6741
+ declare class AppNamespace {
6742
+ private readonly deps;
6743
+ constructor(deps: AppNamespaceDeps);
6744
+ /**
6745
+ * Whether the signed-in user may add data in this app and, if not, why
6746
+ * and where to send them. Needs the app key and a session; a stale session
6747
+ * is re-established once, as for every request. The route is never
6748
+ * refused for payment. Throws `HttpError` for anything else, among them a
6749
+ * 401 without a session and a 404 from an accelerator older than the
6750
+ * route.
6751
+ *
6752
+ * Each `allowed: true` also sends any writes the offline queue kept after
6753
+ * a refusal for payment, without waiting for them. Call it after sign-in,
6754
+ * and again when the user comes back from the portal.
6755
+ */
6756
+ access(): Promise<AppAccess>;
6757
+ }
6758
+
6551
6759
  /**
6552
6760
  * Wire types for the VFS metadata layer.
6553
6761
  *
@@ -6757,6 +6965,114 @@ declare class VfsLimitError extends Error {
6757
6965
  constructor(limit: VfsLimitError["limit"], max: number, path: string, at: string, doing?: string);
6758
6966
  }
6759
6967
 
6968
+ /**
6969
+ * How `client.vfs` orders writes of one directory record between the tabs of
6970
+ * an app on one device. Internal: nothing re-exports this module, and it is
6971
+ * not public API.
6972
+ *
6973
+ * The personal space keeps whichever write of a key arrives last, so two tabs
6974
+ * that each edit a copy of a folder and write it lose one tab's edit. A
6975
+ * coordinator gives every namespace on the device one lock per record, held
6976
+ * from the decision to write until the write has landed or failed, and a
6977
+ * count of each record's writes, which a writer stores before it lets go of
6978
+ * the lock and the next holder reads to tell whether its copy is current.
6979
+ * It also tells the others which record was written, as a hint: that can
6980
+ * reach them after the next holder has decided, or never. And it gives
6981
+ * each file or folder being moved or deleted a lock, which a move or delete
6982
+ * of it elsewhere takes only if it is free, and refuses otherwise (see
6983
+ * `holdMoving`). `Client` builds one
6984
+ * from Web Locks and a BroadcastChannel in a browser tab (see
6985
+ * `core/crossTab.ts`); without one, writes are ordered within one namespace
6986
+ * only, as they always were.
6987
+ */
6988
+ interface VfsCoordinator {
6989
+ /**
6990
+ * Run `fn` holding the device-wide lock for record `id`, and settle as it
6991
+ * does. Where the runtime refuses the lock to this document, as it then
6992
+ * does to every tab of the app, `fn` runs without it.
6993
+ */
6994
+ lock<T>(id: string, fn: () => Promise<T>): Promise<T>;
6995
+ /** Tell every other namespace that this one has just written record `id`. Called while holding its lock. */
6996
+ announce(id: string): void;
6997
+ /**
6998
+ * Call `handler` with the id of each record another namespace announces -
6999
+ * or with null when announcements may have been missed, because this one
7000
+ * has only just started hearing them, or now hears them for someone else,
7001
+ * so that every record held must be taken as written elsewhere. Returns a
7002
+ * function that stops it.
7003
+ */
7004
+ onAnnounce(handler: (id: string | null) => void): () => void;
7005
+ /**
7006
+ * Make sure announcements for whoever is signed in now are being heard.
7007
+ * Cheap; called before every read of a record from the store, so that
7008
+ * nothing is read before this namespace can hear of a later write of it.
7009
+ */
7010
+ listen(): void;
7011
+ /**
7012
+ * How often each record in `ids` has been written by any namespace on
7013
+ * the device, for whoever is signed in: one counter each, in order, read
7014
+ * at one moment from storage every tab of the app shares (IndexedDB, in
7015
+ * a browser). Null where it cannot be told: the storage cannot be read,
7016
+ * or does not answer within a few seconds, or a write of the record has
7017
+ * begun and not been counted (see `begin`). Never rejects.
7018
+ *
7019
+ * A copy of a record fetched after its counter was read holds every
7020
+ * write the counter counts. Read again once its holder has taken a lock
7021
+ * that another tab held while it wrote the record - the record's own, or
7022
+ * a move lock - a counter that has not moved says no other tab has
7023
+ * written it since: unlike an announcement, a count is stored before
7024
+ * the writer lets go of its locks. See `VfsNamespace.sendLocked`.
7025
+ */
7026
+ counters(ids: readonly string[]): Promise<Array<string | null>>;
7027
+ /**
7028
+ * Called holding record `id`'s lock, before deciding whether a copy of it
7029
+ * is current: its counter as the last tab to write it left it - one whose
7030
+ * write began and was never counted, which no copy holds, included. And
7031
+ * from then, stored with it, a mark that a write of it has begun, which
7032
+ * `counters` reports as null until `bump`: a tab that goes, or cannot
7033
+ * count its write, in between leaves every tab reading the record again.
7034
+ * Null when the storage could not be read and marked within a few
7035
+ * seconds. Never rejects.
7036
+ */
7037
+ begin(id: string): Promise<string | null>;
7038
+ /**
7039
+ * Called holding record `id`'s lock, after `begin`, once the write has
7040
+ * landed or failed, or nothing was written after all: count it, and
7041
+ * resolve to the record's new counter once that is stored - so before
7042
+ * the lock is let go of. Null when it could not be stored within a few
7043
+ * seconds. Never rejects.
7044
+ */
7045
+ bump(id: string): Promise<string | null>;
7046
+ /**
7047
+ * Hold the lock that says entry `id` - a file or a folder, by its id in
7048
+ * the tree - is being moved or deleted on this device, if no one holds
7049
+ * it. Never waits: resolves to null when another holder has it, in this
7050
+ * tab or another, and otherwise to the function that lets go of it. A
7051
+ * tab that dies lets go of everything it held. With no one signed in it
7052
+ * holds nothing, and resolves to a function that does nothing; so too
7053
+ * where the runtime refuses the lock to this document, as it then does
7054
+ * to every tab of the app.
7055
+ *
7056
+ * `shared` holds a folder's lock as a place on the way to where a move
7057
+ * is putting something. Any number of shared holders hold it at once,
7058
+ * in any tab; a holder that is not shared cannot have it while they do,
7059
+ * nor they while it does.
7060
+ *
7061
+ * A move marks its entry before it puts it in its second place, and a
7062
+ * mark cannot tell a move still writing from one that was interrupted.
7063
+ * Another tab took the first for the second: it finished the move too,
7064
+ * naming the entry in two places, or let go of what the move was about
7065
+ * to put somewhere else. So a move holds this from before it marks until
7066
+ * it has taken the entry from where it was, a delete holds it for all it
7067
+ * is deleting, and either refuses when it cannot have it. A move also
7068
+ * holds the folder it is moving into, and every folder above that one,
7069
+ * shared, for as long: a move into a folder that another tab was
7070
+ * deleting put what it moved in a record the delete then purged. See
7071
+ * `VfsNamespace.rename` and `VfsNamespace.delete`.
7072
+ */
7073
+ holdMoving(id: string, shared?: boolean): Promise<(() => void) | null>;
7074
+ }
7075
+
6760
7076
  /**
6761
7077
  * `client.vfs` — a real filesystem over Muhkoo primitives.
6762
7078
  *
@@ -6769,21 +7085,25 @@ declare class VfsLimitError extends Error {
6769
7085
  *
6770
7086
  * Every mutation is a read-modify-write of exactly ONE directory record, so a
6771
7087
  * write cannot leave the tree half-updated: either the parent names the new
6772
- * child or it does not. Two tabs writing different directories never conflict;
6773
- * two tabs (or devices) writing the SAME directory are last-writer-wins. A VFS
6774
- * write sends no HLC and the personal space has no compare-and-swap: it applies
6775
- * puts of one key in the order they arrive, so whichever arrives last is kept,
6776
- * and the other tab's edit is lost. Orphaned records (a directory whose parent
6777
- * entry lost the race) are unreachable rather than corrupting — they cost
6778
- * storage until a future sweep, which is the trade this shape makes in
7088
+ * child or it does not. A VFS write sends no HLC and the personal space has
7089
+ * no compare-and-swap: of two writes of one key it keeps whichever arrives
7090
+ * last.
7091
+ *
7092
+ * Within ONE namespace, writes of a record are sent one at a time, in the
7093
+ * order they were made - edits made while one is in flight go out together
7094
+ * in the next (see `queue`) - and a read that has to fetch a record waits for
7095
+ * its write in flight (see `writing`). Every edit of a record is made to one
7096
+ * in-memory copy of it, and that copy is what is written (see `mutate`).
7097
+ *
7098
+ * Between the tabs of an app on one device, a coordinator (`VfsCoordinator`;
7099
+ * `Client` wires one in a browser tab) gives each record one lock, and a tab
7100
+ * reads a record another tab has written again before its next write of it
7101
+ * (see `sendLocked`). Between devices - or a browser and the CLI - two writes
7102
+ * of the same directory are still last-writer-wins, and the other edit is
7103
+ * lost: that takes a compare-and-swap at the server. Orphaned records (a
7104
+ * directory whose parent entry lost the race) are unreachable rather than
7105
+ * corrupting - they cost storage until a sweep, the trade this shape makes in
6779
7106
  * exchange for single-record writes.
6780
- *
6781
- * Within ONE tab, writes of a record are queued and sent one at a time, in the
6782
- * order they were made, and a read that has to fetch a record waits for its
6783
- * write in flight (see `writing`). Every edit of a record is made to one
6784
- * in-memory copy of it, and that copy is what is written (see `mutate`). All
6785
- * of this is per namespace instance only; nothing orders writes across tabs
6786
- * or devices - that would take a compare-and-swap at the server.
6787
7107
  */
6788
7108
 
6789
7109
  /**
@@ -6849,6 +7169,13 @@ interface VfsNamespaceDeps {
6849
7169
  entries?: number;
6850
7170
  pathChars?: number;
6851
7171
  };
7172
+ /**
7173
+ * Orders writes of a record with the other tabs of this app on the
7174
+ * device. `Client` passes one in a browser tab; without it - Node, a
7175
+ * test, a runtime with no Web Locks - writes are ordered within this
7176
+ * namespace only. See `VfsCoordinator`.
7177
+ */
7178
+ coordinator?: VfsCoordinator;
6852
7179
  }
6853
7180
  declare class VfsNamespace {
6854
7181
  private readonly deps;
@@ -6892,6 +7219,81 @@ declare class VfsNamespace {
6892
7219
  * `openDirById`.
6893
7220
  */
6894
7221
  private readonly writing;
7222
+ /**
7223
+ * Every entry this namespace is moving right now, by id.
7224
+ *
7225
+ * A move between two directories marks the entry before it puts it in
7226
+ * the second (see `rename`), and a mark is all a later operation can
7227
+ * see. It cannot tell a move still writing from one that was
7228
+ * interrupted, and was taken for the second: a delete that began after
7229
+ * a move had marked a folder looked for the folder's other half, found
7230
+ * none yet, and purged it while the move was putting it in its new
7231
+ * place; a second move of a file finished the "interrupted" move and
7232
+ * left it named in two places. So a move holds its entry here until it
7233
+ * has taken it from where it was, and `rename` and `delete` refuse an
7234
+ * entry that is here - or, for a delete, a folder holding one. A delete
7235
+ * holds what it deletes the same way: see `deleting`.
7236
+ *
7237
+ * This set is one namespace's. With a coordinator, a move also holds
7238
+ * the entry's move lock for every tab on the device, for as long as the
7239
+ * entry is here: see `VfsCoordinator.holdMoving`.
7240
+ */
7241
+ private readonly inMotion;
7242
+ /**
7243
+ * What each delete under way in this namespace is deleting, by entry id,
7244
+ * one set per delete: its target from the moment it has found the target
7245
+ * not in `inMotion`, and everything it read below the target once it has
7246
+ * read it. Each delete lets go of its own set when it is done.
7247
+ *
7248
+ * A delete waits after it has read what it will let go of: on more
7249
+ * reads, and on a read of the whole tree for the other half of a move.
7250
+ * A move of any of it that started meanwhile could put it in its new
7251
+ * place, fail to take it from the old, and end, all before the delete's
7252
+ * detach. Ended, it was no longer in `inMotion`; and an entry that was
7253
+ * marked already showed no change. So the delete let go of what the
7254
+ * move had just named somewhere else. Now `rename` refuses an entry that
7255
+ * is here, or one on a way from the root that passes through a folder
7256
+ * that is: everything below a delete's target, read yet or not.
7257
+ */
7258
+ private readonly deleting;
7259
+ /**
7260
+ * The write of each record that has not gone out yet, by id: the one
7261
+ * the next edit of that record joins. See `queue`.
7262
+ */
7263
+ private readonly waiting;
7264
+ /**
7265
+ * Announcements heard from other tabs, counted. `heardAt` is the count
7266
+ * at the last one for each record, `missedAt` the count when some may
7267
+ * have been missed. A copy read after both holds every write announced:
7268
+ * see `current`.
7269
+ */
7270
+ private hearing;
7271
+ private missedAt;
7272
+ private readonly heardAt;
7273
+ /**
7274
+ * Each record a write of which this namespace marked as begun and could
7275
+ * not count, and has said so, until one is counted. And whether it has
7276
+ * said that a write it could not mark or count may be lost, which it
7277
+ * says only once. See `notCounted`.
7278
+ */
7279
+ private readonly uncounted;
7280
+ private lossWarned;
7281
+ /**
7282
+ * The copy of each record this namespace is writing under the record's
7283
+ * lock, by id, from when it has decided what to write until it has
7284
+ * counted the write, or failed to. Its counter reads as unknown
7285
+ * meanwhile, as this write has begun and is not counted yet, but the
7286
+ * copy holds every write of the record another tab has counted, and no
7287
+ * other tab can make one until this one lets go of the lock. See
7288
+ * `dropStale`.
7289
+ */
7290
+ private readonly locked;
7291
+ /**
7292
+ * Each directory a `createDir` here has named whose write has not landed
7293
+ * yet, by entry id: a promise that settles - and never rejects - once
7294
+ * that write has landed or failed. See `mkdir`.
7295
+ */
7296
+ private readonly naming;
6895
7297
  private readonly historyLimit;
6896
7298
  private readonly maxEntries;
6897
7299
  private readonly maxPathChars;
@@ -7113,11 +7515,12 @@ declare class VfsNamespace {
7113
7515
  * Delete metadata records no longer reachable from the root.
7114
7516
  *
7115
7517
  * These accumulate because every write touches exactly one record: if two
7116
- * tabs or devices edit the same directory, the personal space keeps
7117
- * whichever put arrives last (a VFS write sends no HLC, and the space
7118
- * applies puts of one key in arrival order), which can leave a child whose
7119
- * parent entry lost the race. The per-record write queue (`writing`) only
7120
- * orders writes within one tab. Unreachable is harmless —
7518
+ * devices edit the same directory - or two tabs, where there is no
7519
+ * coordinator - the personal space keeps whichever put arrives last (a
7520
+ * VFS write sends no HLC, and the space applies puts of one key in arrival
7521
+ * order), which can leave a child whose parent entry lost the race. The
7522
+ * per-record queue and the coordinator order writes within one device
7523
+ * only. Unreachable is harmless —
7121
7524
  * it is invisible and undecryptable-by-nobody — but it costs storage, so
7122
7525
  * this reclaims it.
7123
7526
  *
@@ -7157,6 +7560,15 @@ declare class VfsNamespace {
7157
7560
  * the error names whichever asked first.
7158
7561
  */
7159
7562
  private openDirById;
7563
+ /**
7564
+ * Fetch record `id` from the store and open it. Whatever another tab
7565
+ * announced before the fetch began is in what it returns (see
7566
+ * `current`), and so is every write its counter counts: read here, or
7567
+ * given as `counter` (see `OpenDir.counter`).
7568
+ */
7569
+ private fetchRecord;
7570
+ /** Record `id`'s write counter now: see `OpenDir.counter`. */
7571
+ private counterOf;
7160
7572
  /**
7161
7573
  * Turn a decrypted record into an OpenDir, or throw.
7162
7574
  *
@@ -7179,8 +7591,18 @@ declare class VfsNamespace {
7179
7591
  *
7180
7592
  * So `edit` must take what it writes from the record it is given, not
7181
7593
  * from anything read off `dir` before an await - and re-check whatever it
7182
- * relies on from then, throwing if another write changed it. Returning
7183
- * false writes nothing after all.
7594
+ * relies on from then, throwing if another write changed it, before it
7595
+ * changes anything. Returning false writes nothing after all.
7596
+ *
7597
+ * The write that carries the edit may carry others, made while an
7598
+ * earlier write of the record was in flight (see `queue`): it lands, or
7599
+ * fails, for all of them at once.
7600
+ *
7601
+ * With a coordinator, the edit may be made a second time, to the record
7602
+ * as another tab left it, and refused then (see `replay`): an edit must
7603
+ * check everything before it changes anything, and whatever it sets
7604
+ * outside `node` and `record` must be safe to set again, since each run
7605
+ * overwrites the last.
7184
7606
  */
7185
7607
  private mutate;
7186
7608
  /**
@@ -7206,6 +7628,112 @@ declare class VfsNamespace {
7206
7628
  private reopen;
7207
7629
  /** Make `dir` the cached copy of its record - unless the cache has been cleared since it was read. */
7208
7630
  private adopt;
7631
+ /** After an edit of `copy`: its time, and any entry it cannot read that the edit replaced. */
7632
+ private touch;
7633
+ /**
7634
+ * The write that will carry the edit just made to `copy`.
7635
+ *
7636
+ * Writes of a record go out one at a time, each once the one before it
7637
+ * has landed or failed (see `writing`), and each seals the record as it
7638
+ * stands when it goes out. So a write still waiting carries every edit
7639
+ * made while it waits, and an edit made then joins it instead of
7640
+ * queueing a write of its own: a burst of edits of one directory while a
7641
+ * write of it is in flight costs two writes, not one per edit. Each is a
7642
+ * billed write; a 20-file upload into one folder cost twenty.
7643
+ */
7644
+ private queue;
7645
+ /**
7646
+ * Send `batch`: from here on, an edit of its record goes in the next
7647
+ * write. With a coordinator, holding the lock every tab of the device
7648
+ * takes to write this record - see `sendLocked`.
7649
+ */
7650
+ private send;
7651
+ /** Stop `batch` taking more edits, as it is sealed. */
7652
+ private close;
7653
+ /**
7654
+ * Send `batch` while no other tab can write its record.
7655
+ *
7656
+ * If another tab wrote the record since this copy was read, the copy is
7657
+ * out of date, and writing it would undo that tab's write. So it is read
7658
+ * again, here, under the lock, and every edit the batch carries is made
7659
+ * again to what was read (see `replay`). A copy no other tab has written
7660
+ * over is sent as it is: one tab on its own costs no extra request.
7661
+ *
7662
+ * Which it is, the record's write counter says (see
7663
+ * `VfsCoordinator.counters`). Read once the lock is granted, it counts
7664
+ * every write of the record another tab made, because each counts its
7665
+ * write, and waits for the count to be stored, before it lets go of the
7666
+ * lock. If it has moved since the copy was read, or cannot be told, the
7667
+ * copy is read again. Whether this tab has heard of another tab's write
7668
+ * does not decide it: an announcement can reach this tab after the
7669
+ * lock does, or never. One it has heard of can only add a read.
7670
+ *
7671
+ * The write is counted once it has landed or failed - one that failed
7672
+ * may have landed even so - and the other tabs are then told of it,
7673
+ * all before the lock is let go of.
7674
+ */
7675
+ private sendLocked;
7676
+ /**
7677
+ * Say that a write of `copy`'s record could not be counted.
7678
+ *
7679
+ * `marked`: `VfsCoordinator.begin` stored its mark, which stays until a
7680
+ * count can be stored, so every tab reads the record again before it
7681
+ * writes it. Said once for each record, until a write of it is counted.
7682
+ *
7683
+ * Not marked, a tab whose IndexedDB works may take its copy for current
7684
+ * and write it over this write. Said once for this namespace, whatever
7685
+ * the record: where IndexedDB cannot be used at all, no write of any
7686
+ * folder is counted, and a warning for each said nothing new. And only
7687
+ * where another tab can count its writes can one be lost, which the
7688
+ * warning says: where no tab can, every tab reads each folder again.
7689
+ */
7690
+ private notCounted;
7691
+ /**
7692
+ * Make every edit in `batch` again, in order, to `fresh` - the record as
7693
+ * another tab left it - and make that the copy. An edit that no longer
7694
+ * applies throws, as it would have the first time, and is left out; its
7695
+ * caller gets what it threw. Every edit checks before it changes
7696
+ * anything (see `mutate`), so one that throws has changed nothing. True
7697
+ * when what is left changes the record, and so needs writing.
7698
+ */
7699
+ private replay;
7700
+ /**
7701
+ * Another tab wrote record `id` - or, null, this namespace may have
7702
+ * missed some announcements. What the cache holds is read again when
7703
+ * next asked for, as a change frame from the personal space would have
7704
+ * it, and a copy read before then is read again before the next write
7705
+ * of its record (see `current`). A hint, not a guarantee: an
7706
+ * announcement can reach this tab after the next lock does, or never.
7707
+ * What decides whether a copy may be written over, or relied on under a
7708
+ * move's or a delete's locks, is the record's counter: see `sendLocked`
7709
+ * and `dropStale`.
7710
+ */
7711
+ private heard;
7712
+ /**
7713
+ * Does `copy` hold every write of its record another tab has announced
7714
+ * that this one has heard of? See `heard`. Only ever a reason to read it
7715
+ * again, never to take it for current: see `sendLocked`.
7716
+ */
7717
+ private current;
7718
+ /**
7719
+ * Drop from the cache every copy of a record in `ids` that may not hold
7720
+ * every write of it another tab has made: its counter has moved since
7721
+ * the copy was read, or cannot be told, or the copy is still being read.
7722
+ * Returns every id whose copy here is not known to be current - those,
7723
+ * and those not cached - so that the next read of each fetches it again,
7724
+ * once any write of it in flight here has landed or failed. Not a copy
7725
+ * this tab is writing under its lock (see `locked`): its counter reads
7726
+ * as unknown only because that write is not counted yet, and dropped,
7727
+ * the next read would wait for the write.
7728
+ *
7729
+ * The counters are read in one go, after the caller has taken the locks
7730
+ * it relies on: another tab counts each write of a record before it lets
7731
+ * go of the locks it held while writing it, the record's own and any
7732
+ * move lock, so what it wrote before letting go of one of them is
7733
+ * counted by then. Its announcements may not have reached this tab yet,
7734
+ * or ever. See `sendLocked`.
7735
+ */
7736
+ private dropStale;
7209
7737
  /**
7210
7738
  * Seal a directory record as it stands NOW and put it in the store.
7211
7739
  *
@@ -7230,8 +7758,44 @@ declare class VfsNamespace {
7230
7758
  *
7231
7759
  * `moving` says whether anything in it is marked as half of an
7232
7760
  * interrupted move, which is what makes a delete look for the other half.
7761
+ *
7762
+ * `ids` is every entry id in it, and `shape` what each record named when
7763
+ * it was read: see `currentSubtree`.
7233
7764
  */
7234
7765
  private subtree;
7766
+ /**
7767
+ * The records a recursive delete read, as they are now - or null when
7768
+ * one has changed since in a way that purging it would get wrong.
7769
+ *
7770
+ * The delete decided what to let go of, and whether to look for the
7771
+ * other half of a move, from what it read; then it waited, on reads and
7772
+ * on the write of its parent. A record that is no longer named by the
7773
+ * record it was read in has been moved out, and is not this delete's to
7774
+ * purge; an entry marked since it was read is being moved, and is about
7775
+ * to be named somewhere the delete never looked. Purging either purged
7776
+ * the folder a move had just put somewhere else. Anything else - a file
7777
+ * saved into one of them, or moved out - is purged as it now stands,
7778
+ * which is why the copies to purge are what this returns.
7779
+ *
7780
+ * Synchronous, for an edit. A record whose copy is not to hand counts as
7781
+ * changed.
7782
+ *
7783
+ * `held`, with a coordinator, is every entry whose move lock the delete
7784
+ * holds. An entry named since the records were read - saved or moved in
7785
+ * - is not among them, so nothing stops another tab moving it out while
7786
+ * the delete writes the parent, and purging it then let go of what that
7787
+ * move had put somewhere else. So with `held`, that counts as changed
7788
+ * too, and the delete is tried again from the start.
7789
+ */
7790
+ private currentSubtree;
7791
+ /**
7792
+ * Hold the move lock of every entry in `ids` - see
7793
+ * `VfsCoordinator.holdMoving` - or of none: null when another holder has
7794
+ * any of them, and then nothing is held. Otherwise the function that
7795
+ * lets go of them all. Asked for all at once: none of them waits.
7796
+ * `shared` holds them as the folders a move goes into.
7797
+ */
7798
+ private holdAll;
7235
7799
  /**
7236
7800
  * Delete these records and let go of every file in them. The second half
7237
7801
  * of a recursive delete, run only once the subtree is detached. Cannot
@@ -7816,6 +8380,8 @@ declare class Client {
7816
8380
  readonly functions: FunctionsNamespace;
7817
8381
  /** Access tokens — `client.accessTokens.create(appId, …)`, etc. */
7818
8382
  readonly accessTokens: AccessTokensNamespace;
8383
+ /** This app — `client.app.access()`: may the signed-in user add data here? */
8384
+ readonly app: AppNamespace;
7819
8385
  /** Offline cache + sync — `client.offline.status`, `client.offline.snapshot`, etc. */
7820
8386
  readonly offline: OfflineManager;
7821
8387
  private readonly session;
@@ -9102,7 +9668,7 @@ declare function getId(row: {
9102
9668
  * expect (and isn't serving a stale cached bundle). Keep this in sync with
9103
9669
  * `package.json` `version`.
9104
9670
  */
9105
- declare const VERSION = "0.15.0-alpha.3";
9671
+ declare const VERSION = "0.15.0-alpha.5";
9106
9672
 
9107
9673
  /**
9108
9674
  * The SDK's process-global logger.
@@ -9134,5 +9700,5 @@ declare global {
9134
9700
  }
9135
9701
  declare const appLogger: InstanceType<typeof Logger>;
9136
9702
 
9137
- export { ACCESS_TOKEN_SCOPES, AES_GCM_IV_BYTES, AES_GCM_KEY_BYTES, 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, 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, assertType, base58Decode, base58Encode, buildCommitment, canonicalUserCode, clearDeviceIdentity, compareHlc, compilePrograms, 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, 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, toBase64Url, toField, toHex, tombstoneRow, unpack, unsealSeed, unsealSeedFromDevice, unwrapWithPassphrase, utf8Decode, utf8Encode, verify, verifyChecksum, verifyGroth16, verifyHashKnowledge, verifyPreimagePoK, wrapWithPassphrase, writeBeatsTombstone, writeColumns, writeRegister };
9138
- export type { ACL, ACLEntry, AccessTokenInfo, AccessTokensNamespaceDeps, AdmissionState, AgentConfig, AgentCreateInput, AgentDbToolMode, AgentProvisioned, AgentScopeOpts, AgentSkill, AgentToolsConfig, AgentTrigger, AgentTriggerType, AgentUpdateInput, AgentsNamespaceDeps, AttachedPeerNetwork, AuthClientOptions, AuthKeyPair, AuthSuccess, AuthToken, AuthType, AuthUser, BlockStore, Bn128WasmInstance, BroadcastChannelEvent, BroadcastChannelOptions, CachedSpaceMessage, Change, ChannelLike, ChatKeyCert, ChunkKeyMaterial, ChunkManifest, CipherFrame, CipherMessage, CipherMessageHeader, CircuitBufferConfig, CircuitIntegrity, CircuitUrls, ClientOptions, Commit, Conflict, ConnectivityOptions, ConnectivityState, CreateAccessTokenInput, CreatedAccessToken, DbFilterOp, DbNamespaceDeps, DbQuery, DbQueryPage, DbQueryResult, DbWhereCondition, DehydratedKeypair, DehydratedKeys, DeviceBlobStore, DeviceKeyVault, DevicePairingErrorReason, DevicePairingKeypair, DevicePairingPoll, DevicePairingRequest, DevicePairingSession, DirEntry, DirNode, DoubleRatchetCipherDeps, ECDHCurve, EncodeResult, EngineHandle, EngineHost, Entry, EphemeralEvent, EpochKeyProvider, FileEntry, FileManifest, FileNamespaceDeps, FileStat, FileStorageOptions, FunctionCaps, FunctionConfig, FunctionDeployInput, FunctionInvokeOptions, FunctionScopeOpts, FunctionTrigger, FunctionTriggerType, FunctionTriggers, FunctionUpdateInput, FunctionsNamespaceDeps, Groth16Proof, Hasher, Head, HistoryRecord, HlcParts, HlcState, HostedAuthDeps, HttpClientOptions, IncomingFrame, KeyExchangeFrame, KeyPair, Keypair, KeyringClientDeps, KeyringTransport, KvEntry, KvNamespaceDeps, LogEntry, LoginOptions, LwwMap, LwwRegister, MemberView, MembershipEntry, Merge3Result, MergeRegionConflict, MergeResult, MessageBody, MessageDeletedEvent, MessageEntry, MessageEvent, MessageHeaders, MessageNamespaceDeps, MessageOp, MessageOptions, MessageSubscription, MuhkooAgentMeta, MuhkooAgentToolsConfig, MuhkooAppDescriptor, MuhkooDBAccess, MuhkooDBMeta, MuhkooFunctionMeta, MuhkooKeystoreBridge, MuhkooMessageEvent, MuhkooSpaceMeta, OAuthProvider, OfflineEntry, OfflineManagerDeps, OfflineStore, OutSink, PacketCipher, PacketHeaders, PacketOptions, PairedDevice, Participant, PasskeyEnrollment, PeerBlockSource, PeerExchangeOptions, PeerId, PeerNetworkOptions, PeerTransport, Permission, PermissionCheckRequest, PermissionCheckResult, PersistedDeviceIdentity, PersonalSpaceClientOptions, Pkce, PublicKeyJWK, QueueEntry, RatchetState, ReceiveResult, RegisterParams, Replayer, Role$1 as Role, SpaceDeps as RoomDeps, SpaceFileMetadata as RoomFileMetadata, Scope, SealedHandoff, SealedHeaders, SealedRecord, Session, SessionOptions, SessionStore, SetOptions, ShardByteCache, ShardClientOptions, SharedSpaceClientOptions, SignalEnvelope, SignalKind, SignalingSpace, SnapshotNamespaceDeps, SnarkProof, SpaceChannelLike, SpaceCursor, SpaceDeps, SpaceFileMetadata, SpaceKeyCache, SpaceKeyringDeps, SpaceMessageEvent, SpaceNamespaceDeps, SpaceOfflineAdapter, SpaceTrustCode, StartDevicePairingOptions, StorageChangeEvent, StoreName, StoredSession, Subscription, Tree, TreeDir, TreeEntry, TreeFile, UserIdentity, VaultFactor, VcsNamespaceDeps, VcsNamespaceOptions, VerificationKey, VfsContentStore, VfsNamespaceDeps, VfsStat, VfsStore, WSMessage, WSMessageType, WSTransportOptions, WaitForDevicePairingOptions, WebRtcTransportOptions, WrappedPayload, WriteFileInput, WriteFileOptions, WriteToShardsInput, ZkAuthDeps, ZkAuthenticateRequest, ZkChallengeResponse, ZkCompiled, ZkIdentity, ZkRegisterRequest, ZkRegisterResponse };
9703
+ export { ACCESS_TOKEN_SCOPES, AES_GCM_IV_BYTES, AES_GCM_KEY_BYTES, 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, 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, assertType, base58Decode, base58Encode, buildCommitment, canonicalUserCode, clearDeviceIdentity, compareHlc, compilePrograms, 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, 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, toBase64Url, toField, toHex, tombstoneRow, unpack, unsealSeed, unsealSeedFromDevice, unwrapWithPassphrase, utf8Decode, utf8Encode, verify, verifyChecksum, verifyGroth16, verifyHashKnowledge, verifyPreimagePoK, wrapWithPassphrase, writeBeatsTombstone, writeColumns, writeRegister };
9704
+ export type { ACL, ACLEntry, AccessTokenInfo, AccessTokensNamespaceDeps, AdmissionState, AgentConfig, AgentCreateInput, AgentDbToolMode, AgentProvisioned, AgentScopeOpts, AgentSkill, AgentToolsConfig, AgentTrigger, AgentTriggerType, AgentUpdateInput, AgentsNamespaceDeps, AppAccess, AppNamespaceDeps, AttachedPeerNetwork, AuthClientOptions, AuthKeyPair, AuthSuccess, AuthToken, AuthType, AuthUser, BlockStore, Bn128WasmInstance, BroadcastChannelEvent, BroadcastChannelOptions, CachedSpaceMessage, Change, ChannelLike, ChatKeyCert, ChunkKeyMaterial, ChunkManifest, CipherFrame, CipherMessage, CipherMessageHeader, CircuitBufferConfig, CircuitIntegrity, CircuitUrls, ClientOptions, Commit, Conflict, ConnectivityOptions, ConnectivityState, CreateAccessTokenInput, CreatedAccessToken, DbFilterOp, DbNamespaceDeps, DbQuery, DbQueryPage, DbQueryResult, DbWhereCondition, DehydratedKeypair, DehydratedKeys, DeviceBlobStore, DeviceKeyVault, DevicePairingErrorReason, DevicePairingKeypair, DevicePairingPoll, DevicePairingRequest, DevicePairingSession, DirEntry, DirNode, DoubleRatchetCipherDeps, ECDHCurve, EncodeResult, EngineHandle, EngineHost, Entry, EphemeralEvent, EpochKeyProvider, FileEntry, FileManifest, FileNamespaceDeps, FileStat, FileStorageOptions, FunctionCaps, FunctionConfig, FunctionDeployInput, FunctionInvokeOptions, FunctionScopeOpts, FunctionTrigger, FunctionTriggerType, FunctionTriggers, FunctionUpdateInput, FunctionsNamespaceDeps, Groth16Proof, Hasher, Head, HistoryRecord, HlcParts, HlcState, HostedAuthDeps, HttpClientOptions, IncomingFrame, KeyExchangeFrame, KeyPair, Keypair, KeyringClientDeps, KeyringTransport, KvEntry, KvNamespaceDeps, LogEntry, LoginOptions, LwwMap, LwwRegister, MemberView, MembershipEntry, Merge3Result, MergeRegionConflict, MergeResult, MessageBody, MessageDeletedEvent, MessageEntry, MessageEvent, MessageHeaders, MessageNamespaceDeps, MessageOp, MessageOptions, MessageSubscription, MuhkooAgentMeta, MuhkooAgentToolsConfig, MuhkooAppDescriptor, MuhkooDBAccess, MuhkooDBMeta, MuhkooFunctionMeta, MuhkooKeystoreBridge, MuhkooMessageEvent, MuhkooSpaceMeta, OAuthProvider, OfflineEntry, OfflineManagerDeps, OfflineStore, OutSink, PacketCipher, PacketHeaders, PacketOptions, PairedDevice, Participant, PasskeyEnrollment, PaymentRequiredCode, PeerBlockSource, PeerExchangeOptions, PeerId, PeerNetworkOptions, PeerTransport, Permission, PermissionCheckRequest, PermissionCheckResult, PersistedDeviceIdentity, PersonalSpaceClientOptions, Pkce, PublicKeyJWK, QueueEntry, RatchetState, ReceiveResult, RegisterParams, Replayer, Role$1 as Role, SpaceDeps as RoomDeps, SpaceFileMetadata as RoomFileMetadata, Scope, SealedHandoff, SealedHeaders, SealedRecord, Session, SessionOptions, SessionStore, SetOptions, ShardByteCache, ShardClientOptions, SharedSpaceClientOptions, SignalEnvelope, SignalKind, SignalingSpace, SnapshotNamespaceDeps, SnarkProof, SpaceChannelLike, SpaceCursor, SpaceDeps, SpaceFileMetadata, SpaceKeyCache, SpaceKeyringDeps, SpaceMessageEvent, SpaceNamespaceDeps, SpaceOfflineAdapter, SpaceTrustCode, StartDevicePairingOptions, StorageChangeEvent, StoreName, StoredSession, Subscription, Tree, TreeDir, TreeEntry, TreeFile, UserIdentity, VaultFactor, VcsNamespaceDeps, VcsNamespaceOptions, VerificationKey, VfsContentStore, VfsNamespaceDeps, VfsStat, VfsStore, WSMessage, WSMessageType, WSTransportOptions, WaitForDevicePairingOptions, WebRtcTransportOptions, WrappedPayload, WriteFileInput, WriteFileOptions, WriteToShardsInput, ZkAuthDeps, ZkAuthenticateRequest, ZkChallengeResponse, ZkCompiled, ZkIdentity, ZkRegisterRequest, ZkRegisterResponse };