Skip to content

Commit

Permalink
feat(signal): new contextConsumer interface
Browse files Browse the repository at this point in the history
  • Loading branch information
alimd committed Jan 28, 2023
1 parent 7b3716c commit 9ee4a62
Showing 1 changed file with 135 additions and 0 deletions.
135 changes: 135 additions & 0 deletions core/signal/src/context-consumer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import {Stringifyable, OmitFirstParam} from '@alwatr/type';

import {signalManager} from './signal-manager.js';

/**
* Context consumer interface.
*/
export const contextConsumer = {
/**
* Get context value.
*
* Return undefined if context not set before or expired.
*
* Example:
*
* ```ts
* const currentProductList = contextConsumer.getValue<ProductListType>('product-list');
* if (currentProductList === undefined) {
* // productList not set before or expired.
* }
* ```
*/
getValue: signalManager.getDetail,

/**
* Waits until the context value changes.
*
* Example:
*
* ```ts
* const newProductList = await contextConsumer.untilChange<ProductListType>('product-list');
* ```
*/
untilChange: signalManager.untilNext,

/**
* Subscribe to context changes, work like addEventListener.
*
* Example:
*
* ```ts
* const listener = contextConsumer.subscribe<ProductListType>('product-list', (productList) => {
* console.log(productList);
* });
* // ...
* contextConsumer.unsubscribe(listener);
* ```
*/
subscribe: signalManager.subscribe,

/**
* Unsubscribe from context changes, work like removeEventListener.
*
* Example:
*
* ```ts
* const listener = contextConsumer.subscribe<ProductListType>('product-list', (productList) => {
* console.log(productList);
* });
* // ...
* contextConsumer.unsubscribe(listener);
* ```
*/
unsubscribe: signalManager.unsubscribe,

/**
* Bind this interface to special context.
*
* Example:
*
* ```ts
* const productListConsumer = contextConsumer.bind<ProductListType>('product-list');
* ```
*/
bind: <T extends Stringifyable>(contextId: string) =>({
/**
* Event signal Id.
*/
id: contextId,

/**
* Get context value.
*
* Return undefined if context not set before or expired.
*
* Example:
*
* ```ts
* const currentProductList = productListConsumer.getValue();
* if (currentProductList === undefined) {
* // productList not set before or expired.
* }
* ```
*/
getValue: signalManager.getDetail.bind(null, contextId) as OmitFirstParam<typeof signalManager.getDetail<T>>,

/**
* Waits until the context value changes.
*
* Example:
*
* ```ts
* const newProductList = await productListConsumer.untilChange();
* ```
*/
untilChange: signalManager.untilNext.bind(null, contextId) as OmitFirstParam<typeof signalManager.untilNext<T>>,

/**
* Subscribe to context changes, work like addEventListener.
*
* Example:
*
* ```ts
* const listener = productListConsumer.subscribe((productList) => console.log(productList));
* // ...
* productListConsumer.unsubscribe(listener);
* ```
*/
subscribe: signalManager.subscribe.bind(null, contextId) as unknown as
OmitFirstParam<typeof signalManager.subscribe<T>>,

/**
* Unsubscribe from context changes, work like removeEventListener.
*
* Example:
*
* ```ts
* const listener = productListConsumer.subscribe((productList) => console.log(productList));
* // ...
* productListConsumer.unsubscribe(listener);
* ```
*/
unsubscribe: signalManager.unsubscribe,
}),
} as const;

0 comments on commit 9ee4a62

Please sign in to comment.