@logixjs/core 0.0.1 → 1.0.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/LICENSE +201 -0
- package/dist/{Action-mqVvtEHt.d.ts → Action-DYl88bwj.d.ts} +1 -1
- package/dist/{Action-BkRHy2vg.d.cts → Action-DkxsI_DK.d.cts} +1 -1
- package/dist/Action.cjs.map +1 -1
- package/dist/Action.d.cts +1 -1
- package/dist/Action.d.ts +1 -1
- package/dist/Action.js +2 -2
- package/dist/{Actions-AsQ07yTP.d.cts → Actions-Dicm7jdc.d.cts} +2 -2
- package/dist/{Actions-AsQ07yTP.d.ts → Actions-Dicm7jdc.d.ts} +2 -2
- package/dist/Actions.cjs.map +1 -1
- package/dist/Actions.d.cts +1 -1
- package/dist/Actions.d.ts +1 -1
- package/dist/Actions.js +1 -1
- package/dist/{Bound-BN1DQ_lM.d.ts → Bound-1OJLzVIS.d.ts} +2 -2
- package/dist/{Bound-BPIfH9SS.d.cts → Bound-BMLrtQ1V.d.cts} +2 -2
- package/dist/Bound.cjs +1737 -399
- package/dist/Bound.cjs.map +1 -1
- package/dist/Bound.d.cts +5 -5
- package/dist/Bound.d.ts +5 -5
- package/dist/Bound.js +19 -17
- package/dist/{Debug-B5q5Bkzx.d.ts → Debug-DKrWP5H1.d.ts} +40 -22
- package/dist/{Debug-Bq8Sqjcr.d.cts → Debug-hIT44XsY.d.cts} +40 -22
- package/dist/Debug.cjs +1348 -318
- package/dist/Debug.cjs.map +1 -1
- package/dist/Debug.d.cts +12 -11
- package/dist/Debug.d.ts +12 -11
- package/dist/Debug.js +20 -11
- package/dist/EffectOp.cjs +15 -6
- package/dist/EffectOp.cjs.map +1 -1
- package/dist/EffectOp.js +3 -3
- package/dist/Env.cjs +772 -6
- package/dist/Env.cjs.map +1 -1
- package/dist/Env.js +5 -2
- package/dist/ExternalStore-DqJKKRJ4.d.ts +61 -0
- package/dist/ExternalStore-JC-gAgEI.d.cts +61 -0
- package/dist/ExternalStore.cjs +774 -0
- package/dist/ExternalStore.cjs.map +1 -0
- package/dist/ExternalStore.d.cts +8 -0
- package/dist/ExternalStore.d.ts +8 -0
- package/dist/ExternalStore.js +19 -0
- package/dist/ExternalStore.js.map +1 -0
- package/dist/{Flow-BhpjE22E.d.ts → Flow-CZmXRDqp.d.cts} +13 -4
- package/dist/{Flow-1fZT8MpX.d.cts → Flow-DIVDxz7R.d.ts} +13 -4
- package/dist/Flow.cjs +765 -148
- package/dist/Flow.cjs.map +1 -1
- package/dist/Flow.d.cts +6 -6
- package/dist/Flow.d.ts +6 -6
- package/dist/Flow.js +9 -8
- package/dist/{Handle-D_cLW1Z3.d.ts → Handle-Bo6cAFut.d.ts} +1 -1
- package/dist/{Handle-D8D1zPb_.d.cts → Handle-CfDvSqN7.d.cts} +1 -1
- package/dist/Handle.d.cts +5 -5
- package/dist/Handle.d.ts +5 -5
- package/dist/{Kernel-8kC-jOda.d.cts → Kernel-CuXBF9S_.d.cts} +16 -7
- package/dist/{Kernel-CnGE1Fyk.d.ts → Kernel-D9guNwRL.d.ts} +16 -7
- package/dist/Kernel.cjs +814 -26
- package/dist/Kernel.cjs.map +1 -1
- package/dist/Kernel.d.cts +13 -12
- package/dist/Kernel.d.ts +13 -12
- package/dist/Kernel.js +7 -4
- package/dist/{Link-Db7975nU.d.ts → Link-CUM0yUCH.d.ts} +10 -3
- package/dist/{Link-fX8x1eCK.d.cts → Link-NAfR6uGD.d.cts} +10 -3
- package/dist/Link.cjs +1294 -121
- package/dist/Link.cjs.map +1 -1
- package/dist/Link.d.cts +5 -5
- package/dist/Link.d.ts +5 -5
- package/dist/Link.js +37 -29
- package/dist/{Logic-DRh4sDZj.d.cts → Logic-09VQpIj3.d.cts} +7 -4
- package/dist/{Logic-BRjEMr-W.d.ts → Logic-DKg7ghGy.d.ts} +7 -4
- package/dist/Logic.cjs +2 -1
- package/dist/Logic.cjs.map +1 -1
- package/dist/Logic.d.cts +5 -5
- package/dist/Logic.d.ts +5 -5
- package/dist/Logic.js +1 -1
- package/dist/{MatchBuilder-CJk5oCkR.d.cts → MatchBuilder-CsW5jgrL.d.ts} +1 -1
- package/dist/{MatchBuilder-0QOc-nlU.d.ts → MatchBuilder-Dksk07F4.d.cts} +1 -1
- package/dist/MatchBuilder.cjs +2 -2
- package/dist/MatchBuilder.cjs.map +1 -1
- package/dist/MatchBuilder.d.cts +6 -6
- package/dist/MatchBuilder.d.ts +6 -6
- package/dist/MatchBuilder.js +2 -2
- package/dist/Middleware-D8tUDLv_.d.cts +100 -0
- package/dist/Middleware-DS7CbTTN.d.ts +100 -0
- package/dist/Middleware.cjs +678 -58
- package/dist/Middleware.cjs.map +1 -1
- package/dist/Middleware.d.cts +2 -86
- package/dist/Middleware.d.ts +2 -86
- package/dist/Middleware.js +15 -12
- package/dist/{Module-DnzluX2J.d.ts → Module-B_Cntyms.d.ts} +54 -25
- package/dist/{Module-B_0xRDMR.d.cts → Module-CmNOVXzf.d.cts} +54 -25
- package/dist/Module.cjs +9331 -3317
- package/dist/Module.cjs.map +1 -1
- package/dist/Module.d.cts +7 -6
- package/dist/Module.d.ts +7 -6
- package/dist/Module.js +39 -31
- package/dist/ModuleTag-CGho_InD.d.ts +113 -0
- package/dist/ModuleTag-CITb8L_G.d.cts +113 -0
- package/dist/ModuleTag.cjs +7248 -2847
- package/dist/ModuleTag.cjs.map +1 -1
- package/dist/ModuleTag.d.cts +6 -6
- package/dist/ModuleTag.d.ts +6 -6
- package/dist/ModuleTag.js +35 -29
- package/dist/Observability-Bdhnx2Dv.d.ts +385 -0
- package/dist/Observability-DXGAFBIT.d.cts +385 -0
- package/dist/Observability.cjs +5093 -1556
- package/dist/Observability.cjs.map +1 -1
- package/dist/Observability.d.cts +6 -7
- package/dist/Observability.d.ts +6 -7
- package/dist/Observability.js +28 -23
- package/dist/{Platform-CHX8o-U4.d.ts → Platform-B4s8tg6C.d.cts} +4 -5
- package/dist/{Platform-C49Pv956.d.cts → Platform-BV_0MW7g.d.cts} +5 -2
- package/dist/{Platform-C49Pv956.d.ts → Platform-BV_0MW7g.d.ts} +5 -2
- package/dist/{Platform-CVlv0xLQ.d.cts → Platform-W0Mefy_e.d.ts} +4 -5
- package/dist/Platform.cjs +2 -1
- package/dist/Platform.cjs.map +1 -1
- package/dist/Platform.d.cts +2 -3
- package/dist/Platform.d.ts +2 -3
- package/dist/Platform.js +2 -2
- package/dist/{Process-CM9xbMdP.d.ts → Process-CO8G7HO9.d.cts} +30 -5
- package/dist/{Process-mL8fHDSB.d.cts → Process-Cyf6VNDR.d.ts} +30 -5
- package/dist/Process.cjs +1288 -120
- package/dist/Process.cjs.map +1 -1
- package/dist/Process.d.cts +6 -6
- package/dist/Process.d.ts +6 -6
- package/dist/Process.js +34 -26
- package/dist/ReadQuery-C_or5nLC.d.ts +128 -0
- package/dist/ReadQuery-DXLzCE0E.d.cts +614 -0
- package/dist/ReadQuery-DXLzCE0E.d.ts +614 -0
- package/dist/ReadQuery-Yve1lmUo.d.cts +128 -0
- package/dist/ReadQuery.cjs +290 -5
- package/dist/ReadQuery.cjs.map +1 -1
- package/dist/ReadQuery.d.cts +3 -2
- package/dist/ReadQuery.d.ts +3 -2
- package/dist/ReadQuery.js +23 -5
- package/dist/{Reflection-CQnKwPXj.d.ts → Reflection-B2Xi1e4Q.d.ts} +89 -7
- package/dist/{Reflection-Kabo1mlU.d.cts → Reflection-DNB4V4_e.d.cts} +89 -7
- package/dist/Reflection.cjs +3227 -1617
- package/dist/Reflection.cjs.map +1 -1
- package/dist/Reflection.d.cts +17 -15
- package/dist/Reflection.d.ts +17 -15
- package/dist/Reflection.js +33 -25
- package/dist/{Resource-Dy1xD_DG.d.cts → Resource-pKvQQ4x5.d.cts} +3 -3
- package/dist/{Resource-Dy1xD_DG.d.ts → Resource-pKvQQ4x5.d.ts} +3 -3
- package/dist/Resource.cjs +781 -15
- package/dist/Resource.cjs.map +1 -1
- package/dist/Resource.d.cts +1 -1
- package/dist/Resource.d.ts +1 -1
- package/dist/Resource.js +6 -3
- package/dist/{Root-7ADUMk4t.d.cts → Root-CCVuFHB6.d.cts} +3 -3
- package/dist/{Root-7ADUMk4t.d.ts → Root-CCVuFHB6.d.ts} +3 -3
- package/dist/Root.cjs +786 -20
- package/dist/Root.cjs.map +1 -1
- package/dist/Root.d.cts +2 -2
- package/dist/Root.d.ts +2 -2
- package/dist/Root.js +7 -3
- package/dist/{Runtime-CtyzZG4i.d.ts → Runtime-CRmvwK4I.d.ts} +70 -14
- package/dist/{Runtime-B-aL-f29.d.cts → Runtime-C_wJM9mN.d.cts} +70 -14
- package/dist/Runtime.cjs +4942 -1601
- package/dist/Runtime.cjs.map +1 -1
- package/dist/Runtime.d.cts +17 -15
- package/dist/Runtime.d.ts +17 -15
- package/dist/Runtime.js +44 -32
- package/dist/{ScopeRegistry-D1owDNSm.d.cts → ScopeRegistry-BhYzqWri.d.cts} +6 -6
- package/dist/{ScopeRegistry-D1owDNSm.d.ts → ScopeRegistry-BhYzqWri.d.ts} +6 -6
- package/dist/ScopeRegistry.cjs +776 -10
- package/dist/ScopeRegistry.cjs.map +1 -1
- package/dist/ScopeRegistry.d.cts +1 -1
- package/dist/ScopeRegistry.d.ts +1 -1
- package/dist/ScopeRegistry.js +6 -3
- package/dist/{State-CU50R26M.d.cts → State-rNFsFPTl.d.cts} +2 -2
- package/dist/{State-CU50R26M.d.ts → State-rNFsFPTl.d.ts} +2 -2
- package/dist/State.cjs.map +1 -1
- package/dist/State.d.cts +1 -1
- package/dist/State.d.ts +1 -1
- package/dist/State.js +1 -1
- package/dist/{StateTrait-BGsZghTz.d.ts → StateTrait-CijdwNb6.d.ts} +25 -8
- package/dist/{StateTrait-OWhbj12c.d.cts → StateTrait-Dltto6PU.d.cts} +25 -8
- package/dist/StateTrait.cjs +1890 -528
- package/dist/StateTrait.cjs.map +1 -1
- package/dist/StateTrait.d.cts +9 -7
- package/dist/StateTrait.d.ts +9 -7
- package/dist/StateTrait.js +18 -14
- package/dist/{TraitLifecycle-CwV5WPFX.d.cts → TraitLifecycle-BKzDqzLu.d.cts} +2 -2
- package/dist/{TraitLifecycle-LdIWmKlg.d.ts → TraitLifecycle-Cvo94uDB.d.ts} +2 -2
- package/dist/TraitLifecycle.cjs +630 -67
- package/dist/TraitLifecycle.cjs.map +1 -1
- package/dist/TraitLifecycle.d.cts +6 -6
- package/dist/TraitLifecycle.d.ts +6 -6
- package/dist/TraitLifecycle.js +8 -7
- package/dist/Workflow-C_OWr4dV.d.ts +415 -0
- package/dist/Workflow-DmydkHO8.d.cts +415 -0
- package/dist/Workflow.cjs +3150 -0
- package/dist/Workflow.cjs.map +1 -0
- package/dist/Workflow.d.cts +7 -0
- package/dist/Workflow.d.ts +7 -0
- package/dist/Workflow.js +58 -0
- package/dist/Workflow.js.map +1 -0
- package/dist/{action-DiMDD_0v.d.cts → action-BQxjPFEw.d.cts} +5 -5
- package/dist/{action-DiMDD_0v.d.ts → action-BQxjPFEw.d.ts} +5 -5
- package/dist/chunk-2XRLXDWR.js +276 -0
- package/dist/chunk-2XRLXDWR.js.map +1 -0
- package/dist/chunk-3L6QGFMM.js +701 -0
- package/dist/chunk-3L6QGFMM.js.map +1 -0
- package/dist/{chunk-GMPEOUP2.js → chunk-4MZ7BT3R.js} +2 -2
- package/dist/chunk-4MZ7BT3R.js.map +1 -0
- package/dist/{chunk-3IYZ5IGG.js → chunk-5WKUGEBY.js} +2 -2
- package/dist/{chunk-3RMKLXHX.js → chunk-63ZQ5RIN.js} +2 -2
- package/dist/{chunk-M3WTHJHJ.js → chunk-67DIEA53.js} +385 -148
- package/dist/chunk-67DIEA53.js.map +1 -0
- package/dist/{chunk-YS3AZQ2G.js → chunk-6HFAW2MH.js} +1 -1
- package/dist/chunk-6HFAW2MH.js.map +1 -0
- package/dist/{chunk-EY4NZKDR.js → chunk-6Y2TKCNY.js} +2 -2
- package/dist/{chunk-76WT3HOR.js → chunk-6YZOXFPQ.js} +25 -24
- package/dist/chunk-6YZOXFPQ.js.map +1 -0
- package/dist/{chunk-G5ZBFPNU.js → chunk-A2RQOJC7.js} +2 -2
- package/dist/{chunk-AUIR5O6W.js → chunk-AFSB6NKM.js} +13 -19
- package/dist/chunk-AFSB6NKM.js.map +1 -0
- package/dist/{chunk-JCXGZRMU.js → chunk-AO4JEOKD.js} +22 -23
- package/dist/chunk-AO4JEOKD.js.map +1 -0
- package/dist/{chunk-TAAPQVZN.js → chunk-AYELIQXR.js} +2 -2
- package/dist/{chunk-QMM6O4CD.js → chunk-BLHZW7DG.js} +15 -3
- package/dist/{chunk-QMM6O4CD.js.map → chunk-BLHZW7DG.js.map} +1 -1
- package/dist/{chunk-TQOBJYDP.js → chunk-CD4N74YC.js} +1 -1
- package/dist/chunk-CD4N74YC.js.map +1 -0
- package/dist/{chunk-ANLBCBDC.js → chunk-CGE2HBTH.js} +11 -11
- package/dist/chunk-CGE2HBTH.js.map +1 -0
- package/dist/{chunk-OFADUJWJ.js → chunk-CYYSQMLO.js} +5 -5
- package/dist/chunk-CYYSQMLO.js.map +1 -0
- package/dist/{chunk-66ALHVEX.js → chunk-EB46EYI7.js} +3 -3
- package/dist/{chunk-NZJKFF45.js → chunk-EKCDHWRK.js} +4 -4
- package/dist/chunk-EKCDHWRK.js.map +1 -0
- package/dist/{chunk-BABLDP24.js → chunk-EPQFNJU3.js} +152 -7
- package/dist/chunk-EPQFNJU3.js.map +1 -0
- package/dist/{chunk-OGWBVHB3.js → chunk-ESR6HGOY.js} +73 -14
- package/dist/chunk-ESR6HGOY.js.map +1 -0
- package/dist/{chunk-NBD3KUOZ.js → chunk-F6RP62H3.js} +150 -98
- package/dist/chunk-F6RP62H3.js.map +1 -0
- package/dist/chunk-FBYW3QDI.js +252 -0
- package/dist/chunk-FBYW3QDI.js.map +1 -0
- package/dist/{chunk-IPF7E66P.js → chunk-FYAODKVP.js} +2 -2
- package/dist/chunk-GNEN7NKO.js +908 -0
- package/dist/chunk-GNEN7NKO.js.map +1 -0
- package/dist/chunk-GWSM4KLB.js +763 -0
- package/dist/chunk-GWSM4KLB.js.map +1 -0
- package/dist/{chunk-4SO6JMZL.js → chunk-HDMXCUZL.js} +1 -1
- package/dist/chunk-HDMXCUZL.js.map +1 -0
- package/dist/{chunk-ZFY7U2FR.js → chunk-HJM5Y5NU.js} +43 -3
- package/dist/chunk-HJM5Y5NU.js.map +1 -0
- package/dist/{chunk-ZGDVUPTM.js → chunk-IOZ3VKPK.js} +129 -68
- package/dist/chunk-IOZ3VKPK.js.map +1 -0
- package/dist/{chunk-PYOE4VSI.js → chunk-IVXSVHO4.js} +303 -247
- package/dist/chunk-IVXSVHO4.js.map +1 -0
- package/dist/chunk-J3CWXIPV.js +242 -0
- package/dist/chunk-J3CWXIPV.js.map +1 -0
- package/dist/chunk-K6JQW266.js +42 -0
- package/dist/chunk-K6JQW266.js.map +1 -0
- package/dist/chunk-KMZYQF6Q.js +202 -0
- package/dist/chunk-KMZYQF6Q.js.map +1 -0
- package/dist/{chunk-JWOYLO27.js → chunk-LPPZDFTD.js} +22 -12
- package/dist/chunk-LPPZDFTD.js.map +1 -0
- package/dist/{chunk-PAYXCY6A.js → chunk-MYB2B5WX.js} +997 -576
- package/dist/chunk-MYB2B5WX.js.map +1 -0
- package/dist/chunk-MYKNINNN.js +228 -0
- package/dist/chunk-MYKNINNN.js.map +1 -0
- package/dist/chunk-NSQIRMVF.js +27 -0
- package/dist/{chunk-QCHIQWAJ.js.map → chunk-NSQIRMVF.js.map} +1 -1
- package/dist/chunk-NUDBM4MM.js +30 -0
- package/dist/chunk-NUDBM4MM.js.map +1 -0
- package/dist/chunk-NZMWWDAY.js +23 -0
- package/dist/chunk-NZMWWDAY.js.map +1 -0
- package/dist/{chunk-RNFE3ML2.js → chunk-OCUV2Y25.js} +4 -3
- package/dist/chunk-OCUV2Y25.js.map +1 -0
- package/dist/chunk-P4ZJOQA7.js +271 -0
- package/dist/chunk-P4ZJOQA7.js.map +1 -0
- package/dist/chunk-P6C5EZ3D.js +342 -0
- package/dist/chunk-P6C5EZ3D.js.map +1 -0
- package/dist/{chunk-CW6T36TN.js → chunk-PBD7BJUN.js} +62 -4
- package/dist/chunk-PBD7BJUN.js.map +1 -0
- package/dist/chunk-PBIUCQY3.js +696 -0
- package/dist/chunk-PBIUCQY3.js.map +1 -0
- package/dist/chunk-PD6YECQH.js +845 -0
- package/dist/chunk-PD6YECQH.js.map +1 -0
- package/dist/{chunk-M7IYCTJV.js → chunk-R4LFQGP3.js} +2 -2
- package/dist/chunk-RHJIGDUE.js +21 -0
- package/dist/chunk-RHJIGDUE.js.map +1 -0
- package/dist/{chunk-KP7MUZNX.js → chunk-RLXO27MW.js} +30 -8
- package/dist/chunk-RLXO27MW.js.map +1 -0
- package/dist/{chunk-DFNM3WX2.js → chunk-S44BEV4B.js} +168 -45
- package/dist/chunk-S44BEV4B.js.map +1 -0
- package/dist/chunk-S4S5N4BJ.js +1461 -0
- package/dist/chunk-S4S5N4BJ.js.map +1 -0
- package/dist/{chunk-BZ2SHDN2.js → chunk-SGTRAXXX.js} +3 -3
- package/dist/chunk-SGTRAXXX.js.map +1 -0
- package/dist/{chunk-M2RGJPXX.js → chunk-SJAE5PB5.js} +3 -3
- package/dist/{chunk-JGIWG6SR.js → chunk-SNPNHU3H.js} +3937 -1776
- package/dist/chunk-SNPNHU3H.js.map +1 -0
- package/dist/{chunk-IHVBV5C2.js → chunk-SOOBFXRR.js} +94 -71
- package/dist/chunk-SOOBFXRR.js.map +1 -0
- package/dist/{chunk-ZDTRWK5F.js → chunk-TAHFWKS6.js} +2 -2
- package/dist/chunk-UEFFTVPY.js +9 -0
- package/dist/chunk-UEFFTVPY.js.map +1 -0
- package/dist/{chunk-24VULZ7A.js → chunk-UR5BXLBP.js} +3 -3
- package/dist/chunk-UR5BXLBP.js.map +1 -0
- package/dist/{chunk-DMBALCE2.js → chunk-V2SBGVDO.js} +471 -186
- package/dist/chunk-V2SBGVDO.js.map +1 -0
- package/dist/chunk-VJLWD47W.js +23 -0
- package/dist/chunk-VJLWD47W.js.map +1 -0
- package/dist/{chunk-4CQAV7YB.js → chunk-W647DX5Z.js} +2 -2
- package/dist/{chunk-THATMZXD.js → chunk-WFIIU3YZ.js} +2 -2
- package/dist/{chunk-THATMZXD.js.map → chunk-WFIIU3YZ.js.map} +1 -1
- package/dist/chunk-YZDJMAKL.js +82 -0
- package/dist/chunk-YZDJMAKL.js.map +1 -0
- package/dist/{chunk-3TMODYZV.js → chunk-Z5XH6VHY.js} +5 -5
- package/dist/chunk-Z5XH6VHY.js.map +1 -0
- package/dist/{chunk-BE3HW4FY.js → chunk-ZBBMZMA6.js} +377 -170
- package/dist/chunk-ZBBMZMA6.js.map +1 -0
- package/dist/index.cjs +21224 -11714
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +195 -49
- package/dist/index.d.ts +195 -49
- package/dist/index.js +150 -74
- package/dist/index.js.map +1 -1
- package/dist/{ir-BMP7yxJJ.d.cts → ir-BSosEwc8.d.cts} +1 -1
- package/dist/{ir-DUOz6H-5.d.ts → ir-D-uqwL_4.d.ts} +1 -1
- package/dist/{module-B8CBqIZ_.d.cts → module-Ds4tarcI.d.cts} +230 -140
- package/dist/{module-k7m3txak.d.ts → module-Zd1Gn-Nj.d.ts} +230 -140
- package/package.json +20 -4
- package/dist/ModuleTag-C8FHY_sY.d.ts +0 -93
- package/dist/ModuleTag-EGbgBMpZ.d.cts +0 -93
- package/dist/Observability-COqEvp2C.d.cts +0 -713
- package/dist/Observability-cY4kLn0S.d.ts +0 -713
- package/dist/ReadQuery-BlMwhe-F.d.ts +0 -30
- package/dist/ReadQuery-CL5XlXts.d.cts +0 -30
- package/dist/ReadQuery-SinbStGF.d.cts +0 -38
- package/dist/ReadQuery-SinbStGF.d.ts +0 -38
- package/dist/chunk-24VULZ7A.js.map +0 -1
- package/dist/chunk-3QMIVH35.js +0 -43
- package/dist/chunk-3QMIVH35.js.map +0 -1
- package/dist/chunk-3TMODYZV.js.map +0 -1
- package/dist/chunk-4SO6JMZL.js.map +0 -1
- package/dist/chunk-76WT3HOR.js.map +0 -1
- package/dist/chunk-ANLBCBDC.js.map +0 -1
- package/dist/chunk-AUIR5O6W.js.map +0 -1
- package/dist/chunk-BABLDP24.js.map +0 -1
- package/dist/chunk-BE3HW4FY.js.map +0 -1
- package/dist/chunk-BZ2SHDN2.js.map +0 -1
- package/dist/chunk-CW6T36TN.js.map +0 -1
- package/dist/chunk-DFNM3WX2.js.map +0 -1
- package/dist/chunk-DMBALCE2.js.map +0 -1
- package/dist/chunk-EGK3KN7B.js +0 -406
- package/dist/chunk-EGK3KN7B.js.map +0 -1
- package/dist/chunk-GMPEOUP2.js.map +0 -1
- package/dist/chunk-IHVBV5C2.js.map +0 -1
- package/dist/chunk-JCXGZRMU.js.map +0 -1
- package/dist/chunk-JGIWG6SR.js.map +0 -1
- package/dist/chunk-JWOYLO27.js.map +0 -1
- package/dist/chunk-KIXAU3GM.js +0 -137
- package/dist/chunk-KIXAU3GM.js.map +0 -1
- package/dist/chunk-KL5ACTCT.js +0 -8
- package/dist/chunk-KL5ACTCT.js.map +0 -1
- package/dist/chunk-KP7MUZNX.js.map +0 -1
- package/dist/chunk-M3BFQ7HK.js +0 -13
- package/dist/chunk-M3BFQ7HK.js.map +0 -1
- package/dist/chunk-M3WTHJHJ.js.map +0 -1
- package/dist/chunk-NBD3KUOZ.js.map +0 -1
- package/dist/chunk-NQZ2OSGR.js +0 -151
- package/dist/chunk-NQZ2OSGR.js.map +0 -1
- package/dist/chunk-NZJKFF45.js.map +0 -1
- package/dist/chunk-OFADUJWJ.js.map +0 -1
- package/dist/chunk-OGWBVHB3.js.map +0 -1
- package/dist/chunk-PAYXCY6A.js.map +0 -1
- package/dist/chunk-PYOE4VSI.js.map +0 -1
- package/dist/chunk-QCHIQWAJ.js +0 -21
- package/dist/chunk-RNFE3ML2.js.map +0 -1
- package/dist/chunk-TKZ7MEIA.js +0 -27
- package/dist/chunk-TKZ7MEIA.js.map +0 -1
- package/dist/chunk-TQOBJYDP.js.map +0 -1
- package/dist/chunk-VZB726PE.js +0 -93
- package/dist/chunk-VZB726PE.js.map +0 -1
- package/dist/chunk-W3TEWHLO.js +0 -568
- package/dist/chunk-W3TEWHLO.js.map +0 -1
- package/dist/chunk-YS3AZQ2G.js.map +0 -1
- package/dist/chunk-ZFLHVFUC.js +0 -192
- package/dist/chunk-ZFLHVFUC.js.map +0 -1
- package/dist/chunk-ZFY7U2FR.js.map +0 -1
- package/dist/chunk-ZGDVUPTM.js.map +0 -1
- package/dist/protocol-g_1897M2.d.cts +0 -127
- package/dist/protocol-g_1897M2.d.ts +0 -127
- /package/dist/{chunk-3IYZ5IGG.js.map → chunk-5WKUGEBY.js.map} +0 -0
- /package/dist/{chunk-3RMKLXHX.js.map → chunk-63ZQ5RIN.js.map} +0 -0
- /package/dist/{chunk-EY4NZKDR.js.map → chunk-6Y2TKCNY.js.map} +0 -0
- /package/dist/{chunk-G5ZBFPNU.js.map → chunk-A2RQOJC7.js.map} +0 -0
- /package/dist/{chunk-TAAPQVZN.js.map → chunk-AYELIQXR.js.map} +0 -0
- /package/dist/{chunk-66ALHVEX.js.map → chunk-EB46EYI7.js.map} +0 -0
- /package/dist/{chunk-IPF7E66P.js.map → chunk-FYAODKVP.js.map} +0 -0
- /package/dist/{chunk-M7IYCTJV.js.map → chunk-R4LFQGP3.js.map} +0 -0
- /package/dist/{chunk-M2RGJPXX.js.map → chunk-SJAE5PB5.js.map} +0 -0
- /package/dist/{chunk-ZDTRWK5F.js.map → chunk-TAHFWKS6.js.map} +0 -0
- /package/dist/{chunk-4CQAV7YB.js.map → chunk-W647DX5Z.js.map} +0 -0
|
@@ -0,0 +1,3150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/Workflow.ts
|
|
21
|
+
var Workflow_exports = {};
|
|
22
|
+
__export(Workflow_exports, {
|
|
23
|
+
KernelPorts: () => KernelPorts,
|
|
24
|
+
call: () => call,
|
|
25
|
+
callById: () => callById,
|
|
26
|
+
compose: () => compose,
|
|
27
|
+
constValue: () => constValue,
|
|
28
|
+
delay: () => delay,
|
|
29
|
+
dispatch: () => dispatch,
|
|
30
|
+
forModule: () => forModule,
|
|
31
|
+
fragment: () => fragment,
|
|
32
|
+
fromJSON: () => fromJSON,
|
|
33
|
+
make: () => make2,
|
|
34
|
+
merge: () => merge,
|
|
35
|
+
object: () => object,
|
|
36
|
+
onAction: () => onAction,
|
|
37
|
+
onInit: () => onInit,
|
|
38
|
+
onStart: () => onStart,
|
|
39
|
+
payload: () => payload,
|
|
40
|
+
payloadPath: () => payloadPath,
|
|
41
|
+
withPolicy: () => withPolicy
|
|
42
|
+
});
|
|
43
|
+
module.exports = __toCommonJS(Workflow_exports);
|
|
44
|
+
var import_effect15 = require("effect");
|
|
45
|
+
|
|
46
|
+
// src/internal/serviceId.ts
|
|
47
|
+
var import_effect = require("effect");
|
|
48
|
+
var asNonEmptyString = (value) => typeof value === "string" && value.length > 0 ? value : void 0;
|
|
49
|
+
var fromTag = (tag) => {
|
|
50
|
+
const anyTag = tag;
|
|
51
|
+
return asNonEmptyString(anyTag.key) ?? asNonEmptyString(anyTag.id) ?? asNonEmptyString(anyTag._id);
|
|
52
|
+
};
|
|
53
|
+
var tagCache = /* @__PURE__ */ new Map();
|
|
54
|
+
var tagFromServiceId = (serviceId) => {
|
|
55
|
+
const cached = tagCache.get(serviceId);
|
|
56
|
+
if (cached) return cached;
|
|
57
|
+
const created = import_effect.ServiceMap.Service(serviceId);
|
|
58
|
+
tagCache.set(serviceId, created);
|
|
59
|
+
return created;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
// src/internal/digest.ts
|
|
63
|
+
var stableStringify = (value) => {
|
|
64
|
+
if (value === null) return "null";
|
|
65
|
+
const t = typeof value;
|
|
66
|
+
if (t === "string") return JSON.stringify(value);
|
|
67
|
+
if (t === "number") return Number.isFinite(value) ? String(value) : "null";
|
|
68
|
+
if (t === "boolean") return value ? "true" : "false";
|
|
69
|
+
if (Array.isArray(value)) {
|
|
70
|
+
return `[${value.map(stableStringify).join(",")}]`;
|
|
71
|
+
}
|
|
72
|
+
if (t === "object") {
|
|
73
|
+
const record2 = value;
|
|
74
|
+
const keys = Object.keys(record2).sort();
|
|
75
|
+
return `{${keys.map((k) => `${JSON.stringify(k)}:${stableStringify(record2[k])}`).join(",")}}`;
|
|
76
|
+
}
|
|
77
|
+
return "null";
|
|
78
|
+
};
|
|
79
|
+
var fnv1a32 = (input) => {
|
|
80
|
+
let hash = 2166136261;
|
|
81
|
+
for (let i = 0; i < input.length; i++) {
|
|
82
|
+
hash ^= input.charCodeAt(i);
|
|
83
|
+
hash = hash * 16777619 >>> 0;
|
|
84
|
+
}
|
|
85
|
+
return hash.toString(16).padStart(8, "0");
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
// src/internal/observability/jsonValue.ts
|
|
89
|
+
var isJsonValue = (input) => {
|
|
90
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
91
|
+
const loop = (value, depth) => {
|
|
92
|
+
if (depth > 64) return false;
|
|
93
|
+
if (value === null) return true;
|
|
94
|
+
switch (typeof value) {
|
|
95
|
+
case "string":
|
|
96
|
+
case "boolean":
|
|
97
|
+
return true;
|
|
98
|
+
case "number":
|
|
99
|
+
return Number.isFinite(value);
|
|
100
|
+
case "object": {
|
|
101
|
+
if (Array.isArray(value)) {
|
|
102
|
+
if (seen.has(value)) return false;
|
|
103
|
+
seen.add(value);
|
|
104
|
+
for (const item of value) {
|
|
105
|
+
if (!loop(item, depth + 1)) return false;
|
|
106
|
+
}
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
if (!isPlainRecord(value)) return false;
|
|
110
|
+
if (seen.has(value)) return false;
|
|
111
|
+
seen.add(value);
|
|
112
|
+
for (const v of Object.values(value)) {
|
|
113
|
+
if (!loop(v, depth + 1)) return false;
|
|
114
|
+
}
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
default:
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
return loop(input, 0);
|
|
122
|
+
};
|
|
123
|
+
var defaultOptions = {
|
|
124
|
+
maxDepth: 6,
|
|
125
|
+
maxObjectKeys: 32,
|
|
126
|
+
maxArrayLength: 32,
|
|
127
|
+
maxStringLength: 256,
|
|
128
|
+
maxJsonBytes: 4 * 1024,
|
|
129
|
+
oversizedPreviewBytes: 256
|
|
130
|
+
};
|
|
131
|
+
var truncateString = (value, maxLen, stats) => {
|
|
132
|
+
if (value.length <= maxLen) return value;
|
|
133
|
+
stats.oversized += 1;
|
|
134
|
+
return value.slice(0, maxLen);
|
|
135
|
+
};
|
|
136
|
+
var mergeDowngrade = (current, next) => {
|
|
137
|
+
if (!current) return next;
|
|
138
|
+
if (current === "non_serializable" || next === "non_serializable") return "non_serializable";
|
|
139
|
+
if (current === "oversized" || next === "oversized") return "oversized";
|
|
140
|
+
return "unknown";
|
|
141
|
+
};
|
|
142
|
+
function isPlainRecord(value) {
|
|
143
|
+
if (typeof value !== "object" || value === null) return false;
|
|
144
|
+
const proto = Object.getPrototypeOf(value);
|
|
145
|
+
return proto === Object.prototype || proto === null;
|
|
146
|
+
}
|
|
147
|
+
var asNumber = (value, stats) => {
|
|
148
|
+
if (Number.isFinite(value)) return value;
|
|
149
|
+
stats.nonSerializable += 1;
|
|
150
|
+
return String(value);
|
|
151
|
+
};
|
|
152
|
+
var toJsonValueInternal = (input, options, stats, seen, depth) => {
|
|
153
|
+
if (input === null) return null;
|
|
154
|
+
switch (typeof input) {
|
|
155
|
+
case "string":
|
|
156
|
+
return truncateString(input, options.maxStringLength, stats);
|
|
157
|
+
case "number":
|
|
158
|
+
return asNumber(input, stats);
|
|
159
|
+
case "boolean":
|
|
160
|
+
return input;
|
|
161
|
+
case "bigint":
|
|
162
|
+
stats.nonSerializable += 1;
|
|
163
|
+
return truncateString(input.toString(), options.maxStringLength, stats);
|
|
164
|
+
case "symbol":
|
|
165
|
+
stats.nonSerializable += 1;
|
|
166
|
+
return truncateString(input.toString(), options.maxStringLength, stats);
|
|
167
|
+
case "function":
|
|
168
|
+
stats.nonSerializable += 1;
|
|
169
|
+
return "[Function]";
|
|
170
|
+
case "undefined":
|
|
171
|
+
stats.dropped += 1;
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
if (depth >= options.maxDepth) {
|
|
175
|
+
stats.oversized += 1;
|
|
176
|
+
return "[Truncated]";
|
|
177
|
+
}
|
|
178
|
+
if (input instanceof Date) {
|
|
179
|
+
return input.toISOString();
|
|
180
|
+
}
|
|
181
|
+
if (input instanceof Error) {
|
|
182
|
+
stats.nonSerializable += 1;
|
|
183
|
+
return {
|
|
184
|
+
name: truncateString(input.name, options.maxStringLength, stats),
|
|
185
|
+
message: truncateString(input.message, options.maxStringLength, stats)
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
if (typeof input === "object") {
|
|
189
|
+
if (seen.has(input)) {
|
|
190
|
+
stats.nonSerializable += 1;
|
|
191
|
+
return "[Circular]";
|
|
192
|
+
}
|
|
193
|
+
seen.add(input);
|
|
194
|
+
}
|
|
195
|
+
if (Array.isArray(input)) {
|
|
196
|
+
const out2 = [];
|
|
197
|
+
const limit2 = Math.min(input.length, options.maxArrayLength);
|
|
198
|
+
for (let i = 0; i < limit2; i++) {
|
|
199
|
+
out2.push(toJsonValueInternal(input[i], options, stats, seen, depth + 1));
|
|
200
|
+
}
|
|
201
|
+
if (input.length > limit2) {
|
|
202
|
+
stats.oversized += 1;
|
|
203
|
+
out2.push(`[...${input.length - limit2} more]`);
|
|
204
|
+
}
|
|
205
|
+
return out2;
|
|
206
|
+
}
|
|
207
|
+
if (!isPlainRecord(input)) {
|
|
208
|
+
stats.nonSerializable += 1;
|
|
209
|
+
return truncateString(String(input), options.maxStringLength, stats);
|
|
210
|
+
}
|
|
211
|
+
const keys = Object.keys(input).sort();
|
|
212
|
+
const limit = Math.min(keys.length, options.maxObjectKeys);
|
|
213
|
+
const out = {};
|
|
214
|
+
for (let i = 0; i < limit; i++) {
|
|
215
|
+
const rawKey = keys[i];
|
|
216
|
+
const rawValue = input[rawKey];
|
|
217
|
+
const key = truncateString(rawKey, options.maxStringLength, stats);
|
|
218
|
+
if (rawValue === void 0) {
|
|
219
|
+
stats.dropped += 1;
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
out[key] = toJsonValueInternal(rawValue, options, stats, seen, depth + 1);
|
|
223
|
+
}
|
|
224
|
+
if (keys.length > limit) {
|
|
225
|
+
stats.oversized += 1;
|
|
226
|
+
out.__truncatedKeys = keys.length - limit;
|
|
227
|
+
}
|
|
228
|
+
return out;
|
|
229
|
+
};
|
|
230
|
+
var projectJsonValue = (input, options) => {
|
|
231
|
+
const resolved = { ...defaultOptions, ...options ?? {} };
|
|
232
|
+
const stats = { dropped: 0, oversized: 0, nonSerializable: 0 };
|
|
233
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
234
|
+
let downgrade;
|
|
235
|
+
const value = toJsonValueInternal(input, resolved, stats, seen, 0);
|
|
236
|
+
if (stats.nonSerializable > 0) {
|
|
237
|
+
downgrade = mergeDowngrade(downgrade, "non_serializable");
|
|
238
|
+
}
|
|
239
|
+
if (stats.oversized > 0) {
|
|
240
|
+
downgrade = mergeDowngrade(downgrade, "oversized");
|
|
241
|
+
}
|
|
242
|
+
try {
|
|
243
|
+
const json = JSON.stringify(value);
|
|
244
|
+
if (json.length > resolved.maxJsonBytes) {
|
|
245
|
+
downgrade = mergeDowngrade(downgrade, "oversized");
|
|
246
|
+
const preview = json.slice(0, Math.min(resolved.oversizedPreviewBytes, resolved.maxJsonBytes));
|
|
247
|
+
return {
|
|
248
|
+
value: {
|
|
249
|
+
_tag: "oversized",
|
|
250
|
+
bytes: json.length,
|
|
251
|
+
preview
|
|
252
|
+
},
|
|
253
|
+
stats: {
|
|
254
|
+
dropped: stats.dropped,
|
|
255
|
+
oversized: stats.oversized + 1,
|
|
256
|
+
nonSerializable: stats.nonSerializable
|
|
257
|
+
},
|
|
258
|
+
downgrade
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
} catch {
|
|
262
|
+
downgrade = mergeDowngrade(downgrade, "non_serializable");
|
|
263
|
+
return {
|
|
264
|
+
value: "[Unserializable]",
|
|
265
|
+
stats: {
|
|
266
|
+
dropped: stats.dropped,
|
|
267
|
+
oversized: stats.oversized,
|
|
268
|
+
nonSerializable: stats.nonSerializable + 1
|
|
269
|
+
},
|
|
270
|
+
downgrade
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
return {
|
|
274
|
+
value,
|
|
275
|
+
stats: {
|
|
276
|
+
dropped: stats.dropped,
|
|
277
|
+
oversized: stats.oversized,
|
|
278
|
+
nonSerializable: stats.nonSerializable
|
|
279
|
+
},
|
|
280
|
+
downgrade
|
|
281
|
+
};
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
// src/internal/workflow/errors.ts
|
|
285
|
+
var toJsonValue = (detail) => {
|
|
286
|
+
if (isJsonValue(detail)) return detail;
|
|
287
|
+
return projectJsonValue(detail).value;
|
|
288
|
+
};
|
|
289
|
+
var makeWorkflowError = (args) => {
|
|
290
|
+
const detailJson = args.detail !== void 0 ? toJsonValue(args.detail) : void 0;
|
|
291
|
+
const msg = args.detail !== void 0 ? `${args.message}
|
|
292
|
+
(detail=${stableStringify(detailJson)})` : args.message;
|
|
293
|
+
return Object.assign(new Error(msg), {
|
|
294
|
+
_tag: "WorkflowError",
|
|
295
|
+
code: args.code,
|
|
296
|
+
programId: args.programId,
|
|
297
|
+
source: args.source,
|
|
298
|
+
detail: detailJson
|
|
299
|
+
});
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
// src/internal/workflow/inputExpr.ts
|
|
303
|
+
var decodePointerToken = (raw) => raw.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
304
|
+
var isIndexToken = (token) => token === "0" || !token.startsWith("0") && /^\d+$/.test(token);
|
|
305
|
+
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
306
|
+
var parseJsonPointer = (pointer) => {
|
|
307
|
+
if (pointer === "") return [];
|
|
308
|
+
if (!pointer.startsWith("/")) {
|
|
309
|
+
throw makeWorkflowError({
|
|
310
|
+
code: "WORKFLOW_INVALID_JSON_POINTER",
|
|
311
|
+
message: 'Invalid JSON Pointer (must be "" or start with "/").',
|
|
312
|
+
detail: { pointer }
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
const raw = pointer.split("/").slice(1);
|
|
316
|
+
const out = [];
|
|
317
|
+
for (const part of raw) {
|
|
318
|
+
const decoded = decodePointerToken(part);
|
|
319
|
+
out.push(isIndexToken(decoded) ? Number(decoded) : decoded);
|
|
320
|
+
}
|
|
321
|
+
return out;
|
|
322
|
+
};
|
|
323
|
+
var compileInputExpr = (expr, pathForError) => {
|
|
324
|
+
switch (expr.kind) {
|
|
325
|
+
case "payload":
|
|
326
|
+
return { kind: "payload" };
|
|
327
|
+
case "payload.path": {
|
|
328
|
+
const pointer = expr.pointer;
|
|
329
|
+
if (typeof pointer !== "string") {
|
|
330
|
+
throw makeWorkflowError({
|
|
331
|
+
code: "WORKFLOW_INVALID_INPUT_EXPR",
|
|
332
|
+
message: "InputExpr.payload.path.pointer must be a string.",
|
|
333
|
+
source: { stepKey: pathForError?.stepKey },
|
|
334
|
+
detail: { pointer }
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
return { kind: "payload.path", pointer, tokens: parseJsonPointer(pointer) };
|
|
338
|
+
}
|
|
339
|
+
case "const": {
|
|
340
|
+
const value = expr.value;
|
|
341
|
+
if (!isJsonValue(value)) {
|
|
342
|
+
throw makeWorkflowError({
|
|
343
|
+
code: "WORKFLOW_INVALID_INPUT_EXPR",
|
|
344
|
+
message: "InputExpr.const.value must be JSON-serializable.",
|
|
345
|
+
source: { stepKey: pathForError?.stepKey },
|
|
346
|
+
detail: { value }
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
return { kind: "const", value };
|
|
350
|
+
}
|
|
351
|
+
case "object": {
|
|
352
|
+
const fields = expr.fields;
|
|
353
|
+
if (!fields || typeof fields !== "object" || Array.isArray(fields)) {
|
|
354
|
+
throw makeWorkflowError({
|
|
355
|
+
code: "WORKFLOW_INVALID_INPUT_EXPR",
|
|
356
|
+
message: "InputExpr.object.fields must be a record.",
|
|
357
|
+
source: { stepKey: pathForError?.stepKey }
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
const entries = Object.entries(fields).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
|
|
361
|
+
return {
|
|
362
|
+
kind: "object",
|
|
363
|
+
fields: entries.map(([k, v]) => [k, compileInputExpr(v, pathForError)])
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
case "merge": {
|
|
367
|
+
const items = expr.items;
|
|
368
|
+
if (!Array.isArray(items)) {
|
|
369
|
+
throw makeWorkflowError({
|
|
370
|
+
code: "WORKFLOW_INVALID_INPUT_EXPR",
|
|
371
|
+
message: "InputExpr.merge.items must be an array.",
|
|
372
|
+
source: { stepKey: pathForError?.stepKey }
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
for (const item of items) {
|
|
376
|
+
const kind = isRecord(item) ? item.kind : void 0;
|
|
377
|
+
if (kind !== "object") {
|
|
378
|
+
throw makeWorkflowError({
|
|
379
|
+
code: "WORKFLOW_INVALID_MERGE_ITEMS",
|
|
380
|
+
message: "InputExpr.merge.items must all be InputExpr.object.",
|
|
381
|
+
source: { stepKey: pathForError?.stepKey },
|
|
382
|
+
detail: { kind }
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
return {
|
|
387
|
+
kind: "merge",
|
|
388
|
+
items: items.map((i) => compileInputExpr(i, pathForError))
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
};
|
|
393
|
+
var isPlainRecord2 = (value) => {
|
|
394
|
+
if (typeof value !== "object" || value === null) return false;
|
|
395
|
+
if (Array.isArray(value)) return false;
|
|
396
|
+
const proto = Object.getPrototypeOf(value);
|
|
397
|
+
return proto === Object.prototype || proto === null;
|
|
398
|
+
};
|
|
399
|
+
var evalPointer = (root, tokens) => {
|
|
400
|
+
let current = root;
|
|
401
|
+
for (const token of tokens) {
|
|
402
|
+
if (current == null) return void 0;
|
|
403
|
+
if (Array.isArray(current) && typeof token === "number") {
|
|
404
|
+
current = current[token];
|
|
405
|
+
continue;
|
|
406
|
+
}
|
|
407
|
+
if (typeof current !== "object") return void 0;
|
|
408
|
+
const key = typeof token === "number" ? String(token) : token;
|
|
409
|
+
current = current[key];
|
|
410
|
+
}
|
|
411
|
+
return current;
|
|
412
|
+
};
|
|
413
|
+
var evalInputExpr = (expr, payload2) => {
|
|
414
|
+
switch (expr.kind) {
|
|
415
|
+
case "payload":
|
|
416
|
+
return payload2;
|
|
417
|
+
case "payload.path":
|
|
418
|
+
return evalPointer(payload2, expr.tokens);
|
|
419
|
+
case "const":
|
|
420
|
+
return expr.value;
|
|
421
|
+
case "object": {
|
|
422
|
+
const out = {};
|
|
423
|
+
for (const [k, v] of expr.fields) {
|
|
424
|
+
out[k] = evalInputExpr(v, payload2);
|
|
425
|
+
}
|
|
426
|
+
return out;
|
|
427
|
+
}
|
|
428
|
+
case "merge": {
|
|
429
|
+
const out = {};
|
|
430
|
+
for (const item of expr.items) {
|
|
431
|
+
const value = evalInputExpr(item, payload2);
|
|
432
|
+
if (isPlainRecord2(value)) {
|
|
433
|
+
for (const [k, v] of Object.entries(value)) {
|
|
434
|
+
out[k] = v;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
return out;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
};
|
|
442
|
+
|
|
443
|
+
// src/internal/workflow/compiler.ts
|
|
444
|
+
var isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
445
|
+
var asNonEmptyString2 = (value) => typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
|
|
446
|
+
var asNonNegInt = (value) => {
|
|
447
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return void 0;
|
|
448
|
+
const n = Math.floor(value);
|
|
449
|
+
return n >= 0 ? n : void 0;
|
|
450
|
+
};
|
|
451
|
+
var asPosInt = (value) => {
|
|
452
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return void 0;
|
|
453
|
+
const n = Math.floor(value);
|
|
454
|
+
return n > 0 ? n : void 0;
|
|
455
|
+
};
|
|
456
|
+
var normalizeWorkflowDefV1 = (input) => {
|
|
457
|
+
const normalizeStep = (step) => {
|
|
458
|
+
if (!isRecord2(step)) return step;
|
|
459
|
+
if (step.kind !== "call") return step;
|
|
460
|
+
const raw = step;
|
|
461
|
+
const onSuccessRaw = Array.isArray(raw.onSuccess) ? raw.onSuccess : [];
|
|
462
|
+
const onFailureRaw = Array.isArray(raw.onFailure) ? raw.onFailure : [];
|
|
463
|
+
return {
|
|
464
|
+
...step,
|
|
465
|
+
onSuccess: onSuccessRaw.map(normalizeStep),
|
|
466
|
+
onFailure: onFailureRaw.map(normalizeStep)
|
|
467
|
+
};
|
|
468
|
+
};
|
|
469
|
+
const normalizeSteps = (steps) => steps.map(normalizeStep);
|
|
470
|
+
return {
|
|
471
|
+
...input,
|
|
472
|
+
steps: normalizeSteps(input.steps)
|
|
473
|
+
};
|
|
474
|
+
};
|
|
475
|
+
function validateWorkflowDefV1(def, options) {
|
|
476
|
+
if (!isRecord2(def)) {
|
|
477
|
+
throw makeWorkflowError({
|
|
478
|
+
code: "WORKFLOW_INVALID_DEF",
|
|
479
|
+
message: "WorkflowDef must be an object.",
|
|
480
|
+
detail: { def }
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
if (def.astVersion !== 1) {
|
|
484
|
+
throw makeWorkflowError({
|
|
485
|
+
code: "WORKFLOW_UNSUPPORTED_VERSION",
|
|
486
|
+
message: "Unsupported workflow astVersion.",
|
|
487
|
+
detail: { astVersion: def.astVersion }
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
if (!asNonEmptyString2(def.localId)) {
|
|
491
|
+
throw makeWorkflowError({
|
|
492
|
+
code: "WORKFLOW_INVALID_DEF",
|
|
493
|
+
message: "WorkflowDef.localId must be a non-empty string.",
|
|
494
|
+
detail: { localId: def.localId }
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
const trigger = def.trigger;
|
|
498
|
+
if (!isRecord2(trigger)) {
|
|
499
|
+
throw makeWorkflowError({
|
|
500
|
+
code: "WORKFLOW_INVALID_TRIGGER",
|
|
501
|
+
message: "Workflow trigger must be an object.",
|
|
502
|
+
detail: { trigger }
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
if (trigger.kind === "action") {
|
|
506
|
+
if (!asNonEmptyString2(trigger.actionTag)) {
|
|
507
|
+
throw makeWorkflowError({
|
|
508
|
+
code: "WORKFLOW_INVALID_TRIGGER",
|
|
509
|
+
message: "Workflow trigger.actionTag must be a non-empty string.",
|
|
510
|
+
detail: { trigger }
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
} else if (trigger.kind === "lifecycle") {
|
|
514
|
+
const phase = trigger.phase;
|
|
515
|
+
if (phase !== "onStart" && phase !== "onInit") {
|
|
516
|
+
throw makeWorkflowError({
|
|
517
|
+
code: "WORKFLOW_INVALID_TRIGGER",
|
|
518
|
+
message: 'Workflow trigger.phase must be "onStart" or "onInit".',
|
|
519
|
+
detail: { trigger }
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
} else {
|
|
523
|
+
throw makeWorkflowError({
|
|
524
|
+
code: "WORKFLOW_INVALID_TRIGGER",
|
|
525
|
+
message: 'Workflow trigger.kind must be "action" or "lifecycle".',
|
|
526
|
+
detail: { trigger }
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
if (!Array.isArray(def.steps)) {
|
|
530
|
+
throw makeWorkflowError({
|
|
531
|
+
code: "WORKFLOW_INVALID_DEF",
|
|
532
|
+
message: "WorkflowDef.steps must be an array.",
|
|
533
|
+
detail: { steps: def.steps }
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
const seenKeys = /* @__PURE__ */ new Set();
|
|
537
|
+
const visit = (step, fragmentId) => {
|
|
538
|
+
if (!isRecord2(step)) {
|
|
539
|
+
throw makeWorkflowError({
|
|
540
|
+
code: "WORKFLOW_INVALID_STEP",
|
|
541
|
+
message: "Workflow step must be an object.",
|
|
542
|
+
detail: { step },
|
|
543
|
+
source: fragmentId ? { fragmentId } : void 0
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
const key = asNonEmptyString2(step.key);
|
|
547
|
+
if (!key) {
|
|
548
|
+
throw makeWorkflowError({
|
|
549
|
+
code: "WORKFLOW_INVALID_STEP",
|
|
550
|
+
message: "Workflow step.key must be a non-empty string.",
|
|
551
|
+
detail: { stepKey: step.key, kind: step.kind },
|
|
552
|
+
source: fragmentId ? { fragmentId } : void 0
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
if (seenKeys.has(key)) {
|
|
556
|
+
throw makeWorkflowError({
|
|
557
|
+
code: "WORKFLOW_DUPLICATE_STEP_KEY",
|
|
558
|
+
message: `Duplicate stepKey "${key}" detected.`,
|
|
559
|
+
detail: { duplicateKey: key },
|
|
560
|
+
source: { stepKey: key, ...fragmentId ? { fragmentId } : null }
|
|
561
|
+
});
|
|
562
|
+
}
|
|
563
|
+
seenKeys.add(key);
|
|
564
|
+
if (step.kind === "dispatch") {
|
|
565
|
+
if (!asNonEmptyString2(step.actionTag)) {
|
|
566
|
+
throw makeWorkflowError({
|
|
567
|
+
code: "WORKFLOW_INVALID_STEP",
|
|
568
|
+
message: "dispatch.actionTag must be a non-empty string.",
|
|
569
|
+
source: { stepKey: key, ...fragmentId ? { fragmentId } : null },
|
|
570
|
+
detail: { actionTag: step.actionTag }
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
const payload2 = step.payload;
|
|
574
|
+
if (payload2 !== void 0) {
|
|
575
|
+
validateInputExpr(payload2, { stepKey: key });
|
|
576
|
+
}
|
|
577
|
+
return;
|
|
578
|
+
}
|
|
579
|
+
if (step.kind === "delay") {
|
|
580
|
+
const ms = asNonNegInt(step.ms);
|
|
581
|
+
if (ms === void 0) {
|
|
582
|
+
throw makeWorkflowError({
|
|
583
|
+
code: "WORKFLOW_INVALID_STEP",
|
|
584
|
+
message: "delay.ms must be a non-negative integer.",
|
|
585
|
+
source: { stepKey: key, ...fragmentId ? { fragmentId } : null },
|
|
586
|
+
detail: { ms: step.ms }
|
|
587
|
+
});
|
|
588
|
+
}
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
591
|
+
if (step.kind === "call") {
|
|
592
|
+
if (!asNonEmptyString2(step.serviceId)) {
|
|
593
|
+
throw makeWorkflowError({
|
|
594
|
+
code: "WORKFLOW_INVALID_SERVICE_ID",
|
|
595
|
+
message: "call.serviceId must be a non-empty string.",
|
|
596
|
+
source: { stepKey: key, ...fragmentId ? { fragmentId } : null },
|
|
597
|
+
detail: { serviceId: step.serviceId }
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
const inputExpr = step.input;
|
|
601
|
+
if (inputExpr !== void 0) {
|
|
602
|
+
validateInputExpr(inputExpr, { stepKey: key });
|
|
603
|
+
}
|
|
604
|
+
const timeoutMsRaw = step.timeoutMs;
|
|
605
|
+
if (timeoutMsRaw !== void 0 && asPosInt(timeoutMsRaw) === void 0) {
|
|
606
|
+
throw makeWorkflowError({
|
|
607
|
+
code: "WORKFLOW_INVALID_STEP",
|
|
608
|
+
message: "call.timeoutMs must be a positive integer (milliseconds).",
|
|
609
|
+
source: { stepKey: key, ...fragmentId ? { fragmentId } : null },
|
|
610
|
+
detail: { timeoutMs: timeoutMsRaw }
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
const retryRaw = step.retry;
|
|
614
|
+
if (retryRaw !== void 0) {
|
|
615
|
+
const times = isRecord2(retryRaw) ? asPosInt(retryRaw.times) : void 0;
|
|
616
|
+
if (times === void 0) {
|
|
617
|
+
throw makeWorkflowError({
|
|
618
|
+
code: "WORKFLOW_INVALID_STEP",
|
|
619
|
+
message: "call.retry.times must be a positive integer.",
|
|
620
|
+
source: { stepKey: key, ...fragmentId ? { fragmentId } : null },
|
|
621
|
+
detail: { retry: retryRaw }
|
|
622
|
+
});
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
const onSuccess = Array.isArray(step.onSuccess) ? step.onSuccess : [];
|
|
626
|
+
const onFailure = Array.isArray(step.onFailure) ? step.onFailure : [];
|
|
627
|
+
for (const inner of onSuccess) visit(inner, fragmentId);
|
|
628
|
+
for (const inner of onFailure) visit(inner, fragmentId);
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
631
|
+
throw makeWorkflowError({
|
|
632
|
+
code: "WORKFLOW_INVALID_STEP",
|
|
633
|
+
message: "Unknown step kind.",
|
|
634
|
+
source: { stepKey: key, ...fragmentId ? { fragmentId } : null },
|
|
635
|
+
detail: { kind: step.kind }
|
|
636
|
+
});
|
|
637
|
+
};
|
|
638
|
+
const sources = def.sources;
|
|
639
|
+
const fragmentByStepKey = /* @__PURE__ */ new Map();
|
|
640
|
+
if (sources && typeof sources === "object") {
|
|
641
|
+
for (const [k, v] of Object.entries(sources)) {
|
|
642
|
+
fragmentByStepKey.set(k, isRecord2(v) ? asNonEmptyString2(v.fragmentId) : void 0);
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
for (const step of def.steps) {
|
|
646
|
+
const key = isRecord2(step) ? asNonEmptyString2(step.key) : void 0;
|
|
647
|
+
const fragmentId = key ? fragmentByStepKey.get(key) : void 0;
|
|
648
|
+
visit(step, fragmentId);
|
|
649
|
+
}
|
|
650
|
+
const generator = isRecord2(def.meta) ? def.meta.generator : void 0;
|
|
651
|
+
if (generator !== void 0 && !isJsonValue(generator)) {
|
|
652
|
+
throw makeWorkflowError({
|
|
653
|
+
code: "WORKFLOW_INVALID_DEF",
|
|
654
|
+
message: "WorkflowDef.meta.generator must be JSON-serializable.",
|
|
655
|
+
detail: { generator }
|
|
656
|
+
});
|
|
657
|
+
}
|
|
658
|
+
const policy = isRecord2(def.policy) ? def.policy : void 0;
|
|
659
|
+
if (policy) {
|
|
660
|
+
const concurrency = policy.concurrency;
|
|
661
|
+
if (concurrency !== void 0 && concurrency !== "latest" && concurrency !== "exhaust" && concurrency !== "parallel") {
|
|
662
|
+
throw makeWorkflowError({
|
|
663
|
+
code: "WORKFLOW_INVALID_DEF",
|
|
664
|
+
message: "policy.concurrency must be latest|exhaust|parallel.",
|
|
665
|
+
detail: { concurrency }
|
|
666
|
+
});
|
|
667
|
+
}
|
|
668
|
+
const priority = policy.priority;
|
|
669
|
+
if (priority !== void 0 && priority !== "urgent" && priority !== "nonUrgent") {
|
|
670
|
+
throw makeWorkflowError({
|
|
671
|
+
code: "WORKFLOW_INVALID_DEF",
|
|
672
|
+
message: "policy.priority must be urgent|nonUrgent.",
|
|
673
|
+
detail: { priority }
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
void options?.moduleId;
|
|
678
|
+
}
|
|
679
|
+
var validateInputExpr = (expr, options) => {
|
|
680
|
+
const visit = (e) => {
|
|
681
|
+
if (!isRecord2(e)) {
|
|
682
|
+
throw makeWorkflowError({
|
|
683
|
+
code: "WORKFLOW_INVALID_INPUT_EXPR",
|
|
684
|
+
message: "InputExpr must be an object.",
|
|
685
|
+
source: { stepKey: options?.stepKey },
|
|
686
|
+
detail: { expr: e }
|
|
687
|
+
});
|
|
688
|
+
}
|
|
689
|
+
const kind = e.kind;
|
|
690
|
+
switch (kind) {
|
|
691
|
+
case "payload":
|
|
692
|
+
return;
|
|
693
|
+
case "payload.path": {
|
|
694
|
+
const pointer = e.pointer;
|
|
695
|
+
if (typeof pointer !== "string") {
|
|
696
|
+
throw makeWorkflowError({
|
|
697
|
+
code: "WORKFLOW_INVALID_INPUT_EXPR",
|
|
698
|
+
message: "InputExpr.payload.path.pointer must be a string.",
|
|
699
|
+
source: { stepKey: options?.stepKey },
|
|
700
|
+
detail: { pointer }
|
|
701
|
+
});
|
|
702
|
+
}
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
705
|
+
case "const": {
|
|
706
|
+
const value = e.value;
|
|
707
|
+
if (!isJsonValue(value)) {
|
|
708
|
+
throw makeWorkflowError({
|
|
709
|
+
code: "WORKFLOW_INVALID_INPUT_EXPR",
|
|
710
|
+
message: "InputExpr.const.value must be JSON-serializable.",
|
|
711
|
+
source: { stepKey: options?.stepKey }
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
return;
|
|
715
|
+
}
|
|
716
|
+
case "object": {
|
|
717
|
+
const fields = e.fields;
|
|
718
|
+
if (!isRecord2(fields)) {
|
|
719
|
+
throw makeWorkflowError({
|
|
720
|
+
code: "WORKFLOW_INVALID_INPUT_EXPR",
|
|
721
|
+
message: "InputExpr.object.fields must be a record.",
|
|
722
|
+
source: { stepKey: options?.stepKey }
|
|
723
|
+
});
|
|
724
|
+
}
|
|
725
|
+
for (const v of Object.values(fields)) {
|
|
726
|
+
visit(v);
|
|
727
|
+
}
|
|
728
|
+
return;
|
|
729
|
+
}
|
|
730
|
+
case "merge": {
|
|
731
|
+
const items = e.items;
|
|
732
|
+
if (!Array.isArray(items)) {
|
|
733
|
+
throw makeWorkflowError({
|
|
734
|
+
code: "WORKFLOW_INVALID_INPUT_EXPR",
|
|
735
|
+
message: "InputExpr.merge.items must be an array.",
|
|
736
|
+
source: { stepKey: options?.stepKey }
|
|
737
|
+
});
|
|
738
|
+
}
|
|
739
|
+
for (const item of items) {
|
|
740
|
+
visit(item);
|
|
741
|
+
}
|
|
742
|
+
return;
|
|
743
|
+
}
|
|
744
|
+
default:
|
|
745
|
+
throw makeWorkflowError({
|
|
746
|
+
code: "WORKFLOW_INVALID_INPUT_EXPR",
|
|
747
|
+
message: "Unknown InputExpr kind.",
|
|
748
|
+
source: { stepKey: options?.stepKey },
|
|
749
|
+
detail: { kind }
|
|
750
|
+
});
|
|
751
|
+
}
|
|
752
|
+
};
|
|
753
|
+
visit(expr);
|
|
754
|
+
};
|
|
755
|
+
var makeDigest = (prefix, value) => `${prefix}:${fnv1a32(stableStringify(value))}`;
|
|
756
|
+
var makeTriggerNodeId = (programId) => `wf_trigger_v1:${fnv1a32(programId)}`;
|
|
757
|
+
var makeStepNodeId = (programId, stepKey, kind) => `wf_node_v1:${fnv1a32(`${programId}\0${stepKey}\0${kind}`)}`;
|
|
758
|
+
var budgetJsonValue = (value) => projectJsonValue(value).value;
|
|
759
|
+
var budgetInputExpr = (expr) => {
|
|
760
|
+
switch (expr.kind) {
|
|
761
|
+
case "payload":
|
|
762
|
+
case "payload.path":
|
|
763
|
+
return expr;
|
|
764
|
+
case "const": {
|
|
765
|
+
const value = expr.value;
|
|
766
|
+
if (!isJsonValue(value)) return expr;
|
|
767
|
+
return { ...expr, value: budgetJsonValue(expr.value) };
|
|
768
|
+
}
|
|
769
|
+
case "object": {
|
|
770
|
+
const out = {};
|
|
771
|
+
for (const k of Object.keys(expr.fields).sort()) {
|
|
772
|
+
out[k] = budgetInputExpr(expr.fields[k]);
|
|
773
|
+
}
|
|
774
|
+
return { ...expr, fields: out };
|
|
775
|
+
}
|
|
776
|
+
case "merge":
|
|
777
|
+
return { ...expr, items: expr.items.map(budgetInputExpr) };
|
|
778
|
+
}
|
|
779
|
+
};
|
|
780
|
+
var toStaticStep = (step) => {
|
|
781
|
+
switch (step.kind) {
|
|
782
|
+
case "dispatch":
|
|
783
|
+
return {
|
|
784
|
+
kind: "dispatch",
|
|
785
|
+
actionTag: step.actionTag,
|
|
786
|
+
...step.payload ? { payload: budgetInputExpr(step.payload) } : null
|
|
787
|
+
};
|
|
788
|
+
case "delay":
|
|
789
|
+
return { kind: "delay", ms: step.ms };
|
|
790
|
+
case "call": {
|
|
791
|
+
const policy = step.timeoutMs !== void 0 || step.retry !== void 0 ? {
|
|
792
|
+
...step.timeoutMs !== void 0 ? { timeoutMs: step.timeoutMs } : null,
|
|
793
|
+
...step.retry !== void 0 ? { retry: { times: step.retry.times } } : null
|
|
794
|
+
} : void 0;
|
|
795
|
+
return {
|
|
796
|
+
kind: "call",
|
|
797
|
+
serviceId: step.serviceId,
|
|
798
|
+
...step.input ? { input: budgetInputExpr(step.input) } : null,
|
|
799
|
+
...policy ? { policy } : null
|
|
800
|
+
};
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
};
|
|
804
|
+
var compileWorkflowStaticIrV1 = (args) => {
|
|
805
|
+
const normalized = normalizeWorkflowDefV1(args.def);
|
|
806
|
+
validateWorkflowDefV1(normalized, { moduleId: args.moduleId });
|
|
807
|
+
const programId = `${args.moduleId}.${normalized.localId}`;
|
|
808
|
+
const triggerNodeId = makeTriggerNodeId(programId);
|
|
809
|
+
const fragmentByStepKey = /* @__PURE__ */ new Map();
|
|
810
|
+
if (normalized.sources && typeof normalized.sources === "object") {
|
|
811
|
+
for (const [k, v] of Object.entries(normalized.sources)) {
|
|
812
|
+
fragmentByStepKey.set(k, isRecord2(v) ? asNonEmptyString2(v.fragmentId) : void 0);
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
const nodesByKey = /* @__PURE__ */ new Map();
|
|
816
|
+
const collectNodes = (steps) => {
|
|
817
|
+
for (const step of steps) {
|
|
818
|
+
const id = makeStepNodeId(programId, step.key, step.kind);
|
|
819
|
+
nodesByKey.set(step.key, id);
|
|
820
|
+
if (step.kind === "call") {
|
|
821
|
+
collectNodes(step.onSuccess);
|
|
822
|
+
collectNodes(step.onFailure);
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
};
|
|
826
|
+
collectNodes(normalized.steps);
|
|
827
|
+
const nodes = [
|
|
828
|
+
{
|
|
829
|
+
id: triggerNodeId,
|
|
830
|
+
kind: "trigger",
|
|
831
|
+
trigger: normalized.trigger
|
|
832
|
+
}
|
|
833
|
+
];
|
|
834
|
+
const addStepNodes = (steps) => {
|
|
835
|
+
for (const step of steps) {
|
|
836
|
+
const id = nodesByKey.get(step.key);
|
|
837
|
+
if (!id) continue;
|
|
838
|
+
const fragmentId = fragmentByStepKey.get(step.key);
|
|
839
|
+
nodes.push({
|
|
840
|
+
id,
|
|
841
|
+
kind: "step",
|
|
842
|
+
step: toStaticStep(step),
|
|
843
|
+
source: {
|
|
844
|
+
stepKey: step.key,
|
|
845
|
+
...fragmentId ? { fragmentId } : null
|
|
846
|
+
}
|
|
847
|
+
});
|
|
848
|
+
if (step.kind === "call") {
|
|
849
|
+
addStepNodes(step.onSuccess);
|
|
850
|
+
addStepNodes(step.onFailure);
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
};
|
|
854
|
+
addStepNodes(normalized.steps);
|
|
855
|
+
const edges = [];
|
|
856
|
+
const pushEdge = (from, to, kind) => {
|
|
857
|
+
edges.push({ from, to, kind });
|
|
858
|
+
};
|
|
859
|
+
const compileBlock = (args2) => {
|
|
860
|
+
if (args2.steps.length === 0) {
|
|
861
|
+
if (args2.continuation) {
|
|
862
|
+
for (const from of args2.entryFrom) {
|
|
863
|
+
pushEdge(from, args2.continuation, args2.entryKind);
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
return;
|
|
867
|
+
}
|
|
868
|
+
const first = args2.steps[0];
|
|
869
|
+
const firstId = nodesByKey.get(first.key);
|
|
870
|
+
if (!firstId) {
|
|
871
|
+
throw makeWorkflowError({
|
|
872
|
+
code: "WORKFLOW_INVALID_STEP",
|
|
873
|
+
message: "Internal error: missing node id for stepKey.",
|
|
874
|
+
programId,
|
|
875
|
+
source: { stepKey: first.key }
|
|
876
|
+
});
|
|
877
|
+
}
|
|
878
|
+
for (const from of args2.entryFrom) {
|
|
879
|
+
pushEdge(from, firstId, args2.entryKind);
|
|
880
|
+
}
|
|
881
|
+
const compileStepAndTail = (step, tail, continuation) => {
|
|
882
|
+
const stepId = nodesByKey.get(step.key);
|
|
883
|
+
if (!stepId) return;
|
|
884
|
+
if (step.kind !== "call") {
|
|
885
|
+
compileBlock({ steps: tail, entryFrom: [stepId], entryKind: "next", continuation });
|
|
886
|
+
return;
|
|
887
|
+
}
|
|
888
|
+
const cont = tail.length > 0 ? nodesByKey.get(tail[0].key) : continuation;
|
|
889
|
+
compileBlock({
|
|
890
|
+
steps: step.onSuccess,
|
|
891
|
+
entryFrom: [stepId],
|
|
892
|
+
entryKind: "success",
|
|
893
|
+
continuation: cont
|
|
894
|
+
});
|
|
895
|
+
compileBlock({
|
|
896
|
+
steps: step.onFailure,
|
|
897
|
+
entryFrom: [stepId],
|
|
898
|
+
entryKind: "failure",
|
|
899
|
+
continuation: cont
|
|
900
|
+
});
|
|
901
|
+
compileBlock({ steps: tail, entryFrom: [], entryKind: "next", continuation });
|
|
902
|
+
};
|
|
903
|
+
compileStepAndTail(first, args2.steps.slice(1), args2.continuation);
|
|
904
|
+
};
|
|
905
|
+
compileBlock({ steps: normalized.steps, entryFrom: [triggerNodeId], entryKind: "next", continuation: void 0 });
|
|
906
|
+
nodes.sort((a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0);
|
|
907
|
+
edges.sort((a, b) => {
|
|
908
|
+
if (a.from !== b.from) return a.from < b.from ? -1 : 1;
|
|
909
|
+
if (a.to !== b.to) return a.to < b.to ? -1 : 1;
|
|
910
|
+
const ak = String(a.kind ?? "");
|
|
911
|
+
const bk = String(b.kind ?? "");
|
|
912
|
+
if (ak !== bk) return ak < bk ? -1 : 1;
|
|
913
|
+
return 0;
|
|
914
|
+
});
|
|
915
|
+
const meta = (() => {
|
|
916
|
+
const generator = normalized.meta?.generator;
|
|
917
|
+
if (generator === void 0) return void 0;
|
|
918
|
+
return { generator: budgetJsonValue(generator) };
|
|
919
|
+
})();
|
|
920
|
+
const irNoDigest = {
|
|
921
|
+
version: 1,
|
|
922
|
+
programId,
|
|
923
|
+
nodes,
|
|
924
|
+
edges,
|
|
925
|
+
policy: normalized.policy,
|
|
926
|
+
meta
|
|
927
|
+
};
|
|
928
|
+
const digest = makeDigest("workflow_ir_v1", irNoDigest);
|
|
929
|
+
return {
|
|
930
|
+
...irNoDigest,
|
|
931
|
+
digest
|
|
932
|
+
};
|
|
933
|
+
};
|
|
934
|
+
var compileWorkflowRuntimeStepsV1 = (args) => {
|
|
935
|
+
const normalized = normalizeWorkflowDefV1(args.def);
|
|
936
|
+
validateWorkflowDefV1(normalized);
|
|
937
|
+
const compileStep = (step) => {
|
|
938
|
+
const stepKey = step.key;
|
|
939
|
+
switch (step.kind) {
|
|
940
|
+
case "dispatch":
|
|
941
|
+
return {
|
|
942
|
+
kind: "dispatch",
|
|
943
|
+
key: step.key,
|
|
944
|
+
actionTag: step.actionTag,
|
|
945
|
+
...step.payload ? { payload: compileInputExpr(step.payload, { stepKey }) } : null
|
|
946
|
+
};
|
|
947
|
+
case "delay":
|
|
948
|
+
return { kind: "delay", key: step.key, ms: step.ms };
|
|
949
|
+
case "call": {
|
|
950
|
+
const retryTimes = step.retry?.times;
|
|
951
|
+
return {
|
|
952
|
+
kind: "call",
|
|
953
|
+
key: step.key,
|
|
954
|
+
serviceId: step.serviceId,
|
|
955
|
+
...step.input ? { input: compileInputExpr(step.input, { stepKey }) } : null,
|
|
956
|
+
...step.timeoutMs !== void 0 ? { timeoutMs: step.timeoutMs } : null,
|
|
957
|
+
...retryTimes !== void 0 ? { retryTimes } : null,
|
|
958
|
+
onSuccess: step.onSuccess.map(compileStep),
|
|
959
|
+
onFailure: step.onFailure.map(compileStep)
|
|
960
|
+
};
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
};
|
|
964
|
+
return normalized.steps.map(compileStep);
|
|
965
|
+
};
|
|
966
|
+
|
|
967
|
+
// src/internal/runtime/core/WorkflowRuntime.ts
|
|
968
|
+
var import_effect14 = require("effect");
|
|
969
|
+
|
|
970
|
+
// src/internal/runtime/core/EffectOpCore.ts
|
|
971
|
+
var import_effect2 = require("effect");
|
|
972
|
+
var currentLinkId = import_effect2.ServiceMap.Reference("@logixjs/core/CurrentLinkId", {
|
|
973
|
+
defaultValue: () => void 0
|
|
974
|
+
});
|
|
975
|
+
var composeMiddlewareCache = /* @__PURE__ */ new WeakMap();
|
|
976
|
+
var EffectOpMiddlewareTag = class extends import_effect2.ServiceMap.Service()("Logix/EffectOpMiddleware") {
|
|
977
|
+
};
|
|
978
|
+
var composeMiddleware = (stack) => {
|
|
979
|
+
const cached = composeMiddlewareCache.get(stack);
|
|
980
|
+
if (cached) {
|
|
981
|
+
return cached;
|
|
982
|
+
}
|
|
983
|
+
const composed = (op) => stack.reduceRight(
|
|
984
|
+
(eff, mw) => mw({ ...op, effect: eff }),
|
|
985
|
+
op.effect
|
|
986
|
+
);
|
|
987
|
+
composeMiddlewareCache.set(stack, composed);
|
|
988
|
+
return composed;
|
|
989
|
+
};
|
|
990
|
+
var runWithMiddleware = (op, stack) => {
|
|
991
|
+
return import_effect2.Effect.gen(function* () {
|
|
992
|
+
const existing = yield* import_effect2.Effect.service(currentLinkId);
|
|
993
|
+
const metaLinkId = op.meta?.linkId;
|
|
994
|
+
const linkId = typeof metaLinkId === "string" && metaLinkId.length > 0 ? metaLinkId : existing ?? op.id;
|
|
995
|
+
const nextOp = {
|
|
996
|
+
...op,
|
|
997
|
+
meta: {
|
|
998
|
+
...op.meta ?? {},
|
|
999
|
+
linkId
|
|
1000
|
+
}
|
|
1001
|
+
};
|
|
1002
|
+
const program = stack.length ? composeMiddleware(stack)(nextOp) : nextOp.effect;
|
|
1003
|
+
return yield* import_effect2.Effect.provideService(program, currentLinkId, linkId);
|
|
1004
|
+
});
|
|
1005
|
+
};
|
|
1006
|
+
|
|
1007
|
+
// src/internal/runtime/core/DebugSink.record.ts
|
|
1008
|
+
var import_effect4 = require("effect");
|
|
1009
|
+
|
|
1010
|
+
// src/internal/runtime/core/errorSummary.ts
|
|
1011
|
+
var import_effect3 = require("effect");
|
|
1012
|
+
var truncate = (value, maxLen) => {
|
|
1013
|
+
if (value.length <= maxLen) return { value, truncated: false };
|
|
1014
|
+
return { value: value.slice(0, maxLen), truncated: true };
|
|
1015
|
+
};
|
|
1016
|
+
var safeStringify = (value) => {
|
|
1017
|
+
try {
|
|
1018
|
+
return { ok: true, json: JSON.stringify(value) };
|
|
1019
|
+
} catch {
|
|
1020
|
+
return { ok: false };
|
|
1021
|
+
}
|
|
1022
|
+
};
|
|
1023
|
+
var getMessageFromUnknown = (cause) => {
|
|
1024
|
+
if (typeof cause === "string") return cause;
|
|
1025
|
+
if (typeof cause === "number" || typeof cause === "boolean" || typeof cause === "bigint") return String(cause);
|
|
1026
|
+
if (cause instanceof Error) return cause.message || cause.name || "Error";
|
|
1027
|
+
if (cause && typeof cause === "object" && "message" in cause && typeof cause.message === "string") {
|
|
1028
|
+
return cause.message;
|
|
1029
|
+
}
|
|
1030
|
+
try {
|
|
1031
|
+
const pretty = import_effect3.Cause.pretty(cause);
|
|
1032
|
+
if (typeof pretty === "string" && pretty.length > 0) return pretty;
|
|
1033
|
+
} catch {
|
|
1034
|
+
}
|
|
1035
|
+
return "Unknown error";
|
|
1036
|
+
};
|
|
1037
|
+
var toSerializableErrorSummary = (cause, options) => {
|
|
1038
|
+
const maxMessageLength = options?.maxMessageLength ?? 256;
|
|
1039
|
+
const messageRaw = getMessageFromUnknown(cause);
|
|
1040
|
+
const { value: message, truncated } = truncate(messageRaw, maxMessageLength);
|
|
1041
|
+
const summary = {
|
|
1042
|
+
message
|
|
1043
|
+
};
|
|
1044
|
+
if (cause instanceof Error) {
|
|
1045
|
+
if (cause.name && cause.name !== "Error") summary.name = cause.name;
|
|
1046
|
+
const anyCause = cause;
|
|
1047
|
+
if (typeof anyCause.code === "string" && anyCause.code.length > 0) summary.code = anyCause.code;
|
|
1048
|
+
else if (typeof anyCause.code === "number" && Number.isFinite(anyCause.code)) summary.code = String(anyCause.code);
|
|
1049
|
+
if (typeof anyCause.hint === "string" && anyCause.hint.length > 0) summary.hint = anyCause.hint;
|
|
1050
|
+
return {
|
|
1051
|
+
errorSummary: summary,
|
|
1052
|
+
downgrade: truncated ? "oversized" : void 0
|
|
1053
|
+
};
|
|
1054
|
+
}
|
|
1055
|
+
if (cause && typeof cause === "object") {
|
|
1056
|
+
const anyCause = cause;
|
|
1057
|
+
if (typeof anyCause.name === "string" && anyCause.name.length > 0) summary.name = anyCause.name;
|
|
1058
|
+
if (typeof anyCause.code === "string" && anyCause.code.length > 0) summary.code = anyCause.code;
|
|
1059
|
+
if (typeof anyCause.hint === "string" && anyCause.hint.length > 0) summary.hint = anyCause.hint;
|
|
1060
|
+
}
|
|
1061
|
+
const stringifyResult = safeStringify(cause);
|
|
1062
|
+
if (!stringifyResult.ok) {
|
|
1063
|
+
return {
|
|
1064
|
+
errorSummary: summary,
|
|
1065
|
+
downgrade: "non_serializable"
|
|
1066
|
+
};
|
|
1067
|
+
}
|
|
1068
|
+
if (truncated) {
|
|
1069
|
+
return {
|
|
1070
|
+
errorSummary: summary,
|
|
1071
|
+
downgrade: "oversized"
|
|
1072
|
+
};
|
|
1073
|
+
}
|
|
1074
|
+
if (message === "Unknown error") {
|
|
1075
|
+
return {
|
|
1076
|
+
errorSummary: summary,
|
|
1077
|
+
downgrade: "unknown"
|
|
1078
|
+
};
|
|
1079
|
+
}
|
|
1080
|
+
return { errorSummary: summary };
|
|
1081
|
+
};
|
|
1082
|
+
|
|
1083
|
+
// src/internal/runtime/core/DebugSink.record.ts
|
|
1084
|
+
var currentDebugSinks = import_effect4.ServiceMap.Reference("@logixjs/core/Debug.currentDebugSinks", {
|
|
1085
|
+
defaultValue: () => []
|
|
1086
|
+
});
|
|
1087
|
+
var currentRuntimeLabel = import_effect4.ServiceMap.Reference("@logixjs/core/Debug.currentRuntimeLabel", {
|
|
1088
|
+
defaultValue: () => void 0
|
|
1089
|
+
});
|
|
1090
|
+
var currentTxnId = import_effect4.ServiceMap.Reference("@logixjs/core/Debug.currentTxnId", {
|
|
1091
|
+
defaultValue: () => void 0
|
|
1092
|
+
});
|
|
1093
|
+
var currentOpSeq = import_effect4.ServiceMap.Reference("@logixjs/core/Debug.currentOpSeq", {
|
|
1094
|
+
defaultValue: () => void 0
|
|
1095
|
+
});
|
|
1096
|
+
var currentDiagnosticsLevel = import_effect4.ServiceMap.Reference("@logixjs/core/Debug.currentDiagnosticsLevel", {
|
|
1097
|
+
defaultValue: () => "off"
|
|
1098
|
+
});
|
|
1099
|
+
var currentDiagnosticsMaterialization = import_effect4.ServiceMap.Reference(
|
|
1100
|
+
"@logixjs/core/Debug.currentDiagnosticsMaterialization",
|
|
1101
|
+
{
|
|
1102
|
+
defaultValue: () => "eager"
|
|
1103
|
+
}
|
|
1104
|
+
);
|
|
1105
|
+
var currentTraceMode = import_effect4.ServiceMap.Reference("@logixjs/core/Debug.currentTraceMode", {
|
|
1106
|
+
defaultValue: () => "on"
|
|
1107
|
+
});
|
|
1108
|
+
var currentTraitConvergeDiagnosticsSampling = import_effect4.ServiceMap.Reference(
|
|
1109
|
+
"@logixjs/core/Debug.currentTraitConvergeDiagnosticsSampling",
|
|
1110
|
+
{
|
|
1111
|
+
defaultValue: () => ({
|
|
1112
|
+
sampleEveryN: 32,
|
|
1113
|
+
topK: 3
|
|
1114
|
+
})
|
|
1115
|
+
}
|
|
1116
|
+
);
|
|
1117
|
+
var browserLifecycleSeen = /* @__PURE__ */ new Set();
|
|
1118
|
+
var browserDiagnosticSeen = /* @__PURE__ */ new Set();
|
|
1119
|
+
var lifecycleErrorLog = (event) => {
|
|
1120
|
+
const moduleId = event.moduleId ?? "unknown";
|
|
1121
|
+
const causePretty = (() => {
|
|
1122
|
+
try {
|
|
1123
|
+
return import_effect4.Cause.pretty(event.cause);
|
|
1124
|
+
} catch {
|
|
1125
|
+
try {
|
|
1126
|
+
return JSON.stringify(event.cause, null, 2);
|
|
1127
|
+
} catch {
|
|
1128
|
+
return String(event.cause);
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
})();
|
|
1132
|
+
const message = `[Logix][module=${moduleId}] lifecycle:error
|
|
1133
|
+
${causePretty}`;
|
|
1134
|
+
return import_effect4.Effect.logError(message).pipe(
|
|
1135
|
+
import_effect4.Effect.annotateLogs({
|
|
1136
|
+
"logix.moduleId": moduleId,
|
|
1137
|
+
"logix.event": "lifecycle:error",
|
|
1138
|
+
"logix.cause": causePretty
|
|
1139
|
+
})
|
|
1140
|
+
);
|
|
1141
|
+
};
|
|
1142
|
+
var diagnosticLog = (event) => {
|
|
1143
|
+
const moduleId = event.moduleId ?? "unknown";
|
|
1144
|
+
const header = `[Logix][module=${moduleId}] diagnostic(${event.severity})`;
|
|
1145
|
+
const detail = `code=${event.code} message=${event.message}${event.actionTag ? ` action=${event.actionTag}` : ""}${event.hint ? `
|
|
1146
|
+
hint: ${event.hint}` : ""}`;
|
|
1147
|
+
const msg = `${header}
|
|
1148
|
+
${detail}`;
|
|
1149
|
+
const base = event.severity === "warning" ? import_effect4.Effect.logWarning(msg) : event.severity === "info" ? import_effect4.Effect.logInfo(msg) : import_effect4.Effect.logError(msg);
|
|
1150
|
+
const annotations = {
|
|
1151
|
+
"logix.moduleId": moduleId,
|
|
1152
|
+
"logix.event": `diagnostic(${event.severity})`,
|
|
1153
|
+
"logix.diagnostic.code": event.code,
|
|
1154
|
+
"logix.diagnostic.message": event.message
|
|
1155
|
+
};
|
|
1156
|
+
if (event.hint) {
|
|
1157
|
+
annotations["logix.diagnostic.hint"] = event.hint;
|
|
1158
|
+
}
|
|
1159
|
+
if (event.actionTag) {
|
|
1160
|
+
annotations["logix.diagnostic.actionTag"] = event.actionTag;
|
|
1161
|
+
}
|
|
1162
|
+
return base.pipe(import_effect4.Effect.annotateLogs(annotations));
|
|
1163
|
+
};
|
|
1164
|
+
var noopLayer = import_effect4.Layer.succeed(currentDebugSinks, []);
|
|
1165
|
+
var errorOnlySink = {
|
|
1166
|
+
record: (event) => event.type === "lifecycle:error" ? lifecycleErrorLog(event) : event.type === "diagnostic" && event.severity !== "info" ? diagnosticLog(event) : import_effect4.Effect.void
|
|
1167
|
+
};
|
|
1168
|
+
var errorOnlyLayer = import_effect4.Layer.succeed(currentDebugSinks, [errorOnlySink]);
|
|
1169
|
+
var isErrorOnlyOnlySinks = (sinks) => sinks.length === 1 && sinks[0] === errorOnlySink;
|
|
1170
|
+
var consoleSink = {
|
|
1171
|
+
record: (event) => event.type === "lifecycle:error" ? lifecycleErrorLog(event) : event.type === "diagnostic" ? diagnosticLog(event) : import_effect4.Effect.logDebug({ debugEvent: event })
|
|
1172
|
+
};
|
|
1173
|
+
var consoleLayer = import_effect4.Layer.succeed(currentDebugSinks, [consoleSink]);
|
|
1174
|
+
var isBrowser = typeof window !== "undefined" && typeof document !== "undefined";
|
|
1175
|
+
var renderBrowserConsoleEvent = (event) => {
|
|
1176
|
+
if (typeof event.type === "string" && event.type.startsWith("trace:")) {
|
|
1177
|
+
const moduleId = event.moduleId ?? "unknown";
|
|
1178
|
+
const type = event.type;
|
|
1179
|
+
return import_effect4.Effect.sync(() => {
|
|
1180
|
+
console.groupCollapsed(
|
|
1181
|
+
"%c[Logix]%c trace %c" + moduleId + "%c " + String(type),
|
|
1182
|
+
"color:#6b7280;font-weight:bold",
|
|
1183
|
+
// tag
|
|
1184
|
+
"color:#3b82f6",
|
|
1185
|
+
// label
|
|
1186
|
+
"color:#9ca3af",
|
|
1187
|
+
// module id
|
|
1188
|
+
"color:#6b7280"
|
|
1189
|
+
// type
|
|
1190
|
+
);
|
|
1191
|
+
console.log(event);
|
|
1192
|
+
console.groupEnd();
|
|
1193
|
+
});
|
|
1194
|
+
}
|
|
1195
|
+
if (event.type === "lifecycle:error") {
|
|
1196
|
+
const moduleId = event.moduleId ?? "unknown";
|
|
1197
|
+
const causePretty = (() => {
|
|
1198
|
+
try {
|
|
1199
|
+
return import_effect4.Cause.pretty(event.cause);
|
|
1200
|
+
} catch {
|
|
1201
|
+
try {
|
|
1202
|
+
return JSON.stringify(event.cause, null, 2);
|
|
1203
|
+
} catch {
|
|
1204
|
+
return String(event.cause);
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
})();
|
|
1208
|
+
const key = `${moduleId}|${causePretty}`;
|
|
1209
|
+
if (browserLifecycleSeen.has(key)) {
|
|
1210
|
+
return import_effect4.Effect.void;
|
|
1211
|
+
}
|
|
1212
|
+
browserLifecycleSeen.add(key);
|
|
1213
|
+
return import_effect4.Effect.sync(() => {
|
|
1214
|
+
console.groupCollapsed(
|
|
1215
|
+
"%c[Logix]%c lifecycle:error %c" + moduleId,
|
|
1216
|
+
"color:#ef4444;font-weight:bold",
|
|
1217
|
+
// tag
|
|
1218
|
+
"color:#ef4444",
|
|
1219
|
+
// label
|
|
1220
|
+
"color:#9ca3af"
|
|
1221
|
+
// module id
|
|
1222
|
+
);
|
|
1223
|
+
console.error(causePretty);
|
|
1224
|
+
console.groupEnd();
|
|
1225
|
+
});
|
|
1226
|
+
}
|
|
1227
|
+
if (event.type === "diagnostic") {
|
|
1228
|
+
const moduleId = event.moduleId ?? "unknown";
|
|
1229
|
+
const detail = `code=${event.code} message=${event.message}${event.actionTag ? ` action=${event.actionTag}` : ""}${event.hint ? `
|
|
1230
|
+
hint: ${event.hint}` : ""}`;
|
|
1231
|
+
const color = event.severity === "warning" ? "color:#d97706" : event.severity === "info" ? "color:#3b82f6" : "color:#ef4444";
|
|
1232
|
+
const label = event.severity === "warning" ? "diagnostic(warning)" : event.severity === "info" ? "diagnostic(info)" : "diagnostic(error)";
|
|
1233
|
+
const key = `${moduleId}|${event.code}|${event.message}`;
|
|
1234
|
+
if (browserDiagnosticSeen.has(key)) {
|
|
1235
|
+
return import_effect4.Effect.void;
|
|
1236
|
+
}
|
|
1237
|
+
browserDiagnosticSeen.add(key);
|
|
1238
|
+
return import_effect4.Effect.sync(() => {
|
|
1239
|
+
console.groupCollapsed(
|
|
1240
|
+
"%c[Logix]%c " + label + "%c module=" + moduleId,
|
|
1241
|
+
"color:#6b7280;font-weight:bold",
|
|
1242
|
+
color,
|
|
1243
|
+
"color:#9ca3af"
|
|
1244
|
+
);
|
|
1245
|
+
if (event.severity === "warning") {
|
|
1246
|
+
console.warn(detail);
|
|
1247
|
+
} else if (event.severity === "info") {
|
|
1248
|
+
console.info(detail);
|
|
1249
|
+
} else {
|
|
1250
|
+
console.error(detail);
|
|
1251
|
+
}
|
|
1252
|
+
console.groupEnd();
|
|
1253
|
+
});
|
|
1254
|
+
}
|
|
1255
|
+
return import_effect4.Effect.void;
|
|
1256
|
+
};
|
|
1257
|
+
var browserConsoleSink = {
|
|
1258
|
+
record: (event) => {
|
|
1259
|
+
if (!isBrowser) {
|
|
1260
|
+
return event.type === "lifecycle:error" ? lifecycleErrorLog(event) : event.type === "diagnostic" ? diagnosticLog(event) : import_effect4.Effect.logDebug({ debugEvent: event });
|
|
1261
|
+
}
|
|
1262
|
+
return renderBrowserConsoleEvent(event);
|
|
1263
|
+
}
|
|
1264
|
+
};
|
|
1265
|
+
var browserConsoleLayer = import_effect4.Layer.succeed(currentDebugSinks, [browserConsoleSink]);
|
|
1266
|
+
var browserDiagnosticConsoleSink = {
|
|
1267
|
+
record: (event) => {
|
|
1268
|
+
if (!isBrowser) {
|
|
1269
|
+
return event.type === "lifecycle:error" ? lifecycleErrorLog(event) : event.type === "diagnostic" && event.severity !== "info" ? diagnosticLog(event) : import_effect4.Effect.void;
|
|
1270
|
+
}
|
|
1271
|
+
return event.type === "lifecycle:error" || event.type === "diagnostic" && event.severity !== "info" ? renderBrowserConsoleEvent(event) : import_effect4.Effect.void;
|
|
1272
|
+
}
|
|
1273
|
+
};
|
|
1274
|
+
var browserDiagnosticConsoleLayer = import_effect4.Layer.succeed(currentDebugSinks, [browserDiagnosticConsoleSink]);
|
|
1275
|
+
var browserPrettyLoggerLayer = import_effect4.Layer.effect(
|
|
1276
|
+
import_effect4.Logger.CurrentLoggers,
|
|
1277
|
+
import_effect4.Effect.gen(function* () {
|
|
1278
|
+
const current = yield* import_effect4.Effect.service(import_effect4.Logger.CurrentLoggers);
|
|
1279
|
+
return new Set(
|
|
1280
|
+
[...current].filter((logger) => logger !== import_effect4.Logger.defaultLogger).concat(import_effect4.Logger.consolePretty({ mode: "browser", colors: true }))
|
|
1281
|
+
);
|
|
1282
|
+
})
|
|
1283
|
+
);
|
|
1284
|
+
var record = (event) => import_effect4.Effect.gen(function* () {
|
|
1285
|
+
const sinks = yield* import_effect4.Effect.service(currentDebugSinks);
|
|
1286
|
+
if (isErrorOnlyOnlySinks(sinks)) {
|
|
1287
|
+
if (event.type === "lifecycle:error") {
|
|
1288
|
+
yield* lifecycleErrorLog(event);
|
|
1289
|
+
return;
|
|
1290
|
+
}
|
|
1291
|
+
if (event.type === "diagnostic" && event.severity !== "info") {
|
|
1292
|
+
yield* diagnosticLog(event);
|
|
1293
|
+
}
|
|
1294
|
+
return;
|
|
1295
|
+
}
|
|
1296
|
+
if (sinks.length === 0) {
|
|
1297
|
+
if (isBrowser) {
|
|
1298
|
+
if (event.type === "lifecycle:error" || event.type === "diagnostic") {
|
|
1299
|
+
yield* renderBrowserConsoleEvent(event);
|
|
1300
|
+
}
|
|
1301
|
+
return;
|
|
1302
|
+
}
|
|
1303
|
+
if (event.type === "lifecycle:error") {
|
|
1304
|
+
yield* lifecycleErrorLog(event);
|
|
1305
|
+
return;
|
|
1306
|
+
}
|
|
1307
|
+
if (event.type === "diagnostic") {
|
|
1308
|
+
yield* diagnosticLog(event);
|
|
1309
|
+
}
|
|
1310
|
+
return;
|
|
1311
|
+
}
|
|
1312
|
+
if (typeof event.type === "string" && event.type.startsWith("trace:")) {
|
|
1313
|
+
const mode = yield* import_effect4.Effect.service(currentTraceMode);
|
|
1314
|
+
if (mode === "off") return;
|
|
1315
|
+
}
|
|
1316
|
+
const enriched = event;
|
|
1317
|
+
const diagnosticsLevel = yield* import_effect4.Effect.service(currentDiagnosticsLevel);
|
|
1318
|
+
let now;
|
|
1319
|
+
const getNow = () => {
|
|
1320
|
+
if (now === void 0) now = Date.now();
|
|
1321
|
+
return now;
|
|
1322
|
+
};
|
|
1323
|
+
if (enriched.timestamp === void 0 && (diagnosticsLevel !== "off" || enriched.type === "lifecycle:error" || enriched.type === "diagnostic")) {
|
|
1324
|
+
;
|
|
1325
|
+
enriched.timestamp = getNow();
|
|
1326
|
+
}
|
|
1327
|
+
if (diagnosticsLevel !== "off" && enriched.runtimeLabel === void 0) {
|
|
1328
|
+
const runtimeLabel = yield* import_effect4.Effect.service(currentRuntimeLabel);
|
|
1329
|
+
if (runtimeLabel) {
|
|
1330
|
+
;
|
|
1331
|
+
enriched.runtimeLabel = runtimeLabel;
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1334
|
+
if (enriched.type === "diagnostic" && enriched.txnId === void 0) {
|
|
1335
|
+
const txnId = yield* import_effect4.Effect.service(currentTxnId);
|
|
1336
|
+
if (txnId) {
|
|
1337
|
+
;
|
|
1338
|
+
enriched.txnId = txnId;
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
if (diagnosticsLevel !== "off" && enriched.type === "trace:effectop" && enriched.linkId === void 0) {
|
|
1342
|
+
const maybeLinkId = yield* import_effect4.Effect.serviceOption(currentLinkId);
|
|
1343
|
+
if (import_effect4.Option.isSome(maybeLinkId) && maybeLinkId.value) {
|
|
1344
|
+
;
|
|
1345
|
+
enriched.linkId = maybeLinkId.value;
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1348
|
+
if (sinks.length === 1) {
|
|
1349
|
+
yield* sinks[0].record(enriched);
|
|
1350
|
+
return;
|
|
1351
|
+
}
|
|
1352
|
+
yield* import_effect4.Effect.forEach(sinks, (sink) => sink.record(enriched), { discard: true });
|
|
1353
|
+
});
|
|
1354
|
+
|
|
1355
|
+
// src/internal/runtime/core/LogicUnitMeta.ts
|
|
1356
|
+
var LOGIC_UNIT_META = /* @__PURE__ */ Symbol.for("logix.module.logic.meta");
|
|
1357
|
+
var attachLogicUnitMeta = (logic, meta) => {
|
|
1358
|
+
try {
|
|
1359
|
+
Object.defineProperty(logic, LOGIC_UNIT_META, {
|
|
1360
|
+
value: meta,
|
|
1361
|
+
enumerable: false,
|
|
1362
|
+
configurable: true
|
|
1363
|
+
});
|
|
1364
|
+
} catch {
|
|
1365
|
+
}
|
|
1366
|
+
return logic;
|
|
1367
|
+
};
|
|
1368
|
+
|
|
1369
|
+
// src/internal/runtime/core/env.ts
|
|
1370
|
+
var import_effect10 = require("effect");
|
|
1371
|
+
|
|
1372
|
+
// src/internal/runtime/core/HostScheduler.ts
|
|
1373
|
+
var noopCancel = () => {
|
|
1374
|
+
};
|
|
1375
|
+
var safeNowMs = () => {
|
|
1376
|
+
const perf = globalThis.performance;
|
|
1377
|
+
if (perf && typeof perf.now === "function") {
|
|
1378
|
+
try {
|
|
1379
|
+
const v = perf.now();
|
|
1380
|
+
if (typeof v === "number" && Number.isFinite(v)) return v;
|
|
1381
|
+
} catch {
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
return Date.now();
|
|
1385
|
+
};
|
|
1386
|
+
var safeQueueMicrotask = (cb) => {
|
|
1387
|
+
const qm = globalThis.queueMicrotask;
|
|
1388
|
+
if (typeof qm === "function") {
|
|
1389
|
+
try {
|
|
1390
|
+
qm(cb);
|
|
1391
|
+
return;
|
|
1392
|
+
} catch {
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
try {
|
|
1396
|
+
Promise.resolve().then(cb);
|
|
1397
|
+
} catch {
|
|
1398
|
+
setTimeout(cb, 0);
|
|
1399
|
+
}
|
|
1400
|
+
};
|
|
1401
|
+
var safeSetTimeout = (ms, cb) => {
|
|
1402
|
+
const id = setTimeout(cb, ms);
|
|
1403
|
+
return () => {
|
|
1404
|
+
try {
|
|
1405
|
+
clearTimeout(id);
|
|
1406
|
+
} catch {
|
|
1407
|
+
}
|
|
1408
|
+
};
|
|
1409
|
+
};
|
|
1410
|
+
var makeMessageChannelMacrotask = () => {
|
|
1411
|
+
const MC = globalThis.MessageChannel;
|
|
1412
|
+
if (typeof MC !== "function") return void 0;
|
|
1413
|
+
let channel;
|
|
1414
|
+
try {
|
|
1415
|
+
channel = new MC();
|
|
1416
|
+
} catch {
|
|
1417
|
+
return void 0;
|
|
1418
|
+
}
|
|
1419
|
+
const queue = [];
|
|
1420
|
+
let scheduled = false;
|
|
1421
|
+
const flush = () => {
|
|
1422
|
+
scheduled = false;
|
|
1423
|
+
const tasks = queue.splice(0, queue.length);
|
|
1424
|
+
for (const t of tasks) {
|
|
1425
|
+
if (t.canceled) continue;
|
|
1426
|
+
try {
|
|
1427
|
+
t.cb();
|
|
1428
|
+
} catch {
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
};
|
|
1432
|
+
try {
|
|
1433
|
+
channel.port1.onmessage = flush;
|
|
1434
|
+
} catch {
|
|
1435
|
+
return void 0;
|
|
1436
|
+
}
|
|
1437
|
+
const schedule = (cb) => {
|
|
1438
|
+
const task = { canceled: false, cb };
|
|
1439
|
+
queue.push(task);
|
|
1440
|
+
if (!scheduled) {
|
|
1441
|
+
scheduled = true;
|
|
1442
|
+
try {
|
|
1443
|
+
channel.port2.postMessage(void 0);
|
|
1444
|
+
} catch {
|
|
1445
|
+
scheduled = false;
|
|
1446
|
+
return safeSetTimeout(0, cb);
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
1449
|
+
return () => {
|
|
1450
|
+
task.canceled = true;
|
|
1451
|
+
};
|
|
1452
|
+
};
|
|
1453
|
+
return schedule;
|
|
1454
|
+
};
|
|
1455
|
+
var makeSetImmediateMacrotask = () => {
|
|
1456
|
+
const si = globalThis.setImmediate;
|
|
1457
|
+
const ci = globalThis.clearImmediate;
|
|
1458
|
+
if (typeof si !== "function") return void 0;
|
|
1459
|
+
return (cb) => {
|
|
1460
|
+
let id;
|
|
1461
|
+
try {
|
|
1462
|
+
id = si(cb);
|
|
1463
|
+
} catch {
|
|
1464
|
+
return safeSetTimeout(0, cb);
|
|
1465
|
+
}
|
|
1466
|
+
return () => {
|
|
1467
|
+
if (typeof ci !== "function") return;
|
|
1468
|
+
try {
|
|
1469
|
+
ci(id);
|
|
1470
|
+
} catch {
|
|
1471
|
+
}
|
|
1472
|
+
};
|
|
1473
|
+
};
|
|
1474
|
+
};
|
|
1475
|
+
var makeRaf = () => {
|
|
1476
|
+
const raf = globalThis.requestAnimationFrame;
|
|
1477
|
+
const cancel = globalThis.cancelAnimationFrame;
|
|
1478
|
+
if (typeof raf !== "function") return void 0;
|
|
1479
|
+
return (cb) => {
|
|
1480
|
+
let id;
|
|
1481
|
+
try {
|
|
1482
|
+
id = raf(cb);
|
|
1483
|
+
} catch {
|
|
1484
|
+
return noopCancel;
|
|
1485
|
+
}
|
|
1486
|
+
return () => {
|
|
1487
|
+
if (typeof cancel !== "function") return;
|
|
1488
|
+
try {
|
|
1489
|
+
cancel(id);
|
|
1490
|
+
} catch {
|
|
1491
|
+
}
|
|
1492
|
+
};
|
|
1493
|
+
};
|
|
1494
|
+
};
|
|
1495
|
+
var makeDefaultHostScheduler = () => {
|
|
1496
|
+
const macrotask = makeSetImmediateMacrotask() ?? makeMessageChannelMacrotask() ?? ((cb) => safeSetTimeout(0, cb));
|
|
1497
|
+
const raf = makeRaf();
|
|
1498
|
+
return {
|
|
1499
|
+
nowMs: safeNowMs,
|
|
1500
|
+
scheduleMicrotask: safeQueueMicrotask,
|
|
1501
|
+
scheduleMacrotask: macrotask,
|
|
1502
|
+
scheduleAnimationFrame: (cb) => raf?.(cb) ?? macrotask(cb),
|
|
1503
|
+
scheduleTimeout: safeSetTimeout
|
|
1504
|
+
};
|
|
1505
|
+
};
|
|
1506
|
+
var globalHostScheduler;
|
|
1507
|
+
var getGlobalHostScheduler = () => {
|
|
1508
|
+
globalHostScheduler ?? (globalHostScheduler = makeDefaultHostScheduler());
|
|
1509
|
+
return globalHostScheduler;
|
|
1510
|
+
};
|
|
1511
|
+
|
|
1512
|
+
// src/internal/runtime/core/RuntimeStore.ts
|
|
1513
|
+
var parseTopicKey = (topicKey) => {
|
|
1514
|
+
const idx = topicKey.indexOf("::");
|
|
1515
|
+
if (idx <= 0) return void 0;
|
|
1516
|
+
const moduleId = topicKey.slice(0, idx);
|
|
1517
|
+
const rest = topicKey.slice(idx + 2);
|
|
1518
|
+
if (rest.length === 0) return void 0;
|
|
1519
|
+
const idx2 = rest.indexOf("::");
|
|
1520
|
+
if (idx2 < 0) {
|
|
1521
|
+
return { kind: "module", moduleInstanceKey: `${moduleId}::${rest}` };
|
|
1522
|
+
}
|
|
1523
|
+
const instanceId = rest.slice(0, idx2);
|
|
1524
|
+
const suffix = rest.slice(idx2 + 2);
|
|
1525
|
+
if (suffix.startsWith("rq:")) {
|
|
1526
|
+
const selectorId = suffix.slice("rq:".length);
|
|
1527
|
+
if (selectorId.length === 0) return void 0;
|
|
1528
|
+
return {
|
|
1529
|
+
kind: "readQuery",
|
|
1530
|
+
moduleInstanceKey: `${moduleId}::${instanceId}`,
|
|
1531
|
+
selectorId
|
|
1532
|
+
};
|
|
1533
|
+
}
|
|
1534
|
+
return { kind: "module", moduleInstanceKey: `${moduleId}::${instanceId}` };
|
|
1535
|
+
};
|
|
1536
|
+
var EMPTY_LISTENER_SNAPSHOT = [];
|
|
1537
|
+
var NO_CHANGED_TOPIC_LISTENERS = [];
|
|
1538
|
+
var makeRuntimeStore = () => {
|
|
1539
|
+
let tickSeq = 0;
|
|
1540
|
+
const moduleStates = /* @__PURE__ */ new Map();
|
|
1541
|
+
const topicVersions = /* @__PURE__ */ new Map();
|
|
1542
|
+
const topicPriorities = /* @__PURE__ */ new Map();
|
|
1543
|
+
const listenersByTopic = /* @__PURE__ */ new Map();
|
|
1544
|
+
const subscriberCountByModule = /* @__PURE__ */ new Map();
|
|
1545
|
+
const getTopicVersion = (topicKey) => topicVersions.get(topicKey) ?? 0;
|
|
1546
|
+
const getTopicPriority = (topicKey) => topicPriorities.get(topicKey) ?? "normal";
|
|
1547
|
+
const commitTopicBump = (topicKey, priority) => {
|
|
1548
|
+
const prev = topicVersions.get(topicKey) ?? 0;
|
|
1549
|
+
topicVersions.set(topicKey, prev + 1);
|
|
1550
|
+
topicPriorities.set(topicKey, priority);
|
|
1551
|
+
};
|
|
1552
|
+
const refreshTopicSnapshot = (state) => {
|
|
1553
|
+
state.snapshot = Array.from(state.listeners);
|
|
1554
|
+
};
|
|
1555
|
+
const subscribeTopic = (topicKey, listener) => {
|
|
1556
|
+
const info = parseTopicKey(topicKey);
|
|
1557
|
+
const existing = listenersByTopic.get(topicKey);
|
|
1558
|
+
const state = existing ?? { listeners: /* @__PURE__ */ new Set(), snapshot: EMPTY_LISTENER_SNAPSHOT };
|
|
1559
|
+
const alreadyHas = state.listeners.has(listener);
|
|
1560
|
+
if (!alreadyHas) {
|
|
1561
|
+
state.listeners.add(listener);
|
|
1562
|
+
refreshTopicSnapshot(state);
|
|
1563
|
+
}
|
|
1564
|
+
if (!existing) {
|
|
1565
|
+
listenersByTopic.set(topicKey, state);
|
|
1566
|
+
}
|
|
1567
|
+
if (!alreadyHas && info) {
|
|
1568
|
+
const prev = subscriberCountByModule.get(info.moduleInstanceKey) ?? 0;
|
|
1569
|
+
subscriberCountByModule.set(info.moduleInstanceKey, prev + 1);
|
|
1570
|
+
}
|
|
1571
|
+
return () => {
|
|
1572
|
+
const currentState = listenersByTopic.get(topicKey);
|
|
1573
|
+
if (!currentState) return;
|
|
1574
|
+
const deleted = currentState.listeners.delete(listener);
|
|
1575
|
+
if (deleted && info) {
|
|
1576
|
+
const prev = subscriberCountByModule.get(info.moduleInstanceKey) ?? 0;
|
|
1577
|
+
const next = prev - 1;
|
|
1578
|
+
if (next <= 0) {
|
|
1579
|
+
subscriberCountByModule.delete(info.moduleInstanceKey);
|
|
1580
|
+
} else {
|
|
1581
|
+
subscriberCountByModule.set(info.moduleInstanceKey, next);
|
|
1582
|
+
}
|
|
1583
|
+
}
|
|
1584
|
+
if (currentState.listeners.size === 0) {
|
|
1585
|
+
listenersByTopic.delete(topicKey);
|
|
1586
|
+
} else if (deleted) {
|
|
1587
|
+
refreshTopicSnapshot(currentState);
|
|
1588
|
+
}
|
|
1589
|
+
};
|
|
1590
|
+
};
|
|
1591
|
+
const getTopicSubscriberCount = (topicKey) => listenersByTopic.get(topicKey)?.listeners.size ?? 0;
|
|
1592
|
+
const getModuleSubscriberCount = (moduleInstanceKey) => subscriberCountByModule.get(moduleInstanceKey) ?? 0;
|
|
1593
|
+
const registerModuleInstance = (args) => {
|
|
1594
|
+
moduleStates.set(args.moduleInstanceKey, args.initialState);
|
|
1595
|
+
if (!topicVersions.has(args.moduleInstanceKey)) {
|
|
1596
|
+
topicVersions.set(args.moduleInstanceKey, 0);
|
|
1597
|
+
topicPriorities.set(args.moduleInstanceKey, "normal");
|
|
1598
|
+
}
|
|
1599
|
+
};
|
|
1600
|
+
const unregisterModuleInstance = (moduleInstanceKey) => {
|
|
1601
|
+
moduleStates.delete(moduleInstanceKey);
|
|
1602
|
+
};
|
|
1603
|
+
const commitTick = (args) => {
|
|
1604
|
+
tickSeq = args.tickSeq;
|
|
1605
|
+
for (const [key, commit] of args.accepted.modules) {
|
|
1606
|
+
moduleStates.set(key, commit.state);
|
|
1607
|
+
}
|
|
1608
|
+
if (args.accepted.dirtyTopics.size === 0) {
|
|
1609
|
+
return {
|
|
1610
|
+
changedTopicListeners: NO_CHANGED_TOPIC_LISTENERS
|
|
1611
|
+
};
|
|
1612
|
+
}
|
|
1613
|
+
if (args.onListener) {
|
|
1614
|
+
let firstTopicListeners;
|
|
1615
|
+
let secondTopicListeners;
|
|
1616
|
+
let restTopicListeners;
|
|
1617
|
+
for (const [topicKey, priority] of args.accepted.dirtyTopics) {
|
|
1618
|
+
commitTopicBump(topicKey, priority);
|
|
1619
|
+
const listeners = listenersByTopic.get(topicKey)?.snapshot ?? EMPTY_LISTENER_SNAPSHOT;
|
|
1620
|
+
if (listeners.length === 0) {
|
|
1621
|
+
continue;
|
|
1622
|
+
}
|
|
1623
|
+
if (!firstTopicListeners) {
|
|
1624
|
+
firstTopicListeners = listeners;
|
|
1625
|
+
continue;
|
|
1626
|
+
}
|
|
1627
|
+
if (!secondTopicListeners) {
|
|
1628
|
+
secondTopicListeners = listeners;
|
|
1629
|
+
continue;
|
|
1630
|
+
}
|
|
1631
|
+
if (!restTopicListeners) {
|
|
1632
|
+
restTopicListeners = [];
|
|
1633
|
+
}
|
|
1634
|
+
restTopicListeners.push(listeners);
|
|
1635
|
+
}
|
|
1636
|
+
if (firstTopicListeners) {
|
|
1637
|
+
for (const listener of firstTopicListeners) {
|
|
1638
|
+
try {
|
|
1639
|
+
args.onListener(listener);
|
|
1640
|
+
} catch {
|
|
1641
|
+
}
|
|
1642
|
+
}
|
|
1643
|
+
}
|
|
1644
|
+
if (secondTopicListeners) {
|
|
1645
|
+
for (const listener of secondTopicListeners) {
|
|
1646
|
+
try {
|
|
1647
|
+
args.onListener(listener);
|
|
1648
|
+
} catch {
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1652
|
+
if (restTopicListeners) {
|
|
1653
|
+
for (const listeners of restTopicListeners) {
|
|
1654
|
+
for (const listener of listeners) {
|
|
1655
|
+
try {
|
|
1656
|
+
args.onListener(listener);
|
|
1657
|
+
} catch {
|
|
1658
|
+
}
|
|
1659
|
+
}
|
|
1660
|
+
}
|
|
1661
|
+
}
|
|
1662
|
+
return {
|
|
1663
|
+
changedTopicListeners: NO_CHANGED_TOPIC_LISTENERS
|
|
1664
|
+
};
|
|
1665
|
+
}
|
|
1666
|
+
let singleTopicListeners;
|
|
1667
|
+
let flattenedTopicListeners;
|
|
1668
|
+
for (const [topicKey, priority] of args.accepted.dirtyTopics) {
|
|
1669
|
+
commitTopicBump(topicKey, priority);
|
|
1670
|
+
const listeners = listenersByTopic.get(topicKey)?.snapshot ?? EMPTY_LISTENER_SNAPSHOT;
|
|
1671
|
+
if (listeners.length === 0) {
|
|
1672
|
+
continue;
|
|
1673
|
+
}
|
|
1674
|
+
if (flattenedTopicListeners) {
|
|
1675
|
+
for (const listener of listeners) {
|
|
1676
|
+
flattenedTopicListeners.push(listener);
|
|
1677
|
+
}
|
|
1678
|
+
continue;
|
|
1679
|
+
}
|
|
1680
|
+
if (!singleTopicListeners) {
|
|
1681
|
+
singleTopicListeners = listeners;
|
|
1682
|
+
continue;
|
|
1683
|
+
}
|
|
1684
|
+
flattenedTopicListeners = Array.from(singleTopicListeners);
|
|
1685
|
+
for (const listener of listeners) {
|
|
1686
|
+
flattenedTopicListeners.push(listener);
|
|
1687
|
+
}
|
|
1688
|
+
}
|
|
1689
|
+
return {
|
|
1690
|
+
changedTopicListeners: flattenedTopicListeners ?? singleTopicListeners ?? NO_CHANGED_TOPIC_LISTENERS
|
|
1691
|
+
};
|
|
1692
|
+
};
|
|
1693
|
+
const getModuleState = (moduleInstanceKey) => moduleStates.get(moduleInstanceKey);
|
|
1694
|
+
const dispose = () => {
|
|
1695
|
+
moduleStates.clear();
|
|
1696
|
+
topicVersions.clear();
|
|
1697
|
+
topicPriorities.clear();
|
|
1698
|
+
listenersByTopic.clear();
|
|
1699
|
+
subscriberCountByModule.clear();
|
|
1700
|
+
};
|
|
1701
|
+
return {
|
|
1702
|
+
getTickSeq: () => tickSeq,
|
|
1703
|
+
getModuleState,
|
|
1704
|
+
getTopicVersion,
|
|
1705
|
+
getTopicPriority,
|
|
1706
|
+
subscribeTopic,
|
|
1707
|
+
getTopicSubscriberCount,
|
|
1708
|
+
getModuleSubscriberCount,
|
|
1709
|
+
registerModuleInstance,
|
|
1710
|
+
unregisterModuleInstance,
|
|
1711
|
+
commitTick,
|
|
1712
|
+
dispose
|
|
1713
|
+
};
|
|
1714
|
+
};
|
|
1715
|
+
|
|
1716
|
+
// src/internal/runtime/core/TickScheduler.ts
|
|
1717
|
+
var import_effect8 = require("effect");
|
|
1718
|
+
|
|
1719
|
+
// src/internal/runtime/core/TaskRunner.ts
|
|
1720
|
+
var import_effect7 = require("effect");
|
|
1721
|
+
|
|
1722
|
+
// src/internal/runtime/core/ModeRunner.ts
|
|
1723
|
+
var import_effect6 = require("effect");
|
|
1724
|
+
|
|
1725
|
+
// src/internal/runtime/core/LatestFiberSlot.ts
|
|
1726
|
+
var import_effect5 = require("effect");
|
|
1727
|
+
|
|
1728
|
+
// src/internal/runtime/core/TaskRunner.ts
|
|
1729
|
+
var inSyncTransactionFiber = import_effect7.ServiceMap.Reference("@logixjs/core/TaskRunner.inSyncTransactionFiber", {
|
|
1730
|
+
defaultValue: () => false
|
|
1731
|
+
});
|
|
1732
|
+
var forceSourceRefresh = import_effect7.ServiceMap.Reference("@logixjs/core/TaskRunner.forceSourceRefresh", {
|
|
1733
|
+
defaultValue: () => false
|
|
1734
|
+
});
|
|
1735
|
+
|
|
1736
|
+
// src/internal/runtime/core/DeclarativeLinkRuntime.ts
|
|
1737
|
+
var import_effect9 = require("effect");
|
|
1738
|
+
var makeDeclarativeLinkRuntime = () => {
|
|
1739
|
+
const moduleAsSourceById = /* @__PURE__ */ new Map();
|
|
1740
|
+
const moduleAsSourceIdsBySource = /* @__PURE__ */ new Map();
|
|
1741
|
+
const declarativeById = /* @__PURE__ */ new Map();
|
|
1742
|
+
const declarativeReadNodesBySource = /* @__PURE__ */ new Map();
|
|
1743
|
+
const registerModuleAsSourceLink = (link) => {
|
|
1744
|
+
const stored = {
|
|
1745
|
+
...link,
|
|
1746
|
+
hasValue: false,
|
|
1747
|
+
lastValue: void 0
|
|
1748
|
+
};
|
|
1749
|
+
moduleAsSourceById.set(link.id, stored);
|
|
1750
|
+
const set = moduleAsSourceIdsBySource.get(link.sourceModuleInstanceKey) ?? /* @__PURE__ */ new Set();
|
|
1751
|
+
set.add(link.id);
|
|
1752
|
+
moduleAsSourceIdsBySource.set(link.sourceModuleInstanceKey, set);
|
|
1753
|
+
return () => {
|
|
1754
|
+
moduleAsSourceById.delete(link.id);
|
|
1755
|
+
const current = moduleAsSourceIdsBySource.get(link.sourceModuleInstanceKey);
|
|
1756
|
+
if (!current) return;
|
|
1757
|
+
current.delete(link.id);
|
|
1758
|
+
if (current.size === 0) {
|
|
1759
|
+
moduleAsSourceIdsBySource.delete(link.sourceModuleInstanceKey);
|
|
1760
|
+
}
|
|
1761
|
+
};
|
|
1762
|
+
};
|
|
1763
|
+
const registerDeclarativeLink = (link) => {
|
|
1764
|
+
const readNodeById = /* @__PURE__ */ new Map();
|
|
1765
|
+
for (const n of link.readNodes) {
|
|
1766
|
+
readNodeById.set(n.nodeId, n);
|
|
1767
|
+
}
|
|
1768
|
+
const dispatchNodeById = /* @__PURE__ */ new Map();
|
|
1769
|
+
for (const n of link.dispatchNodes) {
|
|
1770
|
+
dispatchNodeById.set(n.nodeId, n);
|
|
1771
|
+
}
|
|
1772
|
+
const incomingByDispatch = /* @__PURE__ */ new Map();
|
|
1773
|
+
for (const e of link.ir.edges) {
|
|
1774
|
+
const to = e.to;
|
|
1775
|
+
const isDispatch = dispatchNodeById.has(to);
|
|
1776
|
+
if (!isDispatch) continue;
|
|
1777
|
+
incomingByDispatch.set(to, (incomingByDispatch.get(to) ?? 0) + 1);
|
|
1778
|
+
const count = incomingByDispatch.get(to) ?? 0;
|
|
1779
|
+
if (count > 1) {
|
|
1780
|
+
throw new Error(
|
|
1781
|
+
`[DeclarativeLinkRuntime] Invalid DeclarativeLinkIR: dispatch node has multiple incoming edges (linkId=${link.linkId}, nodeId=${to}).`
|
|
1782
|
+
);
|
|
1783
|
+
}
|
|
1784
|
+
}
|
|
1785
|
+
const dispatchTargetsByReadNode = /* @__PURE__ */ new Map();
|
|
1786
|
+
for (const e of link.ir.edges) {
|
|
1787
|
+
const from = e.from;
|
|
1788
|
+
const to = e.to;
|
|
1789
|
+
if (!readNodeById.has(from)) continue;
|
|
1790
|
+
if (!dispatchNodeById.has(to)) continue;
|
|
1791
|
+
const list = dispatchTargetsByReadNode.get(from) ?? [];
|
|
1792
|
+
list.push(to);
|
|
1793
|
+
dispatchTargetsByReadNode.set(from, list);
|
|
1794
|
+
}
|
|
1795
|
+
const stored = {
|
|
1796
|
+
...link,
|
|
1797
|
+
readNodeById,
|
|
1798
|
+
dispatchNodeById,
|
|
1799
|
+
dispatchTargetsByReadNode,
|
|
1800
|
+
readNodeState: /* @__PURE__ */ new Map()
|
|
1801
|
+
};
|
|
1802
|
+
declarativeById.set(link.linkId, stored);
|
|
1803
|
+
for (const n of link.readNodes) {
|
|
1804
|
+
const list = declarativeReadNodesBySource.get(n.moduleInstanceKey) ?? [];
|
|
1805
|
+
list.push({ linkId: link.linkId, nodeId: n.nodeId });
|
|
1806
|
+
declarativeReadNodesBySource.set(n.moduleInstanceKey, list);
|
|
1807
|
+
}
|
|
1808
|
+
return () => {
|
|
1809
|
+
declarativeById.delete(link.linkId);
|
|
1810
|
+
for (const n of link.readNodes) {
|
|
1811
|
+
const list = declarativeReadNodesBySource.get(n.moduleInstanceKey);
|
|
1812
|
+
if (!list) continue;
|
|
1813
|
+
const next = list.filter((x) => !(x.linkId === link.linkId && x.nodeId === n.nodeId));
|
|
1814
|
+
if (next.length === 0) {
|
|
1815
|
+
declarativeReadNodesBySource.delete(n.moduleInstanceKey);
|
|
1816
|
+
} else {
|
|
1817
|
+
declarativeReadNodesBySource.set(n.moduleInstanceKey, next);
|
|
1818
|
+
}
|
|
1819
|
+
}
|
|
1820
|
+
};
|
|
1821
|
+
};
|
|
1822
|
+
const applyForSources = (args) => import_effect9.Effect.gen(function* () {
|
|
1823
|
+
let scheduled = false;
|
|
1824
|
+
for (const sourceKey of args.changedModuleInstanceKeys) {
|
|
1825
|
+
const ids = moduleAsSourceIdsBySource.get(sourceKey);
|
|
1826
|
+
if (!ids || ids.size === 0) continue;
|
|
1827
|
+
const commit = args.acceptedModules.get(sourceKey);
|
|
1828
|
+
if (!commit) continue;
|
|
1829
|
+
for (const id of ids) {
|
|
1830
|
+
const link = moduleAsSourceById.get(id);
|
|
1831
|
+
if (!link) continue;
|
|
1832
|
+
let selected;
|
|
1833
|
+
try {
|
|
1834
|
+
selected = link.readQuery.select(commit.state);
|
|
1835
|
+
} catch {
|
|
1836
|
+
continue;
|
|
1837
|
+
}
|
|
1838
|
+
const nextValue = link.computeValue(selected);
|
|
1839
|
+
if (link.hasValue && link.equalsValue(link.lastValue, nextValue)) {
|
|
1840
|
+
continue;
|
|
1841
|
+
}
|
|
1842
|
+
link.hasValue = true;
|
|
1843
|
+
link.lastValue = nextValue;
|
|
1844
|
+
scheduled = true;
|
|
1845
|
+
yield* link.applyValue(nextValue);
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
for (const sourceKey of args.changedModuleInstanceKeys) {
|
|
1849
|
+
const refs = declarativeReadNodesBySource.get(sourceKey);
|
|
1850
|
+
if (!refs || refs.length === 0) continue;
|
|
1851
|
+
const commit = args.acceptedModules.get(sourceKey);
|
|
1852
|
+
if (!commit) continue;
|
|
1853
|
+
for (const ref of refs) {
|
|
1854
|
+
const link = declarativeById.get(ref.linkId);
|
|
1855
|
+
if (!link) continue;
|
|
1856
|
+
const readNode = link.readNodeById.get(ref.nodeId);
|
|
1857
|
+
if (!readNode) continue;
|
|
1858
|
+
let value;
|
|
1859
|
+
try {
|
|
1860
|
+
value = readNode.readQuery.select(commit.state);
|
|
1861
|
+
} catch {
|
|
1862
|
+
continue;
|
|
1863
|
+
}
|
|
1864
|
+
const state = link.readNodeState.get(ref.nodeId) ?? { hasValue: false, lastValue: void 0 };
|
|
1865
|
+
const changed = !state.hasValue || !Object.is(state.lastValue, value);
|
|
1866
|
+
if (!changed) continue;
|
|
1867
|
+
state.hasValue = true;
|
|
1868
|
+
state.lastValue = value;
|
|
1869
|
+
link.readNodeState.set(ref.nodeId, state);
|
|
1870
|
+
const targets = link.dispatchTargetsByReadNode.get(ref.nodeId) ?? [];
|
|
1871
|
+
for (const dispatchNodeId of targets) {
|
|
1872
|
+
const node = link.dispatchNodeById.get(dispatchNodeId);
|
|
1873
|
+
if (!node) continue;
|
|
1874
|
+
scheduled = true;
|
|
1875
|
+
yield* node.dispatch(value);
|
|
1876
|
+
}
|
|
1877
|
+
}
|
|
1878
|
+
}
|
|
1879
|
+
return { scheduled };
|
|
1880
|
+
});
|
|
1881
|
+
return {
|
|
1882
|
+
registerModuleAsSourceLink,
|
|
1883
|
+
registerDeclarativeLink,
|
|
1884
|
+
applyForSources
|
|
1885
|
+
};
|
|
1886
|
+
};
|
|
1887
|
+
|
|
1888
|
+
// src/internal/runtime/core/env.ts
|
|
1889
|
+
var getNodeEnv = () => {
|
|
1890
|
+
try {
|
|
1891
|
+
const env = globalThis?.process?.env;
|
|
1892
|
+
return typeof env?.NODE_ENV === "string" ? env.NODE_ENV : void 0;
|
|
1893
|
+
} catch {
|
|
1894
|
+
return void 0;
|
|
1895
|
+
}
|
|
1896
|
+
};
|
|
1897
|
+
var isDevEnv = () => getNodeEnv() !== "production";
|
|
1898
|
+
var StateTransactionConfigTagImpl = class extends import_effect10.ServiceMap.Service()("@logixjs/core/StateTransactionRuntimeConfig") {
|
|
1899
|
+
};
|
|
1900
|
+
var ReadQueryStrictGateConfigTagImpl = class extends import_effect10.ServiceMap.Service()("@logixjs/core/ReadQueryStrictGateRuntimeConfig") {
|
|
1901
|
+
};
|
|
1902
|
+
var ReplayModeConfigTagImpl = class extends import_effect10.ServiceMap.Service()("@logixjs/core/ReplayModeConfig") {
|
|
1903
|
+
};
|
|
1904
|
+
var StateTransactionOverridesTagImpl = class extends import_effect10.ServiceMap.Service()("@logixjs/core/StateTransactionOverrides") {
|
|
1905
|
+
};
|
|
1906
|
+
var SchedulingPolicySurfaceTagImpl = class extends import_effect10.ServiceMap.Service()("@logixjs/core/SchedulingPolicySurface") {
|
|
1907
|
+
};
|
|
1908
|
+
var SchedulingPolicySurfaceOverridesTagImpl = class extends import_effect10.ServiceMap.Service()("@logixjs/core/SchedulingPolicySurfaceOverrides") {
|
|
1909
|
+
};
|
|
1910
|
+
var RuntimeStoreTag = class extends import_effect10.ServiceMap.Service()("@logixjs/core/RuntimeStore") {
|
|
1911
|
+
};
|
|
1912
|
+
var runtimeStoreLayer = import_effect10.Layer.effect(
|
|
1913
|
+
RuntimeStoreTag,
|
|
1914
|
+
import_effect10.Effect.acquireRelease(
|
|
1915
|
+
import_effect10.Effect.sync(() => makeRuntimeStore()),
|
|
1916
|
+
(store) => import_effect10.Effect.sync(() => store.dispose())
|
|
1917
|
+
)
|
|
1918
|
+
);
|
|
1919
|
+
var HostSchedulerTag = class extends import_effect10.ServiceMap.Service()("@logixjs/core/HostScheduler") {
|
|
1920
|
+
};
|
|
1921
|
+
var hostSchedulerLayer = import_effect10.Layer.succeed(
|
|
1922
|
+
HostSchedulerTag,
|
|
1923
|
+
getGlobalHostScheduler()
|
|
1924
|
+
);
|
|
1925
|
+
var DeclarativeLinkRuntimeTag = class extends import_effect10.ServiceMap.Service()("@logixjs/core/DeclarativeLinkRuntime") {
|
|
1926
|
+
};
|
|
1927
|
+
var declarativeLinkRuntimeLayer = import_effect10.Layer.succeed(
|
|
1928
|
+
DeclarativeLinkRuntimeTag,
|
|
1929
|
+
makeDeclarativeLinkRuntime()
|
|
1930
|
+
);
|
|
1931
|
+
var TickSchedulerTag = class extends import_effect10.ServiceMap.Service()("@logixjs/core/TickScheduler") {
|
|
1932
|
+
};
|
|
1933
|
+
|
|
1934
|
+
// src/internal/runtime/core/runtimeInternalsAccessor.ts
|
|
1935
|
+
var RUNTIME_INTERNALS = /* @__PURE__ */ Symbol.for("@logixjs/core/runtimeInternals");
|
|
1936
|
+
var formatScope = (moduleId, instanceId) => {
|
|
1937
|
+
const m = typeof moduleId === "string" && moduleId.length > 0 ? moduleId : "unknown";
|
|
1938
|
+
const i = typeof instanceId === "string" && instanceId.length > 0 ? instanceId : "unknown";
|
|
1939
|
+
return `moduleId=${m}, instanceId=${i}`;
|
|
1940
|
+
};
|
|
1941
|
+
var getRuntimeInternals = (runtime) => {
|
|
1942
|
+
const scope = runtime;
|
|
1943
|
+
const internals = runtime[RUNTIME_INTERNALS];
|
|
1944
|
+
if (!internals) {
|
|
1945
|
+
const msg = isDevEnv() ? [
|
|
1946
|
+
"[MissingRuntimeInternals] Runtime internals not installed on ModuleRuntime instance.",
|
|
1947
|
+
`scope: ${formatScope(scope.moduleId, scope.instanceId)}`,
|
|
1948
|
+
"fix:",
|
|
1949
|
+
"- Ensure ModuleRuntime.make calls internalHooks.installInternalHooks (020 foundation).",
|
|
1950
|
+
"- If you created a mock runtime for tests, attach internals or avoid calling internal-only APIs."
|
|
1951
|
+
].join("\n") : "Runtime internals not installed";
|
|
1952
|
+
throw new Error(msg);
|
|
1953
|
+
}
|
|
1954
|
+
const runtimeInstanceId = scope.instanceId;
|
|
1955
|
+
if (typeof runtimeInstanceId === "string" && runtimeInstanceId.length > 0 && runtimeInstanceId !== internals.instanceId) {
|
|
1956
|
+
throw new Error(
|
|
1957
|
+
isDevEnv() ? [
|
|
1958
|
+
"[InconsistentRuntimeInternals] Runtime internals instanceId mismatch.",
|
|
1959
|
+
`runtime: ${formatScope(scope.moduleId, runtimeInstanceId)}`,
|
|
1960
|
+
`internals: ${formatScope(internals.moduleId, internals.instanceId)}`
|
|
1961
|
+
].join("\n") : "Runtime internals mismatch"
|
|
1962
|
+
);
|
|
1963
|
+
}
|
|
1964
|
+
return internals;
|
|
1965
|
+
};
|
|
1966
|
+
|
|
1967
|
+
// src/internal/runtime/core/RootContext.ts
|
|
1968
|
+
var import_effect11 = require("effect");
|
|
1969
|
+
var RootContextTagImpl = class extends import_effect11.ServiceMap.Service()("@logixjs/core/RootContext") {
|
|
1970
|
+
};
|
|
1971
|
+
var RootContextTag = RootContextTagImpl;
|
|
1972
|
+
|
|
1973
|
+
// src/internal/runtime/core/diagnosticsBudget.ts
|
|
1974
|
+
var DIAGNOSTICS_BUDGET_CONTRACT_V1 = "diagnostics_budget.v1";
|
|
1975
|
+
var normalizePositiveInteger = (value) => {
|
|
1976
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) return void 0;
|
|
1977
|
+
return Math.floor(value);
|
|
1978
|
+
};
|
|
1979
|
+
var makeRunBudgetEnvelopeV1 = (args) => {
|
|
1980
|
+
const maxEvents = normalizePositiveInteger(args.limits?.maxEvents);
|
|
1981
|
+
const maxBytes = normalizePositiveInteger(args.limits?.maxBytes);
|
|
1982
|
+
const emitted = normalizePositiveInteger(args.usage?.emitted);
|
|
1983
|
+
const dropped = normalizePositiveInteger(args.usage?.dropped);
|
|
1984
|
+
const downgraded = normalizePositiveInteger(args.usage?.downgraded);
|
|
1985
|
+
return {
|
|
1986
|
+
contract: DIAGNOSTICS_BUDGET_CONTRACT_V1,
|
|
1987
|
+
domain: args.domain,
|
|
1988
|
+
runId: args.runId,
|
|
1989
|
+
...maxEvents !== void 0 || maxBytes !== void 0 ? {
|
|
1990
|
+
limits: {
|
|
1991
|
+
...maxEvents !== void 0 ? { maxEvents } : null,
|
|
1992
|
+
...maxBytes !== void 0 ? { maxBytes } : null
|
|
1993
|
+
}
|
|
1994
|
+
} : null,
|
|
1995
|
+
...emitted !== void 0 || dropped !== void 0 || downgraded !== void 0 ? {
|
|
1996
|
+
usage: {
|
|
1997
|
+
...emitted !== void 0 ? { emitted } : null,
|
|
1998
|
+
...dropped !== void 0 ? { dropped } : null,
|
|
1999
|
+
...downgraded !== void 0 ? { downgraded } : null
|
|
2000
|
+
}
|
|
2001
|
+
} : null
|
|
2002
|
+
};
|
|
2003
|
+
};
|
|
2004
|
+
var makeRunDegradeMarkerV1 = (degraded, reason) => ({
|
|
2005
|
+
contract: DIAGNOSTICS_BUDGET_CONTRACT_V1,
|
|
2006
|
+
degraded,
|
|
2007
|
+
...degraded && reason ? { reason } : null
|
|
2008
|
+
});
|
|
2009
|
+
|
|
2010
|
+
// src/internal/effect-op.ts
|
|
2011
|
+
var import_effect13 = require("effect");
|
|
2012
|
+
|
|
2013
|
+
// src/internal/observability/runSession.ts
|
|
2014
|
+
var import_effect12 = require("effect");
|
|
2015
|
+
var RunSessionTagImpl = class extends import_effect12.ServiceMap.Service()("@logixjs/core/RunSession") {
|
|
2016
|
+
};
|
|
2017
|
+
var RunSessionTag = RunSessionTagImpl;
|
|
2018
|
+
|
|
2019
|
+
// src/internal/effect-op.ts
|
|
2020
|
+
var nextGlobalOpSeq = 0;
|
|
2021
|
+
var nextOpSeq = () => {
|
|
2022
|
+
nextGlobalOpSeq += 1;
|
|
2023
|
+
return nextGlobalOpSeq;
|
|
2024
|
+
};
|
|
2025
|
+
var makeId = (instanceId, opSeq) => instanceId ? `${instanceId}::o${opSeq}` : `o${opSeq}`;
|
|
2026
|
+
var makeInRunSession = (params) => import_effect13.Effect.gen(function* () {
|
|
2027
|
+
if (params.id) {
|
|
2028
|
+
return {
|
|
2029
|
+
id: params.id,
|
|
2030
|
+
kind: params.kind,
|
|
2031
|
+
name: params.name,
|
|
2032
|
+
payload: params.payload,
|
|
2033
|
+
meta: params.meta,
|
|
2034
|
+
effect: params.effect
|
|
2035
|
+
};
|
|
2036
|
+
}
|
|
2037
|
+
const meta = params.meta ?? {};
|
|
2038
|
+
const instanceId = meta.instanceId;
|
|
2039
|
+
let opSeq;
|
|
2040
|
+
if (typeof meta.opSeq === "number" && Number.isFinite(meta.opSeq)) {
|
|
2041
|
+
opSeq = Math.floor(meta.opSeq);
|
|
2042
|
+
} else {
|
|
2043
|
+
const sessionOpt = yield* import_effect13.Effect.serviceOption(RunSessionTag);
|
|
2044
|
+
if (import_effect13.Option.isSome(sessionOpt)) {
|
|
2045
|
+
const key = instanceId ?? "global";
|
|
2046
|
+
opSeq = sessionOpt.value.local.nextSeq("opSeq", key);
|
|
2047
|
+
} else {
|
|
2048
|
+
opSeq = nextOpSeq();
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
2051
|
+
return {
|
|
2052
|
+
id: makeId(instanceId, opSeq),
|
|
2053
|
+
kind: params.kind,
|
|
2054
|
+
name: params.name,
|
|
2055
|
+
payload: params.payload,
|
|
2056
|
+
meta: meta.opSeq === opSeq ? meta : { ...meta, opSeq },
|
|
2057
|
+
effect: params.effect
|
|
2058
|
+
};
|
|
2059
|
+
});
|
|
2060
|
+
var run = (op, stack) => runWithMiddleware(op, stack);
|
|
2061
|
+
|
|
2062
|
+
// src/internal/runtime/core/WorkflowRuntime.ts
|
|
2063
|
+
var WORKFLOW_REGISTRY = /* @__PURE__ */ Symbol.for("@logixjs/core/workflowRegistry");
|
|
2064
|
+
var isRecord3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2065
|
+
var isObjectLike = (value) => typeof value === "object" && value !== null || typeof value === "function";
|
|
2066
|
+
var getRegistry = (runtime) => runtime[WORKFLOW_REGISTRY];
|
|
2067
|
+
var resolveActionTag = (action) => {
|
|
2068
|
+
const tag = isObjectLike(action) ? action._tag : void 0;
|
|
2069
|
+
if (typeof tag === "string" && tag.length > 0) return tag;
|
|
2070
|
+
const type = isObjectLike(action) ? action.type : void 0;
|
|
2071
|
+
if (typeof type === "string" && type.length > 0) return type;
|
|
2072
|
+
if (tag != null) return String(tag);
|
|
2073
|
+
if (type != null) return String(type);
|
|
2074
|
+
return void 0;
|
|
2075
|
+
};
|
|
2076
|
+
var asNonEmptyString3 = (value) => typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
|
|
2077
|
+
var KERNEL_PORT_SOURCE_REFRESH = "logix/kernel/sourceRefresh";
|
|
2078
|
+
var resolveServicePort = (runtime, env, serviceId, programId, stepKey) => {
|
|
2079
|
+
if (serviceId === KERNEL_PORT_SOURCE_REFRESH) {
|
|
2080
|
+
return (input) => import_effect14.Effect.gen(function* () {
|
|
2081
|
+
const fieldPath = asNonEmptyString3(isRecord3(input) ? input.fieldPath : void 0);
|
|
2082
|
+
if (!fieldPath) {
|
|
2083
|
+
throw makeWorkflowError({
|
|
2084
|
+
code: "WORKFLOW_INVALID_STEP",
|
|
2085
|
+
message: "KernelPort sourceRefresh requires input.fieldPath (non-empty string).",
|
|
2086
|
+
programId,
|
|
2087
|
+
source: { stepKey },
|
|
2088
|
+
detail: { serviceId, input }
|
|
2089
|
+
});
|
|
2090
|
+
}
|
|
2091
|
+
const internals = getRuntimeInternals(runtime);
|
|
2092
|
+
const handler = internals.traits.getSourceRefreshHandler(fieldPath);
|
|
2093
|
+
if (!handler) {
|
|
2094
|
+
return;
|
|
2095
|
+
}
|
|
2096
|
+
const force = isRecord3(input) && input.force === true;
|
|
2097
|
+
const runHandler = (state) => force ? import_effect14.Effect.provideService(handler(state), forceSourceRefresh, true) : handler(state);
|
|
2098
|
+
const inTxn = yield* import_effect14.Effect.service(inSyncTransactionFiber).pipe(import_effect14.Effect.orDie);
|
|
2099
|
+
if (inTxn) {
|
|
2100
|
+
const state = yield* runtime.getState;
|
|
2101
|
+
yield* runHandler(state);
|
|
2102
|
+
return;
|
|
2103
|
+
}
|
|
2104
|
+
yield* internals.txn.runWithStateTransaction(
|
|
2105
|
+
{
|
|
2106
|
+
kind: "source-refresh",
|
|
2107
|
+
name: fieldPath
|
|
2108
|
+
},
|
|
2109
|
+
() => import_effect14.Effect.gen(function* () {
|
|
2110
|
+
const state = yield* runtime.getState;
|
|
2111
|
+
yield* runHandler(state);
|
|
2112
|
+
})
|
|
2113
|
+
);
|
|
2114
|
+
});
|
|
2115
|
+
}
|
|
2116
|
+
const tag = tagFromServiceId(serviceId);
|
|
2117
|
+
const opt = import_effect14.ServiceMap.getOption(env, tag);
|
|
2118
|
+
if (import_effect14.Option.isNone(opt)) {
|
|
2119
|
+
throw makeWorkflowError({
|
|
2120
|
+
code: "WORKFLOW_MISSING_SERVICE",
|
|
2121
|
+
message: `Missing service for serviceId="${serviceId}".`,
|
|
2122
|
+
programId,
|
|
2123
|
+
source: { stepKey },
|
|
2124
|
+
detail: { serviceId }
|
|
2125
|
+
});
|
|
2126
|
+
}
|
|
2127
|
+
const value = opt.value;
|
|
2128
|
+
if (typeof value === "function") {
|
|
2129
|
+
const fn = value;
|
|
2130
|
+
return (input) => fn(input);
|
|
2131
|
+
}
|
|
2132
|
+
const callFn = isObjectLike(value) ? value.call : void 0;
|
|
2133
|
+
if (typeof callFn === "function") {
|
|
2134
|
+
const call2 = callFn;
|
|
2135
|
+
return (input) => call2.call(value, input);
|
|
2136
|
+
}
|
|
2137
|
+
throw makeWorkflowError({
|
|
2138
|
+
code: "WORKFLOW_INVALID_SERVICE_PORT",
|
|
2139
|
+
message: `Invalid service port for serviceId="${serviceId}" (expected a function or { call(input): Effect }).`,
|
|
2140
|
+
programId,
|
|
2141
|
+
source: { stepKey },
|
|
2142
|
+
detail: { serviceId, portType: typeof value }
|
|
2143
|
+
});
|
|
2144
|
+
};
|
|
2145
|
+
var compileSteps = (steps, resolvePort) => {
|
|
2146
|
+
const visit = (step) => {
|
|
2147
|
+
switch (step.kind) {
|
|
2148
|
+
case "dispatch":
|
|
2149
|
+
return {
|
|
2150
|
+
kind: "dispatch",
|
|
2151
|
+
key: step.key,
|
|
2152
|
+
actionTag: step.actionTag,
|
|
2153
|
+
...step.payload ? { payload: step.payload } : null
|
|
2154
|
+
};
|
|
2155
|
+
case "delay":
|
|
2156
|
+
return { kind: "delay", key: step.key, ms: step.ms };
|
|
2157
|
+
case "call":
|
|
2158
|
+
return {
|
|
2159
|
+
kind: "call",
|
|
2160
|
+
key: step.key,
|
|
2161
|
+
serviceId: step.serviceId,
|
|
2162
|
+
port: resolvePort(step.serviceId, step.key),
|
|
2163
|
+
...step.input ? { input: step.input } : null,
|
|
2164
|
+
...step.timeoutMs !== void 0 ? { timeoutMs: step.timeoutMs } : null,
|
|
2165
|
+
...step.retryTimes !== void 0 ? { retryTimes: step.retryTimes } : null,
|
|
2166
|
+
onSuccess: step.onSuccess.map(visit),
|
|
2167
|
+
onFailure: step.onFailure.map(visit)
|
|
2168
|
+
};
|
|
2169
|
+
}
|
|
2170
|
+
};
|
|
2171
|
+
return steps.map(visit);
|
|
2172
|
+
};
|
|
2173
|
+
var resolveConcurrency = (def) => def.policy?.concurrency ?? "parallel";
|
|
2174
|
+
var resolvePriority = (def) => def.policy?.priority ?? "urgent";
|
|
2175
|
+
var makeRunId = (instanceId, programId, runSeq) => `${instanceId}::wf:${programId}::r${runSeq}`;
|
|
2176
|
+
var makeWorkflowRunBudgetMeta = (args) => ({
|
|
2177
|
+
budgetEnvelope: makeRunBudgetEnvelopeV1({
|
|
2178
|
+
domain: "workflow",
|
|
2179
|
+
runId: args.runId
|
|
2180
|
+
}),
|
|
2181
|
+
degrade: makeRunDegradeMarkerV1(
|
|
2182
|
+
!args.observed,
|
|
2183
|
+
args.observed ? void 0 : args.diagnostics === "sampled" ? "sampled_out" : "observer_disabled"
|
|
2184
|
+
)
|
|
2185
|
+
});
|
|
2186
|
+
var runBoundary = (args) => import_effect14.Effect.gen(function* () {
|
|
2187
|
+
const op = yield* makeInRunSession({
|
|
2188
|
+
kind: args.kind,
|
|
2189
|
+
name: args.name,
|
|
2190
|
+
effect: args.effect,
|
|
2191
|
+
payload: args.payload,
|
|
2192
|
+
meta: args.meta
|
|
2193
|
+
});
|
|
2194
|
+
const stack = args.middleware?.stack ?? [];
|
|
2195
|
+
return yield* run(op, stack);
|
|
2196
|
+
});
|
|
2197
|
+
var makeWorkflowBoundaryRunner = (args) => {
|
|
2198
|
+
const baseMeta = {
|
|
2199
|
+
moduleId: args.runtime.moduleId,
|
|
2200
|
+
instanceId: args.runtime.instanceId,
|
|
2201
|
+
programId: args.programId
|
|
2202
|
+
};
|
|
2203
|
+
return (boundary) => runBoundary({
|
|
2204
|
+
kind: boundary.kind,
|
|
2205
|
+
name: boundary.name,
|
|
2206
|
+
effect: boundary.effect,
|
|
2207
|
+
payload: boundary.payload,
|
|
2208
|
+
meta: {
|
|
2209
|
+
...baseMeta,
|
|
2210
|
+
...boundary.meta ?? null
|
|
2211
|
+
},
|
|
2212
|
+
middleware: args.middleware
|
|
2213
|
+
});
|
|
2214
|
+
};
|
|
2215
|
+
var makeTimer = (args) => import_effect14.Effect.promise(
|
|
2216
|
+
(signal) => new Promise((resolve) => {
|
|
2217
|
+
let fired = false;
|
|
2218
|
+
const cancel = args.ms <= 0 ? args.host.scheduleMacrotask(() => {
|
|
2219
|
+
fired = true;
|
|
2220
|
+
args.host.scheduleMicrotask(resolve);
|
|
2221
|
+
}) : args.host.scheduleTimeout(args.ms, () => {
|
|
2222
|
+
fired = true;
|
|
2223
|
+
args.host.scheduleMicrotask(resolve);
|
|
2224
|
+
});
|
|
2225
|
+
const onAbort = () => {
|
|
2226
|
+
cancel();
|
|
2227
|
+
if (!fired) {
|
|
2228
|
+
void import_effect14.Effect.runPromise(args.onCancel);
|
|
2229
|
+
}
|
|
2230
|
+
};
|
|
2231
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
2232
|
+
})
|
|
2233
|
+
);
|
|
2234
|
+
var ensureLimiterReady = (registry, runtime) => import_effect14.Effect.gen(function* () {
|
|
2235
|
+
if (registry.parallelLimiter !== void 0) return;
|
|
2236
|
+
const internals = getRuntimeInternals(runtime);
|
|
2237
|
+
const policy = yield* internals.concurrency.resolveConcurrencyPolicy();
|
|
2238
|
+
const limit = policy.concurrencyLimit;
|
|
2239
|
+
if (limit === "unbounded") {
|
|
2240
|
+
registry.parallelLimiter = null;
|
|
2241
|
+
return;
|
|
2242
|
+
}
|
|
2243
|
+
const n = typeof limit === "number" && Number.isFinite(limit) && limit >= 1 ? Math.floor(limit) : 16;
|
|
2244
|
+
registry.parallelLimiter = yield* import_effect14.Semaphore.make(n);
|
|
2245
|
+
});
|
|
2246
|
+
var withRootEnvIfAvailable = (eff) => import_effect14.Effect.gen(function* () {
|
|
2247
|
+
const rootOpt = yield* import_effect14.Effect.serviceOption(RootContextTag);
|
|
2248
|
+
if (import_effect14.Option.isNone(rootOpt)) {
|
|
2249
|
+
return yield* eff;
|
|
2250
|
+
}
|
|
2251
|
+
const root = rootOpt.value;
|
|
2252
|
+
const rootEnv = root.context ?? (yield* import_effect14.Deferred.await(root.ready));
|
|
2253
|
+
const currentEnv = yield* import_effect14.Effect.services();
|
|
2254
|
+
const mergedEnv = import_effect14.ServiceMap.merge(rootEnv, currentEnv);
|
|
2255
|
+
return yield* import_effect14.Effect.provideServices(eff, mergedEnv);
|
|
2256
|
+
});
|
|
2257
|
+
var ensurePortsResolved = (registry, runtime) => import_effect14.Effect.gen(function* () {
|
|
2258
|
+
const done = yield* import_effect14.Deferred.isDone(registry.portsReady);
|
|
2259
|
+
if (done) {
|
|
2260
|
+
yield* import_effect14.Deferred.await(registry.portsReady);
|
|
2261
|
+
return;
|
|
2262
|
+
}
|
|
2263
|
+
if (registry.portsResolving) {
|
|
2264
|
+
yield* import_effect14.Deferred.await(registry.portsReady);
|
|
2265
|
+
return;
|
|
2266
|
+
}
|
|
2267
|
+
registry.portsResolving = true;
|
|
2268
|
+
const env = yield* import_effect14.Effect.services();
|
|
2269
|
+
yield* import_effect14.Effect.sync(() => {
|
|
2270
|
+
const portCache = /* @__PURE__ */ new Map();
|
|
2271
|
+
for (const entry of registry.entries) {
|
|
2272
|
+
const program = entry.program;
|
|
2273
|
+
if (program.steps) continue;
|
|
2274
|
+
const resolvePort = (serviceId, stepKey) => {
|
|
2275
|
+
const cached = portCache.get(serviceId);
|
|
2276
|
+
if (cached) return cached;
|
|
2277
|
+
const resolved = resolveServicePort(runtime, env, serviceId, program.programId, stepKey);
|
|
2278
|
+
portCache.set(serviceId, resolved);
|
|
2279
|
+
return resolved;
|
|
2280
|
+
};
|
|
2281
|
+
program.steps = compileSteps(program.compiledSteps, resolvePort);
|
|
2282
|
+
}
|
|
2283
|
+
}).pipe(
|
|
2284
|
+
import_effect14.Effect.tap(() => import_effect14.Deferred.succeed(registry.portsReady, void 0)),
|
|
2285
|
+
import_effect14.Effect.catchCause((cause) => import_effect14.Deferred.failCause(registry.portsReady, cause).pipe(import_effect14.Effect.flatMap(() => import_effect14.Effect.failCause(cause)))),
|
|
2286
|
+
import_effect14.Effect.ensuring(
|
|
2287
|
+
import_effect14.Effect.sync(() => {
|
|
2288
|
+
registry.portsResolving = false;
|
|
2289
|
+
})
|
|
2290
|
+
)
|
|
2291
|
+
);
|
|
2292
|
+
});
|
|
2293
|
+
var shouldObserveForRun = (diagnostics, runSeq) => {
|
|
2294
|
+
if (diagnostics === "off") return false;
|
|
2295
|
+
if (diagnostics === "sampled") {
|
|
2296
|
+
return (runSeq & 15) === 0;
|
|
2297
|
+
}
|
|
2298
|
+
return true;
|
|
2299
|
+
};
|
|
2300
|
+
var startProgramRun = (args) => import_effect14.Effect.gen(function* () {
|
|
2301
|
+
const { entry, runtime, registry } = args;
|
|
2302
|
+
const { program, state } = entry;
|
|
2303
|
+
const runWorkflowBoundary = makeWorkflowBoundaryRunner({
|
|
2304
|
+
runtime,
|
|
2305
|
+
programId: program.programId,
|
|
2306
|
+
middleware: args.middleware
|
|
2307
|
+
});
|
|
2308
|
+
const diagnostics = yield* import_effect14.Effect.service(currentDiagnosticsLevel).pipe(import_effect14.Effect.orDie);
|
|
2309
|
+
const beginRun2 = () => {
|
|
2310
|
+
if (state.mode === "latest") {
|
|
2311
|
+
state.runSeq += 1;
|
|
2312
|
+
const runSeq3 = state.runSeq;
|
|
2313
|
+
const runId3 = makeRunId(runtime.instanceId, program.programId, runSeq3);
|
|
2314
|
+
return {
|
|
2315
|
+
runSeq: runSeq3,
|
|
2316
|
+
runId: runId3,
|
|
2317
|
+
canWriteBack: () => state.runSeq === runSeq3
|
|
2318
|
+
};
|
|
2319
|
+
}
|
|
2320
|
+
state.runSeq += 1;
|
|
2321
|
+
const runSeq2 = state.runSeq;
|
|
2322
|
+
const runId2 = makeRunId(runtime.instanceId, program.programId, runSeq2);
|
|
2323
|
+
return {
|
|
2324
|
+
runSeq: runSeq2,
|
|
2325
|
+
runId: runId2,
|
|
2326
|
+
canWriteBack: () => true
|
|
2327
|
+
};
|
|
2328
|
+
};
|
|
2329
|
+
if (state.mode === "exhaust") {
|
|
2330
|
+
if (state.busy) {
|
|
2331
|
+
if (diagnostics !== "off") {
|
|
2332
|
+
const observe2 = shouldObserveForRun(diagnostics, state.runSeq);
|
|
2333
|
+
const tickScheduler = yield* import_effect14.Effect.service(TickSchedulerTag).pipe(import_effect14.Effect.orDie);
|
|
2334
|
+
const tickSeq = observe2 ? tickScheduler.getTickSeq() : void 0;
|
|
2335
|
+
yield* runWorkflowBoundary({
|
|
2336
|
+
kind: "flow",
|
|
2337
|
+
name: "workflow.drop",
|
|
2338
|
+
payload: { programId: program.programId, trigger: args.trigger },
|
|
2339
|
+
meta: {
|
|
2340
|
+
...tickSeq !== void 0 ? { tickSeq } : null,
|
|
2341
|
+
policy: { disableObservers: !observe2 },
|
|
2342
|
+
reason: "exhaust"
|
|
2343
|
+
},
|
|
2344
|
+
effect: import_effect14.Effect.void
|
|
2345
|
+
});
|
|
2346
|
+
}
|
|
2347
|
+
return;
|
|
2348
|
+
}
|
|
2349
|
+
state.busy = true;
|
|
2350
|
+
}
|
|
2351
|
+
const { runSeq, runId, canWriteBack } = beginRun2();
|
|
2352
|
+
if (state.mode === "latest") {
|
|
2353
|
+
const prev = state.current;
|
|
2354
|
+
const prevRunId = state.currentRunId;
|
|
2355
|
+
if (prev) {
|
|
2356
|
+
yield* import_effect14.Fiber.interrupt(prev);
|
|
2357
|
+
if (diagnostics !== "off") {
|
|
2358
|
+
const observe2 = shouldObserveForRun(diagnostics, runSeq);
|
|
2359
|
+
const tickScheduler = yield* import_effect14.Effect.service(TickSchedulerTag).pipe(import_effect14.Effect.orDie);
|
|
2360
|
+
const tickSeq = observe2 ? tickScheduler.getTickSeq() : void 0;
|
|
2361
|
+
yield* runWorkflowBoundary({
|
|
2362
|
+
kind: "flow",
|
|
2363
|
+
name: "workflow.cancel",
|
|
2364
|
+
payload: { programId: program.programId, cancelled: prevRunId, by: runId },
|
|
2365
|
+
meta: {
|
|
2366
|
+
...makeWorkflowRunBudgetMeta({
|
|
2367
|
+
runId,
|
|
2368
|
+
diagnostics,
|
|
2369
|
+
observed: observe2
|
|
2370
|
+
}),
|
|
2371
|
+
...tickSeq !== void 0 ? { tickSeq } : null,
|
|
2372
|
+
policy: { disableObservers: !observe2 },
|
|
2373
|
+
reason: "latest",
|
|
2374
|
+
cancelledByRunId: runId,
|
|
2375
|
+
cancelledRunId: prevRunId
|
|
2376
|
+
},
|
|
2377
|
+
effect: import_effect14.Effect.void
|
|
2378
|
+
});
|
|
2379
|
+
}
|
|
2380
|
+
}
|
|
2381
|
+
state.currentRunId = runId;
|
|
2382
|
+
}
|
|
2383
|
+
const observe = shouldObserveForRun(diagnostics, runSeq);
|
|
2384
|
+
const policy = { disableObservers: !observe };
|
|
2385
|
+
const runBudgetMeta = makeWorkflowRunBudgetMeta({
|
|
2386
|
+
runId,
|
|
2387
|
+
diagnostics,
|
|
2388
|
+
observed: observe
|
|
2389
|
+
});
|
|
2390
|
+
const programEffect = import_effect14.Effect.gen(function* () {
|
|
2391
|
+
const host = yield* import_effect14.Effect.service(HostSchedulerTag).pipe(import_effect14.Effect.orDie);
|
|
2392
|
+
const tick = yield* import_effect14.Effect.service(TickSchedulerTag).pipe(import_effect14.Effect.orDie);
|
|
2393
|
+
if (!program.steps) {
|
|
2394
|
+
throw makeWorkflowError({
|
|
2395
|
+
code: "WORKFLOW_INVALID_DEF",
|
|
2396
|
+
message: `Workflow steps were not resolved before run (programId="${program.programId}").`,
|
|
2397
|
+
programId: program.programId,
|
|
2398
|
+
detail: { programId: program.programId }
|
|
2399
|
+
});
|
|
2400
|
+
}
|
|
2401
|
+
const getTickSeq = () => observe ? tick.getTickSeq() : void 0;
|
|
2402
|
+
const emitTimerEvents = observe && diagnostics === "full";
|
|
2403
|
+
const evalPayload = (expr) => expr ? evalInputExpr(expr, args.payload) : void 0;
|
|
2404
|
+
const defaultInputForCall = () => args.trigger.kind === "action" ? args.payload : void 0;
|
|
2405
|
+
let timerTriggered = false;
|
|
2406
|
+
const runSteps = (steps) => import_effect14.Effect.gen(function* () {
|
|
2407
|
+
for (const step of steps) {
|
|
2408
|
+
if (!canWriteBack()) return;
|
|
2409
|
+
if (step.kind === "dispatch") {
|
|
2410
|
+
const payload2 = evalPayload(step.payload);
|
|
2411
|
+
const action = { _tag: step.actionTag, payload: payload2 };
|
|
2412
|
+
const tickSeq = getTickSeq();
|
|
2413
|
+
const timerOriginOverride = timerTriggered ? {
|
|
2414
|
+
kind: "workflow.timer",
|
|
2415
|
+
name: `timer:${program.programId}:${step.key}`
|
|
2416
|
+
} : void 0;
|
|
2417
|
+
const internals = timerOriginOverride ? getRuntimeInternals(runtime) : void 0;
|
|
2418
|
+
const dispatchEffectBase = program.priority === "nonUrgent" ? timerOriginOverride ? internals.txn.dispatchLowPriorityWithOriginOverride(action, timerOriginOverride) : runtime.dispatchLowPriority(action) : timerOriginOverride ? internals.txn.dispatchWithOriginOverride(action, timerOriginOverride) : runtime.dispatch(action);
|
|
2419
|
+
yield* runWorkflowBoundary({
|
|
2420
|
+
kind: "flow",
|
|
2421
|
+
name: "workflow.dispatch",
|
|
2422
|
+
payload: { actionTag: step.actionTag },
|
|
2423
|
+
meta: {
|
|
2424
|
+
runId,
|
|
2425
|
+
...runBudgetMeta,
|
|
2426
|
+
stepKey: step.key,
|
|
2427
|
+
...tickSeq !== void 0 ? { tickSeq } : null,
|
|
2428
|
+
policy
|
|
2429
|
+
},
|
|
2430
|
+
effect: dispatchEffectBase
|
|
2431
|
+
}).pipe(import_effect14.Effect.asVoid);
|
|
2432
|
+
continue;
|
|
2433
|
+
}
|
|
2434
|
+
if (step.kind === "delay") {
|
|
2435
|
+
const timerId = emitTimerEvents ? `${runId}::timer:${step.key}` : void 0;
|
|
2436
|
+
const recordTimerEvent = (name, patchMeta) => import_effect14.Effect.gen(function* () {
|
|
2437
|
+
const tickSeq2 = getTickSeq();
|
|
2438
|
+
yield* runWorkflowBoundary({
|
|
2439
|
+
kind: "flow",
|
|
2440
|
+
name,
|
|
2441
|
+
payload: { ms: step.ms },
|
|
2442
|
+
meta: {
|
|
2443
|
+
runId,
|
|
2444
|
+
...runBudgetMeta,
|
|
2445
|
+
stepKey: step.key,
|
|
2446
|
+
...timerId ? { timerId } : null,
|
|
2447
|
+
...tickSeq2 !== void 0 ? { tickSeq: tickSeq2 } : null,
|
|
2448
|
+
policy,
|
|
2449
|
+
...patchMeta ?? null
|
|
2450
|
+
},
|
|
2451
|
+
effect: import_effect14.Effect.void
|
|
2452
|
+
});
|
|
2453
|
+
});
|
|
2454
|
+
const schedule = emitTimerEvents ? recordTimerEvent("workflow.timer.schedule") : import_effect14.Effect.void;
|
|
2455
|
+
const onCancel = emitTimerEvents ? recordTimerEvent("workflow.timer.cancel", { reason: "interrupt" }) : import_effect14.Effect.void;
|
|
2456
|
+
const fired = emitTimerEvents ? recordTimerEvent("workflow.timer.fired") : import_effect14.Effect.void;
|
|
2457
|
+
const delayEffect = schedule.pipe(
|
|
2458
|
+
import_effect14.Effect.flatMap(() => makeTimer({ host, ms: step.ms, onCancel })),
|
|
2459
|
+
import_effect14.Effect.flatMap(() => fired)
|
|
2460
|
+
);
|
|
2461
|
+
const tickSeq = getTickSeq();
|
|
2462
|
+
yield* runWorkflowBoundary({
|
|
2463
|
+
kind: "flow",
|
|
2464
|
+
name: "workflow.delay",
|
|
2465
|
+
payload: { ms: step.ms },
|
|
2466
|
+
meta: {
|
|
2467
|
+
runId,
|
|
2468
|
+
...runBudgetMeta,
|
|
2469
|
+
stepKey: step.key,
|
|
2470
|
+
...tickSeq !== void 0 ? { tickSeq } : null,
|
|
2471
|
+
...timerId ? { timerId } : null,
|
|
2472
|
+
policy
|
|
2473
|
+
},
|
|
2474
|
+
effect: delayEffect
|
|
2475
|
+
}).pipe(import_effect14.Effect.asVoid);
|
|
2476
|
+
timerTriggered = true;
|
|
2477
|
+
continue;
|
|
2478
|
+
}
|
|
2479
|
+
const input = step.input ? evalInputExpr(step.input, args.payload) : defaultInputForCall();
|
|
2480
|
+
const maxRetries = step.retryTimes ?? 0;
|
|
2481
|
+
let exit;
|
|
2482
|
+
for (let attempt = 1; attempt <= maxRetries + 1; attempt += 1) {
|
|
2483
|
+
const tickSeq = getTickSeq();
|
|
2484
|
+
const base = runWorkflowBoundary({
|
|
2485
|
+
kind: "service",
|
|
2486
|
+
name: `workflow.call:${step.serviceId}`,
|
|
2487
|
+
payload: { serviceId: step.serviceId },
|
|
2488
|
+
meta: {
|
|
2489
|
+
runId,
|
|
2490
|
+
...runBudgetMeta,
|
|
2491
|
+
stepKey: step.key,
|
|
2492
|
+
serviceId: step.serviceId,
|
|
2493
|
+
attempt,
|
|
2494
|
+
...tickSeq !== void 0 ? { tickSeq } : null,
|
|
2495
|
+
policy
|
|
2496
|
+
},
|
|
2497
|
+
effect: step.port(input)
|
|
2498
|
+
});
|
|
2499
|
+
const withTimeout = step.timeoutMs === void 0 ? base : import_effect14.Effect.gen(function* () {
|
|
2500
|
+
const timeoutMs = step.timeoutMs;
|
|
2501
|
+
if (timeoutMs === void 0) {
|
|
2502
|
+
return yield* base;
|
|
2503
|
+
}
|
|
2504
|
+
const timerId = emitTimerEvents ? `${runId}::timeout:${step.key}:a${attempt}` : void 0;
|
|
2505
|
+
const recordTimeoutEvent = (name, patchMeta) => import_effect14.Effect.gen(function* () {
|
|
2506
|
+
const tickSeq2 = getTickSeq();
|
|
2507
|
+
yield* runWorkflowBoundary({
|
|
2508
|
+
kind: "flow",
|
|
2509
|
+
name,
|
|
2510
|
+
payload: { ms: timeoutMs },
|
|
2511
|
+
meta: {
|
|
2512
|
+
runId,
|
|
2513
|
+
...runBudgetMeta,
|
|
2514
|
+
stepKey: step.key,
|
|
2515
|
+
attempt,
|
|
2516
|
+
...timerId ? { timerId } : null,
|
|
2517
|
+
...tickSeq2 !== void 0 ? { tickSeq: tickSeq2 } : null,
|
|
2518
|
+
policy,
|
|
2519
|
+
...patchMeta ?? null
|
|
2520
|
+
},
|
|
2521
|
+
effect: import_effect14.Effect.void
|
|
2522
|
+
});
|
|
2523
|
+
});
|
|
2524
|
+
const schedule = emitTimerEvents ? recordTimeoutEvent("workflow.timeout.schedule") : import_effect14.Effect.void;
|
|
2525
|
+
const onCancel = emitTimerEvents ? recordTimeoutEvent("workflow.timeout.cancel", { reason: "interrupt" }) : import_effect14.Effect.void;
|
|
2526
|
+
const fired = emitTimerEvents ? recordTimeoutEvent("workflow.timeout.fired") : import_effect14.Effect.void;
|
|
2527
|
+
const timeoutError = makeWorkflowError({
|
|
2528
|
+
code: "WORKFLOW_CALL_TIMEOUT",
|
|
2529
|
+
message: `Workflow call timed out (serviceId="${step.serviceId}", timeoutMs=${timeoutMs}).`,
|
|
2530
|
+
programId: program.programId,
|
|
2531
|
+
source: { stepKey: step.key },
|
|
2532
|
+
detail: { serviceId: step.serviceId, timeoutMs, attempt }
|
|
2533
|
+
});
|
|
2534
|
+
const timeoutFail = schedule.pipe(
|
|
2535
|
+
import_effect14.Effect.flatMap(() => makeTimer({ host, ms: timeoutMs, onCancel })),
|
|
2536
|
+
import_effect14.Effect.flatMap(() => fired),
|
|
2537
|
+
import_effect14.Effect.flatMap(() => import_effect14.Effect.fail(timeoutError))
|
|
2538
|
+
);
|
|
2539
|
+
return yield* import_effect14.Effect.raceFirst(base, timeoutFail);
|
|
2540
|
+
});
|
|
2541
|
+
const attemptExit = yield* import_effect14.Effect.exit(withTimeout);
|
|
2542
|
+
exit = attemptExit;
|
|
2543
|
+
if (!canWriteBack() || import_effect14.Exit.isSuccess(attemptExit)) {
|
|
2544
|
+
break;
|
|
2545
|
+
}
|
|
2546
|
+
if (import_effect14.Cause.hasInterruptsOnly(attemptExit.cause) || import_effect14.Option.isNone(import_effect14.Cause.findErrorOption(attemptExit.cause))) {
|
|
2547
|
+
break;
|
|
2548
|
+
}
|
|
2549
|
+
if (attempt < maxRetries + 1) {
|
|
2550
|
+
continue;
|
|
2551
|
+
}
|
|
2552
|
+
break;
|
|
2553
|
+
}
|
|
2554
|
+
if (!exit) {
|
|
2555
|
+
exit = import_effect14.Exit.succeed(void 0);
|
|
2556
|
+
}
|
|
2557
|
+
if (!canWriteBack()) return;
|
|
2558
|
+
if (import_effect14.Exit.isSuccess(exit)) {
|
|
2559
|
+
yield* runSteps(step.onSuccess);
|
|
2560
|
+
} else {
|
|
2561
|
+
const failure = import_effect14.Option.getOrUndefined(import_effect14.Cause.findErrorOption(exit.cause));
|
|
2562
|
+
const isTimeout = isObjectLike(failure) && failure._tag === "WorkflowError" && failure.code === "WORKFLOW_CALL_TIMEOUT";
|
|
2563
|
+
if (isTimeout) timerTriggered = true;
|
|
2564
|
+
yield* runSteps(step.onFailure);
|
|
2565
|
+
}
|
|
2566
|
+
}
|
|
2567
|
+
});
|
|
2568
|
+
const runTickSeq = getTickSeq();
|
|
2569
|
+
yield* runWorkflowBoundary({
|
|
2570
|
+
kind: "flow",
|
|
2571
|
+
name: "workflow.run",
|
|
2572
|
+
payload: { trigger: args.trigger },
|
|
2573
|
+
meta: {
|
|
2574
|
+
runId,
|
|
2575
|
+
...runBudgetMeta,
|
|
2576
|
+
...runTickSeq !== void 0 ? { tickSeq: runTickSeq } : null,
|
|
2577
|
+
policy
|
|
2578
|
+
},
|
|
2579
|
+
effect: runSteps(program.steps)
|
|
2580
|
+
}).pipe(import_effect14.Effect.asVoid);
|
|
2581
|
+
});
|
|
2582
|
+
const limited = registry.parallelLimiter ? registry.parallelLimiter.withPermits(1)(programEffect) : programEffect;
|
|
2583
|
+
const runOutsideTransaction = import_effect14.Effect.provideService(limited.pipe(
|
|
2584
|
+
import_effect14.Effect.catchCause((cause) => {
|
|
2585
|
+
const { errorSummary, downgrade } = toSerializableErrorSummary(cause);
|
|
2586
|
+
const downgradeHint = downgrade ? ` (downgrade=${downgrade})` : "";
|
|
2587
|
+
return record({
|
|
2588
|
+
type: "diagnostic",
|
|
2589
|
+
moduleId: runtime.moduleId,
|
|
2590
|
+
instanceId: runtime.instanceId,
|
|
2591
|
+
code: "workflow::run_crashed",
|
|
2592
|
+
severity: "error",
|
|
2593
|
+
message: `Workflow run crashed for programId="${program.programId}" runId="${runId}".${downgradeHint}`,
|
|
2594
|
+
hint: `${errorSummary.name ? `${errorSummary.name}: ` : ""}${errorSummary.message}`,
|
|
2595
|
+
actionTag: args.trigger.kind === "action" ? args.trigger.actionTag : void 0,
|
|
2596
|
+
kind: "workflow_run_crashed",
|
|
2597
|
+
trigger: {
|
|
2598
|
+
kind: "workflow",
|
|
2599
|
+
name: "run",
|
|
2600
|
+
details: {
|
|
2601
|
+
programId: program.programId,
|
|
2602
|
+
runId,
|
|
2603
|
+
trigger: args.trigger
|
|
2604
|
+
}
|
|
2605
|
+
}
|
|
2606
|
+
}).pipe(import_effect14.Effect.catchCause(() => import_effect14.Effect.void));
|
|
2607
|
+
}),
|
|
2608
|
+
import_effect14.Effect.ensuring(
|
|
2609
|
+
import_effect14.Effect.sync(() => {
|
|
2610
|
+
if (state.mode === "exhaust") {
|
|
2611
|
+
state.busy = false;
|
|
2612
|
+
}
|
|
2613
|
+
})
|
|
2614
|
+
)
|
|
2615
|
+
), inSyncTransactionFiber, false);
|
|
2616
|
+
const fiber = yield* runOutsideTransaction.pipe(import_effect14.Effect.forkScoped({ startImmediately: true }));
|
|
2617
|
+
if (state.mode === "latest") {
|
|
2618
|
+
state.current = fiber;
|
|
2619
|
+
}
|
|
2620
|
+
});
|
|
2621
|
+
var ensureRegistry = (runtime) => import_effect14.Effect.gen(function* () {
|
|
2622
|
+
const existing = getRegistry(runtime);
|
|
2623
|
+
if (existing) {
|
|
2624
|
+
return {
|
|
2625
|
+
moduleId: runtime.moduleId,
|
|
2626
|
+
instanceId: runtime.instanceId,
|
|
2627
|
+
registry: existing
|
|
2628
|
+
};
|
|
2629
|
+
}
|
|
2630
|
+
const portsReady = yield* import_effect14.Deferred.make();
|
|
2631
|
+
const next = {
|
|
2632
|
+
byActionTag: /* @__PURE__ */ new Map(),
|
|
2633
|
+
entries: [],
|
|
2634
|
+
watcherStarted: false,
|
|
2635
|
+
watcherStartCount: 0,
|
|
2636
|
+
portsResolving: false,
|
|
2637
|
+
portsReady,
|
|
2638
|
+
parallelLimiter: void 0
|
|
2639
|
+
};
|
|
2640
|
+
Object.defineProperty(runtime, WORKFLOW_REGISTRY, {
|
|
2641
|
+
value: next,
|
|
2642
|
+
enumerable: false,
|
|
2643
|
+
configurable: true,
|
|
2644
|
+
writable: false
|
|
2645
|
+
});
|
|
2646
|
+
return { moduleId: runtime.moduleId, instanceId: runtime.instanceId, registry: next };
|
|
2647
|
+
});
|
|
2648
|
+
var registerPrograms = (args) => import_effect14.Effect.gen(function* () {
|
|
2649
|
+
const runtime = yield* import_effect14.Effect.service(args.moduleTag).pipe(import_effect14.Effect.orDie);
|
|
2650
|
+
const { moduleId, instanceId, registry } = yield* ensureRegistry(runtime);
|
|
2651
|
+
if (registry.parallelLimiter === void 0) {
|
|
2652
|
+
yield* ensureLimiterReady(registry, runtime);
|
|
2653
|
+
}
|
|
2654
|
+
const validateNoIoStepsForOnInit = (steps, programId) => {
|
|
2655
|
+
const visit = (step) => {
|
|
2656
|
+
if (step.kind === "call" || step.kind === "delay") {
|
|
2657
|
+
throw makeWorkflowError({
|
|
2658
|
+
code: "WORKFLOW_INVALID_TRIGGER",
|
|
2659
|
+
message: "Lifecycle onInit programs must not include call/delay (initRequired must stay sync-only; use onStart for IO/time).",
|
|
2660
|
+
programId,
|
|
2661
|
+
source: { stepKey: step.key },
|
|
2662
|
+
detail: { kind: step.kind }
|
|
2663
|
+
});
|
|
2664
|
+
}
|
|
2665
|
+
};
|
|
2666
|
+
for (const s of steps) visit(s);
|
|
2667
|
+
};
|
|
2668
|
+
const programHasCall = (steps) => steps.some((s) => s.kind === "call");
|
|
2669
|
+
const insertEntry = (actionTag, entry) => {
|
|
2670
|
+
const prev = registry.byActionTag.get(actionTag);
|
|
2671
|
+
registry.byActionTag.set(actionTag, prev ? [...prev, entry] : [entry]);
|
|
2672
|
+
};
|
|
2673
|
+
const internals = getRuntimeInternals(runtime);
|
|
2674
|
+
for (const program of args.programs) {
|
|
2675
|
+
const def = program.def;
|
|
2676
|
+
const localId = asNonEmptyString3(def.localId);
|
|
2677
|
+
if (!localId) {
|
|
2678
|
+
throw makeWorkflowError({
|
|
2679
|
+
code: "WORKFLOW_INVALID_DEF",
|
|
2680
|
+
message: "Workflow.install: def.localId must be a non-empty string.",
|
|
2681
|
+
detail: { localId: def.localId }
|
|
2682
|
+
});
|
|
2683
|
+
}
|
|
2684
|
+
const programId = `${moduleId}.${localId}`;
|
|
2685
|
+
const compiled = compileWorkflowRuntimeStepsV1({ def });
|
|
2686
|
+
if (def.trigger.kind === "lifecycle" && def.trigger.phase === "onInit") {
|
|
2687
|
+
validateNoIoStepsForOnInit(compiled, programId);
|
|
2688
|
+
}
|
|
2689
|
+
const compiledProgram = {
|
|
2690
|
+
programId,
|
|
2691
|
+
localId,
|
|
2692
|
+
trigger: def.trigger,
|
|
2693
|
+
concurrency: resolveConcurrency(def),
|
|
2694
|
+
priority: resolvePriority(def),
|
|
2695
|
+
compiledSteps: compiled
|
|
2696
|
+
};
|
|
2697
|
+
if (!programHasCall(compiled)) {
|
|
2698
|
+
compiledProgram.steps = compileSteps(compiled, () => {
|
|
2699
|
+
throw makeWorkflowError({
|
|
2700
|
+
code: "WORKFLOW_MISSING_SERVICE",
|
|
2701
|
+
message: "Internal error: unexpected call step while resolving call-less program.",
|
|
2702
|
+
programId,
|
|
2703
|
+
detail: { programId }
|
|
2704
|
+
});
|
|
2705
|
+
});
|
|
2706
|
+
}
|
|
2707
|
+
const state = compiledProgram.concurrency === "latest" ? { mode: "latest", runSeq: 0, current: void 0, currentRunId: void 0 } : compiledProgram.concurrency === "exhaust" ? { mode: "exhaust", runSeq: 0, busy: false } : { mode: "parallel", runSeq: 0 };
|
|
2708
|
+
const entry = { program: compiledProgram, state };
|
|
2709
|
+
registry.entries.push(entry);
|
|
2710
|
+
if (def.trigger.kind === "action") {
|
|
2711
|
+
insertEntry(def.trigger.actionTag, entry);
|
|
2712
|
+
} else {
|
|
2713
|
+
if (def.trigger.phase === "onStart") {
|
|
2714
|
+
internals.lifecycle.registerStart(
|
|
2715
|
+
withRootEnvIfAvailable(
|
|
2716
|
+
import_effect14.Effect.gen(function* () {
|
|
2717
|
+
const middlewareOpt = yield* import_effect14.Effect.serviceOption(EffectOpMiddlewareTag);
|
|
2718
|
+
const middleware = import_effect14.Option.isSome(middlewareOpt) ? middlewareOpt.value : void 0;
|
|
2719
|
+
yield* ensurePortsResolved(registry, runtime).pipe(import_effect14.Effect.orDie);
|
|
2720
|
+
yield* startProgramRun({
|
|
2721
|
+
entry,
|
|
2722
|
+
runtime,
|
|
2723
|
+
registry,
|
|
2724
|
+
trigger: { kind: "lifecycle", phase: "onStart" },
|
|
2725
|
+
payload: void 0,
|
|
2726
|
+
middleware
|
|
2727
|
+
});
|
|
2728
|
+
})
|
|
2729
|
+
),
|
|
2730
|
+
{ name: `workflow:${localId}` }
|
|
2731
|
+
);
|
|
2732
|
+
} else {
|
|
2733
|
+
internals.lifecycle.registerInitRequired(
|
|
2734
|
+
import_effect14.Effect.gen(function* () {
|
|
2735
|
+
const middlewareOpt = yield* import_effect14.Effect.serviceOption(EffectOpMiddlewareTag);
|
|
2736
|
+
const middleware = import_effect14.Option.isSome(middlewareOpt) ? middlewareOpt.value : void 0;
|
|
2737
|
+
yield* startProgramRun({
|
|
2738
|
+
entry,
|
|
2739
|
+
runtime,
|
|
2740
|
+
registry,
|
|
2741
|
+
trigger: { kind: "lifecycle", phase: "onInit" },
|
|
2742
|
+
payload: void 0,
|
|
2743
|
+
middleware
|
|
2744
|
+
});
|
|
2745
|
+
}),
|
|
2746
|
+
{ name: `workflow:${localId}` }
|
|
2747
|
+
);
|
|
2748
|
+
}
|
|
2749
|
+
}
|
|
2750
|
+
}
|
|
2751
|
+
void instanceId;
|
|
2752
|
+
});
|
|
2753
|
+
var startWatcherIfNeeded = (args) => import_effect14.Effect.gen(function* () {
|
|
2754
|
+
const runtime = yield* import_effect14.Effect.service(args.moduleTag).pipe(import_effect14.Effect.orDie);
|
|
2755
|
+
const init = yield* ensureRegistry(runtime);
|
|
2756
|
+
const registry = init.registry;
|
|
2757
|
+
if (registry.watcherStarted) {
|
|
2758
|
+
return;
|
|
2759
|
+
}
|
|
2760
|
+
registry.watcherStarted = true;
|
|
2761
|
+
registry.watcherStartCount += 1;
|
|
2762
|
+
const middlewareOpt = yield* import_effect14.Effect.serviceOption(EffectOpMiddlewareTag);
|
|
2763
|
+
const middleware = import_effect14.Option.isSome(middlewareOpt) ? middlewareOpt.value : void 0;
|
|
2764
|
+
const actions$ = runtime.actions$;
|
|
2765
|
+
const portsExit = yield* import_effect14.Effect.exit(ensurePortsResolved(registry, runtime));
|
|
2766
|
+
if (import_effect14.Exit.isFailure(portsExit)) {
|
|
2767
|
+
const { errorSummary, downgrade } = toSerializableErrorSummary(portsExit.cause);
|
|
2768
|
+
const downgradeHint = downgrade ? ` (downgrade=${downgrade})` : "";
|
|
2769
|
+
yield* record({
|
|
2770
|
+
type: "diagnostic",
|
|
2771
|
+
moduleId: runtime.moduleId,
|
|
2772
|
+
instanceId: runtime.instanceId,
|
|
2773
|
+
code: "workflow::ports_resolution_failed",
|
|
2774
|
+
severity: "error",
|
|
2775
|
+
message: `Workflow ports resolution failed before starting watcher.${downgradeHint}`,
|
|
2776
|
+
hint: `${errorSummary.name ? `${errorSummary.name}: ` : ""}${errorSummary.message}`,
|
|
2777
|
+
kind: "workflow_ports_resolution_failed",
|
|
2778
|
+
trigger: {
|
|
2779
|
+
kind: "workflow",
|
|
2780
|
+
name: "portsResolution",
|
|
2781
|
+
details: {
|
|
2782
|
+
entryLabel: args.entryLabel
|
|
2783
|
+
}
|
|
2784
|
+
}
|
|
2785
|
+
});
|
|
2786
|
+
return;
|
|
2787
|
+
}
|
|
2788
|
+
yield* import_effect14.Stream.runForEach(
|
|
2789
|
+
actions$,
|
|
2790
|
+
(action) => import_effect14.Effect.gen(function* () {
|
|
2791
|
+
const actionTag = resolveActionTag(action);
|
|
2792
|
+
if (!actionTag) return;
|
|
2793
|
+
const entries = registry.byActionTag.get(actionTag);
|
|
2794
|
+
if (!entries || entries.length === 0) return;
|
|
2795
|
+
const payload2 = isRecord3(action) ? action.payload : void 0;
|
|
2796
|
+
yield* import_effect14.Effect.forEach(
|
|
2797
|
+
entries,
|
|
2798
|
+
(entry) => startProgramRun({
|
|
2799
|
+
entry,
|
|
2800
|
+
runtime,
|
|
2801
|
+
registry,
|
|
2802
|
+
trigger: { kind: "action", actionTag },
|
|
2803
|
+
payload: payload2,
|
|
2804
|
+
middleware
|
|
2805
|
+
}),
|
|
2806
|
+
{ discard: true }
|
|
2807
|
+
);
|
|
2808
|
+
})
|
|
2809
|
+
).pipe(
|
|
2810
|
+
(effect) => import_effect14.Effect.provideService(effect, inSyncTransactionFiber, false),
|
|
2811
|
+
import_effect14.Effect.catchCause((cause) => {
|
|
2812
|
+
const { errorSummary, downgrade } = toSerializableErrorSummary(cause);
|
|
2813
|
+
const downgradeHint = downgrade ? ` (downgrade=${downgrade})` : "";
|
|
2814
|
+
return record({
|
|
2815
|
+
type: "diagnostic",
|
|
2816
|
+
moduleId: runtime.moduleId,
|
|
2817
|
+
instanceId: runtime.instanceId,
|
|
2818
|
+
code: "workflow::watcher_crashed",
|
|
2819
|
+
severity: "error",
|
|
2820
|
+
message: `Workflow watcher crashed.${downgradeHint}`,
|
|
2821
|
+
hint: `${errorSummary.name ? `${errorSummary.name}: ` : ""}${errorSummary.message}`,
|
|
2822
|
+
kind: "workflow_watcher_crashed",
|
|
2823
|
+
trigger: {
|
|
2824
|
+
kind: "workflow",
|
|
2825
|
+
name: "watcher",
|
|
2826
|
+
details: {
|
|
2827
|
+
entryLabel: args.entryLabel
|
|
2828
|
+
}
|
|
2829
|
+
}
|
|
2830
|
+
});
|
|
2831
|
+
})
|
|
2832
|
+
);
|
|
2833
|
+
void args.entryLabel;
|
|
2834
|
+
});
|
|
2835
|
+
var installOne = (args) => {
|
|
2836
|
+
const localId = asNonEmptyString3(args.program.def.localId) ?? "unknown";
|
|
2837
|
+
const plan = {
|
|
2838
|
+
setup: registerPrograms({ moduleTag: args.moduleTag, programs: [args.program], entryLabel: `install:${localId}` }),
|
|
2839
|
+
run: startWatcherIfNeeded({ moduleTag: args.moduleTag, entryLabel: `install:${localId}` })
|
|
2840
|
+
};
|
|
2841
|
+
attachLogicUnitMeta(plan, {
|
|
2842
|
+
id: `workflow:${localId}`,
|
|
2843
|
+
kind: "workflow",
|
|
2844
|
+
name: localId
|
|
2845
|
+
});
|
|
2846
|
+
return plan;
|
|
2847
|
+
};
|
|
2848
|
+
|
|
2849
|
+
// src/Workflow.ts
|
|
2850
|
+
var KernelSourceRefreshPortTagImpl = class extends import_effect15.ServiceMap.Service()("logix/kernel/sourceRefresh") {
|
|
2851
|
+
};
|
|
2852
|
+
var KernelPorts = {
|
|
2853
|
+
sourceRefresh: KernelSourceRefreshPortTagImpl
|
|
2854
|
+
};
|
|
2855
|
+
var forModule = (_module) => {
|
|
2856
|
+
return {
|
|
2857
|
+
onAction: (actionTag) => onAction(actionTag),
|
|
2858
|
+
onStart,
|
|
2859
|
+
onInit,
|
|
2860
|
+
payload,
|
|
2861
|
+
payloadPath,
|
|
2862
|
+
constValue,
|
|
2863
|
+
object,
|
|
2864
|
+
merge,
|
|
2865
|
+
dispatch: (args) => dispatch(args),
|
|
2866
|
+
delay,
|
|
2867
|
+
callById: (args) => callById(args),
|
|
2868
|
+
call: (args) => call(args),
|
|
2869
|
+
fragment: (fragmentId, steps) => fragment(fragmentId, steps),
|
|
2870
|
+
withPolicy: (patch, part) => withPolicy(patch, part),
|
|
2871
|
+
compose: (...parts) => compose(...parts),
|
|
2872
|
+
make: (input) => make2(input),
|
|
2873
|
+
fromJSON: (def) => fromJSON(def)
|
|
2874
|
+
};
|
|
2875
|
+
};
|
|
2876
|
+
var isRecord4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2877
|
+
var isReadonlyArray = (value) => Array.isArray(value);
|
|
2878
|
+
var asNonEmptyString4 = (value) => typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
|
|
2879
|
+
var mergePolicy = (base, patch) => {
|
|
2880
|
+
if (!base && !patch) return void 0;
|
|
2881
|
+
return {
|
|
2882
|
+
...base ?? {},
|
|
2883
|
+
...patch ?? {}
|
|
2884
|
+
};
|
|
2885
|
+
};
|
|
2886
|
+
var applyCallDefaults = (steps, patch) => {
|
|
2887
|
+
const timeoutMsDefault = patch.timeoutMs;
|
|
2888
|
+
const retryDefault = patch.retry;
|
|
2889
|
+
const visit = (step) => {
|
|
2890
|
+
if (step.kind !== "call") return step;
|
|
2891
|
+
let changed = false;
|
|
2892
|
+
const timeoutMs = step.timeoutMs ?? timeoutMsDefault;
|
|
2893
|
+
if (timeoutMs !== step.timeoutMs) changed = true;
|
|
2894
|
+
const retry = step.retry ?? retryDefault;
|
|
2895
|
+
if (retry !== step.retry) changed = true;
|
|
2896
|
+
const onSuccess = step.onSuccess.map(visit);
|
|
2897
|
+
const onFailure = step.onFailure.map(visit);
|
|
2898
|
+
if (onSuccess !== step.onSuccess) changed = true;
|
|
2899
|
+
if (onFailure !== step.onFailure) changed = true;
|
|
2900
|
+
if (!changed) return step;
|
|
2901
|
+
return {
|
|
2902
|
+
...step,
|
|
2903
|
+
...timeoutMs !== void 0 ? { timeoutMs } : null,
|
|
2904
|
+
...retry !== void 0 ? { retry } : null,
|
|
2905
|
+
onSuccess,
|
|
2906
|
+
onFailure
|
|
2907
|
+
};
|
|
2908
|
+
};
|
|
2909
|
+
return steps.map(visit);
|
|
2910
|
+
};
|
|
2911
|
+
var resolveStepsInput = (input) => {
|
|
2912
|
+
if (Array.isArray(input)) {
|
|
2913
|
+
return { steps: input };
|
|
2914
|
+
}
|
|
2915
|
+
if (isRecord4(input) && Array.isArray(input.steps)) {
|
|
2916
|
+
return input;
|
|
2917
|
+
}
|
|
2918
|
+
throw makeWorkflowError({
|
|
2919
|
+
code: "WORKFLOW_INVALID_DEF",
|
|
2920
|
+
message: 'Workflow.make: "steps" must be an array or a { steps, sources?, policy? } object.',
|
|
2921
|
+
detail: { steps: input }
|
|
2922
|
+
});
|
|
2923
|
+
};
|
|
2924
|
+
var recordSourcesForFragment = (sources, fragmentId, step) => {
|
|
2925
|
+
sources[step.key] = { fragmentId };
|
|
2926
|
+
if (step.kind !== "call") return;
|
|
2927
|
+
for (const inner of step.onSuccess) recordSourcesForFragment(sources, fragmentId, inner);
|
|
2928
|
+
for (const inner of step.onFailure) recordSourcesForFragment(sources, fragmentId, inner);
|
|
2929
|
+
};
|
|
2930
|
+
var onAction = (actionTag) => ({
|
|
2931
|
+
kind: "action",
|
|
2932
|
+
actionTag
|
|
2933
|
+
});
|
|
2934
|
+
var onStart = () => ({
|
|
2935
|
+
kind: "lifecycle",
|
|
2936
|
+
phase: "onStart"
|
|
2937
|
+
});
|
|
2938
|
+
var onInit = () => ({
|
|
2939
|
+
kind: "lifecycle",
|
|
2940
|
+
phase: "onInit"
|
|
2941
|
+
});
|
|
2942
|
+
var payload = () => ({ kind: "payload" });
|
|
2943
|
+
var payloadPath = (pointer) => ({ kind: "payload.path", pointer });
|
|
2944
|
+
var constValue = (value) => ({ kind: "const", value });
|
|
2945
|
+
var object = (fields) => ({ kind: "object", fields });
|
|
2946
|
+
var merge = (items) => ({ kind: "merge", items });
|
|
2947
|
+
var dispatch = (args) => ({
|
|
2948
|
+
kind: "dispatch",
|
|
2949
|
+
key: args.key,
|
|
2950
|
+
actionTag: args.actionTag,
|
|
2951
|
+
...args.payload ? { payload: args.payload } : null
|
|
2952
|
+
});
|
|
2953
|
+
var delay = (args) => ({
|
|
2954
|
+
kind: "delay",
|
|
2955
|
+
key: args.key,
|
|
2956
|
+
ms: args.ms
|
|
2957
|
+
});
|
|
2958
|
+
var callById = (args) => ({
|
|
2959
|
+
kind: "call",
|
|
2960
|
+
key: args.key,
|
|
2961
|
+
serviceId: args.serviceId,
|
|
2962
|
+
...args.input ? { input: args.input } : null,
|
|
2963
|
+
...args.timeoutMs !== void 0 ? { timeoutMs: args.timeoutMs } : null,
|
|
2964
|
+
...args.retry ? { retry: args.retry } : null,
|
|
2965
|
+
onSuccess: args.onSuccess ?? [],
|
|
2966
|
+
onFailure: args.onFailure ?? []
|
|
2967
|
+
});
|
|
2968
|
+
var call = (args) => {
|
|
2969
|
+
const serviceId = fromTag(args.service);
|
|
2970
|
+
if (!serviceId) {
|
|
2971
|
+
throw makeWorkflowError({
|
|
2972
|
+
code: "WORKFLOW_INVALID_SERVICE_ID",
|
|
2973
|
+
message: "call(service): serviceId derived from tag must be a non-empty string (see 078 ServiceId contract).",
|
|
2974
|
+
detail: { tag: String(args.service) }
|
|
2975
|
+
});
|
|
2976
|
+
}
|
|
2977
|
+
return callById({
|
|
2978
|
+
...args,
|
|
2979
|
+
serviceId
|
|
2980
|
+
});
|
|
2981
|
+
};
|
|
2982
|
+
var fragment = (fragmentId, steps) => ({
|
|
2983
|
+
fragmentId,
|
|
2984
|
+
steps
|
|
2985
|
+
});
|
|
2986
|
+
var withPolicy = (patch, part) => {
|
|
2987
|
+
let normalized;
|
|
2988
|
+
if (isReadonlyArray(part)) {
|
|
2989
|
+
normalized = { steps: part };
|
|
2990
|
+
} else {
|
|
2991
|
+
const partUnknown = part;
|
|
2992
|
+
if (!isRecord4(partUnknown) || !isReadonlyArray(partUnknown.steps)) {
|
|
2993
|
+
throw makeWorkflowError({
|
|
2994
|
+
code: "WORKFLOW_INVALID_DEF",
|
|
2995
|
+
message: "withPolicy: invalid workflow part (expected steps[] / fragment / composeResult).",
|
|
2996
|
+
detail: { part }
|
|
2997
|
+
});
|
|
2998
|
+
}
|
|
2999
|
+
normalized = {
|
|
3000
|
+
steps: part.steps,
|
|
3001
|
+
...part.sources ? { sources: part.sources } : null,
|
|
3002
|
+
...part.policy ? { policy: part.policy } : null
|
|
3003
|
+
};
|
|
3004
|
+
}
|
|
3005
|
+
const steps = applyCallDefaults(normalized.steps, patch);
|
|
3006
|
+
const patchPolicy = (() => {
|
|
3007
|
+
const concurrency = patch.concurrency;
|
|
3008
|
+
const priority = patch.priority;
|
|
3009
|
+
return concurrency !== void 0 || priority !== void 0 ? { concurrency, priority } : void 0;
|
|
3010
|
+
})();
|
|
3011
|
+
const nextPolicy = mergePolicy(patchPolicy, normalized.policy);
|
|
3012
|
+
return {
|
|
3013
|
+
steps,
|
|
3014
|
+
...normalized.sources ? { sources: normalized.sources } : null,
|
|
3015
|
+
...nextPolicy ? { policy: nextPolicy } : null
|
|
3016
|
+
};
|
|
3017
|
+
};
|
|
3018
|
+
var compose = (...parts) => {
|
|
3019
|
+
const steps = [];
|
|
3020
|
+
const sources = {};
|
|
3021
|
+
let policy = void 0;
|
|
3022
|
+
const ownersByKey = /* @__PURE__ */ new Map();
|
|
3023
|
+
const recordOwner = (stepKey, fragmentId) => {
|
|
3024
|
+
const list = ownersByKey.get(stepKey) ?? [];
|
|
3025
|
+
list.push({ stepKey, ...fragmentId ? { fragmentId } : null });
|
|
3026
|
+
ownersByKey.set(stepKey, list);
|
|
3027
|
+
};
|
|
3028
|
+
const recordOwners = (step, resolveFragmentId) => {
|
|
3029
|
+
recordOwner(step.key, resolveFragmentId(step.key));
|
|
3030
|
+
if (step.kind !== "call") return;
|
|
3031
|
+
for (const inner of step.onSuccess) recordOwners(inner, resolveFragmentId);
|
|
3032
|
+
for (const inner of step.onFailure) recordOwners(inner, resolveFragmentId);
|
|
3033
|
+
};
|
|
3034
|
+
for (const part of parts) {
|
|
3035
|
+
if (isReadonlyArray(part)) {
|
|
3036
|
+
steps.push(...part);
|
|
3037
|
+
for (const step of part) recordOwners(step, () => void 0);
|
|
3038
|
+
continue;
|
|
3039
|
+
}
|
|
3040
|
+
const partSteps = part.steps;
|
|
3041
|
+
steps.push(...partSteps);
|
|
3042
|
+
const partSources = part.sources;
|
|
3043
|
+
if (partSources && typeof partSources === "object") {
|
|
3044
|
+
for (const k of Object.keys(partSources).sort()) {
|
|
3045
|
+
sources[k] = { ...partSources[k] };
|
|
3046
|
+
}
|
|
3047
|
+
}
|
|
3048
|
+
const fragmentId = "fragmentId" in part ? part.fragmentId : void 0;
|
|
3049
|
+
if (typeof fragmentId === "string" && fragmentId.length > 0) {
|
|
3050
|
+
for (const step of partSteps) {
|
|
3051
|
+
recordSourcesForFragment(sources, fragmentId, step);
|
|
3052
|
+
}
|
|
3053
|
+
}
|
|
3054
|
+
const resolveFragmentIdForPart = (stepKey) => {
|
|
3055
|
+
if (typeof fragmentId === "string" && fragmentId.length > 0) return fragmentId;
|
|
3056
|
+
const fromSources = partSources?.[stepKey]?.fragmentId;
|
|
3057
|
+
return typeof fromSources === "string" && fromSources.length > 0 ? fromSources : void 0;
|
|
3058
|
+
};
|
|
3059
|
+
for (const step of partSteps) recordOwners(step, resolveFragmentIdForPart);
|
|
3060
|
+
policy = mergePolicy(policy, part.policy);
|
|
3061
|
+
}
|
|
3062
|
+
const finalSources = Object.keys(sources).length > 0 ? sources : void 0;
|
|
3063
|
+
const duplicateKeys = Array.from(ownersByKey.entries()).filter(([, owners]) => owners.length > 1).map(([k]) => k).sort();
|
|
3064
|
+
if (duplicateKeys.length > 0) {
|
|
3065
|
+
const k = duplicateKeys[0];
|
|
3066
|
+
throw makeWorkflowError({
|
|
3067
|
+
code: "WORKFLOW_DUPLICATE_STEP_KEY",
|
|
3068
|
+
message: `Duplicate stepKey "${k}" detected during composition.`,
|
|
3069
|
+
source: { stepKey: k },
|
|
3070
|
+
detail: { duplicateKey: k, owners: ownersByKey.get(k) ?? [] }
|
|
3071
|
+
});
|
|
3072
|
+
}
|
|
3073
|
+
return {
|
|
3074
|
+
steps,
|
|
3075
|
+
...finalSources ? { sources: finalSources } : null,
|
|
3076
|
+
...policy ? { policy } : null
|
|
3077
|
+
};
|
|
3078
|
+
};
|
|
3079
|
+
var make2 = (input) => {
|
|
3080
|
+
const localId = asNonEmptyString4(input.localId);
|
|
3081
|
+
if (!localId) {
|
|
3082
|
+
throw makeWorkflowError({
|
|
3083
|
+
code: "WORKFLOW_INVALID_DEF",
|
|
3084
|
+
message: "Workflow.make: localId must be a non-empty string.",
|
|
3085
|
+
detail: { localId: input.localId }
|
|
3086
|
+
});
|
|
3087
|
+
}
|
|
3088
|
+
const stepsInput = resolveStepsInput(input.steps);
|
|
3089
|
+
const merged = mergePolicy(input.policy, stepsInput.policy);
|
|
3090
|
+
const def = normalizeWorkflowDefV1({
|
|
3091
|
+
astVersion: 1,
|
|
3092
|
+
localId,
|
|
3093
|
+
trigger: input.trigger,
|
|
3094
|
+
...merged ? { policy: merged } : null,
|
|
3095
|
+
steps: stepsInput.steps,
|
|
3096
|
+
...stepsInput.sources ? { sources: stepsInput.sources } : null,
|
|
3097
|
+
...input.meta ? { meta: input.meta } : null
|
|
3098
|
+
});
|
|
3099
|
+
const staticIrCache = /* @__PURE__ */ new Map();
|
|
3100
|
+
return {
|
|
3101
|
+
_tag: "Workflow",
|
|
3102
|
+
def,
|
|
3103
|
+
toJSON: () => def,
|
|
3104
|
+
validate: () => validateWorkflowDefV1(def),
|
|
3105
|
+
exportStaticIr: (moduleId) => {
|
|
3106
|
+
const cached = staticIrCache.get(moduleId);
|
|
3107
|
+
if (cached) return cached;
|
|
3108
|
+
const ir = compileWorkflowStaticIrV1({ moduleId, def });
|
|
3109
|
+
staticIrCache.set(moduleId, ir);
|
|
3110
|
+
return ir;
|
|
3111
|
+
},
|
|
3112
|
+
install: (moduleTag) => installOne({
|
|
3113
|
+
moduleTag,
|
|
3114
|
+
program: { _tag: "Workflow", def }
|
|
3115
|
+
})
|
|
3116
|
+
};
|
|
3117
|
+
};
|
|
3118
|
+
var fromJSON = (def) => make2({
|
|
3119
|
+
localId: def.localId,
|
|
3120
|
+
trigger: def.trigger,
|
|
3121
|
+
...def.policy ? { policy: def.policy } : null,
|
|
3122
|
+
steps: {
|
|
3123
|
+
steps: def.steps,
|
|
3124
|
+
...def.sources ? { sources: def.sources } : null
|
|
3125
|
+
},
|
|
3126
|
+
...def.meta ? { meta: def.meta } : null
|
|
3127
|
+
});
|
|
3128
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
3129
|
+
0 && (module.exports = {
|
|
3130
|
+
KernelPorts,
|
|
3131
|
+
call,
|
|
3132
|
+
callById,
|
|
3133
|
+
compose,
|
|
3134
|
+
constValue,
|
|
3135
|
+
delay,
|
|
3136
|
+
dispatch,
|
|
3137
|
+
forModule,
|
|
3138
|
+
fragment,
|
|
3139
|
+
fromJSON,
|
|
3140
|
+
make,
|
|
3141
|
+
merge,
|
|
3142
|
+
object,
|
|
3143
|
+
onAction,
|
|
3144
|
+
onInit,
|
|
3145
|
+
onStart,
|
|
3146
|
+
payload,
|
|
3147
|
+
payloadPath,
|
|
3148
|
+
withPolicy
|
|
3149
|
+
});
|
|
3150
|
+
//# sourceMappingURL=Workflow.cjs.map
|