@microsoft/rayfin-functions
FunctionClient, the FunctionsSchema type, and client.functions.<name>.invoke() for calling serverless functions from the Rayfin SDK.
@microsoft/rayfin-functions provides the typed client behind client.functions.<name>.invoke()
on RayfinClient. It depends only on
@microsoft/rayfin-lib.
Warning
This package is marked experimental by its own README and may change substantially.
The functions service is not available in every Fabric region or tenant. The exact return
shape of invoke() has changed across versions (see
Version notes below) — confirm the behavior for your installed version
with rayfin docs get --symbol FunctionClient or the MCP server
before relying on it in production code.
Installation
npm create @microsoft/rayfin@latest@microsoft/rayfin-functions is normally installed as a dependency of
@microsoft/rayfin-client; you rarely add it directly.
Declaring a FunctionsSchema
Define a type that maps each function name to its input and output, and pass it as
RayfinClient's third type parameter so client.functions.<name>.invoke() is fully typed:
import type { FunctionsSchema } from '@microsoft/rayfin-functions';
export type MyFunctionsSchema = {
helloWorld: { input: { firstName: string; lastName: string }; output: string };
add: { input: { a: number; b: number }; output: number };
noParams: { input: void; output: string }; // use `void` (or `{}`) for no-input functions
} satisfies FunctionsSchema;type FunctionsSchema = Record<string, { input: any; output: any }>;import { RayfinClient } from '@microsoft/rayfin-client';
import type { MyFunctionsSchema } from '../rayfin/functions/src/types';
import type { AppSchema } from '../rayfin/data/schema';
const client = new RayfinClient<AppSchema, MyFunctionsSchema>({
baseUrl: 'https://<your-app>-app.rayfin.windows.net/',
publishableKey: 'pk-commonSampleAppKey',
});Invoking a function
const greeting = await client.functions.helloWorld.invoke({
firstName: 'Ada',
lastName: 'Lovelace',
});client.functions is built by createFunctionsApi, which lazily instantiates and caches
one FunctionClient per schema entry:
function createFunctionsApi<TSchema extends FunctionsSchema = FunctionsSchema>(
apiClient: ApiClient,
): TypedFunctionClients<TSchema>;
type TypedFunctionClients<TSchema extends FunctionsSchema> = {
[K in keyof TSchema & string]: FunctionClient<TSchema[K]['input'], TSchema[K]['output']>;
};FunctionClient
class FunctionClient<TInput = any, TOutput = any> {
constructor(apiClient: ApiClient, functionName: string);
invoke(
...args: TInput extends void | Record<string, never>
? [options?: InvokeOptions]
: [params: TInput, options?: InvokeOptions]
): Promise<TOutput>;
}
interface InvokeOptions {
headers?: Record<string, string>;
}- When the schema's
inputisvoid, callinvoke(options?)with no params. - Otherwise call
invoke(params, options?).options.headersadds extra headers to that one request. invoke()resolves to the function's output directly, typed asTOutput. If the raw response contains a JSON-encoded string, it is auto-parsed so the caller never has to.- Failures throw rather than returning an error value: a non-empty
errorsarray or non-success status is surfaced asFunctionsError; network failures asNetworkError; anything else asSdkError.
import { FunctionsError } from '@microsoft/rayfin-functions';
import { NetworkError } from '@microsoft/rayfin-lib';
try {
const result = await client.functions.add.invoke({ a: 1, b: 2 });
console.log(result); // 3, typed as number
} catch (error) {
if (error instanceof FunctionsError) {
console.error('Function failed:', error.message, error.code);
} else if (error instanceof NetworkError) {
console.error('Network issue:', error.message);
}
}FunctionsError
class FunctionsError extends SdkError {
constructor(message: string, code?: string);
}Full exported surface (index.d.ts)
export {
FunctionsError,
createFunctionsApi,
FunctionClient,
} from './Functions.js';
export type {
FunctionInvocationResponse,
InvokeOptions,
TypedFunctionClients,
} from './Functions.js';
export type { FunctionsSchema } from './FunctionsSchema.js';FunctionInvocationResponse<TOutput> is the raw wire envelope the function endpoint
returns before invoke() unwraps it:
interface FunctionInvocationResponse<TOutput = any> {
functionName: string;
invocationId: string;
status: string;
output: TOutput;
errors: Array<string | Record<string, any>>;
}Version notes
The exact shape invoke() resolves to has changed between releases of this experimental
package:
- Documented / current behavior (shown above):
invoke()resolves directly toTOutput— the envelope'soutputfield, auto-unwrapped — and throws on failure instead of returning anerrorsarray. TheinvocationIdis still emitted viaconsole.debugfor correlation, without being part of the typed return value. - This machine's installed version (1.31.0):
invoke()instead resolves to the fullPromise<FunctionInvocationResponse<TOutput>>envelope — callers must read.outputthemselves and check.errors/.statusmanually.
Check which behavior applies to your project before writing calling code — the two shapes
are not interchangeable (result.output vs. result directly).
@microsoft/rayfin-auth-provider-fabric
Fabric brokered authentication for Rayfin apps — ensureSignedInWithFabric, the embedded and popup flows, and the origins each one works from.
@microsoft/rayfin-storage
Type-safe blob storage client for Rayfin — what it's for and how to model storage folders today, pending a version-locked API reference.