@demlik/tea 0.13.0 → 0.15.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.
- package/README.md +11 -9
- package/dist/agent/index.d.ts +638 -45
- package/dist/agent/index.js +9 -19
- package/dist/{chunk-RH5EFRVJ.js → chunk-22POWGFA.js} +31 -5
- package/dist/chunk-22POWGFA.js.map +1 -0
- package/dist/{chunk-DMYGQB4O.js → chunk-3B5X7SBB.js} +23 -6
- package/dist/chunk-3B5X7SBB.js.map +1 -0
- package/dist/chunk-66PY5WYF.js +1816 -0
- package/dist/chunk-66PY5WYF.js.map +1 -0
- package/dist/{chunk-25LBDCBC.js → chunk-6IQPODUF.js} +2 -2
- package/dist/{chunk-25LBDCBC.js.map → chunk-6IQPODUF.js.map} +1 -1
- package/dist/chunk-AYS5N6WY.js +505 -0
- package/dist/chunk-AYS5N6WY.js.map +1 -0
- package/dist/{chunk-EWJP3YYP.js → chunk-HWVW4AXC.js} +3 -3
- package/dist/chunk-HWVW4AXC.js.map +1 -0
- package/dist/{chunk-O4MVQTEJ.js → chunk-L3TND7LA.js} +20 -16
- package/dist/chunk-L3TND7LA.js.map +1 -0
- package/dist/{chunk-J6527VRQ.js → chunk-LFZUK6J2.js} +3 -3
- package/dist/chunk-LFZUK6J2.js.map +1 -0
- package/dist/{chunk-D736QUGF.js → chunk-MYXFNWAJ.js} +4 -5
- package/dist/chunk-MYXFNWAJ.js.map +1 -0
- package/dist/{chunk-K575PT4S.js → chunk-PR6TB3BL.js} +15 -4
- package/dist/chunk-PR6TB3BL.js.map +1 -0
- package/dist/{chunk-YUXP55T2.js → chunk-Q5CQTBFA.js} +57 -7
- package/dist/chunk-Q5CQTBFA.js.map +1 -0
- package/dist/{batch-window/index.js → chunk-QPEVCJ5Q.js} +4 -8
- package/dist/chunk-QPEVCJ5Q.js.map +1 -0
- package/dist/chunk-TCLBCERH.js +1480 -0
- package/dist/chunk-TCLBCERH.js.map +1 -0
- package/dist/{chunk-FV3Z5MBE.js → chunk-TXN2KFHF.js} +14 -4
- package/dist/chunk-TXN2KFHF.js.map +1 -0
- package/dist/{chunk-MUUROGIH.js → chunk-V46HSVCK.js} +62 -12
- package/dist/chunk-V46HSVCK.js.map +1 -0
- package/dist/{chunk-Q2UM7BXU.js → chunk-VBDU4JL6.js} +2 -2
- package/dist/chunk-VBDU4JL6.js.map +1 -0
- package/dist/{chunk-ZVJZ72HY.js → chunk-VTQI2NHP.js} +25 -11
- package/dist/chunk-VTQI2NHP.js.map +1 -0
- package/dist/{core-Co0LWkIA.d.ts → core-DnzqWy6u.d.ts} +72 -23
- package/dist/devtools/index.d.ts +2 -2
- package/dist/devtools/index.js +207 -2
- package/dist/devtools/index.js.map +1 -1
- package/dist/do/index.d.ts +43 -29
- package/dist/do/index.js +36 -25
- package/dist/do/index.js.map +1 -1
- package/dist/{durable-effects-C6uwzjb5.d.ts → durable-effects-CWzA-o2B.d.ts} +2 -2
- package/dist/extension/index.d.ts +300 -3
- package/dist/extension/index.js +596 -5
- package/dist/extension/index.js.map +1 -1
- package/dist/flow/index.d.ts +1284 -0
- package/dist/flow/index.js +732 -0
- package/dist/flow/index.js.map +1 -0
- package/dist/idempotency/index.d.ts +90 -116
- package/dist/idempotency/index.js +4 -1
- package/dist/index-Bc40JWVl.d.ts +131 -0
- package/dist/{batch-window/index.d.ts → index-C2DwkjlP.d.ts} +7 -12
- package/dist/index-CA_7I5g9.d.ts +806 -0
- package/dist/index-CSyMYDAB.d.ts +69 -0
- package/dist/{fan-out/index.d.ts → index-CuNO9m8i.d.ts} +7 -9
- package/dist/{debounce/index.d.ts → index-DHSUmQTR.d.ts} +7 -7
- package/dist/{recorder/index.d.ts → index-DrIRb_Ch.d.ts} +4 -7
- package/dist/index-HSYgG2Yt.d.ts +380 -0
- package/dist/{monitored-run/index.d.ts → index-KXqTRJyb.d.ts} +37 -13
- package/dist/{snapshot/index.d.ts → index-ZCMhnVKN.d.ts} +15 -78
- package/dist/index.d.ts +771 -6
- package/dist/index.js +1 -2
- package/dist/jev/index.d.ts +646 -0
- package/dist/jev/index.js +485 -0
- package/dist/jev/index.js.map +1 -0
- package/dist/machine-DGlPWCWI.d.ts +1781 -0
- package/dist/machine-viz/index.d.ts +1 -1
- package/dist/machine-viz/index.js +12 -5
- package/dist/machine-viz/index.js.map +1 -1
- package/dist/mem/index.d.ts +18 -3
- package/dist/mem/index.js +22 -2
- package/dist/mem/index.js.map +1 -1
- package/dist/node/index.d.ts +104 -6
- package/dist/node/index.js +132 -9
- package/dist/node/index.js.map +1 -1
- package/dist/{paginator → paginate}/index.d.ts +140 -6
- package/dist/paginate/index.js +7 -0
- package/dist/parity/index.d.ts +4 -10
- package/dist/parity/index.js +4 -7
- package/dist/parity/index.js.map +1 -1
- package/dist/pbt/index.d.ts +247 -5
- package/dist/pbt/index.js +124 -5
- package/dist/pbt/index.js.map +1 -1
- package/dist/{trace-replay → persistence}/index.d.ts +7 -5
- package/dist/persistence/index.js +6 -0
- package/dist/{protocol-B5YmJr0d.d.ts → protocol-D8VbH-VH.d.ts} +10 -1
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +1 -2
- package/dist/react/index.js.map +1 -1
- package/dist/resilience/index.d.ts +744 -0
- package/dist/resilience/index.js +657 -0
- package/dist/resilience/index.js.map +1 -0
- package/dist/retry-backoff/index.d.ts +3 -2
- package/dist/retry-backoff/index.js +1 -1
- package/dist/runtime-types-CMF13BBh.d.ts +998 -0
- package/dist/testing/index.d.ts +147 -3
- package/dist/testing/index.js +95 -3
- package/dist/testing/index.js.map +1 -1
- package/dist/{throttled-input → timing}/index.d.ts +143 -12
- package/dist/{throttled-input → timing}/index.js +57 -12
- package/dist/timing/index.js.map +1 -0
- package/dist/{types-XS_miRnB.d.ts → types-BseNPIhr.d.ts} +1 -1
- package/dist/work-queue/index.d.ts +130 -54
- package/dist/work-queue/index.js +3 -2
- package/dist/work-queue/index.js.map +1 -1
- package/package.json +45 -218
- package/dist/authed-call/index.d.ts +0 -120
- package/dist/authed-call/index.js +0 -134
- package/dist/authed-call/index.js.map +0 -1
- package/dist/await-terminal/index.d.ts +0 -101
- package/dist/await-terminal/index.js +0 -76
- package/dist/await-terminal/index.js.map +0 -1
- package/dist/batch-window/index.js.map +0 -1
- package/dist/cache/index.d.ts +0 -152
- package/dist/cache/index.js +0 -8
- package/dist/chart/index.d.ts +0 -218
- package/dist/chart/index.js +0 -16
- package/dist/chart/index.js.map +0 -1
- package/dist/chart/inspect/index.d.ts +0 -86
- package/dist/chart/inspect/index.js +0 -5
- package/dist/chart/inspect/react.d.ts +0 -113
- package/dist/chart/inspect/react.js +0 -11
- package/dist/chart/inspect/react.js.map +0 -1
- package/dist/chart/inspect/styles.css +0 -286
- package/dist/chart/lane/index.d.ts +0 -362
- package/dist/chart/lane/index.js +0 -9
- package/dist/chart/lane/index.js.map +0 -1
- package/dist/chart/lane/react.d.ts +0 -84
- package/dist/chart/lane/react.js +0 -559
- package/dist/chart/lane/react.js.map +0 -1
- package/dist/chart/lane/server.d.ts +0 -148
- package/dist/chart/lane/server.js +0 -209
- package/dist/chart/lane/server.js.map +0 -1
- package/dist/chart/lane/styles.css +0 -498
- package/dist/chart/lane/viewer/assets/abnfDiagram-N423BO3Z-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/architectureDiagram-T3A2C74G-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/blockDiagram-VBNYF7ZC-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/c4Diagram-5PPSVZJV-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/chunk-2GRJ4B5K-HdDf8SI3.js +0 -1
- package/dist/chart/lane/viewer/assets/chunk-5RXB4S5H-CcNtpUd7.js +0 -231
- package/dist/chart/lane/viewer/assets/chunk-5VM5RSS4-BP4fRS_5.js +0 -15
- package/dist/chart/lane/viewer/assets/chunk-KBJHAD2P-DZOw7xU6.js +0 -1
- package/dist/chart/lane/viewer/assets/chunk-NSK5VX7P-CBCyTZMs.js +0 -128
- package/dist/chart/lane/viewer/assets/classDiagram-JCYQIIEL-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/classDiagram-v2-OCEON4UE-D4uAiFr8.js +0 -206
- package/dist/chart/lane/viewer/assets/cose-bilkent-JH36ORCC-DOwCrGXH.js +0 -1
- package/dist/chart/lane/viewer/assets/cynefinDiagram-MW4NZA55-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/dagre-K_PewWfS.js +0 -1
- package/dist/chart/lane/viewer/assets/dagre-VZM6K2ZE-831qZcA8.js +0 -4
- package/dist/chart/lane/viewer/assets/diagram-7IWD3JNH-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/diagram-B4RE2ZJO-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/diagram-LBJQPF4R-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/diagram-Q27KOJAE-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/diagram-UB23O5K3-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/ebnfDiagram-BXEA7PRR-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/erDiagram-JOGREHBK-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/flowDiagram-UKHOOZJN-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/ganttDiagram-PKOTCBZU-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/gitGraphDiagram-DS77QQ5N-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/index-9SkH5NA3.css +0 -1
- package/dist/chart/lane/viewer/assets/index-Bgt4sXpW.js +0 -195
- package/dist/chart/lane/viewer/assets/infoDiagram-6WML65LV-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/ishikawaDiagram-WSZJBQD7-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/journeyDiagram-NVQOT4AX-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/kanban-definition-27J2QSJJ-G7PaPzy-.js +0 -89
- package/dist/chart/lane/viewer/assets/katex-DOwCrGXH.js +0 -1
- package/dist/chart/lane/viewer/assets/mindmap-definition-FAOFIHXS-CGj9nrVk.js +0 -96
- package/dist/chart/lane/viewer/assets/path-fybaL0A-.js +0 -1
- package/dist/chart/lane/viewer/assets/pegDiagram-VL7TDLO6-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/pieDiagram-7S7Q4E2Y-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/quadrantDiagram-CIZ2JOQS-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/railroadDiagram-AXF67PYL-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/requirementDiagram-LRYGKXZP-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/sankeyDiagram-W5VNT64P-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/sequenceDiagram-SI44F4Z6-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/stateDiagram-OKZ733FA-B_88AzBS.js +0 -1
- package/dist/chart/lane/viewer/assets/stateDiagram-v2-UEYNNEHI-CR5gcgq6.js +0 -1
- package/dist/chart/lane/viewer/assets/swimlanes-SLNWSIFB-B4xK-rwg.js +0 -1
- package/dist/chart/lane/viewer/assets/swimlanesDiagram-ULZ7WXOC-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/timeline-definition-Z64GVDOM-CCv52MfY.js +0 -120
- package/dist/chart/lane/viewer/assets/vennDiagram-T6HMQDX7-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/wardleyDiagram-T6FBY63Y-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/xychartDiagram-ELKLHX3M-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/index.html +0 -15
- package/dist/chart/report/index.d.ts +0 -117
- package/dist/chart/report/index.js +0 -32
- package/dist/chart/report/index.js.map +0 -1
- package/dist/chunk-2YFLOCWX.js +0 -15
- package/dist/chunk-2YFLOCWX.js.map +0 -1
- package/dist/chunk-3I52QZZ5.js +0 -519
- package/dist/chunk-3I52QZZ5.js.map +0 -1
- package/dist/chunk-3ZAFFRRB.js +0 -457
- package/dist/chunk-3ZAFFRRB.js.map +0 -1
- package/dist/chunk-4EQZ76JC.js +0 -33
- package/dist/chunk-4EQZ76JC.js.map +0 -1
- package/dist/chunk-4KLG43GY.js +0 -223
- package/dist/chunk-4KLG43GY.js.map +0 -1
- package/dist/chunk-7FRZ2CT2.js +0 -424
- package/dist/chunk-7FRZ2CT2.js.map +0 -1
- package/dist/chunk-AZZLE7XR.js +0 -62
- package/dist/chunk-AZZLE7XR.js.map +0 -1
- package/dist/chunk-BYQUGDD3.js +0 -16
- package/dist/chunk-BYQUGDD3.js.map +0 -1
- package/dist/chunk-CIQG5L42.js +0 -685
- package/dist/chunk-CIQG5L42.js.map +0 -1
- package/dist/chunk-CLM6ERNO.js +0 -61
- package/dist/chunk-CLM6ERNO.js.map +0 -1
- package/dist/chunk-COS5MSTO.js +0 -88
- package/dist/chunk-COS5MSTO.js.map +0 -1
- package/dist/chunk-CRPZJVD2.js +0 -71
- package/dist/chunk-CRPZJVD2.js.map +0 -1
- package/dist/chunk-D62FDQKE.js +0 -53
- package/dist/chunk-D62FDQKE.js.map +0 -1
- package/dist/chunk-D736QUGF.js.map +0 -1
- package/dist/chunk-DGE4PV4A.js +0 -26
- package/dist/chunk-DGE4PV4A.js.map +0 -1
- package/dist/chunk-DMYGQB4O.js.map +0 -1
- package/dist/chunk-EWJP3YYP.js.map +0 -1
- package/dist/chunk-FV3Z5MBE.js.map +0 -1
- package/dist/chunk-HCEVHFJ7.js +0 -54
- package/dist/chunk-HCEVHFJ7.js.map +0 -1
- package/dist/chunk-J6527VRQ.js.map +0 -1
- package/dist/chunk-JELSZN25.js +0 -47
- package/dist/chunk-JELSZN25.js.map +0 -1
- package/dist/chunk-K575PT4S.js.map +0 -1
- package/dist/chunk-L57ZOT5K.js +0 -184
- package/dist/chunk-L57ZOT5K.js.map +0 -1
- package/dist/chunk-MU6MCIAC.js +0 -15
- package/dist/chunk-MU6MCIAC.js.map +0 -1
- package/dist/chunk-MUUROGIH.js.map +0 -1
- package/dist/chunk-NR7BU22N.js +0 -758
- package/dist/chunk-NR7BU22N.js.map +0 -1
- package/dist/chunk-O4MVQTEJ.js.map +0 -1
- package/dist/chunk-OOYD44JI.js +0 -317
- package/dist/chunk-OOYD44JI.js.map +0 -1
- package/dist/chunk-Q2UM7BXU.js.map +0 -1
- package/dist/chunk-RH5EFRVJ.js.map +0 -1
- package/dist/chunk-S2EGRPCM.js +0 -47
- package/dist/chunk-S2EGRPCM.js.map +0 -1
- package/dist/chunk-SINXE47Y.js +0 -55
- package/dist/chunk-SINXE47Y.js.map +0 -1
- package/dist/chunk-UF4MZSLT.js +0 -53
- package/dist/chunk-UF4MZSLT.js.map +0 -1
- package/dist/chunk-UOC2PL46.js +0 -13
- package/dist/chunk-UOC2PL46.js.map +0 -1
- package/dist/chunk-VYFAZN3F.js +0 -372
- package/dist/chunk-VYFAZN3F.js.map +0 -1
- package/dist/chunk-WRAA7GVZ.js +0 -209
- package/dist/chunk-WRAA7GVZ.js.map +0 -1
- package/dist/chunk-XGELA764.js +0 -163
- package/dist/chunk-XGELA764.js.map +0 -1
- package/dist/chunk-YUXP55T2.js.map +0 -1
- package/dist/chunk-YWIKDKHY.js +0 -307
- package/dist/chunk-YWIKDKHY.js.map +0 -1
- package/dist/chunk-ZJ5AOYBH.js +0 -8
- package/dist/chunk-ZJ5AOYBH.js.map +0 -1
- package/dist/chunk-ZSUUOEPL.js +0 -731
- package/dist/chunk-ZSUUOEPL.js.map +0 -1
- package/dist/chunk-ZVJZ72HY.js.map +0 -1
- package/dist/circuit-breaker/index.d.ts +0 -197
- package/dist/circuit-breaker/index.js +0 -3
- package/dist/circuit-breaker/index.js.map +0 -1
- package/dist/deadline/index.d.ts +0 -199
- package/dist/deadline/index.js +0 -6
- package/dist/deadline/index.js.map +0 -1
- package/dist/debounce/index.js +0 -3
- package/dist/debounce/index.js.map +0 -1
- package/dist/extension/react.d.ts +0 -121
- package/dist/extension/react.js +0 -75
- package/dist/extension/react.js.map +0 -1
- package/dist/extension/subs/index.d.ts +0 -45
- package/dist/extension/subs/index.js +0 -80
- package/dist/extension/subs/index.js.map +0 -1
- package/dist/extension/test-utils.d.ts +0 -128
- package/dist/extension/test-utils.js +0 -277
- package/dist/extension/test-utils.js.map +0 -1
- package/dist/fan-out/index.js +0 -5
- package/dist/fan-out/index.js.map +0 -1
- package/dist/fold-BJPdjc9w.d.ts +0 -435
- package/dist/graph-B3L5e0N1.d.ts +0 -923
- package/dist/idempotency/adapter.d.ts +0 -62
- package/dist/idempotency/adapter.js +0 -4
- package/dist/idempotency/adapter.js.map +0 -1
- package/dist/idempotent-intake/index.d.ts +0 -188
- package/dist/idempotent-intake/index.js +0 -7
- package/dist/idempotent-intake/index.js.map +0 -1
- package/dist/journal/index.d.ts +0 -373
- package/dist/journal/index.js +0 -3
- package/dist/journal/index.js.map +0 -1
- package/dist/llm-call/index.d.ts +0 -311
- package/dist/llm-call/index.js +0 -16
- package/dist/llm-call/index.js.map +0 -1
- package/dist/machine-BtFWQmmq.d.ts +0 -804
- package/dist/monitored-run/index.js +0 -10
- package/dist/monitored-run/index.js.map +0 -1
- package/dist/paginated-walk/index.d.ts +0 -235
- package/dist/paginated-walk/index.js +0 -16
- package/dist/paginated-walk/index.js.map +0 -1
- package/dist/paginator/index.js +0 -3
- package/dist/paginator/index.js.map +0 -1
- package/dist/pbt/arbitraries/index.d.ts +0 -136
- package/dist/pbt/arbitraries/index.js +0 -3
- package/dist/pbt/arbitraries/index.js.map +0 -1
- package/dist/pbt/runners/index.d.ts +0 -118
- package/dist/pbt/runners/index.js +0 -5
- package/dist/pbt/runners/index.js.map +0 -1
- package/dist/poller/index.d.ts +0 -352
- package/dist/poller/index.js +0 -115
- package/dist/poller/index.js.map +0 -1
- package/dist/prediction/index.d.ts +0 -131
- package/dist/prediction/index.js +0 -4
- package/dist/prediction/index.js.map +0 -1
- package/dist/pure/index.d.ts +0 -3
- package/dist/pure/index.js +0 -4
- package/dist/pure/index.js.map +0 -1
- package/dist/rate-limit/index.d.ts +0 -115
- package/dist/rate-limit/index.js +0 -3
- package/dist/rate-limit/index.js.map +0 -1
- package/dist/reconciler/index.d.ts +0 -193
- package/dist/reconciler/index.js +0 -164
- package/dist/reconciler/index.js.map +0 -1
- package/dist/recorder/index.js +0 -3
- package/dist/recorder/index.js.map +0 -1
- package/dist/reducer-4GNR6b8B.d.ts +0 -447
- package/dist/resilient-call/index.d.ts +0 -320
- package/dist/resilient-call/index.js +0 -14
- package/dist/resilient-call/index.js.map +0 -1
- package/dist/retry-to-success/index.d.ts +0 -109
- package/dist/retry-to-success/index.js +0 -37
- package/dist/retry-to-success/index.js.map +0 -1
- package/dist/run-pAcmBpah.d.ts +0 -713
- package/dist/runtime-types-CNLmhWif.d.ts +0 -517
- package/dist/saga/index.d.ts +0 -241
- package/dist/saga/index.js +0 -150
- package/dist/saga/index.js.map +0 -1
- package/dist/samples-B3My5oh2.d.ts +0 -59
- package/dist/snapshot/index.js +0 -5
- package/dist/snapshot/index.js.map +0 -1
- package/dist/subs/index.d.ts +0 -472
- package/dist/subs/index.js +0 -7
- package/dist/subs/index.js.map +0 -1
- package/dist/throttle/index.d.ts +0 -134
- package/dist/throttle/index.js +0 -3
- package/dist/throttle/index.js.map +0 -1
- package/dist/throttled-input/index.js.map +0 -1
- package/dist/token-refresh/index.d.ts +0 -216
- package/dist/token-refresh/index.js +0 -6
- package/dist/token-refresh/index.js.map +0 -1
- package/dist/trace-replay/index.js +0 -6
- package/dist/trace-replay/index.js.map +0 -1
- package/dist/with-deadline/index.d.ts +0 -197
- package/dist/with-deadline/index.js +0 -111
- package/dist/with-deadline/index.js.map +0 -1
- package/dist/with-resilience/index.d.ts +0 -225
- package/dist/with-resilience/index.js +0 -240
- package/dist/with-resilience/index.js.map +0 -1
- package/dist/with-telemetry/index.d.ts +0 -150
- package/dist/with-telemetry/index.js +0 -70
- package/dist/with-telemetry/index.js.map +0 -1
- package/dist/work-queue/adapter.d.ts +0 -84
- package/dist/work-queue/adapter.js +0 -4
- package/dist/work-queue/adapter.js.map +0 -1
- package/dist/work-queue/ops.d.ts +0 -71
- package/dist/work-queue/ops.js +0 -3
- package/dist/work-queue/ops.js.map +0 -1
- package/dist/workflow/index.d.ts +0 -485
- package/dist/workflow/index.js +0 -244
- package/dist/workflow/index.js.map +0 -1
- /package/dist/{cache → paginate}/index.js.map +0 -0
- /package/dist/{chart/inspect → persistence}/index.js.map +0 -0
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { IdempotencyStore } from './index.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @demlik/tea/idempotency/adapter — the verb seam over the pure idempotency ops.
|
|
5
|
-
*
|
|
6
|
-
* The functions in `./index` (`seen` / `recall` / `remember` / `evictExpired`
|
|
7
|
-
* / `initStore`) are the BLESSED transitions, but their names and the
|
|
8
|
-
* `IdempotencyStore<V>` shape they read/return are the STORE's vocabulary. A
|
|
9
|
-
* consumer that owns an `IdempotencyStore<V>` slice (`idempotent-intake`,
|
|
10
|
-
* `poller`) used to import those functions by name and call them directly, so
|
|
11
|
-
* a change to the op surface — or to `IdempotencyStore`'s fields — cascaded to
|
|
12
|
-
* every call site.
|
|
13
|
-
*
|
|
14
|
-
* `IdempotencyMemory<V>` is the insulating interface: five VERBS (`isSeen` /
|
|
15
|
-
* `recall` / `remember` / `evict` / `init`) consumers depend on instead of the
|
|
16
|
-
* raw functions. The verbs keep the ops' pure contract — no I/O, no `Date.now`
|
|
17
|
-
* (the clock is injected as `now`) — so a consumer folding the adapter through
|
|
18
|
-
* its reducer stays inside invariant 2 (pure transitions). `isSeen` renames the
|
|
19
|
-
* blessed `seen` predicate (a noun-y `seen` reads ambiguously as a slice field;
|
|
20
|
-
* the verb form states the question it answers), and `evict` is the verb form
|
|
21
|
-
* of `evictExpired`.
|
|
22
|
-
*
|
|
23
|
-
* `idempotencyMemory<V>()` is the canonical implementation, a thin binding of
|
|
24
|
-
* the blessed ops. Because the verbs are the only surface consumers touch, an
|
|
25
|
-
* `IdempotencyStore` shape change is absorbed HERE rather than at the consumer
|
|
26
|
-
* call sites.
|
|
27
|
-
*
|
|
28
|
-
* INTERNAL seam (no public-API port): consumers import the adapter from this
|
|
29
|
-
* subpath the same way they imported the ops. The ops remain exported from
|
|
30
|
-
* `./index` for any call site that genuinely wants a function directly.
|
|
31
|
-
*/
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* The verb interface over an `IdempotencyStore<V>`. Each verb mirrors a blessed
|
|
35
|
-
* op's pure contract but speaks the consumer's dedupe vocabulary, so the
|
|
36
|
-
* consumer never names a store function or reaches into an `IdempotencyStore`
|
|
37
|
-
* field it did not put there.
|
|
38
|
-
*/
|
|
39
|
-
interface IdempotencyMemory<V> {
|
|
40
|
-
/** Create an empty store, optionally bounded by `capacity` and/or `ttlMs`. */
|
|
41
|
-
init(opts?: {
|
|
42
|
-
capacity?: number;
|
|
43
|
-
ttlMs?: number;
|
|
44
|
-
}): IdempotencyStore<V>;
|
|
45
|
-
/** True iff `key` is present AND not expired at `now`. Read-only. */
|
|
46
|
-
isSeen(store: IdempotencyStore<V>, key: string, now: number): boolean;
|
|
47
|
-
/** The cached value for `key` if present and unexpired at `now`. Read-only. */
|
|
48
|
-
recall(store: IdempotencyStore<V>, key: string, now: number): V | undefined;
|
|
49
|
-
/** Record `key → value` at `now`, enforcing the store's bounds. Returns a new store. */
|
|
50
|
-
remember(store: IdempotencyStore<V>, key: string, value: V, now: number): IdempotencyStore<V>;
|
|
51
|
-
/** Drop every entry expired at `now`. Returns a new store. */
|
|
52
|
-
evict(store: IdempotencyStore<V>, now: number): IdempotencyStore<V>;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* The canonical `IdempotencyMemory<V>`, binding each verb to its blessed op.
|
|
56
|
-
* Pure and stateless — call once at module scope in a consumer and fold its
|
|
57
|
-
* verbs through the reducer. An `IdempotencyStore` shape change is absorbed by
|
|
58
|
-
* re-binding a verb here, not at the consumers.
|
|
59
|
-
*/
|
|
60
|
-
declare function idempotencyMemory<V>(): IdempotencyMemory<V>;
|
|
61
|
-
|
|
62
|
-
export { type IdempotencyMemory, idempotencyMemory };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"adapter.js"}
|
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
import { IdempotencyStore } from '../idempotency/index.js';
|
|
2
|
-
import { C as Cmd } from '../core-Co0LWkIA.js';
|
|
3
|
-
import { QueueItem } from '../work-queue/index.js';
|
|
4
|
-
import 'zod';
|
|
5
|
-
import '../runtime-types-CNLmhWif.js';
|
|
6
|
-
import 'better-result';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* @demlik/tea/idempotent-intake — receive-once intake for webhooks / queue
|
|
10
|
-
* messages: dedupe by key, enqueue the new ones, replay the cached result to
|
|
11
|
-
* the duplicates. The "process this payload exactly once even though it
|
|
12
|
-
* arrives N times" knob.
|
|
13
|
-
*
|
|
14
|
-
* **The recipe.** This is a Level-2 composition — it owns no primitive
|
|
15
|
-
* queue/cache logic of its own, it *splices two L1 bricks into one Model slice*
|
|
16
|
-
* and DELEGATES every transition to their VERB SEAMS — `IdempotencyMemory`
|
|
17
|
-
* (`../idempotency/adapter`) and `QueueAdapter` (`../work-queue/adapter`) —
|
|
18
|
-
* so the store ops and the `QueueItem` / `IdempotencyStore` shapes stay
|
|
19
|
-
* insulated behind verbs the intake calls:
|
|
20
|
-
*
|
|
21
|
-
* - `../idempotency/adapter` — the dedupe-by-key + last-result cache. The
|
|
22
|
-
* `seen` half of the slice is its `IdempotencyStore`, keyed by
|
|
23
|
-
* `keyOf(payload)`. A key is recorded once `receive` calls `memory.remember`;
|
|
24
|
-
* `complete` calls `memory.remember` again to swap its cached value from
|
|
25
|
-
* `pending` to the finished `result`. The cache write is the brick's, never
|
|
26
|
-
* re-rolled here.
|
|
27
|
-
* - `../work-queue/adapter` — the pending-work list. The `queue` half of the
|
|
28
|
-
* slice is its `QueueItem<P>[]`. Every status flip routes through the
|
|
29
|
-
* adapter verbs: `receive` enqueues via `queue.enqueue`, `claimNext` stamps
|
|
30
|
-
* the `running` claim via `queue.patch`, `boot` re-arms a dead worker's
|
|
31
|
-
* claim via `queue.patch`. Intake owns only the SELECTION (which item,
|
|
32
|
-
* gated on the done-cache reconcile below) — the array transition is the
|
|
33
|
-
* brick's. The consumer drains it (claim → process → `complete`) at its own
|
|
34
|
-
* pace.
|
|
35
|
-
*
|
|
36
|
-
* Both bricks are pure-state + pure-ops, host- and clock-agnostic by
|
|
37
|
-
* construction, so the combined slice inherits TEA's two non-negotiables:
|
|
38
|
-
*
|
|
39
|
-
* - **Durable** — the slice is a plain serializable value (a record-backed
|
|
40
|
-
* idempotency store + an array of queue items, no `Map`, no closures), so
|
|
41
|
-
* it survives a Durable-Object eviction / reload and rehydrates whole.
|
|
42
|
-
* - **Replayable** — every verb is a pure `(state, …) => [state, Cmd[]]`
|
|
43
|
-
* transition; no `Date.now()`, no `Math.random()`, no I/O inside a verb.
|
|
44
|
-
* `at` (the clock) and `id` (the queue-item id) are *injected* at the call
|
|
45
|
-
* site, so `trace-replay` reconstructs each transition exactly.
|
|
46
|
-
*
|
|
47
|
-
* **The decision lives in a Cmd, not in a return shape.** `receive` cannot
|
|
48
|
-
* "return" what it decided (the knob contract pins the shape to
|
|
49
|
-
* `[State, Cmd[]]`), so the decision is *reified as a Cmd* the runtime
|
|
50
|
-
* performs:
|
|
51
|
-
*
|
|
52
|
-
* - first sighting of a key → mark it `pending`, enqueue the payload, emit
|
|
53
|
-
* `IntakeProcess` (go run the work).
|
|
54
|
-
* - a key already `pending` → drop silently (the original is in flight);
|
|
55
|
-
* emit nothing.
|
|
56
|
-
* - a key already `done` → emit `IntakeReplay` carrying the cached
|
|
57
|
-
* result so the duplicate caller gets the SAME response the first one
|
|
58
|
-
* produced, with zero re-execution of the side effect.
|
|
59
|
-
*
|
|
60
|
-
* **Two crash-safety guarantees the verbs enforce (and the unit specs alone
|
|
61
|
-
* missed — see the wired-machine test):**
|
|
62
|
-
*
|
|
63
|
-
* - *A slow worker is never double-enqueued.* The TTL clock starts at
|
|
64
|
-
* `complete`, not at `receive`: a `pending` entry NEVER ages out, so a
|
|
65
|
-
* duplicate of an in-flight key is always dropped no matter how long the
|
|
66
|
-
* worker takes. Only a `done` entry expires (see `liveEntry`).
|
|
67
|
-
* - *A complete-then-crash never re-runs.* `boot` and `claimNext` reconcile
|
|
68
|
-
* the queue against the done cache: a queue item whose key already resolved
|
|
69
|
-
* to `done` in `seen` is skipped (never reset to pending, never claimed),
|
|
70
|
-
* so a worker that finished and cached its result before the DO evicted is
|
|
71
|
-
* not re-executed on resume.
|
|
72
|
-
*
|
|
73
|
-
* Typical wiring (the combinator form — splice ~3 hooks into a host machine):
|
|
74
|
-
*
|
|
75
|
-
* const intake = createIntake<StripeEvent, ChargeResult>({
|
|
76
|
-
* keyOf: (e) => e.id, // Stripe's idempotency key
|
|
77
|
-
* ttlMs: 24 * 60 * 60 * 1000, // a replayed webhook 24h after it COMPLETED is re-run
|
|
78
|
-
* });
|
|
79
|
-
*
|
|
80
|
-
* // in `init`:
|
|
81
|
-
* intake: intake.init(),
|
|
82
|
-
* // in `update`, on the inbound-webhook Msg:
|
|
83
|
-
* const [next, cmds] = intake.receive(state.intake, payload, at, id);
|
|
84
|
-
* // …route `IntakeProcess` to your worker, `IntakeReplay` to the responder.
|
|
85
|
-
* // on the worker's done Msg:
|
|
86
|
-
* const [next, _] = intake.complete(state.intake, key, result, at);
|
|
87
|
-
* // once, after boot (DO reload), before resuming the drain:
|
|
88
|
-
* const [next, _] = intake.boot(state.intake);
|
|
89
|
-
*
|
|
90
|
-
* Escape hatch: reach the raw L1 ops via `@demlik/tea/idempotency` and
|
|
91
|
-
* `@demlik/tea/work-queue` and thread them by hand.
|
|
92
|
-
*/
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* A cached intake entry: either a key whose work is still in flight
|
|
96
|
-
* (`pending`) or one whose work has finished and whose `result` is held for
|
|
97
|
-
* replay to later duplicates (`done`). Discriminated on `phase` — `pending`
|
|
98
|
-
* carries no payload, `done` carries the result `R`.
|
|
99
|
-
*
|
|
100
|
-
* Lives inside the `seen` half of the slice (`IdempotencyStore<IntakeEntry<R>>`).
|
|
101
|
-
* It is the dedupe ledger's *value*; the ledger's *key* is `keyOf(payload)`.
|
|
102
|
-
*/
|
|
103
|
-
type IntakeEntry<R> = {
|
|
104
|
-
readonly phase: "pending";
|
|
105
|
-
} | {
|
|
106
|
-
readonly phase: "done";
|
|
107
|
-
readonly result: R;
|
|
108
|
-
};
|
|
109
|
-
/**
|
|
110
|
-
* The intake knob's config — `keyOf` derives the idempotency key from a
|
|
111
|
-
* payload, `ttlMs` (optional) ages a *completed* cached key out so a webhook
|
|
112
|
-
* replayed long after the work finished is treated as new and re-processed.
|
|
113
|
-
*
|
|
114
|
-
* **The TTL clock starts at `complete`, not at `receive`.** A `pending` entry
|
|
115
|
-
* (work still in flight) NEVER ages out, no matter how slow the worker is —
|
|
116
|
-
* ageing a pending key would let the duplicate re-enqueue the in-flight
|
|
117
|
-
* payload and double-process it. Only a `done` entry expires, measured from
|
|
118
|
-
* the `at` passed to `complete` (the moment the result was cached). Inside the
|
|
119
|
-
* window a duplicate replays the cached result; at/after the window it is
|
|
120
|
-
* re-accepted and re-processed.
|
|
121
|
-
*
|
|
122
|
-
* Omit `ttlMs` for a cache whose `done` entries never expire by age (keys live
|
|
123
|
-
* forever — fine for a bounded universe of ids, unbounded growth otherwise).
|
|
124
|
-
*
|
|
125
|
-
* The TTL is owned HERE, not delegated to the composed `IdempotencyStore`: the
|
|
126
|
-
* store's uniform per-entry TTL cannot tell `pending` from `done`, so intake
|
|
127
|
-
* keeps the store TTL-free and applies the phase-aware rule itself (see
|
|
128
|
-
* `liveEntry`).
|
|
129
|
-
*/
|
|
130
|
-
interface IntakeConfig<P> {
|
|
131
|
-
/** Derive the idempotency key from a payload. Must be pure + deterministic. */
|
|
132
|
-
readonly keyOf: (payload: P) => string;
|
|
133
|
-
/**
|
|
134
|
-
* Age a *completed* key out after this many ms, measured from the `at`
|
|
135
|
-
* passed to `complete`. Pending keys never age out.
|
|
136
|
-
*/
|
|
137
|
-
readonly ttlMs?: number;
|
|
138
|
-
}
|
|
139
|
-
/**
|
|
140
|
-
* The Model slice this knob owns. `seen` is the dedupe + last-result cache
|
|
141
|
-
* (the `../idempotency` brick); `queue` is the pending-work list (the
|
|
142
|
-
* `../work-queue` brick). Both are plain serializable values — the whole slice
|
|
143
|
-
* round-trips through `JSON` so it survives eviction and replays exactly.
|
|
144
|
-
*/
|
|
145
|
-
interface IntakeState<P, R> {
|
|
146
|
-
readonly seen: IdempotencyStore<IntakeEntry<R>>;
|
|
147
|
-
readonly queue: readonly QueueItem<P>[];
|
|
148
|
-
}
|
|
149
|
-
/** A genuinely-new payload was accepted and enqueued — go run the work. */
|
|
150
|
-
interface IntakeProcessCmd<P> extends Cmd<"intake:process"> {
|
|
151
|
-
/** The dedupe key the payload was filed under. */
|
|
152
|
-
readonly key: string;
|
|
153
|
-
/** The enqueued queue-item id (the same `id` passed to `receive`). */
|
|
154
|
-
readonly itemId: string;
|
|
155
|
-
/** The original payload, for the worker to process. */
|
|
156
|
-
readonly payload: P;
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* A duplicate of an already-completed key arrived — replay the cached result
|
|
160
|
-
* to the caller instead of re-running the side effect.
|
|
161
|
-
*/
|
|
162
|
-
interface IntakeReplayCmd<R> extends Cmd<"intake:replay"> {
|
|
163
|
-
/** The dedupe key whose cached result is being replayed. */
|
|
164
|
-
readonly key: string;
|
|
165
|
-
/** The result the ORIGINAL request produced, recalled from the cache. */
|
|
166
|
-
readonly result: R;
|
|
167
|
-
}
|
|
168
|
-
/** The Cmd union the intake verbs emit. */
|
|
169
|
-
type IntakeCmd<P, R> = IntakeProcessCmd<P> | IntakeReplayCmd<R>;
|
|
170
|
-
/**
|
|
171
|
-
* Build an idempotent-intake knob from `config`. Returns the uniform L2
|
|
172
|
-
* contract — `init()` + the verbs (`receive`, `complete`, `boot`, `claimNext`).
|
|
173
|
-
* No `subs` / `handlers`: intake owns no timers and does no I/O of its own (the
|
|
174
|
-
* composed bricks are pure-ops; the worker that runs `IntakeProcess` and the
|
|
175
|
-
* responder that runs `IntakeReplay` live in the host's interpret map).
|
|
176
|
-
*/
|
|
177
|
-
declare function createIntake<P, R>(config: IntakeConfig<P>): {
|
|
178
|
-
init: () => IntakeState<P, R>;
|
|
179
|
-
receive: (state: IntakeState<P, R>, payload: P, at: number, id: string) => readonly [IntakeState<P, R>, readonly IntakeCmd<P, R>[]];
|
|
180
|
-
complete: (state: IntakeState<P, R>, key: string, result: R, at: number) => readonly [IntakeState<P, R>, readonly IntakeCmd<P, R>[]];
|
|
181
|
-
boot: (state: IntakeState<P, R>) => readonly [IntakeState<P, R>, readonly IntakeCmd<P, R>[]];
|
|
182
|
-
claimNext: (state: IntakeState<P, R>, at: number) => {
|
|
183
|
-
readonly state: IntakeState<P, R>;
|
|
184
|
-
readonly claimed: QueueItem<P>;
|
|
185
|
-
} | null;
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
export { type IntakeCmd, type IntakeConfig, type IntakeEntry, type IntakeProcessCmd, type IntakeReplayCmd, type IntakeState, createIntake };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|
package/dist/journal/index.d.ts
DELETED
|
@@ -1,373 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* journal sync — a remote journal and per-remote cursors, so two local journals
|
|
3
|
-
* meet in one order.
|
|
4
|
-
*
|
|
5
|
-
* `Journal<R>` (`./index`) is the LOCAL append-only log a single machine replays
|
|
6
|
-
* from. This is the second half: a **remote** journal that many local journals
|
|
7
|
-
* push their appends into and pull everyone else's out of, with the remote
|
|
8
|
-
* assigning the one `seq` that counts. Records are append-only, so there is
|
|
9
|
-
* nothing to merge — the fold over the remote's order *is* the merge. This is
|
|
10
|
-
* the network-in-the-middle twin of the append-then-fold shape already proven
|
|
11
|
-
* in-repo by `src/do/event-sourced-store.ts` (append each record to a
|
|
12
|
-
* monotonically-keyed log; rebuild state by folding the log via `replay`).
|
|
13
|
-
*
|
|
14
|
-
* The three moving parts:
|
|
15
|
-
* - `RemoteJournal<R>` — the append-only remote. `push` sends the records a
|
|
16
|
-
* client has not yet had acked and gets back the `seq` the remote assigned
|
|
17
|
-
* each; `pull` reads everyone's records after a given `seq`. One monotonic
|
|
18
|
-
* `seq` per stream, assigned by the remote, is the whole ordering contract.
|
|
19
|
-
* - a per-`(client, stream)` **cursor** (`CursorStore`) kept locally — the
|
|
20
|
-
* last remote `seq` a client has pulled — so `push`/`pull` resume
|
|
21
|
-
* incrementally instead of re-sending or re-reading the whole stream.
|
|
22
|
-
* - `SyncClient<R>` — a local `Journal<R>` joined to a `RemoteJournal<R>`
|
|
23
|
-
* through that cursor and a stable author identity. A local `append` is
|
|
24
|
-
* PROVISIONAL (it has a local order but no remote `seq`) until `sync` pushes
|
|
25
|
-
* it and pulls it back under the `seq` the remote assigned.
|
|
26
|
-
*
|
|
27
|
-
* Domain-blind and auth-blind: the remote takes an opaque `token` and an opaque
|
|
28
|
-
* `stream` key and does nothing with the token — who-may-push-to-which-stream is
|
|
29
|
-
* the host's concern, not this primitive's (the same way the local `Journal` is
|
|
30
|
-
* blind to what a record means). Interface shape follows Effect
|
|
31
|
-
* `unstable/eventlog` `EventJournal` (`writeFromRemote`, per-remote cursors, a
|
|
32
|
-
* `changes` stream) as prior art, not a dependency.
|
|
33
|
-
*/
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* A remote-assigned order key. Like a local `Seq` it starts at 1 and increments
|
|
37
|
-
* by one per record within a stream, but it is assigned by the REMOTE — it is
|
|
38
|
-
* the authoritative order every client folds over, not any one client's local
|
|
39
|
-
* append order.
|
|
40
|
-
*/
|
|
41
|
-
type RemoteSeq = number;
|
|
42
|
-
/**
|
|
43
|
-
* A record paired with the stable identity of whoever authored it. Author
|
|
44
|
-
* identity is the one fact a team-mode record needs that a solo record does not:
|
|
45
|
-
* once records from many clients interleave in the remote's order, the fold
|
|
46
|
-
* still has to know who wrote each. It is opaque — a string the host assigns
|
|
47
|
-
* meaning to (a device id, a user handle) — never interpreted here.
|
|
48
|
-
*/
|
|
49
|
-
interface AuthoredRecord<R> {
|
|
50
|
-
/** The stable identity of the client that authored `record`. */
|
|
51
|
-
readonly author: string;
|
|
52
|
-
/** The domain record itself; this primitive knows nothing of its shape. */
|
|
53
|
-
readonly record: R;
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* One record as it lives on the remote: the `seq` the remote assigned, the
|
|
57
|
-
* `author` that wrote it, the `stream` it belongs to, and the record. This is
|
|
58
|
-
* the entry every client pulls and folds; two clients that pull the same stream
|
|
59
|
-
* see identical `RemoteEntry`s in identical `seq` order, which is what lets
|
|
60
|
-
* their folds agree.
|
|
61
|
-
*/
|
|
62
|
-
interface RemoteEntry<R> {
|
|
63
|
-
/** The stream this entry belongs to. */
|
|
64
|
-
readonly stream: string;
|
|
65
|
-
/** The remote-assigned order key — 1-based, gap-free, monotonic per stream. */
|
|
66
|
-
readonly seq: RemoteSeq;
|
|
67
|
-
/** The stable identity of the client that authored the record. */
|
|
68
|
-
readonly author: string;
|
|
69
|
-
/** The domain record. */
|
|
70
|
-
readonly record: R;
|
|
71
|
-
}
|
|
72
|
-
/** A `push` — the records a client wants acked, presented under its token. */
|
|
73
|
-
interface PushRequest<R> {
|
|
74
|
-
/**
|
|
75
|
-
* An opaque credential the host's remote may check. This primitive does
|
|
76
|
-
* nothing with it: authorization (who may push to which stream) is the host's
|
|
77
|
-
* concern, deliberately out of scope here.
|
|
78
|
-
*/
|
|
79
|
-
readonly token: unknown;
|
|
80
|
-
/** The opaque stream key to append to. */
|
|
81
|
-
readonly stream: string;
|
|
82
|
-
/**
|
|
83
|
-
* The records to append, in the client's local order. Normally these are the
|
|
84
|
-
* client's own appends made since its last successful push — the incremental
|
|
85
|
-
* tail, not the whole stream.
|
|
86
|
-
*/
|
|
87
|
-
readonly records: ReadonlyArray<AuthoredRecord<R>>;
|
|
88
|
-
}
|
|
89
|
-
/** The remote's answer to a `push`: the `seq` it assigned each record, in order. */
|
|
90
|
-
interface PushResult {
|
|
91
|
-
/**
|
|
92
|
-
* The remote `seq` assigned to each record of the request, in the same order.
|
|
93
|
-
* `seqs[i]` is the seq of `records[i]`. A client does not need to fold these —
|
|
94
|
-
* it learns the full ordered stream (its own records included) through `pull`,
|
|
95
|
-
* which is the single reader of converged state.
|
|
96
|
-
*/
|
|
97
|
-
readonly seqs: ReadonlyArray<RemoteSeq>;
|
|
98
|
-
}
|
|
99
|
-
/** A `pull` — read everyone's records after a `seq` the client already has. */
|
|
100
|
-
interface PullRequest {
|
|
101
|
-
/** The opaque credential; ignored here, see {@link PushRequest.token}. */
|
|
102
|
-
readonly token: unknown;
|
|
103
|
-
/** The opaque stream key to read. */
|
|
104
|
-
readonly stream: string;
|
|
105
|
-
/**
|
|
106
|
-
* Return only entries with `seq` strictly greater than this. A client passes
|
|
107
|
-
* its cursor (the last `seq` it pulled), so it reads only what is new — never
|
|
108
|
-
* re-reading the whole stream. `0` (the cursor's initial value) reads from the
|
|
109
|
-
* start.
|
|
110
|
-
*/
|
|
111
|
-
readonly since: RemoteSeq;
|
|
112
|
-
}
|
|
113
|
-
/** The remote's answer to a `pull`: the new entries, in `seq` order. */
|
|
114
|
-
interface PullResult<R> {
|
|
115
|
-
/** Every entry with `seq > since`, in ascending `seq` order. */
|
|
116
|
-
readonly entries: ReadonlyArray<RemoteEntry<R>>;
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* An append-only remote journal: many clients push into it, all pull from it,
|
|
120
|
-
* and it assigns the one monotonic `seq` per stream that every client's fold
|
|
121
|
-
* agrees over. It is the network-in-the-middle: a real one is a server; this
|
|
122
|
-
* interface is what a client talks to, host- and transport-blind.
|
|
123
|
-
*
|
|
124
|
-
* The remote never merges and never resolves conflicts — records are
|
|
125
|
-
* append-only, so its only job is to assign an honest total order. That order
|
|
126
|
-
* is enough: two clients that both push and both pull fold the same sequence and
|
|
127
|
-
* reach the same state (the append-then-fold result proven in phoenix spike
|
|
128
|
-
* #6673, reused here rather than reinvented).
|
|
129
|
-
*/
|
|
130
|
-
interface RemoteJournal<R> {
|
|
131
|
-
/**
|
|
132
|
-
* Append `records` to `stream` durably and return the `seq` assigned to each,
|
|
133
|
-
* in order. Concurrent pushes to one stream are serialised into a single total
|
|
134
|
-
* order — the seq assignment is the remote's whole ordering guarantee.
|
|
135
|
-
*/
|
|
136
|
-
push(request: PushRequest<R>): Promise<PushResult>;
|
|
137
|
-
/**
|
|
138
|
-
* Read every entry of `stream` with `seq` strictly greater than
|
|
139
|
-
* `request.since`, in ascending `seq` order. Empty when the client is already
|
|
140
|
-
* caught up.
|
|
141
|
-
*/
|
|
142
|
-
pull(request: PullRequest): Promise<PullResult<R>>;
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* An in-memory `RemoteJournal<R>` — the standard test/reference substrate,
|
|
146
|
-
* mirroring `memoryStore` (`@demlik/tea/mem`) and `memoryJournal` (`./index`).
|
|
147
|
-
*
|
|
148
|
-
* It is built ON `memoryJournal`: the remote's authoritative `seq` assignment IS
|
|
149
|
-
* a local `Journal`'s per-stream total order. `push` appends each record under
|
|
150
|
-
* the stream's lock (so concurrent pushes serialise into one order and never
|
|
151
|
-
* race the seq), and `pull` is `list` filtered past the client's cursor. The
|
|
152
|
-
* seq machinery is `makeJournal`'s, reused — this substrate reinvents none of
|
|
153
|
-
* it, exactly as the issue's seam was designed to be consumed.
|
|
154
|
-
*
|
|
155
|
-
* The `token` is accepted and ignored: this substrate enforces no authorization,
|
|
156
|
-
* because who-may-push-to-which-stream is the host's concern, out of scope here.
|
|
157
|
-
*/
|
|
158
|
-
declare function memoryRemoteJournal<R>(): RemoteJournal<R>;
|
|
159
|
-
/**
|
|
160
|
-
* Where a client keeps its per-`(client, stream)` cursor — the last remote `seq`
|
|
161
|
-
* it has pulled. Kept LOCALLY (the client's own disk/memory), never on the
|
|
162
|
-
* remote, so `push`/`pull` resume incrementally after a restart instead of
|
|
163
|
-
* re-reading the whole stream. `get` returns `0` for a stream never pulled.
|
|
164
|
-
*/
|
|
165
|
-
interface CursorStore {
|
|
166
|
-
/** The last remote `seq` pulled for `stream`, or `0` if none yet. */
|
|
167
|
-
get(stream: string): Promise<RemoteSeq>;
|
|
168
|
-
/** Record `seq` as the last remote `seq` pulled for `stream`. */
|
|
169
|
-
set(stream: string, seq: RemoteSeq): Promise<void>;
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* An in-memory `CursorStore`, mirroring `memoryStore`. A durable client swaps in
|
|
173
|
-
* a file- or DB-backed one so its cursor survives a restart; the semantics are
|
|
174
|
-
* identical.
|
|
175
|
-
*/
|
|
176
|
-
declare function memoryCursorStore(): CursorStore;
|
|
177
|
-
/** How to build a {@link SyncClient}. */
|
|
178
|
-
interface SyncClientOptions<R> {
|
|
179
|
-
/** The remote every push/pull talks to. */
|
|
180
|
-
readonly remote: RemoteJournal<R>;
|
|
181
|
-
/**
|
|
182
|
-
* This client's stable author identity, stamped on every record it appends —
|
|
183
|
-
* the one fact team mode needs that solo mode does not.
|
|
184
|
-
*/
|
|
185
|
-
readonly author: string;
|
|
186
|
-
/**
|
|
187
|
-
* The opaque credential presented on every push/pull. Optional because this
|
|
188
|
-
* primitive never checks it; a host that runs an authorizing remote supplies
|
|
189
|
-
* it here.
|
|
190
|
-
*/
|
|
191
|
-
readonly token?: unknown;
|
|
192
|
-
/**
|
|
193
|
-
* The client's LOCAL append-only journal — its own provisional appends live
|
|
194
|
-
* here. Defaults to a `memoryJournal`; a durable client passes a `fileJournal`
|
|
195
|
-
* (or any `Journal<R>`), which is the #30 substrate seam this consumes.
|
|
196
|
-
*/
|
|
197
|
-
readonly local?: LocalJournal<R>;
|
|
198
|
-
/**
|
|
199
|
-
* Where the per-stream pull cursor lives. Defaults to a `memoryCursorStore`; a
|
|
200
|
-
* durable client passes one backed by its own storage.
|
|
201
|
-
*/
|
|
202
|
-
readonly cursors?: CursorStore;
|
|
203
|
-
}
|
|
204
|
-
/**
|
|
205
|
-
* The slice of a local `Journal<R>` a `SyncClient` drives — its own provisional
|
|
206
|
-
* appends and reading them back in local order. This is structurally the #30
|
|
207
|
-
* `Journal<R>` interface narrowed to what sync needs, so a `memoryJournal` or a
|
|
208
|
-
* `fileJournal` satisfies it as-is.
|
|
209
|
-
*/
|
|
210
|
-
interface LocalJournal<R> {
|
|
211
|
-
append(stream: string, record: R): Promise<{
|
|
212
|
-
seq: number;
|
|
213
|
-
}>;
|
|
214
|
-
list(stream: string): Promise<ReadonlyArray<JournalEntry<R>>>;
|
|
215
|
-
}
|
|
216
|
-
/**
|
|
217
|
-
* A local `Journal` joined to a `RemoteJournal` through a cursor and an author
|
|
218
|
-
* identity. It is what makes two local journals "meet in one order": each
|
|
219
|
-
* appends offline, both `sync`, and both converge on the remote's order.
|
|
220
|
-
*/
|
|
221
|
-
interface SyncClient<R> {
|
|
222
|
-
/**
|
|
223
|
-
* Append `record` to the client's LOCAL journal. The append is PROVISIONAL: it
|
|
224
|
-
* has a local order immediately, but no remote `seq` — and so no place in the
|
|
225
|
-
* converged order — until a later `sync` pushes it and pulls it back. Resolves
|
|
226
|
-
* once the local append is durable.
|
|
227
|
-
*/
|
|
228
|
-
append(stream: string, record: R): Promise<void>;
|
|
229
|
-
/**
|
|
230
|
-
* The client's local appends for `stream` that have not yet been pushed — the
|
|
231
|
-
* provisional tail. Empty right after a successful `sync`.
|
|
232
|
-
*/
|
|
233
|
-
pending(stream: string): Promise<ReadonlyArray<AuthoredRecord<R>>>;
|
|
234
|
-
/**
|
|
235
|
-
* Reconcile `stream` with the remote: PUSH every local append not yet pushed,
|
|
236
|
-
* then PULL every remote entry after the cursor and fold it into the converged
|
|
237
|
-
* log, advancing the cursor. One `sync` may not see records a peer pushes
|
|
238
|
-
* concurrently (they may land after this pull); a second `sync` — with nothing
|
|
239
|
-
* new to push — pulls them, which is how two racing clients converge.
|
|
240
|
-
*/
|
|
241
|
-
sync(stream: string): Promise<void>;
|
|
242
|
-
/**
|
|
243
|
-
* The converged log for `stream`: every entry the client has pulled, in remote
|
|
244
|
-
* `seq` order. This is the fold's input — reducing over it yields the client's
|
|
245
|
-
* state. After both of two racing clients sync to quiescence, their `log`s are
|
|
246
|
-
* identical, which is the convergence guarantee.
|
|
247
|
-
*/
|
|
248
|
-
log(stream: string): ReadonlyArray<RemoteEntry<R>>;
|
|
249
|
-
}
|
|
250
|
-
/**
|
|
251
|
-
* Build a {@link SyncClient} over a remote, an author identity, and (optionally)
|
|
252
|
-
* a local journal and cursor store.
|
|
253
|
-
*
|
|
254
|
-
* The client holds two watermarks per stream: how many of its own local appends
|
|
255
|
-
* it has PUSHED (so a re-`sync` sends only the new tail), and — in the
|
|
256
|
-
* `CursorStore` — the last remote `seq` it has PULLED (so it reads only what is
|
|
257
|
-
* new). Its converged `log` is built solely from `pull`, so `pull` is the single
|
|
258
|
-
* source of converged truth; a client learns even its OWN records' remote order
|
|
259
|
-
* by pulling them back.
|
|
260
|
-
*/
|
|
261
|
-
declare function makeSyncClient<R>(options: SyncClientOptions<R>): SyncClient<R>;
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* @packageDocumentation
|
|
265
|
-
* @demlik/tea/journal — an append-only, ordered record log for `@demlik/tea`.
|
|
266
|
-
*
|
|
267
|
-
* The log a "durable, replayable state machine" replays from. tea already ships
|
|
268
|
-
* the log's neighbours — `fileStore`/`memoryStore` (`Store<S>`: snapshot with
|
|
269
|
-
* whole-load / whole-save), `recorder` (JSONL debug traces), `durable-effects`
|
|
270
|
-
* (`foldLedger` over an owed-effect ledger) — but not the log itself, so every
|
|
271
|
-
* consumer hand-rolled it. This is that log, domain-blind: a `Journal<R>` over
|
|
272
|
-
* an opaque record `R`, with no pipeline/ledger vocabulary of its own.
|
|
273
|
-
*
|
|
274
|
-
* Three operations carry the contract:
|
|
275
|
-
* - `append(stream, record)` — durable before it returns, assigning a
|
|
276
|
-
* per-stream total-order `seq` (1, 2, 3, …). Concurrent appenders to one
|
|
277
|
-
* stream converge on one order; the lock's only job is an honest order key.
|
|
278
|
-
* - `list(stream)` — every entry of a stream in `seq` order.
|
|
279
|
-
* - `changes(listener)` — a subscription over appends made through this
|
|
280
|
-
* instance after subscribing.
|
|
281
|
-
*
|
|
282
|
-
* `withLock(stream, fx)` runs `fx` with exclusive access to a stream, so a
|
|
283
|
-
* read-decide-append sequence is atomic against other writers. It is
|
|
284
|
-
* re-entrant for the same stream: an `append` inside `fx` does not deadlock on
|
|
285
|
-
* the lock `fx` already holds.
|
|
286
|
-
*
|
|
287
|
-
* The substrate is a `JournalBackend<R>` — how a stream is read, how one record
|
|
288
|
-
* is appended durably, and how a stream is locked across processes.
|
|
289
|
-
* `makeJournal` wires the domain-blind orchestration (per-stream serialisation,
|
|
290
|
-
* `seq` assignment, `changes` fan-out) over any backend. `memoryJournal` is the
|
|
291
|
-
* in-process backend that mirrors `memoryStore` for tests; the Node file
|
|
292
|
-
* backend (`fileJournal`) homes in `@demlik/tea/node` beside `fileStore`.
|
|
293
|
-
*
|
|
294
|
-
* Interface shape follows Effect `unstable/eventlog` `EventJournal`
|
|
295
|
-
* (`entries`/`write`/`changes`/`withLock`) as prior art, not a dependency.
|
|
296
|
-
*/
|
|
297
|
-
/** A per-stream total-order key. Starts at 1 and increments by one per append. */
|
|
298
|
-
type Seq = number;
|
|
299
|
-
/** One appended record, tagged with its stream and its per-stream `seq`. */
|
|
300
|
-
interface JournalEntry<R> {
|
|
301
|
-
readonly stream: string;
|
|
302
|
-
readonly seq: Seq;
|
|
303
|
-
readonly record: R;
|
|
304
|
-
}
|
|
305
|
-
/**
|
|
306
|
-
* An append-only, ordered record log over an opaque record `R`.
|
|
307
|
-
*
|
|
308
|
-
* Domain-blind: it knows nothing of what a record means. Ordering, durability
|
|
309
|
-
* and the honest order key are its whole contract.
|
|
310
|
-
*/
|
|
311
|
-
interface Journal<R> {
|
|
312
|
-
/**
|
|
313
|
-
* Append `record` to `stream`, durable before the promise resolves, and
|
|
314
|
-
* resolve with the `seq` it was assigned — the next integer in the stream's
|
|
315
|
-
* total order.
|
|
316
|
-
*/
|
|
317
|
-
append(stream: string, record: R): Promise<{
|
|
318
|
-
seq: Seq;
|
|
319
|
-
}>;
|
|
320
|
-
/** Every entry of `stream`, in `seq` order. Empty for an unwritten stream. */
|
|
321
|
-
list(stream: string): Promise<ReadonlyArray<JournalEntry<R>>>;
|
|
322
|
-
/**
|
|
323
|
-
* Subscribe to appends made through this instance after this call. Returns an
|
|
324
|
-
* unsubscribe. Cross-process appends are not delivered — a cross-process
|
|
325
|
-
* subscription is a polling concern this log leaves to its consumer.
|
|
326
|
-
*/
|
|
327
|
-
changes(listener: (entry: JournalEntry<R>) => void): () => void;
|
|
328
|
-
/**
|
|
329
|
-
* Run `fx` with exclusive access to `stream` — the in-process mutex against
|
|
330
|
-
* other callers here, the backend lock against other processes. Re-entrant
|
|
331
|
-
* for the same stream, so an `append` (or nested `withLock`) inside `fx` runs
|
|
332
|
-
* under the lock this call already holds rather than deadlocking on it.
|
|
333
|
-
*/
|
|
334
|
-
withLock<A>(stream: string, fx: () => Promise<A>): Promise<A>;
|
|
335
|
-
}
|
|
336
|
-
/**
|
|
337
|
-
* The substrate a `Journal<R>` is built over. Everything host-specific lives
|
|
338
|
-
* here; `makeJournal` owns the host-blind rest.
|
|
339
|
-
*
|
|
340
|
-
* `append` is always invoked under `lock` for the same stream, so a backend
|
|
341
|
-
* assigns `seq` from `read().length + 1` without racing itself.
|
|
342
|
-
*/
|
|
343
|
-
interface JournalBackend<R> {
|
|
344
|
-
/** Every entry of `stream` in `seq` order; empty for an unwritten stream. */
|
|
345
|
-
read(stream: string): Promise<ReadonlyArray<JournalEntry<R>>>;
|
|
346
|
-
/**
|
|
347
|
-
* Persist `record` as the next entry of `stream`, durable before resolving,
|
|
348
|
-
* and resolve with the entry it wrote. Invoked only while `lock` holds the
|
|
349
|
-
* stream, so `seq` is safely the current length plus one.
|
|
350
|
-
*/
|
|
351
|
-
append(stream: string, record: R): Promise<JournalEntry<R>>;
|
|
352
|
-
/** Run `fx` while holding `stream`'s cross-process lock. */
|
|
353
|
-
lock<A>(stream: string, fx: () => Promise<A>): Promise<A>;
|
|
354
|
-
}
|
|
355
|
-
/**
|
|
356
|
-
* Build a `Journal<R>` over `backend`. Owns the host-blind half: per-stream
|
|
357
|
-
* serialisation, re-entrant exclusion, and the `changes` fan-out. `append` and
|
|
358
|
-
* `withLock` both route through `exclusive`, which holds the in-process mutex
|
|
359
|
-
* and the backend lock for one stream and is re-entrant for that stream within
|
|
360
|
-
* a single call chain.
|
|
361
|
-
*/
|
|
362
|
-
declare function makeJournal<R>(backend: JournalBackend<R>): Journal<R>;
|
|
363
|
-
/**
|
|
364
|
-
* An in-process `Journal<R>` — the standard test substrate, mirroring
|
|
365
|
-
* `memoryStore` from `@demlik/tea/mem`. Reference semantics: a record handed to
|
|
366
|
-
* `append` is stored by reference, exactly as `memoryStore` stores state. No
|
|
367
|
-
* cross-process lock is needed — a single process owns the whole log — so the
|
|
368
|
-
* backend lock is identity and `makeJournal`'s in-process mutex is the only
|
|
369
|
-
* ordering guarantee.
|
|
370
|
-
*/
|
|
371
|
-
declare function memoryJournal<R>(): Journal<R>;
|
|
372
|
-
|
|
373
|
-
export { type AuthoredRecord, type CursorStore, type Journal, type JournalBackend, type JournalEntry, type LocalJournal, type PullRequest, type PullResult, type PushRequest, type PushResult, type RemoteEntry, type RemoteJournal, type RemoteSeq, type Seq, type SyncClient, type SyncClientOptions, makeJournal, makeSyncClient, memoryCursorStore, memoryJournal, memoryRemoteJournal };
|
package/dist/journal/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|