sdk comments

This commit is contained in:
Matt Hill
2026-02-05 08:10:53 -07:00
parent 58e0b166cb
commit 9519684185
37 changed files with 3603 additions and 150 deletions

View File

@@ -1,5 +1,26 @@
import { HealthStatus } from "../../../base/lib/types"
/**
* Input state provided to trigger functions.
* Contains information about the health check's current state
* that triggers can use to adjust their timing behavior.
*
* @example
* ```typescript
* const myTrigger: Trigger = (getInput) => {
* return (async function* () {
* while (true) {
* const input: TriggerInput = getInput()
* // Check more frequently if last result was failure
* const delay = input.lastResult === 'failure' ? 1000 : 30000
* await new Promise(r => setTimeout(r, delay))
* yield
* }
* })()
* }
* ```
*/
export type TriggerInput = {
/** The result of the most recent health check execution, if any */
lastResult?: HealthStatus
}

View File

@@ -1,5 +1,35 @@
import { Trigger } from "./index"
/**
* Creates a trigger that uses different timing before and after the first successful health check.
*
* This is useful for services that need frequent checks during startup (to quickly report
* when they become healthy) but can reduce check frequency once they're running stably.
*
* The trigger switches permanently to `afterFirstSuccess` timing once a success is seen.
* It does NOT switch back even if the service later becomes unhealthy.
*
* @param o.beforeFirstSuccess - Trigger to use until the first successful health check
* @param o.afterFirstSuccess - Trigger to use after the first successful health check
* @returns A composite trigger that switches behavior after first success
*
* @example
* ```typescript
* // Check every second while starting, every 30 seconds once healthy
* const trigger = changeOnFirstSuccess({
* beforeFirstSuccess: cooldownTrigger(1000), // 1s while starting
* afterFirstSuccess: cooldownTrigger(30000) // 30s after healthy
* })
*
* // Use in a health check
* daemons.addHealthCheck({
* id: 'main',
* name: 'Main Health',
* trigger,
* fn: checkServiceHealth
* })
* ```
*/
export function changeOnFirstSuccess(o: {
beforeFirstSuccess: Trigger
afterFirstSuccess: Trigger

View File

@@ -1,3 +1,25 @@
/**
* Creates a simple timer-based trigger that fires at regular intervals.
* This is the most basic trigger type - it just waits the specified
* time between each health check.
*
* @param timeMs - Interval between health checks in milliseconds
* @returns A trigger factory function
*
* @example
* ```typescript
* // Check health every 5 seconds
* const trigger = cooldownTrigger(5000)
*
* // Use in a health check
* daemons.addHealthCheck({
* id: 'main',
* name: 'Main Check',
* trigger: cooldownTrigger(10000), // Every 10 seconds
* fn: async () => ({ result: 'success', message: 'OK' })
* })
* ```
*/
export function cooldownTrigger(timeMs: number) {
return async function* () {
while (true) {

View File

@@ -1,6 +1,35 @@
import { cooldownTrigger } from "./cooldownTrigger"
import { changeOnFirstSuccess } from "./changeOnFirstSuccess"
/**
* The default trigger used when no custom trigger is specified for a health check.
*
* Provides sensible defaults for most services:
* - **Before first success**: Checks every 1 second (rapid during startup)
* - **After first success**: Checks every 30 seconds (stable once healthy)
*
* This trigger is automatically used by `Daemons.addDaemon()` and `Daemons.addHealthCheck()`
* when no `trigger` option is provided.
*
* @example
* ```typescript
* // These are equivalent - both use defaultTrigger
* daemons.addHealthCheck({
* id: 'main',
* name: 'Main',
* fn: checkHealth
* // trigger: defaultTrigger // implicit
* })
*
* // Custom trigger overrides the default
* daemons.addHealthCheck({
* id: 'main',
* name: 'Main',
* trigger: cooldownTrigger(5000), // Check every 5s instead
* fn: checkHealth
* })
* ```
*/
export const defaultTrigger = changeOnFirstSuccess({
beforeFirstSuccess: cooldownTrigger(1000),
afterFirstSuccess: cooldownTrigger(30000),

View File

@@ -1,7 +1,57 @@
/**
* @module trigger
*
* Triggers control when health checks are executed. They are async generators
* that yield when a health check should run. This allows fine-grained control
* over check frequency based on the service's current state.
*
* Built-in triggers:
* - `cooldownTrigger(ms)` - Simple timer-based trigger
* - `changeOnFirstSuccess` - Different timing before/after first successful check
* - `successFailure` - Different timing based on success/failure state
* - `lastStatus` - Configurable timing per health status
*
* @example
* ```typescript
* // Check every 5 seconds
* const trigger = cooldownTrigger(5000)
*
* // Fast checks until healthy, then slow down
* const adaptiveTrigger = changeOnFirstSuccess({
* beforeFirstSuccess: cooldownTrigger(1000), // 1s while starting
* afterFirstSuccess: cooldownTrigger(30000) // 30s once healthy
* })
* ```
*/
import { TriggerInput } from "./TriggerInput"
export { changeOnFirstSuccess } from "./changeOnFirstSuccess"
export { cooldownTrigger } from "./cooldownTrigger"
/**
* A trigger function that controls when health checks execute.
*
* Triggers are async generator factories. Given a function to get the current
* input state (e.g., last health result), they return an async iterator that
* yields when a health check should run.
*
* @param getInput - Function returning the current trigger input state
* @returns An async iterator that yields when a check should run
*
* @example
* ```typescript
* // Custom trigger that checks every 10s during success, 2s during failure
* const myTrigger: Trigger = (getInput) => {
* return (async function* () {
* while (true) {
* const { lastResult } = getInput()
* const delay = lastResult === 'success' ? 10000 : 2000
* await new Promise(r => setTimeout(r, delay))
* yield
* }
* })()
* }
* ```
*/
export type Trigger = (
getInput: () => TriggerInput,
) => AsyncIterator<unknown, unknown, never>

View File

@@ -1,10 +1,39 @@
import { Trigger } from "."
import { HealthStatus } from "../../../base/lib/types"
/**
* Configuration for status-based trigger selection.
* Maps health statuses to triggers, with a required default fallback.
*/
export type LastStatusTriggerParams = { [k in HealthStatus]?: Trigger } & {
/** Trigger to use when no status-specific trigger is defined */
default: Trigger
}
/**
* Creates a trigger that dynamically selects timing based on the last health check result.
*
* This allows different check frequencies for each health status:
* - `success` - When the service is healthy
* - `failure` - When the service is unhealthy
* - `starting` - When the service is still starting up
*
* Uses the `default` trigger for any status not explicitly configured.
*
* @param o - Map of health statuses to triggers, plus a required default
* @returns A composite trigger that adapts to the current health status
*
* @example
* ```typescript
* // Check frequently during failure, rarely during success
* const adaptiveTrigger = lastStatus({
* success: cooldownTrigger(60000), // 60s when healthy
* failure: cooldownTrigger(5000), // 5s when unhealthy
* starting: cooldownTrigger(2000), // 2s while starting
* default: cooldownTrigger(10000) // 10s fallback
* })
* ```
*/
export function lastStatus(o: LastStatusTriggerParams): Trigger {
return async function* (getInput) {
let trigger = o.default(getInput)

View File

@@ -1,6 +1,26 @@
import { Trigger } from "."
import { lastStatus } from "./lastStatus"
/**
* Creates a trigger with different timing for success vs failure/starting states.
*
* This is a simplified wrapper around `lastStatus` for the common case
* where you want one timing during healthy operation and another during
* any error condition (failure or starting).
*
* @param o.duringSuccess - Trigger to use when the last check succeeded
* @param o.duringError - Trigger to use for failure, starting, or unknown states
* @returns A composite trigger that adapts to success/failure state
*
* @example
* ```typescript
* // Check every minute when healthy, every 5 seconds when unhealthy
* const trigger = successFailure({
* duringSuccess: cooldownTrigger(60000), // 1 minute
* duringError: cooldownTrigger(5000) // 5 seconds
* })
* ```
*/
export const successFailure = (o: {
duringSuccess: Trigger
duringError: Trigger