@spooky-sync/core 0.0.1-canary.279 → 0.0.1-canary.281

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
@@ -41,6 +41,8 @@ re-materialized from state, never patched in place.
41
41
  - `CrdtManager`, `CrdtField`, `cursorColorFromName`, `CURSOR_COLORS` — Loro-CRDT integration.
42
42
  - Types: `Sp00kyConfig` (client-solid wraps it as `SyncedDbConfig`), `QueryTimeToLive`, `PersistenceClient`, `StoreType`, `UpdateOptions`, `RunOptions`, `PreloadOptions`.
43
43
  - Subpath: `@spooky-sync/core/otel` — `createOtelTransmit(endpoint)` for piping pino logs to OpenTelemetry.
44
+ - `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`.
45
+ - Subpaths for service workers, workers and Node (no wasm, no pino, no DOM; `scripts/check-worker-entries.mjs` enforces it in `build`): `@spooky-sync/core/pure` (protocol builders), `@spooky-sync/core/live` (`createLiveFeed`, the live subscriber over the pure-JS SDK), `@spooky-sync/core/sw` (`installPushHandlers`, `getBridgedToken`). Built by the second tsdown config; chunks are prefixed `worker-`. See `docs/web-push-design.md` at the repo root.
44
46
 
45
47
  ## Common gotchas
46
48
 
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { $ as ORIGIN_TOKEN_KEY, A as RunOptions, B as SyncHealthStatus, C as QueryTimeToLive, D as RecordVersionArray, E as ReconnectConfig, F as StorageHealth, G as DatabaseEventTypes, H as UpdateOptions, I as StorageHealthStatus, J as EventSystem, K as SealedQuery, L as StoreType, M as Sp00kyConfig, N as Sp00kyQueryResult, O as RecordVersionDiff, P as Sp00kyQueryResultPromise, Q as ImpersonationTimers, R as SyncHealth, S as QueryStatusCallback, T as QueryUpdateCallback, U as LocalStore, V as TimingPhase, W as DatabaseEventSystem, X as ImpersonationInfo, Y as IMPERSONATION_ACCESS, Z as ImpersonationTimerHost, _ as QueryConfig, a as Level, at as sameImpersonation, b as QueryState, c as MutationCallback, d as PersistenceClient, et as SESSION_POLL_MS, f as PhaseStat, g as QueryAuthorityCallback, h as PreloadRefresh, i as InlineRow, it as renewDelayMs, j as ServerViewMeta, k as RegistrationTimings, l as MutationEvent, m as PreloadOptions, n as DebounceOptions, nt as decodeTokenClaims, o as MATERIALIZATION_SAMPLE_WINDOW, p as PinoTransmit, q as EventDefinition, r as EventSubscriptionOptions, rt as impersonationFromToken, s as MembershipOutcome, t as ConnectionState, tt as TokenClaims, u as MutationEventType, v as QueryConfigRecord, w as QueryTimings, x as QueryStatus, y as QueryHash, z as SyncHealthConfig } from "./types.js";
2
- import { AccessDefinition, BackendNames, BackendRoutes, BucketNames, ColumnSchema, FinalQuery, GetTable, QueryBuilder, QueryOptions, QueryPlan, RecordId, RoutePayload, SchemaStructure, TableModel, TableNames, TypeNameToTypeMap } from "@spooky-sync/query-builder";
1
+ import { $ as WebPushSupport, A as RunOptions, At as SealedQuery, B as SyncHealthStatus, Bt as decodeTokenClaims, C as QueryTimeToLive, Ct as AuthEventSystem, D as RecordVersionArray, Dt as RemoteDatabaseService, E as ReconnectConfig, Et as createAuthEventSystem, F as StorageHealth, Ft as ImpersonationTimerHost, G as WebPushDevice, H as UpdateOptions, Ht as renewDelayMs, I as StorageHealthStatus, It as ImpersonationTimers, J as WebPushInfo, K as WebPushError, L as StoreType, Lt as ORIGIN_TOKEN_KEY, M as Sp00kyConfig, Mt as EventSystem, N as Sp00kyQueryResult, Nt as IMPERSONATION_ACCESS, O as RecordVersionDiff, Ot as Logger$1, P as Sp00kyQueryResultPromise, Pt as ImpersonationInfo, Q as WebPushSubscribeOptions, R as SyncHealth, Rt as SESSION_POLL_MS, S as QueryStatusCallback, St as SignOutHook, T as QueryUpdateCallback, Tt as AuthEventTypes, U as PUSH_ENDPOINT_KEY, Ut as sameImpersonation, V as TimingPhase, Vt as impersonationFromToken, W as WebPushConfig, X as WebPushMessageInput, Y as WebPushMessage, Z as WebPushModule, _ as QueryConfig, _t as ActiveImpersonation, a as Level, at as detectWebPushSupport, b as QueryState, bt as SIGN_OUT_HOOK_TIMEOUT_MS, c as MutationCallback, ct as PUSH_PAYLOAD_VERSION, d as PersistenceClient, dt as PushOp, et as WebPushSyncOptions, f as PhaseStat, ft as PushPayload, g as QueryAuthorityCallback, gt as isPushPayload, h as PreloadRefresh, ht as WebPushClientMessage, i as InlineRow, it as WebPushUpdateOptions, j as ServerViewMeta, jt as EventDefinition, k as RegistrationTimings, kt as LocalStore, l as MutationEvent, lt as PushNotification, m as PreloadOptions, mt as PushUrgency, n as DebounceOptions, nt as WebPushUnsubscribeOptions, o as MATERIALIZATION_SAMPLE_WINDOW, ot as BridgeSignOutMessage, p as PinoTransmit, pt as PushPayloadKind, q as WebPushErrorCode, r as EventSubscriptionOptions, rt as WebPushUnsupportedReason, s as MembershipOutcome, st as BridgeTokenMessage, t as ConnectionState, tt as WebPushSyncStatus, u as MutationEventType, ut as PushNotificationAction, v as QueryConfigRecord, vt as AuthService, w as QueryTimings, wt as AuthEventTypeMap, x as QueryStatus, xt as SignOutContext, y as QueryHash, yt as ImpersonationCandidate, z as SyncHealthConfig, zt as TokenClaims } from "./types.js";
2
+ import { BackendNames, BackendRoutes, BucketNames, FinalQuery, GetTable, QueryBuilder, QueryOptions, QueryPlan, RecordId, RoutePayload, SchemaStructure, TableModel, TableNames } from "@spooky-sync/query-builder";
3
3
  import * as surrealdb0 from "surrealdb";
