@systemfsoftware/effect-daemon-spec 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import { Cause, Context, Duration, Effect, Layer, Metric, Option, Schedule, Schema, Scope, Stream } from "effect";
2
-
3
2
  //#region src/backoff.d.ts
4
3
  declare const cappedBackoff: (base: Duration.DurationInput, cap: Duration.DurationInput) => Schedule.Schedule<Duration.Duration>;
5
4
  //#endregion
@@ -80,12 +79,12 @@ declare const ChildPolicyConfig_base: Schema.Class<ChildPolicyConfig, {
80
79
  window: typeof Schema.DurationFromSelf;
81
80
  }>>;
82
81
  }>, never, {
82
+ readonly restart?: "permanent" | "transient" | "temporary" | undefined;
83
+ } & {
83
84
  readonly intensity?: {
84
85
  readonly restarts: number;
85
86
  readonly window: import("effect/Duration").Duration;
86
87
  } | undefined;
87
- } & {
88
- readonly restart?: "permanent" | "temporary" | "transient" | undefined;
89
88
  }, {}, {}>;
90
89
  declare class ChildPolicyConfig extends ChildPolicyConfig_base {}
91
90
  declare const LockPolicyConfig_base: Schema.Class<LockPolicyConfig, {
@@ -95,9 +94,9 @@ declare const LockPolicyConfig_base: Schema.Class<LockPolicyConfig, {
95
94
  mode: Schema.optional<Schema.Literal<["none", "required", "optional"]>>;
96
95
  key: Schema.optional<typeof Schema.String>;
97
96
  }>, never, {
98
- readonly key?: string | undefined;
97
+ readonly mode?: "none" | "required" | "optional" | undefined;
99
98
  } & {
100
- readonly mode?: "none" | "optional" | "required" | undefined;
99
+ readonly key?: string | undefined;
101
100
  }, {}, {}>;
102
101
  declare class LockPolicyConfig extends LockPolicyConfig_base {}
103
102
  declare const TickPolicyConfig_base: Schema.Class<TickPolicyConfig, {
@@ -109,11 +108,11 @@ declare const TickPolicyConfig_base: Schema.Class<TickPolicyConfig, {
109
108
  tickTimeout: typeof Schema.DurationFromSelf;
110
109
  startLogLevel: Schema.optional<Schema.Literal<["debug", "info"]>>;
111
110
  }>, never, {
111
+ readonly tickTimeout: import("effect/Duration").Duration;
112
+ } & {
112
113
  readonly spanName?: string | undefined;
113
114
  } & {
114
115
  readonly startLogLevel?: "debug" | "info" | undefined;
115
- } & {
116
- readonly tickTimeout: import("effect/Duration").Duration;
117
116
  }, {}, {}>;
118
117
  declare class TickPolicyConfig extends TickPolicyConfig_base {}
119
118
  //#endregion
@@ -244,9 +243,13 @@ declare const subscription: <A, E, R, L extends LockConfig>(opts: CommonOpts<L>
244
243
  readonly acquire: Effect.Effect<A, E, R>;
245
244
  }) => Worker<E, R, L>;
246
245
  declare const Daemon: {
247
- readonly poll: typeof poll;
248
- readonly stream: typeof stream;
249
- readonly subscription: typeof subscription;
246
+ readonly poll: <A, E, R, L extends LockConfig>(opts: PollOpts<A, E, R, L>) => Worker<E, R, L>;
247
+ readonly stream: <A, E, R, L extends LockConfig>(opts: CommonOpts<L> & {
248
+ readonly stream: Stream.Stream<A, E, R>;
249
+ }) => Worker<E, R, L>;
250
+ readonly subscription: <A, E, R, L extends LockConfig>(opts: CommonOpts<L> & {
251
+ readonly acquire: Effect.Effect<A, E, R>;
252
+ }) => Worker<E, R, L>;
250
253
  };
251
254
  //#endregion
252
255
  //#region src/leader-lock.schema.d.ts
@@ -308,11 +311,10 @@ declare function supervisor<E, R>(s: Supervisor<E, R, {
308
311
  mode: 'none';
309
312
  }>): Effect.Effect<SupervisorHealth, never, R | DaemonReporter | Scope.Scope>;
310
313
  declare function supervisor<E, R>(s: Supervisor<E, R, LockConfig>): Effect.Effect<SupervisorHealth, never, R | LeaderLock | DaemonReporter | Scope.Scope>;
311
- declare const dynamic$1: <E, R, Args>(spec: DynamicSpec<E, R, Args>) => Effect.Effect<DynamicHandle<Args, R | LeaderLock | DaemonReporter | Scope.Scope>, never, R | LeaderLock | DaemonReporter | Scope.Scope>;
312
314
  declare const run: {
313
315
  readonly worker: typeof worker;
314
316
  readonly supervisor: typeof supervisor;
315
- readonly dynamic: typeof dynamic$1;
317
+ readonly dynamic: <E, R, Args>(spec: DynamicSpec<E, R, Args>) => Effect.Effect<DynamicHandle<Args, R | LeaderLock | DaemonReporter | Scope.Scope>, never, R | LeaderLock | DaemonReporter | Scope.Scope>;
316
318
  };
317
319
  //#endregion
318
320
  //#region src/supervisor.d.ts
package/dist/index.mjs CHANGED
@@ -73,15 +73,19 @@ const make$1 = (common, loop) => ({
73
73
  lock: common.lock
74
74
  });
75
75
  const poll = (opts) => {
76
- if (typeof opts.prereq === "undefined") return make$1(opts, {
77
- _tag: "Poll",
78
- gate: Effect.succeed(Option.some(Effect.asVoid(opts.work))),
79
- interval: opts.interval
80
- });
76
+ if (typeof opts.prereq === "undefined") {
77
+ const gate = Effect.succeed(Option.some(Effect.asVoid(opts.work)));
78
+ return make$1(opts, {
79
+ _tag: "Poll",
80
+ gate,
81
+ interval: opts.interval
82
+ });
83
+ }
81
84
  const { prereq, work } = opts;
85
+ const gate = Effect.map(prereq, Option.map((data) => work(data)));
82
86
  return make$1(opts, {
83
87
  _tag: "Poll",
84
- gate: Effect.map(prereq, Option.map((data) => work(data))),
88
+ gate,
85
89
  interval: opts.interval
86
90
  });
87
91
  };
@@ -165,10 +169,12 @@ const boundedTracker = (restarts, window) => Effect.gen(function* () {
165
169
  yield* Ref.update(timestamps, (ts) => recordTimestamp(ts, now, windowMillis));
166
170
  }),
167
171
  isExceeded: Effect.gen(function* () {
168
- return exceedsRestarts((yield* prune(yield* Clock.currentTimeMillis)).length, restarts);
172
+ const now = yield* Clock.currentTimeMillis;
173
+ return exceedsRestarts((yield* prune(now)).length, restarts);
169
174
  }),
170
175
  count: Effect.gen(function* () {
171
- return (yield* prune(yield* Clock.currentTimeMillis)).length;
176
+ const now = yield* Clock.currentTimeMillis;
177
+ return (yield* prune(now)).length;
172
178
  })
173
179
  };
