IS-11380 HaapiStepper: own bootstrap config and the haapiFetch lifecycle#207
Conversation
luisgoncalves
left a comment
There was a problem hiding this comment.
Looks good 👍
Added a couple of comments that I think need attention.
| import { handleAuthenticationOrRegistrationStep } from './step-handlers/authentication-or-registration-step'; | ||
|
|
||
| const DEFAULT_CONFIG: Required<HaapiStepperConfig> = { | ||
| bootstrap: configuration, |
There was a problem hiding this comment.
This comes from the import from bootstrap-configuration, which eagerly checks for window.__CONFIG__ to be present and bombs if not.
In a scenario where the consumer wants to override, it would still bomb, right?
Since configResult is already memoized, perhaps we could build it slightly differently, and only load the bootstrap config if one was not provided via prop? We may need to expose a function to load window config, instead.
There was a problem hiding this comment.
Very good catch, thanks 🙏 ! I just pushed a refactor that decouples app and library configuration consumption and polishes the standalone (library) mode:
- Two configuration modes are first-class: served (LWA default — reads window.CONFIG) and standalone (library — consumer passes config.bootstrap). The window.CONFIG read is lazy now (inside resolveStepperConfig), so the override prop is actually reachable from third-party apps.
- Missing config on both sides → actionable error at first render naming both recovery paths.
There was a problem hiding this comment.
Pull request overview
Makes HaapiStepper's bootstrap (initial URL + HAAPI config) overridable via the config prop and replaces the module-load haapi-fetch-initializer singleton with a useHaapiFetch hook that caches a single fetcher to survive React StrictMode's double-invoke. Also refactors processHaapiNextStep to take a single named-params object.
Changes:
- Introduce
useHaapiFetchhook + cachedFetchLike; thread the fetcher explicitly throughsendHaapiFetchRequest; deletehaapi-fetch-initializer.ts. - Move
HaapiStepperConfigintohaapi-stepper.types.ts, addbootstrap: BootstrapConfigurationto it, and use it both for defaults and viaPartial<HaapiStepperConfig>on the props. - Refactor
processHaapiNextStepto a single params object and update recursive call sites and tests accordingly.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/login-web-app/src/haapi-stepper/data-access/useHaapiFetch.ts | New hook that builds/caches the HAAPI fetcher and returns a bound sendHaapiFetchRequest. |
| src/login-web-app/src/haapi-stepper/data-access/useHaapiFetch.spec.ts | New tests verifying fetcher creation and link/form request forwarding. |
| src/login-web-app/src/haapi-stepper/data-access/happi-fetch-request.ts | sendHaapiFetchRequest now takes the FetchLike as a parameter instead of importing the singleton. |
| src/login-web-app/src/haapi-stepper/data-access/haapi-fetch-initializer.ts | Removed; replaced by useHaapiFetch. |
| src/login-web-app/src/haapi-stepper/data-access/index.ts | Re-export the new useHaapiFetch hook. |
| src/login-web-app/src/haapi-stepper/feature/stepper/HaapiStepper.tsx | Wire useHaapiFetch, use bootstrap from merged config for initial URL, refactor processHaapiNextStep to a params object. |
| src/login-web-app/src/haapi-stepper/feature/stepper/haapi-stepper.types.ts | Move HaapiStepperConfig here and add bootstrap: BootstrapConfiguration. |
| src/login-web-app/src/haapi-stepper/feature/stepper/data-formatters/polling-step.ts | Import HaapiStepperConfig from its new location. |
| src/login-web-app/src/haapi-stepper/feature/stepper/step-handlers/authentication-or-registration-step.ts | Same import-source update. |
| src/login-web-app/src/haapi-stepper/feature/stepper/step-handlers/completed-with-success-step.ts | Same import-source update. |
| src/login-web-app/src/haapi-stepper/feature/stepper/HaapiStepper.spec.tsx | Mock @curity/identityserver-haapi-web-driver directly, add haapi to mock bootstrap, add override-bootstrap test. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| let cachedHaapiFetch: FetchLike | undefined; | ||
|
|
||
| function getHaapiFetch(haapi: HaapiConfiguration): FetchLike { | ||
| return (cachedHaapiFetch ??= createHaapiFetch(haapi)); | ||
| } | ||
|
|
||
| export function useHaapiFetch(haapi: HaapiConfiguration) { | ||
| const haapiFetch = useMemo(() => getHaapiFetch(haapi), [haapi]); |
…cle.
- Add bootstrap: BootstrapConfiguration to HaapiStepperConfig (single
field, defaults to the module-level configuration singleton). Override
via <HaapiStepper config={{ bootstrap }}>.
- Introduce useHaapiFetch(haapi) hook in data-access/. Owns the
haapiFetch lifecycle via a module-level single-slot cache (driver is a
process-global, one active fetcher per page). Returns a bound
sendHaapiFetchRequest.
- sendHaapiFetchRequest(action, haapiFetch: FetchLike) becomes pure.
haapi-fetch-initializer.ts removed.
- Move HaapiStepperConfig to haapi-stepper.types.ts (CONFIG TYPINGS).
- Refactor processHaapiNextStep to a single named-params object.
- Re-export useHaapiFetch from data-access/index.ts.
- Tests: new useHaapiFetch.spec.ts (binding to config, link routing,
form routing); new bootstrap-override case in HaapiStepper.spec.tsx.
…standalone-mode support. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6e9cfc6 to
5319c8b
Compare
Jira: https://curity.atlassian.net/browse/IS-11380
Summary
HaapiStepper's bootstrap config (initial URL + HAAPI config) is now overridable via theconfigprop. Apps can pass their own<HaapiStepper config={{ bootstrap }}>; omitting it keeps the previous behaviour (the module-levelconfigurationsingleton fromwindow.__CONFIG__).haapi-fetch-initializer.tssingleton with a newuseHaapiFetchhook. It builds the HAAPI fetcher from the supplied config and returns a ready-to-callsendHaapiFetchRequest.Already disposederrors during dev.processHaapiNextStepnow takes a single named-params object instead of eight positional arguments — easier to read and to extend.