effect-jobs 0.1.0-alpha.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 (157) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/LICENSE +22 -0
  3. package/README.md +142 -0
  4. package/dist/Job.d.ts +33 -0
  5. package/dist/Job.d.ts.map +1 -0
  6. package/dist/Job.js +66 -0
  7. package/dist/Job.js.map +1 -0
  8. package/dist/JobConsumer.d.ts +34 -0
  9. package/dist/JobConsumer.d.ts.map +1 -0
  10. package/dist/JobConsumer.js +28 -0
  11. package/dist/JobConsumer.js.map +1 -0
  12. package/dist/JobContract.d.ts +128 -0
  13. package/dist/JobContract.d.ts.map +1 -0
  14. package/dist/JobContract.js +15 -0
  15. package/dist/JobContract.js.map +1 -0
  16. package/dist/JobFailure.d.ts +51 -0
  17. package/dist/JobFailure.d.ts.map +1 -0
  18. package/dist/JobFailure.js +34 -0
  19. package/dist/JobFailure.js.map +1 -0
  20. package/dist/JobId.d.ts +5 -0
  21. package/dist/JobId.d.ts.map +1 -0
  22. package/dist/JobId.js +4 -0
  23. package/dist/JobId.js.map +1 -0
  24. package/dist/JobIdentity.d.ts +54 -0
  25. package/dist/JobIdentity.d.ts.map +1 -0
  26. package/dist/JobIdentity.js +82 -0
  27. package/dist/JobIdentity.js.map +1 -0
  28. package/dist/JobLifecycle.d.ts +173 -0
  29. package/dist/JobLifecycle.d.ts.map +1 -0
  30. package/dist/JobLifecycle.js +234 -0
  31. package/dist/JobLifecycle.js.map +1 -0
  32. package/dist/JobPayload.d.ts +18 -0
  33. package/dist/JobPayload.d.ts.map +1 -0
  34. package/dist/JobPayload.js +10 -0
  35. package/dist/JobPayload.js.map +1 -0
  36. package/dist/JobPayloadCodec.d.ts +14 -0
  37. package/dist/JobPayloadCodec.d.ts.map +1 -0
  38. package/dist/JobPayloadCodec.js +78 -0
  39. package/dist/JobPayloadCodec.js.map +1 -0
  40. package/dist/JobPolicy.d.ts +50 -0
  41. package/dist/JobPolicy.d.ts.map +1 -0
  42. package/dist/JobPolicy.js +85 -0
  43. package/dist/JobPolicy.js.map +1 -0
  44. package/dist/JobProducer.d.ts +14 -0
  45. package/dist/JobProducer.d.ts.map +1 -0
  46. package/dist/JobProducer.js +23 -0
  47. package/dist/JobProducer.js.map +1 -0
  48. package/dist/JobQueue.d.ts +16 -0
  49. package/dist/JobQueue.d.ts.map +1 -0
  50. package/dist/JobQueue.js +16 -0
  51. package/dist/JobQueue.js.map +1 -0
  52. package/dist/JobRegistry.d.ts +37 -0
  53. package/dist/JobRegistry.d.ts.map +1 -0
  54. package/dist/JobRegistry.js +47 -0
  55. package/dist/JobRegistry.js.map +1 -0
  56. package/dist/JobStore.d.ts +348 -0
  57. package/dist/JobStore.d.ts.map +1 -0
  58. package/dist/JobStore.js +19 -0
  59. package/dist/JobStore.js.map +1 -0
  60. package/dist/JobTelemetry.d.ts +7 -0
  61. package/dist/JobTelemetry.d.ts.map +1 -0
  62. package/dist/JobTelemetry.js +61 -0
  63. package/dist/JobTelemetry.js.map +1 -0
  64. package/dist/JobTransaction.d.ts +24 -0
  65. package/dist/JobTransaction.d.ts.map +1 -0
  66. package/dist/JobTransaction.js +7 -0
  67. package/dist/JobTransaction.js.map +1 -0
  68. package/dist/JobWorker.d.ts +24 -0
  69. package/dist/JobWorker.d.ts.map +1 -0
  70. package/dist/JobWorker.js +155 -0
  71. package/dist/JobWorker.js.map +1 -0
  72. package/dist/JobWorkerRuntime.d.ts +18 -0
  73. package/dist/JobWorkerRuntime.d.ts.map +1 -0
  74. package/dist/JobWorkerRuntime.js +5 -0
  75. package/dist/JobWorkerRuntime.js.map +1 -0
  76. package/dist/PollingJobWorker.d.ts +9 -0
  77. package/dist/PollingJobWorker.d.ts.map +1 -0
  78. package/dist/PollingJobWorker.js +54 -0
  79. package/dist/PollingJobWorker.js.map +1 -0
  80. package/dist/PostgreSqlDrizzleSchema.d.ts +432 -0
  81. package/dist/PostgreSqlDrizzleSchema.d.ts.map +1 -0
  82. package/dist/PostgreSqlDrizzleSchema.js +72 -0
  83. package/dist/PostgreSqlDrizzleSchema.js.map +1 -0
  84. package/dist/PostgreSqlJobs.d.ts +25 -0
  85. package/dist/PostgreSqlJobs.d.ts.map +1 -0
  86. package/dist/PostgreSqlJobs.js +38 -0
  87. package/dist/PostgreSqlJobs.js.map +1 -0
  88. package/dist/PostgreSqlSchema.d.ts +30 -0
  89. package/dist/PostgreSqlSchema.d.ts.map +1 -0
  90. package/dist/PostgreSqlSchema.js +63 -0
  91. package/dist/PostgreSqlSchema.js.map +1 -0
  92. package/dist/PostgreSqlTransaction.d.ts +42 -0
  93. package/dist/PostgreSqlTransaction.d.ts.map +1 -0
  94. package/dist/PostgreSqlTransaction.js +9 -0
  95. package/dist/PostgreSqlTransaction.js.map +1 -0
  96. package/dist/index.d.ts +7 -0
  97. package/dist/index.d.ts.map +1 -0
  98. package/dist/index.js +7 -0
  99. package/dist/index.js.map +1 -0
  100. package/dist/internal/JobTransaction.d.ts +16 -0
  101. package/dist/internal/JobTransaction.d.ts.map +1 -0
  102. package/dist/internal/JobTransaction.js +21 -0
  103. package/dist/internal/JobTransaction.js.map +1 -0
  104. package/dist/internal/codec/CanonicalJson.d.ts +9 -0
  105. package/dist/internal/codec/CanonicalJson.d.ts.map +1 -0
  106. package/dist/internal/codec/CanonicalJson.js +184 -0
  107. package/dist/internal/codec/CanonicalJson.js.map +1 -0
  108. package/dist/internal/codec/ProtectedProjection.d.ts +12 -0
  109. package/dist/internal/codec/ProtectedProjection.d.ts.map +1 -0
  110. package/dist/internal/codec/ProtectedProjection.js +121 -0
  111. package/dist/internal/codec/ProtectedProjection.js.map +1 -0
  112. package/dist/internal/lifecycle/Artifacts.d.ts +6 -0
  113. package/dist/internal/lifecycle/Artifacts.d.ts.map +1 -0
  114. package/dist/internal/lifecycle/Artifacts.js +49 -0
  115. package/dist/internal/lifecycle/Artifacts.js.map +1 -0
  116. package/dist/internal/lifecycle/Reconciliation.d.ts +82 -0
  117. package/dist/internal/lifecycle/Reconciliation.d.ts.map +1 -0
  118. package/dist/internal/lifecycle/Reconciliation.js +98 -0
  119. package/dist/internal/lifecycle/Reconciliation.js.map +1 -0
  120. package/dist/internal/postgresql/Producer.d.ts +14 -0
  121. package/dist/internal/postgresql/Producer.d.ts.map +1 -0
  122. package/dist/internal/postgresql/Producer.js +55 -0
  123. package/dist/internal/postgresql/Producer.js.map +1 -0
  124. package/dist/internal/postgresql/Readiness.d.ts +5 -0
  125. package/dist/internal/postgresql/Readiness.d.ts.map +1 -0
  126. package/dist/internal/postgresql/Readiness.js +53 -0
  127. package/dist/internal/postgresql/Readiness.js.map +1 -0
  128. package/dist/internal/postgresql/Rows.d.ts +45 -0
  129. package/dist/internal/postgresql/Rows.d.ts.map +1 -0
  130. package/dist/internal/postgresql/Rows.js +75 -0
  131. package/dist/internal/postgresql/Rows.js.map +1 -0
  132. package/dist/internal/postgresql/Store.d.ts +5 -0
  133. package/dist/internal/postgresql/Store.d.ts.map +1 -0
  134. package/dist/internal/postgresql/Store.js +211 -0
  135. package/dist/internal/postgresql/Store.js.map +1 -0
  136. package/dist/internal/worker/Capability.d.ts +106 -0
  137. package/dist/internal/worker/Capability.d.ts.map +1 -0
  138. package/dist/internal/worker/Capability.js +11 -0
  139. package/dist/internal/worker/Capability.js.map +1 -0
  140. package/dist/internal/worker/Drain.d.ts +22 -0
  141. package/dist/internal/worker/Drain.d.ts.map +1 -0
  142. package/dist/internal/worker/Drain.js +59 -0
  143. package/dist/internal/worker/Drain.js.map +1 -0
  144. package/dist/internal/worker/Execution.d.ts +7 -0
  145. package/dist/internal/worker/Execution.d.ts.map +1 -0
  146. package/dist/internal/worker/Execution.js +125 -0
  147. package/dist/internal/worker/Execution.js.map +1 -0
  148. package/dist/internal/worker/Results.d.ts +108 -0
  149. package/dist/internal/worker/Results.d.ts.map +1 -0
  150. package/dist/internal/worker/Results.js +3 -0
  151. package/dist/internal/worker/Results.js.map +1 -0
  152. package/package.json +169 -0
  153. package/specs/architecture-decisions.md +841 -0
  154. package/specs/core-contract.md +323 -0
  155. package/specs/drizzle-compatibility.md +167 -0
  156. package/specs/postgresql-backend.md +291 -0
  157. package/specs/release-qualification.md +107 -0
