Skip to content

feat: expose subscribe method on journey-client and oidc-client#633

Open
ryanbas21 wants to merge 1 commit into
mainfrom
feat/export-subscribe-method-v2
Open

feat: expose subscribe method on journey-client and oidc-client#633
ryanbas21 wants to merge 1 commit into
mainfrom
feat/export-subscribe-method-v2

Conversation

@ryanbas21
Copy link
Copy Markdown
Collaborator

@ryanbas21 ryanbas21 commented May 13, 2026

Summary

  • Adds subscribe to the JourneyClient interface and exposes store.subscribe from the journey() factory function
  • Exposes store.subscribe from the oidc() factory function
  • Aligns both packages with the existing pattern in davinci-client

Changeset

Minor bump for @forgerock/journey-client and @forgerock/oidc-client — backwards-compatible public API addition.

Summary by CodeRabbit

Release Notes

  • New Features
    • Journey Client and OIDC Client now expose a subscribe method, allowing you to listen for store state changes. Call subscribe(listener) to register a listener function, which returns an unsubscribe function for cleanup.

Review Change Stack

Aligns journey-client and oidc-client with davinci-client's public API
by exporting store.subscribe from each client factory function.
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 13, 2026

🦋 Changeset detected

Latest commit: 6519fcc

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 12 packages
Name Type
@forgerock/journey-client Minor
@forgerock/oidc-client Minor
@forgerock/davinci-client Minor
@forgerock/device-client Minor
@forgerock/protect Minor
@forgerock/sdk-types Minor
@forgerock/sdk-utilities Minor
@forgerock/iframe-manager Minor
@forgerock/sdk-logger Minor
@forgerock/sdk-oidc Minor
@forgerock/sdk-request-middleware Minor
@forgerock/storage Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@nx-cloud
Copy link
Copy Markdown
Contributor

nx-cloud Bot commented May 13, 2026

View your CI Pipeline Execution ↗ for commit 6519fcc

Command Status Duration Result
nx affected -t build lint test typecheck e2e-ci ❌ Failed 10m 20s View ↗

☁️ Nx Cloud last updated this comment at 2026-05-13 15:00:06 UTC

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 13, 2026

📝 Walkthrough

Walkthrough

Both @forgerock/journey-client and @forgerock/oidc-client now expose a subscribe method on their client instances, delegating directly to the underlying store's subscription interface. The change includes interface updates, implementation wiring, generated API reports, tests, and a versioning changeset.

Changes

Subscribe Method Export

Layer / File(s) Summary
Release Notes and Versioning
.changeset/export-subscribe-method.md
Minor version bumps for both journey-client and oidc-client; notes that subscribe is now exposed for listening to store state changes.
Journey Client Subscribe Method
packages/journey-client/src/lib/client.store.ts, packages/journey-client/api-report/journey-client.api.md, packages/journey-client/api-report/journey-client.types.api.md, packages/journey-client/src/lib/client.store.test.ts
JourneyClient interface declares subscribe, factory implementation wires it to store.subscribe, API reports reflect the new method signature, and test verifies the method exists and is callable.
OIDC Client Subscribe Method with Redux Unsubscribe Type
packages/oidc-client/api-report/oidc-client.api.md, packages/oidc-client/api-report/oidc-client.types.api.md, packages/oidc-client/src/lib/client.store.ts, packages/oidc-client/src/lib/client.store.test.ts
OIDC client imports Unsubscribe type from redux-toolkit, api reports use it for subscribe return type, factory wires subscribe to store.subscribe, and test verifies subscribe returns an unsubscribe function.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Suggested reviewers

  • cerebrl

Poem

🐰 A rabbit rejoices in hops most divine,
Subscribe now exposed, in stores both align!
Journey and OIDC, in harmony dance,
Listeners now listen with newfound chance! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The description provides a clear summary and changeset information, but does not follow the repository's template structure with JIRA Ticket and Description sections. Follow the provided template by adding explicit JIRA Ticket and Description section headings, even if JIRA reference is not applicable.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: exposing a subscribe method on two client packages.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/export-subscribe-method-v2

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (7)
packages/journey-client/src/lib/client.store.ts (1)

