Rayfin

@microsoft/rayfin-client

RayfinClient construction, configuration options, and the client.data, client.auth, and client.functions facades, with exact signatures from the SDK.

@microsoft/rayfin-client is the main SDK entrypoint. It composes @microsoft/rayfin-auth, @microsoft/rayfin-data, and @microsoft/rayfin-functions behind a single configured client, built on the HTTP plumbing in @microsoft/rayfin-lib.

Installation

npm install @microsoft/rayfin-client

RayfinClient

Use RayfinClient in browser and frontend code — it includes the full auth facade.

class RayfinClient<
  TSchema extends EntitySchema = Record<string, any>,
  TFunctionsSchema extends FunctionsSchema = FunctionsSchema,
> {
  readonly data: TypedDataClients<TSchema>;
  readonly auth: Auth;
  readonly functions: TypedFunctionClients<TFunctionsSchema>;
  constructor(config: RayfinClientConfig);
}

The first type parameter maps entity names to their classes, so client.data.<Entity> is fully typed. Pass your AppSchema (built from rayfin/data/schema.ts) and, if you use @microsoft/rayfin-functions, your FunctionsSchema.

src/services/rayfinClient.ts
import { RayfinClient } from '@microsoft/rayfin-client';
import type { AppSchema } from '../../rayfin/data/schema';

const client = new RayfinClient<AppSchema>({
  baseUrl: 'https://<your-app>-app.rayfin.windows.net/',
  publishableKey: 'pk-commonSampleAppKey',
});

const todos = await client.data.Todo.select(['id', 'title']).execute();

RayfinClientConfig

interface RayfinClientConfig extends ApiClientConfig {
  authStorage?: AuthStorage | boolean;
  persistSession?: boolean;
  autoRefreshToken?: boolean;
  multiTabSync?: boolean;
  runtimeConfig?: RayfinRuntimeConfig;
}

interface ApiClientConfig {
  baseUrl: string;
  publishableKey: string;
  functionsBaseUrl?: string;
  headers?: Record<string, string>;
  moniker?: string;
  timeout?: number;
  fetch?: typeof globalThis.fetch;
  getAccessToken?: () => string | null;
  useProxy?: boolean;
  onAuthExhausted?: () => void;
  onRefreshNeeded?: () => Promise<void>;
}
OptionTypeDefaultDescription
baseUrlstring—Required. Absolute deployed backend URL, or '' when a same-origin dev proxy forwards requests.
publishableKeystring—Required. The project's public pk-* key. Safe for client-side code.
authStorageAuthStorage | booleantrue (browser)true uses localStorage; false disables persistence; or pass a custom storage implementation.
persistSessionbooleantrueWhen false, auth uses an in-memory session only.
autoRefreshTokenbooleantrueWhen false, the client does not schedule session expiration timers or refresh automatically after a 401.
multiTabSyncbooleanauto-detectedControls the browser StorageEvent listener for session changes in other tabs.
runtimeConfigRayfinRuntimeConfignoneValues exposed as client.runtimeConfig, typically from resolveRayfinConfig() or VITE_FABRIC_* defaults.
functionsBaseUrlstringnoneRoutes client.functions.<name>.invoke() to ${functionsBaseUrl}/api/<name> for local Functions calls while data continues to use baseUrl.
headersRecord<string, string>noneExtra headers sent with every request.
monikerstringinferred from URLExplicit x-ms-workload-resource-moniker, usually the Fabric item ID.
timeoutnumber30000Default request timeout in milliseconds.
fetchtypeof globalThis.fetchglobal fetchCustom fetch implementation, for example one configured with a network proxy. New in 1.36
getAccessToken() => string | nullwired up by AuthOverrides how the client obtains an access token for the Authorization header.
useProxybooleanno effectDeprecated. Set baseUrl: '' and configure a dev-server proxy instead.
onAuthExhausted() => voidwired up by AuthCalled when a retry after token refresh still returns 401.
onRefreshNeeded() => Promise<void>wired up by AuthCalled before a request is retried after a refreshable 401.

getAccessToken and onRefreshNeeded are normally wired up automatically when RayfinClient constructs its internal Auth instance — most applications never set them directly.

Runtime configuration

resolveRayfinConfig(defaults, options?) loads /rayfin.config.json in a browser, overlays it on caller-supplied defaults, and returns { baseUrl, publishableKey, runtimeConfig }. Deployed static apps use that runtime file so the same built bundle can move between environments; rayfin dev falls back to generated VITE_* values when the file is absent.

import { RayfinClient, resolveRayfinConfig } from '@microsoft/rayfin-client';

