Skip to content

Commit

Permalink
feat(signal): new RequestableContext with state
Browse files Browse the repository at this point in the history
  • Loading branch information
AliMD committed Mar 16, 2023
1 parent c612efc commit b8a8e55
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 12 deletions.
24 changes: 19 additions & 5 deletions core/signal/src/requestable-context-consumer.ts
Original file line number Diff line number Diff line change
@@ -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';

Expand All @@ -16,7 +17,7 @@ export const requestableContextConsumer = {
*
* ```ts
* requestableContextConsumer.request<RequestParamType>('product-list', {foo: 'bar'});
* const newProductList = await requestableContextConsumer.untilChange<ProductListType>('product-list');
* TODO: update me
* ```
*/
request: requestContext,
Expand All @@ -30,8 +31,21 @@ export const requestableContextConsumer = {
* const productListConsumer = requestableContextConsumer.bind<ProductListType>('product-list');
* ```
*/
bind: <TContext extends Stringifyable, TRquest extends Stringifyable>(contextId: string) =>({
...contextConsumer.bind<TContext>(contextId),
bind: <TContextContent extends Stringifyable, TRquest extends Stringifyable = null>(contextId: string) =>({
...contextConsumer.bind<RequestableContext<TContextContent>>(contextId),

/**
* Get context value.
*
* Example:
*
* ```ts
* const currentProductList = productListConsumer.getValue();
* TODO: update me
* ```
*/
getValue: (): RequestableContext<TContextContent> =>
getDetail<RequestableContext<TContextContent>>(contextId) ?? {state: 'initial'},

/**
* Send new context request to the provider.
Expand All @@ -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
Expand Down
7 changes: 4 additions & 3 deletions core/signal/src/requestable-context-provider.ts
Original file line number Diff line number Diff line change
@@ -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';

Expand Down Expand Up @@ -36,8 +37,8 @@ export const requestableContextProvider = {
* const productListProvider = requestableContextProvider.bind<ProductListType>('product-list');
* ```
*/
bind: <TContext extends Stringifyable, TRquest extends Stringifyable>(contextId: string) =>({
...contextProvider.bind<TContext>(contextId),
bind: <TContextContent extends Stringifyable, TRquest extends Stringifyable>(contextId: string) =>({
...contextProvider.bind<RequestableContext<TContextContent>>(contextId),

/**
* Defines the provider of the context signal that will be called when the context requested.
Expand All @@ -53,6 +54,6 @@ export const requestableContextProvider = {
* ```
*/
setProvider: setContextProvider.bind(null, contextId) as
OmitFirstParam<typeof setContextProvider<TContext, TRquest>>,
OmitFirstParam<typeof setContextProvider<RequestableContext<TContextContent>, TRquest>>,
} as const),
} as const;
23 changes: 19 additions & 4 deletions core/signal/src/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,7 @@ export type ListenerFunction<T extends Stringifyable> = (detail: T) => void | Pr
/**
* Command/Context provider/handler function.
*/
export type ProviderFunction<TArgument, TReturn> = (
argumentObject: TArgument
) => MaybePromise<TReturn>;
export type ProviderFunction<TArgument, TReturn> = (argumentObject: TArgument) => MaybePromise<TReturn>;

/**
* Listener spec.
Expand All @@ -99,7 +97,7 @@ export type ListenerSpec = {
* Signal id
*/
signalId: string;
}
};

/**
* Signal listeners object in storage.
Expand Down Expand Up @@ -153,3 +151,20 @@ export type SignalObject<T extends Stringifyable> = {
* Signal stack storage.
*/
export type SignalStorage = Record<string, SignalObject<Stringifyable> | undefined>;

/**
* Requestable context value type.
*/
export type RequestableContext<T extends Stringifyable> =
| {
state: 'initial' | 'pending';
content?: never;
}
| {
state: 'error';
content?: T; // last data
}
| {
state: 'complete' | 'reloading';
content: T;
};

0 comments on commit b8a8e55

Please sign in to comment.