4
- import { Duration, RecordId as RecordId$1, Surreal, SurrealEvents, SurrealTransaction } from "surrealdb";
5
- import { Level as Level$1, Logger } from "pino";
4
+ import { Duration, RecordId as RecordId$1, Surreal } from "surrealdb";
5
+ import { Logger } from "pino";
6
6
  import { decode, encode, isBlurhashValid } from "blurhash";
7
7
  import { LoroDoc } from "loro-crdt";
8
8
 
@@ -87,188 +87,6 @@ type LeaderToFollowerMessage = {
87
87
  count: number;
88
88
  };
89
89
  //#endregion
90
- //#region src/services/logger/index.d.ts
91
- type Logger$1 = Logger;
92
- //#endregion
93
- //#region src/services/database/database.d.ts
94
- declare abstract class AbstractDatabaseService {
95
- protected client: Surreal;
96
- protected logger: Logger$1;
97
- protected events: DatabaseEventSystem;
98
- /**
99
- * Per-query deadline in ms; `0` disables. The remote service sets it from
100
- * `queryTimeoutMs` (see `RemoteDatabaseService`), the local one from
101
- * `localOpTimeoutMs` (see `LocalDatabaseService`): a local query can be
102
- * legitimately slow, but it must never be endless - every query waits on the
103
- * previous link of {@link query}'s chain, and one that never settled wedged
104
- * every later local op behind it.
105
- */
106
- protected queryTimeoutMs: number;
107
- /** The error a deadline expiry rejects with; the local service substitutes
108
- * its typed `LocalOpTimeoutError`. "timed out" in the message is
109
- * load-bearing either way: `classifySyncError` keys off it. */
110
- protected timeoutError(_query: string): Error;
111
- protected abstract eventType: typeof DatabaseEventTypes.LocalQuery | typeof DatabaseEventTypes.RemoteQuery;
112
- constructor(client: Surreal, logger: Logger$1, events: DatabaseEventSystem);
113
- abstract connect(): Promise<void>;
114
- getClient(): Surreal;
115
- getEvents(): DatabaseEventSystem;
116
- tx(): Promise<SurrealTransaction>;
117
- /**
118
- * How many statements may be in flight at once.
119
- *
120
- * `1` serializes every statement behind the previous one. The local engines
121
- * need that: overlapping ops trip the WASM / SQLite transaction layer. The
122
- * remote service raises it (`RemoteDatabaseService`): a SurrealDB socket
123
- * multiplexes requests by id, and serializing them capped the client at one
124
- * statement per round trip (~5/s at 170ms RTT), so the `_00_list_ref` poll
125
- * alone could hold every registration behind it and one slow one-shot read
126
- * stalled the whole client. The scheduler's `MAX_CONCURRENT_DOWN` only means
127
- * something when this is above 1.
128
- */
129
- protected maxConcurrentQueries: number;
130
- private inFlightQueries;
131
- private queryWaiters;
132
- /** FIFO slot acquisition, so `maxConcurrentQueries = 1` keeps strict order. */
133
- private acquireQuerySlot;
134
- private releaseQuerySlot;
135
- /**
136
- * Hook run right before a statement is sent, inside its slot. The remote
137
- * service uses it to hold statements while a connect is in flight, so a
138
- * query never runs on a socket that is open but has not had its namespace
139
- * and token applied yet. The default does nothing.
140
- */
141
- protected beforeQuery(): Promise<void>;
142
- /**
143
- * Execute a statement under {@link maxConcurrentQueries}.
144
- *
145
- * A statement that never settles would hold its slot forever, and with a
146
- * limit of 1 that blocks every later statement behind it. {@link
147
- * queryTimeoutMs} bounds each one: on expiry this promise rejects and the
148
- * slot is released, even though the underlying RPC is still parked in the
149
- * SDK's pending map.
150
- */
151
- query<T extends unknown[]>(query: string, vars?: Record<string, unknown>): Promise<T>;
152
- /**
153
- * Like {@link query} but never rejects on a statement error: every
154
- * statement answers on its own as `{ status: 'OK', result }` or
155
- * `{ status: 'ERR', error }`. This is what lets a batched outbox push judge
156
- * each mutation separately.
157
- */
158
- queryResponses(query: string, vars?: Record<string, unknown>): Promise<Array<{
159
- status: 'OK';
160
- result: unknown;
161
- } | {
162
- status: 'ERR';
163
- error: string;
164
- }>>;
165
- private runStatement;
166
- execute<T>(query: SealedQuery<T>, vars?: Record<string, unknown>): Promise<T>;
167
- close(): Promise<void>;
168
- }
169
- //#endregion
170
- //#region src/services/database/remote.d.ts
171
- /** Transport events the SDK publishes, mapped 1:1 to {@link ConnectionState}. */
172
- type RemoteConnectionEvent = ConnectionState | 'error';
173
- declare class RemoteDatabaseService extends AbstractDatabaseService {
174
- private config;
175
- protected eventType: "DATABASE_REMOTE_QUERY";
176
- private readonly reconnectConfig;
177
- /**
178
- * In-flight `connect()`, so concurrent callers (boot + supervisor revive +
179
- * an `online` event landing at the same moment) share one attempt instead of
180
- * racing two sockets. Cleared on settle, so a later call always reconnects.
181
- */
182
- private connecting;
183
- /**
184
- * The token to re-authenticate a freshly opened socket with, kept current by
185
- * {@link setAuthToken}.
186
- *
187
- * `config.token` is fixed at construction and most apps never set it: they
188
- * sign in later, which authenticates the socket that happens to be open at
189
- * the time. That is enough for the SDK's OWN reconnects (it replays
190
- * `version`/`use`/`authenticate` itself), but not for the supervisor's revive
191
- * loop, which builds a socket from scratch. Without this the revived socket
192
- * came back UNAUTHENTICATED and stayed that way for the life of the page,
193
- * while the client's `currentUserId` — restored from local storage — kept
194
- * reporting the user as signed in.
195
- *
196
- * The visible damage is silent and total: `fn::query::register` sends
197
- * `<string>($auth.id OR '')`, so every view registered afterwards is stamped
198
- * with an empty identity, and every `$auth.id` predicate in it resolves
199
- * false. Public tables keep returning rows while everything owned by the user
200
- * returns nothing, on a page that still looks signed in.
201
- */
202
- private authToken;
203
- constructor(config: Sp00kyConfig<any>['database'], logger: Logger$1);
204
- getConfig(): Sp00kyConfig<any>['database'];
205
- /**
206
- * Send one SurrealQL statement so that it survives the page going away.
207
- *
208
- * A WebSocket `send()` during `pagehide` is not guaranteed to flush — the
209
- * browser may tear the socket down first, and the frame is simply lost.
210
- * Measured: an unload-time release over the live socket reached the server
211
- * zero times out of one. `fetch` with `keepalive` is the primitive the
212
- * platform actually guarantees here, so this goes over SurrealDB's HTTP
213
- * `/sql` endpoint instead of the RPC socket.
214
- *
215
- * Best-effort by design: no await, no retry, errors swallowed. Every caller
216
- * must have a server-side fallback that makes a lost beacon a non-event.
217
- */
218
- beaconSql(sql: string): void;
219
- /**
220
- * Record the token every future connect should authenticate with, or `null`
221
- * on sign-out. See {@link authToken}.
222
- *
223
- * Does not touch the CURRENT socket: callers authenticate that themselves
224
- * (sign-in and session restore both already do). This only makes the next
225
- * from-scratch connect reproduce that state.
226
- */
227
- setAuthToken(token: string | null): void;
228
- /** Resolved reconnect tunables; the supervisor reads its own knobs here. */
229
- getReconnectConfig(): Required<ReconnectConfig>;
230
- /** Current transport state as reported by the SDK. */
231
- getStatus(): ConnectionState;
232
- /**
233
- * Observe transport events. Thin passthrough so callers (the supervisor,
234
- * sync, CRDT) don't have to reach through `getClient()`.
235
- */
236
- subscribeConnection<K extends RemoteConnectionEvent>(event: K, cb: (...payload: SurrealEvents[K]) => void): () => void;
237
- /**
238
- * Tear the socket down on purpose. Used by the heartbeat watchdog when a
239
- * socket stops answering but never closes: `close()` makes the SDK publish
240
- * `disconnected`, which is what drives the supervisor's revive loop.
241
- */
242
- forceClose(): Promise<void>;
243
- /**
244
- * Hold statements while a connect is in flight.
245
- *
246
- * `connect()` opens the socket, then selects the namespace/database, then
247
- * authenticates - three round trips. The SDK considers the connection ready
248
- * after the first, so a query queued during the other two ran on a socket
249
- * with no namespace ("Specify a namespace to use") or, worse, no identity.
250
- * Seen 2026-09-06 after the supervisor rebuilt a socket: a collection
251
- * recount failed with exactly that error. Waiting on the in-flight connect
252
- * costs nothing when no connect is running; a failed connect is not
253
- * swallowed here - the query then fails on its own, as before.
254
- */
255
- protected beforeQuery(): Promise<void>;
256
- /**
257
- * Open (or re-open) the remote connection.
258
- *
259
- * Safe to call repeatedly: concurrent calls share the in-flight attempt, and
260
- * a call after a `disconnected` builds a fresh socket. `use()` and
261
- * `authenticate()` are re-applied here for the cold path; the SDK also
262
- * replays them itself on its own internal reconnects.
263
- */
264
- connect(): Promise<void>;
265
- private doConnect;
266
- signin(params: any): Promise<any>;
267
- signup(params: any): Promise<any>;
268
- authenticate(token: string): Promise<any>;
269
- invalidate(): Promise<void>;
270
- }
271
- //#endregion
272
90
  //#region src/services/database/connection-supervisor.d.ts
