@demlik/tea 0.13.0 → 0.14.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 +637 -45
- package/dist/agent/index.js +9 -19
- 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-AQ6ZIMEA.js +421 -0
- package/dist/chunk-AQ6ZIMEA.js.map +1 -0
- package/dist/{chunk-MUUROGIH.js → chunk-BLJ2JQSH.js} +62 -12
- package/dist/chunk-BLJ2JQSH.js.map +1 -0
- package/dist/{chunk-RH5EFRVJ.js → chunk-F2US5BW6.js} +25 -5
- package/dist/chunk-F2US5BW6.js.map +1 -0
- package/dist/{batch-window/index.js → chunk-F7FMAWLA.js} +4 -8
- package/dist/chunk-F7FMAWLA.js.map +1 -0
- package/dist/{chunk-O4MVQTEJ.js → chunk-HUKZQX6U.js} +20 -16
- package/dist/chunk-HUKZQX6U.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-DMYGQB4O.js → chunk-HYDWG35Q.js} +23 -6
- package/dist/chunk-HYDWG35Q.js.map +1 -0
- package/dist/{chunk-YUXP55T2.js → chunk-I5MQMJDW.js} +57 -7
- package/dist/chunk-I5MQMJDW.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-ZVJZ72HY.js → chunk-LYLTKJWM.js} +25 -11
- package/dist/chunk-LYLTKJWM.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-RQULHGYH.js +1804 -0
- package/dist/chunk-RQULHGYH.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-Q2UM7BXU.js → chunk-VBDU4JL6.js} +2 -2
- package/dist/chunk-VBDU4JL6.js.map +1 -0
- package/dist/chunk-Z2L3LSNV.js +1470 -0
- package/dist/chunk-Z2L3LSNV.js.map +1 -0
- package/dist/{core-Co0LWkIA.d.ts → core-CTzMJ82M.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 +42 -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-B0-qGQDy.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 +1295 -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/{batch-window/index.d.ts → index-4vZzljCD.d.ts} +7 -12
- package/dist/{fan-out/index.d.ts → index-6A7dB8f6.d.ts} +7 -9
- package/dist/index-B5BZ-_cT.d.ts +616 -0
- package/dist/index-Bc40JWVl.d.ts +131 -0
- package/dist/{debounce/index.d.ts → index-DHSUmQTR.d.ts} +7 -7
- package/dist/index-DJWIER_3.d.ts +69 -0
- package/dist/{snapshot/index.d.ts → index-DMCeMPMJ.d.ts} +15 -78
- package/dist/{monitored-run/index.d.ts → index-NjrT3fL2.d.ts} +37 -13
- package/dist/{recorder/index.d.ts → index-TvRb1KVf.d.ts} +4 -7
- package/dist/{deadline/index.d.ts → index-q0hXFeZ0.d.ts} +155 -9
- package/dist/index.d.ts +711 -6
- package/dist/index.js +1 -2
- package/dist/jev/index.d.ts +634 -0
- package/dist/jev/index.js +433 -0
- package/dist/jev/index.js.map +1 -0
- package/dist/machine-CdIcN2Xm.d.ts +1773 -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 +151 -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/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 +743 -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-LWDoi943.d.ts +998 -0
- package/dist/testing/index.d.ts +2 -2
- package/dist/testing/index.js +1 -2
- 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-DP3f5NIl.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.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/protocol-B5YmJr0d.d.ts +0 -45
- 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
package/dist/agent/index.js
CHANGED
|
@@ -1,22 +1,12 @@
|
|
|
1
|
-
export { COMPACTION_PURPOSE, agentBootMsg, agentEvents, agentTurnSchema, compactionSummarySchema, createAgent, isAgentTurn, isCompactionSummary, liftAgent, mergeInterpret, status } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
3
|
-
import '../chunk-
|
|
4
|
-
import '../chunk-
|
|
5
|
-
import '../chunk-
|
|
6
|
-
import '../chunk-
|
|
7
|
-
import '../chunk-
|
|
8
|
-
|
|
9
|
-
export { deadlineSub, subscribeDeadline } from '../chunk-DGE4PV4A.js';
|
|
10
|
-
import '../chunk-Q2UM7BXU.js';
|
|
11
|
-
import '../chunk-S2EGRPCM.js';
|
|
12
|
-
import '../chunk-UF4MZSLT.js';
|
|
1
|
+
export { COMPACTION_PURPOSE, PLAIN_MODEL_MISROUTE_REASON, TOOL_RETRY_EXHAUSTED_TAG, TOOL_TIMEOUT_TAG, agentBootMsg, agentCancelMsg, agentEvents, agentTurnSchema, compactionSummarySchema, createAgent, defineAgent, fanOutInterpret, isAgentTurn, isCompactionSummary, isReservedToolName, isStreamingModel, liftAgent, mergeInterpret, plainModel, renderPrompt, status, tool, toolErrorReason, toolRouter, transcript } from '../chunk-Z2L3LSNV.js';
|
|
2
|
+
import '../chunk-HYDWG35Q.js';
|
|
3
|
+
import '../chunk-MYXFNWAJ.js';
|
|
4
|
+
import '../chunk-TXN2KFHF.js';
|
|
5
|
+
import '../chunk-HUKZQX6U.js';
|
|
6
|
+
import '../chunk-AQ6ZIMEA.js';
|
|
7
|
+
import '../chunk-VBDU4JL6.js';
|
|
8
|
+
export { deadlineSub, subscribeDeadline } from '../chunk-F2US5BW6.js';
|
|
13
9
|
import '../chunk-G5E74IJB.js';
|
|
14
|
-
import '../chunk-
|
|
15
|
-
import '../chunk-FV3Z5MBE.js';
|
|
16
|
-
import '../chunk-VYFAZN3F.js';
|
|
17
|
-
import '../chunk-2YFLOCWX.js';
|
|
18
|
-
import '../chunk-ZJ5AOYBH.js';
|
|
19
|
-
import '../chunk-ZSUUOEPL.js';
|
|
20
|
-
import '../chunk-OOYD44JI.js';
|
|
10
|
+
import '../chunk-RQULHGYH.js';
|
|
21
11
|
//# sourceMappingURL=index.js.map
|
|
22
12
|
//# sourceMappingURL=index.js.map
|
|
@@ -62,5 +62,5 @@ function pendingEffectsLedger(restore) {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
export { applyEffectEvent, emptyLedger, foldLedger, isOwed, pendingEffectsLedger, survivingEffects };
|
|
65
|
-
//# sourceMappingURL=chunk-
|
|
66
|
-
//# sourceMappingURL=chunk-
|
|
65
|
+
//# sourceMappingURL=chunk-6IQPODUF.js.map
|
|
66
|
+
//# sourceMappingURL=chunk-6IQPODUF.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/do/durable-effects.ts"],"names":[],"mappings":"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","file":"chunk-25LBDCBC.js","sourcesContent":["/**\n * @demlik/tea/do — the durable pending-effects ledger (substrate primitive #1).\n *\n * Durable *state* and durable *effects* are different problems. An\n * event-sourced actor rebuilds its STATE by folding the event log\n * (`doEventSourcedStore`, sibling file). But an outbound side effect — a tool\n * round-trip, a message to a sibling grain — is fire-and-forget: if the actor\n * interprets the `Cmd` inside an activation that hibernates mid-flight, the\n * effect is lost, yet nothing in the replayed state records that it is still\n * OWED. This is the one real tax of the event-sourced-virtual-actor target\n * (ADR 0003 primitive #1): \"I owe this effect\" must itself be part of the\n * folded state.\n *\n * Akka's classic `AtLeastOnceDelivery` solves it with a ledger of unconfirmed\n * deliveries kept AS PART OF the persisted state: each `deliver` adds an entry\n * keyed by a monotonic `deliveryId`; each `confirmDelivery` removes it. On\n * recovery the ledger is rebuilt from the SAME events, and any surviving entry\n * is re-sent. At-least-once ⇒ a confirmed-but-not-yet-persisted delivery WILL\n * be re-sent after a crash, so the receiver must deduplicate by id.\n *\n * ## The load-bearing rule (do not violate)\n *\n * The ledger is a PURE FOLD over the same kind of event stream the actor\n * already replays — it is **NOT** a separately-persisted side table:\n *\n * - `effect_owed` — `{ id, effect }` ADDS an entry to the ledger.\n * - `effect_confirmed`— `{ id }` REMOVES the entry.\n *\n * `foldLedger(events)` is `events.reduce(applyEffectEvent, empty())` — the same\n * fold shape `replay` / `foldEvents` / the recorder use. Persist these two\n * events into the SAME log `doEventSourcedStore` already appends (they are just\n * Msg variants), and the ledger is rebuilt for free on the next activation:\n * `foldLedger(log)` after eviction equals `foldLedger(log)` never-evicted, by\n * construction (a pure fold over identical input).\n *\n * On activation (replay completion), `survivingEffects(ledger)` returns the\n * owed-but-unconfirmed entries to re-fire, ordered by their monotonic id. The\n * re-fire is a SIDE EFFECT DERIVED from the surviving ledger — never stored\n * separately, never fired during replay (recovery.md: add to the ledger during\n * recovery; let recovery-END re-emit the survivors).\n *\n * Anti-patterns this file refuses (mirroring durable-effects.md):\n * - A side-table ledger persisted apart from the events. The events ARE the\n * ledger; the Map is rebuilt by folding them.\n * - Re-firing every historical effect during replay. Only `survivingEffects`\n * (post-fold) re-emits.\n * - Assuming the receiver gets each effect exactly once. At-least-once: dedup\n * by `id` at the receiver (`isOwed` here is the sender's view; the receiver\n * owns its own dedup).\n */\n\nimport type { Cmd } from \"../index\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// The two events the ledger folds. These are ordinary Msg variants — persist\n// them into the same event log `doEventSourcedStore` appends, and the ledger\n// rebuilds itself on the next activation with no extra storage.\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Monotonic, gap-free delivery id — the single correlation + dedup key. */\nexport type DeliveryId = number;\n\n/**\n * An effect is now OWED: it has been decided but its delivery is not yet\n * confirmed. Adds `{ id → effect }` to the ledger when folded.\n *\n * Persist this BEFORE interpreting the effect (durable-effects.md rule:\n * \"persist the intent before deliver\"). A crash between persist and deliver is\n * fine — the surviving entry re-fires on activation. A crash before the persist\n * means the effect was never owed, so nothing is lost that the actor promised.\n */\nexport interface EffectOwed<E> extends Cmd<\"effect_owed\"> {\n readonly id: DeliveryId;\n readonly effect: E;\n}\n\n/**\n * An owed effect has been CONFIRMED delivered. Removes its entry from the\n * ledger when folded. Persist this BEFORE acting on the confirmation\n * (\"persist the confirmation before confirmDelivery\").\n */\nexport interface EffectConfirmed extends Cmd<\"effect_confirmed\"> {\n readonly id: DeliveryId;\n}\n\n/** The event union the ledger folds over. `E` is the consumer's effect type. */\nexport type EffectLedgerEvent<E> = EffectOwed<E> | EffectConfirmed;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// The ledger itself — a pure value. Insertion-ordered by monotonic id, so\n// `survivingEffects` re-emits in owed-order without a sort.\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * The pending-effects ledger: owed-but-unconfirmed effects keyed by their\n * monotonic delivery id. A pure value reconstructed by `foldLedger` — it is\n * never persisted on its own; the events are.\n *\n * `ReadonlyMap` preserves insertion order, which (because ids are appended\n * monotonically) is exactly id order — so iteration yields the survivors\n * oldest-first with no sort.\n */\nexport type PendingEffectsLedger<E> = ReadonlyMap<DeliveryId, E>;\n\n/** A single surviving entry to re-emit: its id and the effect it owes. */\nexport interface OwedEffect<E> {\n readonly id: DeliveryId;\n readonly effect: E;\n}\n\n/** The empty ledger — the fold's seed (a fresh actor owes nothing). */\nexport function emptyLedger<E>(): PendingEffectsLedger<E> {\n return new Map<DeliveryId, E>();\n}\n\n/**\n * Apply ONE ledger event — the reducer at the heart of the fold.\n *\n * - `effect_owed` → add `{ id → effect }`.\n * - `effect_confirmed` → remove `id` (no-op if already absent: a duplicate\n * confirm, or a confirm for an id evicted with the actor — at-least-once\n * tolerates both).\n *\n * Pure: returns a NEW ledger, never mutates the input — so folding the same\n * events twice (live and post-eviction) yields equal results, and a caller may\n * keep the prior ledger value.\n */\nexport function applyEffectEvent<E>(\n ledger: PendingEffectsLedger<E>,\n event: EffectLedgerEvent<E>,\n): PendingEffectsLedger<E> {\n const next = new Map(ledger);\n switch (event.type) {\n case \"effect_owed\":\n next.set(event.id, event.effect);\n return next;\n case \"effect_confirmed\":\n next.delete(event.id);\n return next;\n }\n}\n\n/**\n * THE FOLD. Rebuild the ledger from an event stream — the same fold shape\n * `replay` uses for state. After a simulated eviction this is called over the\n * persisted log and yields a ledger byte-for-byte equal to the never-evicted\n * one, because a pure fold over identical input is identical.\n *\n * This is the function that proves \"no side table\": the ledger is `events`\n * reduced, nothing more.\n */\nexport function foldLedger<E>(\n events: Iterable<EffectLedgerEvent<E>>,\n): PendingEffectsLedger<E> {\n let ledger = emptyLedger<E>();\n for (const event of events) ledger = applyEffectEvent(ledger, event);\n return ledger;\n}\n\n/**\n * RE-EMIT ON ACTIVATION. Given the rebuilt ledger, the owed-but-unconfirmed\n * effects to re-fire — ordered oldest-first by monotonic id. On a fresh /\n * fully-confirmed actor this is empty (nothing re-emitted).\n *\n * Idempotency is the RECEIVER's job: it must dedup by `id`, because\n * at-least-once means a re-emitted already-handled id WILL arrive again\n * (e.g. an effect confirmed in the activation that hibernated before the\n * `effect_confirmed` event was persisted). Re-firing the same id is therefore\n * a no-op AT THE RECEIVER, not here.\n */\nexport function survivingEffects<E>(\n ledger: PendingEffectsLedger<E>,\n): readonly OwedEffect<E>[] {\n const out: OwedEffect<E>[] = [];\n for (const [id, effect] of ledger) out.push({ id, effect });\n return out;\n}\n\n/** Is this id still owed (unconfirmed) in the ledger? Sender-side view. */\nexport function isOwed<E>(\n ledger: PendingEffectsLedger<E>,\n id: DeliveryId,\n): boolean {\n return ledger.has(id);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// pendingEffectsLedger — the stateful, monotonic-id-issuing recorder.\n//\n// The pure `foldLedger` is the contract; this is the ergonomic driver a host\n// uses live. It owns the monotonic `deliveryId` (gap-free, shared across all\n// destinations — durable-effects.md), emits the `effect_owed` / `effect_confirmed`\n// events for the caller to PERSIST, and keeps an in-memory mirror folded from\n// those same events so `survivingEffects` is available without a re-read.\n//\n// Mirrors `deferredGateway`'s factory shape: no clock / RNG captured; pure\n// bookkeeping. The caller is responsible for persisting each returned event\n// into the log (so the ledger survives eviction) and for actually interpreting\n// the effect after the owed event is durable.\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * A live, monotonic-id-issuing ledger recorder.\n *\n * - `owe(effect)` — allocate the next `deliveryId`, return the\n * `effect_owed` event to PERSIST plus the allocated `id`. Folding the event\n * into the recorder's mirror is done for you; the caller persists it.\n * - `confirm(id)` — return the `effect_confirmed` event to PERSIST, and `true`\n * iff the id was owed (a duplicate confirm returns `false` — the boolean is\n * itself a dedup signal, exactly Akka `confirmDelivery`).\n * - `surviving()` — the current owed-but-unconfirmed effects (for re-emit on\n * activation).\n * - `ledger()` — the current folded ledger value.\n * - `lastId()` — the highest id issued (so a host can seed the counter from a\n * rebuilt ledger after eviction; see `restore`).\n */\nexport interface PendingEffectsRecorder<E> {\n owe(effect: E): { id: DeliveryId; event: EffectOwed<E> };\n confirm(id: DeliveryId): { confirmed: boolean; event: EffectConfirmed };\n surviving(): readonly OwedEffect<E>[];\n ledger(): PendingEffectsLedger<E>;\n lastId(): DeliveryId;\n}\n\n/**\n * Build a live recorder. `restore` rehydrates it after an eviction: pass the\n * events read back from the log (or the rebuilt ledger's survivors) so the\n * monotonic counter resumes WITHOUT gaps and the mirror reflects the surviving\n * owed set. Omit `restore` for a fresh actor.\n *\n * Counter seeding rule: the next id is `max(seen ids) + 1`. Restoring only the\n * survivors is sufficient for correctness of re-emit, but to keep ids gap-free\n * across confirmed-and-pruned entries the host should pass `lastId` explicitly\n * when it has it (e.g. persisted alongside the snapshot). When only survivors\n * are known, the counter resumes from the highest surviving id — a confirmed id\n * higher than every survivor could in principle be reissued, so a host that\n * needs strict global monotonicity persists `lastId`.\n */\nexport function pendingEffectsLedger<E>(restore?: {\n readonly events?: Iterable<EffectLedgerEvent<E>>;\n readonly lastId?: DeliveryId;\n}): PendingEffectsRecorder<E> {\n // Materialize the restore events ONCE — `restore.events` is only an\n // `Iterable`, so a single-use generator would be exhausted by `foldLedger`\n // and yield nothing on a second walk (seeding the counter to 0 and reissuing\n // colliding ids). Folding and counter-seeding both read this array.\n const events = restore?.events ? [...restore.events] : undefined;\n let mirror: PendingEffectsLedger<E> = events\n ? foldLedger(events)\n : emptyLedger<E>();\n\n // Seed the monotonic counter. Prefer an explicit `lastId` (gap-free across\n // pruned ids); else the highest id observed in the restore events; else the\n // highest surviving id; else 0 (fresh).\n let counter = restore?.lastId ?? 0;\n if (restore?.lastId === undefined && events) {\n for (const e of events) if (e.id > counter) counter = e.id;\n } else if (restore?.lastId === undefined) {\n for (const id of mirror.keys()) if (id > counter) counter = id;\n }\n\n return {\n owe(effect) {\n counter += 1;\n const id = counter;\n const event: EffectOwed<E> = { type: \"effect_owed\", id, effect };\n mirror = applyEffectEvent(mirror, event);\n return { id, event };\n },\n confirm(id) {\n const confirmed = mirror.has(id);\n const event: EffectConfirmed = { type: \"effect_confirmed\", id };\n mirror = applyEffectEvent(mirror, event);\n return { confirmed, event };\n },\n surviving() {\n return survivingEffects(mirror);\n },\n ledger() {\n return mirror;\n },\n lastId() {\n return counter;\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/do/durable-effects.ts"],"names":[],"mappings":"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","file":"chunk-6IQPODUF.js","sourcesContent":["/**\n * @demlik/tea/do — the durable pending-effects ledger (substrate primitive #1).\n *\n * Durable *state* and durable *effects* are different problems. An\n * event-sourced actor rebuilds its STATE by folding the event log\n * (`doEventSourcedStore`, sibling file). But an outbound side effect — a tool\n * round-trip, a message to a sibling grain — is fire-and-forget: if the actor\n * interprets the `Cmd` inside an activation that hibernates mid-flight, the\n * effect is lost, yet nothing in the replayed state records that it is still\n * OWED. This is the one real tax of the event-sourced-virtual-actor target\n * (ADR 0003 primitive #1): \"I owe this effect\" must itself be part of the\n * folded state.\n *\n * Akka's classic `AtLeastOnceDelivery` solves it with a ledger of unconfirmed\n * deliveries kept AS PART OF the persisted state: each `deliver` adds an entry\n * keyed by a monotonic `deliveryId`; each `confirmDelivery` removes it. On\n * recovery the ledger is rebuilt from the SAME events, and any surviving entry\n * is re-sent. At-least-once ⇒ a confirmed-but-not-yet-persisted delivery WILL\n * be re-sent after a crash, so the receiver must deduplicate by id.\n *\n * ## The load-bearing rule (do not violate)\n *\n * The ledger is a PURE FOLD over the same kind of event stream the actor\n * already replays — it is **NOT** a separately-persisted side table:\n *\n * - `effect_owed` — `{ id, effect }` ADDS an entry to the ledger.\n * - `effect_confirmed`— `{ id }` REMOVES the entry.\n *\n * `foldLedger(events)` is `events.reduce(applyEffectEvent, empty())` — the same\n * fold shape `replay` / `foldEvents` / the recorder use. Persist these two\n * events into the SAME log `doEventSourcedStore` already appends (they are just\n * Msg variants), and the ledger is rebuilt for free on the next activation:\n * `foldLedger(log)` after eviction equals `foldLedger(log)` never-evicted, by\n * construction (a pure fold over identical input).\n *\n * On activation (replay completion), `survivingEffects(ledger)` returns the\n * owed-but-unconfirmed entries to re-fire, ordered by their monotonic id. The\n * re-fire is a SIDE EFFECT DERIVED from the surviving ledger — never stored\n * separately, never fired during replay (recovery.md: add to the ledger during\n * recovery; let recovery-END re-emit the survivors).\n *\n * Anti-patterns this file refuses (mirroring durable-effects.md):\n * - A side-table ledger persisted apart from the events. The events ARE the\n * ledger; the Map is rebuilt by folding them.\n * - Re-firing every historical effect during replay. Only `survivingEffects`\n * (post-fold) re-emits.\n * - Assuming the receiver gets each effect exactly once. At-least-once: dedup\n * by `id` at the receiver (`isOwed` here is the sender's view; the receiver\n * owns its own dedup).\n */\n\nimport type { Cmd } from \"../index\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// The two events the ledger folds. These are ordinary Msg variants — persist\n// them into the same event log `doEventSourcedStore` appends, and the ledger\n// rebuilds itself on the next activation with no extra storage.\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Monotonic, gap-free delivery id — the single correlation + dedup key. */\nexport type DeliveryId = number;\n\n/**\n * An effect is now OWED: it has been decided but its delivery is not yet\n * confirmed. Adds `{ id → effect }` to the ledger when folded.\n *\n * Persist this BEFORE interpreting the effect (durable-effects.md rule:\n * \"persist the intent before deliver\"). A crash between persist and deliver is\n * fine — the surviving entry re-fires on activation. A crash before the persist\n * means the effect was never owed, so nothing is lost that the actor promised.\n */\nexport interface EffectOwed<E> extends Cmd<\"effect_owed\"> {\n readonly id: DeliveryId;\n readonly effect: E;\n}\n\n/**\n * An owed effect has been CONFIRMED delivered. Removes its entry from the\n * ledger when folded. Persist this BEFORE acting on the confirmation\n * (\"persist the confirmation before confirmDelivery\").\n */\nexport interface EffectConfirmed extends Cmd<\"effect_confirmed\"> {\n readonly id: DeliveryId;\n}\n\n/** The event union the ledger folds over. `E` is the consumer's effect type. */\nexport type EffectLedgerEvent<E> = EffectOwed<E> | EffectConfirmed;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// The ledger itself — a pure value. Insertion-ordered by monotonic id, so\n// `survivingEffects` re-emits in owed-order without a sort.\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * The pending-effects ledger: owed-but-unconfirmed effects keyed by their\n * monotonic delivery id. A pure value reconstructed by `foldLedger` — it is\n * never persisted on its own; the events are.\n *\n * `ReadonlyMap` preserves insertion order, which (because ids are appended\n * monotonically) is exactly id order — so iteration yields the survivors\n * oldest-first with no sort.\n */\nexport type PendingEffectsLedger<E> = ReadonlyMap<DeliveryId, E>;\n\n/** A single surviving entry to re-emit: its id and the effect it owes. */\nexport interface OwedEffect<E> {\n readonly id: DeliveryId;\n readonly effect: E;\n}\n\n/** The empty ledger — the fold's starting value (a fresh actor owes nothing). */\nexport function emptyLedger<E>(): PendingEffectsLedger<E> {\n return new Map<DeliveryId, E>();\n}\n\n/**\n * Apply ONE ledger event — the reducer at the heart of the fold.\n *\n * - `effect_owed` → add `{ id → effect }`.\n * - `effect_confirmed` → remove `id` (no-op if already absent: a duplicate\n * confirm, or a confirm for an id evicted with the actor — at-least-once\n * tolerates both).\n *\n * Pure: returns a NEW ledger, never mutates the input — so folding the same\n * events twice (live and post-eviction) yields equal results, and a caller may\n * keep the prior ledger value.\n */\nexport function applyEffectEvent<E>(\n ledger: PendingEffectsLedger<E>,\n event: EffectLedgerEvent<E>,\n): PendingEffectsLedger<E> {\n const next = new Map(ledger);\n switch (event.type) {\n case \"effect_owed\":\n next.set(event.id, event.effect);\n return next;\n case \"effect_confirmed\":\n next.delete(event.id);\n return next;\n }\n}\n\n/**\n * THE FOLD. Rebuild the ledger from an event stream — the same fold shape\n * `replay` uses for state. After a simulated eviction this is called over the\n * persisted log and yields a ledger byte-for-byte equal to the never-evicted\n * one, because a pure fold over identical input is identical.\n *\n * This is the function that proves \"no side table\": the ledger is `events`\n * reduced, nothing more.\n */\nexport function foldLedger<E>(\n events: Iterable<EffectLedgerEvent<E>>,\n): PendingEffectsLedger<E> {\n let ledger = emptyLedger<E>();\n for (const event of events) ledger = applyEffectEvent(ledger, event);\n return ledger;\n}\n\n/**\n * RE-EMIT ON ACTIVATION. Given the rebuilt ledger, the owed-but-unconfirmed\n * effects to re-fire — ordered oldest-first by monotonic id. On a fresh /\n * fully-confirmed actor this is empty (nothing re-emitted).\n *\n * Idempotency is the RECEIVER's job: it must dedup by `id`, because\n * at-least-once means a re-emitted already-handled id WILL arrive again\n * (e.g. an effect confirmed in the activation that hibernated before the\n * `effect_confirmed` event was persisted). Re-firing the same id is therefore\n * a no-op AT THE RECEIVER, not here.\n */\nexport function survivingEffects<E>(\n ledger: PendingEffectsLedger<E>,\n): readonly OwedEffect<E>[] {\n const out: OwedEffect<E>[] = [];\n for (const [id, effect] of ledger) out.push({ id, effect });\n return out;\n}\n\n/** Is this id still owed (unconfirmed) in the ledger? Sender-side view. */\nexport function isOwed<E>(\n ledger: PendingEffectsLedger<E>,\n id: DeliveryId,\n): boolean {\n return ledger.has(id);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// pendingEffectsLedger — the stateful, monotonic-id-issuing recorder.\n//\n// The pure `foldLedger` is the contract; this is the ergonomic driver a host\n// uses live. It owns the monotonic `deliveryId` (gap-free, shared across all\n// destinations — durable-effects.md), emits the `effect_owed` / `effect_confirmed`\n// events for the caller to PERSIST, and keeps an in-memory mirror folded from\n// those same events so `survivingEffects` is available without a re-read.\n//\n// Mirrors `deferredGateway`'s factory shape: no clock / RNG captured; pure\n// bookkeeping. The caller is responsible for persisting each returned event\n// into the log (so the ledger survives eviction) and for actually interpreting\n// the effect after the owed event is durable.\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * A live, monotonic-id-issuing ledger recorder.\n *\n * - `owe(effect)` — allocate the next `deliveryId`, return the\n * `effect_owed` event to PERSIST plus the allocated `id`. Folding the event\n * into the recorder's mirror is done for you; the caller persists it.\n * - `confirm(id)` — return the `effect_confirmed` event to PERSIST, and `true`\n * iff the id was owed (a duplicate confirm returns `false` — the boolean is\n * itself a dedup signal, exactly Akka `confirmDelivery`).\n * - `surviving()` — the current owed-but-unconfirmed effects (for re-emit on\n * activation).\n * - `ledger()` — the current folded ledger value.\n * - `lastId()` — the highest id issued (so a host can seed the counter from a\n * rebuilt ledger after eviction; see `restore`).\n */\nexport interface PendingEffectsRecorder<E> {\n owe(effect: E): { id: DeliveryId; event: EffectOwed<E> };\n confirm(id: DeliveryId): { confirmed: boolean; event: EffectConfirmed };\n surviving(): readonly OwedEffect<E>[];\n ledger(): PendingEffectsLedger<E>;\n lastId(): DeliveryId;\n}\n\n/**\n * Build a live recorder. `restore` rehydrates it after an eviction: pass the\n * events read back from the log (or the rebuilt ledger's survivors) so the\n * monotonic counter resumes WITHOUT gaps and the mirror reflects the surviving\n * owed set. Omit `restore` for a fresh actor.\n *\n * Counter seeding rule: the next id is `max(seen ids) + 1`. Restoring only the\n * survivors is sufficient for correctness of re-emit, but to keep ids gap-free\n * across confirmed-and-pruned entries the host should pass `lastId` explicitly\n * when it has it (e.g. persisted alongside the snapshot). When only survivors\n * are known, the counter resumes from the highest surviving id — a confirmed id\n * higher than every survivor could in principle be reissued, so a host that\n * needs strict global monotonicity persists `lastId`.\n */\nexport function pendingEffectsLedger<E>(restore?: {\n readonly events?: Iterable<EffectLedgerEvent<E>>;\n readonly lastId?: DeliveryId;\n}): PendingEffectsRecorder<E> {\n // Materialize the restore events ONCE — `restore.events` is only an\n // `Iterable`, so a single-use generator would be exhausted by `foldLedger`\n // and yield nothing on a second walk (seeding the counter to 0 and reissuing\n // colliding ids). Folding and counter-seeding both read this array.\n const events = restore?.events ? [...restore.events] : undefined;\n let mirror: PendingEffectsLedger<E> = events\n ? foldLedger(events)\n : emptyLedger<E>();\n\n // Seed the monotonic counter. Prefer an explicit `lastId` (gap-free across\n // pruned ids); else the highest id observed in the restore events; else the\n // highest surviving id; else 0 (fresh).\n let counter = restore?.lastId ?? 0;\n if (restore?.lastId === undefined && events) {\n for (const e of events) if (e.id > counter) counter = e.id;\n } else if (restore?.lastId === undefined) {\n for (const id of mirror.keys()) if (id > counter) counter = id;\n }\n\n return {\n owe(effect) {\n counter += 1;\n const id = counter;\n const event: EffectOwed<E> = { type: \"effect_owed\", id, effect };\n mirror = applyEffectEvent(mirror, event);\n return { id, event };\n },\n confirm(id) {\n const confirmed = mirror.has(id);\n const event: EffectConfirmed = { type: \"effect_confirmed\", id };\n mirror = applyEffectEvent(mirror, event);\n return { confirmed, event };\n },\n surviving() {\n return survivingEffects(mirror);\n },\n ledger() {\n return mirror;\n },\n lastId() {\n return counter;\n },\n };\n}\n"]}
|
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
import { asRng, recordFailure, shouldRetry, nextDelayMs, initRetry } from './chunk-VBDU4JL6.js';
|
|
2
|
+
import { initCache, set, deadlineSub, get } from './chunk-F2US5BW6.js';
|
|
3
|
+
import { Cmd, without, tryInterpret } from './chunk-RQULHGYH.js';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
|
|
6
|
+
// src/protocol.ts
|
|
7
|
+
var MsgType = {
|
|
8
|
+
// --- resilient-call: the run Cmd + its two settle Msgs -------------------
|
|
9
|
+
/** The "run the port for `key`" effect Cmd resilient-call emits. */
|
|
10
|
+
ResilientRun: "resilient_run",
|
|
11
|
+
/** PRIVATE success settle Msg (read only by `agentEvents`, #47). */
|
|
12
|
+
ResilientOk: "resilient_ok",
|
|
13
|
+
/** Failure settle Msg — routed to the `fail` verb (back off via retry). */
|
|
14
|
+
ResilientErr: "resilient_err",
|
|
15
|
+
// --- agent: the wired machine's own entry-point Msgs ---------------------
|
|
16
|
+
/** Begin a run. */
|
|
17
|
+
AgentStart: "agent_start",
|
|
18
|
+
/** PRIVATE tool-fan-out success settle Msg (read only by `agentEvents`, #47). */
|
|
19
|
+
AgentToolOk: "agent_tool_ok",
|
|
20
|
+
/** Tool-fan-out failure settle Msg. */
|
|
21
|
+
AgentToolErr: "agent_tool_err",
|
|
22
|
+
/**
|
|
23
|
+
* Re-fire the one outstanding effect on rehydrate (the do↔agent seam). Fired
|
|
24
|
+
* by `do/host`'s `autoBoot` via the typed `agentBootMsg` constructor, matched
|
|
25
|
+
* by the agent reducer — see `AgentBootPort` in `../agent`.
|
|
26
|
+
*/
|
|
27
|
+
AgentBoot: "agent_boot",
|
|
28
|
+
/**
|
|
29
|
+
* Stop the run from outside and settle it `cancelled` — what an `AbortSignal`
|
|
30
|
+
* handed to `driveToDone` / a defined agent's `run` dispatches on abort. A
|
|
31
|
+
* transition, never a throw: the outcome lands in the Model, so a reload reads
|
|
32
|
+
* a run that ended rather than one to resume.
|
|
33
|
+
*/
|
|
34
|
+
AgentCancel: "agent_cancel",
|
|
35
|
+
// --- agent: the context-compaction round-trip (#85) ----------------------
|
|
36
|
+
/**
|
|
37
|
+
* The "summarize the oldest N turns" effect Cmd the agent emits when its
|
|
38
|
+
* `CompactionPolicy` asks to compact before a brain call. A DEDICATED
|
|
39
|
+
* round-trip (design B1), distinct from the brain call's `resilient_run`, so
|
|
40
|
+
* compaction is its own honest `Awaiting` state — see `../agent`.
|
|
41
|
+
*/
|
|
42
|
+
CompactRun: "compact_run",
|
|
43
|
+
/** Compaction round-trip resolved — carries the summary text the fold-back folds. */
|
|
44
|
+
CompactOk: "compact_ok",
|
|
45
|
+
/** Compaction round-trip failed (exhausted retry) — surfaced as data, not a stall. */
|
|
46
|
+
CompactErr: "compact_err",
|
|
47
|
+
// --- token-refresh: the two refresh-result Msgs --------------------------
|
|
48
|
+
/** Refresh port resolved — carries the fresh `Token`. */
|
|
49
|
+
TokenRefreshed: "token_refreshed",
|
|
50
|
+
/** Refresh port rejected — carries the rejection (errors are data). */
|
|
51
|
+
TokenRefreshFailed: "token_refresh_failed",
|
|
52
|
+
// --- authed-call: the 401 trigger ----------------------------------------
|
|
53
|
+
/** The 401 the consumer dispatches when a guarded call comes back unauthorized. */
|
|
54
|
+
Unauthorized: "unauthorized"
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
// src/internal/resilience/circuit-breaker/index.ts
|
|
58
|
+
var defaultCircuitPolicy = {
|
|
59
|
+
failureThreshold: 5,
|
|
60
|
+
cooldownMs: 3e4,
|
|
61
|
+
halfOpenMaxProbes: 1
|
|
62
|
+
};
|
|
63
|
+
function initCircuit() {
|
|
64
|
+
return { phase: "closed", failures: 0 };
|
|
65
|
+
}
|
|
66
|
+
function onSuccess(state, _policy) {
|
|
67
|
+
switch (state.phase) {
|
|
68
|
+
case "closed":
|
|
69
|
+
return state.failures === 0 ? state : { phase: "closed", failures: 0 };
|
|
70
|
+
case "half_open":
|
|
71
|
+
return { phase: "closed", failures: 0 };
|
|
72
|
+
case "open":
|
|
73
|
+
return state;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function onFailure(state, policy, nowMs) {
|
|
77
|
+
switch (state.phase) {
|
|
78
|
+
case "closed": {
|
|
79
|
+
const failures = state.failures + 1;
|
|
80
|
+
return failures >= policy.failureThreshold ? { phase: "open", openedAtMs: nowMs } : { phase: "closed", failures };
|
|
81
|
+
}
|
|
82
|
+
case "half_open":
|
|
83
|
+
return { phase: "open", openedAtMs: nowMs };
|
|
84
|
+
case "open":
|
|
85
|
+
return state;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function canPass(state, policy, nowMs) {
|
|
89
|
+
switch (state.phase) {
|
|
90
|
+
case "closed":
|
|
91
|
+
return [state, true];
|
|
92
|
+
case "open": {
|
|
93
|
+
const elapsed = nowMs - state.openedAtMs;
|
|
94
|
+
if (elapsed >= policy.cooldownMs) {
|
|
95
|
+
return [{ phase: "half_open", probes: 1 }, true];
|
|
96
|
+
}
|
|
97
|
+
return [state, false];
|
|
98
|
+
}
|
|
99
|
+
case "half_open":
|
|
100
|
+
if (state.probes < policy.halfOpenMaxProbes) {
|
|
101
|
+
return [{ phase: "half_open", probes: state.probes + 1 }, true];
|
|
102
|
+
}
|
|
103
|
+
return [state, false];
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// src/internal/resilience/rate-limit/index.ts
|
|
108
|
+
function initBucket(capacity, refillPerSec, nowMs) {
|
|
109
|
+
return {
|
|
110
|
+
tokens: capacity,
|
|
111
|
+
capacity,
|
|
112
|
+
refillPerSec,
|
|
113
|
+
lastRefillMs: nowMs
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
function refill(bucket, nowMs) {
|
|
117
|
+
const elapsedSec = Math.max(0, nowMs - bucket.lastRefillMs) / 1e3;
|
|
118
|
+
const replenished = bucket.tokens + elapsedSec * bucket.refillPerSec;
|
|
119
|
+
return {
|
|
120
|
+
...bucket,
|
|
121
|
+
tokens: Math.min(bucket.capacity, replenished),
|
|
122
|
+
lastRefillMs: nowMs
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
function tryConsume(bucket, nowMs, n = 1) {
|
|
126
|
+
const refilled = refill(bucket, nowMs);
|
|
127
|
+
if (refilled.tokens >= n) {
|
|
128
|
+
return [{ ...refilled, tokens: refilled.tokens - n }, true];
|
|
129
|
+
}
|
|
130
|
+
return [refilled, false];
|
|
131
|
+
}
|
|
132
|
+
function initWindow(windowMs, limit) {
|
|
133
|
+
return { hits: [], windowMs, limit };
|
|
134
|
+
}
|
|
135
|
+
function prune(window, nowMs) {
|
|
136
|
+
const cutoff = nowMs - window.windowMs;
|
|
137
|
+
return window.hits.filter((t) => t > cutoff);
|
|
138
|
+
}
|
|
139
|
+
function record(window, nowMs) {
|
|
140
|
+
const pruned = prune(window, nowMs);
|
|
141
|
+
if (pruned.length < window.limit) {
|
|
142
|
+
return [{ ...window, hits: [...pruned, nowMs] }, true];
|
|
143
|
+
}
|
|
144
|
+
return [{ ...window, hits: pruned }, false];
|
|
145
|
+
}
|
|
146
|
+
function remaining(window, nowMs) {
|
|
147
|
+
const live = prune(window, nowMs).length;
|
|
148
|
+
return Math.max(0, window.limit - live);
|
|
149
|
+
}
|
|
150
|
+
function runCmdDef() {
|
|
151
|
+
return Cmd.define(MsgType.ResilientRun, {
|
|
152
|
+
input: z.custom(),
|
|
153
|
+
ok: z.custom(),
|
|
154
|
+
err: ["port_rejected", "deadline_exceeded"]
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
function circuitPolicy(config) {
|
|
158
|
+
if (config.circuit === void 0) return null;
|
|
159
|
+
return {
|
|
160
|
+
failureThreshold: config.circuit.threshold,
|
|
161
|
+
cooldownMs: config.circuit.cooldownMs,
|
|
162
|
+
halfOpenMaxProbes: config.circuit.halfOpenMaxProbes ?? 1
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
function charge(budget, at) {
|
|
166
|
+
if (budget.remainingMs <= 0) return { ...budget, chargingSinceMs: at };
|
|
167
|
+
const elapsed = Math.max(0, at - budget.chargingSinceMs);
|
|
168
|
+
return { remainingMs: budget.remainingMs - elapsed, chargingSinceMs: at };
|
|
169
|
+
}
|
|
170
|
+
function retryTimerId(key) {
|
|
171
|
+
return `resilient:retry:${key}`;
|
|
172
|
+
}
|
|
173
|
+
function deadlineTimerId(key) {
|
|
174
|
+
return `resilient:deadline:${key}`;
|
|
175
|
+
}
|
|
176
|
+
function createResilientCall(config, rng = Math.random) {
|
|
177
|
+
const cPolicy = circuitPolicy(config);
|
|
178
|
+
const rngBranded = asRng(rng);
|
|
179
|
+
const runCmd = runCmdDef();
|
|
180
|
+
function init() {
|
|
181
|
+
return {
|
|
182
|
+
circuit: initCircuit(),
|
|
183
|
+
// The bucket carries a default value even without the rateLimit brick so
|
|
184
|
+
// the slice shape is uniform, but the rate-limit GATE is skipped entirely
|
|
185
|
+
// when the brick is absent (see `gate`) — the bucket is simply never
|
|
186
|
+
// consulted. A `0/0` placeholder bucket would be touched by `tryConsume`;
|
|
187
|
+
// a `1-cap` default is harmless because the gate never calls it.
|
|
188
|
+
bucket: config.rateLimit ? initBucket(
|
|
189
|
+
config.rateLimit.capacity,
|
|
190
|
+
config.rateLimit.refillPerSec,
|
|
191
|
+
0
|
|
192
|
+
) : initBucket(1, 1, 0),
|
|
193
|
+
retry: {},
|
|
194
|
+
cache: initCache(),
|
|
195
|
+
calls: {}
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
function retryOf(s, key) {
|
|
199
|
+
return s.retry[key] ?? initRetry();
|
|
200
|
+
}
|
|
201
|
+
function freshBudget(at) {
|
|
202
|
+
return {
|
|
203
|
+
remainingMs: config.deadline ? config.deadline.ms : 0,
|
|
204
|
+
chargingSinceMs: at
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
function budgetFor(s, key, at) {
|
|
208
|
+
const call = s.calls[key];
|
|
209
|
+
if (call?.phase === "running" || call?.phase === "waiting_retry") {
|
|
210
|
+
return charge(call.budget, at);
|
|
211
|
+
}
|
|
212
|
+
return freshBudget(at);
|
|
213
|
+
}
|
|
214
|
+
function gate(s, key, input, at, budget) {
|
|
215
|
+
if (config.deadline !== void 0 && budget.remainingMs <= 0) {
|
|
216
|
+
return [
|
|
217
|
+
setCall(s, key, {
|
|
218
|
+
phase: "failed",
|
|
219
|
+
error: {
|
|
220
|
+
_tag: "deadline_exceeded",
|
|
221
|
+
id: deadlineTimerId(key),
|
|
222
|
+
atMs: at
|
|
223
|
+
}
|
|
224
|
+
}),
|
|
225
|
+
[]
|
|
226
|
+
];
|
|
227
|
+
}
|
|
228
|
+
if (config.cache !== void 0) {
|
|
229
|
+
const cached = get(s.cache, key, at);
|
|
230
|
+
if (cached !== void 0) {
|
|
231
|
+
return [setCall(s, key, { phase: "succeeded", result: cached }), []];
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
let bucket = s.bucket;
|
|
235
|
+
if (config.rateLimit !== void 0) {
|
|
236
|
+
const [next, hasToken] = tryConsume(bucket, at);
|
|
237
|
+
bucket = next;
|
|
238
|
+
if (!hasToken) {
|
|
239
|
+
return backoff(
|
|
240
|
+
{ ...s, bucket },
|
|
241
|
+
key,
|
|
242
|
+
input,
|
|
243
|
+
"rate_limited",
|
|
244
|
+
at,
|
|
245
|
+
budget
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
let circuit = s.circuit;
|
|
250
|
+
if (cPolicy !== null) {
|
|
251
|
+
const [next, ok] = canPass(circuit, cPolicy, at);
|
|
252
|
+
circuit = next;
|
|
253
|
+
if (!ok) {
|
|
254
|
+
return [
|
|
255
|
+
{ ...setCall(s, key, { phase: "circuit_open" }), bucket, circuit },
|
|
256
|
+
[]
|
|
257
|
+
];
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return [
|
|
261
|
+
{
|
|
262
|
+
...setCall(s, key, { phase: "running", input, budget }),
|
|
263
|
+
circuit,
|
|
264
|
+
bucket
|
|
265
|
+
},
|
|
266
|
+
[runCmd({ key, input })]
|
|
267
|
+
];
|
|
268
|
+
}
|
|
269
|
+
function backoff(s, key, input, error, at, budget) {
|
|
270
|
+
if (config.retry === void 0) {
|
|
271
|
+
return [setCall(s, key, { phase: "failed", error }), []];
|
|
272
|
+
}
|
|
273
|
+
const retry = recordFailure(retryOf(s, key), error, at);
|
|
274
|
+
const withRetry = { ...s, retry: { ...s.retry, [key]: retry } };
|
|
275
|
+
if (!shouldRetry(retry, config.retry, at)) {
|
|
276
|
+
return [setCall(withRetry, key, { phase: "failed", error }), []];
|
|
277
|
+
}
|
|
278
|
+
const retryAtMs = at + nextDelayMs(retry, config.retry, rngBranded);
|
|
279
|
+
return [
|
|
280
|
+
setCall(withRetry, key, {
|
|
281
|
+
phase: "waiting_retry",
|
|
282
|
+
input,
|
|
283
|
+
retryAtMs,
|
|
284
|
+
budget
|
|
285
|
+
}),
|
|
286
|
+
[]
|
|
287
|
+
];
|
|
288
|
+
}
|
|
289
|
+
function setCall(s, key, phase) {
|
|
290
|
+
return { ...s, calls: { ...s.calls, [key]: phase } };
|
|
291
|
+
}
|
|
292
|
+
function attempt(s, key, input, at) {
|
|
293
|
+
return gate(s, key, input, at, budgetFor(s, key, at));
|
|
294
|
+
}
|
|
295
|
+
function resume(s, at) {
|
|
296
|
+
const calls = { ...s.calls };
|
|
297
|
+
for (const [key, call] of Object.entries(calls)) {
|
|
298
|
+
if (call.phase !== "running" && call.phase !== "waiting_retry") continue;
|
|
299
|
+
calls[key] = {
|
|
300
|
+
...call,
|
|
301
|
+
budget: { ...call.budget, chargingSinceMs: at }
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
return { ...s, calls };
|
|
305
|
+
}
|
|
306
|
+
function succeed(s, key, msg) {
|
|
307
|
+
const circuit = cPolicy !== null ? onSuccess(s.circuit) : s.circuit;
|
|
308
|
+
const cache = config.cache !== void 0 ? set(s.cache, key, msg.result, msg.at, config.cache.ttlMs) : s.cache;
|
|
309
|
+
const retry = without(s.retry, key);
|
|
310
|
+
return [
|
|
311
|
+
{
|
|
312
|
+
...setCall(s, key, { phase: "succeeded", result: msg.result }),
|
|
313
|
+
circuit,
|
|
314
|
+
cache,
|
|
315
|
+
retry
|
|
316
|
+
},
|
|
317
|
+
[]
|
|
318
|
+
];
|
|
319
|
+
}
|
|
320
|
+
function fail(s, key, msg) {
|
|
321
|
+
const circuit = cPolicy !== null ? onFailure(s.circuit, cPolicy, msg.at) : s.circuit;
|
|
322
|
+
const withCircuit = { ...s, circuit };
|
|
323
|
+
const call = s.calls[key];
|
|
324
|
+
const input = call?.phase === "running" ? call.input : void 0;
|
|
325
|
+
const budget = budgetFor(s, key, msg.at);
|
|
326
|
+
if (input === void 0) {
|
|
327
|
+
return [
|
|
328
|
+
setCall(withCircuit, key, { phase: "failed", error: msg.error }),
|
|
329
|
+
[]
|
|
330
|
+
];
|
|
331
|
+
}
|
|
332
|
+
return backoff(withCircuit, key, input, msg.error, msg.at, budget);
|
|
333
|
+
}
|
|
334
|
+
function settleFailed(s, key, error) {
|
|
335
|
+
return [setCall(s, key, { phase: "failed", error }), []];
|
|
336
|
+
}
|
|
337
|
+
function onTimer(s, msg) {
|
|
338
|
+
for (const [key, call] of Object.entries(s.calls)) {
|
|
339
|
+
if (msg.id === retryTimerId(key)) {
|
|
340
|
+
if (call.phase !== "waiting_retry") return [s, []];
|
|
341
|
+
return gate(
|
|
342
|
+
s,
|
|
343
|
+
key,
|
|
344
|
+
call.input,
|
|
345
|
+
msg.atMs,
|
|
346
|
+
charge(call.budget, msg.atMs)
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
if (msg.id === deadlineTimerId(key)) {
|
|
350
|
+
if (call.phase !== "running" && call.phase !== "waiting_retry")
|
|
351
|
+
return [s, []];
|
|
352
|
+
return [
|
|
353
|
+
setCall(s, key, {
|
|
354
|
+
phase: "failed",
|
|
355
|
+
error: {
|
|
356
|
+
_tag: "deadline_exceeded",
|
|
357
|
+
id: msg.id,
|
|
358
|
+
atMs: msg.atMs
|
|
359
|
+
}
|
|
360
|
+
}),
|
|
361
|
+
[]
|
|
362
|
+
];
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
return [s, []];
|
|
366
|
+
}
|
|
367
|
+
function subs(s) {
|
|
368
|
+
const out = [];
|
|
369
|
+
for (const [key, call] of Object.entries(s.calls)) {
|
|
370
|
+
if (call.phase === "waiting_retry") {
|
|
371
|
+
out.push(deadlineSub(retryTimerId(key), call.retryAtMs));
|
|
372
|
+
}
|
|
373
|
+
if (config.deadline !== void 0 && (call.phase === "running" || call.phase === "waiting_retry") && call.budget.remainingMs > 0) {
|
|
374
|
+
out.push(
|
|
375
|
+
deadlineSub(
|
|
376
|
+
deadlineTimerId(key),
|
|
377
|
+
call.budget.chargingSinceMs + call.budget.remainingMs
|
|
378
|
+
)
|
|
379
|
+
);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
return out;
|
|
383
|
+
}
|
|
384
|
+
function handlers(ports) {
|
|
385
|
+
return {
|
|
386
|
+
resilient_run: tryInterpret(
|
|
387
|
+
(cmd) => ports.run(cmd.input, cmd.key),
|
|
388
|
+
(result, cmd) => ({
|
|
389
|
+
type: MsgType.ResilientOk,
|
|
390
|
+
key: cmd.key,
|
|
391
|
+
result,
|
|
392
|
+
at: Date.now()
|
|
393
|
+
}),
|
|
394
|
+
(error, cmd) => ({
|
|
395
|
+
type: MsgType.ResilientErr,
|
|
396
|
+
key: cmd.key,
|
|
397
|
+
error,
|
|
398
|
+
at: Date.now()
|
|
399
|
+
})
|
|
400
|
+
)
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
return {
|
|
404
|
+
init,
|
|
405
|
+
attempt,
|
|
406
|
+
resume,
|
|
407
|
+
succeed,
|
|
408
|
+
fail,
|
|
409
|
+
settleFailed,
|
|
410
|
+
onTimer,
|
|
411
|
+
subs,
|
|
412
|
+
handlers
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
function liftResilience(state, [slice, cmds]) {
|
|
416
|
+
return [{ ...state, resilience: slice }, cmds];
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
export { MsgType, canPass, createResilientCall, defaultCircuitPolicy, initBucket, initCircuit, initWindow, liftResilience, onFailure, onSuccess, record, refill, remaining, runCmdDef, tryConsume };
|
|
420
|
+
//# sourceMappingURL=chunk-AQ6ZIMEA.js.map
|
|
421
|
+
//# sourceMappingURL=chunk-AQ6ZIMEA.js.map
|