39-39: ⚡ Quick win

Consider using Unsubscribe type from @reduxjs/toolkit for consistency.

The return type () => void works but is less precise than Redux Toolkit's Unsubscribe type. According to the review context, oidc-client imports and uses the Unsubscribe type for the same method being added in this PR. Using the same type would improve consistency across both clients and provide better type documentation.

♻️ Suggested type refinement
+import type { Unsubscribe } from '@reduxjs/toolkit';
+
 /** The journey client instance returned by the `journey()` function. */
 export interface JourneyClient {
-  subscribe: (listener: () => void) => () => void;
+  subscribe: (listener: () => void) => Unsubscribe;
   start: (options?: StartParam) => Promise<JourneyResult>;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/journey-client/src/lib/client.store.ts` at line 39, The subscribe
method signature currently uses a generic () => void return type; replace that
with the Redux Toolkit Unsubscribe type to match other clients: import
Unsubscribe from '@reduxjs/toolkit' (or import { Unsubscribe } if needed) and
change the signature on subscribe (the subscribe declaration in client.store.ts)
from subscribe: (listener: () => void) => () => void to subscribe: (listener: ()
=> void) => Unsubscribe so the type is consistent with oidc-client and provides
clearer docs.
packages/journey-client/api-report/journey-client.api.md (2)

197-197: ⚡ Quick win

Add JSDoc documentation for the new public subscribe method.

The subscribe method is marked as // (undocumented), meaning it lacks JSDoc comments in the source file. For a new public API being added in a minor version bump, documentation would help consumers understand:

  • The purpose of the method (listening to store state changes)
  • When the listener is invoked
  • How to access state inside the listener
  • What the returned unsubscribe function does
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/journey-client/api-report/journey-client.api.md` at line 197, Add
JSDoc for the public subscribe method to replace the "(undocumented)" tag:
document purpose (listening to store state changes), describe when the listener
is invoked (after state updates), specify the listener signature and how to
access the current state from the provided callback (e.g., receives state or a
selector), and explain that subscribe returns an unsubscribe function that
removes the listener when called; apply this to the subscribe method declaration
so consumers see purpose, invocation timing, parameter details, and that the
return value is a cleanup function.

197-197: ⚡ Quick win

Use Unsubscribe type for consistency with oidc-client.

Journey Client's subscribe method returns () => void, while oidc-client uses the Unsubscribe type (imported from @reduxjs/toolkit) for its subscribe method's return type. Consider using the same Unsubscribe type here for consistency across both client packages.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/journey-client/api-report/journey-client.api.md` at line 197, The
subscribe method currently returns a bare () => void; change its return type to
use the Unsubscribe type (imported from `@reduxjs/toolkit`) for consistency with
oidc-client — update the method signature for subscribe (and any related
types/exports) to import Unsubscribe and annotate the return type as Unsubscribe
so callers and API docs match oidc-client.
packages/oidc-client/src/lib/client.store.ts (1)

98-99: Add JSDoc documentation for the new public API method.

The subscribe method is now part of the public client API but lacks documentation. Adding JSDoc here will improve developer experience by explaining the subscription pattern, listener signature, and how to unsubscribe.

📚 Suggested documentation
+/**
+ * `@method` subscribe
+ * `@description` Subscribes to store state changes. The listener will be called whenever the state updates.
+ * `@param` {() => void} listener - Callback function invoked on each state change.
+ * `@returns` {Unsubscribe} - Function to call to unsubscribe the listener.
+ */
 subscribe: store.subscribe,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/oidc-client/src/lib/client.store.ts` around lines 98 - 99, Add JSDoc
for the newly exported public subscribe method so developers understand the
subscription pattern, listener signature, and how to unsubscribe: update the
object that passes store.subscribe (the subscribe property) in client.store.ts
to include a JSDoc block above it describing that subscribe is a public method
on the client, the expected listener callback signature (e.g., receives the
current client state or change), that it returns an unsubscribe function, and
any edge cases (immediate vs. deferred invocation). Target the subscribe
property being assigned to store.subscribe so the docs live next to the public
API surface.
packages/journey-client/api-report/journey-client.types.api.md (1)

184-184: ⚡ Quick win

Consider using the Unsubscribe type for consistency with oidc-client.

The oidc-client package imports and uses Unsubscribe from @reduxjs/toolkit for its subscribe method return type (see packages/oidc-client/api-report/oidc-client.types.api.md line 261), while journey-client uses the generic () => void. Since both packages expose Redux store subscriptions, using the semantic Unsubscribe type consistently across both clients improves API clarity and maintainability.

📝 Suggested alignment

Import the type in your source file:

+import type { Unsubscribe } from '@reduxjs/toolkit';

Then update the interface:

-subscribe: (listener: () => void) => () => void;
+subscribe: (listener: () => void) => Unsubscribe;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/journey-client/api-report/journey-client.types.api.md` at line 184,
The subscribe signature currently uses a raw function type; change it to use the
semantic Unsubscribe type from `@reduxjs/toolkit` for consistency with
oidc-client: import Unsubscribe from '@reduxjs/toolkit' (or from the same place
oidc-client uses) and update the subscribe declaration from subscribe:
(listener: () => void) => () => void to subscribe: (listener: () => void) =>
Unsubscribe so the return type is the named Unsubscribe type.
packages/journey-client/src/lib/client.store.test.ts (1)

111-111: Consider testing the subscription functionality, not just existence.

The test verifies that subscribe is a function but doesn't confirm that it actually notifies listeners on state changes or that the returned unsubscribe function works. The oidc-client test (line 140-141) goes one step further by verifying the unsubscribe return value.

💡 Suggested enhancement
 expect(client.subscribe).toBeInstanceOf(Function);
+const listener = vi.fn();
+const unsubscribe = client.subscribe(listener);
+expect(unsubscribe).toBeInstanceOf(Function);
+// Optionally: trigger a state change and verify listener was called
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/journey-client/src/lib/client.store.test.ts` at line 111, The test
currently only asserts client.subscribe is a Function; enhance it to verify
subscription behavior by subscribing a mock listener (e.g., const listener =
jest.fn()) via client.subscribe(listener), trigger a state change using the
store update method used elsewhere in tests (e.g., client.setState(...) or
client.update(...)/client.set(...)), assert listener was called with the new
state, capture the return value from client.subscribe and call it to
unsubscribe, then trigger another state change and assert listener was not
called again; reference client.subscribe and the store's state mutation method
to locate the code to change.
packages/oidc-client/src/lib/client.store.test.ts (1)

132-142: Consider verifying that listeners are notified on state changes.

The test confirms that subscribe returns an unsubscribe function, which is good. For additional confidence, you could trigger a store action and verify the listener is called, though the current test provides reasonable coverage for the direct delegation to store.subscribe.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/oidc-client/src/lib/client.store.test.ts` around lines 132 - 142,
Add an assertion that listeners are notified when the store changes: create a
mock listener (vi.fn()), subscribe it via oidcClient.subscribe, trigger a
store-changing method on the client (for example call a method that updates
state such as saveClient or setToken on oidcClient), assert the mock listener
was called, then call the returned unsubscribe and optionally assert it is a
function; use the existing oidc, oidcClient and subscribe identifiers to locate
where to add this behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/journey-client/api-report/journey-client.api.md`:
- Line 197: Add JSDoc for the public subscribe method to replace the
"(undocumented)" tag: document purpose (listening to store state changes),
describe when the listener is invoked (after state updates), specify the
listener signature and how to access the current state from the provided
callback (e.g., receives state or a selector), and explain that subscribe
returns an unsubscribe function that removes the listener when called; apply
this to the subscribe method declaration so consumers see purpose, invocation
timing, parameter details, and that the return value is a cleanup function.
- Line 197: The subscribe method currently returns a bare () => void; change its
return type to use the Unsubscribe type (imported from `@reduxjs/toolkit`) for
consistency with oidc-client — update the method signature for subscribe (and
any related types/exports) to import Unsubscribe and annotate the return type as
Unsubscribe so callers and API docs match oidc-client.

In `@packages/journey-client/api-report/journey-client.types.api.md`:
- Line 184: The subscribe signature currently uses a raw function type; change
it to use the semantic Unsubscribe type from `@reduxjs/toolkit` for consistency
with oidc-client: import Unsubscribe from '@reduxjs/toolkit' (or from the same
place oidc-client uses) and update the subscribe declaration from subscribe:
(listener: () => void) => () => void to subscribe: (listener: () => void) =>
Unsubscribe so the return type is the named Unsubscribe type.

In `@packages/journey-client/src/lib/client.store.test.ts`:
- Line 111: The test currently only asserts client.subscribe is a Function;
enhance it to verify subscription behavior by subscribing a mock listener (e.g.,
const listener = jest.fn()) via client.subscribe(listener), trigger a state
change using the store update method used elsewhere in tests (e.g.,
client.setState(...) or client.update(...)/client.set(...)), assert listener was
called with the new state, capture the return value from client.subscribe and
call it to unsubscribe, then trigger another state change and assert listener
was not called again; reference client.subscribe and the store's state mutation
method to locate the code to change.

In `@packages/journey-client/src/lib/client.store.ts`:
- Line 39: The subscribe method signature currently uses a generic () => void
return type; replace that with the Redux Toolkit Unsubscribe type to match other
clients: import Unsubscribe from '@reduxjs/toolkit' (or import { Unsubscribe }
if needed) and change the signature on subscribe (the subscribe declaration in
client.store.ts) from subscribe: (listener: () => void) => () => void to
subscribe: (listener: () => void) => Unsubscribe so the type is consistent with
oidc-client and provides clearer docs.

In `@packages/oidc-client/src/lib/client.store.test.ts`:
- Around line 132-142: Add an assertion that listeners are notified when the
store changes: create a mock listener (vi.fn()), subscribe it via
oidcClient.subscribe, trigger a store-changing method on the client (for example
call a method that updates state such as saveClient or setToken on oidcClient),
assert the mock listener was called, then call the returned unsubscribe and
optionally assert it is a function; use the existing oidc, oidcClient and
subscribe identifiers to locate where to add this behavior.

In `@packages/oidc-client/src/lib/client.store.ts`:
- Around line 98-99: Add JSDoc for the newly exported public subscribe method so
developers understand the subscription pattern, listener signature, and how to
unsubscribe: update the object that passes store.subscribe (the subscribe
property) in client.store.ts to include a JSDoc block above it describing that
subscribe is a public method on the client, the expected listener callback
signature (e.g., receives the current client state or change), that it returns
an unsubscribe function, and any edge cases (immediate vs. deferred invocation).
Target the subscribe property being assigned to store.subscribe so the docs live
next to the public API surface.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ac2a5978-f319-4dae-aa1b-9b2a551ee5d1

📥 Commits

Reviewing files that changed from the base of the PR and between 207e275 and 6519fcc.

📒 Files selected for processing (9)
  • .changeset/export-subscribe-method.md
  • packages/journey-client/api-report/journey-client.api.md
  • packages/journey-client/api-report/journey-client.types.api.md
  • packages/journey-client/src/lib/client.store.test.ts
  • packages/journey-client/src/lib/client.store.ts
  • packages/oidc-client/api-report/oidc-client.api.md
  • packages/oidc-client/api-report/oidc-client.types.api.md
  • packages/oidc-client/src/lib/client.store.test.ts
  • packages/oidc-client/src/lib/client.store.ts

Copy link
Copy Markdown
Contributor

@nx-cloud nx-cloud Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nx Cloud has identified a possible root cause for your failed CI:

We reviewed all failing tasks and none are related to the changes introduced in this PR. The OIDC and protect suite failures are caused by an external PingAM/Forgeblocks service returning invalid request errors, confirmed as a pre-existing issue also present in branch 618. The api-report timeout is a local environment timing issue unrelated to the subscribe method additions.

No code changes were suggested for this issue.

Trigger a rerun:

Rerun CI

Nx Cloud View detailed reasoning on Nx Cloud ↗


🎓 Learn more about Self-Healing CI on nx.dev

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant