@spooky-sync/core 0.0.1-canary.355 → 0.0.1-canary.356

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/AGENTS.md CHANGED
@@ -45,6 +45,7 @@ re-materialized from state, never patched in place.
45
45
  - `services/blobs/` — durable cache for bucket bytes: OPFS holds the files, `_00_blob` holds a manifest that reconcile rebuilds from disk (so a wiped local store costs metadata, not the offline cache). Nothing expires on a timer; eviction is LRU under a byte budget only, skipping pinned and on-screen entries. Config: `blobCache` in `types.ts`.
46
46
  - `AuthService` — token management, sign-in/sign-out events. `subscribe(cb, { immediate? })` calls `cb` at once with the current user unless `immediate: false`, then on every change.
47
47
  - `CrdtManager`, `CrdtField`, `cursorColorFromName`, `CURSOR_COLORS`: collaborative `@crdt` fields on Loro. Client methods: `openCrdtField(table, recordId, field, draft?)` -> `Promise<CrdtField>` (every open of one field in a tab shares one `LoroDoc`; pair each with a close), `closeCrdtField(table, recordId, field)` -> `Promise<void>` (resolves once unsent edits are in the outbox; offline, once they are saved on the device, never waiting on the network), `createCrdtDraft(table, field)` -> a detached `CrdtField` for a record not created yet (`db.create` first, then pass it to `openCrdtField` as `draft`). `CrdtField`: `getDoc()`, `hasContent()`, `pushCursorState(bytes)`, `onCursorUpdate = cb` (a setter). Config: `crdt: true` preloads Loro, `crdtDebounceMs` (the first edit after a quiet spell waits this long, default 50), `crdtSendIntervalMs` (shortest gap between two sends of one field while typing, default 200). Design: `docs/crdt-v2.md` at the repo root.
48
+ - **Peer to peer channels** (`-- @channel` tables, experimental): `client.channel(query, peers)` (a query builder, a built query, or a list, on `@channel` tables; typed from the query; own id skipped; both sides must list each other) opens WebRTC data channels to the peers' tabs and returns `Sp00kyChannel` (`state()`, `subscribe(cb)`, `setPeers`, `setQueries`, `close`, `tables()`, plus scoped `update` / `create` / `delete`). Only the query's `where` counts (`matchesWhere`, pure JS over the plan; `compileScope` throws for `.related()`, link-following paths, `$params`, unknown ops); it is never registered. `orderBy` / `limit` / `offset` / `select` / `.one()` warn once per shape (`unusedArgs`) unless the builder has `.ignoreUnusedArgs()`. Writes go to the peers of every open channel whose filter the row matches: a create checks the new row, an update or delete the stored row (`readRow` saga) before and after the patch. A peer's write is taken only if the sender is listed by a channel whose filter the row matches (an update/delete of a row not held is ignored). Peers fold updates into every subscription showing the row (output only, never the store): normal fields retire once the synced row holds them (or after `channels.confirmTimeoutMs`, default 5000); `-- @ephemeral` fields (optional, never filtered on) never reach the database, last writer wins, vanish when their author disconnects. A peer's create goes into the store and circuit like an own optimistic create minus the outbox (`peerCreate` saga, `state.peerWrites` folded into `overlay()`) and is undone at `confirmTimeoutMs` unless the server body landed (`versions`); a peer's delete hides the row through the overlay until it expires (`peerDelete`, `PeerWriteExpired`). Signaling is raw CREATE/LIVE on the generated server-only `_00_channel_signal` (sender stamped by the DB). Everything beyond identity, filter and field types is `channels.accept: { [table]: ({ kind, from, table, id, row, patch }) => boolean }`. Config also `iceServers`, `transport`. TS only (no Dart). Code: `modules/channel/`. Docs: `/docs/client/channels`.
48
49
  - Types: `Sp00kyConfig` (client-solid wraps it as `SyncedDbConfig`), `QueryTimeToLive`, `PersistenceClient`, `StoreType`, `UpdateOptions`, `RunOptions`, `PreloadOptions`.
49
50
  - Subpath: `@spooky-sync/core/otel` — `createOtelTransmit(endpoint)` for piping pino logs to OpenTelemetry.
