UNPKG

@grammyjs/conversations

Version:

Conversational interfaces for grammY

170 lines (169 loc) 6.23 kB
import type { Context } from "./deps.node.js"; /** Current data version of this plugin */ export declare const PLUGIN_DATA_VERSION = 0; /** * A value with a version. * * The version consists of two pieces. * * The first piece is a number that is defined by the plugin internally and * cannot be changed. When the plugin is updated and it changes its internal * data format, then it can use this part of the version to detect and * automatically migrate the versioned state as necessary. * * The second piece is a number or a string and can be set by the developer. It * should be changed whenever the application code changes in a way that * invalidates the state. The plugin can then discard and re-create the state as * necesarry. * * Versioned states are typically created via the {@link pinVersion} function. * * @typeParam S The type of the state to be versioned */ export interface VersionedState<S> { /** The version of the state */ version: [typeof PLUGIN_DATA_VERSION, string | number]; /** The state to be versioned */ state: S; } /** * A container for two functions that are pinned to a specific version. The two * functions can be used to add the bound version to data, and to unpack the * data again. This container is typically created using {@link pinVersion}. */ export interface PinnedVersion { /** * Adds a version to some data. * * @param state Some data */ versionify<S>(state: S): VersionedState<S>; /** * Unpacks some versioned data. Returns the original data if the data is * correct, and `undefined` otherwise. If `undefined` is passed, then * `undefined` will be returned. * * @param data Some versioned data or `undefined` */ unpack<S>(data?: VersionedState<S>): S | undefined; } /** * Takes a version number and returns two state management functions that are pinned to this * version. * * The two functions it returns are `versionify` and `unpack`. The former can be * used to add a version to some data. The latter can be used to unpack the data * again, validating the version on the fly. * * ```ts * import { assert } from "jsr:@std/assert"; * * const { versionify, unpack } = pinVersion(42); * * const data = { prop: "pizza" }; * const versioned = versionify(data); * const unpacked = unpack(versioned); * assert(data === unpacked); * ``` * * @param version the version to use for pinning */ export declare function pinVersion(version: string | number): PinnedVersion; /** * A value or a promise of a value. * * @typeParam T The type of value */ export type MaybePromise<T> = T | Promise<T>; /** * A storage for versioned state. * * Specify this to define how to persist data. * * This type is a union of three types, each representing a different way to * store data. * * 1. A {@link VersionedStateStorage} directly provides definitions for reading, * writing, and deleting data based on `ctx.chatId`. No versions can be * specified and the storage key function cannot be changed. * 2. A {@link ConversationKeyStorage}, disambiguated via `{ type: "key" }`, is * more general. It supports versioning the data and changing the storage key * function. * 3. A {@link ConversationContextStorage}, disambiguated via `{ type: "context" * }`, is even more general. It no longer needs a storage key function. * Instead, it provides read, write, and delete operations for data based on * the context object directly. It also supports versioning data. * * @typeParam C A custom context type * @typeParam S A type for the state to version and store */ export type ConversationStorage<C extends Context, S> = { type?: never; version?: never; } & VersionedStateStorage<string, S> | ConversationContextStorage<C, S> | ConversationKeyStorage<C, S>; /** * An object that defines how to read, write, and delete versioned data based on * a key. * * @typeParam K The type of key to use * @typeParam S The type of data to store */ export interface VersionedStateStorage<K, S> { /** * Reads the data for a given key. * * @param key A key to identify the data */ read(key: K): MaybePromise<VersionedState<S> | undefined>; /** * Writes some data to the storage for a given key. * * @param key A key to identify the data * @param state The data to write */ write(key: K, state: VersionedState<S>): MaybePromise<void>; /** * Deletes some data from the storage for a given key. * * @param key A key to identify the data */ delete(key: K): MaybePromise<void>; } /** * An object that defines how to read, write, or delete versioned data based on * a context object. */ export interface ConversationContextStorage<C extends Context, S> { /** The type of storage, always `"context"` */ type: "context"; /** An optional version for the data, defaults to `0` */ version?: string | number; /** The underlying storage that defines how to read and write raw data */ adapter: VersionedStateStorage<C, S>; } export interface ConversationKeyStorage<C extends Context, S> { /** The type of storage, always `"key"` */ type: "key"; /** An optional version for the data, defaults to `0` */ version?: string | number; /** An optional prefix to prepend to the storage key */ prefix?: string; /** An optional storage key function, defaults to `ctx.chatId` */ getStorageKey?(ctx: C): string | undefined; /** The underlying storage that defines how to read and write raw data */ adapter: VersionedStateStorage<string, S>; } /** * Coerces different storages to a single uniform abstraction. * * This function takes a {@link ConversationStorage} object and unifies its * union members behind a common abstraction that simply exposes a read, write, * and delete method for a given context object. * * @param storage An object defining how to store data */ export declare function uniformStorage<C extends Context, S>(storage?: ConversationStorage<C, S>): (ctx: C) => { read: () => MaybePromise<S | undefined>; write: (state: S) => MaybePromise<void>; delete: () => MaybePromise<void>; };