@adonis-agora/durable 0.41.0 → 0.43.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 (71) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/dist/assets/spa/assets/index-BkHCh-H3.js +16 -0
  3. package/dist/assets/spa/assets/index-BkHCh-H3.js.map +1 -0
  4. package/dist/assets/spa/index.html +1 -1
  5. package/dist/providers/durable_provider.d.ts.map +1 -1
  6. package/dist/providers/durable_provider.js +10 -0
  7. package/dist/providers/durable_provider.js.map +1 -1
  8. package/dist/src/codec-state-store.d.ts +13 -1
  9. package/dist/src/codec-state-store.d.ts.map +1 -1
  10. package/dist/src/codec-state-store.js +32 -0
  11. package/dist/src/codec-state-store.js.map +1 -1
  12. package/dist/src/commands/worker.d.ts.map +1 -1
  13. package/dist/src/commands/worker.js +4 -0
  14. package/dist/src/commands/worker.js.map +1 -1
  15. package/dist/src/concurrency.d.ts +55 -0
  16. package/dist/src/concurrency.d.ts.map +1 -0
  17. package/dist/src/concurrency.js +52 -0
  18. package/dist/src/concurrency.js.map +1 -0
  19. package/dist/src/dashboard/index.d.ts +1 -1
  20. package/dist/src/dashboard/index.js +1 -1
  21. package/dist/src/define_config.d.ts +17 -1
  22. package/dist/src/define_config.d.ts.map +1 -1
  23. package/dist/src/define_config.js.map +1 -1
  24. package/dist/src/engine.d.ts +73 -2
  25. package/dist/src/engine.d.ts.map +1 -1
  26. package/dist/src/engine.js +195 -26
  27. package/dist/src/engine.js.map +1 -1
  28. package/dist/src/errors.d.ts +13 -0
  29. package/dist/src/errors.d.ts.map +1 -1
  30. package/dist/src/errors.js +20 -0
  31. package/dist/src/errors.js.map +1 -1
  32. package/dist/src/index.d.ts +3 -1
  33. package/dist/src/index.d.ts.map +1 -1
  34. package/dist/src/index.js +3 -1
  35. package/dist/src/index.js.map +1 -1
  36. package/dist/src/interfaces.d.ts +111 -0
  37. package/dist/src/interfaces.d.ts.map +1 -1
  38. package/dist/src/interfaces.js +18 -1
  39. package/dist/src/interfaces.js.map +1 -1
  40. package/dist/src/run-value-facets.d.ts +1 -1
  41. package/dist/src/run-value-facets.d.ts.map +1 -1
  42. package/dist/src/run-value-facets.js +1 -1
  43. package/dist/src/run-value-facets.js.map +1 -1
  44. package/dist/src/schedules.d.ts +172 -0
  45. package/dist/src/schedules.d.ts.map +1 -0
  46. package/dist/src/schedules.js +362 -0
  47. package/dist/src/schedules.js.map +1 -0
  48. package/dist/src/stores/lucid-schema.d.ts +1 -0
  49. package/dist/src/stores/lucid-schema.d.ts.map +1 -1
  50. package/dist/src/stores/lucid-schema.js +21 -0
  51. package/dist/src/stores/lucid-schema.js.map +1 -1
  52. package/dist/src/stores/lucid.d.ts +9 -1
  53. package/dist/src/stores/lucid.d.ts.map +1 -1
  54. package/dist/src/stores/lucid.js +107 -0
  55. package/dist/src/stores/lucid.js.map +1 -1
  56. package/dist/src/testing/in-memory-state-store.d.ts +8 -1
  57. package/dist/src/testing/in-memory-state-store.d.ts.map +1 -1
  58. package/dist/src/testing/in-memory-state-store.js +38 -0
  59. package/dist/src/testing/in-memory-state-store.js.map +1 -1
  60. package/dist/src/testing-kit/state-store-conformance.d.ts.map +1 -1
  61. package/dist/src/testing-kit/state-store-conformance.js +101 -0
  62. package/dist/src/testing-kit/state-store-conformance.js.map +1 -1
  63. package/dist/src/workflow-discovery.d.ts.map +1 -1
  64. package/dist/src/workflow-discovery.js +1 -0
  65. package/dist/src/workflow-discovery.js.map +1 -1
  66. package/dist/src/workflow-ref.d.ts +9 -0
  67. package/dist/src/workflow-ref.d.ts.map +1 -1
  68. package/dist/src/workflow-ref.js.map +1 -1
  69. package/package.json +6 -6
  70. package/dist/assets/spa/assets/index-CeHc6GHq.js +0 -16
  71. package/dist/assets/spa/assets/index-CeHc6GHq.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,50 @@
