UNPKG

@sveltejs/kit

Version:

SvelteKit is the fastest way to build Svelte apps

104 lines (90 loc) 3.38 kB
/** @import { RemoteCommand } from '@sveltejs/kit' */ /** @import { MaybePromise, RemoteCommandInternals } from 'types' */ /** @import { StandardSchemaV1 } from '@standard-schema/spec' */ import { get_request_store } from '@sveltejs/kit/internal/server'; import { create_validator, run_remote_function } from './shared.js'; import { MUTATIVE_METHODS } from '../../../../constants.js'; /** * Creates a remote command. When called from the browser, the function will be invoked on the server via a `fetch` call. * * See [Remote functions](https://svelte.dev/docs/kit/remote-functions#command) for full documentation. * * @template Output * @overload * @param {() => MaybePromise<Output>} fn * @returns {RemoteCommand<void, Output>} * @since 2.27 */ /** * Creates a remote command. When called from the browser, the function will be invoked on the server via a `fetch` call. * * See [Remote functions](https://svelte.dev/docs/kit/remote-functions#command) for full documentation. * * @template Input * @template Output * @overload * @param {'unchecked'} validate * @param {(arg: Input) => MaybePromise<Output>} fn * @returns {RemoteCommand<Input, Output>} * @since 2.27 */ /** * Creates a remote command. When called from the browser, the function will be invoked on the server via a `fetch` call. * * See [Remote functions](https://svelte.dev/docs/kit/remote-functions#command) for full documentation. * * @template {StandardSchemaV1} Schema * @template Output * @overload * @param {Schema} validate * @param {(arg: StandardSchemaV1.InferOutput<Schema>) => MaybePromise<Output>} fn * @returns {RemoteCommand<StandardSchemaV1.InferInput<Schema>, Output>} * @since 2.27 */ /** * @template Input * @template Output * @param {any} validate_or_fn * @param {(arg?: Input) => MaybePromise<Output>} [maybe_fn] * @returns {RemoteCommand<Input, Output>} * @since 2.27 */ /*@__NO_SIDE_EFFECTS__*/ export function command(validate_or_fn, maybe_fn) { /** @type {(arg?: Input) => MaybePromise<Output>} */ const fn = maybe_fn ?? validate_or_fn; /** @type {(arg?: any) => MaybePromise<Input>} */ const validate = create_validator(validate_or_fn, maybe_fn); /** @type {RemoteCommandInternals} */ const __ = { type: 'command', id: '', name: '' }; /** @type {RemoteCommand<Input, Output> & { __: RemoteCommandInternals }} */ const wrapper = (arg) => { const { event, state } = get_request_store(); if (!MUTATIVE_METHODS.includes(event.request.method)) { throw new Error( `Cannot call a command (\`${__.name}(${maybe_fn ? '...' : ''})\`) from a ${event.request.method} handler` ); } if (state.is_in_render) { throw new Error( `Cannot call a command (\`${__.name}(${maybe_fn ? '...' : ''})\`) during server-side rendering` ); } state.remote.refreshes ??= new Map(); state.remote.reconnects ??= new Map(); const promise = Promise.resolve( run_remote_function(event, state, true, () => validate(arg), fn) ); // @ts-expect-error promise.updates = () => { throw new Error(`Cannot call '${__.name}(...).updates(...)' on the server`); }; return /** @type {ReturnType<RemoteCommand<Input, Output>>} */ (promise); }; Object.defineProperty(wrapper, '__', { value: __ }); // On the server, pending is always 0 Object.defineProperty(wrapper, 'pending', { get: () => 0 }); return wrapper; }