diff --git a/core/signal/src/requestable-context-provider.ts b/core/signal/src/requestable-context-provider.ts new file mode 100644 index 000000000..ecd90ce68 --- /dev/null +++ b/core/signal/src/requestable-context-provider.ts @@ -0,0 +1,58 @@ +import {Stringifyable, OmitFirstParam} from '@alwatr/type'; + +import {contextProvider} from './context-provider.js'; +import {signalManager} from './signal-manager.js'; + +/** + * Requestable context provider interface. + */ +export const requestableContextProvider = { + ...contextProvider, + + /** + * Defines the provider of the context signal that will be called when the context requested. + * + * subscribe to request context signal. + * + * Example: + * + * ```ts + * requestableContextProvider.setProvider( + * 'product-list', + * async (requestParam) => { + * return await fetchNewProductList(requestParam) + * }, + * ); + * ``` + */ + setProvider: signalManager.setContextProvider, + + /** + * Bind this interface to special context. + * + * Example: + * + * ```ts + * const productListProvider = requestableContextProvider.bind('product-list'); + * ``` + */ + bind: (contextId: string) =>({ + ...contextProvider.bind(contextId), + + /** + * Defines the provider of the context signal that will be called when the context requested. + * + * subscribe to request context signal. + * + * Example: + * + * ```ts + * productListProvider.setProvider(async (requestParam) => { + * return await fetchNewProductList(requestParam) + * }); + * ``` + */ + setProvider: signalManager.setContextProvider.bind(null, contextId) as + OmitFirstParam>, + } as const), +} as const; diff --git a/core/signal/src/signal-manager.ts b/core/signal/src/signal-manager.ts index 0e82b6801..5f64482ae 100644 --- a/core/signal/src/signal-manager.ts +++ b/core/signal/src/signal-manager.ts @@ -297,9 +297,9 @@ export const signalManager = { * signalManager.setContextProvider('content-change', async (requestParam) => await fetchNewContent(requestParam)); * ``` */ - setContextProvider: ( + setContextProvider: ( signalId: string, - signalProvider: ProviderFunction, + signalProvider: ProviderFunction, options: Partial = {}, ): void => { options.debounce ??= 'AnimationFrame'; @@ -307,12 +307,12 @@ export const signalManager = { signalManager._logger.logMethodArgs('setContextProvider', {signalId, options}); const requestSignalId = 'request-' + signalId; signalManager.removeAllListeners(requestSignalId); - signalManager.subscribe( + signalManager.subscribe( requestSignalId, async (argumentObject): Promise => { const signalDetail = await signalProvider(argumentObject); if (signalDetail !== undefined) { - signalManager.dispatch(signalId, signalDetail, {debounce: options.debounce}); + signalManager.dispatch(signalId, signalDetail, {debounce: options.debounce}); } }, {