@shivaedev/effect-pg-boss 0.1.3 → 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.
Files changed (44) hide show
  1. package/CHANGELOG.md +10 -1
  2. package/README.md +7 -5
  3. package/dist/definition.d.ts.map +1 -1
  4. package/dist/definition.js.map +1 -1
  5. package/dist/error.d.ts +1 -1
  6. package/dist/error.d.ts.map +1 -1
  7. package/dist/error.js.map +1 -1
  8. package/dist/health.d.ts.map +1 -1
  9. package/dist/health.js.map +1 -1
  10. package/dist/index.d.ts +5 -5
  11. package/dist/internal/client.d.ts +1 -1
  12. package/dist/internal/client.d.ts.map +1 -1
  13. package/dist/internal/client.js.map +1 -1
  14. package/dist/internal/health.d.ts +3 -3
  15. package/dist/internal/health.d.ts.map +1 -1
  16. package/dist/internal/health.js +2 -5
  17. package/dist/internal/health.js.map +1 -1
  18. package/dist/internal/lifecycle.d.ts +4 -4
  19. package/dist/internal/lifecycle.d.ts.map +1 -1
  20. package/dist/internal/lifecycle.js +15 -9
  21. package/dist/internal/lifecycle.js.map +1 -1
  22. package/dist/internal/register.d.ts +5 -4
  23. package/dist/internal/register.d.ts.map +1 -1
  24. package/dist/internal/register.js +19 -8
  25. package/dist/internal/register.js.map +1 -1
  26. package/dist/internal/service.d.ts +2 -2
  27. package/dist/internal/service.d.ts.map +1 -1
  28. package/dist/internal/service.js +1 -1
  29. package/dist/internal/service.js.map +1 -1
  30. package/dist/service.d.ts +6 -5
  31. package/dist/service.d.ts.map +1 -1
  32. package/dist/service.js +6 -13
  33. package/dist/service.js.map +1 -1
  34. package/package.json +1 -1
  35. package/src/definition.ts +9 -33
  36. package/src/error.ts +3 -12
  37. package/src/health.ts +1 -2
  38. package/src/index.ts +5 -5
  39. package/src/internal/client.ts +6 -32
  40. package/src/internal/health.ts +6 -19
  41. package/src/internal/lifecycle.ts +23 -29
  42. package/src/internal/register.ts +44 -67
  43. package/src/internal/service.ts +20 -36
  44. package/src/service.ts +29 -90
package/src/service.ts CHANGED
@@ -1,31 +1,19 @@
1
1
  import { Context, Effect, Layer, type Option, type Schema } from "effect";
2
2
  import type { ConstructorOptions, SendOptions, StopOptions } from "pg-boss";
3
- import type {
4
- JobPayloadSchema,
5
- JobRegistration,
6
- QueueDefinition,
7
- RegistrationRequirements,
8
- } from "./definition.js";
9
- import type { PgBossError, PgBossPayloadError } from "./error.js";
10
- import type { JobsHealth } from "./health.js";
11
- import type { PgBossClientFactory } from "./internal/client.js";
12
- import { acquireClient, releaseClient } from "./internal/lifecycle.js";
13
- import { registerJobs } from "./internal/register.js";
14
- import { makeService } from "./internal/service.js";
3
+ import type { JobPayloadSchema, JobRegistration, QueueDefinition, RegistrationRequirements } from "./definition.ts";
4
+ import type { PgBossError, PgBossPayloadError } from "./error.ts";
5
+ import type { JobsHealth } from "./health.ts";
6
+ import type { PgBossClientFactory } from "./internal/client.ts";
7
+ import { acquireClient, releaseClient } from "./internal/lifecycle.ts";
8
+ import { registerJobs, registrationName } from "./internal/register.ts";
9
+ import { makeService } from "./internal/service.ts";
15
10
 
16
11
  export interface PgBossService {
17
- readonly enqueue: <
18
- const Name extends string,
19
- const Payload extends JobPayloadSchema,
20
- >(
12
+ readonly enqueue: <const Name extends string, const Payload extends JobPayloadSchema>(
21
13
  queue: QueueDefinition<Name, Payload>,
22
14
  payload: Schema.Schema.Type<Payload>,
23
15
  options?: SendOptions,
24
- ) => Effect.Effect<
25
- Option.Option<string>,
26
- PgBossError | PgBossPayloadError,
27
- Payload["EncodingServices"]
28
- >;
16
+ ) => Effect.Effect<Option.Option<string>, PgBossError | PgBossPayloadError, Payload["EncodingServices"]>;
29
17
  readonly health: Effect.Effect<JobsHealth, PgBossError>;
30
18
  }
31
19
 
@@ -33,64 +21,33 @@ interface PgBossIdentifier {
33
21
  readonly _pgBossIdentifier: unique symbol;
34
22
  }
35
23
 
