auth-yes/tasks/new/2026-0824.02.jul.feat.sdk.realtime-invalidation-bus-1200.md
google-labs-jules[bot] 2753b6b757 docs(tasks): draft realtime invalidation bus task for SDK
Creates a Kanban task file outlining the architectural plan and
implementation steps for adding a zero-dependency real-time event
bus to `@auth-yes/sdk`. This bus will listen for Valkey RESP3 push
invalidation events and emit raw token strings to registered
listeners, ensuring safe and isolated execution to prevent downstream
crashes.

Co-authored-by: mrteye <1945243+mrteye@users.noreply.github.com>
2026-08-24 03:54:55 +00:00

70 lines
4.1 KiB
Markdown

# TASK METADATA
- **Target Files:** `sdk/mod.ts`, `sdk/mod.test.ts`
- **Core Objective:** Extend `@auth-yes/sdk` with a zero-dependency real-time event bus to listen for Valkey 8 RESP3 push invalidation events and emit them to registered listeners.
- **Dependencies:** None.
- **Additional Important Notes:** Handlers must support async execution. Errors thrown by handlers must be caught and logged so they do not crash the Valkey push listener or stop other registered handlers. No external EventEmitter libraries are allowed.
---
## Architectural Considerations & Risks
### Risks
- **Memory Leaks:** Downstream consumers registering listeners for `"invalidate"` without subsequently calling `off` could result in an unbounded map of listeners. We must clearly document the `off` method and emphasize its usage during cleanup (e.g., when a consumer class is destroyed or a connection pool closes).
- **Callback Crash Propagation:** If a downstream consumer's callback throws an exception (e.g., failing to terminate a WebSocket), and it is not caught, it could crash the internal Valkey `push` event handler. The implementation must guarantee isolated execution via a `try/catch` wrapper and gracefully handle Promise rejections.
- **Payload Alignment:** Any discrepancy between the raw key emitted by Valkey and the expected token by downstream listeners could result in missed invalidations. As confirmed, Valkey stores and emits the raw `token` without prefixes, so we must emit the token strictly as received.
### Alternatives
- Using the web standard `EventTarget` natively supported in Deno. While native, standard `EventTarget` limits the payload to custom `Event` objects (`CustomEvent`), which adds boilerplate (`event.detail.token`) and type-casting complexity for downstream users. A custom lightweight callback Set (`Set<InvalidationHandler>`) allows us to pass the `token: string` payload directly and cleanly.
- Using an external EventEmitter package. This was rejected per the zero-dependency directive.
## Proposed Implementation
### 1. Define the Handler Type
In `sdk/mod.ts`, define the TypeScript type for the invalidation handler:
```typescript
export type InvalidationHandler = (token: string) => void | Promise<void>;
```
### 2. Implement the Internal Event Bus
In the `AuthSdk` class (`sdk/mod.ts`):
- Add a private property to store listeners:
```typescript
private listeners: Map<string, Set<InvalidationHandler>> = new Map();
```
- Implement the `on` method:
```typescript
/**
* Registers a callback to be invoked when a specific event occurs.
* Currently, only the "invalidate" event is supported.
*
* @param event The event name (e.g., "invalidate").
* @param handler The callback function.
*/
on(event: "invalidate", handler: InvalidationHandler): void;
```
- Implement the `off` method:
```typescript
/**
* Unregisters a previously registered callback.
*
* @param event The event name (e.g., "invalidate").
* @param handler The callback function to remove.
*/
off(event: "invalidate", handler: InvalidationHandler): void;
```
### 3. Integrate with Valkey `push` Events
In the `initValkeyClient` method of `AuthSdk` (`sdk/mod.ts`):
- Locate the existing `"push"` event listener for the Valkey client.
- Inside the loop that iterates over `keysToInvalidate` (which represents the raw tokens), add the emission logic.
- Retrieve the `Set` of listeners for the `"invalidate"` event.
- Iterate over the handlers and invoke them safely using a `try/catch` block and `Promise.resolve(...).catch(...)` to prevent any single failing handler from impacting the others or crashing the SDK.
### 4. Write Unit Tests
In `sdk/mod.test.ts`:
- Write tests to verify that `on` and `off` correctly add and remove handlers.
- Simulate the Valkey `"push"` event (e.g., by creating an instance with a mocked `valkeyClient` or directly testing an internal emit method, or sending mock payloads if the Valkey client is mocked).
- Verify that registered listeners are invoked with the correct token.
- Verify that a throwing or rejecting handler does not disrupt the execution of subsequent handlers.