@andrew_l/service-actor
Version:
Forget about passing data like trace IDs between functions.
61 lines (58 loc) • 1.76 kB
text/typescript
import { OverwriteWith, AnyFunction } from '@andrew_l/toolkit';
type AnyServiceActor = {
traceId: any;
actorId: any;
actorType: any;
[x: PropertyKey]: any;
};
type ServiceActorData<T extends Record<PropertyKey, any> = {}> = OverwriteWith<{
traceId: string;
actorId: string | null;
actorType: 'unknown' | string;
}, T>;
type ServiceActor<T extends Record<PropertyKey, any> = {}> = ServiceActorData<T> & {
assign(params: Partial<ServiceActorData<T>>): ServiceActor<T>;
};
/**
* Create service actor hooks
*
* @example
* const { use: useServiceActor, with: withServiceActor } = serviceActor(() => ({
* actorType: 'http-request',
* ipAddress: '',
* }));
*
* app.use((ctx, next) => {
* return withServiceActor(
* {
* traceId: ctx.headers['x-request-id'],
* ipAddress: ctx.headers['x-forwarded-for'],
* },
* next,
* );
* });
*
* app.get('/', () => {
* const actor = useServiceActor();
*
* // { traceId: 'req_35123', actorId: null, actorType: 'http-request', ipAddress: '::' }
* console.log(actor);
* });
*
* @group Main
*/
declare function serviceActor<T extends Record<PropertyKey, any> = {}>(factory?: () => T): {
/**
* Wrap a function to execute it with service actor providers
*/
with: <Fn extends AnyFunction>(fn: Fn, params?: Partial<ServiceActor<T>>) => Fn;
/**
* Returns the service actor instance from the current context.
*/
inject: () => ServiceActor<T> | undefined;
/**
* Returns the service actor instance from the context, or creates and binds a new instance if none exists.
*/
use: () => ServiceActor<T>;
};
export { type AnyServiceActor, type ServiceActor, type ServiceActorData, serviceActor };