50
51
  - `client.webPush` (`WebPushModule`, `db.webPush` in the Solid bindings) - Web Push on the page: `support()`, `info()`, `subscribe(opts)` (call from a click), `unsubscribe(opts)`, `sync()`, `isSubscribed()`, `update(opts)`, `devices()`, `notify(msg)`, `cancel(id)`, `test()`, `bridge()`, `onMessage(cb)`. Server calls are `fn::push::*`; typed `WebPushError`; config `webPush` in `types.ts`. Sign-out runs through `AuthService.onBeforeSignOut`.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { $ as WebPushModule, A as RegistrationTimings, At as RemoteDatabaseService, B as SyncHealthConfig, Bt as ImpersonationTimers, C as QueryStatusCallback, Ct as SIGN_OUT_HOOK_TIMEOUT_MS, D as ReconnectConfig, Dt as AuthEventTypeMap, E as QueryUpdateCallback, Et as AuthEventSystem, F as Sp00kyQueryResultPromise, Ft as EventDefinition, G as PushDeviceKind, Gt as impersonationFromToken, H as TimingPhase, Ht as SESSION_POLL_MS, I as StorageHealth, It as EventSystem, J as WebPushError, K as WebPushConfig, Kt as renewDelayMs, L as StorageHealthStatus, Lt as IMPERSONATION_ACCESS, M as ServerViewMeta, Mt as Logger$1, N as Sp00kyConfig, Nt as LocalStore, O as RecordVersionArray, Ot as AuthEventTypes, P as Sp00kyQueryResult, Pt as SealedQuery, Q as WebPushMessageInput, R as StoreType, Rt as ImpersonationInfo, S as QueryStatus, St as REFUSAL_RECHECK_MIN_MS, T as QueryTimings, Tt as SignOutHook, U as UpdateOptions, Ut as TokenClaims, V as SyncHealthStatus, Vt as ORIGIN_TOKEN_KEY, W as PUSH_ENDPOINT_KEY, Wt as decodeTokenClaims, X as WebPushInfo, Y as WebPushErrorCode, Z as WebPushMessage, _ as QueryAuthorityCallback, _t as WebPushClientMessage, a as InlineRow, at as WebPushUnsupportedReason, b as QueryHash, bt as AuthService, c as MembershipOutcome, ct as BridgeSignOutMessage, d as MutationEventType, dt as PushNotification, et as WebPushSubscribeOptions, f as PersistenceClient, ft as PushNotificationAction, g as PreloadRefresh, gt as PushUrgency, h as PreloadOptions, ht as PushPayloadKind, i as EventSubscriptionOptions, it as WebPushUnsubscribeOptions, j as RunOptions, jt as LogTap, k as RecordVersionDiff, kt as createAuthEventSystem, l as MutationCallback, lt as BridgeTokenMessage, m as PinoTransmit, mt as PushPayload, n as DebounceOptions, nt as WebPushSyncOptions, o as Level, ot as WebPushUpdateOptions, p as PhaseStat, pt as PushOp, q as WebPushDevice, qt as sameImpersonation, r as EdgeDelta, rt as WebPushSyncStatus, s as MATERIALIZATION_SAMPLE_WINDOW, st as detectWebPushSupport, t as ConnectionState, tt as WebPushSupport, u as MutationEvent, ut as PUSH_PAYLOAD_VERSION, v as QueryConfig, vt as isPushPayload, w as QueryTimeToLive, wt as SignOutContext, x as QueryState, xt as ImpersonationCandidate, y as QueryConfigRecord, yt as ActiveImpersonation, z as SyncHealth, zt as ImpersonationTimerHost } from "./types.js";
