Framework Wrapper Guide
Build framework integrations on top of createSkyStateClient() from @skystate/core.
Core Shape
Create one client per (apiUrl, account, project, environment) scope and expose it through your framework's provider/context mechanism.
ts
import { createSkyStateClient } from '@skystate/core';
const client = createSkyStateClient({
apiUrl,
account,
project,
environment,
});
await client.init();Do not recreate the client on every render. If connection parameters change, unmount and create a new client.
State Updates
Wrappers should create one framework-facing store from the core client and update that store when SkyState status or values change. The snapshot contains:
publicStatefor anonymous public-state loading status and data.authforunauthenticated,authenticating, andauthenticatedstates.userStatefor authenticated user state.misusefor the permanent async-misuse pin (AsyncMisuseError | null).
Expose two orthogonal facets rather than per-subsystem status: an auth facet built from snapshot.auth, and one unified operational-health signal derived from the state facets. isHealthError(error) decides what belongs on health; auth errors belong on the auth facet instead, and a non-null snapshot.misuse should pin health to error for the client's lifetime.
For keyed user reads and writes, expose clear(key) and syncStatus(key) alongside get/set: clear is the only removal path (set rejects undefined at the type level), and syncStatus reports whether the key's stored value is 'unset', 'syncing', or 'synced'.
SkyStateError is a discriminated union. Narrow on error.code before reading variant fields such as httpStatus, path (the failing user-state key on keyed writes), or retryAfter. Keep the wrapper focused on values and status; leave inspection and history workflows to the console, CLI, or REST API.
Auth Actions
Browser wrappers own the hosted login redirect. After the hosted flow exchanges a code for tokens, call:
ts
client.setAuthTokens({ idToken, refreshToken });Expose two separate actions:
logout()should callawait client.logout()so the refresh-token family is revoked server-side.clearAuthTokens()should be local-only and should callclient.clearAuthTokens().