const resolved = await resolveRayfinConfig({
  apiUrl: import.meta.env.VITE_RAYFIN_API_URL,
  publishableKey: import.meta.env.VITE_RAYFIN_PUBLISHABLE_KEY,
  workspaceId: import.meta.env.VITE_FABRIC_WORKSPACE_ID,
  itemId: import.meta.env.VITE_FABRIC_ITEM_ID,
  portalUrl: import.meta.env.VITE_FABRIC_PORTAL_URL,
});

const client = new RayfinClient({ ...resolved, authStorage: true });

loadRayfinConfig() is an internal helper behind resolveRayfinConfig(). It returns null only when the config is genuinely absent; malformed or unreachable config throws RayfinConfigError with codes such as CONFIG_LOAD_FAILED, CONFIG_PARSE_FAILED, CONFIG_INVALID, or CONFIG_INCOMPLETE.

RayfinServerClient

Use RayfinServerClient in Node.js and worker code. It skips the browser-coupled Auth module entirely; you supply the access token yourself.

class RayfinServerClient<TSchema extends EntitySchema = Record<string, any>> {
  readonly data: TypedDataClients<TSchema>;
  constructor(config: RayfinServerClientConfig);
}

interface RayfinServerClientConfig extends Omit<ApiClientConfig, 'getAccessToken'> {
  accessToken?: string | (() => string | null);
  runtimeConfig?: RayfinRuntimeConfig;
}
import { RayfinServerClient } from '@microsoft/rayfin-client';
import type { AppSchema } from '../rayfin/data/schema';

const client = new RayfinServerClient<AppSchema>({
  baseUrl: process.env.RAYFIN_BASE_URL!,
  publishableKey: process.env.RAYFIN_PUBLISHABLE_KEY!,
  accessToken: () => incomingRequest.headers.authorization,
});

const todos = await client.data.Todo.select(['id', 'title']).execute();

accessToken accepts either a static string or a function, so a server can rotate the token it forwards per request (for example, from an incoming request's Authorization header).

The data facade

Both client classes expose .data, typed as TypedDataClients<TSchema> — one GraphQLEntityClient per entry in TSchema, giving you client.data.<Entity>.select(), .where(), .create(), .update(), .delete(), and more. See @microsoft/rayfin-data for the full query and mutation API.

The auth facade

RayfinClient.auth is a full Auth instance from @microsoft/rayfin-auth — signOut, onSessionChange, getSession, and the rest of the session lifecycle. Sign-in itself goes through @microsoft/rayfin-auth-provider-fabric, which operates on this same Auth instance. See @microsoft/rayfin-auth for the complete surface. RayfinServerClient has no auth property, since server code authenticates via the accessToken config option instead of a browser session.

The functions facade

RayfinClient.functions is typed as TypedFunctionClients<TFunctionsSchema> — one FunctionClient per entry in your FunctionsSchema, each with a typed invoke(). See @microsoft/rayfin-functions.

The connectors facade

ConnectorsRayfinClient is exported from the stable package root in 1.36. The @microsoft/rayfin-client/experimental subpath still re-exports it for existing apps, but new code should import from @microsoft/rayfin-client. Changed in 1.36

import { ConnectorsRayfinClient } from '@microsoft/rayfin-client';

The root package also re-exports connector types such as ConnectorConfig, ConnectorMarker, ConnectorsSchema, OperationCatalog, OperationDef, TypedConnectorsApi, and TypedConnectorClient.

Errors

Both client classes expose a static errors map, and instances throw these types instead of raw Error:

class RayfinClientBase {
  static readonly errors: {
    SdkError: typeof SdkError;
    AuthError: typeof AuthError;
    NetworkError: typeof NetworkError;
  };
}

SdkError and NetworkError in this map are re-exported directly from @microsoft/rayfin-lib. AuthError is not — @microsoft/rayfin-client declares its own AuthError extends SdkError, distinct from (though structurally identical to) @microsoft/rayfin-lib's own AuthError class. Import whichever one matches where the error actually originated; instanceof checks against the wrong package's AuthError will not match. Catch by branching on failure type:

import { RayfinClient } from '@microsoft/rayfin-client';

try {
  await client.auth.refreshSession();
} catch (error) {
  if (error instanceof RayfinClient.errors.AuthError) {
    console.error('Auth failed:', error.message);
  } else if (error instanceof RayfinClient.errors.NetworkError) {
    console.error('Network issue:', error.message);
  }
}

Note

Newer releases of @microsoft/rayfin-client add setDeprecationsSilenced() and isDeprecationSilenced() for quieting deprecation warnings in application code. See Deprecation warnings for usage and the version this applies to.

Something wrong on this page?Report an issueEdit this page

On this page