Description:
Implement the ChangeDetector module and the foundational RolloutStateMachine. This slice establishes the core continuous polling mechanism using a recursive setTimeout loop that checks for configuration changes via If-None-Match (ETag) HTTP headers. To prevent cluster thundering herds, the polling interval must apply a +/- 15% randomized jitter. Update the BaseOptions API contract to accept pollIntervalMs, disableHotReload, and the onChange callback. When a change (200 OK) is detected, the SDK should deliver the payload directly to the onChange callback and update its internal ETag state.
Acceptance criteria
Blocked by:
None - can start immediately
User stories covered: 1, 2, 3, 10
Description:
Implement the ChangeDetector module and the foundational RolloutStateMachine. This slice establishes the core continuous polling mechanism using a recursive setTimeout loop that checks for configuration changes via If-None-Match (ETag) HTTP headers. To prevent cluster thundering herds, the polling interval must apply a +/- 15% randomized jitter. Update the BaseOptions API contract to accept pollIntervalMs, disableHotReload, and the onChange callback. When a change (200 OK) is detected, the SDK should deliver the payload directly to the onChange callback and update its internal ETag state.
Acceptance criteria
BaseOptions accepts the new parameters (pollIntervalMs, disableHotReload, onChange).
Passing disableHotReload: true completely disables the polling loop.
The polling mechanism uses recursive setTimeout with +/- 15% randomized jitter (verified via vi.useFakeTimers()).
Detecting a 200 OK response successfully triggers the onChange callback with the new configuration.
Blocked by:
None - can start immediately
User stories covered: 1, 2, 3, 10