Wooks Context
@wooksjs/event-core provides the low-level utilities for creating, managing, and accessing asynchronous event contexts in Wooks. It enables you to establish strongly typed, per-event storage that persists through async calls without manual propagation. This guide targets advanced users who want to understand event-core or create custom event integrations.
Creating and Running an Event Context
To start, you define:
- Event Data Interface: Describes your event’s shape and includes a
typefield. - Context Store Interface: Describes the additional properties you want to store in the event context.
createAsyncEventContext()
Signature:
function createAsyncEventContext<StoreType, EventType extends TGenericEvent>(
data: StoreType & { event: EventType, options: TEventOptions }
): <T>(callback: (...args: any[]) => T) => TUsage:
- Call
createAsyncEventContext()with your event data and store. - It returns a function you can use to run any callback inside the newly created event context.
Key Points:
- The returned function binds the
AsyncLocalStoragecontext so that within the callback, alluseAsyncEventContext()calls refer to the provided event and store. - You can nest contexts. A child context can have a
parentCtxfrom a previously active event.
useAsyncEventContext()
Signature:
function useAsyncEventContext<StoreType, EventType extends TGenericEvent>(
expectedTypes?: string | string[]
): {
getCtx: () => (StoreType & { event: EventType, options: TEventOptions }),
store: <K extends keyof StoreType>(key: K) => StoreStoreHandle<StoreType[K]>,
...
}Usage:
- Call
useAsyncEventContext()within a callback previously executed bycreateAsyncEventContext(). - If
expectedTypesis provided, it ensures the current event type matches one of the expected types. - Returns helper functions (
getCtx(),store(key), etc.) to interact with the context.
Key Points:
- Throws an error if called outside an event context or if the type doesn’t match.
- Ensures type safety: you know exactly what event data and store properties are available.
Working with Stores
event-core provides a structured approach to managing nested state through store(key). Each key should represent an object within your store’s type definition, letting you handle multiple properties inside it.
Store Handle Methods
Calling store(key) returns a handle with methods to manage properties inside that store object:
init(propName, getter): Initialize a property if it’s not set. Useful for lazy loading or expensive operations.get(propName): Retrieve the property’s value.set(propName, value): Set or update the property’s value.del(propName): Delete the property’s value.entries(): Return an array of[propName, value]pairs for all properties.clear(): Remove all properties from the store object.
Key Points:
- Use
initto avoid unnecessary computations or I/O until the property is first accessed. - Keep your store keys simple and well-structured. Each
keycorresponds to a known object in your store’s type definition.
Best Practices for Creating Custom Event Contexts
Define Clear Types:
Create explicit interfaces for your event data and store. Strong typing ensures better developer experience and safer refactoring.Use
initfor Laziness:
If a property requires parsing or fetching data, useinitto do it once, on-demand.Organize Your Store:
Assign meaningfulkeynames that group related data (e.g.,cookies,request,auth), making composables more readable and maintainable.Validate Event Types:
UseexpectedTypesinuseAsyncEventContext()to ensure composables are only called within the correct event flow.Graceful Error Handling:
If you calluseAsyncEventContext()outside the correct context or after the event ends, it throws an error.
