Hyperlinkv0.8.0-beta.28

Polling

Polling.acceleratingconstsrc/Polling.ts:355
(config: AcceleratingConfig): Layer.Layer<PollingTag>

Exponentially accelerating poll cadence. Starts slow (at slowest), speeds up toward fastest as iterations increase. resetCadence resets to iteration 0.

presets
Source src/Polling.ts:35565 lines
export const accelerating = (
  config: AcceleratingConfig
): Layer.Layer<PollingTag> => {
  const fastestMs = Duration.toMillis(Duration.fromInputUnsafe(config.fastest));
  const slowestMs = Math.max(
    fastestMs,
    Duration.toMillis(Duration.fromInputUnsafe(config.slowest))
  );
  const decay = config.decay ?? 0.3;
  const excitement = config.excitement ?? 1;

  return registerPollingLayer(
    Layer.effect(
      PollingTag,
      Effect.gen(function* () {
        const iterationRef = yield* Ref.make(0);
        const wakeRef = yield* Ref.make<Deferred.Deferred<void, never>>(
          Deferred.makeUnsafe()
        );

        const awaitNextTick: Effect.Effect<void> = Effect.gen(function* () {
          const d = Deferred.makeUnsafe<void, never>();
          yield* Ref.set(wakeRef, d);
          const n = yield* Ref.get(iterationRef);
          const ms = delayMsForIteration(
            fastestMs,
            slowestMs,
            decay,
            excitement,
            n
          );
          yield* Effect.race(
            Effect.sleep(Duration.millis(ms)),
            Deferred.await(d)
          ).pipe(Effect.asVoid);
        });

        const requestWake = Effect.flatMap(Ref.get(wakeRef), (d) =>
          Deferred.succeed(d, undefined)
        ).pipe(Effect.asVoid);

        const resetCadence = Ref.set(iterationRef, 0).pipe(
          Effect.andThen(requestWake)
        );
        const afterTick = Ref.update(iterationRef, (n) => n + 1);

        const peekCadence = Effect.map(Ref.get(iterationRef), (n) =>
          Option.some(
            Duration.millis(
              delayMsForIteration(fastestMs, slowestMs, decay, excitement, n)
            )
          )
        );

        return {
          awaitNextTick,
          requestWake,
          resetCadence,
          afterTick,
          peekCadence,
        } satisfies PollingService;
      })
    )
  );
};