@satorio/machinery 0.2.1

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 (341) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +71 -0
  3. package/dictionary/all.json +4656 -0
  4. package/dictionary/all.toon +639 -0
  5. package/dictionary/core.json +221 -0
  6. package/dictionary/core.toon +33 -0
  7. package/dictionary/graphql.json +212 -0
  8. package/dictionary/graphql.toon +32 -0
  9. package/dictionary/http.json +113 -0
  10. package/dictionary/http.toon +21 -0
  11. package/dictionary/identifiers.json +266 -0
  12. package/dictionary/identifiers.toon +38 -0
  13. package/dictionary/index.json +96 -0
  14. package/dictionary/index.toon +18 -0
  15. package/dictionary/integration.json +131 -0
  16. package/dictionary/integration.toon +23 -0
  17. package/dictionary/money.json +383 -0
  18. package/dictionary/money.toon +51 -0
  19. package/dictionary/ports.json +392 -0
  20. package/dictionary/ports.toon +52 -0
  21. package/dictionary/postgres.json +473 -0
  22. package/dictionary/postgres.toon +61 -0
  23. package/dictionary/publishing.json +131 -0
  24. package/dictionary/publishing.toon +23 -0
  25. package/dictionary/queue.json +365 -0
  26. package/dictionary/queue.toon +49 -0
  27. package/dictionary/reference/api.mdx +843 -0
  28. package/dictionary/reference/uk/api.mdx +844 -0
  29. package/dictionary/storage.json +194 -0
  30. package/dictionary/storage.toon +30 -0
  31. package/dictionary/testing.json +707 -0
  32. package/dictionary/testing.toon +87 -0
  33. package/dictionary/time.json +311 -0
  34. package/dictionary/time.toon +43 -0
  35. package/dictionary/vitest.json +356 -0
  36. package/dictionary/vitest.toon +48 -0
  37. package/dictionary/workflow.json +185 -0
  38. package/dictionary/workflow.toon +29 -0
  39. package/dist/bin/command.d.ts +45 -0
  40. package/dist/bin/command.js +113 -0
  41. package/dist/bin.d.ts +2 -0
  42. package/dist/bin.js +11 -0
  43. package/dist/core/bigint-json.d.ts +6 -0
  44. package/dist/core/bigint-json.js +6 -0
  45. package/dist/core/closed-set.d.ts +14 -0
  46. package/dist/core/closed-set.js +8 -0
  47. package/dist/core/domain-error.d.ts +8 -0
  48. package/dist/core/domain-error.js +11 -0
  49. package/dist/core/environment.d.ts +124 -0
  50. package/dist/core/environment.js +115 -0
  51. package/dist/core/index.d.ts +13 -0
  52. package/dist/core/index.js +13 -0
  53. package/dist/core/ulid.d.ts +27 -0
  54. package/dist/core/ulid.js +27 -0
  55. package/dist/graphql/builder.d.ts +36 -0
  56. package/dist/graphql/builder.js +35 -0
  57. package/dist/graphql/context.d.ts +36 -0
  58. package/dist/graphql/context.js +69 -0
  59. package/dist/graphql/failure-classification.d.ts +11 -0
  60. package/dist/graphql/failure-classification.js +1 -0
  61. package/dist/graphql/failures.d.ts +62 -0
  62. package/dist/graphql/failures.js +30 -0
  63. package/dist/graphql/graphiql.d.ts +45 -0
  64. package/dist/graphql/graphiql.js +56 -0
  65. package/dist/graphql/index.d.ts +15 -0
  66. package/dist/graphql/index.js +14 -0
  67. package/dist/graphql/layer.d.ts +15 -0
  68. package/dist/graphql/layer.js +23 -0
  69. package/dist/graphql/request-handler.d.ts +26 -0
  70. package/dist/graphql/request-handler.js +33 -0
  71. package/dist/graphql/server.d.ts +19 -0
  72. package/dist/graphql/server.js +16 -0
  73. package/dist/graphql/settings.d.ts +55 -0
  74. package/dist/graphql/settings.js +82 -0
  75. package/dist/http/health.d.ts +70 -0
  76. package/dist/http/health.js +60 -0
  77. package/dist/http/index.d.ts +5 -0
  78. package/dist/http/index.js +5 -0
  79. package/dist/identifiers/client-code.d.ts +37 -0
  80. package/dist/identifiers/client-code.js +41 -0
  81. package/dist/identifiers/creditor-reference.d.ts +38 -0
  82. package/dist/identifiers/creditor-reference.js +32 -0
  83. package/dist/identifiers/damm.d.ts +22 -0
  84. package/dist/identifiers/damm.js +50 -0
  85. package/dist/identifiers/document-number.d.ts +68 -0
  86. package/dist/identifiers/document-number.js +73 -0
  87. package/dist/identifiers/document-numbers.d.ts +27 -0
  88. package/dist/identifiers/document-numbers.js +16 -0
  89. package/dist/identifiers/failures.d.ts +46 -0
  90. package/dist/identifiers/failures.js +48 -0
  91. package/dist/identifiers/index.d.ts +14 -0
  92. package/dist/identifiers/index.js +13 -0
  93. package/dist/identifiers/next-document-number.d.ts +26 -0
  94. package/dist/identifiers/next-document-number.js +31 -0
  95. package/dist/identifiers/ulid.d.ts +28 -0
  96. package/dist/identifiers/ulid.js +71 -0
  97. package/dist/integration/external-http-client.d.ts +22 -0
  98. package/dist/integration/external-http-client.js +74 -0
  99. package/dist/integration/index.d.ts +12 -0
  100. package/dist/integration/index.js +12 -0
  101. package/dist/integration/layer.d.ts +19 -0
  102. package/dist/integration/layer.js +30 -0
  103. package/dist/integration/retry.d.ts +65 -0
  104. package/dist/integration/retry.js +54 -0
  105. package/dist/integration/settings.d.ts +73 -0
  106. package/dist/integration/settings.js +92 -0
  107. package/dist/money/amount.d.ts +60 -0
  108. package/dist/money/amount.js +67 -0
  109. package/dist/money/arithmetic.d.ts +60 -0
  110. package/dist/money/arithmetic.js +73 -0
  111. package/dist/money/currency.d.ts +25 -0
  112. package/dist/money/currency.js +24 -0
  113. package/dist/money/decimal.d.ts +29 -0
  114. package/dist/money/decimal.js +39 -0
  115. package/dist/money/exchange-rate.d.ts +32 -0
  116. package/dist/money/exchange-rate.js +28 -0
  117. package/dist/money/failures.d.ts +86 -0
  118. package/dist/money/failures.js +97 -0
  119. package/dist/money/index.d.ts +15 -0
  120. package/dist/money/index.js +15 -0
  121. package/dist/money/percent.d.ts +35 -0
  122. package/dist/money/percent.js +50 -0
  123. package/dist/money/schema.d.ts +25 -0
  124. package/dist/money/schema.js +41 -0
  125. package/dist/ports/blob-store.d.ts +42 -0
  126. package/dist/ports/blob-store.js +13 -0
  127. package/dist/ports/document-number-counter.d.ts +36 -0
  128. package/dist/ports/document-number-counter.js +12 -0
  129. package/dist/ports/event-publisher.d.ts +29 -0
  130. package/dist/ports/event-publisher.js +13 -0
  131. package/dist/ports/external-http-client.d.ts +60 -0
  132. package/dist/ports/external-http-client.js +25 -0
  133. package/dist/ports/index.d.ts +17 -0
  134. package/dist/ports/index.js +17 -0
  135. package/dist/ports/integration-event-outbox.d.ts +44 -0
  136. package/dist/ports/integration-event-outbox.js +13 -0
  137. package/dist/ports/port-unavailable.d.ts +21 -0
  138. package/dist/ports/port-unavailable.js +30 -0
  139. package/dist/ports/processed-event-registry.d.ts +57 -0
  140. package/dist/ports/processed-event-registry.js +24 -0
  141. package/dist/ports/queue-message-producer.d.ts +26 -0
  142. package/dist/ports/queue-message-producer.js +12 -0
  143. package/dist/ports/queue-message-source.d.ts +39 -0
  144. package/dist/ports/queue-message-source.js +13 -0
  145. package/dist/ports/readiness-probe.d.ts +27 -0
  146. package/dist/ports/readiness-probe.js +13 -0
  147. package/dist/ports/transaction-boundary.d.ts +28 -0
  148. package/dist/ports/transaction-boundary.js +13 -0
  149. package/dist/postgres/client.d.ts +51 -0
  150. package/dist/postgres/client.js +81 -0
  151. package/dist/postgres/document-number-counter.d.ts +14 -0
  152. package/dist/postgres/document-number-counter.js +27 -0
  153. package/dist/postgres/failures.d.ts +28 -0
  154. package/dist/postgres/failures.js +18 -0
  155. package/dist/postgres/index.d.ts +18 -0
  156. package/dist/postgres/index.js +18 -0
  157. package/dist/postgres/integration-event-outbox.d.ts +15 -0
  158. package/dist/postgres/integration-event-outbox.js +60 -0
  159. package/dist/postgres/jsonb-value.d.ts +10 -0
  160. package/dist/postgres/jsonb-value.js +9 -0
  161. package/dist/postgres/layer.d.ts +57 -0
  162. package/dist/postgres/layer.js +72 -0
  163. package/dist/postgres/migrations/advisory-lock.d.ts +47 -0
  164. package/dist/postgres/migrations/advisory-lock.js +59 -0
  165. package/dist/postgres/migrations/runner.d.ts +56 -0
  166. package/dist/postgres/migrations/runner.js +69 -0
  167. package/dist/postgres/migrations/sql-file-loader.d.ts +59 -0
  168. package/dist/postgres/migrations/sql-file-loader.js +99 -0
  169. package/dist/postgres/processed-event-registry.d.ts +13 -0
  170. package/dist/postgres/processed-event-registry.js +44 -0
  171. package/dist/postgres/readiness-probe.d.ts +27 -0
  172. package/dist/postgres/readiness-probe.js +33 -0
  173. package/dist/postgres/settings.d.ts +134 -0
  174. package/dist/postgres/settings.js +210 -0
  175. package/dist/postgres/sql/0001_processed_event.sql +4 -0
  176. package/dist/postgres/sql/0002_integration_event_outbox.sql +13 -0
  177. package/dist/postgres/sql/0003_document_number_counter.sql +6 -0
  178. package/dist/postgres/sql-failure.d.ts +19 -0
  179. package/dist/postgres/sql-failure.js +22 -0
  180. package/dist/postgres/store-failure.d.ts +17 -0
  181. package/dist/postgres/store-failure.js +16 -0
  182. package/dist/postgres/transaction-boundary.d.ts +13 -0
  183. package/dist/postgres/transaction-boundary.js +21 -0
  184. package/dist/publishing/event-publisher.sns.d.ts +66 -0
  185. package/dist/publishing/event-publisher.sns.js +75 -0
  186. package/dist/publishing/event-publisher.stdout.d.ts +15 -0
  187. package/dist/publishing/event-publisher.stdout.js +24 -0
  188. package/dist/publishing/index.d.ts +10 -0
  189. package/dist/publishing/index.js +10 -0
  190. package/dist/publishing/layer.d.ts +25 -0
  191. package/dist/publishing/layer.js +39 -0
  192. package/dist/publishing/settings.d.ts +60 -0
  193. package/dist/publishing/settings.js +85 -0
  194. package/dist/queue/consumer.d.ts +91 -0
  195. package/dist/queue/consumer.js +92 -0
  196. package/dist/queue/envelope.d.ts +39 -0
  197. package/dist/queue/envelope.js +39 -0
  198. package/dist/queue/failures.d.ts +33 -0
  199. package/dist/queue/failures.js +15 -0
  200. package/dist/queue/index.d.ts +14 -0
  201. package/dist/queue/index.js +14 -0
  202. package/dist/queue/layer.d.ts +33 -0
  203. package/dist/queue/layer.js +58 -0
  204. package/dist/queue/message-codec.d.ts +43 -0
  205. package/dist/queue/message-codec.js +33 -0
  206. package/dist/queue/queue-message-producer.d.ts +61 -0
  207. package/dist/queue/queue-message-producer.js +52 -0
  208. package/dist/queue/queue-message-source.d.ts +93 -0
  209. package/dist/queue/queue-message-source.js +86 -0
  210. package/dist/queue/readiness.d.ts +78 -0
  211. package/dist/queue/readiness.js +86 -0
  212. package/dist/queue/settings.d.ts +106 -0
  213. package/dist/queue/settings.js +160 -0
  214. package/dist/storage/blob-store.d.ts +84 -0
  215. package/dist/storage/blob-store.js +109 -0
  216. package/dist/storage/index.d.ts +9 -0
  217. package/dist/storage/index.js +9 -0
  218. package/dist/storage/layer.d.ts +17 -0
  219. package/dist/storage/layer.js +30 -0
  220. package/dist/storage/settings.d.ts +48 -0
  221. package/dist/storage/settings.js +65 -0
  222. package/dist/testing/blob-store.d.ts +27 -0
  223. package/dist/testing/blob-store.js +45 -0
  224. package/dist/testing/clock.d.ts +29 -0
  225. package/dist/testing/clock.js +41 -0
  226. package/dist/testing/dna-perturbator/attention.d.ts +55 -0
  227. package/dist/testing/dna-perturbator/attention.js +49 -0
  228. package/dist/testing/dna-perturbator/chains.d.ts +31 -0
  229. package/dist/testing/dna-perturbator/chains.js +53 -0
  230. package/dist/testing/dna-perturbator/report.d.ts +12 -0
  231. package/dist/testing/dna-perturbator/report.js +22 -0
  232. package/dist/testing/dna-perturbator/verdict.d.ts +26 -0
  233. package/dist/testing/dna-perturbator/verdict.js +28 -0
  234. package/dist/testing/dna-perturbator.d.ts +48 -0
  235. package/dist/testing/dna-perturbator.js +145 -0
  236. package/dist/testing/document-number-counter.d.ts +29 -0
  237. package/dist/testing/document-number-counter.js +39 -0
  238. package/dist/testing/event-publisher.d.ts +28 -0
  239. package/dist/testing/event-publisher.js +33 -0
  240. package/dist/testing/external-http-client.d.ts +29 -0
  241. package/dist/testing/external-http-client.js +49 -0
  242. package/dist/testing/index.d.ts +24 -0
  243. package/dist/testing/index.js +24 -0
  244. package/dist/testing/integration-event-outbox.d.ts +37 -0
  245. package/dist/testing/integration-event-outbox.js +67 -0
  246. package/dist/testing/mutation-settings.d.ts +71 -0
  247. package/dist/testing/mutation-settings.js +57 -0
  248. package/dist/testing/postgres-rows.d.ts +12 -0
  249. package/dist/testing/postgres-rows.js +19 -0
  250. package/dist/testing/processed-event-registry.d.ts +25 -0
  251. package/dist/testing/processed-event-registry.js +39 -0
  252. package/dist/testing/queue-message-producer.d.ts +27 -0
  253. package/dist/testing/queue-message-producer.js +41 -0
  254. package/dist/testing/queue-message-source.d.ts +54 -0
  255. package/dist/testing/queue-message-source.js +71 -0
  256. package/dist/testing/quiet-reporter.d.ts +86 -0
  257. package/dist/testing/quiet-reporter.js +81 -0
  258. package/dist/testing/readiness-probe.d.ts +27 -0
  259. package/dist/testing/readiness-probe.js +33 -0
  260. package/dist/testing/scenario.d.ts +94 -0
  261. package/dist/testing/scenario.js +81 -0
  262. package/dist/testing/transaction-boundary.d.ts +30 -0
  263. package/dist/testing/transaction-boundary.js +36 -0
  264. package/dist/testing/typed-failure.d.ts +8 -0
  265. package/dist/testing/typed-failure.js +15 -0
  266. package/dist/time/calendar-day.d.ts +83 -0
  267. package/dist/time/calendar-day.js +112 -0
  268. package/dist/time/failures.d.ts +51 -0
  269. package/dist/time/failures.js +56 -0
  270. package/dist/time/index.d.ts +11 -0
  271. package/dist/time/index.js +11 -0
  272. package/dist/time/instant.d.ts +64 -0
  273. package/dist/time/instant.js +67 -0
  274. package/dist/time/period.d.ts +45 -0
  275. package/dist/time/period.js +55 -0
  276. package/dist/vitest/container-reuse.d.ts +14 -0
  277. package/dist/vitest/container-reuse.js +15 -0
  278. package/dist/vitest/dotenv.d.ts +16 -0
  279. package/dist/vitest/dotenv.js +48 -0
  280. package/dist/vitest/effect-single-instance.d.ts +36 -0
  281. package/dist/vitest/effect-single-instance.js +125 -0
  282. package/dist/vitest/fast-check-single-instance.d.ts +11 -0
  283. package/dist/vitest/fast-check-single-instance.js +26 -0
  284. package/dist/vitest/index.d.ts +31 -0
  285. package/dist/vitest/index.js +30 -0
  286. package/dist/vitest/localstack-container.d.ts +32 -0
  287. package/dist/vitest/localstack-container.js +55 -0
  288. package/dist/vitest/port-contract-tester.d.ts +8 -0
  289. package/dist/vitest/port-contract-tester.js +1 -0
  290. package/dist/vitest/port-contracts/blob-store.contract.d.ts +22 -0
  291. package/dist/vitest/port-contracts/blob-store.contract.js +108 -0
  292. package/dist/vitest/port-contracts/document-number-counter.contract.d.ts +18 -0
  293. package/dist/vitest/port-contracts/document-number-counter.contract.js +90 -0
  294. package/dist/vitest/port-contracts/event-publisher.contract.d.ts +35 -0
  295. package/dist/vitest/port-contracts/event-publisher.contract.js +67 -0
  296. package/dist/vitest/port-contracts/external-http-client.contract.d.ts +35 -0
  297. package/dist/vitest/port-contracts/external-http-client.contract.js +52 -0
  298. package/dist/vitest/port-contracts/integration-event-outbox.contract.d.ts +23 -0
  299. package/dist/vitest/port-contracts/integration-event-outbox.contract.js +75 -0
  300. package/dist/vitest/port-contracts/processed-event-registry.contract.d.ts +18 -0
  301. package/dist/vitest/port-contracts/processed-event-registry.contract.js +84 -0
  302. package/dist/vitest/port-contracts/queue-message-producer.contract.d.ts +26 -0
  303. package/dist/vitest/port-contracts/queue-message-producer.contract.js +48 -0
  304. package/dist/vitest/port-contracts/queue-message-source.contract.d.ts +29 -0
  305. package/dist/vitest/port-contracts/queue-message-source.contract.js +71 -0
  306. package/dist/vitest/port-contracts/readiness-probe.contract.d.ts +18 -0
  307. package/dist/vitest/port-contracts/readiness-probe.contract.js +41 -0
  308. package/dist/vitest/port-contracts/transaction-boundary.contract.d.ts +21 -0
  309. package/dist/vitest/port-contracts/transaction-boundary.contract.js +64 -0
  310. package/dist/vitest/postgres-container.d.ts +57 -0
  311. package/dist/vitest/postgres-container.js +118 -0
  312. package/dist/vitest/reader-port-contract.d.ts +41 -0
  313. package/dist/vitest/reader-port-contract.js +43 -0
  314. package/dist/vitest/repo-source-files.d.ts +37 -0
  315. package/dist/vitest/repo-source-files.js +61 -0
  316. package/dist/vitest/reset-tables.d.ts +18 -0
  317. package/dist/vitest/reset-tables.js +30 -0
  318. package/dist/vitest/settings-contract.d.ts +38 -0
  319. package/dist/vitest/settings-contract.js +77 -0
  320. package/dist/vitest/stub-server.d.ts +43 -0
  321. package/dist/vitest/stub-server.js +60 -0
  322. package/dist/vitest/term-registry.json +730 -0
  323. package/dist/vitest/testclock-fork-isolated-files.d.ts +13 -0
  324. package/dist/vitest/testclock-fork-isolated-files.js +18 -0
  325. package/dist/vitest/testclock-fork-isolation.d.ts +77 -0
  326. package/dist/vitest/testclock-fork-isolation.js +188 -0
  327. package/dist/workflow/claim-once.d.ts +16 -0
  328. package/dist/workflow/claim-once.js +9 -0
  329. package/dist/workflow/failures.d.ts +47 -0
  330. package/dist/workflow/failures.js +22 -0
  331. package/dist/workflow/index.d.ts +12 -0
  332. package/dist/workflow/index.js +12 -0
  333. package/dist/workflow/on-claim.d.ts +17 -0
  334. package/dist/workflow/on-claim.js +8 -0
  335. package/dist/workflow/publish-pending-events.d.ts +31 -0
  336. package/dist/workflow/publish-pending-events.js +31 -0
  337. package/dist/workflow/transactionally.d.ts +8 -0
  338. package/dist/workflow/transactionally.js +8 -0
  339. package/dist/workflow/versioned-payload.d.ts +35 -0
  340. package/dist/workflow/versioned-payload.js +43 -0
  341. package/package.json +309 -0
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Public entry to the publishing mechanism: the event publisher, bound to a
3
+ * topic or to one line on stdout. It gives you the `EventPublisher` port bound
4
+ * to SNS or to one JSON line on stdout, with the topic read from one prefixed
5
+ * variable and a loud stand in its place when nobody set it.
6
+ */
7
+ export { snsMessageBodyOf } from './event-publisher.sns.js';
8
+ export { stdoutLineOf } from './event-publisher.stdout.js';
9
+ export { StdoutEventPublisherLive, snsEventPublisherLive } from './layer.js';
10
+ export { DEFAULT_EVENT_CHANNEL, ENVIRONMENT, type SnsPublisherSettings, snsPublisherSettings, topicArnVariable, } from './settings.js';
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Public entry to the publishing mechanism: the event publisher, bound to a
3
+ * topic or to one line on stdout. It gives you the `EventPublisher` port bound
4
+ * to SNS or to one JSON line on stdout, with the topic read from one prefixed
5
+ * variable and a loud stand in its place when nobody set it.
6
+ */
7
+ export { snsMessageBodyOf } from './event-publisher.sns.js';
8
+ export { stdoutLineOf } from './event-publisher.stdout.js';
9
+ export { StdoutEventPublisherLive, snsEventPublisherLive } from './layer.js';
10
+ export { DEFAULT_EVENT_CHANNEL, ENVIRONMENT, snsPublisherSettings, topicArnVariable, } from './settings.js';
@@ -0,0 +1,25 @@
1
+ import { EventPublisher } from '@satorio/machinery/ports';
2
+ import { type ConfigError, Layer } from 'effect';
3
+ import { type ClosableSnsTransport } from './event-publisher.sns.js';
4
+ import { type SnsPublisherSettings } from './settings.js';
5
+ /**
6
+ * An SNS publisher built from environment variables with the given
7
+ * prefix. With no topic set it mounts the loud stand and logs the one
8
+ * refusal every later publish repeats, so startup carries on and no
9
+ * event goes missing in silence. The transport is a parameter, so a test
10
+ * substitutes its own without touching the wiring.
11
+ *
12
+ * @internal
13
+ */
14
+ export declare const snsEventPublisherFromEnvironmentLive: (variablePrefix: string, openTransport: (settings: SnsPublisherSettings) => ClosableSnsTransport) => Layer.Layer<EventPublisher, ConfigError.ConfigError>;
15
+ /**
16
+ * The SNS publisher on the real AWS SDK transport, reading the variables
17
+ * this prefix names.
18
+ */
19
+ export declare const snsEventPublisherLive: (variablePrefix: string) => Layer.Layer<EventPublisher, ConfigError.ConfigError>;
20
+ /**
21
+ * The stdout publisher, mounted: one JSON line per event under the
22
+ * channel `EVENT_CHANNEL` names. Nothing here can refuse, so the layer
23
+ * carries no failure of its own.
24
+ */
25
+ export declare const StdoutEventPublisherLive: Layer.Layer<EventPublisher>;
@@ -0,0 +1,39 @@
1
+ import { refusalText } from '@satorio/machinery/core';
2
+ import { EventPublisher } from '@satorio/machinery/ports';
3
+ import { Console, Effect, Layer, Option } from 'effect';
4
+ import { eventPublisherUnavailableWithoutConfiguration, makeSnsEventPublisher, openSnsTransport, scopedSnsTransport, } from './event-publisher.sns.js';
5
+ import { makeStdoutEventPublisher } from './event-publisher.stdout.js';
6
+ import { configuredTopicArn, eventChannelFromEnvironment, snsPublisherSettings, topicArnRefusal, } from './settings.js';
7
+ /**
8
+ * An SNS publisher built from environment variables with the given
9
+ * prefix. With no topic set it mounts the loud stand and logs the one
10
+ * refusal every later publish repeats, so startup carries on and no
11
+ * event goes missing in silence. The transport is a parameter, so a test
12
+ * substitutes its own without touching the wiring.
13
+ *
14
+ * @internal
15
+ */
16
+ export const snsEventPublisherFromEnvironmentLive = (variablePrefix, openTransport) => Layer.unwrapEffect(Effect.gen(function* () {
17
+ const configured = yield* configuredTopicArn(variablePrefix);
18
+ if (Option.isNone(configured)) {
19
+ const refusal = topicArnRefusal(variablePrefix);
20
+ yield* Effect.logError(refusalText(refusal));
21
+ return Layer.succeed(EventPublisher, eventPublisherUnavailableWithoutConfiguration(refusal));
22
+ }
23
+ return Layer.scoped(EventPublisher, Effect.gen(function* () {
24
+ const settings = yield* snsPublisherSettings(variablePrefix);
25
+ const transport = yield* scopedSnsTransport(() => openTransport(settings));
26
+ return makeSnsEventPublisher(transport, settings);
27
+ }));
28
+ }));
29
+ /**
30
+ * The SNS publisher on the real AWS SDK transport, reading the variables
31
+ * this prefix names.
32
+ */
33
+ export const snsEventPublisherLive = (variablePrefix) => snsEventPublisherFromEnvironmentLive(variablePrefix, openSnsTransport);
34
+ /**
35
+ * The stdout publisher, mounted: one JSON line per event under the
36
+ * channel `EVENT_CHANNEL` names. Nothing here can refuse, so the layer
37
+ * carries no failure of its own.
38
+ */
39
+ export const StdoutEventPublisherLive = Layer.effect(EventPublisher, Effect.map(eventChannelFromEnvironment, (channel) => makeStdoutEventPublisher(channel, (line) => Console.log(line)))).pipe(Layer.orDie);
@@ -0,0 +1,60 @@
1
+ import { type EnvironmentEntry, type Refusal } from '@satorio/machinery/core';
2
+ import { Config, type Option } from 'effect';
3
+ /**
4
+ * The log channel the stdout publisher writes its events under when
5
+ * nobody names one. A log collector filters on this word, so it has to
6
+ * mean something on its own.
7
+ */
8
+ export declare const DEFAULT_EVENT_CHANNEL = "machinery-integration-events";
9
+ /**
10
+ * Builds the environment variable name from the prefix the application
11
+ * gives at mount time. A per-prefix name lets several topics share one
12
+ * process and stay readable: `EVENTS_TOPIC_ARN`, `AUDIT_TOPIC_ARN`, and
13
+ * so on.
14
+ */
15
+ export declare const topicArnVariable: (variablePrefix: string) => string;
16
+ /**
17
+ * What the SNS publisher needs before it can send: one topic, and the
18
+ * two variables the AWS SDK reads for itself when nobody names them.
19
+ */
20
+ export interface SnsPublisherSettings {
21
+ readonly topicArn: string;
22
+ readonly region: Option.Option<string>;
23
+ readonly endpoint: Option.Option<string>;
24
+ }
25
+ /**
26
+ * The three parts a reader meets when the topic is not set. The mount
27
+ * desk logs this text and every publish of the loud stand fails with it,
28
+ * so an operator reads one sentence rather than two.
29
+ *
30
+ * @internal
31
+ */
32
+ export declare const topicArnRefusal: (variablePrefix: string) => Refusal;
33
+ /**
34
+ * Reads the topic without refusing, so the mount desk can put up the
35
+ * loud stand instead of failing service startup.
36
+ *
37
+ * @internal
38
+ */
39
+ export declare const configuredTopicArn: (variablePrefix: string) => Config.Config<Option.Option<string>>;
40
+ /**
41
+ * Every variable this adapter reads, and the one state each of them
42
+ * stands in. `<PREFIX>` is the prefix the application passes at mount
43
+ * time; `EVENT_CHANNEL` belongs to the stdout publisher, which serves
44
+ * one process and needs no prefix.
45
+ */
46
+ export declare const ENVIRONMENT: readonly EnvironmentEntry[];
47
+ /**
48
+ * Reads every variable the SNS publisher needs under one prefix. A
49
+ * missing or blank topic refuses in three parts; region and endpoint
50
+ * stay `Option.none`, and the SDK decides.
51
+ */
52
+ export declare const snsPublisherSettings: (variablePrefix: string) => Config.Config<SnsPublisherSettings>;
53
+ /**
54
+ * Reads the channel the stdout publisher writes under. Nobody has to set
55
+ * it: an unset channel takes the default rather than refusing, because a
56
+ * line on stdout is readable either way.
57
+ *
58
+ * @internal
59
+ */
60
+ export declare const eventChannelFromEnvironment: Config.Config<string>;
@@ -0,0 +1,85 @@
1
+ import { fallsBackTo, handedOn, optionalText, refuses, requiredText, } from '@satorio/machinery/core';
2
+ import { Config } from 'effect';
3
+ const TOPIC_ARN_SUFFIX = '_TOPIC_ARN';
4
+ const EVENT_CHANNEL = 'EVENT_CHANNEL';
5
+ const REGION = 'AWS_REGION';
6
+ const ENDPOINT = 'AWS_ENDPOINT_URL';
7
+ /**
8
+ * The log channel the stdout publisher writes its events under when
9
+ * nobody names one. A log collector filters on this word, so it has to
10
+ * mean something on its own.
11
+ */
12
+ export const DEFAULT_EVENT_CHANNEL = 'machinery-integration-events';
13
+ /**
14
+ * Builds the environment variable name from the prefix the application
15
+ * gives at mount time. A per-prefix name lets several topics share one
16
+ * process and stay readable: `EVENTS_TOPIC_ARN`, `AUDIT_TOPIC_ARN`, and
17
+ * so on.
18
+ */
19
+ export const topicArnVariable = (variablePrefix) => `${variablePrefix}${TOPIC_ARN_SUFFIX}`;
20
+ /**
21
+ * The three parts a reader meets when the topic is not set. The mount
22
+ * desk logs this text and every publish of the loud stand fails with it,
23
+ * so an operator reads one sentence rather than two.
24
+ *
25
+ * @internal
26
+ */
27
+ export const topicArnRefusal = (variablePrefix) => ({
28
+ what: `${topicArnVariable(variablePrefix)} is not set, so this publisher has no topic.`,
29
+ why: 'One process publishes to several topics, each under its own prefix, so the publisher cannot guess which one you meant.',
30
+ whatToDo: `Set ${topicArnVariable(variablePrefix)} to the topic ARN from the AWS console or your .env, then start the service again.`,
31
+ });
32
+ /**
33
+ * Reads the topic without refusing, so the mount desk can put up the
34
+ * loud stand instead of failing service startup.
35
+ *
36
+ * @internal
37
+ */
38
+ export const configuredTopicArn = (variablePrefix) => optionalText(topicArnVariable(variablePrefix));
39
+ /**
40
+ * Every variable this adapter reads, and the one state each of them
41
+ * stands in. `<PREFIX>` is the prefix the application passes at mount
42
+ * time; `EVENT_CHANNEL` belongs to the stdout publisher, which serves
43
+ * one process and needs no prefix.
44
+ */
45
+ export const ENVIRONMENT = [
46
+ {
47
+ name: TOPIC_ARN_SUFFIX,
48
+ prefixed: true,
49
+ what: 'The SNS topic this publisher sends events to.',
50
+ state: refuses(topicArnRefusal('<PREFIX>')),
51
+ },
52
+ {
53
+ name: EVENT_CHANNEL,
54
+ what: "The word a log collector filters the stdout publisher's lines by.",
55
+ state: fallsBackTo(DEFAULT_EVENT_CHANNEL),
56
+ },
57
+ {
58
+ name: REGION,
59
+ what: 'The region the SNS client talks to.',
60
+ state: handedOn('the AWS SDK finds its own region from the machine it runs on.'),
61
+ },
62
+ {
63
+ name: ENDPOINT,
64
+ what: 'A local stand to talk to instead of real SNS, such as localstack.',
65
+ state: handedOn('the client goes to the real SNS for the region it found.'),
66
+ },
67
+ ];
68
+ /**
69
+ * Reads every variable the SNS publisher needs under one prefix. A
70
+ * missing or blank topic refuses in three parts; region and endpoint
71
+ * stay `Option.none`, and the SDK decides.
72
+ */
73
+ export const snsPublisherSettings = (variablePrefix) => Config.all({
74
+ topicArn: requiredText(topicArnVariable(variablePrefix), topicArnRefusal(variablePrefix)),
75
+ region: optionalText(REGION),
76
+ endpoint: optionalText(ENDPOINT),
77
+ });
78
+ /**
79
+ * Reads the channel the stdout publisher writes under. Nobody has to set
80
+ * it: an unset channel takes the default rather than refusing, because a
81
+ * line on stdout is readable either way.
82
+ *
83
+ * @internal
84
+ */
85
+ export const eventChannelFromEnvironment = Config.string(EVENT_CHANNEL).pipe(Config.withDefault(DEFAULT_EVENT_CHANNEL));
@@ -0,0 +1,91 @@
1
+ import { QueueMessageSource, type QueueMessageSourceUnavailableError } from '@satorio/machinery/ports';
2
+ import type { DateTime } from 'effect';
3
+ import { Effect, Schedule, Stream } from 'effect';
4
+ import type { QueueMessageNotDecodableError } from './failures.js';
5
+ import { type PayloadDecoder } from './message-codec.js';
6
+ /**
7
+ * One message as a handler meets it: the envelope's own fields, and the
8
+ * decoded event itself.
9
+ */
10
+ export interface IncomingQueueMessage<A> {
11
+ readonly eventId: string;
12
+ readonly eventType: string;
13
+ readonly schemaVersion: number;
14
+ readonly occurredAt: DateTime.Utc;
15
+ readonly event: A;
16
+ }
17
+ /**
18
+ * Why a message goes back on the queue: it never decoded, or the handler
19
+ * rejected it.
20
+ */
21
+ export type RedeliveryReason = {
22
+ readonly _tag: 'MessageNotDecodable';
23
+ readonly error: QueueMessageNotDecodableError;
24
+ } | {
25
+ readonly _tag: 'HandlerRejectedMessage';
26
+ readonly error: unknown;
27
+ };
28
+ /**
29
+ * The reason for a message that never decoded.
30
+ */
31
+ export declare const messageNotDecodable: (error: QueueMessageNotDecodableError) => RedeliveryReason;
32
+ /**
33
+ * The reason for a message the handler itself rejected.
34
+ */
35
+ export declare const handlerRejectedMessage: (error: unknown) => RedeliveryReason;
36
+ /**
37
+ * The fate of one message has exactly three endings: acknowledged, left
38
+ * for redelivery, or refused permanently. There is no fourth, silent
39
+ * outcome.
40
+ */
41
+ export type QueueMessageOutcome = {
42
+ readonly _tag: 'MessageAcknowledged';
43
+ readonly messageId: string;
44
+ } | {
45
+ readonly _tag: 'MessageLeftForRedelivery';
46
+ readonly messageId: string;
47
+ readonly reason: RedeliveryReason;
48
+ } | {
49
+ readonly _tag: 'MessageRefusedPermanently';
50
+ readonly messageId: string;
51
+ readonly eventId: string;
52
+ readonly refusal: unknown;
53
+ };
54
+ /**
55
+ * The fate of a message the handler took, so the queue may drop it.
56
+ */
57
+ export declare const messageAcknowledged: (messageId: string) => QueueMessageOutcome;
58
+ /**
59
+ * The fate of a message that goes back on the queue, with the reason it did.
60
+ */
61
+ export declare const messageLeftForRedelivery: (messageId: string, reason: RedeliveryReason) => QueueMessageOutcome;
62
+ /**
63
+ * The fate of a message no retry can help, so the platform's own redrive takes
64
+ * it from here.
65
+ */
66
+ export declare const messageRefusedPermanently: (messageId: string, eventId: string, refusal: unknown) => QueueMessageOutcome;
67
+ /**
68
+ * How a consumer waits and tries again while the queue itself does not answer.
69
+ */
70
+ export type QueueRetrySchedule = Schedule.Schedule<unknown, QueueMessageSourceUnavailableError>;
71
+ /**
72
+ * The waiting a consumer keeps when a service names no schedule of its own:
73
+ * growing pauses, jittered, and a limit on how often it tries.
74
+ */
75
+ export declare const defaultQueueRetrySchedule: QueueRetrySchedule;
76
+ /**
77
+ * What a consumer needs to turn a queue message into work. It names how to
78
+ * decode a payload, what to do with it, how to wait out a queue that is down,
79
+ * and which refusals no retry can help.
80
+ */
81
+ export interface QueueMessageConsumerOptions<A, E, R> {
82
+ readonly decodePayload: PayloadDecoder<A>;
83
+ readonly handle: (input: IncomingQueueMessage<A>) => Effect.Effect<unknown, E, R>;
84
+ readonly retrySchedule: QueueRetrySchedule;
85
+ readonly isPermanentRefusal?: (error: E) => boolean;
86
+ }
87
+ /**
88
+ * Reads messages off the queue and hands each one to the handler, answering
89
+ * with the fate of every message it took.
90
+ */
91
+ export declare const consumeQueueMessages: <A, E, R>(options: QueueMessageConsumerOptions<A, E, R>) => Stream.Stream<QueueMessageOutcome, QueueMessageSourceUnavailableError, R | QueueMessageSource>;
@@ -0,0 +1,92 @@
1
+ import { QueueMessageSource, } from '@satorio/machinery/ports';
2
+ import { Chunk, Duration, Effect, Match, Schedule, Stream } from 'effect';
3
+ import { decodeQueueMessageBody } from './message-codec.js';
4
+ /**
5
+ * The reason for a message that never decoded.
6
+ */
7
+ export const messageNotDecodable = (error) => ({
8
+ _tag: 'MessageNotDecodable',
9
+ error,
10
+ });
11
+ /**
12
+ * The reason for a message the handler itself rejected.
13
+ */
14
+ export const handlerRejectedMessage = (error) => ({
15
+ _tag: 'HandlerRejectedMessage',
16
+ error,
17
+ });
18
+ /**
19
+ * The fate of a message the handler took, so the queue may drop it.
20
+ */
21
+ export const messageAcknowledged = (messageId) => ({
22
+ _tag: 'MessageAcknowledged',
23
+ messageId,
24
+ });
25
+ /**
26
+ * The fate of a message that goes back on the queue, with the reason it did.
27
+ */
28
+ export const messageLeftForRedelivery = (messageId, reason) => ({
29
+ _tag: 'MessageLeftForRedelivery',
30
+ messageId,
31
+ reason,
32
+ });
33
+ /**
34
+ * The fate of a message no retry can help, so the platform's own redrive takes
35
+ * it from here.
36
+ */
37
+ export const messageRefusedPermanently = (messageId, eventId, refusal) => ({
38
+ _tag: 'MessageRefusedPermanently',
39
+ messageId,
40
+ eventId,
41
+ refusal,
42
+ });
43
+ /**
44
+ * The waiting a consumer keeps when a service names no schedule of its own:
45
+ * growing pauses, jittered, and a limit on how often it tries.
46
+ */
47
+ export const defaultQueueRetrySchedule = Schedule.exponential(Duration.millis(200), 2).pipe(Schedule.union(Schedule.spaced(Duration.seconds(30))), Schedule.jittered, Schedule.intersect(Schedule.recurs(10)));
48
+ const useCaseInputFrom = (envelope, event) => ({
49
+ eventId: envelope.eventId,
50
+ eventType: envelope.eventType,
51
+ schemaVersion: envelope.schemaVersion,
52
+ occurredAt: envelope.occurredAt,
53
+ event,
54
+ });
55
+ const outcomeOf = (options, message) => decodeQueueMessageBody(message.body).pipe(Effect.flatMap((envelope) => options
56
+ .decodePayload(envelope.schemaVersion, envelope.payload)
57
+ .pipe(Effect.map((event) => useCaseInputFrom(envelope, event)))), Effect.matchEffect({
58
+ onFailure: (error) => {
59
+ const reason = messageNotDecodable(error);
60
+ return Effect.logWarning('Queue message: left for redelivery', {
61
+ messageId: message.messageId,
62
+ reason: reason._tag,
63
+ error,
64
+ }).pipe(Effect.as(messageLeftForRedelivery(message.messageId, reason)));
65
+ },
66
+ onSuccess: (input) => options.handle(input).pipe(Effect.matchEffect({
67
+ onFailure: (error) => {
68
+ if (options.isPermanentRefusal?.(error) === true) {
69
+ return Effect.logError('Queue message: event refused permanently, message goes to the platform DLQ after the redrive limit runs out', {
70
+ eventId: input.eventId,
71
+ eventType: input.eventType,
72
+ refusal: error,
73
+ }).pipe(Effect.as(messageRefusedPermanently(message.messageId, input.eventId, error)));
74
+ }
75
+ const reason = handlerRejectedMessage(error);
76
+ return Effect.logWarning('Queue message: left for redelivery', {
77
+ messageId: message.messageId,
78
+ reason: reason._tag,
79
+ error,
80
+ }).pipe(Effect.as(messageLeftForRedelivery(message.messageId, reason)));
81
+ },
82
+ onSuccess: () => Effect.succeed(messageAcknowledged(message.messageId)),
83
+ })),
84
+ }));
85
+ const applyOutcome = (source, message, retrySchedule, outcome) => Match.value(outcome).pipe(Match.tag('MessageAcknowledged', () => source
86
+ .acknowledge(message.receiptHandle)
87
+ .pipe(Effect.retry(retrySchedule))), Match.tag('MessageLeftForRedelivery', () => Effect.void), Match.tag('MessageRefusedPermanently', () => Effect.void), Match.exhaustive);
88
+ /**
89
+ * Reads messages off the queue and hands each one to the handler, answering
90
+ * with the fate of every message it took.
91
+ */
92
+ export const consumeQueueMessages = (options) => Stream.unwrap(Effect.map(QueueMessageSource, (source) => Stream.repeatEffectChunk(source.receive.pipe(Effect.retry(options.retrySchedule), Effect.map(Chunk.fromIterable))).pipe(Stream.mapEffect((message) => outcomeOf(options, message).pipe(Effect.tap((outcome) => applyOutcome(source, message, options.retrySchedule, outcome)))))));
@@ -0,0 +1,39 @@
1
+ import type { VersionedEventDefinition } from '@satorio/machinery/workflow';
2
+ import { Effect, Schema } from 'effect';
3
+ import { UnknownEventTypeError } from './failures.js';
4
+ /**
5
+ * The version a stored payload was shaped by: a whole number above zero, and
6
+ * never anything else.
7
+ */
8
+ export declare const SchemaVersion: Schema.brand<Schema.filter<typeof Schema.Int>, "SchemaVersion">;
9
+ export type SchemaVersion = typeof SchemaVersion.Type;
10
+ /**
11
+ * The shared queue contract every message travels in.
12
+ *
13
+ * The shared queue contract: who sent it (eventId), what it is (eventType),
14
+ * which schema shaped it (schemaVersion), when it happened (occurredAt), and
15
+ * the content itself (payload). The payload is the service's concern; the
16
+ * envelope is the machinery's concern.
17
+ */
18
+ export declare const StoredEventEnvelope: Schema.Struct<{
19
+ eventId: typeof Schema.NonEmptyTrimmedString;
20
+ eventType: typeof Schema.NonEmptyTrimmedString;
21
+ schemaVersion: Schema.brand<Schema.filter<typeof Schema.Int>, "SchemaVersion">;
22
+ occurredAt: typeof Schema.DateTimeUtc;
23
+ payload: Schema.Record$<typeof Schema.String, typeof Schema.Unknown>;
24
+ }>;
25
+ export type StoredEventEnvelope = typeof StoredEventEnvelope.Type;
26
+ /**
27
+ * What a service's own list of event definitions offers: whether an event type
28
+ * is known, and the definition behind it.
29
+ */
30
+ export interface EventDefinitionRegistry<S extends Schema.Schema.AnyNoContext> {
31
+ readonly knows: (eventType: string) => boolean;
32
+ readonly definitionFor: (eventType: string) => Effect.Effect<VersionedEventDefinition<S>, UnknownEventTypeError>;
33
+ }
34
+ /**
35
+ * Builds a registry of known event definitions. Your service lists its
36
+ * definitions; the machinery gives lookup and a loud refusal for an
37
+ * unknown type.
38
+ */
39
+ export declare const eventDefinitionRegistry: <S extends Schema.Schema.AnyNoContext>(definitions: readonly VersionedEventDefinition<S>[]) => EventDefinitionRegistry<S>;
@@ -0,0 +1,39 @@
1
+ import { Effect, Schema } from 'effect';
2
+ import { UnknownEventTypeError } from './failures.js';
3
+ /**
4
+ * The version a stored payload was shaped by: a whole number above zero, and
5
+ * never anything else.
6
+ */
7
+ export const SchemaVersion = Schema.Int.pipe(Schema.positive(), Schema.brand('SchemaVersion')).annotations({ identifier: 'SchemaVersion' });
8
+ /**
9
+ * The shared queue contract every message travels in.
10
+ *
11
+ * The shared queue contract: who sent it (eventId), what it is (eventType),
12
+ * which schema shaped it (schemaVersion), when it happened (occurredAt), and
13
+ * the content itself (payload). The payload is the service's concern; the
14
+ * envelope is the machinery's concern.
15
+ */
16
+ export const StoredEventEnvelope = Schema.Struct({
17
+ eventId: Schema.NonEmptyTrimmedString,
18
+ eventType: Schema.NonEmptyTrimmedString,
19
+ schemaVersion: SchemaVersion,
20
+ occurredAt: Schema.DateTimeUtc,
21
+ payload: Schema.Record({ key: Schema.String, value: Schema.Unknown }),
22
+ }).annotations({ identifier: 'StoredEventEnvelope' });
23
+ /**
24
+ * Builds a registry of known event definitions. Your service lists its
25
+ * definitions; the machinery gives lookup and a loud refusal for an
26
+ * unknown type.
27
+ */
28
+ export const eventDefinitionRegistry = (definitions) => {
29
+ const byEventType = new Map(definitions.map((definition) => [definition.eventType, definition]));
30
+ return {
31
+ knows: (eventType) => byEventType.has(eventType),
32
+ definitionFor: (eventType) => {
33
+ const found = byEventType.get(eventType);
34
+ return found === undefined
35
+ ? Effect.fail(new UnknownEventTypeError({ eventType }))
36
+ : Effect.succeed(found);
37
+ },
38
+ };
39
+ };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * The stage a message fell over at: the envelope every message shares,
3
+ * or the payload one event type defines.
4
+ *
5
+ * @internal
6
+ */
7
+ export type QueueMessageDecodingStage = 'envelope' | 'payload';
8
+ declare const QueueMessageNotDecodableError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
9
+ readonly _tag: "QueueMessageNotDecodableError";
10
+ } & Readonly<A>;
11
+ /**
12
+ * A message whose text this service cannot turn into an event. The stage
13
+ * says whether the shared envelope or the event's own payload was the
14
+ * part that would not decode.
15
+ */
16
+ export declare class QueueMessageNotDecodableError extends QueueMessageNotDecodableError_base<{
17
+ readonly stage: QueueMessageDecodingStage;
18
+ readonly cause: unknown;
19
+ }> {
20
+ }
21
+ declare const UnknownEventTypeError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
22
+ readonly _tag: "UnknownEventTypeError";
23
+ } & Readonly<A>;
24
+ /**
25
+ * A message naming an event type this service never registered. The
26
+ * registry refuses loudly rather than guessing which definition was
27
+ * meant.
28
+ */
29
+ export declare class UnknownEventTypeError extends UnknownEventTypeError_base<{
30
+ readonly eventType: string;
31
+ }> {
32
+ }
33
+ export {};
@@ -0,0 +1,15 @@
1
+ import { Data } from 'effect';
2
+ /**
3
+ * A message whose text this service cannot turn into an event. The stage
4
+ * says whether the shared envelope or the event's own payload was the
5
+ * part that would not decode.
6
+ */
7
+ export class QueueMessageNotDecodableError extends Data.TaggedError('QueueMessageNotDecodableError') {
8
+ }
9
+ /**
10
+ * A message naming an event type this service never registered. The
11
+ * registry refuses loudly rather than guessing which definition was
12
+ * meant.
13
+ */
14
+ export class UnknownEventTypeError extends Data.TaggedError('UnknownEventTypeError') {
15
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Public entry to the queue mechanism: the envelope a message travels in, and
3
+ * the consumer that decides its fate. It gives you the envelope every message
4
+ * carries, the decoder that opens it, the consumer that decides each message's
5
+ * fate, and the SQS source and producer read from one prefix of environment
6
+ * variables.
7
+ */
8
+ export { consumeQueueMessages, defaultQueueRetrySchedule, handlerRejectedMessage, type IncomingQueueMessage, messageAcknowledged, messageLeftForRedelivery, messageNotDecodable, messageRefusedPermanently, type QueueMessageConsumerOptions, type QueueMessageOutcome, type QueueRetrySchedule, type RedeliveryReason, } from './consumer.js';
9
+ export { type EventDefinitionRegistry, eventDefinitionRegistry, SchemaVersion, StoredEventEnvelope, } from './envelope.js';
10
+ export { QueueMessageNotDecodableError, UnknownEventTypeError, } from './failures.js';
11
+ export { sqsQueueMessageProducerLive, sqsQueueMessageSourceLive, } from './layer.js';
12
+ export { decodeQueueMessageBody, type PayloadDecoder, payloadDecoderFor, QueueMessageBody, queueMessageBodyOf, } from './message-codec.js';
13
+ export { queueReadinessCheck } from './readiness.js';
14
+ export { ENVIRONMENT, type QueueConsumerSettings, type QueueProducerSettings, queueConsumerSettings, queueProducerSettings, queueUrlVariable, SQS_DEFAULT_VISIBILITY_TIMEOUT_SECONDS, } from './settings.js';
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Public entry to the queue mechanism: the envelope a message travels in, and
3
+ * the consumer that decides its fate. It gives you the envelope every message
4
+ * carries, the decoder that opens it, the consumer that decides each message's
5
+ * fate, and the SQS source and producer read from one prefix of environment
6
+ * variables.
7
+ */
8
+ export { consumeQueueMessages, defaultQueueRetrySchedule, handlerRejectedMessage, messageAcknowledged, messageLeftForRedelivery, messageNotDecodable, messageRefusedPermanently, } from './consumer.js';
9
+ export { eventDefinitionRegistry, SchemaVersion, StoredEventEnvelope, } from './envelope.js';
10
+ export { QueueMessageNotDecodableError, UnknownEventTypeError, } from './failures.js';
11
+ export { sqsQueueMessageProducerLive, sqsQueueMessageSourceLive, } from './layer.js';
12
+ export { decodeQueueMessageBody, payloadDecoderFor, QueueMessageBody, queueMessageBodyOf, } from './message-codec.js';
13
+ export { queueReadinessCheck } from './readiness.js';
14
+ export { ENVIRONMENT, queueConsumerSettings, queueProducerSettings, queueUrlVariable, SQS_DEFAULT_VISIBILITY_TIMEOUT_SECONDS, } from './settings.js';
@@ -0,0 +1,33 @@
1
+ import { QueueMessageProducer, QueueMessageSource } from '@satorio/machinery/ports';
2
+ import { type ConfigError, Layer } from 'effect';
3
+ import { type ClosableSqsSendTransport } from './queue-message-producer.js';
4
+ import { type ClosableSqsTransport } from './queue-message-source.js';
5
+ import { type QueueConsumerSettings, type QueueProducerSettings } from './settings.js';
6
+ /**
7
+ * A message source built from environment variables with the given
8
+ * prefix. With no queue URL set it mounts the loud stand and logs the
9
+ * one refusal every later receive repeats, so startup carries on and
10
+ * nothing goes missing in silence. The transport is a parameter, so a
11
+ * test substitutes its own without touching the wiring.
12
+ *
13
+ * @internal
14
+ */
15
+ export declare const queueMessageSourceFromEnvironmentLive: (variablePrefix: string, openTransport: (settings: QueueConsumerSettings) => ClosableSqsTransport) => Layer.Layer<QueueMessageSource, ConfigError.ConfigError>;
16
+ /**
17
+ * The message source on the real AWS SDK transport, reading the
18
+ * variables this prefix names.
19
+ */
20
+ export declare const sqsQueueMessageSourceLive: (variablePrefix: string) => Layer.Layer<QueueMessageSource, ConfigError.ConfigError>;
21
+ /**
22
+ * A message producer built from environment variables with the given
23
+ * prefix, mounting the loud stand when no queue URL is set. The
24
+ * transport is a parameter for the same reason the source's is.
25
+ *
26
+ * @internal
27
+ */
28
+ export declare const queueMessageProducerFromEnvironmentLive: (variablePrefix: string, openTransport: (settings: QueueProducerSettings) => ClosableSqsSendTransport) => Layer.Layer<QueueMessageProducer, ConfigError.ConfigError>;
29
+ /**
30
+ * The message producer on the real AWS SDK transport, reading the
31
+ * variables this prefix names.
32
+ */
33
+ export declare const sqsQueueMessageProducerLive: (variablePrefix: string) => Layer.Layer<QueueMessageProducer, ConfigError.ConfigError>;