1
1
  # @adonis-agora/durable
2
2
 
3
+ ## 0.43.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#222](https://github.com/DavideCarvalho/adonis-agora-durable/pull/222) [`9540e66`](https://github.com/DavideCarvalho/adonis-agora-durable/commit/9540e66f942c3bbae6440ca6657909ffd6cc3734) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - **Persisted schedules** — port of nestjs-durable#338. Temporal-style schedules managed at runtime and stored next to the runs, alongside the code-declared `schedules` config / `static schedule`.
8
+
9
+ - `engine.schedules`: `create` / `upsert` / `get` / `list` / `pause(note?)` / `resume` / `trigger` / `delete` / `tick`. A schedule starts `workflow` with `input` on a `cron` (+ IANA `timezone`) or a fixed `every` interval, with a stable per-window `jitter`, `overlap` (`allow` / `skip` while the previous run is in flight), `catchup` (`latest` missed window once, or `skip`), `tags` (also stamped on its runs, plus `schedule:<id>`), `searchAttributes`, `priority` and `namespace`. Failed starts are recorded as `lastError`; `get`/`list` report next/last fire, last run and fire count.
10
+ - **Multi-worker safe without locks**: a window's run id is deterministic (`sched:<id>:<windowMs>`) and advancing a schedule is a compare-and-set on its `next_fire_at`.
11
+ - `persistedSchedules: true` in `config/durable.ts` makes the worker tick (`durable:work` / the embedded worker) fire due schedules — off by default.
12
+ - New `durable_schedules` table, created by `createDurableTables` (auto-schema on boot; with `autoSchema: false`, add a migration that calls `createDurableTables` again — it only creates what's missing), and five optional `StateStore` methods (`saveSchedule`, `getSchedule`, `updateSchedule` with CAS, `deleteSchedule`, `listSchedules`) implemented by the Lucid and in-memory stores; `CodecStateStore` forwards them, encoding the schedule input. Covered by the shared contract.
13
+
14
+ - [#226](https://github.com/DavideCarvalho/adonis-agora-durable/pull/226) [`edab227`](https://github.com/DavideCarvalho/adonis-agora-durable/commit/edab227f547e2804688ec7b8596c085a71240393) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - A persisted schedule can carry a **concurrency quota** (port of nestjs-durable#340): `engine.schedules.create/upsert({ …, concurrency: { key, limit, countStatuses? } })` applies it to every run the schedule starts, like `StartOptions.concurrency`. An over-limit window is skipped and recorded as the schedule's `lastError`; the schedule moves on to its next window.
15
+
16
+ ## 0.42.0
17
+
18
+ ### Minor Changes
19
+
20
+ - [#221](https://github.com/DavideCarvalho/adonis-agora-durable/pull/221) [`448b3b1`](https://github.com/DavideCarvalho/adonis-agora-durable/commit/448b3b129c0f586b19b35036cf76a4e3982d7a60) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - New `DynamicWorkflowCtx` type — port of nestjs-durable#337: `WorkflowCtx` with ONE string-addressed signature for each of its overloaded methods (`step`, `child`, `startChild`, `all`). Every `WorkflowCtx` is assignable to it, so code that drives the ctx by names (a graph interpreter) and test fakes can depend on it — or on a `Pick` of it — instead of re-declaring a narrow interface and casting `ctx as unknown as …`. A type-test pins the assignability.
21
+
22
+ - [#219](https://github.com/DavideCarvalho/adonis-agora-durable/pull/219) [`614ca9b`](https://github.com/DavideCarvalho/adonis-agora-durable/commit/614ca9bd259e48710738a88f73dc227d4f9844c2) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - Retention can be **scoped**, and a tenant's runs can be **purged** through the engine — port of nestjs-durable#335.
23
+
24
+ - **`retention.policies`** (engine: `retentionPolicies`): scoped rules next to the per-status ages — each deletes terminal runs in its `statuses` that match its `scope` (`namespace(s)`, `workflow(s)`, `tag`/`tags`, search-attribute `attributes` — the new `RunScope` type) once their last activity is older than `maxAge`. Swept by the same throttled `sweepRetention`, with the same `onEvict` archival hooks and subtree cascade. A namespaced worker never sweeps another partition's scope.
25
+ - **`engine.purgeRuns(scope, { batchSize?, cancelLive?, children? })` / `engine.purgeNamespace(ns)`**: hard-delete every run a scope matches with its child subtree (children inherit `namespace`, not `tags` — they go with their root either way), in bounded batches, sweeping their buffered signals. Live runs are cancelled first (`cancelLive: false` keeps them). An empty scope is rejected.
26
+ - New exports: `RunScope`, `isNonEmptyRunScope`, `TERMINAL_RUN_STATUSES`, `TerminalRunStatus`, `ScopedRetentionPolicy`.
27
+
28
+ - [#220](https://github.com/DavideCarvalho/adonis-agora-durable/pull/220) [`0d19781`](https://github.com/DavideCarvalho/adonis-agora-durable/commit/0d1978138af2bb5f7348b49dd618fad77aa4c200) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - **Start-time concurrency quotas** — port of nestjs-durable#336. Cap how many runs sharing a key can be in flight and reject the start that would exceed it ("a tenant can have at most 8 turns executing"), without a hand-rolled count gate.
29
+
30
+ - `static workflow = { concurrency: { key: (input) => …, limit, countStatuses? } }` (also `engine.register` / `registerRemote`), or per start with `StartOptions.concurrency: { key, limit, countStatuses? }` (overrides the workflow's). The key is global, so several workflows can share one quota; `limit` may be an async function of the key; `countStatuses` narrows what occupies a slot (default: every non-terminal status).
31
+ - Over the limit `start` throws **`ConcurrencyLimitError`** (`key`, `limit`, `active`, `workflow`) and creates nothing; an idempotent re-start of an existing run id is never rejected. Quota-bearing runs carry the engine-minted tag `concurrency:<key>`.
32
+ - New optional `StateStore.countRuns(query)` — one `COUNT(*)` over the `listRuns` predicates — implemented by the Lucid and in-memory stores and `CodecStateStore`, and covered by the shared contract. The engine falls back to counting a listing for a custom store.
33
+
34
+ A soft cap under a race (count and insert are separate statements); use `singleton` for a strict, queueing per-key limit.
35
+
36
+ ## 0.41.1
37
+
38
+ ### Patch Changes
39
+
40
+ - [#202](https://github.com/DavideCarvalho/adonis-agora-durable/pull/202) [`573a198`](https://github.com/DavideCarvalho/adonis-agora-durable/commit/573a198ae5e1e69503f3a37d3b9817da07b038c4) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - A run is no longer counted, dead-lettered or executed twice when its turn settles while the orphan sweep is looking at it.
41
+
42
+ Port of the same race fixed in the NestJS core (nestjs-durable#331), seen there as intermittently hung durable chat turns where an in-process worker answers a dispatched step in a couple of milliseconds:
43
+
44
+ - **A turn releases its lease only after its settled state is written.** `runExecution` returned `this.settleRun(...)` (and `this.parkBlocked(...)`) without awaiting it inside `try … finally { releaseRunLock }`, so the `finally` ran first: a first turn that completed, failed or parked `blocked` sat unlocked while its row still read `running`, which is what `listOrphanedRuns` returns for a crashed turn. Every settle in that block is now `return await`ed. (The suspend settle was already awaited.)
45
+ - **`recoverIncomplete` decides on the run it locked, not the one it listed.** It trusted the listed `running` status: a run that settled between the listing and `tryLockRun` got a recovery attempt counted and, past `maxRecoveryAttempts`, an unconditional `dead` written over a completed or suspended run. It now re-reads the run under the lease and releases it again unless it still reads `running`. The dead-letter write is also conditional on `running`, so a lease-free `cancel()` landing after that re-read is not overwritten with `dead`.
46
+ - **A replay re-reads a `pending` remote step before acting on it.** With `remoteRedispatchMs` set, a replay that found its step pending in its start-of-execution snapshot stamped the lease by writing `{ ...snapshot, wakeAt }` back, overwriting a result that had landed since with `pending` and parking the run on a lease an hour out. The step is now re-read from the store first; a result that has landed is replayed instead.
47
+
3
48
  ## 0.41.0
4
49
 
5
50
  ### Minor Changes