reqon-dsl 0.2.0 → 0.3.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 (396) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +22 -0
  3. package/dist/ast/nodes.d.ts +83 -4
  4. package/dist/ast/nodes.js +14 -0
  5. package/dist/auth/circuit-breaker.js +7 -6
  6. package/dist/auth/rate-limiter.d.ts +4 -0
  7. package/dist/auth/rate-limiter.js +9 -16
  8. package/dist/cli.d.ts +13 -0
  9. package/dist/cli.js +84 -4
  10. package/dist/config/constants.d.ts +141 -0
  11. package/dist/config/constants.js +128 -0
  12. package/dist/config/index.d.ts +4 -0
  13. package/dist/config/index.js +4 -0
  14. package/dist/control/index.d.ts +2 -0
  15. package/dist/control/index.js +1 -0
  16. package/dist/control/server.d.ts +88 -0
  17. package/dist/control/server.js +238 -0
  18. package/dist/control/types.d.ts +55 -0
  19. package/dist/control/types.js +7 -0
  20. package/dist/debug/cli-debugger.d.ts +17 -0
  21. package/dist/debug/cli-debugger.js +180 -0
  22. package/dist/debug/controller.d.ts +94 -0
  23. package/dist/debug/controller.js +45 -0
  24. package/dist/debug/index.d.ts +6 -0
  25. package/dist/debug/index.js +5 -0
  26. package/dist/errors/index.d.ts +67 -0
  27. package/dist/errors/index.js +89 -1
  28. package/dist/execution/index.d.ts +1 -1
  29. package/dist/execution/state.d.ts +24 -0
  30. package/dist/index.d.ts +21 -1
  31. package/dist/index.js +33 -2
  32. package/dist/interpreter/context.d.ts +14 -0
  33. package/dist/interpreter/context.js +15 -0
  34. package/dist/interpreter/evaluator.d.ts +63 -1
  35. package/dist/interpreter/evaluator.js +186 -39
  36. package/dist/interpreter/executor.d.ts +70 -14
  37. package/dist/interpreter/executor.js +503 -174
  38. package/dist/interpreter/fetch-handler.d.ts +9 -0
  39. package/dist/interpreter/fetch-handler.js +133 -24
  40. package/dist/interpreter/http.d.ts +5 -0
  41. package/dist/interpreter/http.js +26 -12
  42. package/dist/interpreter/index.d.ts +3 -1
  43. package/dist/interpreter/index.js +2 -0
  44. package/dist/interpreter/pagination.d.ts +11 -2
  45. package/dist/interpreter/pagination.js +95 -31
  46. package/dist/interpreter/signals.d.ts +8 -0
  47. package/dist/interpreter/signals.js +12 -0
  48. package/dist/interpreter/source-manager.d.ts +75 -0
  49. package/dist/interpreter/source-manager.js +157 -0
  50. package/dist/interpreter/step-handlers/apply-handler.d.ts +29 -0
  51. package/dist/interpreter/step-handlers/apply-handler.js +79 -0
  52. package/dist/interpreter/step-handlers/for-handler.d.ts +13 -0
  53. package/dist/interpreter/step-handlers/for-handler.js +71 -4
  54. package/dist/interpreter/step-handlers/index.d.ts +4 -2
  55. package/dist/interpreter/step-handlers/index.js +4 -2
  56. package/dist/interpreter/step-handlers/match-handler.d.ts +9 -0
  57. package/dist/interpreter/step-handlers/match-handler.js +43 -16
  58. package/dist/interpreter/step-handlers/pause-handler.d.ts +52 -0
  59. package/dist/interpreter/step-handlers/pause-handler.js +87 -0
  60. package/dist/interpreter/step-handlers/store-handler.d.ts +11 -1
  61. package/dist/interpreter/step-handlers/store-handler.js +45 -13
  62. package/dist/interpreter/step-handlers/types.d.ts +3 -0
  63. package/dist/interpreter/step-handlers/validate-handler.d.ts +2 -1
  64. package/dist/interpreter/step-handlers/validate-handler.js +4 -2
  65. package/dist/interpreter/step-handlers/webhook-handler.d.ts +3 -0
  66. package/dist/interpreter/step-handlers/webhook-handler.js +18 -2
  67. package/dist/interpreter/store-manager.d.ts +46 -0
  68. package/dist/interpreter/store-manager.js +66 -0
  69. package/dist/lexer/index.d.ts +11 -4
  70. package/dist/lexer/index.js +11 -4
  71. package/dist/lexer/tokens.d.ts +17 -1
  72. package/dist/lexer/tokens.js +36 -0
  73. package/dist/mcp/index.d.ts +11 -0
  74. package/dist/mcp/index.js +11 -0
  75. package/dist/mcp/server.d.ts +17 -0
  76. package/dist/mcp/server.js +451 -0
  77. package/dist/oas/index.d.ts +2 -0
  78. package/dist/oas/index.js +1 -0
  79. package/dist/oas/mock-generator.d.ts +12 -0
  80. package/dist/oas/mock-generator.js +187 -0
  81. package/dist/observability/events.d.ts +244 -0
  82. package/dist/observability/events.js +90 -0
  83. package/dist/observability/index.d.ts +15 -0
  84. package/dist/observability/index.js +12 -0
  85. package/dist/observability/logger.d.ts +106 -0
  86. package/dist/observability/logger.js +259 -0
  87. package/dist/observability/otel.d.ts +135 -0
  88. package/dist/observability/otel.js +386 -0
  89. package/dist/parser/action-parser.d.ts +105 -0
  90. package/dist/parser/action-parser.js +645 -0
  91. package/dist/parser/expressions.d.ts +13 -0
  92. package/dist/parser/expressions.js +72 -2
  93. package/dist/parser/fetch-parser.d.ts +27 -0
  94. package/dist/parser/fetch-parser.js +269 -0
  95. package/dist/parser/index.d.ts +17 -0
  96. package/dist/parser/index.js +17 -0
  97. package/dist/parser/parser.d.ts +44 -46
  98. package/dist/parser/parser.js +122 -1070
  99. package/dist/parser/pipeline-parser.d.ts +12 -0
  100. package/dist/parser/pipeline-parser.js +52 -0
  101. package/dist/parser/schedule-parser.d.ts +7 -0
  102. package/dist/parser/schedule-parser.js +137 -0
  103. package/dist/parser/source-parser.d.ts +9 -0
  104. package/dist/parser/source-parser.js +151 -0
  105. package/dist/pause/index.d.ts +14 -0
  106. package/dist/pause/index.js +11 -0
  107. package/dist/pause/manager.d.ts +118 -0
  108. package/dist/pause/manager.js +245 -0
  109. package/dist/pause/state.d.ts +93 -0
  110. package/dist/pause/state.js +103 -0
  111. package/dist/pause/store.d.ts +61 -0
  112. package/dist/pause/store.js +156 -0
  113. package/dist/plugin.d.ts +9 -12
  114. package/dist/plugin.js +10 -13
  115. package/dist/stores/factory.d.ts +1 -1
  116. package/dist/stores/factory.js +3 -2
  117. package/dist/stores/file.d.ts +26 -0
  118. package/dist/stores/file.js +64 -10
  119. package/dist/stores/index.d.ts +16 -1
  120. package/dist/stores/index.js +16 -1
  121. package/dist/stores/memory.d.ts +4 -0
  122. package/dist/stores/memory.js +11 -0
  123. package/dist/stores/types.d.ts +17 -0
  124. package/dist/stores/types.js +12 -0
  125. package/dist/trace/index.d.ts +16 -0
  126. package/dist/trace/index.js +12 -0
  127. package/dist/trace/recorder.d.ts +71 -0
  128. package/dist/trace/recorder.js +144 -0
  129. package/dist/trace/replay.d.ts +132 -0
  130. package/dist/trace/replay.js +264 -0
  131. package/dist/trace/state.d.ts +102 -0
  132. package/dist/trace/state.js +86 -0
  133. package/dist/trace/store.d.ts +69 -0
  134. package/dist/trace/store.js +225 -0
  135. package/dist/utils/index.d.ts +1 -0
  136. package/dist/utils/index.js +1 -0
  137. package/dist/utils/type-guards.d.ts +58 -0
  138. package/dist/utils/type-guards.js +92 -0
  139. package/dist/webhook/server.js +7 -6
  140. package/package.json +55 -6
  141. package/.claude/settings.local.json +0 -31
  142. package/.claude/skills/api-integration.md +0 -125
  143. package/.claude/skills/database-schema.md +0 -51
  144. package/.claude/skills/dsl-design.md +0 -80
  145. package/.claude/skills/property-testing.md +0 -143
  146. package/.claude/skills/reqon/SKILL.md +0 -44
  147. package/.claude/skills/reqon/references/examples.md +0 -206
  148. package/.claude/skills/reqon/references/syntax.md +0 -263
  149. package/.claude/skills/vscode-extension.md +0 -113
  150. package/.github/dependabot.yml +0 -32
  151. package/.github/pull_request_template.md +0 -21
  152. package/.github/workflows/ci.yml +0 -174
  153. package/.github/workflows/release.yml +0 -73
  154. package/CLAUDE.md +0 -72
  155. package/CONTRIBUTING.md +0 -161
  156. package/TODO.md +0 -51
  157. package/dist/auth/auth.test.d.ts +0 -1
  158. package/dist/auth/auth.test.js +0 -255
  159. package/dist/errors/errors.test.d.ts +0 -1
  160. package/dist/errors/errors.test.js +0 -165
  161. package/dist/execution/execution.test.d.ts +0 -1
  162. package/dist/execution/execution.test.js +0 -246
  163. package/dist/integration.test.d.ts +0 -1
  164. package/dist/integration.test.js +0 -168
  165. package/dist/interpreter/evaluator.test.d.ts +0 -1
  166. package/dist/interpreter/evaluator.test.js +0 -512
  167. package/dist/interpreter/http.test.d.ts +0 -1
  168. package/dist/interpreter/http.test.js +0 -299
  169. package/dist/interpreter/progress.test.d.ts +0 -1
  170. package/dist/interpreter/progress.test.js +0 -216
  171. package/dist/interpreter/schema-matcher.test.d.ts +0 -1
  172. package/dist/interpreter/schema-matcher.test.js +0 -122
  173. package/dist/lexer/lexer.d.ts +0 -24
  174. package/dist/lexer/lexer.js +0 -264
  175. package/dist/lexer/lexer.test.d.ts +0 -1
  176. package/dist/lexer/lexer.test.js +0 -259
  177. package/dist/loader/loader.test.d.ts +0 -1
  178. package/dist/loader/loader.test.js +0 -287
  179. package/dist/oas/oas.test.d.ts +0 -1
  180. package/dist/oas/oas.test.js +0 -218
  181. package/dist/parser/expressions.test.d.ts +0 -1
  182. package/dist/parser/expressions.test.js +0 -378
  183. package/dist/parser/match.test.d.ts +0 -1
  184. package/dist/parser/match.test.js +0 -254
  185. package/dist/parser/parser.test.d.ts +0 -1
  186. package/dist/parser/parser.test.js +0 -333
  187. package/dist/parser/schedule.test.d.ts +0 -1
  188. package/dist/parser/schedule.test.js +0 -241
  189. package/dist/scheduler/cron-parser.test.d.ts +0 -1
  190. package/dist/scheduler/cron-parser.test.js +0 -188
  191. package/dist/stores/file.test.d.ts +0 -1
  192. package/dist/stores/file.test.js +0 -165
  193. package/dist/stores/memory.test.d.ts +0 -1
  194. package/dist/stores/memory.test.js +0 -157
  195. package/dist/stores/stores.test.d.ts +0 -1
  196. package/dist/stores/stores.test.js +0 -158
  197. package/dist/sync/sync.test.d.ts +0 -1
  198. package/dist/sync/sync.test.js +0 -221
  199. package/docusaurus/README.md +0 -41
  200. package/docusaurus/docs/advanced/execution-state.md +0 -283
  201. package/docusaurus/docs/advanced/extending-reqon.md +0 -388
  202. package/docusaurus/docs/advanced/multi-file-missions.md +0 -250
  203. package/docusaurus/docs/advanced/parallel-execution.md +0 -353
  204. package/docusaurus/docs/api-reference.md +0 -443
  205. package/docusaurus/docs/authentication/api-key.md +0 -339
  206. package/docusaurus/docs/authentication/basic.md +0 -276
  207. package/docusaurus/docs/authentication/bearer.md +0 -282
  208. package/docusaurus/docs/authentication/oauth2.md +0 -317
  209. package/docusaurus/docs/authentication/overview.md +0 -251
  210. package/docusaurus/docs/cli.md +0 -229
  211. package/docusaurus/docs/core-concepts/actions.md +0 -286
  212. package/docusaurus/docs/core-concepts/missions.md +0 -264
  213. package/docusaurus/docs/core-concepts/schemas.md +0 -353
  214. package/docusaurus/docs/core-concepts/sources.md +0 -339
  215. package/docusaurus/docs/core-concepts/stores.md +0 -332
  216. package/docusaurus/docs/dsl-syntax/expressions.md +0 -361
  217. package/docusaurus/docs/dsl-syntax/fetch.md +0 -293
  218. package/docusaurus/docs/dsl-syntax/for-loops.md +0 -324
  219. package/docusaurus/docs/dsl-syntax/map.md +0 -345
  220. package/docusaurus/docs/dsl-syntax/match.md +0 -387
  221. package/docusaurus/docs/dsl-syntax/pipelines.md +0 -397
  222. package/docusaurus/docs/dsl-syntax/validate.md +0 -401
  223. package/docusaurus/docs/error-handling/dead-letter-queues.md +0 -399
  224. package/docusaurus/docs/error-handling/flow-control.md +0 -337
  225. package/docusaurus/docs/error-handling/retry-strategies.md +0 -368
  226. package/docusaurus/docs/examples.md +0 -488
  227. package/docusaurus/docs/getting-started.md +0 -256
  228. package/docusaurus/docs/http/circuit-breaker.md +0 -401
  229. package/docusaurus/docs/http/incremental-sync.md +0 -394
  230. package/docusaurus/docs/http/pagination.md +0 -361
  231. package/docusaurus/docs/http/rate-limiting.md +0 -383
  232. package/docusaurus/docs/http/requests.md +0 -328
  233. package/docusaurus/docs/http/retry.md +0 -402
  234. package/docusaurus/docs/intro.md +0 -90
  235. package/docusaurus/docs/openapi/loading-specs.md +0 -305
  236. package/docusaurus/docs/openapi/operation-calls.md +0 -314
  237. package/docusaurus/docs/openapi/overview.md +0 -212
  238. package/docusaurus/docs/openapi/response-validation.md +0 -344
  239. package/docusaurus/docs/scheduling/cron.md +0 -305
  240. package/docusaurus/docs/scheduling/daemon-mode.md +0 -317
  241. package/docusaurus/docs/scheduling/intervals.md +0 -289
  242. package/docusaurus/docs/scheduling/overview.md +0 -231
  243. package/docusaurus/docs/stores/custom-adapters.md +0 -376
  244. package/docusaurus/docs/stores/file.md +0 -236
  245. package/docusaurus/docs/stores/memory.md +0 -193
  246. package/docusaurus/docs/stores/overview.md +0 -274
  247. package/docusaurus/docs/stores/postgrest.md +0 -316
  248. package/docusaurus/docusaurus.config.ts +0 -148
  249. package/docusaurus/package-lock.json +0 -18029
  250. package/docusaurus/package.json +0 -47
  251. package/docusaurus/sidebars.ts +0 -155
  252. package/docusaurus/src/components/HomepageFeatures/index.tsx +0 -105
  253. package/docusaurus/src/components/HomepageFeatures/styles.module.css +0 -12
  254. package/docusaurus/src/css/custom.css +0 -169
  255. package/docusaurus/src/pages/index.module.css +0 -48
  256. package/docusaurus/src/pages/index.tsx +0 -110
  257. package/docusaurus/src/pages/markdown-page.md +0 -7
  258. package/docusaurus/static/.nojekyll +0 -0
  259. package/docusaurus/static/img/docusaurus-social-card.jpg +0 -0
  260. package/docusaurus/static/img/docusaurus.png +0 -0
  261. package/docusaurus/static/img/favicon.ico +0 -0
  262. package/docusaurus/static/img/logo.svg +0 -10
  263. package/docusaurus/static/img/undraw_docusaurus_mountain.svg +0 -171
  264. package/docusaurus/static/img/undraw_docusaurus_react.svg +0 -170
  265. package/docusaurus/static/img/undraw_docusaurus_tree.svg +0 -40
  266. package/docusaurus/tsconfig.json +0 -8
  267. package/examples/README.md +0 -112
  268. package/examples/error-handling/README.md +0 -150
  269. package/examples/error-handling/payment-processor.vague +0 -287
  270. package/examples/github-sync/README.md +0 -74
  271. package/examples/github-sync/fetch-issues.vague +0 -47
  272. package/examples/github-sync/fetch-prs.vague +0 -40
  273. package/examples/github-sync/mission.vague +0 -101
  274. package/examples/github-sync/normalize.vague +0 -70
  275. package/examples/jsonplaceholder/README.md +0 -28
  276. package/examples/jsonplaceholder/posts.vague +0 -48
  277. package/examples/petstore/README.md +0 -35
  278. package/examples/petstore/openapi.yaml +0 -97
  279. package/examples/petstore/sync.vague +0 -52
  280. package/examples/temporal-comparison/README.md +0 -297
  281. package/examples/temporal-comparison/reconciliation.vague +0 -355
  282. package/examples/temporal-comparison/temporal/activities/index.ts +0 -8
  283. package/examples/temporal-comparison/temporal/activities/shipstation.ts +0 -225
  284. package/examples/temporal-comparison/temporal/activities/shopify.ts +0 -257
  285. package/examples/temporal-comparison/temporal/activities/storage.ts +0 -198
  286. package/examples/temporal-comparison/temporal/activities/stripe.ts +0 -169
  287. package/examples/temporal-comparison/temporal/activities/validation.ts +0 -205
  288. package/examples/temporal-comparison/temporal/client/schedule.ts +0 -218
  289. package/examples/temporal-comparison/temporal/config/retry.ts +0 -63
  290. package/examples/temporal-comparison/temporal/types/index.ts +0 -129
  291. package/examples/temporal-comparison/temporal/workers/main.ts +0 -130
  292. package/examples/temporal-comparison/temporal/workflows/orderReconciliation.ts +0 -262
  293. package/examples/xero/README.md +0 -88
  294. package/examples/xero/invoices.vague +0 -189
  295. package/src/api-integration.test.ts +0 -954
  296. package/src/ast/index.ts +0 -1
  297. package/src/ast/nodes.ts +0 -310
  298. package/src/auth/auth.test.ts +0 -326
  299. package/src/auth/circuit-breaker.test.ts +0 -390
  300. package/src/auth/circuit-breaker.ts +0 -379
  301. package/src/auth/credentials.test.ts +0 -273
  302. package/src/auth/credentials.ts +0 -246
  303. package/src/auth/index.ts +0 -40
  304. package/src/auth/oauth2-provider.ts +0 -177
  305. package/src/auth/rate-limiter.ts +0 -459
  306. package/src/auth/token-store.ts +0 -177
  307. package/src/auth/types.ts +0 -159
  308. package/src/benchmark/e2e.bench.ts +0 -288
  309. package/src/benchmark/evaluator.bench.ts +0 -331
  310. package/src/benchmark/fixtures.ts +0 -295
  311. package/src/benchmark/index.ts +0 -108
  312. package/src/benchmark/lexer.bench.ts +0 -69
  313. package/src/benchmark/parser.bench.ts +0 -103
  314. package/src/benchmark/resilience.bench.ts +0 -193
  315. package/src/benchmark/store.bench.ts +0 -147
  316. package/src/benchmark/utils.ts +0 -230
  317. package/src/cli.ts +0 -313
  318. package/src/errors/errors.test.ts +0 -234
  319. package/src/errors/index.ts +0 -223
  320. package/src/execution/execution.test.ts +0 -307
  321. package/src/execution/index.ts +0 -21
  322. package/src/execution/state.ts +0 -207
  323. package/src/execution/store.ts +0 -188
  324. package/src/index.ts +0 -169
  325. package/src/integration.test.ts +0 -192
  326. package/src/interpreter/context.ts +0 -57
  327. package/src/interpreter/evaluator.test.ts +0 -796
  328. package/src/interpreter/evaluator.ts +0 -245
  329. package/src/interpreter/executor.ts +0 -946
  330. package/src/interpreter/fetch-handler.ts +0 -302
  331. package/src/interpreter/http.test.ts +0 -423
  332. package/src/interpreter/http.ts +0 -308
  333. package/src/interpreter/index.ts +0 -32
  334. package/src/interpreter/pagination.ts +0 -207
  335. package/src/interpreter/progress.test.ts +0 -276
  336. package/src/interpreter/schema-matcher.test.ts +0 -160
  337. package/src/interpreter/schema-matcher.ts +0 -168
  338. package/src/interpreter/signals.ts +0 -73
  339. package/src/interpreter/step-handlers/for-handler.ts +0 -65
  340. package/src/interpreter/step-handlers/index.ts +0 -17
  341. package/src/interpreter/step-handlers/map-handler.ts +0 -24
  342. package/src/interpreter/step-handlers/match-handler.ts +0 -101
  343. package/src/interpreter/step-handlers/store-handler.ts +0 -78
  344. package/src/interpreter/step-handlers/types.ts +0 -17
  345. package/src/interpreter/step-handlers/validate-handler.ts +0 -30
  346. package/src/interpreter/step-handlers/webhook-handler.ts +0 -142
  347. package/src/lexer/index.ts +0 -18
  348. package/src/lexer/lexer.test.ts +0 -316
  349. package/src/lexer/tokens.ts +0 -179
  350. package/src/loader/index.ts +0 -288
  351. package/src/loader/loader.test.ts +0 -360
  352. package/src/oas/index.ts +0 -4
  353. package/src/oas/loader.ts +0 -126
  354. package/src/oas/oas.test.ts +0 -254
  355. package/src/oas/validator.ts +0 -299
  356. package/src/parser/base.ts +0 -124
  357. package/src/parser/expressions.test.ts +0 -525
  358. package/src/parser/expressions.ts +0 -314
  359. package/src/parser/index.ts +0 -3
  360. package/src/parser/match.test.ts +0 -296
  361. package/src/parser/parser.test.ts +0 -739
  362. package/src/parser/parser.ts +0 -1469
  363. package/src/parser/schedule.test.ts +0 -287
  364. package/src/parser/webhook.test.ts +0 -248
  365. package/src/plugin.ts +0 -83
  366. package/src/scheduler/cron-parser.test.ts +0 -236
  367. package/src/scheduler/cron-parser.ts +0 -236
  368. package/src/scheduler/index.ts +0 -10
  369. package/src/scheduler/scheduler.ts +0 -443
  370. package/src/scheduler/types.ts +0 -71
  371. package/src/stores/factory.ts +0 -104
  372. package/src/stores/file.test.ts +0 -276
  373. package/src/stores/file.ts +0 -211
  374. package/src/stores/index.ts +0 -6
  375. package/src/stores/memory.test.ts +0 -238
  376. package/src/stores/memory.ts +0 -63
  377. package/src/stores/postgrest.test.ts +0 -488
  378. package/src/stores/postgrest.ts +0 -263
  379. package/src/stores/stores.test.ts +0 -197
  380. package/src/stores/types.ts +0 -58
  381. package/src/sync/index.ts +0 -16
  382. package/src/sync/state.ts +0 -126
  383. package/src/sync/store.ts +0 -139
  384. package/src/sync/sync.test.ts +0 -271
  385. package/src/utils/async.ts +0 -10
  386. package/src/utils/file.ts +0 -106
  387. package/src/utils/index.ts +0 -14
  388. package/src/utils/logger.ts +0 -53
  389. package/src/utils/path.ts +0 -47
  390. package/src/webhook/index.ts +0 -15
  391. package/src/webhook/server.test.ts +0 -253
  392. package/src/webhook/server.ts +0 -389
  393. package/src/webhook/store.ts +0 -239
  394. package/src/webhook/types.ts +0 -93
  395. package/tsconfig.json +0 -17
  396. package/vitest.config.ts +0 -39