273
91
  /**
274
92
  * Keeps the remote WebSocket alive for the whole life of the page.
@@ -674,148 +492,6 @@ declare class StreamProcessorService {
674
492
  private normalizeValue;
675
493
  }
676
494
  //#endregion
677
- //#region src/modules/auth/events/index.d.ts
678
- declare const AuthEventTypes: {
679
- readonly AuthStateChanged: "AUTH_STATE_CHANGED";
680
- readonly ImpersonationChanged: "IMPERSONATION_CHANGED";
681
- };
682
- type AuthEventTypeMap = {
683
- [AuthEventTypes.AuthStateChanged]: EventDefinition<typeof AuthEventTypes.AuthStateChanged, string | null>;
684
- [AuthEventTypes.ImpersonationChanged]: EventDefinition<typeof AuthEventTypes.ImpersonationChanged, ImpersonationInfo | null>;
685
- };
686
- type AuthEventSystem = EventSystem<AuthEventTypeMap>;
687
- declare function createAuthEventSystem(): AuthEventSystem;
688
- //#endregion
689
- //#region src/modules/auth/index.d.ts
690
- /** What `fn::_00_impersonate::list_users` returns per row. */
691
- interface ImpersonationCandidate {
692
- id: string;
693
- is_admin: boolean;
694
- [field: string]: unknown;
695
- }
696
- /** An open session, as `fn::_00_impersonate::active` lists it. */
697
- interface ActiveImpersonation {
698
- session: string;
699
- target: string;
700
- admin: string;
701
- reason: string;
702
- started_at: unknown;
703
- expires_at: unknown;
704
- }
705
- type Prettify<T> = { [K in keyof T]: T[K] } & {};
706
- type MapColumnType<T extends ColumnSchema> = T['optional'] extends true ? TypeNameToTypeMap[T['type']] | undefined : TypeNameToTypeMap[T['type']];
707
- type ExtractAccessParams<S extends SchemaStructure, Name extends keyof S['access'], Method extends 'signIn' | 'signup'> = S['access'] extends undefined ? never : S['access'][Name] extends AccessDefinition ? Prettify<{ [K in keyof S['access'][Name][Method]['params']]: MapColumnType<S['access'][Name][Method]['params'][K]> }> : never;
708
- declare class AuthService<S extends SchemaStructure> {
709
- private schema;
710
- private remote;
711
- private persistenceClient;
712
- private logger;
713
- token: string | null;
714
- currentUser: any | null;
715
- isAuthenticated: boolean;
716
- /**
717
- * The record-access method name for the current session (e.g. `"account"`),
718
- * derived from the token's `AC` claim. Consumed by the in-browser SSP's
719
- * permission injection so `$access`-gated table predicates resolve locally,
720
- * mirroring the server's `$access`. Null when logged out.
721
- */
722
- access: string | null;
723
- isLoading: boolean;
724
- private events;
725
- /** The impersonation last announced, for change detection. */
726
- private announcedImpersonation;
727
- /** Target of an impersonation that just ended, until the client purges its
728
- * local bucket (see `consumeEndedImpersonation`). */
729
- private endedImpersonationTarget;
730
- private impersonationTimers;
731
- get eventSystem(): AuthEventSystem;
732
- constructor(schema: S, remote: RemoteDatabaseService, persistenceClient: PersistenceClient, logger: Logger$1);
733
- init(): Promise<void>;
734
- getAccessDefinition<Name extends keyof S['access']>(name: Name): AccessDefinition | undefined;
735
- /**
736
- * Subscribe to auth state changes.
737
- * callback is called immediately with current value and whenever validation status changes.
738
- */
739
- subscribe(cb: (userId: string | null) => void): () => void;
740
- private notifyListeners;
741
- /**
742
- * The impersonation the current session is, or null. Derived from the
743
- * token in use, so it always describes the identity the server sees.
744
- */
745
- get impersonation(): ImpersonationInfo | null;
746
- /** Subscribe to impersonation changes; called immediately with the current value. */
747
- subscribeImpersonation(cb: (info: ImpersonationInfo | null) => void): () => void;
748
- /**
749
- * Act as `targetId` (a record id such as `user:abc`). Admins only, and only
750
- * when the project enabled `impersonation` in sp00ky.yml: the server refuses
751
- * everything else. `reason` is recorded in the audit log.
752
- *
753
- * The admin's session is kept aside and restored by
754
- * {@link stopImpersonating}. Local data switches to the target's bucket
755
- * exactly as on a sign-in, and that bucket is removed on stop.
756
- */
757
- impersonate(targetId: string, reason: string): Promise<ImpersonationInfo>;
758
- /**
759
- * Return to the admin session. Always leaves the impersonated identity,
760
- * even when the server cannot be reached: the admin token is restored
761
- * locally first and verified afterwards, and a rejected admin token ends in
762
- * a full sign-out rather than staying on the target.
763
- */
764
- stopImpersonating(opts?: {
765
- serverEnded?: boolean;
766
- }): Promise<void>;
767
- /** Re-sign the impersonation token before it expires. */
768
- renewImpersonation(): Promise<void>;
769
- /** Users an admin may pick from. Admin-only on the server. */
770
- searchImpersonationTargets(search: string): Promise<ImpersonationCandidate[]>;
771
- /** Open impersonation sessions. Admin-only on the server. */
772
- listActiveImpersonations(): Promise<ActiveImpersonation[]>;
773
- /**
774
- * The target of an impersonation that ended, once. The bucket switch calls
775
- * this after leaving a bucket so it can delete that user's local data.
776
- */
777
- consumeEndedImpersonation(): string | null;
778
- /**
779
- * Restore a session from the locally cached JWT, with NO network.
780
- *
781
- * This is what makes a warm boot paint instantly and what makes an offline
782
- * boot possible at all: the token is in local storage, and it already carries
783
- * both the access method and the `$auth.id` record id. Everything the client
784
- * needs to route queries (`setCurrentUserId`) and to satisfy `$auth`-gated
785
- * permission predicates in the in-browser SSP (`setSessionAuth`) is therefore
786
- * available before a socket exists.
787
- *
788
- * The session is OPTIMISTIC: the token is unverified here. `check()` runs
789
- * afterwards in the background and downgrades to a real sign-out if the
790
- * server rejects it. Nothing is trusted that the server has not also seen -
791
- * the local store only ever holds rows the server previously sent.
792
- *
793
- * Returns the restored user id, or null when there is no usable token.
794
- */
795
- restoreSessionFromToken(): Promise<string | null>;
796
- /**
797
- * Check for existing session and validate
798
- */
799
- check(accessToken?: string): Promise<void>;
800
- /**
801
- * The server refused `token`. A refused impersonation token (stopped,
802
- * expired, or revoked) returns to the admin session instead of signing the
803
- * admin out; anything else signs out.
804
- */
805
- private rejectToken;
806
- /**
807
- * Sign out and clear session. While impersonating this ends the
808
- * impersonation and signs the admin out too.
809
- */
810
- signOut(): Promise<void>;
811
- private setSession;
812
- /** Fallback when the token carries no `AC` claim: if the schema defines
813
- * exactly one record-access method, assume the session used it. */
814
- private defaultAccessName;
815
- signUp<Name extends keyof S['access'] & string>(accessName: Name, params: ExtractAccessParams<S, Name, 'signup'>): Promise<void>;
816
- signIn<Name extends keyof S['access'] & string>(accessName: Name, params: ExtractAccessParams<S, Name, 'signIn'>): Promise<void>;
817
- }
818
- //#endregion
819
495
  //#region src/modules/crdt/crdt-field.d.ts
