Skip to content

Core Client

@skystate/core exports createSkyStateClient(), the framework-agnostic client factory used by direct JavaScript integrations and wrapper SDKs.

Basic Example

ts
import { createSkyStateClient } from '@skystate/core';

const client = createSkyStateClient({
  account: 'acc_example',
  project: 'my-project',
  environment: 'production',
});

await client.init();

account, project, and environment are required. apiUrl defaults to https://api.skystate.io; fetch and storage can be supplied for tests, non-browser runtimes, or custom token persistence.

Common Workflows

Read public state

Public state is available without end-user auth. Use it for application config, feature flags, settings, and catalog or inventory values:

ts
const banner = client.publicState.get('banner', { enabled: false });

Keys are top-level names such as banner, flags, or theme. They are not nested paths.

Attach hosted-auth tokens

The core client does not open login windows. Pass tokens from the hosted auth flow into the client:

ts
client.setAuthTokens({ idToken, refreshToken });

Use client.clearAuthTokens() for local-only session cleanup. Use await client.logout() when the user signs out.

Read and write user state

User state is available after an end user signs in:

ts
const theme = client.userState.get('theme', 'dark');
client.userState.set('theme', 'light');

Writes update local subscribers immediately and are persisted by the SDK. Temporary network, sign-in renewal, concurrent update, validation, and permission issues are reported through the client status and wrapper callbacks.

For signatures, parameters, return values, and draft handle members, see the @skystate/core user-state reference.

Stage edits with drafts

Drafts are useful for edit-then-save screens:

ts
const profile = client.userState.draft('profile', { displayName: '' });

profile.set((current) => ({ ...current, displayName: 'Ada' }));
profile.push();

Use profile.discard() to drop local form edits before saving.

Failure handling

Every request (public-state loads, user-state reads and writes, and auth token refresh) runs under a hard ten-second deadline. A request that stalls past it is aborted and treated as a retryable network failure.

Failures are retried first: network failures, 5xx responses, rate limits, and quota pauses keep the write queued and retry with capped backoff (a 429 honors the server's Retry-After). Only a legible server verdict ends differently. A patch_* validation rejection drops that one write and continues the queue; an authentication rejection halts the queue and preserves it, so a later sign-in by the same user resumes it; a write the server committed but could not confirm is kept, never resent or rolled back, and surfaced as a protocol error. Auth failures surface on the auth snapshot, operational failures share one set of health codes (isHealthError(error) narrows to them), and write rejections surface on the user-state snapshot with the failing key in error.path.

Observe client status

Advanced integrations can subscribe to client status changes and read the latest snapshot:

ts
const unsubscribe = client.subscribe(() => {
  const snapshot = client.getSnapshot();
  console.log(snapshot.publicState.status, snapshot.auth.status, snapshot.userState.status);
});

When snapshot.auth.status is 'authenticated', the snapshot also carries the signed-in user's name and email (each string | null).

SDK accessors return application values and subsystem status. Use the console, CLI, or REST API when you need inspection or audit metadata.