36
- export type PgBossLayerOptions<
37
- Registrations extends readonly JobRegistration[],
38
- ErrorRequirements,
39
- > = ConstructorOptions & {
24
+ export type PgBossLayerOptions<Registrations extends readonly JobRegistration[], ErrorRequirements> = ConstructorOptions & {
40
25
  /** Override client construction for compatible clients or deterministic tests. */
41
26
  readonly clientFactory?: PgBossClientFactory;
42
- readonly developmentCacheKey?: string | symbol;
27
+ /** Reuse and reference-count one started client under this key, e.g. across development module reloads. */
28
+ readonly clientCacheKey?: string | symbol | undefined;
43
29
  readonly jobs: Registrations;
44
- readonly onError?: (
45
- error: Error,
46
- ) => Effect.Effect<unknown, never, ErrorRequirements>;
30
+ readonly onError?: (error: Error) => Effect.Effect<unknown, never, ErrorRequirements>;
47
31
  readonly stop?: StopOptions;
48
32
  };
49
33
 
50
- export interface PgBossDefinition
51
- extends Context.Service<PgBossIdentifier, PgBossService> {
52
- readonly layer: <
53
- const Registrations extends readonly JobRegistration[],
54
- ErrorRequirements = never,
55
- >(
34
+ export interface PgBossDefinition extends Context.Service<PgBossIdentifier, PgBossService> {
35
+ readonly layer: <const Registrations extends readonly JobRegistration[], ErrorRequirements = never>(
56
36
  options: PgBossLayerOptions<Registrations, ErrorRequirements>,
57
- ) => Layer.Layer<
58
- PgBossIdentifier,
59
- PgBossError,
60
- RegistrationRequirements<Registrations> | ErrorRequirements
61
- >;
37
+ ) => Layer.Layer<PgBossIdentifier, PgBossError, RegistrationRequirements<Registrations> | ErrorRequirements>;
62
38
  }
63
39
 
40
+ const logClientError = (error: Error): Effect.Effect<void> => Effect.logError({ event: "pg_boss_error", message: error.message });
41
+
64
42
  export const makePgBoss = (identifier: string): PgBossDefinition => {
65
43
  const Service = Context.Service<PgBossIdentifier, PgBossService>(identifier);
66
44
 
67
- const layer = <
68
- const Registrations extends readonly JobRegistration[],
69
- ErrorRequirements = never,
70
- >(
45
+ const layer = <const Registrations extends readonly JobRegistration[], ErrorRequirements = never>(
71
46
  options: PgBossLayerOptions<Registrations, ErrorRequirements>,
72
- ): Layer.Layer<
73
- PgBossIdentifier,
74
- PgBossError,
75
- RegistrationRequirements<Registrations> | ErrorRequirements
76
- > => {
77
- type Requirements =
78
- | RegistrationRequirements<Registrations>
79
- | ErrorRequirements;
80
- const names = options.jobs.map((registration) =>
81
- registration._tag === "QueueWorker"
82
- ? (registration as import("./definition.js").QueueWorker).queue.name
83
- : (registration as import("./definition.js").ScheduledWorker).schedule
84
- .name,
85
- );
86
- const {
87
- clientFactory,
88
- developmentCacheKey,
89
- jobs,
90
- onError,
91
- stop,
92
- ...constructorOptions
93
- } = options;
47
+ ): Layer.Layer<PgBossIdentifier, PgBossError, RegistrationRequirements<Registrations> | ErrorRequirements> => {
48
+ type Requirements = RegistrationRequirements<Registrations> | ErrorRequirements;
49
+ const names = options.jobs.map(registrationName);
50
+ const { clientFactory, clientCacheKey, jobs, onError, stop, ...constructorOptions } = options;
94
51
 
95
52
  const acquire = Effect.acquireRelease(
96
53
  Effect.gen(function* () {
@@ -98,30 +55,14 @@ export const makePgBoss = (identifier: string): PgBossDefinition => {
98
55
  const acquired = yield* acquireClient({
99
56
  clientFactory,
100
57
  constructor: constructorOptions,
101
- developmentCacheKey,
58
+ clientCacheKey,
102
59
  });
103
- const reportError: (
104
- error: Error,
105
- ) => Effect.Effect<unknown, never, Requirements> =
106
- onError === undefined
107
- ? (error) =>
108
- Effect.logError({
109
- event: "pg_boss_error",
110
- message: error.message,
111
- })
112
- : onError;
60
+ const reportError: (error: Error) => Effect.Effect<unknown, never, Requirements> = onError ?? logClientError;
113
61
  const errorListener = (error: Error) => {
114
- void Effect.runPromise(
115
- Effect.exit(Effect.provide(reportError(error), context)),
116
- );
62
+ void Effect.runPromise(Effect.exit(Effect.provide(reportError(error), context)));
117
63
  };
118
64
  acquired.client.on("error", errorListener);
119
- const registration = registerJobs(
120
- acquired.client,
121
- jobs,
122
- context,
123
- acquired.reused,
124
- );
65
+ const registration = registerJobs(acquired.client, jobs, context, acquired.reused);
125
66
  return yield* registration.pipe(
126
67
  Effect.as({ acquired, context, errorListener }),
127
68
  Effect.onError(() => {
@@ -138,11 +79,9 @@ export const makePgBoss = (identifier: string): PgBossDefinition => {
138
79
 
139
80
  return Layer.effect(
140
81
  Service,
141
- Effect.map(acquire, ({ acquired }) =>
142
- makeService(acquired.client, names),
143
- ),
82
+ Effect.map(acquire, ({ acquired }) => makeService(acquired.client, names)),
144
83
  );
145
84
  };
146
85
 
147
- return Object.assign(Service, { layer }) as PgBossDefinition;
86
+ return Object.assign(Service, { layer });
148
87
  };