@@ -1,297 +0,0 @@
1
- # Reqon vs Temporal: E-Commerce Order Reconciliation
2
-
3
- This example demonstrates a complex multi-vendor order reconciliation pipeline that syncs data from Shopify, Stripe, and ShipStation, validates for discrepancies, and stores results in a database.
4
-
5
- ## The Scenario
6
-
7
- An e-commerce company needs to:
8
- 1. Sync orders from Shopify (source of truth for orders)
9
- 2. Sync payments from Stripe (source of truth for payments)
10
- 3. Sync shipments from ShipStation (source of truth for fulfillment)
11
- 4. Cross-reference and validate all three data sources
12
- 5. Flag discrepancies (unpaid orders, missing shipments, refund mismatches)
13
- 6. Store reconciled data with audit trail
14
- 7. Handle rate limits, retries, and pagination across all APIs
15
- 8. Run daily with incremental sync
16
-
17
- ## The Numbers
18
-
19
- | Metric | Reqon | Temporal |
20
- |--------|-------|----------|
21
- | **Total Lines of Code** | ~280 | ~1,500+ |
22
- | **Files** | 1 | 12 |
23
- | **Dependencies** | 1 (reqon) | 8+ (@temporalio/*, axios, pg, stripe) |
24
- | **Infrastructure** | None | Temporal Server + PostgreSQL + Workers |
25
- | **Setup Time** | 0 minutes | 30+ minutes |
26
- | **Learning Curve** | Hours | Days/Weeks |
27
-
28
- ## Side-by-Side Comparison
29
-
30
- ### 1. API Pagination
31
-
32
- **Reqon** (2 lines):
33
- ```vague
34
- paginate: cursor(page_info, 250, "link.next"),
35
- until: response.orders.length == 0,
36
- ```
37
-
38
- **Temporal** (40+ lines):
39
- ```typescript
40
- let cursor: string | null = null;
41
- do {
42
- Context.current().heartbeat({ page: pageCount, ordersFound: allOrders.length });
43
- const { orders, nextCursor } = await client.fetchOrdersPage(cursor, since);
44
- for (const order of orders) {
45
- allOrders.push(transformOrder(order));
46
- }
47
- cursor = nextCursor;
48
- pageCount++;
49
- } while (cursor);
50
- ```
51
-
52
- ### 2. Rate Limiting
53
-
54
- **Reqon** (4 lines):
55
- ```vague
56
- rateLimit: {
57
- strategy: "pause",
58
- maxWait: 120,
59
- fallbackRpm: 40
60
- }
61
- ```
62
-
63
- **Temporal** (50+ lines):
64
- ```typescript
65
- class ShopifyClient {
66
- private rateLimitState: RateLimitState | null = null;
67
-
68
- private updateRateLimitState(headers: Record<string, string>): void {
69
- // Parse headers, calculate remaining, track reset time...
70
- }
71
-
72
- private async waitForRateLimit(): Promise<void> {
73
- if (!this.rateLimitState) return;
74
- if (this.rateLimitState.remaining < 5) {
75
- const waitTime = Math.max(0, this.rateLimitState.resetAt.getTime() - Date.now());
76
- if (waitTime > 0) {
77
- await new Promise((resolve) => setTimeout(resolve, waitTime));
78
- }
79
- }
80
- }
81
- }
82
- ```
83
-
84
- ### 3. Schema Transformation
85
-
86
- **Reqon** (15 lines):
87
- ```vague
88
- map order -> UnifiedOrder {
89
- order_id: "shopify_" + .id,
90
- customer_email: .customer.email,
91
- total_amount: .total_price,
92
- payment_status: match .financial_status {
93
- "paid" => "captured",
94
- "pending" => "pending",
95
- "refunded" => "refunded",
96
- _ => "unknown"
97
- }
98
- }
99
- ```
100
-
101
- **Temporal** (30+ lines):
102
- ```typescript
103
- function transformOrder(order: ShopifyOrder): UnifiedOrder {
104
- const paymentStatusMap: Record<string, string> = {
105
- paid: 'captured',
106
- partially_paid: 'partial',
107
- pending: 'pending',
108
- refunded: 'refunded',
109
- partially_refunded: 'partial_refund',
110
- };
111
-
112
- return {
113
- order_id: `shopify_${order.id}`,
114
- customer_email: order.customer?.email || '',
115
- total_amount: parseFloat(order.total_price),
116
- payment_status: paymentStatusMap[order.financial_status] || 'unknown',
117
- // ... 10 more fields
118
- };
119
- }
120
- ```
121
-
122
- ### 4. Validation Rules
123
-
124
- **Reqon** (5 lines):
125
- ```vague
126
- validate order {
127
- assume payment_exists == true
128
- } or {
129
- store { type: "missing_payment", ... } -> discrepancies { ... }
130
- }
131
- ```
132
-
133
- **Temporal** (50+ lines):
134
- ```typescript
135
- export async function validateOrdersHavePayments(
136
- orders: UnifiedOrder[],
137
- payments: UnifiedPayment[]
138
- ): Promise<Discrepancy[]> {
139
- const discrepancies: Discrepancy[] = [];
140
- const paymentsByOrderId = new Map<string, UnifiedPayment[]>();
141
-
142
- for (const payment of payments) {
143
- const existing = paymentsByOrderId.get(payment.order_id) || [];
144
- existing.push(payment);
145
- paymentsByOrderId.set(payment.order_id, existing);
146
- }
147
-
148
- const threeDaysAgo = new Date(Date.now() - 3 * 24 * 60 * 60 * 1000);
149
-
150
- for (const order of orders) {
151
- if (order.payment_status === 'pending' && order.created_at < threeDaysAgo) {
152
- const orderPayments = paymentsByOrderId.get(order.order_id);
153
- if (!orderPayments || orderPayments.length === 0) {
154
- discrepancies.push({
155
- id: `disc_${order.order_id}_no_payment`,
156
- // ... more fields
157
- });
158
- }
159
- }
160
- }
161
- return discrepancies;
162
- }
163
- ```
164
-
165
- ### 5. Pipeline Orchestration with Parallel Execution
166
-
167
- **Reqon** (3 lines):
168
- ```vague
169
- // Fetch from all three APIs in parallel, then validate
170
- run [SyncShopifyOrders, SyncStripePayments, SyncShipStationShipments]
171
- then ValidateReconciliation
172
- ```
173
- Brackets indicate parallel execution - all three sync actions run concurrently for maximum performance.
174
-
175
- **Temporal** (100+ lines):
176
- ```typescript
177
- export async function orderReconciliationWorkflow(): Promise<ReconciliationResult> {
178
- // Initialize state, queries, signals...
179
- setHandler(getStatusQuery, () => state);
180
- setHandler(cancelSignal, () => { cancelled = true; });
181
- setHandler(pauseSignal, () => { paused = true; });
182
- setHandler(resumeSignal, () => { paused = false; });
183
-
184
- try {
185
- state.status = 'syncing_shopify';
186
- await checkPauseAndCancel();
187
- const shopifyLastSync = await storage.getCheckpoint('shopify_orders_last_sync');
188
- const orders = await shopify.fetchAllShopifyOrders(shopifyLastSync);
189
- state.ordersProcessed = await storage.upsertOrders(orders);
190
- await storage.setCheckpoint('shopify_orders_last_sync', new Date().toISOString());
191
-
192
- // Repeat for Stripe...
193
- // Repeat for ShipStation...
194
- // Validation step...
195
- } catch (error) {
196
- state.status = 'failed';
197
- throw error;
198
- }
199
- }
200
- ```
201
-
202
- ### 6. Running the Pipeline
203
-
204
- **Reqon**:
205
- ```bash
206
- # Run once
207
- reqon reconciliation.vague --auth ./credentials.json
208
-
209
- # Dry run
210
- reqon reconciliation.vague --dry-run
211
-
212
- # Resume from checkpoint
213
- reqon reconciliation.vague --resume exec-abc123
214
-
215
- # Schedule with cron
216
- 0 2 * * * reqon reconciliation.vague
217
- ```
218
-
219
- **Temporal**:
220
- ```bash
221
- # 1. Start PostgreSQL
222
- docker-compose up -d postgresql
223
-
224
- # 2. Start Temporal Server
225
- docker-compose up -d temporal temporal-ui
226
-
227
- # 3. Wait for server to be ready
228
- sleep 30
229
-
230
- # 4. Start worker (in separate terminal)
231
- npx ts-node src/workers/main.ts
232
-
233
- # 5. Trigger workflow
234
- npx ts-node src/client/schedule.ts run
235
-
236
- # 6. (Optional) Create schedule
237
- npx ts-node src/client/schedule.ts schedule
238
- ```
239
-
240
- ## When to Use Which
241
-
242
- ### Use Reqon When:
243
- - ✅ Your workflow is data synchronization / ETL
244
- - ✅ You need to fetch, transform, validate, and store data
245
- - ✅ You want minimal infrastructure
246
- - ✅ Business users need to understand the pipeline
247
- - ✅ You need quick iteration and prototyping
248
- - ✅ The "happy path" is the main path
249
- - ✅ Retry/backoff/rate-limiting are your main concerns
250
-
251
- ### Use Temporal When:
252
- - ⚡ You need human-in-the-loop workflows
253
- - ⚡ You have complex branching/conditional logic
254
- - ⚡ You need workflow versioning/migration
255
- - ⚡ You need sub-second latency on signals
256
- - ⚡ You're building microservice orchestration
257
- - ⚡ You need the full power of a programming language
258
- - ⚡ You already have Temporal infrastructure
259
-
260
- ## Files
261
-
262
- ### Reqon Solution
263
- - `reconciliation.vague` - **The complete solution in ~280 lines**
264
-
265
- ### Temporal Solution (11 files, ~1,500 lines)
266
- ```
267
- temporal/
268
- ├── types/
269
- │ └── index.ts # Type definitions (130 lines)
270
- ├── config/
271
- │ └── retry.ts # Retry configuration (50 lines)
272
- ├── activities/
273
- │ ├── index.ts # Activity exports
274
- │ ├── shopify.ts # Shopify API (220 lines)
275
- │ ├── stripe.ts # Stripe API (150 lines)
276
- │ ├── shipstation.ts # ShipStation API (180 lines)
277
- │ ├── validation.ts # Validation logic (180 lines)
278
- │ └── storage.ts # Database operations (160 lines)
279
- ├── workflows/
280
- │ └── orderReconciliation.ts # Main workflow (200 lines)
281
- ├── workers/
282
- │ └── main.ts # Worker setup (100 lines)
283
- └── client/
284
- └── schedule.ts # Scheduler client (180 lines)
285
- ```
286
-
287
- ## The Bottom Line
288
-
289
- For data synchronization pipelines, Reqon offers:
290
-
291
- 1. **10x less code** - Focus on *what* you want, not *how* to do it
292
- 2. **Zero infrastructure** - Run anywhere Node.js runs
293
- 3. **Domain-specific** - Built specifically for fetch/transform/validate/store
294
- 4. **Readable** - Business logic is visible, not buried in code
295
- 5. **Batteries included** - Pagination, rate limiting, retries, checkpointing built-in
296
-
297
- Temporal is a powerful general-purpose workflow engine, but for the specific domain of data pipelines, it's like using a chainsaw to cut butter. Reqon is purpose-built for this domain and shows in every aspect of the developer experience.
@@ -1,355 +0,0 @@
1
- // E-Commerce Order Reconciliation Pipeline
2
- // Syncs and validates orders across Shopify, Stripe, and ShipStation
3
- // ~150 lines of declarative code vs ~1,500+ lines in Temporal
4
-
5
- mission OrderReconciliation {
6
-
7
- // ============================================================
8
- // SOURCES - API definitions with auth and rate limiting
9
- // ============================================================
10
-
11
- source Shopify {
12
- auth: oauth2,
13
- base: "https://mystore.myshopify.com/admin/api/2024-01",
14
- headers: { "X-Shopify-Access-Token": "${SHOPIFY_TOKEN}" },
15
- rateLimit: {
16
- strategy: "pause",
17
- maxWait: 120,
18
- fallbackRpm: 40
19
- }
20
- }
21
-
22
- source Stripe {
23
- auth: bearer,
24
- base: "https://api.stripe.com/v1",
25
- rateLimit: {
26
- strategy: "throttle",
27
- maxWait: 60,
28
- fallbackRpm: 100
29
- }
30
- }
31
-
32
- source ShipStation {
33
- auth: basic,
34
- base: "https://ssapi.shipstation.com",
35
- rateLimit: {
36
- strategy: "pause",
37
- maxWait: 30,
38
- fallbackRpm: 40
39
- }
40
- }
41
-
42
- // ============================================================
43
- // STORES - Where we persist reconciled data
44
- // ============================================================
45
-
46
- store orders: sql("reconciled_orders")
47
- store payments: sql("reconciled_payments")
48
- store shipments: sql("reconciled_shipments")
49
- store discrepancies: sql("audit_discrepancies")
50
- store sync_state: sql("sync_checkpoints")
51
-
52
- // ============================================================
53
- // SCHEMAS - Unified data models
54
- // ============================================================
55
-
56
- schema UnifiedOrder {
57
- order_id: string,
58
- external_id: string,
59
- source: string,
60
- customer_email: string,
61
- total_amount: decimal,
62
- currency: string,
63
- status: string,
64
- created_at: date,
65
- line_items_count: int,
66
- payment_status: string,
67
- fulfillment_status: string,
68
- synced_at: date
69
- }
70
-
71
- schema UnifiedPayment {
72
- payment_id: string,
73
- order_id: string,
74
- amount: decimal,
75
- currency: string,
76
- status: string,
77
- method: string,
78
- captured_at: date,
79
- refunded_amount: decimal
80
- }
81
-
82
- schema UnifiedShipment {
83
- shipment_id: string,
84
- order_id: string,
85
- carrier: string,
86
- tracking_number: string,
87
- status: string,
88
- shipped_at: date,
89
- delivered_at: date
90
- }
91
-
92
- schema Discrepancy {
93
- id: string,
94
- order_id: string,
95
- type: string,
96
- severity: string,
97
- description: string,
98
- shopify_value: string,
99
- stripe_value: string,
100
- shipstation_value: string,
101
- detected_at: date
102
- }
103
-
104
- // ============================================================
105
- // ACTION: Sync Shopify Orders (with incremental sync)
106
- // ============================================================
107
-
108
- action SyncShopifyOrders {
109
- // Get last sync timestamp for incremental sync
110
- get "/orders.json" {
111
- source: "Shopify",
112
- body: {
113
- "status": "any",
114
- "updated_at_min": sync_state.get("shopify_orders_last_sync"),
115
- "limit": 250
116
- },
117
- paginate: cursor(page_info, 250, "link.next"),
118
- until: response.orders.length == 0,
119
- retry: {
120
- maxAttempts: 5,
121
- backoff: "exponential",
122
- initialDelay: 2000,
123
- maxDelay: 60000
124
- }
125
- },
126
-
127
- // Transform each order to unified schema
128
- for order in response.orders {
129
- map order -> UnifiedOrder {
130
- order_id: "shopify_" + .id,
131
- external_id: .id,
132
- source: "shopify",
133
- customer_email: .customer.email,
134
- total_amount: .total_price,
135
- currency: .currency,
136
- status: .status,
137
- created_at: .created_at,
138
- line_items_count: length(.line_items),
139
- payment_status: match .financial_status {
140
- "paid" => "captured",
141
- "partially_paid" => "partial",
142
- "pending" => "pending",
143
- "refunded" => "refunded",
144
- "partially_refunded" => "partial_refund",
145
- _ => "unknown"
146
- },
147
- fulfillment_status: match .fulfillment_status {
148
- "fulfilled" => "shipped",
149
- "partial" => "partial",
150
- null => "unfulfilled",
151
- _ => .fulfillment_status
152
- },
153
- synced_at: now()
154
- },
155
-
156
- store response -> orders { key: .order_id, upsert: true }
157
- },
158
-
159
- // Update checkpoint
160
- store { "shopify_orders_last_sync": now() } -> sync_state { key: "shopify_orders_last_sync" }
161
- }
162
-
163
- // ============================================================
164
- // ACTION: Sync Stripe Payments
165
- // ============================================================
166
-
167
- action SyncStripePayments {
168
- get "/payment_intents" {
169
- source: "Stripe",
170
- body: {
171
- "limit": 100,
172
- "created[gte]": sync_state.get("stripe_payments_last_sync"),
173
- "expand[]": "data.charges"
174
- },
175
- paginate: cursor(starting_after, 100, "data[-1].id"),
176
- until: response.has_more == false,
177
- retry: {
178
- maxAttempts: 3,
179
- backoff: "exponential",
180
- initialDelay: 1000
181
- }
182
- },
183
-
184
- for payment in response.data where .metadata.shopify_order_id != null {
185
- map payment -> UnifiedPayment {
186
- payment_id: "stripe_" + .id,
187
- order_id: "shopify_" + .metadata.shopify_order_id,
188
- amount: .amount / 100, // Stripe uses cents
189
- currency: .currency,
190
- status: match .status {
191
- "succeeded" => "captured",
192
- "requires_capture" => "authorized",
193
- "canceled" => "voided",
194
- _ => .status
195
- },
196
- method: .payment_method_types[0],
197
- captured_at: .charges.data[0].created,
198
- refunded_amount: .charges.data[0].amount_refunded / 100
199
- },
200
-
201
- store response -> payments { key: .payment_id, upsert: true }
202
- },
203
-
204
- store { "stripe_payments_last_sync": now() } -> sync_state { key: "stripe_payments_last_sync" }
205
- }
206
-
207
- // ============================================================
208
- // ACTION: Sync ShipStation Shipments
209
- // ============================================================
210
-
211
- action SyncShipStationShipments {
212
- get "/shipments" {
213
- source: "ShipStation",
214
- body: {
215
- "pageSize": 500,
216
- "createDateStart": sync_state.get("shipstation_last_sync"),
217
- "sortBy": "CreateDate"
218
- },
219
- paginate: page(page, 500),
220
- until: response.shipments.length == 0,
221
- retry: {
222
- maxAttempts: 4,
223
- backoff: "exponential",
224
- initialDelay: 3000
225
- }
226
- },
227
-
228
- for shipment in response.shipments {
229
- map shipment -> UnifiedShipment {
230
- shipment_id: "ss_" + .shipmentId,
231
- order_id: "shopify_" + .orderNumber,
232
- carrier: .carrierCode,
233
- tracking_number: .trackingNumber,
234
- status: match .voided {
235
- true => "voided",
236
- _ => match .trackingNumber {
237
- null => "label_created",
238
- _ => "shipped"
239
- }
240
- },
241
- shipped_at: .shipDate,
242
- delivered_at: .deliveryDate
243
- },
244
-
245
- store response -> shipments { key: .shipment_id, upsert: true }
246
- },
247
-
248
- store { "shipstation_last_sync": now() } -> sync_state { key: "shipstation_last_sync" }
249
- }
250
-
251
- // ============================================================
252
- // ACTION: Cross-Reference and Validate
253
- // ============================================================
254
-
255
- action ValidateReconciliation {
256
- // Check for orders without payments
257
- for order in orders where .payment_status == "pending" and .created_at < now() - days(3) {
258
- let payment_exists = any of payments where .order_id == order.order_id,
259
-
260
- validate order {
261
- assume payment_exists == true
262
- } or {
263
- store {
264
- id: "disc_" + order.order_id + "_no_payment",
265
- order_id: order.order_id,
266
- type: "missing_payment",
267
- severity: "high",
268
- description: "Order older than 3 days has no matching Stripe payment",
269
- shopify_value: order.total_amount,
270
- stripe_value: null,
271
- shipstation_value: null,
272
- detected_at: now()
273
- } -> discrepancies { key: .id, upsert: true }
274
- }
275
- },
276
-
277
- // Check for payment/order amount mismatches
278
- for order in orders {
279
- let matching_payments = payments where .order_id == order.order_id,
280
- let total_paid = sum(matching_payments.amount),
281
-
282
- validate order {
283
- assume total_paid >= order.total_amount - 0.01,
284
- assume total_paid <= order.total_amount + 0.01
285
- } or {
286
- store {
287
- id: "disc_" + order.order_id + "_amount_mismatch",
288
- order_id: order.order_id,
289
- type: "amount_mismatch",
290
- severity: match abs(order.total_amount - total_paid) {
291
- x where x > 100 => "critical",
292
- x where x > 10 => "high",
293
- _ => "medium"
294
- },
295
- description: "Order total does not match payment total",
296
- shopify_value: order.total_amount,
297
- stripe_value: total_paid,
298
- shipstation_value: null,
299
- detected_at: now()
300
- } -> discrepancies { key: .id, upsert: true }
301
- }
302
- },
303
-
304
- // Check for shipped orders without shipment records
305
- for order in orders where .fulfillment_status == "shipped" {
306
- let shipment_exists = any of shipments where .order_id == order.order_id,
307
-
308
- validate order {
309
- assume shipment_exists == true
310
- } or {
311
- store {
312
- id: "disc_" + order.order_id + "_no_shipment",
313
- order_id: order.order_id,
314
- type: "missing_shipment_record",
315
- severity: "medium",
316
- description: "Shopify shows fulfilled but no ShipStation shipment found",
317
- shopify_value: order.fulfillment_status,
318
- stripe_value: null,
319
- shipstation_value: null,
320
- detected_at: now()
321
- } -> discrepancies { key: .id, upsert: true }
322
- }
323
- },
324
-
325
- // Check for refund discrepancies
326
- for payment in payments where .refunded_amount > 0 {
327
- let order = first(orders where .order_id == payment.order_id),
328
-
329
- validate payment {
330
- assume order.payment_status == "refunded" or order.payment_status == "partial_refund"
331
- } or {
332
- store {
333
- id: "disc_" + payment.order_id + "_refund_mismatch",
334
- order_id: payment.order_id,
335
- type: "refund_status_mismatch",
336
- severity: "high",
337
- description: "Stripe shows refund but Shopify payment status not updated",
338
- shopify_value: order.payment_status,
339
- stripe_value: payment.refunded_amount,
340
- shipstation_value: null,
341
- detected_at: now()
342
- } -> discrepancies { key: .id, upsert: true }
343
- }
344
- }
345
- }
346
-
347
- // ============================================================
348
- // PIPELINE: Parallel fetch, then sequential validation
349
- // ============================================================
350
-
351
- // Fetch from all three APIs in parallel for maximum performance
352
- // ValidateReconciliation runs after all three complete
353
- run [SyncShopifyOrders, SyncStripePayments, SyncShipStationShipments]
354
- then ValidateReconciliation
355
- }
@@ -1,8 +0,0 @@
1
- // Activity exports
2
- // Aggregate all activities for worker registration
3
-
4
- export * from './shopify';
5
- export * from './stripe';
6
- export * from './shipstation';
7
- export * from './validation';
8
- export * from './storage';