From b8a8e550d3952863d85ba9d9d87513a668a9430d Mon Sep 17 00:00:00 2001 From: Ali Mihandoost Date: Sat, 11 Mar 2023 16:15:51 +0330 Subject: [PATCH] feat(signal): new RequestableContext with state --- .../src/requestable-context-consumer.ts | 24 +++++++++++++++---- .../src/requestable-context-provider.ts | 7 +++--- core/signal/src/type.ts | 23 ++++++++++++++---- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/core/signal/src/requestable-context-consumer.ts b/core/signal/src/requestable-context-consumer.ts index 2e1740737..46c4f99a5 100644 --- a/core/signal/src/requestable-context-consumer.ts +++ b/core/signal/src/requestable-context-consumer.ts @@ -1,5 +1,6 @@ import {contextConsumer} from './context-consumer.js'; -import {requestContext} from './core.js'; +import {getDetail, requestContext} from './core.js'; +import {RequestableContext} from './type.js'; import type {Stringifyable, OmitFirstParam} from '@alwatr/type'; @@ -16,7 +17,7 @@ export const requestableContextConsumer = { * * ```ts * requestableContextConsumer.request('product-list', {foo: 'bar'}); - * const newProductList = await requestableContextConsumer.untilChange('product-list'); + * TODO: update me * ``` */ request: requestContext, @@ -30,8 +31,21 @@ export const requestableContextConsumer = { * const productListConsumer = requestableContextConsumer.bind('product-list'); * ``` */ - bind: (contextId: string) =>({ - ...contextConsumer.bind(contextId), + bind: (contextId: string) =>({ + ...contextConsumer.bind>(contextId), + + /** + * Get context value. + * + * Example: + * + * ```ts + * const currentProductList = productListConsumer.getValue(); + * TODO: update me + * ``` + */ + getValue: (): RequestableContext => + getDetail>(contextId) ?? {state: 'initial'}, /** * Send new context request to the provider. @@ -40,7 +54,7 @@ export const requestableContextConsumer = { * * ```ts * productListConsumer.request({foo: 'bar'}); - * const newProductList = await productListConsumer.untilChange(); + * TODO: update me * ``` */ request: requestContext.bind(null, contextId) as diff --git a/core/signal/src/requestable-context-provider.ts b/core/signal/src/requestable-context-provider.ts index 2d13f386f..e7abbfb61 100644 --- a/core/signal/src/requestable-context-provider.ts +++ b/core/signal/src/requestable-context-provider.ts @@ -1,5 +1,6 @@ import {contextProvider} from './context-provider.js'; import {setContextProvider} from './core.js'; +import {RequestableContext} from './type.js'; import type {Stringifyable, OmitFirstParam} from '@alwatr/type'; @@ -36,8 +37,8 @@ export const requestableContextProvider = { * const productListProvider = requestableContextProvider.bind('product-list'); * ``` */ - bind: (contextId: string) =>({ - ...contextProvider.bind(contextId), + bind: (contextId: string) =>({ + ...contextProvider.bind>(contextId), /** * Defines the provider of the context signal that will be called when the context requested. @@ -53,6 +54,6 @@ export const requestableContextProvider = { * ``` */ setProvider: setContextProvider.bind(null, contextId) as - OmitFirstParam>, + OmitFirstParam, TRquest>>, } as const), } as const; diff --git a/core/signal/src/type.ts b/core/signal/src/type.ts index ec372e698..69c3b6f13 100644 --- a/core/signal/src/type.ts +++ b/core/signal/src/type.ts @@ -82,9 +82,7 @@ export type ListenerFunction = (detail: T) => void | Pr /** * Command/Context provider/handler function. */ -export type ProviderFunction = ( - argumentObject: TArgument -) => MaybePromise; +export type ProviderFunction = (argumentObject: TArgument) => MaybePromise; /** * Listener spec. @@ -99,7 +97,7 @@ export type ListenerSpec = { * Signal id */ signalId: string; -} +}; /** * Signal listeners object in storage. @@ -153,3 +151,20 @@ export type SignalObject = { * Signal stack storage. */ export type SignalStorage = Record | undefined>; + +/** + * Requestable context value type. + */ +export type RequestableContext = + | { + state: 'initial' | 'pending'; + content?: never; + } + | { + state: 'error'; + content?: T; // last data + } + | { + state: 'complete' | 'reloading'; + content: T; + };