2
- import { BackendNames, BackendRoutes, BucketNames, FinalQuery, GetTable, QueryBuilder, QueryOptions, QueryPlan, RecordId, RoutePayload, SchemaStructure, TableModel, TableNames } from "@spooky-sync/query-builder";
1
+ import { $ as WebPushMessage, $t as ChannelState, A as RecordVersionDiff, At as AuthEventTypes, B as StoreType, Bt as ImpersonationTimers, C as QueryStatus, Ct as ImpersonationCandidate, D as QueryUpdateCallback, Dt as SignOutHook, E as QueryTimings, Et as SignOutContext, F as Sp00kyConfig, Ft as EventDefinition, G as UpdateOptions, Gt as impersonationFromToken, H as SyncHealthConfig, Ht as SESSION_POLL_MS, I as Sp00kyQueryResult, It as EventSystem, J as WebPushConfig, Jt as ChannelAcceptRule, K as PUSH_ENDPOINT_KEY, Kt as renewDelayMs, L as Sp00kyQueryResultPromise, Lt as IMPERSONATION_ACCESS, M as RunOptions, Mt as RemoteDatabaseService, N as ServerViewMeta, Nt as LocalStore, O as ReconnectConfig, Ot as AuthEventSystem, P as Sp00kyChannel, Pt as SealedQuery, Q as WebPushInfo, Qt as ChannelScope, R as StorageHealth, Rt as ImpersonationInfo, S as QueryState, St as AuthService, T as QueryTimeToLive, Tt as SIGN_OUT_HOOK_TIMEOUT_MS, U as SyncHealthStatus, Ut as TokenClaims, V as SyncHealth, Vt as ORIGIN_TOKEN_KEY, W as TimingPhase, Wt as decodeTokenClaims, X as WebPushError, Xt as ChannelMessage, Y as WebPushDevice, Yt as ChannelHandle, Z as WebPushErrorCode, Zt as ChannelOp, _ as PreloadRefresh, _t as PushPayloadKind, a as EventSubscriptionOptions, an as TransportHooks, at as WebPushSyncStatus, b as QueryConfigRecord, bt as isPushPayload, c as MATERIALIZATION_SAMPLE_WINDOW, cn as LogTap, ct as WebPushUpdateOptions, d as MutationEvent, dt as BridgeTokenMessage, en as ChannelStatus, et as WebPushMessageInput, f as MutationEventType, ft as PUSH_PAYLOAD_VERSION, g as PreloadOptions, gt as PushPayload, h as PinoTransmit, ht as PushOp, i as EdgeDelta, in as PeerRef, it as WebPushSyncOptions, j as RegistrationTimings, jt as createAuthEventSystem, k as RecordVersionArray, kt as AuthEventTypeMap, l as MembershipOutcome, ln as Logger$1, lt as detectWebPushSupport, m as PhaseStat, mt as PushNotificationAction, n as ConnectionState, nn as ChannelTransportFactory, nt as WebPushSubscribeOptions, o as InlineRow, on as matchesWhere, ot as WebPushUnsubscribeOptions, p as PersistenceClient, pt as PushNotification, q as PushDeviceKind, qt as sameImpersonation, r as DebounceOptions, rn as ChannelsConfig, rt as WebPushSupport, s as Level, sn as unusedArgs, st as WebPushUnsupportedReason, t as ChannelQuery, tn as ChannelTransport, tt as WebPushModule, u as MutationCallback, ut as BridgeSignOutMessage, v as QueryAuthorityCallback, vt as PushUrgency, w as QueryStatusCallback, wt as REFUSAL_RECHECK_MIN_MS, x as QueryHash, xt as ActiveImpersonation, y as QueryConfig, yt as WebPushClientMessage, z as StorageHealthStatus, zt as ImpersonationTimerHost } from "./types.js";
2
+ import { BackendNames, BackendRoutes, BucketNames, ChannelPeer, ChannelTableNames, FinalQuery, GetTable, QueryBuilder, QueryOptions, QueryPlan, RecordId, RoutePayload, SchemaStructure, TableModel, TableNames } from "@spooky-sync/query-builder";
3
3
  import * as surrealdb0 from "surrealdb";
4
4
  import { Duration, RecordId as RecordId$1, Surreal } from "surrealdb";
5
5
  import { Logger } from "pino";