820
496
  declare const CURSOR_COLORS: string[];
821
497
  declare function cursorColorFromName(name: string): string;
@@ -2314,6 +1990,8 @@ declare class Sp00kyClient<S extends SchemaStructure> {
2314
1990
  private readonly config;
2315
1991
  readonly auth: AuthService<S>;
2316
1992
  readonly streamProcessor: StreamProcessorService;
1993
+ /** Web Push for this browser: subscribe, devices, self-pushes, service worker bridge. */
1994
+ readonly webPush: WebPushModule;
2317
1995
  private readonly services;
2318
1996
  private readonly env;
2319
1997
  private readonly runtime;
@@ -2457,4 +2135,4 @@ declare function textToHtml(text: string): string;
2457
2135
  */
2458
2136
 
2459
2137
  //#endregion
2460
- 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, BucketHandle, BucketPutOptions, BucketPutResult, CURSOR_COLORS, ConnectionState, CrdtField, CrdtManager, DEFAULT_LOCAL_OP_TIMEOUT_MS, DebounceOptions, 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, PersistenceClient, PhaseStat, PinoTransmit, PreloadOptions, PreloadRefresh, QueryAuthorityCallback, QueryConfig, QueryConfigRecord, QueryHash, QueryState, QueryStatus, QueryStatusCallback, QueryTimeToLive, QueryTimings, QueryUpdateCallback, ReconnectConfig, RecordVersionArray, RecordVersionDiff, RegistrationTimings, RunOptions, SESSION_POLL_MS, ServerViewMeta, Sp00kyClient, Sp00kyClientDeps, Sp00kyConfig, Sp00kyQueryResult, Sp00kyQueryResultPromise, StorageHealth, StorageHealthStatus, StoreType, SyncHealth, SyncHealthConfig, SyncHealthStatus, TimingPhase, TokenClaims, UpdateOptions, blurhashSidecarPath, bucketContentToBlob, createAuthEventSystem, cursorColorFromName, decode as decodeBlurhash, decodeTokenClaims, encode as encodeBlurhash, encodeImageToBlurhash, fileToUint8Array, impersonationFromToken, isBlurhashValid, isImagePath, renewDelayMs, sameImpersonation, semverGt, textToHtml };
2138
+ 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, 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 PushNotification, type PushNotificationAction, type PushOp, type PushPayload, type PushPayloadKind, type PushUrgency, QueryAuthorityCallback, QueryConfig, QueryConfigRecord, QueryHash, QueryState, QueryStatus, QueryStatusCallback, QueryTimeToLive, QueryTimings, QueryUpdateCallback, 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 };