UNPKG

@atlaskit/node-data-provider

Version:

Node data provider for @atlaskit/editor-core plugins and @atlaskit/renderer

215 lines (214 loc) 8.55 kB
import type { JSONNode } from '@atlaskit/editor-json-transformer'; import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model'; /** * Represents the SSR data for a single provider. * It's a map where each key is a unique node data key and the value is the prefetched data for that node. * * @example * { * 'node-id-1': { value: 'some data' }, * 'node-id-2': { value: 'other data' } * } */ type SSRData<Data> = { [dataKey: string]: Data; }; type CacheRecords<Data> = SSRData<Data>; /** * Represents the cached data for a Node Data Provider. * Each key is a unique node data key, and the value is an object containing: * - `source`: Indicates whether the data was fetched from SSR or the network. * - `data`: The actual data, which can be either a resolved value or a Promise. * * @example * { * 'node-id-1': { source: 'ssr', data: { value: 'some data' } }, * 'node-id-2': { source: 'network', data: { value: 'other data' } } * } */ type CacheData<Data> = Record<string, { data: Data; source: 'ssr' | 'network'; }>; /** * Represents the payload passed to the callback function when data is fetched. * It can either contain an error or the fetched data. */ export type CallbackPayload<Data> = { data?: undefined; /** An error that occurred while fetching data. */ error: Error; } | { /** Fetched data for the node. */ data: Data; error?: undefined; }; /** * A Node Data Provider is responsible for fetching and caching data associated with specific ProseMirror nodes. * It supports a cache-first-then-network strategy, with initial data potentially provided via SSR. * * @template Node The specific type of JSONNode this provider supports. * @template Data The type of data this provider fetches and manages. */ export declare abstract class NodeDataProvider<Node extends JSONNode, Data> { private cacheVersion; private cache; private readonly networkRequestsInFlight; /** * A unique name for the provider. Used for identification in SSR. */ abstract readonly name: string; /** * A type guard to check if a given JSONNode is supported by this provider. * Used to ensure that the provider can handle the node type before attempting to fetch data. * * @param node The node to check. * @returns `true` if the node is of the type supported by this provider, otherwise `false`. */ abstract isNodeSupported(node: JSONNode): node is Node; /** * Generates a unique key for a given node to be used for caching. * * @param node The node for which to generate a data key. * @returns A unique string key for the node's data. */ abstract nodeDataKey(node: Node): string; /** * Fetches data for a batch of nodes from the network or another asynchronous source. * * @param nodes An array of nodes for which to fetch data. * @returns A promise that resolves to an array of data corresponding to the input nodes. */ abstract fetchNodesData(nodes: Node[]): Promise<Data[]>; protected constructor(); /** * Sets the SSR data for the provider. * This pre-populates the cache with data rendered on the server, preventing redundant network requests on the client. * Calling this method will invalidate the existing cache. * * @example * ``` * const ssrData = window.__SSR_NODE_DATA__ || {}; * nodeDataProvider.setSSRData(ssrData); * ``` * * @param ssrData A map of node data keys to their corresponding data. */ setSSRData(ssrData?: SSRData<Data>): void; /** * Clears all cached data. * This increments the internal cache version, invalidating any pending network requests. * * @example * ``` * function useMyNodeDataProvider(contentId: string) { * const nodeDataProvider = new MyNodeDataProvider(); * * // Reset the cache when the contentId changes (e.g., when the user navigates to a different page). * useEffect(() => { * nodeDataProvider.resetCache(); * }, [contentId]); * * return nodeDataProvider; * } * ``` */ resetCache(): void; /** * Fetches data for a given node using a cache-first-then-network strategy. * * The provided callback may be called multiple times: * 1. Immediately with data from the SSR cache, if available. * 2. Asynchronously with data fetched from the network. * * @example * ``` * const nodeDataProvider = new MyNodeDataProvider(); * * nodeDataProvider.getData(node, (data) => { * console.log('Node data:', data); * }); * ``` * * @param node The node (or its ProseMirror representation) for which to fetch data. * @param callback The callback function to call with the fetched data or an error. */ getData(node: Node | PMNode, callback: (payload: CallbackPayload<Data>) => void): void; protected getDataAsync(node: Node | PMNode, callback: (payload: CallbackPayload<Data>) => void): Promise<void>; /** * Fetches data for a given node and returns it as a Promise. * This is a convenience wrapper around the `data` method for use with async/await. * * Note: This promise resolves with the *first* available data, which could be from the SSR cache or the network. * It may not provide the most up-to-date data if a network fetch is in progress. * * Note: This method is only for migration purposes. Use {@link getData} in new code instead. * * @private * @deprecated Don't use this method, use {@link getData} method instead. * This method is only for migration purposes. * * @param node The node (or its ProseMirror representation) for which to fetch data. * @returns A promise that resolves with the node's data. */ getDataAsPromise_DO_NOT_USE_OUTSIDE_MIGRATIONS(node: Node | PMNode): Promise<Data>; /** * Checks the cache for the given node and returns its status. * * Possible return values: * - `false`: No cached data found for the node. * - `'ssr'`: Data is cached from server-side rendering (SSR). * - `'network'`: Data is cached from a network request. * * @param node The node (or its ProseMirror representation) to check in the cache. * @returns The cache status: `false`, `'ssr'`, or `'network'`. */ getCacheStatusForNode(node: Node | PMNode): false | 'ssr' | 'network'; /** * Retrieves the cached data for a given node, if available. * * @param node The node (or its ProseMirror representation) for which to retrieve cached data. * @returns The cached data object containing `data` and `source`, or `undefined` if no cache entry exists. */ getNodeDataFromCache(node: JSONNode | PMNode): CacheData<Data>[string] | undefined; /** * Returns the keys of the cache. * * @returns An array of the keys of the cache. */ getNodeDataCacheKeys(): string[]; /** * Updates the cache with new records using merge or replace strategies. * This method should be the only way to modify the cache directly. * This allow subclasses to use it when needed. e.g. abstract fetchNodesData implementation. * * @example * ``` * const newRecords = { * 'node-id-1': { value: 'updated data' }, * 'node-id-3': { value: 'new data' } * }; * nodeDataProvider.updateCache(newRecords, { strategy: 'merge', source: 'network' }); * ``` * * Supports two strategies: * - 'merge' (default): Merges new records into the existing cache. * - 'replace': Replaces the entire cache with the new records, invalidating any in-flight requests. * * @param records A map of node data keys to their corresponding data. * @param options Optional settings for the update operation. * @param options.strategy The strategy to use for updating the cache ('merge' or 'replace'). Defaults to 'merge'. * @param options.source The source of the data being added ('ssr' or 'network'). Defaults to 'network'. */ updateCache(records?: CacheRecords<Data>, options?: { source?: 'ssr' | 'network'; strategy?: 'merge' | 'replace'; }): void; /** * Removes one or more entries from the cache. * * @param keys A single data key or array of data keys to remove from the cache. */ removeFromCache(keys: string[]): void; } export {};