New v4.9.0 created automatically from CircleCI#140
Merged
Conversation
Implement WebSocket presence tracking plugin with:
- PresenceAdapter interface + DYNAMIC_API_PRESENCE_ADAPTER injection token
- InMemoryPresenceAdapter (Map-based, multi-tab support)
- RedisPresenceAdapter (ioredis, atomic Lua SREM+DEL, configurable TTL)
- PresenceGateway (createPresenceGateway factory, shared namespace/Option B)
emits user:online / user:offline events
- PresenceController (GET /presence[?room=], opt-in via enableController)
- DynamicApiPresenceModule.register({ adapter, redisUrl?, redisTtlSeconds?, enableController? })
- 72 unit tests, 100% coverage on all presence files
- E2E spec: presence.e2e-spec.ts (real MongoDB + NestJS)
- README/presence.md documentation
ioredis added as direct dependency (v5.10.1).
…onditions The global DynamicApiJwtAuthGuard was blocking GET /presence (401) because the route lacked the @public() decorator. Added @public() to getOnlineUsers so the endpoint is accessible without a JWT token. Also fixed two e2e race conditions where waitForEvent(user:online) was registered after the event had already fired: - user:offline test: register listener before authenticated socket connects - GET /presence test: same pattern, then await confirmation before HTTP call Added jest.setTimeout(20000) for the full e2e suite to avoid flaky timeouts during slow CI app initialisation. All 6 presence e2e tests now pass, unit coverage remains 100% (73 tests).
…uired) Add a note explaining that GET /presence is decorated with @public() and therefore bypasses DynamicApiJwtAuthGuard.
…dules barrel Export presence module directly from src/index.ts instead of modules/index.ts. The cycle was: interfaces/dynamic-api-options → ../modules → presence.module → dynamic-api.module → ./modules (already loading), causing DYNAMIC_API_PRESENCE_ADAPTER to be undefined at decorator application time (TypeError: decorator is not a function).
…PresenceAdapter Replace get()! pattern with a local variable + nullish coalescing to avoid the redundant assertion warning.
…or handler Avoids '[object Object]' default stringification for non-Error thrown values.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

feat(presence): add DynamicApiPresenceModule with pluggable adapters
Implement WebSocket presence tracking plugin with:
emits user:online / user:offline events
ioredis added as direct dependency (v5.10.1).
fix(presence): add @public() to PresenceController and fix e2e race conditions
The global DynamicApiJwtAuthGuard was blocking GET /presence (401)
because the route lacked the @public() decorator. Added @public() to
getOnlineUsers so the endpoint is accessible without a JWT token.
Also fixed two e2e race conditions where waitForEvent(user:online) was
registered after the event had already fired:
Added jest.setTimeout(20000) for the full e2e suite to avoid flaky timeouts
during slow CI app initialisation.
All 6 presence e2e tests now pass, unit coverage remains 100% (73 tests).
docs(presence): document GET /presence as public endpoint (no JWT required)
Add a note explaining that GET /presence is decorated with @public()
and therefore bypasses DynamicApiJwtAuthGuard.
fix(presence): break circular dependency by moving presence out of modules barrel
Export presence module directly from src/index.ts instead of modules/index.ts.
The cycle was: interfaces/dynamic-api-options → ../modules → presence.module
→ dynamic-api.module → ./modules (already loading), causing DYNAMIC_API_PRESENCE_ADAPTER
to be undefined at decorator application time (TypeError: decorator is not a function).
refactor(presence): remove unnecessary non-null assertion in InMemoryPresenceAdapter
Replace get()! pattern with a local variable + nullish coalescing to avoid
the redundant assertion warning.
fix(presence): replace String(err) with JSON.stringify in gateway error handler
Avoids '[object Object]' default stringification for non-Error thrown values.
chore(release): 4.9.0