174
180
  });
@@ -284,7 +290,7 @@ const superviseChild = (ctx, child, idx) => Effect.gen(function* () {
284
290
  });
285
291
  const loop = () => Effect.gen(function* () {
286
292
  const supIntensity = yield* make(ctx.policy.intensity);
287
- const epochResult = yield* runSupervisionEpochWithBackoff(Effect.gen(function* () {
293
+ const attempt = Effect.gen(function* () {
288
294
  yield* ctx.health.paused.await;
289
295
  const fiber = yield* Effect.forkScoped(child.run);
290
296
  const exit = yield* Fiber.await(fiber);
@@ -308,7 +314,8 @@ const superviseChild = (ctx, child, idx) => Effect.gen(function* () {
308
314
  return yield* Match.value(decision).pipe(Match.tag("Continue", () => Effect.succeed(new StopEpoch())), Match.tag("Exhausted", () => handleExhausted(ctx, exit.cause)), Match.tag("Restart", () => handleRestart(ctx, exit.cause, Effect.void)), Match.exhaustive);
309
315
  }
310
316
  return new StopEpoch();
311
- }), ctx);
317
+ });
318
+ const epochResult = yield* runSupervisionEpochWithBackoff(attempt, ctx);
312
319
  return yield* Match.value(epochResult).pipe(Match.tag("ContinueSupervision", () => loop()), Match.tag("StopSupervision", () => Effect.void), Match.exhaustive);
313
320
  });
314
321
  return yield* loop();
@@ -327,7 +334,7 @@ const runGroup = (strategy, ctx) => Effect.gen(function* () {
327
334
  onSome: (cfg) => Effect.map(make(new BoundedIntensity(cfg)), Option.some)
328
335
  }));
329
336
  const cursor = yield* Ref.make(0);
