Merge pull request #4 from mrteye/feat-sdk-realtime-invalidation-bus-task-2670591133327528715
docs(tasks): draft realtime invalidation bus task for SDK
This commit is contained in:
commit
4b72d491bf
@ -0,0 +1,69 @@
|
|||||||
|
# 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.
|
||||||
Loading…
x
Reference in New Issue
Block a user