@@ -0,0 +1,49 @@
1
+ import { Result, Schema } from "effect";
2
+ import * as Contract from "../../JobContract.js";
3
+ import { CatalogIdentity, ProducerIdentity } from "../../JobIdentity.js";
4
+ import { EpochMillis, PersistedJobPolicy } from "../../JobPolicy.js";
5
+ import * as Lifecycle from "../../JobLifecycle.js";
6
+ import { JobStoreProtocolError } from "../../JobStore.js";
7
+ const bytes = (maximum) => Schema.instanceOf(Uint8Array).pipe(Schema.check(Schema.makeFilter((value) => value.byteLength > 0 && value.byteLength <= maximum)));
8
+ const PreparedArtifact = Schema.Struct({
9
+ catalog: CatalogIdentity,
10
+ producer: ProducerIdentity,
11
+ policy: PersistedJobPolicy,
12
+ availableAt: Schema.optional(EpochMillis),
13
+ encoded: Schema.Struct({
14
+ formatVersion: Schema.Literal(Contract.jobPayloadFormatVersion),
15
+ payloadBytes: bytes(Contract.maximumJobPayloadBytes),
16
+ semanticProjectionBytes: bytes(Contract.maximumJobSemanticProjectionBytes)
17
+ })
18
+ });
19
+ /** Validates portable structure only. Codec must still validate canonical bytes/schema/projection before execution. */
20
+ export const validateClaimArtifact = (claim) => Result.gen(function* () {
21
+ const fail = () => new JobStoreProtocolError({ reason: "invalid-artifact" });
22
+ const row = yield* Result.mapError(Lifecycle.validateSnapshot(claim.snapshot), fail);
23
+ const ownership = yield* Result.mapError(Lifecycle.ownershipOf(row), fail);
24
+ const suppliedOwnership = yield* Result.mapError(Schema.decodeResult(Lifecycle.JobOwnership, { onExcessProperty: "error" })(claim.ownership), fail);
25
+ const prepared = yield* Result.mapError(Schema.decodeUnknownResult(PreparedArtifact, { onExcessProperty: "error" })(claim.prepared), fail);
26
+ if (!Schema.toEquivalence(Lifecycle.JobOwnership)(ownership, suppliedOwnership) ||
27
+ !Schema.toEquivalence(PersistedJobPolicy)(row.policy, prepared.policy)) {
28
+ return yield* Result.fail(fail());
29
+ }
30
+ return Object.freeze({
31
+ catalog: Object.freeze(prepared.catalog),
32
+ producer: Object.freeze(prepared.producer),
33
+ policy: Object.freeze({
34
+ ...prepared.policy,
35
+ retrySchedule: Object.freeze(prepared.policy.retrySchedule),
36
+ completedRetention: Object.freeze(prepared.policy.completedRetention),
37
+ deadRetention: Object.freeze(prepared.policy.deadRetention)
38
+ }),
39
+ ...(prepared.availableAt === undefined
40
+ ? {}
41
+ : { availableAt: prepared.availableAt }),
42
+ encoded: Object.freeze({
43
+ ...prepared.encoded,
44
+ payloadBytes: new Uint8Array(prepared.encoded.payloadBytes),
45
+ semanticProjectionBytes: new Uint8Array(prepared.encoded.semanticProjectionBytes)
46
+ })
47
+ });
48
+ });
49
+ //# sourceMappingURL=Artifacts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Artifacts.js","sourceRoot":"","sources":["../../../src/internal/lifecycle/Artifacts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACvC,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAA;AAChD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AACxE,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AACpE,OAAO,KAAK,SAAS,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAE,qBAAqB,EAAmB,MAAM,mBAAmB,CAAA;AAE1E,MAAM,KAAK,GAAG,CAAC,OAAe,EAAE,EAAE,CAChC,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,IAAI,CAChC,MAAM,CAAC,KAAK,CACV,MAAM,CAAC,UAAU,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,IAAI,OAAO,CAAC,CAClF,CACF,CAAA;AACH,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,CAAC;IACrC,OAAO,EAAE,eAAe;IACxB,QAAQ,EAAE,gBAAgB;IAC1B,MAAM,EAAE,kBAAkB;IAC1B,WAAW,EAAE,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC;IACzC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAC;QAC/D,YAAY,EAAE,KAAK,CAAC,QAAQ,CAAC,sBAAsB,CAAC;QACpD,uBAAuB,EAAE,KAAK,CAAC,QAAQ,CAAC,iCAAiC,CAAC;KAC3E,CAAC;CACH,CAAC,CAAA;AACF,uHAAuH;AACvH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,KAAiB,EAC2C,EAAE,CAC9D,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,IAAI,qBAAqB,CAAC,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC,CAAA;IAC5E,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,gBAAgB,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAA;IACpF,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAA;IAC1E,MAAM,iBAAiB,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAC9C,MAAM,CAAC,YAAY,CAAC,SAAS,CAAC,YAAY,EAAE,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC,CACxE,KAAK,CAAC,SAAS,CAChB,EACD,IAAI,CACL,CAAA;IACD,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CACrC,MAAM,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC,CACzE,KAAK,CAAC,QAAQ,CACf,EACD,IAAI,CACL,CAAA;IACD,IACE,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,SAAS,EAAE,iBAAiB,CAAC;QAC3E,CAAC,MAAM,CAAC,aAAa,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,EACtE,CAAC;QACD,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;IACnC,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC;QACxC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC1C,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC;YACpB,GAAG,QAAQ,CAAC,MAAM;YAClB,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC;YAC3D,kBAAkB,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,kBAAkB,CAAC;YACrE,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC;SAC5D,CAAC;QACF,GAAG,CAAC,QAAQ,CAAC,WAAW,KAAK,SAAS;YACpC,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,CAAC;QAC1C,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC;YACrB,GAAG,QAAQ,CAAC,OAAO;YACnB,YAAY,EAAE,IAAI,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,YAAY,CAAC;YAC3D,uBAAuB,EAAE,IAAI,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,uBAAuB,CAAC;SAClF,CAAC;KACH,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -0,0 +1,82 @@
1
+ import { Data, Effect, Result } from "effect";
2
+ import * as Lifecycle from "../../JobLifecycle.js";
3
+ import * as Store from "../../JobStore.js";
4
+ /** Read reconciliation is evidence of the exact original command, never permission to replay a handler. */
5
+ export declare const inspectFinalization: (request: Store.FinalizationRequest, observed: unknown, dbNow: number) => Result.Result<Store.FinalizationReconciliation, Lifecycle.JobLifecycleError>;
6
+ /** One original-token storage read; absence is evidence only for that claim. */
7
+ export declare const inspectClaim: (leaseToken: string, observed: Store.ClaimedJob | null, dbNow: number, operationResponseBudgetMillis: number) => Result.Result<Store.ClaimReconciliation, Lifecycle.JobLifecycleError>;
8
+ export type ClaimResolution = Data.TaggedEnum<{
9
+ Ready: {
10
+ readonly claim: Store.ClaimedJob;
11
+ };
12
+ Skipped: {};
13
+ Deferred: {};
14
+ }>;
15
+ export declare const ClaimResolutions: {
16
+ readonly $is: <Tag extends "Deferred" | "Ready" | "Skipped">(tag: Tag) => (u: unknown) => u is Extract<{
17
+ readonly _tag: "Deferred";
18
+ }, {
19
+ readonly _tag: Tag;
20
+ }> | Extract<{
21
+ readonly _tag: "Ready";
22
+ readonly claim: Store.ClaimedJob;
23
+ }, {
24
+ readonly _tag: Tag;
25
+ }> | Extract<{
26
+ readonly _tag: "Skipped";
27
+ }, {
28
+ readonly _tag: Tag;
29
+ }>;
30
+ readonly $match: {
31
+ <Cases extends { readonly [Tag in "Deferred" | "Ready" | "Skipped"]: (args: Extract<{
32
+ readonly _tag: "Deferred";
33
+ } | {
34
+ readonly _tag: "Ready";
35
+ readonly claim: Store.ClaimedJob;
36
+ } | {
37
+ readonly _tag: "Skipped";
38
+ }, {
39
+ readonly _tag: Tag;
40
+ }>) => any; }>(cases: Cases): (value: {
41
+ readonly _tag: "Deferred";
42
+ } | {
43
+ readonly _tag: "Ready";
44
+ readonly claim: Store.ClaimedJob;
45
+ } | {
46
+ readonly _tag: "Skipped";
47
+ }) => import("effect/Unify").Unify<ReturnType<Cases["Deferred" | "Ready" | "Skipped"]>>;
48
+ <Cases extends { readonly [Tag in "Deferred" | "Ready" | "Skipped"]: (args: Extract<{
49
+ readonly _tag: "Deferred";
50
+ } | {
51
+ readonly _tag: "Ready";
52
+ readonly claim: Store.ClaimedJob;
53
+ } | {
54
+ readonly _tag: "Skipped";
55
+ }, {
56
+ readonly _tag: Tag;
57
+ }>) => any; }>(value: {
58
+ readonly _tag: "Deferred";
59
+ } | {
60
+ readonly _tag: "Ready";
61
+ readonly claim: Store.ClaimedJob;
62
+ } | {
63
+ readonly _tag: "Skipped";
64
+ }, cases: Cases): import("effect/Unify").Unify<ReturnType<Cases["Deferred" | "Ready" | "Skipped"]>>;
65
+ };
66
+ readonly Deferred: Data.TaggedEnum.ConstructorFrom<{
67
+ readonly _tag: "Deferred";
68
+ }, "_tag">;
69
+ readonly Ready: Data.TaggedEnum.ConstructorFrom<{
70
+ readonly _tag: "Ready";
71
+ readonly claim: Store.ClaimedJob;
72
+ }, "_tag">;
73
+ readonly Skipped: Data.TaggedEnum.ConstructorFrom<{
74
+ readonly _tag: "Skipped";
75
+ }, "_tag">;
76
+ };
77
+ /** One original-token read at most. Insufficient leases may be released ONLY before execution. */
78
+ export declare const resolveClaim: <E, R>(store: Store.JobStoreService<E, R>, request: Store.ClaimRequest) => Effect.Effect<ClaimResolution, E | Store.JobStoreProtocolError | Store.JobOwnershipLost, R>;
79
+ export type FinalizationResolution = "Applied" | "OwnershipLost" | "Deferred";
80
+ /** One read and at most ONE identical finalization retry. Never retries execution or loops on Unknown. */
81
+ export declare const resolveFinalization: <E, R>(store: Store.JobStoreService<E, R>, request: Store.FinalizationRequest) => Effect.Effect<FinalizationResolution, E | Store.JobStoreProtocolError | Store.JobOwnershipLost, R>;
82
+ //# sourceMappingURL=Reconciliation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Reconciliation.d.ts","sourceRoot":"","sources":["../../../src/internal/lifecycle/Reconciliation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAA;AACrD,OAAO,KAAK,SAAS,MAAM,uBAAuB,CAAA;AAClD,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAA;AAG1C,2GAA2G;AAC3G,eAAO,MAAM,mBAAmB,YACrB,KAAK,CAAC,mBAAmB,YACxB,OAAO,SACV,MAAM,KACZ,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,EAAE,SAAS,CAAC,iBAAiB,CAkC1E,CAAA;AAEJ,gFAAgF;AAChF,eAAO,MAAM,YAAY,eACX,MAAM,YACR,KAAK,CAAC,UAAU,GAAG,IAAI,SAC1B,MAAM,iCACkB,MAAM,KACpC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,EAAE,SAAS,CAAC,iBAAiB,CA8BnE,CAAA;AAEJ,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,UAAU,CAAC;IAC5C,KAAK,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAA;KAAE,CAAA;IAC3C,OAAO,EAAE,EAAE,CAAA;IACX,QAAQ,EAAE,EAAE,CAAA;CACb,CAAC,CAAA;AACF,eAAO,MAAM,gBAAgB;;;;;;;wBAJF,KAAK,CAAC,UAAU;;;;;;;;;;;;;4BAAhB,KAAK,CAAC,UAAU;;;;;;;;;;;;;;;;;4BAAhB,KAAK,CAAC,UAAU;;;;;;;;;;;;;;;;;;;wBAAhB,KAAK,CAAC,UAAU;;;;;CAIuB,CAAA;AAElE,kGAAkG;AAClG,eAAO,MAAM,YAAY,GAAI,CAAC,EAAE,CAAC,SACxB,KAAK,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,WACzB,KAAK,CAAC,YAAY,KAC1B,MAAM,CAAC,MAAM,CACd,eAAe,EACf,CAAC,GAAG,KAAK,CAAC,qBAAqB,GAAG,KAAK,CAAC,gBAAgB,EACxD,CAAC,CAyBC,CAAA;AAEJ,MAAM,MAAM,sBAAsB,GAAG,SAAS,GAAG,eAAe,GAAG,UAAU,CAAA;AAC7E,0GAA0G;AAC1G,eAAO,MAAM,mBAAmB,GAAI,CAAC,EAAE,CAAC,SAC/B,KAAK,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,WACzB,KAAK,CAAC,mBAAmB,KACjC,MAAM,CAAC,MAAM,CACd,sBAAsB,EACtB,CAAC,GAAG,KAAK,CAAC,qBAAqB,GAAG,KAAK,CAAC,gBAAgB,EACxD,CAAC,CAoBC,CAAA"}
@@ -0,0 +1,98 @@
1
+ import { Data, Effect, Result, Schema } from "effect";
2
+ import * as Lifecycle from "../../JobLifecycle.js";
3
+ import * as Store from "../../JobStore.js";
4
+ import { EpochMillis } from "../../JobPolicy.js";
5
+ /** Read reconciliation is evidence of the exact original command, never permission to replay a handler. */
6
+ export const inspectFinalization = (request, observed, dbNow) => Result.gen(function* () {
7
+ const before = yield* Lifecycle.validateSnapshot(request.before);
8
+ const originalOwnership = yield* Lifecycle.ownershipOf(before);
9
+ if (!Schema.is(Lifecycle.JobOwnership)(request.ownership) ||
10
+ !Schema.is(Lifecycle.JobFinalization)(request.finalization) ||
11
+ !Schema.is(EpochMillis)(dbNow) ||
12
+ !Schema.toEquivalence(Lifecycle.JobOwnership)(originalOwnership, request.ownership)) {
13
+ return yield* Result.fail(new Lifecycle.JobLifecycleError({ reason: "invalid-command" }));
14
+ }
15
+ if (observed === null) {
16
+ return Store.FinalizationReconciliations.OwnershipLost();
17
+ }
18
+ const row = yield* Lifecycle.validateSnapshot(observed);
19
+ const expected = Lifecycle.finalize(before, request.ownership, request.finalization, row.updatedAt);
20
+ if (Result.isSuccess(expected) &&
21
+ Schema.toEquivalence(Lifecycle.JobSnapshot)(row, expected.success)) {
22
+ return Store.FinalizationReconciliations.Applied();
23
+ }
24
+ return Lifecycle.isOwned(row, request.ownership, dbNow) &&
25
+ Schema.toEquivalence(Lifecycle.JobSnapshot)(row, before)
26
+ ? Store.FinalizationReconciliations.StillOwned()
27
+ : Store.FinalizationReconciliations.OwnershipLost();
28
+ });
29
+ /** One original-token storage read; absence is evidence only for that claim. */
30
+ export const inspectClaim = (leaseToken, observed, dbNow, operationResponseBudgetMillis) => Result.gen(function* () {
31
+ if (!Schema.is(Lifecycle.LeaseToken)(leaseToken) ||
32
+ !Schema.is(EpochMillis)(dbNow) ||
33
+ !Schema.is(EpochMillis)(operationResponseBudgetMillis)) {
34
+ return yield* Result.fail(new Lifecycle.JobLifecycleError({ reason: "invalid-command" }));
35
+ }
36
+ if (observed === null) {
37
+ return Store.ClaimReconciliations.NotOwned();
38
+ }
39
+ const row = yield* Lifecycle.validateSnapshot(observed.snapshot);
40
+ const ownership = yield* Lifecycle.ownershipOf(row);
41
+ if (!Schema.is(Lifecycle.JobOwnership)(observed.ownership) ||
42
+ !Schema.toEquivalence(Lifecycle.JobOwnership)(ownership, observed.ownership)) {
43
+ return yield* Result.fail(new Lifecycle.JobLifecycleError({ reason: "invalid-command" }));
44
+ }
45
+ if (ownership.leaseToken !== leaseToken) {
46
+ return Store.ClaimReconciliations.NotOwned();
47
+ }
48
+ return Lifecycle.usableLease(row, dbNow, operationResponseBudgetMillis)
49
+ ? Store.ClaimReconciliations.Owned({ claim: observed })
50
+ : Store.ClaimReconciliations.InsufficientLease({ ownership });
51
+ });
52
+ export const ClaimResolutions = Data.taggedEnum();
53
+ /** One original-token read at most. Insufficient leases may be released ONLY before execution. */
54
+ export const resolveClaim = (store, request) => Effect.gen(function* () {
55
+ const result = yield* store.claim(request);
56
+ if (result._tag === "Claimed") {
57
+ return ClaimResolutions.Ready({ claim: result.claim });
58
+ }
59
+ if (result._tag === "Empty") {
60
+ return ClaimResolutions.Skipped();
61
+ }
62
+ const reconciled = yield* store.reconcileClaim(request.leaseToken);
63
+ switch (reconciled._tag) {
64
+ case "Owned":
65
+ return ClaimResolutions.Ready({ claim: reconciled.claim });
66
+ case "NotOwned":
67
+ return ClaimResolutions.Skipped();
68
+ case "Unknown":
69
+ return ClaimResolutions.Deferred();
70
+ case "InsufficientLease": {
71
+ const released = yield* store.release(reconciled.ownership, "BeforeExecution");
72
+ return released._tag === "Applied"
73
+ ? ClaimResolutions.Skipped()
74
+ : ClaimResolutions.Deferred();
75
+ }
76
+ }
77
+ });
78
+ /** One read and at most ONE identical finalization retry. Never retries execution or loops on Unknown. */
79
+ export const resolveFinalization = (store, request) => Effect.gen(function* () {
80
+ const result = yield* store.finalize(request);
81
+ if (result._tag === "Applied") {
82
+ return "Applied";
83
+ }
84
+ const reconciled = yield* store.reconcileFinalization(request);
85
+ switch (reconciled._tag) {
86
+ case "Applied":
87
+ return "Applied";
88
+ case "OwnershipLost":
89
+ return "OwnershipLost";
90
+ case "Unknown":
91
+ return "Deferred";
92
+ case "StillOwned": {
93
+ const repeated = yield* store.finalize(request);
94
+ return repeated._tag === "Applied" ? "Applied" : "Deferred";
95
+ }
96
+ }
97
+ });
98
+ //# sourceMappingURL=Reconciliation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Reconciliation.js","sourceRoot":"","sources":["../../../src/internal/lifecycle/Reconciliation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACrD,OAAO,KAAK,SAAS,MAAM,uBAAuB,CAAA;AAClD,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAA;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAEhD,2GAA2G;AAC3G,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,OAAkC,EAClC,QAAiB,EACjB,KAAa,EACiE,EAAE,CAChF,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IAChE,MAAM,iBAAiB,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;IAC9D,IACE,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC;QACrD,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC;QAC3D,CAAC,MAAM,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC;QAC9B,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,iBAAiB,EAAE,OAAO,CAAC,SAAS,CAAC,EACnF,CAAC;QACD,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CACvB,IAAI,SAAS,CAAC,iBAAiB,CAAC,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC,CAC/D,CAAA;IACH,CAAC;IACD,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,OAAO,KAAK,CAAC,2BAA2B,CAAC,aAAa,EAAE,CAAA;IAC1D,CAAC;IACD,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAA;IACvD,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,CACjC,MAAM,EACN,OAAO,CAAC,SAAS,EACjB,OAAO,CAAC,YAAY,EACpB,GAAG,CAAC,SAAS,CACd,CAAA;IACD,IACE,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC;QAC1B,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,GAAG,EAAE,QAAQ,CAAC,OAAO,CAAC,EAClE,CAAC;QACD,OAAO,KAAK,CAAC,2BAA2B,CAAC,OAAO,EAAE,CAAA;IACpD,CAAC;IACD,OAAO,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC;QACrD,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC;QACxD,CAAC,CAAC,KAAK,CAAC,2BAA2B,CAAC,UAAU,EAAE;QAChD,CAAC,CAAC,KAAK,CAAC,2BAA2B,CAAC,aAAa,EAAE,CAAA;AACvD,CAAC,CAAC,CAAA;AAEJ,gFAAgF;AAChF,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,UAAkB,EAClB,QAAiC,EACjC,KAAa,EACb,6BAAqC,EACkC,EAAE,CACzE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,IACE,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,UAAU,CAAC;QAC5C,CAAC,MAAM,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC;QAC9B,CAAC,MAAM,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,6BAA6B,CAAC,EACtD,CAAC;QACD,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CACvB,IAAI,SAAS,CAAC,iBAAiB,CAAC,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC,CAC/D,CAAA;IACH,CAAC;IACD,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,OAAO,KAAK,CAAC,oBAAoB,CAAC,QAAQ,EAAE,CAAA;IAC9C,CAAC;IACD,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;IAChE,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;IACnD,IACE,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC;QACtD,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,SAAS,EAAE,QAAQ,CAAC,SAAS,CAAC,EAC5E,CAAC;QACD,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CACvB,IAAI,SAAS,CAAC,iBAAiB,CAAC,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC,CAC/D,CAAA;IACH,CAAC;IACD,IAAI,SAAS,CAAC,UAAU,KAAK,UAAU,EAAE,CAAC;QACxC,OAAO,KAAK,CAAC,oBAAoB,CAAC,QAAQ,EAAE,CAAA;IAC9C,CAAC;IACD,OAAO,SAAS,CAAC,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE,6BAA6B,CAAC;QACrE,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;QACvD,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,SAAS,EAAE,CAAC,CAAA;AACjE,CAAC,CAAC,CAAA;AAOJ,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC,UAAU,EAAmB,CAAA;AAElE,kGAAkG;AAClG,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,KAAkC,EAClC,OAA2B,EAK3B,EAAE,CACF,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAC1C,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,gBAAgB,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAA;IACxD,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC5B,OAAO,gBAAgB,CAAC,OAAO,EAAE,CAAA;IACnC,CAAC;IACD,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;IAClE,QAAQ,UAAU,CAAC,IAAI,EAAE,CAAC;QACxB,KAAK,OAAO;YACV,OAAO,gBAAgB,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,CAAC,CAAA;QAC5D,KAAK,UAAU;YACb,OAAO,gBAAgB,CAAC,OAAO,EAAE,CAAA;QACnC,KAAK,SAAS;YACZ,OAAO,gBAAgB,CAAC,QAAQ,EAAE,CAAA;QACpC,KAAK,mBAAmB,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAA;YAC9E,OAAO,QAAQ,CAAC,IAAI,KAAK,SAAS;gBAChC,CAAC,CAAC,gBAAgB,CAAC,OAAO,EAAE;gBAC5B,CAAC,CAAC,gBAAgB,CAAC,QAAQ,EAAE,CAAA;QACjC,CAAC;IACH,CAAC;AACH,CAAC,CAAC,CAAA;AAGJ,0GAA0G;AAC1G,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,KAAkC,EAClC,OAAkC,EAKlC,EAAE,CACF,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;IAC7C,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAA;IAC9D,QAAQ,UAAU,CAAC,IAAI,EAAE,CAAC;QACxB,KAAK,SAAS;YACZ,OAAO,SAAS,CAAA;QAClB,KAAK,eAAe;YAClB,OAAO,eAAe,CAAA;QACxB,KAAK,SAAS;YACZ,OAAO,UAAU,CAAA;QACnB,KAAK,YAAY,EAAE,CAAC;YAClB,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;YAC/C,OAAO,QAAQ,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAA;QAC7D,CAAC;IACH,CAAC;AACH,CAAC,CAAC,CAAA"}
@@ -0,0 +1,14 @@
1
+ import { Effect } from "effect";
2
+ import { JobIntegrityConflict } from "../../JobContract.js";
3
+ import type { PreparedJob } from "../../JobContract.js";
4
+ import type { JobId } from "../../JobId.js";
5
+ import type { TransactionQuery } from "../../PostgreSqlTransaction.js";
6
+ /** READ COMMITTED is required: the post-conflict statement sees the committed winner. */
7
+ export declare const insertOrCompare: (query: TransactionQuery, jobs: string, payloads: string, prepared: PreparedJob) => Effect.Effect<{
8
+ readonly _tag: "AlreadyPresent";
9
+ readonly jobId: JobId;
10
+ } | {
11
+ readonly _tag: "Inserted";
12
+ readonly jobId: JobId;
13
+ }, JobIntegrityConflict | import("../../PostgreSqlTransaction.js").PostgreSqlError, never>;
14
+ //# sourceMappingURL=Producer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Producer.d.ts","sourceRoot":"","sources":["../../../src/internal/postgresql/Producer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAA;AACvC,OAAO,EAAkB,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAC3E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AACvD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAE3C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAA;AAItE,yFAAyF;AACzF,eAAO,MAAM,eAAe,UACnB,gBAAgB,QACjB,MAAM,YACF,MAAM,YACN,WAAW;;;;;;0FA8DnB,CAAA"}
@@ -0,0 +1,55 @@
1
+ import { Effect, Schema } from "effect";
2
+ import { EnqueueResults, JobIntegrityConflict } from "../../JobContract.js";
3
+ import { JobId as JobIdSchema } from "../../JobId.js";
4
+ import { dbTime } from "./Rows.js";
5
+ import { PostgreSqlFailure } from "../../PostgreSqlTransaction.js";
6
+ /** READ COMMITTED is required: the post-conflict statement sees the committed winner. */
7
+ export const insertOrCompare = (query, jobs, payloads, prepared) => Effect.gen(function* () {
8
+ const { catalog, producer, encoded } = prepared;
9
+ const id = yield* Effect.sync(() => globalThis.crypto.randomUUID());
10
+ const now = yield* dbTime(query).pipe(Effect.mapError(() => new PostgreSqlFailure({ commitKnowledge: "NotCommitted" })));
11
+ const rows = yield* query.query(`INSERT INTO ${jobs} (id,operation,operation_id,slot,queue,kind,version,policy,initial_available_at,state,available_at,updated_at)
12
+ VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,'Pending',$10,$11)
13
+ ON CONFLICT (operation,operation_id,slot) DO NOTHING RETURNING id`, [
14
+ id,
15
+ producer.operation,
16
+ producer.operationId,
17
+ producer.slot,
18
+ catalog.queue,
19
+ catalog.kind,
20
+ catalog.version,
21
+ JSON.stringify(prepared.policy),
22
+ prepared.availableAt ?? null,
23
+ prepared.availableAt ?? now,
24
+ now
25
+ ]);
26
+ if (rows.length === 0) {
27
+ // Hold the parent until comparison completes: cleanup cannot remove evidence in between.
28
+ const prior = (yield* query.query(`SELECT j.id,j.queue,j.kind,j.version,p.format_version,p.projection FROM ${jobs} j JOIN ${payloads} p ON p.job_id=j.id
29
+ WHERE j.operation=$1 AND j.operation_id=$2 AND j.slot=$3 FOR KEY SHARE OF j`, [producer.operation, producer.operationId, producer.slot]))[0];
30
+ const projection = prior?.projection;
31
+ if (prior === undefined ||
32
+ !Schema.is(JobIdSchema)(prior.id) ||
33
+ prior.queue !== catalog.queue ||
34
+ prior.kind !== catalog.kind ||
35
+ prior.version !== catalog.version ||
36
+ prior.format_version !== encoded.formatVersion ||
37
+ !(projection instanceof Uint8Array) ||
38
+ projection.length !== encoded.semanticProjectionBytes.length ||
39
+ !encoded.semanticProjectionBytes.every((byte, i) => byte === projection[i])) {
40
+ // Poison this producer transaction even if trusted application code catches the typed error.
41
+ // A real SQL error forces the outer owner to roll back all domain writes.
42
+ yield* query.query("SELECT 1/0").pipe(Effect.ignore);
43
+ return yield* new JobIntegrityConflict();
44
+ }
45
+ return EnqueueResults.AlreadyPresent({ jobId: prior.id });
46
+ }
47
+ yield* query.query(`INSERT INTO ${payloads} (job_id,format_version,payload,projection) VALUES ($1,$2,$3,$4)`, [
48
+ id,
49
+ encoded.formatVersion,
50
+ new Uint8Array(encoded.payloadBytes),
51
+ new Uint8Array(encoded.semanticProjectionBytes)
52
+ ]);
53
+ return EnqueueResults.Inserted({ jobId: id });
54
+ });
55
+ //# sourceMappingURL=Producer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Producer.js","sourceRoot":"","sources":["../../../src/internal/postgresql/Producer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { Effect } from "effect";
2
+ import type { ApplicationAdapter } from "../../PostgreSqlTransaction.js";
3
+ /** Explicit bounded introspection of only the two configured relations, never DDL. */
4
+ export declare const ready: (adapter: ApplicationAdapter, jobs: string, payloads: string) => Effect.Effect<undefined, import("../../PostgreSqlTransaction.js").PostgreSqlError, never>;
5
+ //# sourceMappingURL=Readiness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Readiness.d.ts","sourceRoot":"","sources":["../../../src/internal/postgresql/Readiness.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE/B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAA;AAExE,sFAAsF;AACtF,eAAO,MAAM,KAAK,YAAa,kBAAkB,QAAQ,MAAM,YAAY,MAAM,8FA6E9E,CAAA"}
@@ -0,0 +1,53 @@
1
+ import { Effect } from "effect";
2
+ import { PostgreSqlFailure } from "../../PostgreSqlTransaction.js";
3
+ /** Explicit bounded introspection of only the two configured relations, never DDL. */
4
+ export const ready = (adapter, jobs, payloads) => adapter.ownedTransaction((query) => Effect.gen(function* () {
5
+ yield* query.query(`SELECT id,operation,operation_id,slot,queue,kind,version,policy,initial_available_at,
6
+ state,available_at,updated_at,attempts_made,stalled_count,lifecycle_version,lease_token,lease_expires_at,
7
+ completed_at,last_failure_code,cleanup_at FROM ${jobs} LIMIT 0`);
8
+ yield* query.query(`SELECT job_id,format_version,payload,projection FROM ${payloads} LIMIT 0`);
9
+ const constraints = yield* query.query(`SELECT c.conrelid=$1::regclass AS jobs,c.conrelid=$2::regclass AS payloads,c.contype AS kind,
10
+ ARRAY(SELECT a.attname::text FROM unnest(c.conkey) WITH ORDINALITY k(n,i)
11
+ JOIN pg_catalog.pg_attribute a ON a.attrelid=c.conrelid AND a.attnum=k.n ORDER BY k.i) AS columns,
12
+ c.confrelid=$1::regclass AS target_jobs,c.confdeltype AS deletion,
13
+ ARRAY(SELECT a.attname::text FROM unnest(c.confkey) WITH ORDINALITY k(n,i)
14
+ JOIN pg_catalog.pg_attribute a ON a.attrelid=c.confrelid AND a.attnum=k.n ORDER BY k.i) AS target_columns
15
+ FROM pg_catalog.pg_constraint c WHERE c.conrelid IN ($1::regclass,$2::regclass)`, [jobs, payloads]);
16
+ const names = (values, expected) => Array.isArray(values) &&
17
+ values.length === expected.length &&
18
+ values.every((value, i) => value === expected[i]);
19
+ const has = (table, kind, columns) => constraints.some((c) => c[table] === true && c.kind === kind && names(c.columns, columns));
20
+ const fk = constraints.some((c) => c.payloads === true &&
21
+ c.kind === "f" &&
22
+ names(c.columns, ["job_id"]) &&
23
+ c.target_jobs === true &&
24
+ names(c.target_columns, ["id"]) &&
25
+ c.deletion === "c");
26
+ if (!has("jobs", "p", ["id"]) ||
27
+ !has("jobs", "u", ["operation", "operation_id", "slot"]) ||
28
+ !has("jobs", "u", ["lease_token"]) ||
29
+ !has("payloads", "p", ["job_id"]) ||
30
+ !fk) {
31
+ return yield* new PostgreSqlFailure({ commitKnowledge: "NotCommitted" });
32
+ }
33
+ const indexes = yield* query.query(`SELECT ARRAY(SELECT a.attname::text FROM unnest(i.indkey::smallint[]) WITH ORDINALITY k(n,o)
34
+ JOIN pg_catalog.pg_attribute a ON a.attrelid=i.indrelid AND a.attnum=k.n ORDER BY k.o) AS columns,
35
+ pg_catalog.pg_get_expr(i.indpred,i.indrelid) AS predicate FROM pg_catalog.pg_index i
36
+ WHERE i.indrelid=$1::regclass AND i.indisvalid AND i.indisready`, [jobs]);
37
+ const required = [
38
+ {
39
+ columns: ["queue", "kind", "version", "available_at", "id"],
40
+ predicate: "state=ANYARRAY['Pending','RetryScheduled']"
41
+ },
42
+ { columns: ["lease_expires_at", "id"], predicate: "state='Active'" },
43
+ { columns: ["cleanup_at", "id"], predicate: "state=ANYARRAY['Completed','Dead']" }
44
+ ];
45
+ for (const expected of required) {
46
+ if (!indexes.some((i) => names(i.columns, expected.columns) &&
47
+ typeof i.predicate === "string" &&
48
+ i.predicate.replace(/\s|\(|\)|::text/g, "") === expected.predicate)) {
49
+ return yield* new PostgreSqlFailure({ commitKnowledge: "NotCommitted" });
50
+ }
51
+ }
52
+ }));
53
+ //# sourceMappingURL=Readiness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Readiness.js","sourceRoot":"","sources":["../../../src/internal/postgresql/Readiness.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import { Effect, Result } from "effect";
2
+ import * as Lifecycle from "../../JobLifecycle.js";
3
+ import { JobStoreProtocolError } from "../../JobStore.js";
4
+ import type { ClaimedJob } from "../../JobStore.js";
5
+ import type { TransactionQuery } from "../../PostgreSqlTransaction.js";
6
+ export declare const snapshot: (row: Record<string, unknown>) => Result.Result<{
7
+ readonly jobId: string & import("effect/Brand").Brand<"effect-jobs/JobId">;
8
+ readonly policy: {
9
+ readonly leaseDurationMillis: number;
10
+ readonly attemptTimeoutMillis: number;
11
+ readonly maxAttempts: number;
12
+ readonly maxStalledCount: number;
13
+ readonly retrySchedule: {
14
+ readonly _tag: "FixedDelayV1";
15
+ readonly delayMillis: number;
16
+ };
17
+ readonly completedRetention: {
18
+ readonly _tag: "Forever";
19
+ } | {
20
+ readonly _tag: "Duration";
21
+ readonly millis: number;
22
+ };
23
+ readonly deadRetention: {
24
+ readonly _tag: "Forever";
25
+ } | {
26
+ readonly _tag: "Duration";
27
+ readonly millis: number;
28
+ };
29
+ };
30
+ readonly state: "Active" | "Completed" | "Dead" | "Isolated" | "Pending" | "RetryScheduled";
31
+ readonly availableAt: number;
32
+ readonly updatedAt: number;
33
+ readonly attemptsMade: number;
34
+ readonly stalledCount: number;
35
+ readonly lifecycleVersion: number;
36
+ readonly leaseToken: string | null;
37
+ readonly leaseExpiresAt: number | null;
38
+ readonly completedAt: number | null;
39
+ readonly lastFailureCode: string | null;
40
+ }, Lifecycle.JobLifecycleError>;
41
+ export declare const claimArtifact: (row: Record<string, unknown>, stored: Lifecycle.JobSnapshot) => Result.Result<ClaimedJob, Lifecycle.JobLifecycleError>;
42
+ export declare const fromResult: <A>(result: Result.Result<A, Lifecycle.JobLifecycleError>) => Effect.Effect<never, JobStoreProtocolError, never> | Effect.Effect<A, never, never>;
43
+ export declare const dbTime: (query: TransactionQuery) => Effect.Effect<number, JobStoreProtocolError | import("../../PostgreSqlTransaction.js").PostgreSqlError, never>;
44
+ export declare const writeSnapshot: (query: TransactionQuery, jobs: string, row: Lifecycle.JobSnapshot) => Effect.Effect<readonly Record<string, unknown>[], import("../../PostgreSqlTransaction.js").PostgreSqlError, never>;
45
+ //# sourceMappingURL=Rows.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Rows.d.ts","sourceRoot":"","sources":["../../../src/internal/postgresql/Rows.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAA;AAC/C,OAAO,KAAK,SAAS,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAA;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAEnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAA;AAKtE,eAAO,MAAM,QAAQ,QAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+BAcjD,CAAA;AACJ,eAAO,MAAM,aAAa,QACnB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,UACpB,SAAS,CAAC,WAAW,KAC5B,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,iBAAiB,CAyBnD,CAAA;AACL,eAAO,MAAM,UAAU,GAAI,CAAC,UAAU,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,SAAS,CAAC,iBAAiB,CAAC,wFAU/E,CAAA;AACJ,eAAO,MAAM,MAAM,UAAW,gBAAgB,mHASzC,CAAA;AACL,eAAO,MAAM,aAAa,UACjB,gBAAgB,QACjB,MAAM,OACP,SAAS,CAAC,WAAW,uHA2B3B,CAAA"}
@@ -0,0 +1,75 @@
1
+ import { Effect, Result, Schema } from "effect";
2
+ import * as Lifecycle from "../../JobLifecycle.js";
3
+ import { JobStoreProtocolError } from "../../JobStore.js";
4
+ import { EpochMillis } from "../../JobPolicy.js";
5
+ /** pg int8 is text by default; accept only exact bounded decimal integer values. */
6
+ const integer = (value) => typeof value === "string" && /^(0|[1-9][0-9]*)$/.test(value) ? Number(value) : value;
7
+ export const snapshot = (row) => Lifecycle.validateSnapshot({
8
+ jobId: row.id,
9
+ policy: row.policy,
10
+ state: row.state,
11
+ availableAt: integer(row.available_at),
12
+ updatedAt: integer(row.updated_at),
13
+ attemptsMade: integer(row.attempts_made),
14
+ stalledCount: integer(row.stalled_count),
15
+ lifecycleVersion: integer(row.lifecycle_version),
16
+ leaseToken: row.lease_token,
17
+ leaseExpiresAt: row.lease_expires_at === null ? null : integer(row.lease_expires_at),
18
+ completedAt: row.completed_at === null ? null : integer(row.completed_at),
19
+ lastFailureCode: row.last_failure_code
20
+ });
21
+ export const claimArtifact = (row, stored) => Result.map(Lifecycle.ownershipOf(stored), (ownership) => ({
22
+ ownership,
23
+ snapshot: stored,
24
+ prepared: {
25
+ catalog: { queue: row.queue, kind: row.kind, version: row.version },
26
+ producer: {
27
+ operation: row.operation,
28
+ operationId: row.operation_id,
29
+ slot: row.slot
30
+ },
31
+ policy: row.policy,
32
+ ...(row.initial_available_at === null
33
+ ? {}
34
+ : { availableAt: integer(row.initial_available_at) }),
35
+ encoded: {
36
+ formatVersion: row.format_version,
37
+ payloadBytes: row.payload instanceof Uint8Array ? new Uint8Array(row.payload) : row.payload,
38
+ semanticProjectionBytes: row.projection instanceof Uint8Array
39
+ ? new Uint8Array(row.projection)
40
+ : row.projection
41
+ }
42
+ }
43
+ }));
44
+ export const fromResult = (result) => Result.match(result, {
45
+ onSuccess: Effect.succeed,
46
+ onFailure: (error) => Effect.fail(new JobStoreProtocolError({
47
+ reason: error.reason === "invalid-command" ? "invalid-input" : "invalid-artifact"
48
+ }))
49
+ });
50
+ export const dbTime = (query) => query
51
+ .query("SELECT floor(extract(epoch FROM clock_timestamp()) * 1000)::bigint AS now")
52
+ .pipe(Effect.flatMap((rows) => Schema.decodeUnknownEffect(EpochMillis)(integer(rows[0]?.now)).pipe(Effect.mapError(() => new JobStoreProtocolError({ reason: "invalid-artifact" })))));
53
+ export const writeSnapshot = (query, jobs, row) => {
54
+ const retention = row.state === "Completed" ? row.policy.completedRetention : row.policy.deadRetention;
55
+ const expiry = row.completedAt !== null && retention._tag === "Duration"
56
+ ? Lifecycle.addTimestamp(row.completedAt, retention.millis)
57
+ : null;
58
+ const cleanupAt = expiry !== null && Result.isSuccess(expiry) ? expiry.success : null;
59
+ return query.query(`UPDATE ${jobs} SET state=$2,available_at=$3,updated_at=$4,attempts_made=$5,stalled_count=$6,
60
+ lifecycle_version=$7,lease_token=$8,lease_expires_at=$9,completed_at=$10,last_failure_code=$11,cleanup_at=$12 WHERE id=$1`, [
61
+ row.jobId,
62
+ row.state,
63
+ row.availableAt,
64
+ row.updatedAt,
65
+ row.attemptsMade,
66
+ row.stalledCount,
67
+ row.lifecycleVersion,
68
+ row.leaseToken,
69
+ row.leaseExpiresAt,
70
+ row.completedAt,
71
+ row.lastFailureCode,
72
+ cleanupAt
73
+ ]);
74
+ };
75
+ //# sourceMappingURL=Rows.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Rows.js","sourceRoot":"","sources":["../../../src/internal/postgresql/Rows.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import * as Store from "../../JobStore.js";
2
+ import type { ApplicationAdapter, PostgreSqlError } from "../../PostgreSqlTransaction.js";
3
+ export declare const makeStore: (adapter: ApplicationAdapter, jobs: string, payloads: string, budget: number) => Store.JobStoreService<PostgreSqlError>;
4
+ export declare const makeCleanup: (adapter: ApplicationAdapter, jobs: string) => Store.JobCleanupService<PostgreSqlError>;
5
+ //# sourceMappingURL=Store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Store.d.ts","sourceRoot":"","sources":["../../../src/internal/postgresql/Store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAA;AAG1C,OAAO,KAAK,EACV,kBAAkB,EAClB,eAAe,EAEhB,MAAM,gCAAgC,CAAA;AA+CvC,eAAO,MAAM,SAAS,YACX,kBAAkB,QACrB,MAAM,YACF,MAAM,UACR,MAAM,KACb,KAAK,CAAC,eAAe,CAAC,eAAe,CAoOvC,CAAA;AAED,eAAO,MAAM,WAAW,YACb,kBAAkB,QACrB,MAAM,KACX,KAAK,CAAC,iBAAiB,CAAC,eAAe,CA4BxC,CAAA"}