330
- const epochResult = yield* runSupervisionEpochWithBackoff(Effect.gen(function* () {
337
+ const attempt = Effect.gen(function* () {
331
338
  yield* ctx.health.paused.await;
332
339
  const startIdx = yield* Ref.get(cursor);
333
340
  const slice = ctx.booted.slice(startIdx);
@@ -359,7 +366,8 @@ const runGroup = (strategy, ctx) => Effect.gen(function* () {
359
366
  return yield* Match.value(decision).pipe(Match.tag("Continue", () => Effect.succeed(new StopEpoch())), Match.tag("Exhausted", () => handleExhausted(ctx, firstExit.cause)), Match.tag("Restart", (restartDecision) => handleRestart(ctx, firstExit.cause, Ref.set(cursor, restartDecision.indices[0]))), Match.exhaustive);
360
367
  }
361
368
  return new StopEpoch();
362
- }), ctx);
369
+ });
370
+ const epochResult = yield* runSupervisionEpochWithBackoff(attempt, ctx);
363
371
  return yield* Match.value(epochResult).pipe(Match.tag("ContinueSupervision", () => loop()), Match.tag("StopSupervision", () => Effect.void), Match.exhaustive);
364
372
  });
365
373
  return yield* loop();
@@ -463,15 +471,17 @@ const buildStreamLoop = (worker, loop, health) => {
463
471
  yield* Effect.raceFirst(ready, Fiber.join(fiber));
464
472
  yield* Fiber.join(fiber);
465
473
  });
466
- return wrapSpan(worker, applyInnerRetry(worker.tickHooks)(body).pipe(Effect.asVoid));
474
+ const retried = applyInnerRetry(worker.tickHooks)(body);
475
+ return wrapSpan(worker, retried.pipe(Effect.asVoid));
467
476
  };
468
477
  const buildSubscriptionLoop = (worker, loop, health) => {
469
- return wrapSpan(worker, Effect.gen(function* () {
478
+ const body = Effect.gen(function* () {
470
479
  yield* health.paused.await;
471
480
  yield* applyTimeout(worker.tick)(loop.acquire);
472
481
  yield* Effect.zipRight(health.ready.open, Metric.set(Metric.tagged(Metric.tagged(healthStateGauge, "daemon", health.name), "latch", "ready"), 1));
473
482
  return yield* Effect.never;
474
- }).pipe(Effect.asVoid));
483
+ });
484
+ return wrapSpan(worker, body.pipe(Effect.asVoid));
475
485
  };
476
486
  const buildWorkerLoop = (worker, health) => Match.value(worker.loop).pipe(Match.tag("Poll", (loop) => buildPollLoop(worker, loop, health)), Match.tag("Stream", (loop) => buildStreamLoop(worker, loop, health)), Match.tag("Subscription", (loop) => buildSubscriptionLoop(worker, loop, health)), Match.exhaustive);
477
487
  //#endregion
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@systemfsoftware/effect-daemon-spec",
3
3
  "license": "MIT",
4
- "version": "0.1.1",
4
+ "version": "0.2.0",
5
5
  "author": "Ryan Lee <drdgvhbh@gmail.com>",
6
6
  "repository": {
7
7
  "type": "git",
@@ -37,23 +37,22 @@
37
37
  "dist"
38
38
  ],
39
39
  "devDependencies": {
40
- "@effect/vitest": "0.29.0",
40
+ "@effect/vitest": "0.30.0",
41
41
  "@microsoft/api-extractor": "^7.58.7",
42
- "@stryker-mutator/core": "^9.6.1",
43
- "@stryker-mutator/typescript-checker": "^9.6.1",
44
42
  "@stryker-mutator/vitest-runner": "^9.6.1",
45
43
  "@types/node": "^24",
46
44
  "@vitest/coverage-v8": "^4",
47
- "effect": "^3.21.2",
45
+ "effect": "^3.22.0",
48
46
  "fast-check": "^3",
49
47
  "rimraf": "^6.1.3",
50
- "tsdown": "^0.22.3",
51
- "typescript": "^7",
48
+ "tsdown": "^0.22.9",
52
49
  "vite-tsconfig-paths": "^6.1.1",
53
50
  "vitest": "^4",
54
- "@systemfsoftware/effect-gherkin-spec": "^0.1.0",
55
51
  "@systemfsoftware/effect-schema-law": "^0.1.0",
52
+ "@systemfsoftware/stryker-js-core": "^0.1.0",
56
53
  "@systemfsoftware/oxlint-config": "^0.1.0",
54
+ "@systemfsoftware/stryker-js-typescript-checker": "^0.1.0",
55
+ "@systemfsoftware/effect-gherkin-spec": "^0.1.0",
57
56
  "@systemfsoftware/stryker-plugins": "^0.1.0",
58
57
  "@systemfsoftware/tsconfig": "^1.0.0",
59
58
  "@systemfsoftware/vitest-config": "^0.1.0"