Primitives / foldkit-primitives/time

debounce

function · packages/primitives/src/time/debounce.ts:14

function debounce<const Name extends string, Value>(config: {
  readonly name: Name
  readonly value: Schema.Codec<Value, unknown>
}): Bundle.Bundle<
  Name,
  { readonly delayMs: number },
  { readonly latest: Value | null; readonly generation: number },
  | { readonly _tag: 'Changed'; readonly value: Value }
  | {
      readonly _tag: 'Settled'
      readonly value: Value
      readonly generation: number
    },
  { readonly _tag: 'Debounced'; readonly value: Value },
  never,
  never,
  void,
  {},
  {}
> & {
  Message: MessageUnion<{
    readonly Changed: {
      readonly value: Schema.Codec<Value, unknown, never, never>
    }
    readonly Settled: {
      readonly value: Schema.Codec<Value, unknown, never, never>
      readonly generation: Schema.Number
    }
  }>
  Debounced: Schema.TaggedStruct<
    'Debounced',
    { readonly value: Schema.Codec<Value, unknown, never, never> }
  >
}

Debounced input as a bundle factory: Changed restarts a timer, and the latest value settles as an OutMessage the placement must handle with onOut. Each Changed bumps a generation carried by the Settled fact it schedules, so a superseded timer's fact emits nothing — the same guard as Presence's exit timeout. Generic over the value Schema, like History. The clock is Effect's, so tests drive it with TestClock.