@@ -952,6 +952,9 @@ type RuntimeEvent = {
952
952
  } | {
953
953
  type: 'FlushWrite';
954
954
  key: string;
955
+ } | {
956
+ type: 'PeerWriteExpired';
957
+ id: string;
955
958
  } | {
956
959
  type: 'FlushPendingWrites';
957
960
  } | {
@@ -1380,6 +1383,17 @@ interface PendingWrite {
1380
1383
  /** Its durable copy in `_00_pending_writes`; null when `flushOnHide` is off. */
1381
1384
  readonly mirrorId: string | null;
1382
1385
  }
1386
+ /**
1387
+ * A create or delete a channel peer sent, applied here before the server has
1388
+ * it (see `modules/channel`). Shown like an own optimistic write through the
1389
+ * overlay; when `expiresAt` passes it is either confirmed (the server's body
1390
+ * landed) or undone.
1391
+ */
1392
+ interface PeerWrite {
1393
+ readonly kind: 'create' | 'delete';
1394
+ readonly table: string;
1395
+ readonly expiresAt: number;
1396
+ }
1383
1397
  interface SyncSlice {
1384
1398
  readonly health: SyncHealth;
1385
1399
  readonly consecutiveFailures: number;
@@ -1427,6 +1441,8 @@ interface ClientState {
1427
1441
  readonly views: ReadonlyMap<string, ReadonlyArray<string>>;
1428
1442
  readonly outbox: ReadonlyArray<OutboxItem>;
1429
1443
  readonly pendingWrites: ReadonlyMap<string, PendingWrite>;
1444
+ /** Channel peers' unconfirmed creates and deletes, by record id. */
1445
+ readonly peerWrites: ReadonlyMap<string, PeerWrite>;
1430
1446
  readonly failedCount: number;
1431
1447
  /** Queries whose render inputs changed since their last materialization. */
1432
1448
  readonly dirty: ReadonlySet<QueryHash>;
@@ -2115,6 +2131,8 @@ declare class Sp00kyClient<S extends SchemaStructure> {
2115
2131
  readonly streamProcessor: StreamProcessorService;
2116
2132
  /** Web Push for this browser: subscribe, devices, self-pushes, service worker bridge. */
2117
2133
  readonly webPush: WebPushModule;
2134
+ /** Peer to peer channels of `-- @channel` tables. */
2135
+ private readonly channels;
2118
2136
  private readonly services;
2119
2137
  private readonly env;
2120
2138
  private readonly runtime;
@@ -2156,6 +2174,16 @@ declare class Sp00kyClient<S extends SchemaStructure> {
2156
2174
  subscribe(queryHash: string, callback: (records: Record<string, any>[]) => void, options?: {
2157
2175
  immediate?: boolean;
2158
2176
  }): Promise<() => void>;
2177
+ /**
2178
+ * Open a peer to peer channel to `peers` (your own id is skipped; a
2179
+ * connection forms only when both sides list each other) for the rows
2180
+ * `queries` match, each a query on a `-- @channel` table. Only its `where`
2181
+ * counts, evaluated against each row; the query is never registered. Writes
2182
+ * to matching rows (plain or the channel's own) reach the peers. Close it
2183
+ * when done.
2184
+ */
2185
+ channel<T extends ChannelTableNames<S>>(queries: ChannelQuery<S, T> | ReadonlyArray<ChannelQuery<S, T>>, peers: Iterable<ChannelPeer>): Sp00kyChannel<S, T>;
2186
+ private channelScopes;
2159
2187
  deregisterQuery(queryHash: string): void;
2160
2188
  subscribeQueryStatus(queryHash: string, callback: QueryStatusCallback, options?: {
2161
2189
  immediate?: boolean;
@@ -2165,8 +2193,11 @@ declare class Sp00kyClient<S extends SchemaStructure> {
2165
2193
  }): () => void;
2166
2194
  reportFrontendTiming(queryHash: string, ms: number): void;
2167
2195
  create<T extends Record<string, unknown>>(id: string, data: T): Promise<T>;
2168
- update<T extends Record<string, unknown>>(_table: string, id: string, data: Partial<T>, options?: UpdateOptions): Promise<T>;
2169
- delete(_table: string, id: string): Promise<void>;
2196
+ update<T extends Record<string, unknown>>(table: string, id: string, data: Partial<T>, options?: UpdateOptions): Promise<T>;
2197
+ delete(table: string, id: string): Promise<void>;
2198
+ private writeCreate;
2199
+ private writeUpdate;
2200
+ private writeDelete;
2170
2201
  run<B extends BackendNames<S>, R extends BackendRoutes<S, B>>(backend: B, path: R, payload: RoutePayload<S, B, R>, options?: RunOptions): Promise<void>;
2171
2202
  get failedMutationCount(): number;
2172
2203
  subscribeToFailedMutations(cb: (count: number) => void): () => void;
@@ -2220,6 +2251,74 @@ declare class Sp00kyClient<S extends SchemaStructure> {
2220
2251
  getBlobCacheStats(): BlobCacheStats;
2221
2252
  }
2222
2253
  //#endregion
2254
+ //#region src/modules/channel/webrtc.d.ts
2255
+ /**
2256
+ * The default channel transport: one WebRTC data channel per pair of tabs,
2257
+ * set up through signaling rows in the database.
2258
+ *
2259
+ * Signaling (all rows of `_00_channel_signal`, read through one raw LIVE):
2260
+ *
2261
+ * 1. A tab that wants user U writes `hello` to U. Every tab of U hears it.
2262
+ * 2. Of each pair of tabs, the one with the lower `user#peer` key offers.
2263
+ * A tab that hears a hello from a higher key offers at once; one that
2264
+ * hears it from a lower key answers with a `hello` addressed back to that
2265
+ * tab, which then offers. So both orders of arrival connect, and nobody
2266
+ * loops.
2267
+ * 3. `offer` / `answer` carry the SDPs, `ice` batches of candidates
2268
+ * (trickled, so nothing waits for gathering to finish).
2269
+ *
2270
+ * A tab only ever reacts to signals from users it wants itself, so a
2271
+ * connection needs both sides to list each other. The database stamps every
2272
+ * row's `sender`, and the offer carries the DTLS fingerprint of the
2273
+ * connection, so the user on the other end of a data channel is proven.
2274
+ */
2275
+ type SignalKind = 'hello' | 'offer' | 'answer' | 'ice';
2276
+ interface Signal {
2277
+ readonly from: string;
2278
+ readonly fromPeer: string;
2279
+ readonly toPeer: string | null;
2280
+ readonly kind: SignalKind;
2281
+ readonly payload: string | null;
2282
+ }
2283
+ interface OutgoingSignal {
2284
+ readonly to: string;
2285
+ readonly toPeer: string | null;
2286
+ readonly fromPeer: string;
2287
+ readonly kind: SignalKind;
2288
+ readonly payload: string | null;
2289
+ }
2290
+ /** Where signals go and come from. The database by default. */
2291
+ interface SignalPort {
2292
+ send(signal: OutgoingSignal): Promise<void>;
2293
+ listen(self: PeerRef, cb: (signal: Signal) => void): () => void;
2294
+ }
2295
+ interface WebRtcOptions {
2296
+ signal: SignalPort;
2297
+ iceServers?: RTCIceServer[];
2298
+ logger?: Pick<Logger$1, 'debug' | 'warn'>;
2299
+ /** Injectable for tests and non-browser runtimes. */
2300
+ RTCPeerConnection?: typeof RTCPeerConnection;
2301
+ /** Give up on one attempt after this long. Default 15000. */
2302
+ connectTimeoutMs?: number;
2303
+ }
2304
+ declare function webrtcTransport(hooks: TransportHooks, opts: WebRtcOptions): ChannelTransport;
2305
+ /** The bits of the remote service signaling needs. */
2306
+ interface SignalRemote {
2307
+ query<T extends unknown[]>(sql: string, vars?: Record<string, unknown>): Promise<T>;
2308
+ getClient(): Pick<Surreal, 'liveOf'>;
2309
+ }
2310
+ interface SignalConnection {
2311
+ subscribe(cb: (state: ConnectionState) => void): () => void;
2312
+ }
2313
+ /**
2314
+ * Signals as rows of `_00_channel_signal` (generated for schemas with a
2315
+ * `@channel` table): a CREATE to send, one raw `LIVE SELECT` on rows
2316
+ * addressed to this user to receive. Not the outbox and not a synced query:
2317
+ * each signal costs one round trip, which is what keeps connection setup
2318
+ * short. The LIVE is re-armed whenever the socket reconnects.
2319
+ */
2320
+ declare function surrealSignal(remote: SignalRemote, connection: SignalConnection, logger?: Pick<Logger$1, 'debug' | 'warn'>): SignalPort;
2321
+ //#endregion
2223
2322
  //#region src/utils/semver.d.ts
2224
2323
  /** True when `a` is a valid version strictly greater than valid version `b`. */
2225
2324
  declare function semverGt(a: unknown, b: unknown): boolean;
@@ -2254,4 +2353,4 @@ declare class LocalOpTimeoutError extends Error {
2254
2353
  * select on a throttled tab is seconds, not tens of seconds. */
2255
2354
  declare const DEFAULT_LOCAL_OP_TIMEOUT_MS = 30000;
2256
2355
  //#endregion
2257
- export { ActiveImpersonation, AppReleaseHandle, AppReleaseModule, type AppReleaseOptions, type AppReleaseSnapshot, AuthEventSystem, AuthEventTypeMap, AuthEventTypes, AuthService, BLURHASH_IMAGE_EXTENSIONS, type BlobCacheStats, type BlobEntry, type BlobKey, type BlobReadOptions, type BlobUrlLease, type BlurhashEncodeOptions, type BlurhashSetting, type BridgeSignOutMessage, type BridgeTokenMessage, BucketHandle, BucketPutOptions, BucketPutResult, CURSOR_COLORS, ConnectionState, CrdtField, CrdtManager, DEFAULT_LOCAL_OP_TIMEOUT_MS, DebounceOptions, EdgeDelta, EventSubscriptionOptions, type FailedMutationRow as FailedMutation, FeatureFlagHandle, FeatureFlagModule, type FeatureFlagOptions, type FeatureFlagOverride, type FeatureFlagSnapshot, IMPERSONATION_ACCESS, ImpersonationCandidate, ImpersonationInfo, ImpersonationTimerHost, ImpersonationTimers, InlineRow, Level, LocalOpTimeoutError, MATERIALIZATION_SAMPLE_WINDOW, MembershipOutcome, MutationCallback, MutationEvent, MutationEventType, ORIGIN_TOKEN_KEY, PUSH_ENDPOINT_KEY, PUSH_PAYLOAD_VERSION, PersistenceClient, PhaseStat, PinoTransmit, PreloadOptions, PreloadRefresh, type PushDeviceKind, type PushNotification, type PushNotificationAction, type PushOp, type PushPayload, type PushPayloadKind, type PushUrgency, QueryAuthorityCallback, QueryConfig, QueryConfigRecord, QueryHash, QueryState, QueryStatus, QueryStatusCallback, QueryTimeToLive, QueryTimings, QueryUpdateCallback, REFUSAL_RECHECK_MIN_MS, ReconnectConfig, RecordVersionArray, RecordVersionDiff, RegistrationTimings, RunOptions, SESSION_POLL_MS, SIGN_OUT_HOOK_TIMEOUT_MS, ServerViewMeta, SignOutContext, SignOutHook, Sp00kyClient, Sp00kyClientDeps, Sp00kyConfig, Sp00kyQueryResult, Sp00kyQueryResultPromise, StorageHealth, StorageHealthStatus, StoreType, SyncHealth, SyncHealthConfig, SyncHealthStatus, TimingPhase, TokenClaims, UpdateOptions, type WebPushClientMessage, type WebPushConfig, type WebPushDevice, WebPushError, type WebPushErrorCode, type WebPushInfo, type WebPushMessage, type WebPushMessageInput, WebPushModule, type WebPushSubscribeOptions, type WebPushSupport, type WebPushSyncOptions, type WebPushSyncStatus, type WebPushUnsubscribeOptions, type WebPushUnsupportedReason, type WebPushUpdateOptions, blurhashSidecarPath, bucketContentToBlob, createAuthEventSystem, cursorColorFromName, decode as decodeBlurhash, decodeTokenClaims, detectWebPushSupport, encode as encodeBlurhash, encodeImageToBlurhash, fileToUint8Array, impersonationFromToken, isBlurhashValid, isImagePath, isPushPayload, renewDelayMs, sameImpersonation, semverGt, textToHtml };
2356
+ export { ActiveImpersonation, AppReleaseHandle, AppReleaseModule, type AppReleaseOptions, type AppReleaseSnapshot, AuthEventSystem, AuthEventTypeMap, AuthEventTypes, AuthService, BLURHASH_IMAGE_EXTENSIONS, type BlobCacheStats, type BlobEntry, type BlobKey, type BlobReadOptions, type BlobUrlLease, type BlurhashEncodeOptions, type BlurhashSetting, type BridgeSignOutMessage, type BridgeTokenMessage, BucketHandle, BucketPutOptions, BucketPutResult, CURSOR_COLORS, type ChannelAcceptRule, type ChannelHandle, type ChannelMessage, type ChannelOp, ChannelQuery, type ChannelScope, type ChannelState, type ChannelStatus, type ChannelTransport, type ChannelTransportFactory, type ChannelsConfig, ConnectionState, CrdtField, CrdtManager, DEFAULT_LOCAL_OP_TIMEOUT_MS, DebounceOptions, EdgeDelta, EventSubscriptionOptions, type FailedMutationRow as FailedMutation, FeatureFlagHandle, FeatureFlagModule, type FeatureFlagOptions, type FeatureFlagOverride, type FeatureFlagSnapshot, IMPERSONATION_ACCESS, ImpersonationCandidate, ImpersonationInfo, ImpersonationTimerHost, ImpersonationTimers, InlineRow, Level, LocalOpTimeoutError, MATERIALIZATION_SAMPLE_WINDOW, MembershipOutcome, MutationCallback, MutationEvent, MutationEventType, ORIGIN_TOKEN_KEY, type OutgoingSignal, PUSH_ENDPOINT_KEY, PUSH_PAYLOAD_VERSION, type PeerRef, PersistenceClient, PhaseStat, PinoTransmit, PreloadOptions, PreloadRefresh, type PushDeviceKind, type PushNotification, type PushNotificationAction, type PushOp, type PushPayload, type PushPayloadKind, type PushUrgency, QueryAuthorityCallback, QueryConfig, QueryConfigRecord, QueryHash, QueryState, QueryStatus, QueryStatusCallback, QueryTimeToLive, QueryTimings, QueryUpdateCallback, REFUSAL_RECHECK_MIN_MS, ReconnectConfig, RecordVersionArray, RecordVersionDiff, RegistrationTimings, RunOptions, SESSION_POLL_MS, SIGN_OUT_HOOK_TIMEOUT_MS, ServerViewMeta, SignOutContext, SignOutHook, type Signal, type SignalPort, Sp00kyChannel, Sp00kyClient, Sp00kyClientDeps, Sp00kyConfig, Sp00kyQueryResult, Sp00kyQueryResultPromise, StorageHealth, StorageHealthStatus, StoreType, SyncHealth, SyncHealthConfig, SyncHealthStatus, TimingPhase, TokenClaims, type TransportHooks, UpdateOptions, type WebPushClientMessage, type WebPushConfig, type WebPushDevice, WebPushError, type WebPushErrorCode, type WebPushInfo, type WebPushMessage, type WebPushMessageInput, WebPushModule, type WebPushSubscribeOptions, type WebPushSupport, type WebPushSyncOptions, type WebPushSyncStatus, type WebPushUnsubscribeOptions, type WebPushUnsupportedReason, type WebPushUpdateOptions, blurhashSidecarPath, bucketContentToBlob, createAuthEventSystem, cursorColorFromName, decode as decodeBlurhash, decodeTokenClaims, detectWebPushSupport, encode as encodeBlurhash, encodeImageToBlurhash, fileToUint8Array, impersonationFromToken, isBlurhashValid, isImagePath, isPushPayload, matchesWhere, renewDelayMs, sameImpersonation, semverGt, surrealSignal, textToHtml, unusedArgs, webrtcTransport };