@makaio/framework 1.0.0-dev-1781022866275 → 1.0.0-dev-1781023871421
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/dist/.makaio-build.json +5 -0
- package/dist/account-identity-DT5NOtFi.mjs +1 -0
- package/dist/adapter-C1eI-fGV.mjs +1 -0
- package/dist/adapters/acp-client/index.d.mts +6208 -0
- package/dist/adapters/acp-client/index.mjs +3 -0
- package/dist/adapters/config/index.d.mts +429 -0
- package/dist/adapters/config/index.mjs +1 -0
- package/dist/adapters/index.d.mts +4202 -0
- package/dist/adapters/index.mjs +18 -0
- package/dist/adapters/node.d.mts +263 -0
- package/dist/adapters/node.mjs +4 -0
- package/dist/adapters/stream-session/index.d.mts +1414 -0
- package/dist/adapters/stream-session/index.mjs +1 -0
- package/dist/adapters/stream-session/testing/index.d.mts +29 -0
- package/dist/adapters/stream-session/testing/index.mjs +1 -0
- package/dist/artifact-B3npq1cy.mjs +1 -0
- package/dist/base-orchestrator-wyumsn3b.d.mts +772 -0
- package/dist/bus/index.d.mts +3994 -0
- package/dist/bus/index.mjs +1 -0
- package/dist/bus-Caz3Jpbc.mjs +1 -0
- package/dist/bus-Hb-LGzgb.mjs +2 -0
- package/dist/capability-service-CJbmhfv9.mjs +1 -0
- package/dist/chunk-DTipWd-i.mjs +1 -0
- package/dist/chunk-cpUYaJdV.mjs +1 -0
- package/dist/cleanEnvForAdapter-KkYzQa1f.mjs +1 -0
- package/dist/client-bx74gm4R.mjs +1 -0
- package/dist/clients/index.d.mts +2639 -0
- package/dist/clients/index.mjs +2 -0
- package/dist/clients-namespace-GmSJpBUV.d.mts +332 -0
- package/dist/config-namespace-CPY9YsR8.d.mts +638 -0
- package/dist/config-namespace-ncYg2ct_.mjs +1 -0
- package/dist/contracts/adapter/index.d.mts +3 -0
- package/dist/contracts/adapter/index.mjs +1 -0
- package/dist/contracts/adapter/schemas/session-lineage.d.mts +2 -0
- package/dist/contracts/adapter/schemas/session-lineage.mjs +1 -0
- package/dist/contracts/artifact/index.d.mts +2 -0
- package/dist/contracts/artifact/index.mjs +1 -0
- package/dist/contracts/client/index.d.mts +3 -0
- package/dist/contracts/client/index.mjs +1 -0
- package/dist/contracts/common/index.d.mts +2 -0
- package/dist/contracts/common/index.mjs +1 -0
- package/dist/contracts/config/index.d.mts +455 -0
- package/dist/contracts/config/index.mjs +1 -0
- package/dist/contracts/extension/index.d.mts +4 -0
- package/dist/contracts/extension/index.mjs +1 -0
- package/dist/contracts/facet/index.d.mts +2 -0
- package/dist/contracts/facet/index.mjs +1 -0
- package/dist/contracts/harness/index.d.mts +2 -0
- package/dist/contracts/harness/index.mjs +1 -0
- package/dist/contracts/host/index.d.mts +2 -0
- package/dist/contracts/host/index.mjs +1 -0
- package/dist/contracts/index.d.mts +23046 -0
- package/dist/contracts/index.mjs +1 -0
- package/dist/contracts/materialization/index.d.mts +4 -0
- package/dist/contracts/materialization/index.mjs +1 -0
- package/dist/contracts/model-registry/index.d.mts +2 -0
- package/dist/contracts/model-registry/index.mjs +1 -0
- package/dist/contracts/native-session-supervisor/index.d.mts +2 -0
- package/dist/contracts/native-session-supervisor/index.mjs +1 -0
- package/dist/contracts/platform/index.d.mts +2 -0
- package/dist/contracts/platform/index.mjs +1 -0
- package/dist/contracts/provider/index.d.mts +3 -0
- package/dist/contracts/provider/index.mjs +1 -0
- package/dist/contracts/session/index.d.mts +3 -0
- package/dist/contracts/session/index.mjs +1 -0
- package/dist/contracts/shared/index.d.mts +2 -0
- package/dist/contracts/shared/index.mjs +1 -0
- package/dist/contracts/skill/index.d.mts +2 -0
- package/dist/contracts/skill/index.mjs +1 -0
- package/dist/contracts/telemetry/index.d.mts +2 -0
- package/dist/contracts/telemetry/index.mjs +1 -0
- package/dist/contracts/timeout/index.d.mts +2 -0
- package/dist/contracts/timeout/index.mjs +1 -0
- package/dist/contracts/toast/index.d.mts +198 -0
- package/dist/contracts/toast/index.mjs +1 -0
- package/dist/contracts/variant/index.d.mts +2 -0
- package/dist/contracts/variant/index.mjs +1 -0
- package/dist/core/index.d.mts +1263 -0
- package/dist/core/index.mjs +1 -0
- package/dist/credential-ref-YWQQENEo.mjs +1 -0
- package/dist/cursor-storage-CtVJ3JzB.mjs +1 -0
- package/dist/definition-BLCdXGzh.d.mts +383 -0
- package/dist/definition-CrgHIpTK.d.mts +60 -0
- package/dist/definition-DZMXOnjX.mjs +1 -0
- package/dist/definition-pkJ6szUl.d.mts +158 -0
- package/dist/drizzle-Eq8W1EbD.mjs +1 -0
- package/dist/event-Ca2yUf5i.mjs +1 -0
- package/dist/execution-target-CRPTfZlc.mjs +1 -0
- package/dist/extension-C-4BHMRI.mjs +1 -0
- package/dist/extension-CpIUgBKI.mjs +1 -0
- package/dist/extension-namespace-cMh_mMiL.mjs +1 -0
- package/dist/facet-BuwhrThl.mjs +1 -0
- package/dist/filesystem-service-B8rhBRgB.mjs +1 -0
- package/dist/filesystem-service-p_iJVHd4.d.mts +66 -0
- package/dist/git/index.d.mts +210 -0
- package/dist/git/index.mjs +18 -0
- package/dist/globby-rtWVaFHv.mjs +41 -0
- package/dist/handlers-CkTsQLra.mjs +41 -0
- package/dist/harness-BRCMcvQN.mjs +1 -0
- package/dist/hooks/index.d.mts +423 -0
- package/dist/hooks/index.mjs +1 -0
- package/dist/host-Br9VuOyr.mjs +1 -0
- package/dist/identity-Cz2IeEtm.mjs +1 -0
- package/dist/index-472sOmsW.d.mts +218 -0
- package/dist/index-8SZkg7s6.d.mts +353 -0
- package/dist/index-B3PK4FIn.d.mts +5116 -0
- package/dist/index-B80L4YqA.d.mts +180 -0
- package/dist/index-BFg9BUpx.d.mts +355 -0
- package/dist/index-BGfWS6GE.d.mts +483 -0
- package/dist/index-BVgfS-AJ.d.mts +109 -0
- package/dist/index-B_zQC98V.d.mts +995 -0
- package/dist/index-Bh_Ne7LF.d.mts +1008 -0
- package/dist/index-Bvb2mMH6.d.mts +1730 -0
- package/dist/index-CCGVh9BF2.d.mts +749 -0
- package/dist/index-CGmcS0Ma.d.mts +412 -0
- package/dist/index-CHQ1SqT0.d.mts +117 -0
- package/dist/index-CLpjm52M.d.mts +183 -0
- package/dist/index-Caig6TeF.d.mts +6746 -0
- package/dist/index-CelJCBjk.d.mts +2992 -0
- package/dist/index-ChunCFu4.d.mts +11 -0
- package/dist/index-Cm0dUkWL.d.mts +4651 -0
- package/dist/index-CokQYGVP.d.mts +184 -0
- package/dist/index-Cs0kZXIz2.d.mts +37 -0
- package/dist/index-D5d5HeWI2.d.mts +259 -0
- package/dist/index-D90OmGmV.d.mts +389 -0
- package/dist/index-D9MwJ2Q8.d.mts +67 -0
- package/dist/index-DANINzMu.d.mts +40 -0
- package/dist/index-DBw-89vC2.d.mts +3640 -0
- package/dist/index-DGBu6bHi2.d.mts +438 -0
- package/dist/index-DKC62dY5.d.mts +146 -0
- package/dist/index-DKia0MX1.d.mts +43 -0
- package/dist/index-DMKnON5s.d.mts +28 -0
- package/dist/index-DUaw0Dw8.d.mts +14747 -0
- package/dist/index-De3kPhlN.d.mts +72 -0
- package/dist/index-L4GjJDKb.d.mts +822 -0
- package/dist/index-U-A8eyGT.d.mts +1490 -0
- package/dist/index-eemAKwsB.d.mts +362 -0
- package/dist/index-mNec7V-9.d.mts +1075 -0
- package/dist/index-soFznFCy2.d.mts +89 -0
- package/dist/index-vtXJuwrz.d.mts +40 -0
- package/dist/index-x_lVDp_J.d.mts +134 -0
- package/dist/json-value-CmhSGMLv.mjs +1 -0
- package/dist/kernel/cli/index.d.mts +143 -0
- package/dist/kernel/cli/index.mjs +1 -0
- package/dist/kernel/cli/schemas.d.mts +64 -0
- package/dist/kernel/cli/schemas.mjs +1 -0
- package/dist/kernel/extension/index.d.mts +2 -0
- package/dist/kernel/extension/index.mjs +1 -0
- package/dist/kernel/index.d.mts +296 -0
- package/dist/kernel/index.mjs +1 -0
- package/dist/kernel/namespace/index.d.mts +2 -0
- package/dist/kernel/namespace/index.mjs +1 -0
- package/dist/kernel/observability/index.d.mts +2 -0
- package/dist/kernel/observability/index.mjs +1 -0
- package/dist/kernel/providers/index.d.mts +2 -0
- package/dist/kernel/providers/index.mjs +1 -0
- package/dist/kernel/window/index.d.mts +2 -0
- package/dist/kernel/window/index.mjs +1 -0
- package/dist/materialization-CuUBu4XI.mjs +1 -0
- package/dist/model-registry-CfXytvzx.mjs +1 -0
- package/dist/model-registry-Scn_MC2d.mjs +1 -0
- package/dist/namespace-5QQqbF-B.d.mts +3133 -0
- package/dist/namespace-BM7Djng9.d.mts +189 -0
- package/dist/namespace-BoD94mrN.mjs +1 -0
- package/dist/namespace-BwzZJqTV.mjs +1 -0
- package/dist/namespace-CFLAmQfh.mjs +1 -0
- package/dist/namespace-CTm3nEvh.d.mts +51 -0
- package/dist/namespace-CaaNnKcR.d.mts +921 -0
- package/dist/namespace-CaoZ3S78.d.mts +43 -0
- package/dist/namespace-CxhsoFUP.d.mts +607 -0
- package/dist/namespace-DD8Oiqo7.d.mts +580 -0
- package/dist/namespace-DLovh2Ws.d.mts +1313 -0
- package/dist/namespace-DgqkaOVu.d.mts +768 -0
- package/dist/namespace-DkRgbZYn.mjs +1 -0
- package/dist/namespace-Dr8K0MCp.d.mts +2047 -0
- package/dist/namespace-DuXK5AYN.mjs +1 -0
- package/dist/namespace-EQniz-Aw.d.mts +142 -0
- package/dist/namespace-IV1QK__V.d.mts +159 -0
- package/dist/namespace-LViZ-EQk.mjs +1 -0
- package/dist/namespace-TyiTsLFv.d.mts +3020 -0
- package/dist/namespace-Yna5-Pws.mjs +1 -0
- package/dist/namespace-xcmbQlxh.mjs +1 -0
- package/dist/native-session-supervisor-B1TnaPUF.mjs +1 -0
- package/dist/node/bus-server/index.d.mts +178 -0
- package/dist/node/bus-server/index.mjs +1 -0
- package/dist/node/bus-server/server-lifecycle.d.mts +2 -0
- package/dist/node/bus-server/server-lifecycle.mjs +1 -0
- package/dist/node/machine-identity/index.d.mts +85 -0
- package/dist/node/machine-identity/index.mjs +3 -0
- package/dist/node/transports/index.d.mts +1945 -0
- package/dist/node/transports/index.mjs +2 -0
- package/dist/orchestrator-shared-CIDiFJMD.mjs +1 -0
- package/dist/orchestrator-shared-Dfa7FMyw.d.mts +249 -0
- package/dist/package-DKVlsMP3.mjs +1 -0
- package/dist/platform-DZ7z-wXD.mjs +1 -0
- package/dist/profile-6ynCD5k3.mjs +1 -0
- package/dist/provider-context-CK6B4X_8.mjs +1 -0
- package/dist/providers/index.d.mts +135 -0
- package/dist/providers/index.mjs +1 -0
- package/dist/providers-namespace-DSEpli4A.d.mts +583 -0
- package/dist/providers-u8i15co9.mjs +1 -0
- package/dist/schema-CoyE6mPt.mjs +1 -0
- package/dist/schema-M5YTvSAG.d.mts +949 -0
- package/dist/schema-e0wU_lcV.mjs +1 -0
- package/dist/schema-introspection-Dn1jWQs1.mjs +1 -0
- package/dist/schemas-Bd0OjRQf.d.mts +46 -0
- package/dist/schemas-C46QfKzv.d.mts +459 -0
- package/dist/schemas-CDBSjg7o.d.mts +237 -0
- package/dist/schemas-CR1Rripy.mjs +1 -0
- package/dist/schemas-CVvwIfG4.mjs +1 -0
- package/dist/schemas-CaLhkkLn.mjs +1 -0
- package/dist/schemas-ClOOT1W6.d.mts +174 -0
- package/dist/schemas-DATniTHb.d.mts +182 -0
- package/dist/schemas-DE-GNmSD.mjs +1 -0
- package/dist/schemas-DVF1A4DF.d.mts +160 -0
- package/dist/schemas-DaRSfYLf.d.mts +73 -0
- package/dist/schemas-DiYVzG6e.d.mts +315 -0
- package/dist/schemas-hSrzflwZ.mjs +1 -0
- package/dist/schemas-j7ivZ2HI.d.mts +944 -0
- package/dist/schemas-jFe1AuI-.mjs +1 -0
- package/dist/schemas-wg_6PAdV.d.mts +153 -0
- package/dist/scoped-bus-04pwo1uM.mjs +1 -0
- package/dist/server-lifecycle-FXTPW39-.mjs +1 -0
- package/dist/server-lifecycle-YoSGFGnU.d.mts +160 -0
- package/dist/service-base/index.d.mts +98 -0
- package/dist/service-base/index.mjs +1 -0
- package/dist/services/adapter-runtime/index.d.mts +4 -0
- package/dist/services/adapter-runtime/index.mjs +1 -0
- package/dist/services/adapter-runtime/namespace.d.mts +2 -0
- package/dist/services/adapter-runtime/namespace.mjs +1 -0
- package/dist/services/adapter-runtime/schemas.d.mts +2 -0
- package/dist/services/adapter-runtime/schemas.mjs +1 -0
- package/dist/services/adapter-subsystem/index.d.mts +3 -0
- package/dist/services/adapter-subsystem/index.mjs +1 -0
- package/dist/services/adapter-subsystem/namespace.d.mts +2 -0
- package/dist/services/adapter-subsystem/namespace.mjs +1 -0
- package/dist/services/agent-runtime/index.d.mts +3 -0
- package/dist/services/agent-runtime/index.mjs +1 -0
- package/dist/services/agent-runtime/namespace.d.mts +2 -0
- package/dist/services/agent-runtime/namespace.mjs +1 -0
- package/dist/services/agent-runtime/schemas.d.mts +2 -0
- package/dist/services/agent-runtime/schemas.mjs +1 -0
- package/dist/services/capability/index.d.mts +2 -0
- package/dist/services/capability/index.mjs +1 -0
- package/dist/services/cli-detection/namespace.d.mts +56 -0
- package/dist/services/cli-detection/namespace.mjs +1 -0
- package/dist/services/codebase/index.d.mts +3 -0
- package/dist/services/codebase/index.mjs +1 -0
- package/dist/services/codebase/namespace.d.mts +2 -0
- package/dist/services/codebase/namespace.mjs +1 -0
- package/dist/services/codebase/schemas.d.mts +2 -0
- package/dist/services/codebase/schemas.mjs +1 -0
- package/dist/services/compression/index.d.mts +3 -0
- package/dist/services/compression/index.mjs +1 -0
- package/dist/services/compression/namespace.d.mts +2 -0
- package/dist/services/compression/namespace.mjs +1 -0
- package/dist/services/compression/schemas.d.mts +2 -0
- package/dist/services/compression/schemas.mjs +1 -0
- package/dist/services/context-rules/index.d.mts +412 -0
- package/dist/services/context-rules/index.mjs +1 -0
- package/dist/services/credential-change/index.d.mts +17 -0
- package/dist/services/credential-change/index.mjs +1 -0
- package/dist/services/definition/index.d.mts +2 -0
- package/dist/services/definition/index.mjs +1 -0
- package/dist/services/definition/namespace.d.mts +71 -0
- package/dist/services/definition/namespace.mjs +1 -0
- package/dist/services/definition/schemas.d.mts +38 -0
- package/dist/services/definition/schemas.mjs +1 -0
- package/dist/services/dialog/namespace.d.mts +105 -0
- package/dist/services/dialog/namespace.mjs +1 -0
- package/dist/services/dialog/schemas.d.mts +109 -0
- package/dist/services/dialog/schemas.mjs +1 -0
- package/dist/services/execution-target/index.d.mts +4 -0
- package/dist/services/execution-target/index.mjs +1 -0
- package/dist/services/execution-target/namespace.d.mts +2 -0
- package/dist/services/execution-target/namespace.mjs +1 -0
- package/dist/services/execution-target/schemas.d.mts +2 -0
- package/dist/services/execution-target/schemas.mjs +1 -0
- package/dist/services/filesystem/index.d.mts +3 -0
- package/dist/services/filesystem/index.mjs +1 -0
- package/dist/services/filesystem/namespace.d.mts +432 -0
- package/dist/services/filesystem/namespace.mjs +1 -0
- package/dist/services/filesystem/schemas.d.mts +240 -0
- package/dist/services/filesystem/schemas.mjs +1 -0
- package/dist/services/git/namespace.d.mts +1163 -0
- package/dist/services/git/namespace.mjs +1 -0
- package/dist/services/git/schemas.d.mts +932 -0
- package/dist/services/git/schemas.mjs +1 -0
- package/dist/services/harness/index.d.mts +861 -0
- package/dist/services/harness/index.mjs +1 -0
- package/dist/services/harness/storage/schema.d.mts +424 -0
- package/dist/services/harness/storage/schema.mjs +1 -0
- package/dist/services/index.d.mts +6185 -0
- package/dist/services/index.mjs +1 -0
- package/dist/services/local-notification/index.d.mts +25 -0
- package/dist/services/local-notification/index.mjs +1 -0
- package/dist/services/local-notification/namespace.d.mts +73 -0
- package/dist/services/local-notification/namespace.mjs +1 -0
- package/dist/services/local-notification/schemas.d.mts +88 -0
- package/dist/services/local-notification/schemas.mjs +1 -0
- package/dist/services/log-import/browser.d.mts +3 -0
- package/dist/services/log-import/browser.mjs +1 -0
- package/dist/services/log-import/index.d.mts +274 -0
- package/dist/services/log-import/index.mjs +2 -0
- package/dist/services/log-import/log-import.d.mts +3 -0
- package/dist/services/log-import/log-import.mjs +1 -0
- package/dist/services/log-import/namespace.d.mts +327 -0
- package/dist/services/log-import/namespace.mjs +1 -0
- package/dist/services/log-import/schemas.d.mts +217 -0
- package/dist/services/log-import/schemas.mjs +1 -0
- package/dist/services/model-registry/index.d.mts +2 -0
- package/dist/services/model-registry/index.mjs +1 -0
- package/dist/services/preferences/index.d.mts +3 -0
- package/dist/services/preferences/index.mjs +1 -0
- package/dist/services/preferences/schemas.d.mts +2 -0
- package/dist/services/preferences/schemas.mjs +1 -0
- package/dist/services/preferences/storage-namespace.d.mts +3 -0
- package/dist/services/preferences/storage-namespace.mjs +1 -0
- package/dist/services/provider-context/index.d.mts +2 -0
- package/dist/services/provider-context/index.mjs +1 -0
- package/dist/services/provider-runtime/index.d.mts +136 -0
- package/dist/services/provider-runtime/index.mjs +1 -0
- package/dist/services/session/handlers/index.d.mts +2 -0
- package/dist/services/session/handlers/index.mjs +1 -0
- package/dist/services/session/index.d.mts +10 -0
- package/dist/services/session/index.mjs +1 -0
- package/dist/services/session/messages/namespace.d.mts +2 -0
- package/dist/services/session/messages/namespace.mjs +1 -0
- package/dist/services/session/orchestrator-testing/index.d.mts +2 -0
- package/dist/services/session/orchestrator-testing/index.mjs +1 -0
- package/dist/services/session/session-events/namespace.d.mts +2 -0
- package/dist/services/session/session-events/namespace.mjs +1 -0
- package/dist/services/session/storage/namespace.d.mts +2 -0
- package/dist/services/session/storage/namespace.mjs +1 -0
- package/dist/services/session/storage/schema.d.mts +2 -0
- package/dist/services/session/storage/schema.mjs +1 -0
- package/dist/services/session/testing/index.d.mts +35 -0
- package/dist/services/session/testing/index.mjs +65 -0
- package/dist/services/session/testing/orchestrator-shared.d.mts +2 -0
- package/dist/services/session/testing/orchestrator-shared.mjs +1 -0
- package/dist/services/session/turns/namespace.d.mts +2 -0
- package/dist/services/session/turns/namespace.mjs +1 -0
- package/dist/services/session-editor/index.d.mts +119 -0
- package/dist/services/session-editor/index.mjs +1 -0
- package/dist/services/settings/index.d.mts +47 -0
- package/dist/services/settings/index.mjs +1 -0
- package/dist/services/settings/namespace.d.mts +663 -0
- package/dist/services/settings/namespace.mjs +1 -0
- package/dist/services/settings/storage/clients-namespace.d.mts +2 -0
- package/dist/services/settings/storage/clients-namespace.mjs +1 -0
- package/dist/services/settings/storage/extension-configs/namespace.d.mts +184 -0
- package/dist/services/settings/storage/extension-configs/namespace.mjs +1 -0
- package/dist/services/settings/storage/index.d.mts +4 -0
- package/dist/services/settings/storage/index.mjs +1 -0
- package/dist/services/settings/storage/providers-namespace.d.mts +2 -0
- package/dist/services/settings/storage/providers-namespace.mjs +1 -0
- package/dist/services/subagent/index.d.mts +2 -0
- package/dist/services/subagent/index.mjs +1 -0
- package/dist/services/subagent-template/index.d.mts +3 -0
- package/dist/services/subagent-template/index.mjs +1 -0
- package/dist/services/subagent-template/namespace.d.mts +2 -0
- package/dist/services/subagent-template/namespace.mjs +1 -0
- package/dist/services/subagent-template/schemas.d.mts +2 -0
- package/dist/services/subagent-template/schemas.mjs +1 -0
- package/dist/services/tool-approval/index.d.mts +2 -0
- package/dist/services/tool-approval/index.mjs +1 -0
- package/dist/services/tools/index.d.mts +2 -0
- package/dist/services/tools/index.mjs +1 -0
- package/dist/services/tray-menu/index.d.mts +4 -0
- package/dist/services/tray-menu/index.mjs +1 -0
- package/dist/services/tray-menu/namespace.d.mts +2 -0
- package/dist/services/tray-menu/namespace.mjs +1 -0
- package/dist/services/tray-menu/schemas.d.mts +2 -0
- package/dist/services/tray-menu/schemas.mjs +1 -0
- package/dist/services/turn/index.d.mts +2 -0
- package/dist/services/turn/index.mjs +1 -0
- package/dist/services/turn/namespace.d.mts +2 -0
- package/dist/services/turn/namespace.mjs +1 -0
- package/dist/services/turn/schemas.d.mts +335 -0
- package/dist/services/turn/schemas.mjs +1 -0
- package/dist/session-BoldSdNZ2.mjs +134 -0
- package/dist/session-DuVOYctZ.mjs +1 -0
- package/dist/session-lineage-CRsc9g1x.d.mts +65 -0
- package/dist/shared-DpOEfD8F.mjs +1 -0
- package/dist/shared-schemas-CPShiLNp.mjs +1 -0
- package/dist/skill-CQO4mDqK.mjs +1 -0
- package/dist/storage/drizzle/client.d.mts +78 -0
- package/dist/storage/drizzle/client.mjs +1 -0
- package/dist/storage/drizzle/index.d.mts +137 -0
- package/dist/storage/drizzle/index.mjs +1 -0
- package/dist/storage/handlers/drizzle/index.d.mts +2 -0
- package/dist/storage/handlers/drizzle/index.mjs +1 -0
- package/dist/storage/handlers/index.d.mts +33 -0
- package/dist/storage/handlers/index.mjs +1 -0
- package/dist/storage/index.d.mts +192 -0
- package/dist/storage/index.mjs +1 -0
- package/dist/storage-namespace-BXkoh5Sy.d.mts +221 -0
- package/dist/storage-namespace-DWsYLAXa.mjs +1 -0
- package/dist/storage-namespace-definition-Bkx5rSto.d.mts +17 -0
- package/dist/storage-namespace-definition-CqSdsuCC.mjs +1 -0
- package/dist/style.css +3782 -0
- package/dist/telemetry-CvdLBWuk.mjs +1 -0
- package/dist/testing/drizzle-harness.d.mts +130 -0
- package/dist/testing/drizzle-harness.mjs +1 -0
- package/dist/testing/index.d.mts +106 -0
- package/dist/testing/index.mjs +1 -0
- package/dist/timeout-XsYIOKrc.mjs +1 -0
- package/dist/tool-approval-service-BvZWhYZp.mjs +1 -0
- package/dist/tools/index.d.mts +835 -0
- package/dist/tools/index.mjs +1 -0
- package/dist/tools/testing/index.d.mts +53 -0
- package/dist/tools/testing/index.mjs +1 -0
- package/dist/tools-D-luYcDw.mjs +1431 -0
- package/dist/tray-menu-service-DuXq5k22.mjs +1 -0
- package/dist/types-BCMUtBj1.d.mts +1106 -0
- package/dist/types-C2Ob9zz_.d.mts +128 -0
- package/dist/types-CCdqjeuH.d.mts +262 -0
- package/dist/types-DZHvOc_Q.d.mts +305 -0
- package/dist/types-Dy3YTcTF.d.mts +6777 -0
- package/dist/types-MfJZ67e9.d.mts +315 -0
- package/dist/types-dyP-bXXE.d.mts +31 -0
- package/dist/ui-components/index.d.mts +2342 -0
- package/dist/ui-components/index.mjs +8 -0
- package/dist/ui-config-9bDRwFZr.mjs +1 -0
- package/dist/ui-hooks/index.d.mts +1915 -0
- package/dist/ui-hooks/index.mjs +1 -0
- package/dist/ui-kernel/index.d.mts +2793 -0
- package/dist/ui-kernel/index.mjs +1 -0
- package/dist/ui-kernel/pages/namespace.d.mts +88 -0
- package/dist/ui-kernel/pages/namespace.mjs +1 -0
- package/dist/ui-kernel/pages/schemas.d.mts +2 -0
- package/dist/ui-kernel/pages/schemas.mjs +1 -0
- package/dist/ui-views/index.d.mts +487 -0
- package/dist/ui-views/index.mjs +30 -0
- package/dist/utils/health-probe.d.mts +26 -0
- package/dist/utils/health-probe.mjs +1 -0
- package/dist/utils/index.d.mts +262 -0
- package/dist/utils/index.mjs +2 -0
- package/dist/utils/keychain.d.mts +31 -0
- package/dist/utils/keychain.mjs +1 -0
- package/dist/utils/project-manifest.d.mts +130 -0
- package/dist/utils/project-manifest.mjs +1 -0
- package/dist/utils/resolve-package-root.d.mts +12 -0
- package/dist/utils/resolve-package-root.mjs +1 -0
- package/dist/utils/scope-paths.d.mts +33 -0
- package/dist/utils/scope-paths.mjs +1 -0
- package/dist/utils/workspace-packages.d.mts +59 -0
- package/dist/utils/workspace-packages.mjs +1 -0
- package/dist/utils/workspace-root.d.mts +24 -0
- package/dist/utils/workspace-root.mjs +2 -0
- package/dist/variant-CT6XBP6T.mjs +1 -0
- package/dist/version-BeT3ASEe.mjs +1 -0
- package/dist/visibility-Cb62p9bv.mjs +1 -0
- package/dist/window-registry-CBcrGTv4.d.mts +130 -0
- package/dist/window-registry-DW-dKRjQ.mjs +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,3994 @@
|
|
|
1
|
+
import * as _$zod from "zod";
|
|
2
|
+
import { ZodType, z } from "zod";
|
|
3
|
+
import { Paths, Simplify, UnknownRecord } from "type-fest";
|
|
4
|
+
import * as _$zod_v4_core0 from "zod/v4/core";
|
|
5
|
+
|
|
6
|
+
//#region core/makaio-core/src/types/message.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* Host-agnostic principal attached by a trusted local transport.
|
|
9
|
+
*
|
|
10
|
+
* The framework treats this as opaque metadata. Host code decides what
|
|
11
|
+
* principal kinds and claims mean.
|
|
12
|
+
*/
|
|
13
|
+
interface PrincipalContext {
|
|
14
|
+
/** Principal kind, such as `user`, `device`, `machine`, or host-defined values. */
|
|
15
|
+
readonly kind: string;
|
|
16
|
+
/** Optional stable principal identifier in the principal namespace. */
|
|
17
|
+
readonly id?: string;
|
|
18
|
+
/** Optional opaque claims supplied by the authenticating transport or host policy. */
|
|
19
|
+
readonly claims?: Readonly<Record<string, unknown>>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Authenticated peer metadata supplied by a transport connection.
|
|
23
|
+
*/
|
|
24
|
+
interface TransportPeerContext {
|
|
25
|
+
/** Peer kind, such as `browser`, `machine`, `worker`, or host-defined values. */
|
|
26
|
+
readonly kind: string;
|
|
27
|
+
/** Optional transport-level peer identifier. */
|
|
28
|
+
readonly id?: string;
|
|
29
|
+
/** Whether the receiving transport authenticated the peer. */
|
|
30
|
+
readonly authenticated?: boolean;
|
|
31
|
+
/** Whether the receiving transport established encrypted payload transport. */
|
|
32
|
+
readonly encrypted?: boolean;
|
|
33
|
+
/** Optional opaque peer claims. */
|
|
34
|
+
readonly claims?: Readonly<Record<string, unknown>>;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Trusted context derived locally by the receiving transport.
|
|
38
|
+
*
|
|
39
|
+
* This context is never serialized into `BusMessage`; each receiving node must
|
|
40
|
+
* derive its own context from its own transport/session state.
|
|
41
|
+
*/
|
|
42
|
+
interface TransportReceiveContext {
|
|
43
|
+
/** Registered bus transport name that received the message. */
|
|
44
|
+
readonly transportName: string;
|
|
45
|
+
/** Optional connection/session identifier local to the transport. */
|
|
46
|
+
readonly connectionId?: string;
|
|
47
|
+
/** Optional authenticated transport peer. */
|
|
48
|
+
readonly peer?: TransportPeerContext;
|
|
49
|
+
/** Optional host-agnostic principal resolved for this connection. */
|
|
50
|
+
readonly principal?: PrincipalContext;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Describes the call origin of a bus message.
|
|
54
|
+
*
|
|
55
|
+
* Set on every context before handlers run; never serialized to wire.
|
|
56
|
+
* Derivation: `local` is `true` when no transport received the message
|
|
57
|
+
* (the call originated in this process), `false` when it arrived over
|
|
58
|
+
* a transport from a remote peer.
|
|
59
|
+
*/
|
|
60
|
+
interface MessageOrigin {
|
|
61
|
+
/** Whether the message originated locally (not from a remote transport). */
|
|
62
|
+
readonly local: boolean;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Base message context interface for both events and requests.
|
|
66
|
+
*
|
|
67
|
+
* Provides common metadata for tracking and correlation:
|
|
68
|
+
* - `messageId`: Unique identifier for this specific message
|
|
69
|
+
* - `correlationId`: Optional identifier linking related operations
|
|
70
|
+
*/
|
|
71
|
+
interface BaseMessageContext {
|
|
72
|
+
/**
|
|
73
|
+
* Unique identifier for this specific message.
|
|
74
|
+
* Auto-generated if not provided.
|
|
75
|
+
*
|
|
76
|
+
* Used for:
|
|
77
|
+
* - Message deduplication
|
|
78
|
+
* - Idempotency checks
|
|
79
|
+
* - Tracking individual messages in logs
|
|
80
|
+
*/
|
|
81
|
+
messageId: string;
|
|
82
|
+
/**
|
|
83
|
+
* Optional identifier linking related operations.
|
|
84
|
+
* Propagated through chains of requests/events.
|
|
85
|
+
*
|
|
86
|
+
* Used for:
|
|
87
|
+
* - Distributed tracing
|
|
88
|
+
* - Causality tracking
|
|
89
|
+
* - Following a workflow through the system
|
|
90
|
+
* @example
|
|
91
|
+
* ```typescript
|
|
92
|
+
* // Initial request generates correlationId
|
|
93
|
+
* const result = await request(
|
|
94
|
+
* UserSubjects.getUser,
|
|
95
|
+
* { userId: '42' },
|
|
96
|
+
* { correlationId: 'user-action-123' }
|
|
97
|
+
* );
|
|
98
|
+
*
|
|
99
|
+
* // Handler propagates correlationId to downstream operations
|
|
100
|
+
* await emit(
|
|
101
|
+
* UserSubjects.userLoaded,
|
|
102
|
+
* { user: result },
|
|
103
|
+
* { correlationId: context.correlationId }
|
|
104
|
+
* );
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
correlationId?: string;
|
|
108
|
+
/**
|
|
109
|
+
* Trusted context supplied by the local receiving transport.
|
|
110
|
+
*
|
|
111
|
+
* Undefined for local calls and for transports that do not supply connection
|
|
112
|
+
* context. Never trust similarly named fields in payloads or wire messages.
|
|
113
|
+
*/
|
|
114
|
+
transport?: TransportReceiveContext;
|
|
115
|
+
/**
|
|
116
|
+
* Where this message originated.
|
|
117
|
+
*
|
|
118
|
+
* `local: true` — emitted in this process.
|
|
119
|
+
* `local: false` — arrived via a transport from a remote caller.
|
|
120
|
+
*
|
|
121
|
+
* Always present; never serialized to the wire. Location-sensitive handlers
|
|
122
|
+
* check this before executing local side-effects.
|
|
123
|
+
*/
|
|
124
|
+
origin: MessageOrigin;
|
|
125
|
+
isRequest: boolean;
|
|
126
|
+
}
|
|
127
|
+
type EventMessagePayload<Payload extends UnknownRecord = UnknownRecord> = Payload & {
|
|
128
|
+
request?: never;
|
|
129
|
+
response?: never;
|
|
130
|
+
};
|
|
131
|
+
type RequestMessagePayload<Request extends UnknownRecord = UnknownRecord, Response extends UnknownRecord = UnknownRecord> = {
|
|
132
|
+
request: Request;
|
|
133
|
+
response: Response;
|
|
134
|
+
};
|
|
135
|
+
type MessagePayload = RequestMessagePayload | EventMessagePayload;
|
|
136
|
+
//#endregion
|
|
137
|
+
//#region core/makaio-core/src/types/context.d.ts
|
|
138
|
+
/**
|
|
139
|
+
* Context object passed to event handlers when using wildcard patterns.
|
|
140
|
+
*
|
|
141
|
+
* Provides:
|
|
142
|
+
* - `isRequest`: Always false (discriminator for type narrowing)
|
|
143
|
+
* - `payload`: The event payload
|
|
144
|
+
* - Message tracking fields from BaseMessage (messageId, correlationId)
|
|
145
|
+
*/
|
|
146
|
+
interface EventContext<Payload> extends BaseMessageContext {
|
|
147
|
+
/** Discriminator - always false for events */
|
|
148
|
+
isRequest: false;
|
|
149
|
+
/** The event payload */
|
|
150
|
+
payload: Payload;
|
|
151
|
+
/** The event subject */
|
|
152
|
+
subject: string;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Context object passed to request handlers.
|
|
156
|
+
*
|
|
157
|
+
* Provides:
|
|
158
|
+
* - `isRequest`: Always true (discriminator for type narrowing)
|
|
159
|
+
* - `payload`: The request payload
|
|
160
|
+
* - `setResult`: Function to set the response value
|
|
161
|
+
* - `next`: Function to call the next handler in the middleware chain
|
|
162
|
+
* - `replacePayload`: Function to transform the payload for subsequent handlers
|
|
163
|
+
* - `identify`: Optional function to identify the handler for broadcast aggregation
|
|
164
|
+
* - `signal`: Optional AbortSignal from the originating request
|
|
165
|
+
* - Message tracking fields from BaseMessage (messageId, correlationId)
|
|
166
|
+
*/
|
|
167
|
+
interface RequestContext<Payload, Response> extends BaseMessageContext {
|
|
168
|
+
/** Discriminator - always true for requests */
|
|
169
|
+
isRequest: true;
|
|
170
|
+
/** The request payload */
|
|
171
|
+
payload: Payload;
|
|
172
|
+
/** AbortSignal supplied by the originating request, if any. */
|
|
173
|
+
signal?: AbortSignal;
|
|
174
|
+
/** Set the response value (ends the handler chain) */
|
|
175
|
+
setResult: (result: Response) => void;
|
|
176
|
+
/**
|
|
177
|
+
* Read the current result value.
|
|
178
|
+
*
|
|
179
|
+
* Returns the value set by `setResult()` in this handler or by a downstream
|
|
180
|
+
* handler after `await next()`. Undefined until a result has been set.
|
|
181
|
+
*/
|
|
182
|
+
readonly result: Response | undefined;
|
|
183
|
+
/**
|
|
184
|
+
* Shallow-merge additional fields into the current result.
|
|
185
|
+
*
|
|
186
|
+
* Only valid for object-typed responses. In the request path the operation
|
|
187
|
+
* uses spread (immutable); in broadcast mode it uses `Object.assign`
|
|
188
|
+
* (in-place mutation) so the already-pushed result reference stays current.
|
|
189
|
+
* If no result has been set yet, starts from an empty object.
|
|
190
|
+
* @param extension - Fields to merge into the current result
|
|
191
|
+
*/
|
|
192
|
+
extendResult: (extension: [Response] extends [Record<string, unknown>] ? Partial<Response> : never) => void;
|
|
193
|
+
/**
|
|
194
|
+
* Call the next handler in the middleware chain.
|
|
195
|
+
* If no more handlers exist, throws NoHandlerError.
|
|
196
|
+
*/
|
|
197
|
+
next: () => Promise<void>;
|
|
198
|
+
/**
|
|
199
|
+
* Replace the payload with a new value.
|
|
200
|
+
* Subsequent handlers in the middleware chain will receive the new payload.
|
|
201
|
+
* Useful for hooks that need to inject context before the main handler runs.
|
|
202
|
+
*/
|
|
203
|
+
replacePayload: (newPayload: Payload) => void;
|
|
204
|
+
/**
|
|
205
|
+
* Identify this handler for broadcast aggregation.
|
|
206
|
+
* Only present when called via broadcast() - call before setResult().
|
|
207
|
+
* @param nodeId - Unique identifier for this handler/node
|
|
208
|
+
*/
|
|
209
|
+
identify?: (nodeId: string) => void;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Unified context for wildcard handlers that can match both events and requests.
|
|
213
|
+
* Use the `isRequest` discriminator to narrow the type.
|
|
214
|
+
* @example
|
|
215
|
+
* ```typescript
|
|
216
|
+
* MakaioBus.on('adapter.*', (context) => {
|
|
217
|
+
* if (context.isRequest) {
|
|
218
|
+
* // TypeScript knows this is RequestContext
|
|
219
|
+
* context.setResult({ handled: true });
|
|
220
|
+
* } else {
|
|
221
|
+
* // TypeScript knows this is EventContext
|
|
222
|
+
* console.debug('Event:', context.payload);
|
|
223
|
+
* }
|
|
224
|
+
* });
|
|
225
|
+
* ```
|
|
226
|
+
*/
|
|
227
|
+
type WildcardContext<Payload = unknown, Response = unknown> = EventContext<Payload> | RequestContext<Payload, Response>;
|
|
228
|
+
//#endregion
|
|
229
|
+
//#region core/makaio-core/src/types/filter.d.ts
|
|
230
|
+
type Primitive = string | number | boolean | null;
|
|
231
|
+
/**
|
|
232
|
+
* Filter operators for payload field matching.
|
|
233
|
+
* @example
|
|
234
|
+
* ```typescript
|
|
235
|
+
* // Equality (implicit)
|
|
236
|
+
* { agentId: 'agent-123' }
|
|
237
|
+
*
|
|
238
|
+
* // Membership
|
|
239
|
+
* { status: { $in: ['active', 'pending'] } }
|
|
240
|
+
*
|
|
241
|
+
* // Not equal
|
|
242
|
+
* { type: { $ne: 'internal' } }
|
|
243
|
+
*
|
|
244
|
+
* // Presence check
|
|
245
|
+
* { error: { $exists: false } }
|
|
246
|
+
*
|
|
247
|
+
* // String prefix/suffix matching
|
|
248
|
+
* { path: { $startsWith: '.git/' } }
|
|
249
|
+
* { file: { $endsWith: '.ts' } }
|
|
250
|
+
* ```
|
|
251
|
+
*/
|
|
252
|
+
type FilterOperator<T extends Primitive = Primitive> = T | {
|
|
253
|
+
$in: T[];
|
|
254
|
+
} | {
|
|
255
|
+
$ne: T;
|
|
256
|
+
} | {
|
|
257
|
+
$exists: boolean;
|
|
258
|
+
} | {
|
|
259
|
+
$startsWith: string;
|
|
260
|
+
} | {
|
|
261
|
+
$endsWith: string;
|
|
262
|
+
};
|
|
263
|
+
/**
|
|
264
|
+
* Untyped payload filter - accepts any string keys.
|
|
265
|
+
* Use TypedPayloadFilter<T> for type-safe filters.
|
|
266
|
+
*/
|
|
267
|
+
type PayloadFilter = Record<string, FilterOperator>;
|
|
268
|
+
/**
|
|
269
|
+
* Type-safe payload filter constrained to valid paths of a payload type.
|
|
270
|
+
*
|
|
271
|
+
* Uses type-fest's `Paths` to support dotted path notation for nested fields.
|
|
272
|
+
* @example
|
|
273
|
+
* ```typescript
|
|
274
|
+
* interface McpPayload {
|
|
275
|
+
* agentId: string;
|
|
276
|
+
* raw: { msg: { type: string } };
|
|
277
|
+
* }
|
|
278
|
+
*
|
|
279
|
+
* // Type-safe - validates both top-level and nested paths
|
|
280
|
+
* const filter: TypedPayloadFilter<McpPayload> = {
|
|
281
|
+
* agentId: 'agent-123',
|
|
282
|
+
* 'raw.msg.type': 'session_configured', // ✅ valid path
|
|
283
|
+
* 'raw.msg.typo': 'x', // ❌ type error
|
|
284
|
+
* };
|
|
285
|
+
* ```
|
|
286
|
+
*/
|
|
287
|
+
type TypedPayloadFilter<T> = { [K in Paths<T> & string]?: FilterOperator };
|
|
288
|
+
//#endregion
|
|
289
|
+
//#region core/makaio-core/src/types/schema.d.ts
|
|
290
|
+
/**
|
|
291
|
+
* Schema definition for event subjects (fire-and-forget).
|
|
292
|
+
* Events have only a payload schema, no response.
|
|
293
|
+
* The payload is now separate from the context, so no restrictions needed.
|
|
294
|
+
*/
|
|
295
|
+
type EventSchema = z.ZodType;
|
|
296
|
+
/**
|
|
297
|
+
* Schema definition for request subjects (request-response).
|
|
298
|
+
* Requests have both a request payload schema and a response schema.
|
|
299
|
+
*/
|
|
300
|
+
type RequestSchema<Request extends ZodType = ZodType, Response extends ZodType = ZodType> = {
|
|
301
|
+
request: Request;
|
|
302
|
+
response: Response;
|
|
303
|
+
};
|
|
304
|
+
/**
|
|
305
|
+
* Wrapper to mark a subject as local-only (never sent to transports).
|
|
306
|
+
*
|
|
307
|
+
* Use `localSubject()` from `@makaio/bus-core` to create these.
|
|
308
|
+
* @example
|
|
309
|
+
* ```typescript
|
|
310
|
+
* import { localSubject } from '@makaio/framework/bus';
|
|
311
|
+
*
|
|
312
|
+
* const WidgetSchemas = {
|
|
313
|
+
* register: localSubject(widgetDefinitionSchema), // local event
|
|
314
|
+
* unregister: localSubject(z.object({ widgetId: z.string() })),
|
|
315
|
+
* };
|
|
316
|
+
* ```
|
|
317
|
+
*/
|
|
318
|
+
type LocalSubjectSchema<T extends EventSchema | RequestSchema = EventSchema | RequestSchema> = {
|
|
319
|
+
readonly __local: true;
|
|
320
|
+
readonly schema: T;
|
|
321
|
+
};
|
|
322
|
+
/**
|
|
323
|
+
* Wrapper to mark an event subject as collector-only.
|
|
324
|
+
*
|
|
325
|
+
* Collector-only events may be received from a transport and delivered to local
|
|
326
|
+
* handlers, but the receiving bus must not relay them onward to other
|
|
327
|
+
* transports. Local emits are also kept local.
|
|
328
|
+
*/
|
|
329
|
+
type CollectorOnlySubjectSchema<T extends EventSchema = EventSchema> = {
|
|
330
|
+
readonly __collectorOnly: true;
|
|
331
|
+
readonly schema: T;
|
|
332
|
+
};
|
|
333
|
+
/**
|
|
334
|
+
* Wrapper to mark a subject as channel-only (encrypted point-to-point).
|
|
335
|
+
*
|
|
336
|
+
* Channel subjects are rejected by public bus methods and are only
|
|
337
|
+
* routable through the DirectChannel encrypted transport. Use
|
|
338
|
+
* `channelSubject()` from `@makaio/bus-core` to create these.
|
|
339
|
+
* @example
|
|
340
|
+
* ```typescript
|
|
341
|
+
* import { channelSubject } from '@makaio/framework/bus';
|
|
342
|
+
*
|
|
343
|
+
* const DirectSchemas = {
|
|
344
|
+
* message: channelSubject(z.object({ text: z.string() })),
|
|
345
|
+
* ping: channelSubject({
|
|
346
|
+
* request: z.object({ ts: z.number() }),
|
|
347
|
+
* response: z.object({ ts: z.number() }),
|
|
348
|
+
* }),
|
|
349
|
+
* };
|
|
350
|
+
* ```
|
|
351
|
+
*/
|
|
352
|
+
type ChannelSubjectSchema<T extends EventSchema | RequestSchema = EventSchema | RequestSchema> = {
|
|
353
|
+
readonly __channel: true;
|
|
354
|
+
readonly schema: T;
|
|
355
|
+
};
|
|
356
|
+
/**
|
|
357
|
+
* Wrapper to set a subject-level default transport routing policy.
|
|
358
|
+
*
|
|
359
|
+
* This is weaker than `localSubject()`: the subject remains routable remotely,
|
|
360
|
+
* but local callers that omit an explicit `transports` option use this default.
|
|
361
|
+
*/
|
|
362
|
+
type DefaultTransportsSubjectSchema<T extends EventSchema | RequestSchema = EventSchema | RequestSchema, Default extends TransportRoutingDefault = TransportRoutingDefault> = {
|
|
363
|
+
readonly __defaultTransports: Default;
|
|
364
|
+
readonly schema: T;
|
|
365
|
+
};
|
|
366
|
+
/**
|
|
367
|
+
* Base schema types (unwrapped).
|
|
368
|
+
*/
|
|
369
|
+
type BaseSubjectSchema = EventSchema | RequestSchema;
|
|
370
|
+
/**
|
|
371
|
+
* Union of all subject schema types (including metadata wrappers).
|
|
372
|
+
*/
|
|
373
|
+
type SubjectSchema = BaseSubjectSchema | LocalSubjectSchema | CollectorOnlySubjectSchema | ChannelSubjectSchema | DefaultTransportsSubjectSchema;
|
|
374
|
+
type SchemaRecord = Record<string, SubjectSchema>;
|
|
375
|
+
//#endregion
|
|
376
|
+
//#region core/makaio-core/src/types/type-helpers.d.ts
|
|
377
|
+
/**
|
|
378
|
+
* Unwrap subject schema wrappers if present. Returns the inner schema for
|
|
379
|
+
* wrapped subjects, or the schema as-is otherwise.
|
|
380
|
+
*/
|
|
381
|
+
type UnwrapSchema<S> = S extends {
|
|
382
|
+
readonly __local: true;
|
|
383
|
+
readonly schema: infer Inner;
|
|
384
|
+
} ? Inner : S extends {
|
|
385
|
+
readonly __collectorOnly: true;
|
|
386
|
+
readonly schema: infer Inner;
|
|
387
|
+
} ? Inner : S extends {
|
|
388
|
+
readonly __channel: true;
|
|
389
|
+
readonly schema: infer Inner;
|
|
390
|
+
} ? Inner : S extends {
|
|
391
|
+
readonly __defaultTransports: TransportRoutingDefault;
|
|
392
|
+
readonly schema: infer Inner;
|
|
393
|
+
} ? Inner : S;
|
|
394
|
+
/**
|
|
395
|
+
* Infer payload type from schema, including subject metadata wrappers.
|
|
396
|
+
*
|
|
397
|
+
* For requests:
|
|
398
|
+
* - Uses z.input for request (what callers pass before validation/defaults)
|
|
399
|
+
* - Uses z.infer for response (what handlers return after processing)
|
|
400
|
+
*
|
|
401
|
+
* This allows schemas with .default() to have optional fields in the caller API
|
|
402
|
+
* while the response type reflects the validated output.
|
|
403
|
+
*
|
|
404
|
+
* Subject schema wrappers are automatically unwrapped before inference.
|
|
405
|
+
*
|
|
406
|
+
* Idempotent: Returns already-inferred types as-is.
|
|
407
|
+
*/
|
|
408
|
+
type InferSchemaPayload<S extends SubjectSchema> = InferSchemaPayloadInner<UnwrapSchema<S>>;
|
|
409
|
+
type InferSchemaPayloadInner<S> = S extends {
|
|
410
|
+
request: infer Req extends z.ZodType;
|
|
411
|
+
response: infer Res extends z.ZodType;
|
|
412
|
+
} ? {
|
|
413
|
+
request: z.input<Req>;
|
|
414
|
+
response: z.infer<Res>;
|
|
415
|
+
} : S extends z.ZodType ? Simplify<z.infer<S>> : unknown;
|
|
416
|
+
/**
|
|
417
|
+
* Compute all subject meta from the original schema in one place.
|
|
418
|
+
*
|
|
419
|
+
* Resolves payload, locality, channel membership, request/event discriminator,
|
|
420
|
+
* default transport routing, and namespace from a raw SubjectSchema.
|
|
421
|
+
* @typeParam S - The subject schema type
|
|
422
|
+
* @typeParam Ns - The namespace string
|
|
423
|
+
*/
|
|
424
|
+
type InferSubjectMeta<S extends SubjectSchema, Ns extends string> = {
|
|
425
|
+
/** True when the subject is a request-response pair, false for events. */isRequest: UnwrapSchema<S> extends {
|
|
426
|
+
request: z.ZodType;
|
|
427
|
+
response: z.ZodType;
|
|
428
|
+
} ? true : false; /** True when the subject is wrapped with `localSubject()`. */
|
|
429
|
+
local: S extends LocalSubjectSchema ? true : false; /** True when the subject is wrapped with `channelSubject()`. */
|
|
430
|
+
channel: S extends ChannelSubjectSchema ? true : false; /** Inferred payload type (request/response pair or event payload). */
|
|
431
|
+
payload: InferSchemaPayload<S>; /** The namespace this subject belongs to. */
|
|
432
|
+
namespace: Ns;
|
|
433
|
+
} & (S extends DefaultTransportsSubjectSchema<EventSchema | RequestSchema, infer Default> ? {
|
|
434
|
+
defaultTransports: Default;
|
|
435
|
+
} : {
|
|
436
|
+
defaultTransports?: TransportRoutingDefault;
|
|
437
|
+
});
|
|
438
|
+
//#endregion
|
|
439
|
+
//#region core/makaio-core/src/types/subjects.d.ts
|
|
440
|
+
type SubjectRecord<SubjectKeys extends string = string, Payload extends MessagePayload = MessagePayload> = Record<SubjectKeys, Payload>;
|
|
441
|
+
/**
|
|
442
|
+
* Default transport routing semantics for a subject or namespace.
|
|
443
|
+
*
|
|
444
|
+
* - `'all'` — send to all registered transports (the default when omitted).
|
|
445
|
+
* - `'local-only'` — suppress outbound transport fan-out unless the caller
|
|
446
|
+
* explicitly provides a `transports` override. Weaker than `localSubject()`:
|
|
447
|
+
* the subject can still be invoked remotely.
|
|
448
|
+
*/
|
|
449
|
+
type TransportRoutingDefault = 'all' | 'local-only';
|
|
450
|
+
type SubjectRecordFromSchemaRecord<SchemaRecord extends Record<string, SubjectSchema>> = { [K in keyof SchemaRecord & string]: Simplify<InferSchemaPayload<SchemaRecord[K]>> };
|
|
451
|
+
type SubjectDefinitionMeta<Subject extends SubjectRecord = SubjectRecord<'default'>, K extends keyof Subject = keyof Subject, Namespace extends string = string> = {
|
|
452
|
+
isRequest: Subject extends SubjectRecord<'default'> ? boolean : Subject[K] extends RequestMessagePayload ? true : false;
|
|
453
|
+
payload: K extends string ? Subject[K] : unknown;
|
|
454
|
+
namespace: Namespace;
|
|
455
|
+
/**
|
|
456
|
+
* If true, this subject is local-only and will never be sent to transports.
|
|
457
|
+
* Use for subjects whose payloads contain non-serializable data (e.g., React components).
|
|
458
|
+
*/
|
|
459
|
+
local: boolean;
|
|
460
|
+
/**
|
|
461
|
+
* If true, this subject is channel-only and is only routable through the
|
|
462
|
+
* DirectChannel encrypted point-to-point transport.
|
|
463
|
+
*/
|
|
464
|
+
channel: boolean;
|
|
465
|
+
/**
|
|
466
|
+
* Default transport routing for bus calls on this subject when the caller
|
|
467
|
+
* does not provide an explicit `transports` option.
|
|
468
|
+
*
|
|
469
|
+
* - `'all'` (default) — send to all registered transports as usual.
|
|
470
|
+
* - `'local-only'` — suppress transport fan-out unless the caller explicitly
|
|
471
|
+
* provides a `transports` override. Weaker than `localSubject()`: the
|
|
472
|
+
* subject can still be invoked remotely; only the outbound default is
|
|
473
|
+
* suppressed.
|
|
474
|
+
*/
|
|
475
|
+
defaultTransports?: TransportRoutingDefault;
|
|
476
|
+
};
|
|
477
|
+
type SubjectDefinition<Subject extends SubjectRecord = SubjectRecord, SubjectKey extends keyof Subject = keyof Subject, Namespace extends string = string> = {
|
|
478
|
+
$meta: SubjectDefinitionMeta<Subject, SubjectKey, Namespace>;
|
|
479
|
+
subject: SubjectKey;
|
|
480
|
+
};
|
|
481
|
+
type ScopedSubjectDefinition<Namespace extends string = string> = SubjectDefinition<SubjectRecord, keyof SubjectRecord, Namespace>;
|
|
482
|
+
/**
|
|
483
|
+
* Extract the filterable payload from a MessagePayload.
|
|
484
|
+
* For requests, returns the request part (what we filter on).
|
|
485
|
+
* For events, returns the payload as-is.
|
|
486
|
+
*/
|
|
487
|
+
type FilterablePayload<P> = P extends RequestMessagePayload ? P['request'] : P;
|
|
488
|
+
/**
|
|
489
|
+
* Union of all filterable payloads from a SubjectRecord.
|
|
490
|
+
*/
|
|
491
|
+
type FilterablePayloadsUnion<Subjects extends SubjectRecord> = FilterablePayload<Subjects[keyof Subjects]>;
|
|
492
|
+
/**
|
|
493
|
+
* Extract keys from ANY member of a union type (distributive).
|
|
494
|
+
*
|
|
495
|
+
* For `{ a: 1, b: 2 } | { a: 1, c: 3 }`, returns `'a' | 'b' | 'c'`.
|
|
496
|
+
*/
|
|
497
|
+
type KeysOfUnion<T> = T extends unknown ? keyof T : never;
|
|
498
|
+
/**
|
|
499
|
+
* Extract value type for a key from union members that have it.
|
|
500
|
+
*/
|
|
501
|
+
type ValueOfKey<T, K extends PropertyKey> = T extends { [P in K]: infer V } ? V : never;
|
|
502
|
+
/**
|
|
503
|
+
* Build an object type with ALL keys from ANY union member.
|
|
504
|
+
*
|
|
505
|
+
* For `{ type: 'a', id: string } | { type: 'b', name: string }`:
|
|
506
|
+
* Result = `{ type: 'a' | 'b', id: string, name: string }`
|
|
507
|
+
*
|
|
508
|
+
* Allows filtering by any key that exists in any payload.
|
|
509
|
+
*/
|
|
510
|
+
type AllPropertiesOfUnion<T> = { [K in KeysOfUnion<T>]: ValueOfKey<T, K> };
|
|
511
|
+
/**
|
|
512
|
+
* Union of all filterable payload properties from a SubjectRecord.
|
|
513
|
+
*
|
|
514
|
+
* Collects ALL keys from ANY payload, allowing filtering by any field.
|
|
515
|
+
* Events without a filtered key simply won't match.
|
|
516
|
+
* @example
|
|
517
|
+
* ```typescript
|
|
518
|
+
* // Given subjects with payloads:
|
|
519
|
+
* // - 'event': { agentId: string, foo: number }
|
|
520
|
+
* // - 'request': { sessionId: string }
|
|
521
|
+
*
|
|
522
|
+
* // FilterablePayloadUnion = { agentId: string, foo: number, sessionId: string }
|
|
523
|
+
*
|
|
524
|
+
* // Filter can use any key from any payload
|
|
525
|
+
* bus.withFilter({ agentId: 'x' }); // ✅ matches events with agentId
|
|
526
|
+
* bus.withFilter({ sessionId: 'y' }); // ✅ matches requests with sessionId
|
|
527
|
+
* ```
|
|
528
|
+
*/
|
|
529
|
+
type FilterablePayloadIntersection<Subjects extends SubjectRecord> = Simplify<AllPropertiesOfUnion<FilterablePayloadsUnion<Subjects>>>;
|
|
530
|
+
//#endregion
|
|
531
|
+
//#region core/makaio-core/src/types/wildcards.d.ts
|
|
532
|
+
type WildcardSubject = '*';
|
|
533
|
+
type WildcardSubjectDefinition<Namespace extends string = string> = SubjectDefinition<Record<'*', MessagePayload>, WildcardSubject, Namespace>;
|
|
534
|
+
//#endregion
|
|
535
|
+
//#region core/makaio-core/src/types/handler-types.d.ts
|
|
536
|
+
type EventHandler<T> = (context: EventContext<T>) => void | Promise<void>;
|
|
537
|
+
type RequestHandler<Payload, Response> = (context: RequestContext<Payload, Response>) => void | Promise<void>;
|
|
538
|
+
/**
|
|
539
|
+
* Context provided to __onAny handlers for debugging/testing.
|
|
540
|
+
* Captures all message metadata regardless of type (event/request/broadcast).
|
|
541
|
+
*/
|
|
542
|
+
interface AnyMessageContext {
|
|
543
|
+
type: 'event' | 'request' | 'broadcast';
|
|
544
|
+
subject: string;
|
|
545
|
+
namespace: string;
|
|
546
|
+
payload: unknown;
|
|
547
|
+
messageId: string;
|
|
548
|
+
correlationId?: string;
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* Handler for __onAny - receives all messages (events and requests) across all namespaces.
|
|
552
|
+
* Used for debugging and testing only.
|
|
553
|
+
*/
|
|
554
|
+
type AnyHandler = (context: AnyMessageContext) => void | Promise<void>;
|
|
555
|
+
/**
|
|
556
|
+
* Special handler for wildcards that match both events and requests.
|
|
557
|
+
* @public
|
|
558
|
+
*/
|
|
559
|
+
type WildcardUnifiedHandler = (context: WildcardContext<unknown, unknown>) => void | Promise<void>;
|
|
560
|
+
/**
|
|
561
|
+
* Resolve the appropriate handler type for a subject pattern (exact or wildcard).
|
|
562
|
+
*
|
|
563
|
+
* Handles all subscription patterns:
|
|
564
|
+
* - Event wildcards (`adapter.*`) → `(payload: unknown) => void | Promise<void>`
|
|
565
|
+
* - Request wildcards (`adapter.*`) → `(context: RequestContext<unknown, unknown>) => void | Promise<void>`
|
|
566
|
+
* - Exact request subjects → `RequestHandler<TPayload, TReturnValue>`
|
|
567
|
+
* - Exact event subjects → `EventHandler<TPayload>`
|
|
568
|
+
*
|
|
569
|
+
* This is the primary type used by the `on()` method to resolve handler signatures.
|
|
570
|
+
* @example
|
|
571
|
+
* ```typescript
|
|
572
|
+
* // Event wildcard - unknown payload
|
|
573
|
+
* type Handler1 = HandlerForPattern<'adapter.*'>;
|
|
574
|
+
* // (payload: unknown) => void | Promise<void>
|
|
575
|
+
*
|
|
576
|
+
* // Exact event subject - typed payload
|
|
577
|
+
* type Handler2 = HandlerForPattern<'adapter.log'>;
|
|
578
|
+
* // EventHandler<{ message: string, level: string }>
|
|
579
|
+
*
|
|
580
|
+
* // Request wildcard - unknown context
|
|
581
|
+
* type Handler3 = HandlerForPattern<'adapter.*'>;
|
|
582
|
+
* // (context: RequestContext<unknown, unknown>) => void | Promise<void>
|
|
583
|
+
*
|
|
584
|
+
* // Exact request subject - typed context
|
|
585
|
+
* type Handler4 = HandlerForPattern<'adapter.getCapabilities'>;
|
|
586
|
+
* // RequestHandler<{ adapterName: string }, { capabilities: string[] }>
|
|
587
|
+
* ```
|
|
588
|
+
*/
|
|
589
|
+
/**
|
|
590
|
+
* Resolve the handler type for a SubjectDefinition.
|
|
591
|
+
*
|
|
592
|
+
* Uses indexed access (`T['$meta']['payload']`) instead of nested `extends` with `infer`
|
|
593
|
+
* to ensure proper type resolution when T is a generic type parameter.
|
|
594
|
+
*/
|
|
595
|
+
type HandlerForSubjectDefinition<T extends SubjectDefinition> = T['subject'] extends WildcardSubject ? WildcardUnifiedHandler : T['$meta']['payload'] extends RequestMessagePayload<infer Request, infer Response> ? RequestHandler<Request, Response> : T['$meta']['payload'] extends EventMessagePayload<infer Payload> ? EventHandler<Payload> : never;
|
|
596
|
+
/**
|
|
597
|
+
* Extract context type for once() promise return value.
|
|
598
|
+
*
|
|
599
|
+
* Uses the same pattern as HandlerForSubjectDefinition for consistency.
|
|
600
|
+
*/
|
|
601
|
+
type ContextForSubjectDefinition<T extends SubjectDefinition> = T['subject'] extends WildcardSubject ? WildcardContext<unknown, unknown> : T['$meta']['payload'] extends RequestMessagePayload<infer Request, infer Response> ? RequestContext<Request, Response> : T['$meta']['payload'] extends EventMessagePayload<infer Payload> ? EventContext<Payload> : never;
|
|
602
|
+
//#endregion
|
|
603
|
+
//#region core/makaio-core/src/types/result.d.ts
|
|
604
|
+
/**
|
|
605
|
+
* Result types for optional request handling.
|
|
606
|
+
*
|
|
607
|
+
* Used by requestOptional to distinguish between "handler returned data"
|
|
608
|
+
* and "no handler was registered".
|
|
609
|
+
*/
|
|
610
|
+
/**
|
|
611
|
+
* Discriminated union for optional request results.
|
|
612
|
+
*
|
|
613
|
+
* - `handled: true` - A handler was found and returned data
|
|
614
|
+
* - `handled: false` - No handler was registered for the subject
|
|
615
|
+
* @example
|
|
616
|
+
* ```typescript
|
|
617
|
+
* const result = await bus.requestOptional(Subjects.getData, { id: '123' });
|
|
618
|
+
* if (result.handled) {
|
|
619
|
+
* console.debug('Got data:', result.data);
|
|
620
|
+
* } else {
|
|
621
|
+
* console.debug('No handler registered for getData');
|
|
622
|
+
* }
|
|
623
|
+
* ```
|
|
624
|
+
*/
|
|
625
|
+
type OptionalResult<T> = {
|
|
626
|
+
handled: true;
|
|
627
|
+
data: T;
|
|
628
|
+
} | {
|
|
629
|
+
handled: false;
|
|
630
|
+
};
|
|
631
|
+
//#endregion
|
|
632
|
+
//#region core/makaio-core/src/subject-helpers/nest-subject-definitions.d.ts
|
|
633
|
+
/**
|
|
634
|
+
* Recursively nests a flat record of dotted keys into a hierarchical object type.
|
|
635
|
+
*
|
|
636
|
+
* ```
|
|
637
|
+
* { 'assistant.text': SubjectDef, 'agent.tool.started': SubjectDef }
|
|
638
|
+
* → { assistant: { text: SubjectDef }, agent: { tool: { started: SubjectDef } } }
|
|
639
|
+
* ```
|
|
640
|
+
*
|
|
641
|
+
* Used to expose registered subjects as a nested accessor tree (e.g.
|
|
642
|
+
* `BootSubjects.service.ready`) without requiring callers to deal with
|
|
643
|
+
* flat dotted-key strings at the type level.
|
|
644
|
+
*/
|
|
645
|
+
type NestedSubjectDefinitions<T extends Record<string, unknown> = Record<string, SubjectDefinition>> = { [K in ExtractPrefixes<keyof T & string>]: NestByPrefix<T, K> };
|
|
646
|
+
type ExtractPrefixes<Keys extends string> = Keys extends `${infer Prefix}.${string}` ? Prefix : Keys;
|
|
647
|
+
type StripPrefixMap<T, Prefix extends string> = { [K in keyof T as K extends `${Prefix}.${infer Rest}` ? Rest : never]: T[K] };
|
|
648
|
+
type NestByPrefix<T extends Record<string, unknown>, Prefix extends string> = Prefix extends keyof T ? T[Prefix] : NestedSubjectDefinitions<StripPrefixMap<T, Prefix>>;
|
|
649
|
+
/**
|
|
650
|
+
* Maps a flat schema record to a flat subject-definition record, attaching the
|
|
651
|
+
* correct `$meta` (namespace, isRequest, local, channel) and `subject` key for
|
|
652
|
+
* each entry.
|
|
653
|
+
*
|
|
654
|
+
* Intermediate type used by {@link nestSubjectDefinitions} before nesting.
|
|
655
|
+
* @typeParam Domain - Namespace domain string (e.g. `'boot'`)
|
|
656
|
+
* @typeParam Schemas - Flat record of raw Zod schemas keyed by dotted subject names
|
|
657
|
+
*/
|
|
658
|
+
type FlatSubjectDefinitions<Domain extends string, Schemas extends Record<string, SubjectSchema>> = { [K in keyof Schemas & string]: {
|
|
659
|
+
$meta: InferSubjectMeta<Schemas[K], Domain>;
|
|
660
|
+
subject: K;
|
|
661
|
+
} };
|
|
662
|
+
/**
|
|
663
|
+
* Fully-nested subject accessor tree returned by `registerNamespace`.
|
|
664
|
+
*
|
|
665
|
+
* Combines the {@link NestedSubjectDefinitions} hierarchy with a `$all`
|
|
666
|
+
* wildcard that matches every subject in the namespace. Consumers use this
|
|
667
|
+
* type to write `SomeNamespace.subjects.foo.bar` instead of raw strings.
|
|
668
|
+
* @typeParam RecordOfSubjectDefinitions - Flat record of subject definitions
|
|
669
|
+
* @typeParam Domain - Namespace domain string used for `$all` wildcard typing
|
|
670
|
+
*/
|
|
671
|
+
type BusSubjects<RecordOfSubjectDefinitions extends Record<string, unknown> = Record<string, SubjectDefinition>, Domain extends string = string> = NestedSubjectDefinitions<RecordOfSubjectDefinitions> & {
|
|
672
|
+
$all: WildcardSubjectDefinition<Domain>;
|
|
673
|
+
};
|
|
674
|
+
/**
|
|
675
|
+
* Gets the fully qualified subject name in namespace.subject format.
|
|
676
|
+
* @param subject - The subject definition to format
|
|
677
|
+
* @returns The full subject string in the format "namespace.subject"
|
|
678
|
+
*/
|
|
679
|
+
declare function getFullSubjectForSubjectDefinition(subject: SubjectDefinition): string;
|
|
680
|
+
//#endregion
|
|
681
|
+
//#region core/makaio-core/src/subject-helpers/is-request-schema.d.ts
|
|
682
|
+
/**
|
|
683
|
+
* Type guard to check if a schema is a request schema.
|
|
684
|
+
* @param schema - The schema to check
|
|
685
|
+
* @returns True if the schema is a RequestSchema, false otherwise
|
|
686
|
+
*/
|
|
687
|
+
declare function isRequestSchema(schema: SubjectSchema): schema is RequestSchema;
|
|
688
|
+
//#endregion
|
|
689
|
+
//#region core/makaio-core/src/subject-helpers/is-local-schema.d.ts
|
|
690
|
+
/**
|
|
691
|
+
* Create a local-only subject schema wrapper.
|
|
692
|
+
*
|
|
693
|
+
* Local subjects are never sent to transports (SharedWorker, WebSocket, etc.).
|
|
694
|
+
* Use this for subjects whose payloads contain non-serializable data like
|
|
695
|
+
* React components or functions.
|
|
696
|
+
* @param schema - The event or request schema to mark as local
|
|
697
|
+
* @returns A LocalSubjectSchema wrapper
|
|
698
|
+
* @example
|
|
699
|
+
* ```typescript
|
|
700
|
+
* import { localSubject } from '@makaio/framework/core';
|
|
701
|
+
*
|
|
702
|
+
* const WidgetSchemas = {
|
|
703
|
+
* // Local event - contains React component, can't be serialized
|
|
704
|
+
* register: localSubject(widgetDefinitionSchema),
|
|
705
|
+
*
|
|
706
|
+
* // Local request - response contains functions
|
|
707
|
+
* getRenderer: localSubject({
|
|
708
|
+
* request: z.object({ widgetId: z.string() }),
|
|
709
|
+
* response: z.object({ render: z.function() }),
|
|
710
|
+
* }),
|
|
711
|
+
* };
|
|
712
|
+
* ```
|
|
713
|
+
*/
|
|
714
|
+
declare function localSubject<T extends EventSchema | RequestSchema>(schema: T): LocalSubjectSchema<T>;
|
|
715
|
+
//#endregion
|
|
716
|
+
//#region core/makaio-core/src/subject-helpers/is-collector-only-schema.d.ts
|
|
717
|
+
/**
|
|
718
|
+
* Create a collector-only event schema wrapper.
|
|
719
|
+
*
|
|
720
|
+
* Collector-only events are transport-ingestable but not transport-relayable:
|
|
721
|
+
* a collector bus can receive them from an upstream peer and handle them
|
|
722
|
+
* locally without pushing them laterally to unrelated peers.
|
|
723
|
+
* @param schema - The event schema to mark as collector-only.
|
|
724
|
+
* @returns A CollectorOnlySubjectSchema wrapper.
|
|
725
|
+
*/
|
|
726
|
+
declare function collectorOnlySubject<T extends EventSchema>(schema: T): CollectorOnlySubjectSchema<T>;
|
|
727
|
+
//#endregion
|
|
728
|
+
//#region core/makaio-core/src/subject-helpers/is-channel-schema.d.ts
|
|
729
|
+
/**
|
|
730
|
+
* Create a channel-only subject schema wrapper.
|
|
731
|
+
*
|
|
732
|
+
* Channel subjects are rejected by public bus methods and are only
|
|
733
|
+
* routable through the DirectChannel encrypted point-to-point transport.
|
|
734
|
+
* Use this for subjects that must never travel over the public bus.
|
|
735
|
+
* @param schema - The event or request schema to mark as channel-only
|
|
736
|
+
* @returns A ChannelSubjectSchema wrapper
|
|
737
|
+
* @example
|
|
738
|
+
* ```typescript
|
|
739
|
+
* import { channelSubject } from '@makaio/framework/core';
|
|
740
|
+
*
|
|
741
|
+
* const DirectSchemas = {
|
|
742
|
+
* // Channel event - encrypted, point-to-point only
|
|
743
|
+
* message: channelSubject(z.object({ text: z.string() })),
|
|
744
|
+
*
|
|
745
|
+
* // Channel request - encrypted request-response pair
|
|
746
|
+
* ping: channelSubject({
|
|
747
|
+
* request: z.object({ ts: z.number() }),
|
|
748
|
+
* response: z.object({ ts: z.number() }),
|
|
749
|
+
* }),
|
|
750
|
+
* };
|
|
751
|
+
* ```
|
|
752
|
+
*/
|
|
753
|
+
declare function channelSubject<T extends EventSchema | RequestSchema>(schema: T): ChannelSubjectSchema<T>;
|
|
754
|
+
//#endregion
|
|
755
|
+
//#region core/makaio-core/src/subject-helpers/default-transports-schema.d.ts
|
|
756
|
+
/**
|
|
757
|
+
* Create a subject schema wrapper with a subject-level default transport policy.
|
|
758
|
+
*
|
|
759
|
+
* Use this when one subject should override its namespace's default transport
|
|
760
|
+
* routing while still remaining remotely invokable when a caller explicitly
|
|
761
|
+
* targets a transport.
|
|
762
|
+
* @param schema - The event or request schema to wrap
|
|
763
|
+
* @param value - Default transport routing policy for this subject
|
|
764
|
+
* @returns A DefaultTransportsSubjectSchema wrapper
|
|
765
|
+
* @example
|
|
766
|
+
* ```typescript
|
|
767
|
+
* import { defaultTransports } from '@makaio/framework/core';
|
|
768
|
+
*
|
|
769
|
+
* const Schemas = {
|
|
770
|
+
* internalEvent: defaultTransports(z.object({ id: z.string() }), 'local-only'),
|
|
771
|
+
* };
|
|
772
|
+
* ```
|
|
773
|
+
*/
|
|
774
|
+
declare function defaultTransports<T extends EventSchema | RequestSchema, Default extends TransportRoutingDefault>(schema: T, value: Default): DefaultTransportsSubjectSchema<T, Default>;
|
|
775
|
+
//#endregion
|
|
776
|
+
//#region core/makaio-core/src/bus-namespace-definition.d.ts
|
|
777
|
+
/**
|
|
778
|
+
* Report passed to the {@link NamespaceRegistrationOptions} `onSchemaViolation` callback
|
|
779
|
+
* when lenient validation detects a schema mismatch.
|
|
780
|
+
*
|
|
781
|
+
* Canonical owner: `@makaio/core`. `@makaio/bus-core` imports this type from core.
|
|
782
|
+
*/
|
|
783
|
+
interface SchemaViolationReport {
|
|
784
|
+
/** Fully-qualified subject key (e.g., `"adapter:claude-code.sdk.event"`) */
|
|
785
|
+
subject: string;
|
|
786
|
+
/** Raw payload that failed validation */
|
|
787
|
+
payload: unknown;
|
|
788
|
+
/** Individual Zod issues from the failed parse */
|
|
789
|
+
issues: unknown[];
|
|
790
|
+
}
|
|
791
|
+
/**
|
|
792
|
+
* Options controlling runtime schema validation for a registered bus namespace.
|
|
793
|
+
*
|
|
794
|
+
* - `strict` (default) — throw `ValidationError` on schema mismatch
|
|
795
|
+
* - `lenient` — invoke `onSchemaViolation` callback, then deliver the event anyway
|
|
796
|
+
* - `skip` — no validation at all (for cross-Zod-version scenarios, e.g., SDK bundles Zod v3)
|
|
797
|
+
*
|
|
798
|
+
* Canonical owner: `@makaio/core`. `@makaio/bus-core` imports this type from core,
|
|
799
|
+
* not the other way around. Single source of truth — no mirroring.
|
|
800
|
+
*/
|
|
801
|
+
type NamespaceRegistrationOptions = {
|
|
802
|
+
busValidationMode?: 'strict';
|
|
803
|
+
} | {
|
|
804
|
+
busValidationMode: 'lenient';
|
|
805
|
+
onSchemaViolation: (report: SchemaViolationReport) => void;
|
|
806
|
+
} | {
|
|
807
|
+
busValidationMode: 'skip';
|
|
808
|
+
};
|
|
809
|
+
/**
|
|
810
|
+
* A declarative bus namespace definition.
|
|
811
|
+
*
|
|
812
|
+
* Created by {@link createBusNamespace}. Carries typed subject tokens for
|
|
813
|
+
* immediate use in bus operations, plus the original schemas for deferred
|
|
814
|
+
* registration at boot time via `MakaioBus.registerNamespace()`.
|
|
815
|
+
*
|
|
816
|
+
* Does not include `scopedBus()` — that method requires a bus instance and
|
|
817
|
+
* is available on the `BusNamespace` object returned by `registerNamespace()`.
|
|
818
|
+
* @typeParam Domain - Namespace domain string (e.g. `'adapter'`, `'session'`)
|
|
819
|
+
* @typeParam Schemas - Schema record mapping subject keys to Zod schemas
|
|
820
|
+
*/
|
|
821
|
+
interface BusNamespaceDefinition<Domain extends string = string, Schemas extends Record<string, SubjectSchema> = Record<string, SubjectSchema>> {
|
|
822
|
+
/** Namespace domain string (e.g., `'adapter'`, `'session'`) */
|
|
823
|
+
readonly name: Domain;
|
|
824
|
+
/**
|
|
825
|
+
* Typed subject tokens for bus operations — no registration needed to use
|
|
826
|
+
* these for `bus.on()`, `bus.emit()`, or `bus.request()`.
|
|
827
|
+
*/
|
|
828
|
+
readonly subjects: BusSubjects<FlatSubjectDefinitions<Domain, Schemas>, Domain>;
|
|
829
|
+
/** Original Zod schemas — carried for deferred registration */
|
|
830
|
+
readonly schemas: Schemas;
|
|
831
|
+
/** Registration options (validation mode, violation callback) */
|
|
832
|
+
readonly options?: NamespaceRegistrationOptions;
|
|
833
|
+
/**
|
|
834
|
+
* Default transport routing for all subjects in this namespace when the
|
|
835
|
+
* caller does not provide an explicit `transports` option.
|
|
836
|
+
*
|
|
837
|
+
* Subject-level `defaultTransports` (set via `SubjectDefinitionMeta`) takes
|
|
838
|
+
* precedence over this namespace-level default when both are set.
|
|
839
|
+
*
|
|
840
|
+
* - `'all'` (default when omitted) — send to all registered transports.
|
|
841
|
+
* - `'local-only'` — suppress outbound transport fan-out by default. Callers
|
|
842
|
+
* can still force transport delivery by passing an explicit `transports`
|
|
843
|
+
* option. Weaker than `localSubject()`: subjects remain reachable remotely.
|
|
844
|
+
*/
|
|
845
|
+
readonly defaultTransports?: TransportRoutingDefault;
|
|
846
|
+
/**
|
|
847
|
+
* Phantom field for type inference of filterable payload shape.
|
|
848
|
+
*
|
|
849
|
+
* Never set at runtime. Exists solely so TypeScript can infer the
|
|
850
|
+
* `FilterPayload` type parameter from the schema record without an
|
|
851
|
+
* explicit annotation at every callsite.
|
|
852
|
+
* @internal
|
|
853
|
+
*/
|
|
854
|
+
readonly __filterPayload?: FilterablePayloadIntersection<SubjectRecordFromSchemaRecord<Schemas>>;
|
|
855
|
+
}
|
|
856
|
+
/**
|
|
857
|
+
* Namespace definition shape required for runtime registration.
|
|
858
|
+
*
|
|
859
|
+
* Structurally derived from {@link BusNamespaceDefinition} with the typed
|
|
860
|
+
* subject tree erased to `unknown`. Composition-root catalogs and extension
|
|
861
|
+
* manifests only need the namespace name, schemas, options, and the runtime
|
|
862
|
+
* subject tokens; keeping this structural type separate lets those catalogs
|
|
863
|
+
* contain heterogeneous namespace definitions without widening every subject
|
|
864
|
+
* tree to an unsafe index signature.
|
|
865
|
+
*/
|
|
866
|
+
type RegistrableBusNamespaceDefinition = Omit<BusNamespaceDefinition, 'subjects' | '__filterPayload'> & {
|
|
867
|
+
/** Runtime subject token tree created by `createBusNamespace`. */readonly subjects: unknown;
|
|
868
|
+
};
|
|
869
|
+
//#endregion
|
|
870
|
+
//#region core/makaio-core/src/errors/index.d.ts
|
|
871
|
+
/**
|
|
872
|
+
* Base error class for all Makaio-related errors.
|
|
873
|
+
*/
|
|
874
|
+
declare class MakaioError extends Error {
|
|
875
|
+
readonly subject?: string | undefined;
|
|
876
|
+
constructor(message: string, subject?: string | undefined);
|
|
877
|
+
}
|
|
878
|
+
//#endregion
|
|
879
|
+
//#region core/bus-core/src/extend-subject.d.ts
|
|
880
|
+
/**
|
|
881
|
+
* Additional fields to add to a request subject's request and/or response schemas.
|
|
882
|
+
* Omit either key to leave that side unchanged.
|
|
883
|
+
*/
|
|
884
|
+
interface RequestSubjectExtension {
|
|
885
|
+
request?: Record<string, z.ZodType>;
|
|
886
|
+
response?: Record<string, z.ZodType>;
|
|
887
|
+
}
|
|
888
|
+
/**
|
|
889
|
+
* Additional fields to add to an event subject's payload schema.
|
|
890
|
+
*/
|
|
891
|
+
type EventSubjectExtension = Record<string, z.ZodType>;
|
|
892
|
+
/**
|
|
893
|
+
* Infers the correct extension shape based on whether the subject is a request or event.
|
|
894
|
+
*/
|
|
895
|
+
type SubjectExtension<SD extends SubjectDefinition> = SD['$meta']['isRequest'] extends true ? RequestSubjectExtension : EventSubjectExtension;
|
|
896
|
+
type ExtendWithInput<Original, Ext extends Record<string, z.ZodType>> = Omit<Original, keyof Ext> & { [K in keyof Ext as undefined extends z.input<Ext[K]> ? never : K]: z.input<Ext[K]> } & { [K in keyof Ext as undefined extends z.input<Ext[K]> ? K : never]?: z.input<Ext[K]> };
|
|
897
|
+
type ExtendWithInfer<Original, Ext extends Record<string, z.ZodType>> = Omit<Original, keyof Ext> & { [K in keyof Ext as undefined extends z.infer<Ext[K]> ? never : K]: z.infer<Ext[K]> } & { [K in keyof Ext as undefined extends z.infer<Ext[K]> ? K : never]?: z.infer<Ext[K]> };
|
|
898
|
+
type ExtendedRequestPayload<OrigPayload, Ext extends RequestSubjectExtension> = {
|
|
899
|
+
request: Ext['request'] extends Record<string, z.ZodType> ? ExtendWithInput<OrigPayload extends {
|
|
900
|
+
request: infer R;
|
|
901
|
+
} ? R : never, Ext['request']> : OrigPayload extends {
|
|
902
|
+
request: infer R;
|
|
903
|
+
} ? R : never;
|
|
904
|
+
response: Ext['response'] extends Record<string, z.ZodType> ? ExtendWithInfer<OrigPayload extends {
|
|
905
|
+
response: infer R;
|
|
906
|
+
} ? R : never, Ext['response']> : OrigPayload extends {
|
|
907
|
+
response: infer R;
|
|
908
|
+
} ? R : never;
|
|
909
|
+
};
|
|
910
|
+
/**
|
|
911
|
+
* A SubjectDefinition with overridden `$meta.payload` — preserves all other metadata.
|
|
912
|
+
*/
|
|
913
|
+
type ExtendedSubjectDefinition<SD extends SubjectDefinition, Ext extends SubjectExtension<SD>> = {
|
|
914
|
+
subject: SD['subject'];
|
|
915
|
+
$meta: {
|
|
916
|
+
namespace: SD['$meta']['namespace'];
|
|
917
|
+
isRequest: SD['$meta']['isRequest'];
|
|
918
|
+
local: SD['$meta']['local'];
|
|
919
|
+
channel: SD['$meta']['channel'];
|
|
920
|
+
payload: SD['$meta']['isRequest'] extends true ? Ext extends RequestSubjectExtension ? ExtendedRequestPayload<SD['$meta']['payload'], Ext> : SD['$meta']['payload'] : Ext extends Record<string, z.ZodType> ? ExtendWithInfer<SD['$meta']['payload'], Ext> : SD['$meta']['payload'];
|
|
921
|
+
};
|
|
922
|
+
};
|
|
923
|
+
/**
|
|
924
|
+
* Pure declaration of a subject extension.
|
|
925
|
+
*
|
|
926
|
+
* This keeps TypeScript's widened subject inference available to importers
|
|
927
|
+
* without mutating the runtime namespace registry at module import time.
|
|
928
|
+
* The owning package must call {@link DefinedSubjectExtension.register} during
|
|
929
|
+
* its activation lifecycle, after the base namespace has been registered.
|
|
930
|
+
*/
|
|
931
|
+
interface DefinedSubjectExtension<SD extends SubjectDefinition, Ext extends SubjectExtension<SD>> {
|
|
932
|
+
/** Subject definition with widened payload inference. */
|
|
933
|
+
readonly subject: ExtendedSubjectDefinition<SD, Ext>;
|
|
934
|
+
/**
|
|
935
|
+
* Register the extension against the runtime bus namespace registry.
|
|
936
|
+
* @param bus - Bus instance whose namespace registry receives the extension.
|
|
937
|
+
* @returns The same subject definition with widened payload inference.
|
|
938
|
+
*/
|
|
939
|
+
register(bus: Pick<IMakaioBus, 'extendSubject'>): ExtendedSubjectDefinition<SD, Ext>;
|
|
940
|
+
}
|
|
941
|
+
/**
|
|
942
|
+
* Declare a subject extension without registering it immediately.
|
|
943
|
+
*
|
|
944
|
+
* Use this for product or extension modules that export typed subjects but
|
|
945
|
+
* cannot safely mutate the namespace registry at import time. Registration
|
|
946
|
+
* remains explicit via the returned `register()` method.
|
|
947
|
+
* @param subject - Base subject definition to widen.
|
|
948
|
+
* @param extension - Additional Zod fields for the subject payload.
|
|
949
|
+
* @returns A declaration containing the widened subject and activation-time registration hook.
|
|
950
|
+
*/
|
|
951
|
+
declare function defineSubjectExtension<SD extends SubjectDefinition, Ext extends SubjectExtension<SD>>(subject: SD, extension: Ext): DefinedSubjectExtension<SD, Ext>;
|
|
952
|
+
/**
|
|
953
|
+
* Extend a registered bus subject's schema with additional fields.
|
|
954
|
+
*
|
|
955
|
+
* Called on the bus context directly. Adds new fields to the Zod schema for
|
|
956
|
+
* dev-mode validation and widens the TypeScript payload type. Successive calls
|
|
957
|
+
* accumulate fields — two packages can independently extend the same subject
|
|
958
|
+
* with different field names. If two extensions add the same field name,
|
|
959
|
+
* the later call's definition wins (Zod `.extend()` semantics).
|
|
960
|
+
*
|
|
961
|
+
* The returned value is the same runtime object — only the TypeScript type widens.
|
|
962
|
+
* @param context - Bus context containing the namespace registry
|
|
963
|
+
* @param subject - The SubjectDefinition to extend
|
|
964
|
+
* @param extensions - Additional Zod fields to add
|
|
965
|
+
* @returns The same SubjectDefinition with wider TypeScript types
|
|
966
|
+
*/
|
|
967
|
+
declare function extendSubjectImpl<SD extends SubjectDefinition, Ext extends SubjectExtension<SD>>(context: MakaioBusContext, subject: SD, extensions: Ext): ExtendedSubjectDefinition<SD, Ext>;
|
|
968
|
+
//#endregion
|
|
969
|
+
//#region core/bus-core/src/types/interceptor.d.ts
|
|
970
|
+
/**
|
|
971
|
+
* Context provided to interceptor handlers.
|
|
972
|
+
*
|
|
973
|
+
* Interceptors run BEFORE event handlers (not request handlers), allowing:
|
|
974
|
+
* - Payload transformation via `replacePayload()`
|
|
975
|
+
* - Event blocking via `stopPropagation()`
|
|
976
|
+
* - Sequential execution in priority order (highest first)
|
|
977
|
+
*
|
|
978
|
+
* Note: Interceptors only work with event subjects. For request/response
|
|
979
|
+
* flow interception, use middleware instead.
|
|
980
|
+
*/
|
|
981
|
+
interface InterceptorContext<P, S = string> {
|
|
982
|
+
readonly subject: S;
|
|
983
|
+
readonly payload: P;
|
|
984
|
+
readonly messageId: string;
|
|
985
|
+
readonly correlationId: string | undefined;
|
|
986
|
+
/**
|
|
987
|
+
* Stop propagation of this message.
|
|
988
|
+
* Subsequent interceptors and all handlers will NOT be called.
|
|
989
|
+
*/
|
|
990
|
+
stopPropagation(): void;
|
|
991
|
+
/**
|
|
992
|
+
* Replace the payload with a new value.
|
|
993
|
+
* Subsequent interceptors and handlers will receive the new payload.
|
|
994
|
+
*/
|
|
995
|
+
replacePayload(newPayload: P): void;
|
|
996
|
+
/**
|
|
997
|
+
* Explicitly continue to the next interceptor (optional).
|
|
998
|
+
* Continuation is implicit if neither stopPropagation() nor next() is called.
|
|
999
|
+
*/
|
|
1000
|
+
next(): void;
|
|
1001
|
+
}
|
|
1002
|
+
/**
|
|
1003
|
+
* Handler function for interceptors.
|
|
1004
|
+
* Receives an InterceptorContext and may optionally return a Promise.
|
|
1005
|
+
*/
|
|
1006
|
+
type InterceptorHandler<P> = (ctx: InterceptorContext<P>) => void | Promise<void>;
|
|
1007
|
+
/**
|
|
1008
|
+
* Options for registering an interceptor.
|
|
1009
|
+
*/
|
|
1010
|
+
interface InterceptOptions {
|
|
1011
|
+
/**
|
|
1012
|
+
* Priority for interceptor execution order.
|
|
1013
|
+
* Higher values run first. Default: 0
|
|
1014
|
+
*/
|
|
1015
|
+
priority?: number;
|
|
1016
|
+
/**
|
|
1017
|
+
* Optional filter to conditionally invoke this interceptor.
|
|
1018
|
+
* Uses the same filter syntax as on() handlers.
|
|
1019
|
+
*/
|
|
1020
|
+
filter?: PayloadFilter;
|
|
1021
|
+
}
|
|
1022
|
+
/**
|
|
1023
|
+
* Entry stored in the interceptor registry.
|
|
1024
|
+
* Similar to HandlerEntry but specific to interceptors.
|
|
1025
|
+
*/
|
|
1026
|
+
interface InterceptorEntry<H> {
|
|
1027
|
+
handler: H;
|
|
1028
|
+
priority: number;
|
|
1029
|
+
}
|
|
1030
|
+
//#endregion
|
|
1031
|
+
//#region core/bus-core/src/methods/once.d.ts
|
|
1032
|
+
/**
|
|
1033
|
+
* Options for the Promise-based once() method.
|
|
1034
|
+
*/
|
|
1035
|
+
type OnceOptions<T extends SubjectDefinition> = {
|
|
1036
|
+
/** Timeout in milliseconds - rejects promise if event not received within this time */timeoutMs?: number;
|
|
1037
|
+
/**
|
|
1038
|
+
* Declarative payload filter for smart-routing.
|
|
1039
|
+
*
|
|
1040
|
+
* Applied both locally and can be sent to transports for server-side filtering.
|
|
1041
|
+
* Replaces the old function-based filter for serialization support.
|
|
1042
|
+
* @example
|
|
1043
|
+
* ```typescript
|
|
1044
|
+
* await bus.once(Subjects.message, {
|
|
1045
|
+
* filter: {
|
|
1046
|
+
* agentId: 'agent-123',
|
|
1047
|
+
* 'raw.msg.type': 'session_configured',
|
|
1048
|
+
* }
|
|
1049
|
+
* });
|
|
1050
|
+
* ```
|
|
1051
|
+
*/
|
|
1052
|
+
filter?: TypedPayloadFilter<T['$meta']['payload']>; /** AbortSignal to cancel waiting */
|
|
1053
|
+
signal?: AbortSignal;
|
|
1054
|
+
};
|
|
1055
|
+
/**
|
|
1056
|
+
* Error thrown when `once()` rejects because its `AbortSignal` was
|
|
1057
|
+
* triggered. Consumers that intentionally abort a pending listener can use
|
|
1058
|
+
* `instanceof OnceAbortError` to distinguish the expected rejection from real
|
|
1059
|
+
* failures.
|
|
1060
|
+
*/
|
|
1061
|
+
declare class OnceAbortError extends Error {
|
|
1062
|
+
constructor();
|
|
1063
|
+
}
|
|
1064
|
+
//#endregion
|
|
1065
|
+
//#region core/bus-core/src/scoped-bus-base.d.ts
|
|
1066
|
+
/**
|
|
1067
|
+
* Minimal shared surface common to {@link ScopedBus} and {@link IFilteredBus}.
|
|
1068
|
+
* @typeParam Namespace - The namespace domain string (e.g. `'adapter:codex-mcp'`)
|
|
1069
|
+
*/
|
|
1070
|
+
interface IScopedBusBase<Namespace extends string> {
|
|
1071
|
+
readonly namespace: Namespace;
|
|
1072
|
+
/**
|
|
1073
|
+
* Register an event or request handler.
|
|
1074
|
+
* @param subject - Subject definition to listen on
|
|
1075
|
+
* @param handler - Handler function to invoke
|
|
1076
|
+
* @param options - Optional subscription options (filter, priority, etc.)
|
|
1077
|
+
* @returns Unsubscribe function
|
|
1078
|
+
*/
|
|
1079
|
+
on<Subject extends ScopedSubjectDefinition<Namespace>>(subject: Subject, handler: HandlerForSubjectDefinition<Subject>, options?: OnOptions): () => void;
|
|
1080
|
+
/**
|
|
1081
|
+
* Register an interceptor that runs BEFORE handlers.
|
|
1082
|
+
* @param subject - Subject definition to intercept
|
|
1083
|
+
* @param handler - Interceptor handler function
|
|
1084
|
+
* @param options - Optional intercept options (filter, priority, etc.)
|
|
1085
|
+
* @returns Unsubscribe function
|
|
1086
|
+
*/
|
|
1087
|
+
intercept<Subject extends ScopedSubjectDefinition<Namespace>>(subject: Subject, handler: InterceptorHandler<Subject['$meta']['payload']>, options?: InterceptOptions): () => void;
|
|
1088
|
+
/**
|
|
1089
|
+
* Register a one-time handler (callback version).
|
|
1090
|
+
* @param subject - Subject definition to listen on once
|
|
1091
|
+
* @param handler - Handler function invoked at most once
|
|
1092
|
+
* @returns Unsubscribe function
|
|
1093
|
+
*/
|
|
1094
|
+
once<Subject extends ScopedSubjectDefinition<Namespace>>(subject: Subject, handler: HandlerForSubjectDefinition<Subject>): () => void;
|
|
1095
|
+
/**
|
|
1096
|
+
* Wait for an event (promise version).
|
|
1097
|
+
* @param subject - Subject definition to await
|
|
1098
|
+
* @param options - Optional filter and timeout options
|
|
1099
|
+
* @returns Promise resolving to the event context
|
|
1100
|
+
*/
|
|
1101
|
+
once<Subject extends ScopedSubjectDefinition<Namespace>>(subject: Subject, options?: OnceOptions<Subject>): Promise<ContextForSubjectDefinition<Subject>>;
|
|
1102
|
+
/**
|
|
1103
|
+
* Emit an event.
|
|
1104
|
+
* @param subject - Subject definition to emit on
|
|
1105
|
+
* @param payload - Event payload matching the subject schema
|
|
1106
|
+
* @returns Promise resolving when all handlers have been notified
|
|
1107
|
+
*/
|
|
1108
|
+
emit<Subject extends ScopedSubjectDefinition<Namespace>>(subject: Subject, payload: Subject['$meta']['payload']): Promise<void>;
|
|
1109
|
+
/**
|
|
1110
|
+
* Make a request (throws if no handler is registered).
|
|
1111
|
+
* @param subject - Subject definition for the request
|
|
1112
|
+
* @param payload - Request payload matching the subject schema
|
|
1113
|
+
* @returns Promise resolving to the response payload
|
|
1114
|
+
*/
|
|
1115
|
+
request<Subject extends ScopedSubjectDefinition<Namespace>>(subject: Subject, payload: Subject['$meta']['payload']['request']): Promise<Subject['$meta']['payload']['response']>;
|
|
1116
|
+
/**
|
|
1117
|
+
* Make an optional request (returns `OptionalResult` instead of throwing
|
|
1118
|
+
* when no handler is registered).
|
|
1119
|
+
* @param subject - Subject definition for the request
|
|
1120
|
+
* @param payload - Request payload matching the subject schema
|
|
1121
|
+
* @returns Promise resolving to an `OptionalResult` wrapper
|
|
1122
|
+
*/
|
|
1123
|
+
requestOptional<Subject extends ScopedSubjectDefinition<Namespace>>(subject: Subject, payload: Subject['$meta']['payload']['request']): Promise<OptionalResult<Subject['$meta']['payload']['response']>>;
|
|
1124
|
+
}
|
|
1125
|
+
//#endregion
|
|
1126
|
+
//#region core/bus-core/src/filtered-bus.d.ts
|
|
1127
|
+
/**
|
|
1128
|
+
* Filtered bus that applies a base filter to all subscriptions.
|
|
1129
|
+
*
|
|
1130
|
+
* Created via `ScopedBus.withFilter()` or `FilteredBus.withFilter()`.
|
|
1131
|
+
* @typeParam Namespace - The namespace domain string
|
|
1132
|
+
* @typeParam Subjects - SubjectRecord for payload types (unused, for type consistency)
|
|
1133
|
+
* @typeParam FilterPayload - Pre-computed filter payload type for type-safe withFilter
|
|
1134
|
+
*/
|
|
1135
|
+
interface IFilteredBus<Namespace extends string = string, Subjects = unknown, FilterPayload = unknown> extends IScopedBusBase<Namespace> {
|
|
1136
|
+
/**
|
|
1137
|
+
* Get the current base filter.
|
|
1138
|
+
*/
|
|
1139
|
+
getFilter(): PayloadFilter | undefined;
|
|
1140
|
+
/**
|
|
1141
|
+
* Create a new FilteredBus with additional filter conditions merged in.
|
|
1142
|
+
* Later filters override earlier ones for the same path.
|
|
1143
|
+
*
|
|
1144
|
+
* When FilterPayload is known, filter keys are automatically type-checked.
|
|
1145
|
+
* @param filter - Additional filter conditions to merge
|
|
1146
|
+
* @returns New FilteredBus with merged filter
|
|
1147
|
+
* @example
|
|
1148
|
+
* ```typescript
|
|
1149
|
+
* // Type-safe filtering - keys validated against FilterPayload
|
|
1150
|
+
* const agentBus = bus.withFilter({ agentId: 'agent-123' }); // ✅
|
|
1151
|
+
* const badBus = bus.withFilter({ unknownKey: 'x' }); // ❌ Error
|
|
1152
|
+
*
|
|
1153
|
+
* // Explicit type override
|
|
1154
|
+
* interface CustomPayload { agentId: string; status: string }
|
|
1155
|
+
* const strictBus = bus.withFilter<CustomPayload>({ agentId: 'agent-123' });
|
|
1156
|
+
* ```
|
|
1157
|
+
*/
|
|
1158
|
+
withFilter(filter: TypedPayloadFilter<FilterPayload>): IFilteredBus<Namespace, Subjects, FilterPayload>;
|
|
1159
|
+
}
|
|
1160
|
+
/**
|
|
1161
|
+
* Create a filtered bus instance.
|
|
1162
|
+
* @param context - Bus context
|
|
1163
|
+
* @param namespace - Namespace for validation
|
|
1164
|
+
* @param baseFilter - Base filter to apply to all subscriptions
|
|
1165
|
+
* @returns FilteredBus instance
|
|
1166
|
+
*/
|
|
1167
|
+
declare function createFilteredBus<Namespace extends string, Subjects = unknown, FilterPayload = unknown>(context: MakaioBusContext, namespace: Namespace, baseFilter?: PayloadFilter): IFilteredBus<Namespace, Subjects, FilterPayload>;
|
|
1168
|
+
//#endregion
|
|
1169
|
+
//#region core/bus-core/src/scoped-bus.d.ts
|
|
1170
|
+
/**
|
|
1171
|
+
* Scoped bus with namespace isolation and type-safe filtering.
|
|
1172
|
+
* @typeParam Namespace - The namespace domain string (e.g., 'adapter:codex-mcp')
|
|
1173
|
+
* @typeParam Subjects - SubjectRecord for payload types (used by on/once/emit)
|
|
1174
|
+
* @typeParam FilterPayload - Pre-computed intersection of all filterable payloads.
|
|
1175
|
+
* When provided, withFilter constrains filter keys to this type.
|
|
1176
|
+
*/
|
|
1177
|
+
type ScopedBus<Namespace extends string, Subjects = SubjectRecord, FilterPayload = unknown> = IScopedBusBase<Namespace> & {
|
|
1178
|
+
/**
|
|
1179
|
+
* Create a filtered bus with a base payload filter.
|
|
1180
|
+
*
|
|
1181
|
+
* The filter is automatically applied to all `on()` and `once()` calls.
|
|
1182
|
+
*
|
|
1183
|
+
* When FilterPayload is known (via BusNamespace.scopedBus()), filter keys are
|
|
1184
|
+
* automatically constrained to the intersection of all subject payloads.
|
|
1185
|
+
* @param filter - Base filter to apply to all subscriptions
|
|
1186
|
+
* @returns FilteredBus with the specified filter
|
|
1187
|
+
* @example
|
|
1188
|
+
* ```typescript
|
|
1189
|
+
* // Type-safe filtering - keys auto-inferred from pre-computed FilterPayload
|
|
1190
|
+
* const scopedBus = await CodexMcpNamespace.scopedBus();
|
|
1191
|
+
* scopedBus.withFilter({ agentId: this.agentId }); // ✅ agentId validated
|
|
1192
|
+
* scopedBus.withFilter({ unknownKey: 'x' }); // ❌ Error - unknown key
|
|
1193
|
+
*
|
|
1194
|
+
* // Explicit type override still works
|
|
1195
|
+
* interface CustomPayload { agentId: string; sessionId: string }
|
|
1196
|
+
* scopedBus.withFilter<CustomPayload>({ agentId: 'x' });
|
|
1197
|
+
* ```
|
|
1198
|
+
*/
|
|
1199
|
+
withFilter(filter: TypedPayloadFilter<FilterPayload>): IFilteredBus<Namespace, Subjects, FilterPayload>;
|
|
1200
|
+
/**
|
|
1201
|
+
* Get the bus context for advanced use cases.
|
|
1202
|
+
*/
|
|
1203
|
+
getContext(): MakaioBusContext;
|
|
1204
|
+
};
|
|
1205
|
+
//#endregion
|
|
1206
|
+
//#region core/bus-core/src/types/namespace.d.ts
|
|
1207
|
+
/**
|
|
1208
|
+
* A registered bus namespace with domain, subjects, and pre-computed filter payload type.
|
|
1209
|
+
* @typeParam Domain - The namespace domain string (e.g., 'adapter:codex-mcp')
|
|
1210
|
+
* @typeParam Subjects - The subject record mapping subject keys to payload types
|
|
1211
|
+
* @typeParam FilterPayload - Pre-computed intersection of all filterable payloads for type-safe withFilter
|
|
1212
|
+
* @typeParam Schemas - The original schema record; drives narrow literal types on subjects.$meta (e.g., local: false)
|
|
1213
|
+
*/
|
|
1214
|
+
type BusNamespace<Domain extends string = string, Subjects extends SubjectRecord | BusSubjects = SubjectRecord, FilterPayload = unknown, Schemas extends Record<string, SubjectSchema> = Record<string, SubjectSchema>> = {
|
|
1215
|
+
name: Domain;
|
|
1216
|
+
subjects: BusSubjects<FlatSubjectDefinitions<Domain, Schemas>, Domain>;
|
|
1217
|
+
scopedBus(context?: MakaioBusContext): Promise<ScopedBus<Domain, Subjects, FilterPayload>>;
|
|
1218
|
+
/**
|
|
1219
|
+
* Phantom property for type extraction. Never accessed at runtime.
|
|
1220
|
+
* Enables `ExtractFilterPayload<T>` to infer the FilterPayload type parameter
|
|
1221
|
+
* without relying on complex nested generic inference.
|
|
1222
|
+
*/
|
|
1223
|
+
readonly __filterPayload?: FilterPayload;
|
|
1224
|
+
};
|
|
1225
|
+
/**
|
|
1226
|
+
* Derive a ScopedBus type from a BusNamespace, preserving Domain, Subjects, and FilterPayload.
|
|
1227
|
+
* @example
|
|
1228
|
+
* ```typescript
|
|
1229
|
+
* const MyNamespace = MakaioBus.registerNamespace('myDomain', { ... });
|
|
1230
|
+
* export type MyBus = ScopedBusFor<typeof MyNamespace>;
|
|
1231
|
+
* // Equivalent to: ScopedBus<'myDomain', { ...subjects... }, FilterPayload>
|
|
1232
|
+
* ```
|
|
1233
|
+
*/
|
|
1234
|
+
type ScopedBusFor<T> = T extends BusNamespace<infer D, infer S, infer F, infer _Sc> ? ScopedBus<D, S extends SubjectRecord ? S : SubjectRecord, F> : never;
|
|
1235
|
+
//#endregion
|
|
1236
|
+
//#region core/bus-core/src/registries/namespace-registry.d.ts
|
|
1237
|
+
/**
|
|
1238
|
+
* Callback invoked when a schema violation is detected in lenient mode.
|
|
1239
|
+
* @param report - Violation details including subject, payload, and Zod issues
|
|
1240
|
+
*/
|
|
1241
|
+
type SchemaViolationCallback = (report: SchemaViolationReport) => void;
|
|
1242
|
+
/**
|
|
1243
|
+
* Validation mode for a namespace's bus payloads.
|
|
1244
|
+
*
|
|
1245
|
+
* - `strict` — throw ValidationError on schema mismatch (default)
|
|
1246
|
+
* - `lenient` — invoke onSchemaViolation callback, then continue (event still delivered)
|
|
1247
|
+
* - `skip` — no validation at all (for Zod version conflicts, e.g., SDK bundles Zod v3)
|
|
1248
|
+
*/
|
|
1249
|
+
type BusValidationMode = 'strict' | 'lenient' | 'skip';
|
|
1250
|
+
/**
|
|
1251
|
+
* Resolved validation config for a namespace's bus payloads.
|
|
1252
|
+
*/
|
|
1253
|
+
interface ValidationConfig {
|
|
1254
|
+
/** Active validation mode */
|
|
1255
|
+
mode: BusValidationMode;
|
|
1256
|
+
/** Callback for lenient-mode violations (undefined for strict/skip) */
|
|
1257
|
+
onViolation?: SchemaViolationCallback;
|
|
1258
|
+
}
|
|
1259
|
+
/**
|
|
1260
|
+
* Runtime schema metadata for one registered bus subject.
|
|
1261
|
+
*/
|
|
1262
|
+
interface RegisteredSubjectSchema {
|
|
1263
|
+
/** Namespace passed to `registerNamespace()`. */
|
|
1264
|
+
namespace: string;
|
|
1265
|
+
/** Subject key inside the namespace's schema record. */
|
|
1266
|
+
subject: string;
|
|
1267
|
+
/** Fully-qualified subject key in `namespace.subject` form. */
|
|
1268
|
+
fullSubject: string;
|
|
1269
|
+
/** Unwrapped event or request schema used by runtime validation. */
|
|
1270
|
+
schema: BaseSubjectSchema;
|
|
1271
|
+
/** Whether the subject was registered through `localSubject()`. */
|
|
1272
|
+
local: boolean;
|
|
1273
|
+
/** Whether the subject was registered through `collectorOnlySubject()`. */
|
|
1274
|
+
collectorOnly: boolean;
|
|
1275
|
+
/** Whether the subject was registered through `channelSubject()`. */
|
|
1276
|
+
channel: boolean;
|
|
1277
|
+
}
|
|
1278
|
+
/**
|
|
1279
|
+
* Creates the namespace registry used by a bus context.
|
|
1280
|
+
*
|
|
1281
|
+
* Maintains a runtime map of registered namespaces and their subject schemas,
|
|
1282
|
+
* enabling schema lookup, request-subject detection, local-subject detection,
|
|
1283
|
+
* and validation configuration for namespaces that bundle incompatible Zod versions.
|
|
1284
|
+
* @returns Namespace registry with registerNamespace, getSchema, listRegisteredSubjects,
|
|
1285
|
+
* isRequestSubject, isLocalSubject, getValidationConfig, and (test-only) __resetNamespaces methods
|
|
1286
|
+
*/
|
|
1287
|
+
declare const createNamespaceRegistry: () => {
|
|
1288
|
+
/**
|
|
1289
|
+
* Register a namespace in the runtime registry.
|
|
1290
|
+
*
|
|
1291
|
+
* Accepts a {@link BusNamespaceDefinition} created by `createBusNamespace()` from
|
|
1292
|
+
* `@makaio/core`. The FilterPayload type parameter is computed eagerly from the
|
|
1293
|
+
* schemas, enabling type-safe filtering via `withFilter()`.
|
|
1294
|
+
* @param definition - Namespace definition created by `createBusNamespace()`
|
|
1295
|
+
* @returns The registered namespace with `scopedBus()` and pre-computed FilterPayload type
|
|
1296
|
+
*/
|
|
1297
|
+
registerNamespace<Domain extends string, Schemas extends Record<string, SubjectSchema>>(definition: BusNamespaceDefinition<Domain, Schemas>): BusNamespace<Domain, SubjectRecordFromSchemaRecord<Schemas>, FilterablePayloadIntersection<SubjectRecordFromSchemaRecord<Schemas>>, Schemas>;
|
|
1298
|
+
/**
|
|
1299
|
+
* Register multiple namespaces in a single call.
|
|
1300
|
+
*
|
|
1301
|
+
* Iterates `definitions` and calls `registerNamespace()` for each. Useful
|
|
1302
|
+
* at composition roots to register a catalog of namespace definitions in one
|
|
1303
|
+
* statement:
|
|
1304
|
+
*
|
|
1305
|
+
* ```typescript
|
|
1306
|
+
* MakaioBus.registerNamespaces(FrameworkContractNamespaces);
|
|
1307
|
+
* ```
|
|
1308
|
+
* @param definitions - Array of namespace definitions to register
|
|
1309
|
+
*/
|
|
1310
|
+
registerNamespaces(definitions: readonly RegistrableBusNamespaceDefinition[]): void;
|
|
1311
|
+
/**
|
|
1312
|
+
* Get the schema for a registered subject.
|
|
1313
|
+
* Returns the unwrapped schema (LocalSubjectSchema and ChannelSubjectSchema wrappers are removed during registration).
|
|
1314
|
+
* @param subject - Subject identifier (e.g., "adapter.getCapabilities")
|
|
1315
|
+
* @returns Schema if found, undefined otherwise
|
|
1316
|
+
*/
|
|
1317
|
+
getSchema(subject: string | SubjectDefinition): BaseSubjectSchema | undefined;
|
|
1318
|
+
/**
|
|
1319
|
+
* List all registered subjects with their runtime schema metadata.
|
|
1320
|
+
* @returns Registered subjects sorted by fully-qualified subject key
|
|
1321
|
+
*/
|
|
1322
|
+
listRegisteredSubjects(): RegisteredSubjectSchema[];
|
|
1323
|
+
/**
|
|
1324
|
+
* Get the full registration record for a subject.
|
|
1325
|
+
* @param subject - Fully-qualified subject identifier (e.g., "adapter.getCapabilities")
|
|
1326
|
+
* @returns Registration record if found, undefined otherwise
|
|
1327
|
+
*/
|
|
1328
|
+
getRegisteredSubject(subject: string): RegisteredSubjectSchema | undefined;
|
|
1329
|
+
/**
|
|
1330
|
+
* Check if a subject is registered as a request subject.
|
|
1331
|
+
* @param subject - Subject identifier
|
|
1332
|
+
* @returns True if subject exists and is a request schema
|
|
1333
|
+
*/
|
|
1334
|
+
isRequestSubject(subject: string): boolean;
|
|
1335
|
+
/**
|
|
1336
|
+
* Check if a subject was registered as a local-only subject.
|
|
1337
|
+
*
|
|
1338
|
+
* Local subjects must never be routed over transports. The `__local` flag
|
|
1339
|
+
* is stripped by `unwrapSchema`, so locality is tracked in a separate set
|
|
1340
|
+
* populated at registration time.
|
|
1341
|
+
* @param subject - Full subject identifier (e.g., "widget.register")
|
|
1342
|
+
* @returns True if the subject was wrapped with `localSubject()`
|
|
1343
|
+
*/
|
|
1344
|
+
isLocalSubject(subject: string): boolean;
|
|
1345
|
+
/**
|
|
1346
|
+
* Check if a subject is collector-only.
|
|
1347
|
+
*
|
|
1348
|
+
* Collector-only events may enter from a transport and run local handlers,
|
|
1349
|
+
* but must not be relayed onward to other transports.
|
|
1350
|
+
* @param subject - Full subject identifier (e.g., "subject-telemetry.fact")
|
|
1351
|
+
* @returns True if the subject was wrapped with `collectorOnlySubject()`
|
|
1352
|
+
*/
|
|
1353
|
+
isCollectorOnlySubject(subject: string): boolean;
|
|
1354
|
+
/**
|
|
1355
|
+
* Get the default transport visibility for a subject.
|
|
1356
|
+
*
|
|
1357
|
+
* Returns the namespace-level `defaultTransports` value recorded at
|
|
1358
|
+
* registration time. Subject-level overrides in `SubjectDefinitionMeta`
|
|
1359
|
+
* take precedence and are resolved by `emit()` directly from the subject
|
|
1360
|
+
* definition token.
|
|
1361
|
+
*
|
|
1362
|
+
* Returns `'all'` when no namespace-level default was registered.
|
|
1363
|
+
* @param subject - Fully-qualified subject identifier (e.g., `"session.list"`)
|
|
1364
|
+
* @returns Effective namespace-level default transport visibility
|
|
1365
|
+
*/
|
|
1366
|
+
getDefaultTransports(subject: string): "all" | "local-only";
|
|
1367
|
+
/**
|
|
1368
|
+
* Get the validation configuration for a subject.
|
|
1369
|
+
*
|
|
1370
|
+
* Looks up the namespace from the subject's prefix and returns
|
|
1371
|
+
* the registered mode and optional violation callback.
|
|
1372
|
+
* @param subject - Full subject identifier (e.g., "adapter:claude-code.sdk.event")
|
|
1373
|
+
* @returns Validation config, or `{ mode: 'strict' }` if none registered
|
|
1374
|
+
*/
|
|
1375
|
+
getValidationConfig(subject: string): ValidationConfig;
|
|
1376
|
+
/**
|
|
1377
|
+
* Additively extend a registered subject's schema with new fields.
|
|
1378
|
+
*
|
|
1379
|
+
* For request subjects, extends the request and/or response ZodObject via `.extend()`.
|
|
1380
|
+
* For event subjects, extends the event ZodObject directly.
|
|
1381
|
+
* Successive calls accumulate fields; if a later extension redefines an existing key, the later definition wins (Zod `.extend()` semantics).
|
|
1382
|
+
* @param fullSubjectKey - Fully-qualified key (e.g., "session.list")
|
|
1383
|
+
* @param additionalFields - For request subjects: `{ request?, response? }` each a record
|
|
1384
|
+
* of Zod field definitions. For event subjects: a flat record of Zod field definitions.
|
|
1385
|
+
* @throws Error if the subject is not registered or the existing schema is not a ZodObject
|
|
1386
|
+
*/
|
|
1387
|
+
extendSubjectSchema(fullSubjectKey: string, additionalFields: z.ZodRawShape | {
|
|
1388
|
+
request?: z.ZodRawShape;
|
|
1389
|
+
response?: z.ZodRawShape;
|
|
1390
|
+
}): void;
|
|
1391
|
+
/**
|
|
1392
|
+
* Reset all registered namespaces (for testing only).
|
|
1393
|
+
* @internal
|
|
1394
|
+
*/
|
|
1395
|
+
__resetNamespaces: (() => void) | undefined;
|
|
1396
|
+
};
|
|
1397
|
+
type NamespaceRegistry = ReturnType<typeof createNamespaceRegistry>;
|
|
1398
|
+
//#endregion
|
|
1399
|
+
//#region core/bus-core/src/registries/transport-registry.d.ts
|
|
1400
|
+
interface BusTransportRegistry extends Record<string, BusTransport> {}
|
|
1401
|
+
type BusTransportKeys = keyof BusTransportRegistry;
|
|
1402
|
+
/**
|
|
1403
|
+
* Creates the transport registry used by a bus context.
|
|
1404
|
+
*
|
|
1405
|
+
* Manages connected transports, handles inbound message routing (events,
|
|
1406
|
+
* requests, broadcasts), and relays messages to other registered transports.
|
|
1407
|
+
* @param context - Bus context that owns this registry
|
|
1408
|
+
* @returns Transport registry with registerTransport, getTransport, all,
|
|
1409
|
+
* names, and getPendingReady methods
|
|
1410
|
+
*/
|
|
1411
|
+
/**
|
|
1412
|
+
* Callback interface for transport lifecycle event emission.
|
|
1413
|
+
*
|
|
1414
|
+
* Set on the transport registry by the bus after construction so that
|
|
1415
|
+
* connect/disconnect transitions emit `BusLifecycle.connected` /
|
|
1416
|
+
* `BusLifecycle.disconnected` automatically for every registered transport.
|
|
1417
|
+
*/
|
|
1418
|
+
interface TransportLifecycleEmitter {
|
|
1419
|
+
/**
|
|
1420
|
+
* Called when a transport establishes a connection.
|
|
1421
|
+
* @param transportName - Name of the connected transport.
|
|
1422
|
+
*/
|
|
1423
|
+
onConnected(transportName: string): void;
|
|
1424
|
+
/**
|
|
1425
|
+
* Called when a transport loses connection unexpectedly.
|
|
1426
|
+
* @param transportName - Name of the disconnected transport.
|
|
1427
|
+
*/
|
|
1428
|
+
onDisconnected(transportName: string): void;
|
|
1429
|
+
}
|
|
1430
|
+
declare const createTransportRegistry: (context: MakaioBusContext) => {
|
|
1431
|
+
registerTransport<K extends BusTransportKeys>(name: K, transport: BusTransportRegistry[K]): TransportRegistration;
|
|
1432
|
+
getTransport<K extends BusTransportKeys>(name: K): BusTransportRegistry[K] | undefined;
|
|
1433
|
+
all(): BusTransport[];
|
|
1434
|
+
names(): BusTransportKeys[];
|
|
1435
|
+
/**
|
|
1436
|
+
* Return all unresolved transport `ready` promises for dispatch-level gating.
|
|
1437
|
+
*
|
|
1438
|
+
* Use `Promise.all(registry.getPendingReady())` to await full initialization.
|
|
1439
|
+
* @returns Array of pending ready promises (empty when all transports are ready)
|
|
1440
|
+
*/
|
|
1441
|
+
getPendingReady(): Promise<void>[];
|
|
1442
|
+
/**
|
|
1443
|
+
* Set the lifecycle emitter used to publish `BusLifecycle.connected` /
|
|
1444
|
+
* `BusLifecycle.disconnected` events whenever a transport connects or
|
|
1445
|
+
* disconnects.
|
|
1446
|
+
*
|
|
1447
|
+
* Called once by the owning bus after construction. Subsequent transport
|
|
1448
|
+
* registrations automatically pick up the emitter through the closure.
|
|
1449
|
+
* @param emitter - Lifecycle emitter to install.
|
|
1450
|
+
*/
|
|
1451
|
+
setLifecycleEmitter(emitter: TransportLifecycleEmitter): void;
|
|
1452
|
+
};
|
|
1453
|
+
type TransportRegistry = ReturnType<typeof createTransportRegistry>;
|
|
1454
|
+
//#endregion
|
|
1455
|
+
//#region core/bus-core/src/types/transports.d.ts
|
|
1456
|
+
/**
|
|
1457
|
+
* Subscribe message for client subscription management.
|
|
1458
|
+
*
|
|
1459
|
+
* Supports both subject-based filtering (wildcards) and payload-based filtering
|
|
1460
|
+
* (declarative filter specs). Both are applied server-side for smart-routing.
|
|
1461
|
+
*
|
|
1462
|
+
* Priority arrays enable cross-transport priority-based dispatch: the receiver
|
|
1463
|
+
* uses the arrays to populate its remote handler registry so that dispatch can
|
|
1464
|
+
* consider handler priorities across process boundaries.
|
|
1465
|
+
* @example
|
|
1466
|
+
* ```typescript
|
|
1467
|
+
* // Request handler with priorities
|
|
1468
|
+
* { type: 'subscribe', subjects: { 'ui.navigate': [100, 200] } }
|
|
1469
|
+
*
|
|
1470
|
+
* // Event-only handler (no priority-based dispatch)
|
|
1471
|
+
* { type: 'subscribe', subjects: { 'session.created': [] } }
|
|
1472
|
+
* ```
|
|
1473
|
+
*/
|
|
1474
|
+
interface BusSubscribeMessage {
|
|
1475
|
+
type: 'subscribe';
|
|
1476
|
+
/**
|
|
1477
|
+
* Optional acknowledgement identifier.
|
|
1478
|
+
* Transports that support dynamic subscription acknowledgements send a
|
|
1479
|
+
* `subscription-ack` after applying the subscription update to their local
|
|
1480
|
+
* routing state.
|
|
1481
|
+
*/
|
|
1482
|
+
ackId?: string;
|
|
1483
|
+
/**
|
|
1484
|
+
* Subjects and their handler priorities.
|
|
1485
|
+
* Keys are subject patterns (can include wildcards like `'adapter.*'`).
|
|
1486
|
+
* Values are arrays of handler priorities registered for that subject.
|
|
1487
|
+
* An empty array indicates event-only handlers with no priority-based dispatch.
|
|
1488
|
+
*/
|
|
1489
|
+
subjects: Record<string, number[]>;
|
|
1490
|
+
/**
|
|
1491
|
+
* Optional payload filters per subject.
|
|
1492
|
+
* Key is the subject pattern, value is the filter to apply.
|
|
1493
|
+
* Messages are only forwarded if payload matches the filter.
|
|
1494
|
+
* @example
|
|
1495
|
+
* ```typescript
|
|
1496
|
+
* {
|
|
1497
|
+
* subjects: { 'mcp.event': [] },
|
|
1498
|
+
* filters: {
|
|
1499
|
+
* 'mcp.event': { agentId: 'agent-123' }
|
|
1500
|
+
* }
|
|
1501
|
+
* }
|
|
1502
|
+
* ```
|
|
1503
|
+
*/
|
|
1504
|
+
filters?: Record<string, PayloadFilter>;
|
|
1505
|
+
}
|
|
1506
|
+
/**
|
|
1507
|
+
* Unsubscribe message for client subscription management.
|
|
1508
|
+
*
|
|
1509
|
+
* Priority arrays enable ref-counted unsubscription: the receiver removes only
|
|
1510
|
+
* the listed handler priorities from its remote handler registry rather than
|
|
1511
|
+
* wiping the entire subject entry.
|
|
1512
|
+
*/
|
|
1513
|
+
interface BusUnsubscribeMessage {
|
|
1514
|
+
type: 'unsubscribe';
|
|
1515
|
+
/**
|
|
1516
|
+
* Optional acknowledgement identifier.
|
|
1517
|
+
* Transports that support dynamic subscription acknowledgements send a
|
|
1518
|
+
* `subscription-ack` after applying the unsubscription update to their local
|
|
1519
|
+
* routing state.
|
|
1520
|
+
*/
|
|
1521
|
+
ackId?: string;
|
|
1522
|
+
/**
|
|
1523
|
+
* Subjects and the handler priorities being removed.
|
|
1524
|
+
* Keys are subject patterns.
|
|
1525
|
+
* Values are the specific priorities being unregistered (for ref-counting).
|
|
1526
|
+
* An empty array removes the subject entirely (no handlers remain).
|
|
1527
|
+
*/
|
|
1528
|
+
subjects: Record<string, number[]>;
|
|
1529
|
+
}
|
|
1530
|
+
/**
|
|
1531
|
+
* Subscribe-sync-complete handshake message.
|
|
1532
|
+
*
|
|
1533
|
+
* Sent by the bus to a newly registered transport after the current handler
|
|
1534
|
+
* subscriptions have been pushed. The recipient resolves its `ready` promise
|
|
1535
|
+
* upon receipt, signalling that priority-based request dispatch may safely
|
|
1536
|
+
* route through the transport.
|
|
1537
|
+
*/
|
|
1538
|
+
interface BusSubscribeSyncCompleteMessage {
|
|
1539
|
+
type: 'subscribe-sync-complete';
|
|
1540
|
+
}
|
|
1541
|
+
/**
|
|
1542
|
+
* Acknowledges a dynamic subscribe/unsubscribe control message.
|
|
1543
|
+
*
|
|
1544
|
+
* Complements the initial `subscribe-sync-complete` handshake: the handshake
|
|
1545
|
+
* covers connection startup, while this message confirms one later
|
|
1546
|
+
* subscription change has reached the remote routing state.
|
|
1547
|
+
*/
|
|
1548
|
+
interface BusSubscriptionAckMessage {
|
|
1549
|
+
type: 'subscription-ack';
|
|
1550
|
+
ackId: string;
|
|
1551
|
+
}
|
|
1552
|
+
/**
|
|
1553
|
+
* Message types for transport wire protocol.
|
|
1554
|
+
*/
|
|
1555
|
+
type BusMessage = BusRequestMessage | BusResponseMessage | BusEventMessage | BusBroadcastMessage | BusBroadcastResponseMessage | BusHeartbeatMessage | BusSubscribeMessage | BusUnsubscribeMessage | BusSubscribeSyncCompleteMessage | BusSubscriptionAckMessage;
|
|
1556
|
+
/**
|
|
1557
|
+
* Handler invoked by transports when a bus message arrives.
|
|
1558
|
+
*
|
|
1559
|
+
* The optional receive context is trusted local metadata supplied by the
|
|
1560
|
+
* receiving transport. It must not be serialized or relayed to other nodes.
|
|
1561
|
+
*/
|
|
1562
|
+
type BusReceiveHandler = (message: BusMessage, context?: TransportReceiveContext) => Promise<void>;
|
|
1563
|
+
/**
|
|
1564
|
+
* Heartbeat message for connection keep-alive.
|
|
1565
|
+
*/
|
|
1566
|
+
interface BusHeartbeatMessage {
|
|
1567
|
+
type: 'heartbeat';
|
|
1568
|
+
timestamp: number;
|
|
1569
|
+
}
|
|
1570
|
+
/**
|
|
1571
|
+
* Request message sent over transport.
|
|
1572
|
+
*/
|
|
1573
|
+
interface BusRequestMessage {
|
|
1574
|
+
type: 'request';
|
|
1575
|
+
subject: string;
|
|
1576
|
+
namespace: string;
|
|
1577
|
+
payload: unknown;
|
|
1578
|
+
correlationId: string;
|
|
1579
|
+
messageId: string;
|
|
1580
|
+
/**
|
|
1581
|
+
* Caller-specified request timeout in milliseconds.
|
|
1582
|
+
*
|
|
1583
|
+
* Propagated across relay hops so intermediate transport registries use the
|
|
1584
|
+
* same timeout policy as the original caller.
|
|
1585
|
+
* A value of `0` means no automatic timeout.
|
|
1586
|
+
*/
|
|
1587
|
+
timeout?: number;
|
|
1588
|
+
/**
|
|
1589
|
+
* Priority cursor for cross-transport priority-based dispatch.
|
|
1590
|
+
*
|
|
1591
|
+
* When set, dispatch considers only handlers with a priority strictly below
|
|
1592
|
+
* this value, enabling the chain to continue from where a previous hop left off.
|
|
1593
|
+
* Omitted on the first dispatch hop (meaning start from the highest priority).
|
|
1594
|
+
*/
|
|
1595
|
+
priority?: number;
|
|
1596
|
+
/**
|
|
1597
|
+
* Absolute dispatch deadline as a Unix timestamp in milliseconds (`Date.now() + timeout`).
|
|
1598
|
+
*
|
|
1599
|
+
* Set on the first dispatch hop and propagated through all subsequent hops so
|
|
1600
|
+
* that each hop can compute its remaining time budget without relying on the
|
|
1601
|
+
* original timeout value alone.
|
|
1602
|
+
*/
|
|
1603
|
+
deadline?: number;
|
|
1604
|
+
}
|
|
1605
|
+
/**
|
|
1606
|
+
* Structured error payload for transport responses.
|
|
1607
|
+
*/
|
|
1608
|
+
interface BusTransportError {
|
|
1609
|
+
/** Human-readable error message */
|
|
1610
|
+
message: string;
|
|
1611
|
+
/** Error code for programmatic handling (e.g., 'IMPORT_CONFLICT') */
|
|
1612
|
+
code?: string;
|
|
1613
|
+
/**
|
|
1614
|
+
* Subject this error pertains to.
|
|
1615
|
+
* Preserved for {@link NoHandlerError} so that `isNoHandlerErrorForSubject`
|
|
1616
|
+
* can match without fragile message-string comparisons after a
|
|
1617
|
+
* serialize → deserialize round-trip.
|
|
1618
|
+
*/
|
|
1619
|
+
subject?: string;
|
|
1620
|
+
/** Additional error data (e.g., conflicts, orphans) */
|
|
1621
|
+
data?: Record<string, unknown>;
|
|
1622
|
+
}
|
|
1623
|
+
/**
|
|
1624
|
+
* Response message sent over transport.
|
|
1625
|
+
*/
|
|
1626
|
+
interface BusResponseMessage {
|
|
1627
|
+
type: 'response';
|
|
1628
|
+
correlationId: string;
|
|
1629
|
+
result?: unknown;
|
|
1630
|
+
error?: BusTransportError;
|
|
1631
|
+
}
|
|
1632
|
+
/**
|
|
1633
|
+
* Event message sent over transport.
|
|
1634
|
+
*/
|
|
1635
|
+
interface BusEventMessage {
|
|
1636
|
+
type: 'event';
|
|
1637
|
+
subject: string;
|
|
1638
|
+
namespace: string;
|
|
1639
|
+
payload: unknown;
|
|
1640
|
+
messageId: string;
|
|
1641
|
+
correlationId?: string;
|
|
1642
|
+
}
|
|
1643
|
+
/**
|
|
1644
|
+
* Broadcast request message sent over transport.
|
|
1645
|
+
*
|
|
1646
|
+
* Unlike regular requests (single response), broadcasts expect
|
|
1647
|
+
* multiple responses aggregated into an array.
|
|
1648
|
+
*/
|
|
1649
|
+
interface BusBroadcastMessage {
|
|
1650
|
+
type: 'broadcast';
|
|
1651
|
+
subject: string;
|
|
1652
|
+
namespace: string;
|
|
1653
|
+
payload: unknown;
|
|
1654
|
+
correlationId: string;
|
|
1655
|
+
messageId: string;
|
|
1656
|
+
/**
|
|
1657
|
+
* Caller-specified broadcast timeout in milliseconds.
|
|
1658
|
+
*
|
|
1659
|
+
* Propagated across relay hops so relayed broadcast collection preserves the
|
|
1660
|
+
* original caller timeout contract.
|
|
1661
|
+
* A value of `0` means no automatic timeout.
|
|
1662
|
+
*/
|
|
1663
|
+
timeout?: number;
|
|
1664
|
+
}
|
|
1665
|
+
/**
|
|
1666
|
+
* Broadcast response message sent over transport.
|
|
1667
|
+
*
|
|
1668
|
+
* Contains an array of results from all handlers that responded.
|
|
1669
|
+
*/
|
|
1670
|
+
interface BusBroadcastResponseMessage {
|
|
1671
|
+
type: 'broadcast-response';
|
|
1672
|
+
correlationId: string;
|
|
1673
|
+
results?: Array<{
|
|
1674
|
+
nodeId: string;
|
|
1675
|
+
payload: unknown;
|
|
1676
|
+
}>;
|
|
1677
|
+
error?: BusTransportError;
|
|
1678
|
+
}
|
|
1679
|
+
/**
|
|
1680
|
+
* Transport interface for bus communication.
|
|
1681
|
+
*
|
|
1682
|
+
* Transports handle serialization, wire protocol, and connection management
|
|
1683
|
+
* for cross-process communication.
|
|
1684
|
+
* @example
|
|
1685
|
+
* ```typescript
|
|
1686
|
+
* class WebSocketTransport implements BusTransport {
|
|
1687
|
+
* readonly name = 'websocket';
|
|
1688
|
+
*
|
|
1689
|
+
* async send(message: BusMessage): Promise<void> {
|
|
1690
|
+
* this.ws.send(JSON.stringify(message));
|
|
1691
|
+
* }
|
|
1692
|
+
*
|
|
1693
|
+
* onReceive(handler: BusReceiveHandler): () => void {
|
|
1694
|
+
* const listener = (data) => {
|
|
1695
|
+
* const message = JSON.parse(data) as BusMessage;
|
|
1696
|
+
* const context: TransportReceiveContext = { transportName: this.name };
|
|
1697
|
+
* void handler(message, context);
|
|
1698
|
+
* };
|
|
1699
|
+
* this.ws.on('message', listener);
|
|
1700
|
+
* return () => this.ws.off('message', listener);
|
|
1701
|
+
* }
|
|
1702
|
+
*
|
|
1703
|
+
* async connect(): Promise<void> {
|
|
1704
|
+
* await this.ws.connect();
|
|
1705
|
+
* }
|
|
1706
|
+
*
|
|
1707
|
+
* async disconnect(): Promise<void> {
|
|
1708
|
+
* await this.ws.close();
|
|
1709
|
+
* }
|
|
1710
|
+
* }
|
|
1711
|
+
* ```
|
|
1712
|
+
*/
|
|
1713
|
+
interface BusTransport {
|
|
1714
|
+
/**
|
|
1715
|
+
* Unique transport name used as the registry key.
|
|
1716
|
+
*
|
|
1717
|
+
* The name is used by `IMakaioBus.registerTransport()` to key the transport
|
|
1718
|
+
* in the internal registry. It must be unique within a single bus instance.
|
|
1719
|
+
* Implementations should declare this as a `readonly` literal or class field.
|
|
1720
|
+
* @example
|
|
1721
|
+
* ```typescript
|
|
1722
|
+
* class MyTransport implements BusTransport {
|
|
1723
|
+
* readonly name = 'my-transport';
|
|
1724
|
+
* }
|
|
1725
|
+
* ```
|
|
1726
|
+
*/
|
|
1727
|
+
name: string;
|
|
1728
|
+
/**
|
|
1729
|
+
* Send a message over the transport.
|
|
1730
|
+
*
|
|
1731
|
+
* **Behavior by message type:**
|
|
1732
|
+
* - **Requests** (`BusRequestMessage`): Returns the response payload from the handler.
|
|
1733
|
+
* Throws error if no clients available to handle request (server mode).
|
|
1734
|
+
* - **Events** (`BusEventMessage`): Returns delivery status boolean.
|
|
1735
|
+
* - `true`: Delivered to at least one recipient
|
|
1736
|
+
* - `false`: No recipients available (not an error)
|
|
1737
|
+
* - **Other messages** (heartbeat, subscribe, etc.): Returns `true` if sent successfully.
|
|
1738
|
+
*
|
|
1739
|
+
* **Error handling:**
|
|
1740
|
+
* - Throws when transport is disconnected
|
|
1741
|
+
* - Throws when sending requests with no connected clients (server mode only)
|
|
1742
|
+
* - Never throws for events - returns `false` instead
|
|
1743
|
+
*
|
|
1744
|
+
* **Timeout contract:**
|
|
1745
|
+
* The `timeout` value flows from the caller's `bus.request({ timeout })` option
|
|
1746
|
+
* through the dispatch layer to the transport's correlation tracker.
|
|
1747
|
+
* A value of `0` means no automatic timeout — the promise stays open until
|
|
1748
|
+
* resolved or rejected externally (e.g. by the caller's own AbortSignal).
|
|
1749
|
+
* @param message - Message to send
|
|
1750
|
+
* @param timeout - Correlation timeout in milliseconds; `0` means no automatic timeout
|
|
1751
|
+
* @returns Promise resolving to response payload (requests) or delivery status (events/other)
|
|
1752
|
+
* @example
|
|
1753
|
+
* ```typescript
|
|
1754
|
+
* // Request: type-safe response handling
|
|
1755
|
+
* const request: BusRequestMessage = {
|
|
1756
|
+
* type: 'request',
|
|
1757
|
+
* subject: 'user.get',
|
|
1758
|
+
* namespace: 'api',
|
|
1759
|
+
* payload: { id: 123 },
|
|
1760
|
+
* correlationId: 'req-1',
|
|
1761
|
+
* messageId: 'msg-1',
|
|
1762
|
+
* };
|
|
1763
|
+
* const response = await transport.send(request, 5000); // response: unknown
|
|
1764
|
+
*
|
|
1765
|
+
* // Event: delivery status
|
|
1766
|
+
* const event: BusEventMessage = {
|
|
1767
|
+
* type: 'event',
|
|
1768
|
+
* subject: 'user.created',
|
|
1769
|
+
* namespace: 'api',
|
|
1770
|
+
* payload: { id: 123 },
|
|
1771
|
+
* messageId: 'evt-1',
|
|
1772
|
+
* };
|
|
1773
|
+
* const delivered = await transport.send(event, 0); // delivered: boolean
|
|
1774
|
+
* if (!delivered) {
|
|
1775
|
+
* console.warn('Event not delivered - no subscribers');
|
|
1776
|
+
* }
|
|
1777
|
+
* ```
|
|
1778
|
+
*/
|
|
1779
|
+
send<TMessage extends BusMessage>(message: TMessage, timeout?: number): Promise<TMessage extends BusRequestMessage ? unknown : TMessage extends BusBroadcastMessage ? Array<{
|
|
1780
|
+
nodeId: string;
|
|
1781
|
+
payload: unknown;
|
|
1782
|
+
}> : boolean>;
|
|
1783
|
+
/**
|
|
1784
|
+
* Optional: cancel/cleanup pending correlation state for an in-flight request.
|
|
1785
|
+
*
|
|
1786
|
+
* Used when the caller aborts while the transport-level correlation promise is
|
|
1787
|
+
* still pending (e.g. timeout `0` + AbortSignal). Implementations should reject
|
|
1788
|
+
* and remove the correlation entry if present.
|
|
1789
|
+
* @param correlationId - Correlation ID to cancel
|
|
1790
|
+
* @param error - Optional cancellation error to propagate
|
|
1791
|
+
*/
|
|
1792
|
+
cancelRequest?(correlationId: string, error?: Error): void;
|
|
1793
|
+
/**
|
|
1794
|
+
* Register a handler for incoming messages.
|
|
1795
|
+
* @param handler - Handler function
|
|
1796
|
+
* @returns Unsubscribe function
|
|
1797
|
+
*/
|
|
1798
|
+
onReceive(handler: BusReceiveHandler): () => void;
|
|
1799
|
+
/**
|
|
1800
|
+
* Connect the transport.
|
|
1801
|
+
*/
|
|
1802
|
+
connect(): Promise<void>;
|
|
1803
|
+
/**
|
|
1804
|
+
* Disconnect the transport.
|
|
1805
|
+
*/
|
|
1806
|
+
disconnect(): Promise<void>;
|
|
1807
|
+
/**
|
|
1808
|
+
* Optional: Trigger an immediate reconnection attempt, bypassing any backoff wait.
|
|
1809
|
+
*
|
|
1810
|
+
* If the transport is currently waiting in an exponential-backoff delay, calling
|
|
1811
|
+
* this wakes it immediately so a new connection attempt starts without waiting.
|
|
1812
|
+
* If reconnection is disabled on the transport, a one-shot connect attempt is made.
|
|
1813
|
+
* No-op when the transport is already connected.
|
|
1814
|
+
* @returns Promise that resolves when the attempt is initiated or completes
|
|
1815
|
+
*/
|
|
1816
|
+
reconnect?(): Promise<void>;
|
|
1817
|
+
/**
|
|
1818
|
+
* Optional: Promise that resolves when the transport is fully operational
|
|
1819
|
+
* (end-to-end, including remote handler availability).
|
|
1820
|
+
*
|
|
1821
|
+
* Resolved after the bus has sent the initial subscribe sync to the transport
|
|
1822
|
+
* and the transport has received the {@link BusSubscribeSyncCompleteMessage}
|
|
1823
|
+
* handshake. Before this resolves, `remoteRequestHandlers` for this transport
|
|
1824
|
+
* may be incomplete and requests should not be routed through it.
|
|
1825
|
+
*
|
|
1826
|
+
* Transports that do not implement `ready` are considered immediately ready.
|
|
1827
|
+
* @remarks
|
|
1828
|
+
* Transports that do not implement `onNewReadySession` are single-use:
|
|
1829
|
+
* after `disconnect()` completes, a later `connect()` call has undefined
|
|
1830
|
+
* behavior. Reconnectable transports must call `onNewReadySession` each time
|
|
1831
|
+
* they create a new `ready` promise so the registry can update its gating.
|
|
1832
|
+
*/
|
|
1833
|
+
ready?: Promise<void>;
|
|
1834
|
+
/**
|
|
1835
|
+
* Optional callback set by the transport registry during registration.
|
|
1836
|
+
* Transports that support reconnection call this at the start of each
|
|
1837
|
+
* new session so the registry can track the new ready promise for
|
|
1838
|
+
* dispatch gating.
|
|
1839
|
+
* @param promise - The new ready promise for the current session
|
|
1840
|
+
*/
|
|
1841
|
+
onNewReadySession?: (promise: Promise<void>) => void;
|
|
1842
|
+
/**
|
|
1843
|
+
* Optional callback set by the transport registry during registration.
|
|
1844
|
+
* Called each time the transport establishes a connection (initial or reconnect),
|
|
1845
|
+
* after authentication and subscription replay are complete.
|
|
1846
|
+
*/
|
|
1847
|
+
onConnected?: () => void;
|
|
1848
|
+
/**
|
|
1849
|
+
* Optional callback set by the transport registry during registration.
|
|
1850
|
+
* Called when the transport loses its connection unexpectedly.
|
|
1851
|
+
* Not called on an explicit `disconnect()`.
|
|
1852
|
+
*/
|
|
1853
|
+
onDisconnected?: () => void;
|
|
1854
|
+
/**
|
|
1855
|
+
* Optional: Synchronous readiness check for transport-level gating.
|
|
1856
|
+
*
|
|
1857
|
+
* When implemented and returning `false`, the bus skips this transport
|
|
1858
|
+
* for outbound sends (requests, broadcasts, events). The transport
|
|
1859
|
+
* continues to receive inbound messages via `onReceive`.
|
|
1860
|
+
*
|
|
1861
|
+
* Complements the async `ready` promise: `isReady()` enables non-blocking
|
|
1862
|
+
* skip decisions in hot paths, while `ready` supports await-based flows.
|
|
1863
|
+
* @returns `true` if the transport can send messages, `false` otherwise
|
|
1864
|
+
*/
|
|
1865
|
+
isReady?(): boolean;
|
|
1866
|
+
/**
|
|
1867
|
+
* Optional: Report which subjects this transport is interested in.
|
|
1868
|
+
* Enables transport-level filtering for efficiency.
|
|
1869
|
+
*
|
|
1870
|
+
* If not implemented, the transport will receive all messages (broadcast mode).
|
|
1871
|
+
* If implemented, only messages matching the subscription patterns will be sent.
|
|
1872
|
+
*
|
|
1873
|
+
* Patterns can include wildcards (e.g., 'adapter.*' matches 'adapter.log', 'adapter.init', etc.)
|
|
1874
|
+
* @returns Set of subscription patterns (can include wildcards)
|
|
1875
|
+
*/
|
|
1876
|
+
getSubscriptions?(): Set<string>;
|
|
1877
|
+
/**
|
|
1878
|
+
* Subscribe to a subject for smart-routing.
|
|
1879
|
+
*
|
|
1880
|
+
* Transports use this to track which subjects have active handlers,
|
|
1881
|
+
* enabling targeted message delivery instead of broadcast.
|
|
1882
|
+
*
|
|
1883
|
+
* When `priorities` is provided the transport should include the priority
|
|
1884
|
+
* information in the next outbound subscribe wire message for this subject,
|
|
1885
|
+
* enabling cross-transport priority-based dispatch on the remote side.
|
|
1886
|
+
* Calling this method again with a new `priorities` array replaces the
|
|
1887
|
+
* previously advertised set for that subject (re-subscribe semantics).
|
|
1888
|
+
*
|
|
1889
|
+
* Transports that do not need subscription management (e.g. local-only
|
|
1890
|
+
* loopback transports) should provide a no-op implementation.
|
|
1891
|
+
* @param subject - Subject pattern to subscribe to (can include wildcards)
|
|
1892
|
+
* @param filter - Optional payload filter for fine-grained routing
|
|
1893
|
+
* @param priorities - Handler priorities registered for this subject; an empty
|
|
1894
|
+
* array signals event-only handlers that do not participate in priority dispatch
|
|
1895
|
+
*/
|
|
1896
|
+
subscribe(subject: string, filter?: PayloadFilter, priorities?: number[]): Promise<void>;
|
|
1897
|
+
/**
|
|
1898
|
+
* Unsubscribe from a subject.
|
|
1899
|
+
*
|
|
1900
|
+
* Called when the last handler for a subject is removed, allowing the
|
|
1901
|
+
* transport to stop routing messages for that subject.
|
|
1902
|
+
*
|
|
1903
|
+
* Transports that do not need subscription management should provide a
|
|
1904
|
+
* no-op implementation.
|
|
1905
|
+
* @param subject - Subject pattern to unsubscribe from
|
|
1906
|
+
*/
|
|
1907
|
+
unsubscribe(subject: string): Promise<void>;
|
|
1908
|
+
/**
|
|
1909
|
+
* Receive aggregated broadcast results from the transport registry.
|
|
1910
|
+
*
|
|
1911
|
+
* Called by the transport registry after executing local handlers and relaying
|
|
1912
|
+
* to other transports for a broadcast that arrived from this transport via
|
|
1913
|
+
* `onReceive`. Replaces the legacy `send({ type: 'broadcast-response' })`
|
|
1914
|
+
* side-channel when implemented.
|
|
1915
|
+
*
|
|
1916
|
+
* Transports that manage their own peer-level fan-out (e.g., ServerTransport
|
|
1917
|
+
* with multiple WebSocket clients) implement this to receive registry results
|
|
1918
|
+
* without abusing the `send()` contract.
|
|
1919
|
+
* @param correlationId - Correlation ID of the originating broadcast
|
|
1920
|
+
* @param results - Aggregated results from local handlers and relay transports
|
|
1921
|
+
* @param error - Optional structured error when broadcast processing failed;
|
|
1922
|
+
* results may be empty or partial in this case
|
|
1923
|
+
*/
|
|
1924
|
+
onBroadcastResults?(correlationId: string, results: ReadonlyArray<{
|
|
1925
|
+
nodeId: string;
|
|
1926
|
+
payload: unknown;
|
|
1927
|
+
}>, error?: BusTransportError): void;
|
|
1928
|
+
}
|
|
1929
|
+
//#endregion
|
|
1930
|
+
//#region core/bus-core/src/methods/broadcast.d.ts
|
|
1931
|
+
/**
|
|
1932
|
+
* Result from a single handler in a broadcast.
|
|
1933
|
+
* @typeParam T - Response payload type
|
|
1934
|
+
*/
|
|
1935
|
+
interface BroadcastResult<T> {
|
|
1936
|
+
/** Handler identifier (set via ctx.identify() in handler, or 'anonymous' if not set) */
|
|
1937
|
+
nodeId: string;
|
|
1938
|
+
/** Response payload from the handler */
|
|
1939
|
+
payload: T;
|
|
1940
|
+
}
|
|
1941
|
+
/**
|
|
1942
|
+
* Extended request context for broadcast handlers.
|
|
1943
|
+
* Adds identify() method to tag responses with a node identifier.
|
|
1944
|
+
*/
|
|
1945
|
+
interface BroadcastContext<Request, Response> extends RequestContext<Request, Response> {
|
|
1946
|
+
/**
|
|
1947
|
+
* Identify this handler for broadcast aggregation.
|
|
1948
|
+
* Call before setResult() to tag the response with a nodeId.
|
|
1949
|
+
* @param nodeId - Unique identifier for this handler/node
|
|
1950
|
+
*/
|
|
1951
|
+
identify: (nodeId: string) => void;
|
|
1952
|
+
}
|
|
1953
|
+
//#endregion
|
|
1954
|
+
//#region core/bus-core/src/types/options.d.ts
|
|
1955
|
+
/**
|
|
1956
|
+
* Default request timeout in milliseconds.
|
|
1957
|
+
*
|
|
1958
|
+
* Shared policy constant used when callers omit `RequestOptions.timeout`.
|
|
1959
|
+
*/
|
|
1960
|
+
declare const DEFAULT_REQUEST_TIMEOUT_MS = 60000;
|
|
1961
|
+
/**
|
|
1962
|
+
* Options for subscribing to events/requests via on().
|
|
1963
|
+
*/
|
|
1964
|
+
interface OnOptions {
|
|
1965
|
+
/**
|
|
1966
|
+
* Explicit handler registry target for wildcard subjects.
|
|
1967
|
+
*
|
|
1968
|
+
* Exact subjects derive their registry from the subject schema. Wildcard
|
|
1969
|
+
* subjects can match both events and requests, so callers that know their
|
|
1970
|
+
* intent can pin the registration to event-only or request-only. Omit this
|
|
1971
|
+
* option to preserve the historical ambiguous wildcard behavior.
|
|
1972
|
+
*/
|
|
1973
|
+
handlerKind?: 'event' | 'request' | 'both';
|
|
1974
|
+
/**
|
|
1975
|
+
* Declarative payload filter for smart-routing.
|
|
1976
|
+
*
|
|
1977
|
+
* Applied both locally (before handler invocation) and can be sent
|
|
1978
|
+
* to transports for server-side filtering.
|
|
1979
|
+
*
|
|
1980
|
+
* All conditions are ANDed together.
|
|
1981
|
+
* @example
|
|
1982
|
+
* ```typescript
|
|
1983
|
+
* bus.on(Subjects.message, handler, {
|
|
1984
|
+
* filter: {
|
|
1985
|
+
* agentId: 'agent-123',
|
|
1986
|
+
* status: { $in: ['active', 'pending'] },
|
|
1987
|
+
* }
|
|
1988
|
+
* });
|
|
1989
|
+
* ```
|
|
1990
|
+
*/
|
|
1991
|
+
filter?: PayloadFilter;
|
|
1992
|
+
/**
|
|
1993
|
+
* Handler priority for middleware-style ordering.
|
|
1994
|
+
*
|
|
1995
|
+
* Higher values run earlier. Default is 0.
|
|
1996
|
+
* Handlers with equal priority preserve registration order.
|
|
1997
|
+
* @example
|
|
1998
|
+
* ```typescript
|
|
1999
|
+
* // Authentication runs first (highest priority)
|
|
2000
|
+
* bus.on(Subjects.request, authHandler, { priority: 100 });
|
|
2001
|
+
*
|
|
2002
|
+
* // Logging runs next
|
|
2003
|
+
* bus.on(Subjects.request, logHandler, { priority: 50 });
|
|
2004
|
+
*
|
|
2005
|
+
* // Business logic runs last (default priority)
|
|
2006
|
+
* bus.on(Subjects.request, businessHandler);
|
|
2007
|
+
* ```
|
|
2008
|
+
*/
|
|
2009
|
+
priority?: number;
|
|
2010
|
+
}
|
|
2011
|
+
/**
|
|
2012
|
+
* Options for emitting events.
|
|
2013
|
+
*
|
|
2014
|
+
* Extends BaseMessage to provide message tracking.
|
|
2015
|
+
* All fields are optional - defaults will be auto-generated.
|
|
2016
|
+
*/
|
|
2017
|
+
interface EmitOptions {
|
|
2018
|
+
/**
|
|
2019
|
+
* Unique identifier for this event.
|
|
2020
|
+
* Auto-generated if not provided.
|
|
2021
|
+
*/
|
|
2022
|
+
messageId?: string;
|
|
2023
|
+
/**
|
|
2024
|
+
* Optional correlation ID for linking related operations.
|
|
2025
|
+
* Useful for tracking events as part of a larger workflow.
|
|
2026
|
+
*/
|
|
2027
|
+
correlationId?: string;
|
|
2028
|
+
/**
|
|
2029
|
+
* Optional set of transport keys to send this event over.
|
|
2030
|
+
* If not specified, the event will be emitted locally and relayed to all ready transports.
|
|
2031
|
+
* Can be provided as a Set or Array of transport names.
|
|
2032
|
+
*/
|
|
2033
|
+
transports?: Set<BusTransportKeys> | Array<BusTransportKeys>;
|
|
2034
|
+
}
|
|
2035
|
+
/**
|
|
2036
|
+
* Options for making requests.
|
|
2037
|
+
*
|
|
2038
|
+
* Extends EmitOptions with request-specific settings like timeout.
|
|
2039
|
+
*/
|
|
2040
|
+
interface RequestOptions extends EmitOptions {
|
|
2041
|
+
/**
|
|
2042
|
+
* Timeout in milliseconds. Defaults to DEFAULT_REQUEST_TIMEOUT_MS (60 seconds) if not specified.
|
|
2043
|
+
* Use `0` for no automatic timeout — the request stays open until resolved,
|
|
2044
|
+
* rejected, or cancelled via the `signal` AbortSignal.
|
|
2045
|
+
*/
|
|
2046
|
+
timeout?: number;
|
|
2047
|
+
/**
|
|
2048
|
+
* AbortSignal to cancel the request.
|
|
2049
|
+
*
|
|
2050
|
+
* When aborted, the request will reject with an AbortError.
|
|
2051
|
+
* This allows callers to cancel long-running requests when they're
|
|
2052
|
+
* no longer needed (e.g., user typing invalidates previous autocomplete).
|
|
2053
|
+
* @example
|
|
2054
|
+
* ```typescript
|
|
2055
|
+
* const controller = new AbortController();
|
|
2056
|
+
* const result = MakaioBus.request(Subject, payload, {
|
|
2057
|
+
* signal: controller.signal,
|
|
2058
|
+
* });
|
|
2059
|
+
* // Later, if needed:
|
|
2060
|
+
* controller.abort();
|
|
2061
|
+
* ```
|
|
2062
|
+
*/
|
|
2063
|
+
signal?: AbortSignal;
|
|
2064
|
+
}
|
|
2065
|
+
//#endregion
|
|
2066
|
+
//#region core/bus-core/src/types/handler-entry.d.ts
|
|
2067
|
+
/**
|
|
2068
|
+
* Handler entry with priority for middleware-style ordering.
|
|
2069
|
+
* Higher priority values run earlier in the handler chain.
|
|
2070
|
+
*/
|
|
2071
|
+
interface HandlerEntry<H> {
|
|
2072
|
+
handler: H;
|
|
2073
|
+
priority: number;
|
|
2074
|
+
}
|
|
2075
|
+
//#endregion
|
|
2076
|
+
//#region core/bus-core/src/types/bus.d.ts
|
|
2077
|
+
/**
|
|
2078
|
+
* Production-capable observation record for local bus API entrypoints.
|
|
2079
|
+
*
|
|
2080
|
+
* Unlike `AnyMessageContext`, this is not debug-only and is safe for runtime
|
|
2081
|
+
* services that need to derive sanitized telemetry.
|
|
2082
|
+
*/
|
|
2083
|
+
interface ObservedBusMessage {
|
|
2084
|
+
readonly type: 'event' | 'request' | 'broadcast';
|
|
2085
|
+
readonly subject: string;
|
|
2086
|
+
readonly namespace: string;
|
|
2087
|
+
readonly payload: unknown;
|
|
2088
|
+
readonly messageId: string;
|
|
2089
|
+
readonly correlationId?: string;
|
|
2090
|
+
readonly transport?: TransportReceiveContext;
|
|
2091
|
+
/** True when the originating bus call was explicitly or inherently local-only. */
|
|
2092
|
+
readonly localOnly?: boolean;
|
|
2093
|
+
}
|
|
2094
|
+
/**
|
|
2095
|
+
* Observer callback invoked for each local bus API message after validation
|
|
2096
|
+
* has succeeded. Observers must not mutate the payload.
|
|
2097
|
+
*/
|
|
2098
|
+
type BusMessageObserver = (message: ObservedBusMessage) => void | Promise<void>;
|
|
2099
|
+
/**
|
|
2100
|
+
* Internal bus context containing handler registries and shared state.
|
|
2101
|
+
*
|
|
2102
|
+
* Enables creation of isolated bus instances (e.g., for testing) by providing
|
|
2103
|
+
* separate handler maps per instance.
|
|
2104
|
+
*
|
|
2105
|
+
* Handler arrays are sorted by priority (highest first), with registration order
|
|
2106
|
+
* preserved for handlers with equal priority.
|
|
2107
|
+
*/
|
|
2108
|
+
interface MakaioBusContext {
|
|
2109
|
+
eventHandlers: Map<string, Array<HandlerEntry<EventHandler<unknown>>>>;
|
|
2110
|
+
requestHandlers: Map<string, Array<HandlerEntry<RequestHandler<unknown, unknown>>>>;
|
|
2111
|
+
interceptorHandlers: Map<string, Array<InterceptorEntry<InterceptorHandler<unknown>>>>;
|
|
2112
|
+
anyHandlers: Set<AnyHandler>;
|
|
2113
|
+
/** Production-capable message observers registered via {@link IMakaioBus.observeMessages}. */
|
|
2114
|
+
messageObservers: Set<BusMessageObserver>;
|
|
2115
|
+
transportRegistry: TransportRegistry;
|
|
2116
|
+
namespaceRegistry: NamespaceRegistry;
|
|
2117
|
+
/** Remote handler priorities from subscribe messages; keyed by subject pattern. */
|
|
2118
|
+
remoteRequestHandlers: Map<string, Array<{
|
|
2119
|
+
transport: string;
|
|
2120
|
+
priority: number;
|
|
2121
|
+
}>>;
|
|
2122
|
+
/**
|
|
2123
|
+
* Set of transport names that have subscribed to each subject with event-only handlers
|
|
2124
|
+
* (i.e. subscribe messages whose priority array was empty).
|
|
2125
|
+
*
|
|
2126
|
+
* Tracked separately from `remoteRequestHandlers` because event-only subscriptions
|
|
2127
|
+
* produce no priority entries yet must still influence advertised-state decisions:
|
|
2128
|
+
* if a remote has event-only handlers for a subject, peers should still receive a
|
|
2129
|
+
* `subscribe` (with an empty priority array) rather than an `unsubscribe`.
|
|
2130
|
+
*/
|
|
2131
|
+
remoteEventHandlers: Map<string, Set<string>>;
|
|
2132
|
+
}
|
|
2133
|
+
/**
|
|
2134
|
+
* Result of registering a transport on the bus.
|
|
2135
|
+
*/
|
|
2136
|
+
interface TransportRegistration {
|
|
2137
|
+
/** Remove the transport from the registry and purge its remote handler entries. */
|
|
2138
|
+
unregister: () => void;
|
|
2139
|
+
/**
|
|
2140
|
+
* Resolves when initial subscribe synchronization is complete and requests
|
|
2141
|
+
* can safely route through this transport. Resolves immediately for
|
|
2142
|
+
* transports that do not implement `ready`.
|
|
2143
|
+
*/
|
|
2144
|
+
ready: Promise<void>;
|
|
2145
|
+
}
|
|
2146
|
+
/**
|
|
2147
|
+
* Options for {@link IMakaioBus.connect}.
|
|
2148
|
+
*/
|
|
2149
|
+
interface ConnectOptions {
|
|
2150
|
+
/**
|
|
2151
|
+
* Whether to await subscribe-sync readiness after connecting (default: `true`).
|
|
2152
|
+
*
|
|
2153
|
+
* When `true`, `connect()` resolves only after all transports have completed
|
|
2154
|
+
* the subscribe-sync handshake (`transport.ready`), guaranteeing
|
|
2155
|
+
* `remoteRequestHandlers` is fully populated before any request dispatch.
|
|
2156
|
+
*
|
|
2157
|
+
* Set to `false` to resolve as soon as sockets are open. Useful when the
|
|
2158
|
+
* caller needs the socket open for a custom handshake before subscribe-sync.
|
|
2159
|
+
* @defaultValue true
|
|
2160
|
+
*/
|
|
2161
|
+
awaitReady?: boolean;
|
|
2162
|
+
}
|
|
2163
|
+
type IMakaioBus<NamespaceDomain extends string | unknown = unknown, Subjects extends SubjectDefinition = SubjectDefinition, StrictNamespace = {
|
|
2164
|
+
$meta: {
|
|
2165
|
+
namespace: NamespaceDomain extends string ? NamespaceDomain : string;
|
|
2166
|
+
};
|
|
2167
|
+
}> = {
|
|
2168
|
+
namespace: NamespaceDomain;
|
|
2169
|
+
/**
|
|
2170
|
+
* Register an event or request handler.
|
|
2171
|
+
*
|
|
2172
|
+
* **Events:** Fire-and-forget - multiple handlers can listen and execute in parallel.
|
|
2173
|
+
* **Requests:** Request-response with middleware support - handlers form a chain.
|
|
2174
|
+
*
|
|
2175
|
+
* **Wildcard Support:** Use `.$all` property on subjects to match all subjects in a namespace.
|
|
2176
|
+
* Wildcard handlers receive `unknown` payload and must use type guards.
|
|
2177
|
+
* @param subject - SubjectDefinition object (exact or wildcard)
|
|
2178
|
+
* @param handler - Handler function (EventHandler for events, RequestHandler for requests)
|
|
2179
|
+
* @returns Unsubscribe function
|
|
2180
|
+
* @example Basic event handler with typed payload
|
|
2181
|
+
* ```typescript
|
|
2182
|
+
* const { subjects: AgentSubjects } = MakaioBus.registerNamespace('agent', {
|
|
2183
|
+
* started: z.object({ agentId: z.string() }),
|
|
2184
|
+
* });
|
|
2185
|
+
*
|
|
2186
|
+
* const unsubscribe = on(AgentSubjects.started, (context) => {
|
|
2187
|
+
* context.payload.agentId; // ✅ string - fully typed
|
|
2188
|
+
* console.debug('Agent started:', context.payload.agentId);
|
|
2189
|
+
* });
|
|
2190
|
+
* ```
|
|
2191
|
+
* @example Wildcard handlers for namespace-level events
|
|
2192
|
+
* ```typescript
|
|
2193
|
+
* // Matches all subjects in namespace
|
|
2194
|
+
* on(AgentSubjects.$all, (context) => {
|
|
2195
|
+
* context.payload; // unknown - must use type guards
|
|
2196
|
+
* if ('agentId' in context.payload) {
|
|
2197
|
+
* console.debug('Any agent event:', context.payload.agentId);
|
|
2198
|
+
* }
|
|
2199
|
+
* });
|
|
2200
|
+
* ```
|
|
2201
|
+
* @example Request handler with typed request/response
|
|
2202
|
+
* ```typescript
|
|
2203
|
+
* const { subjects: AgentSubjects } = MakaioBus.registerNamespace('agent', {
|
|
2204
|
+
* toolApprove: {
|
|
2205
|
+
* request: z.object({ toolName: z.string() }),
|
|
2206
|
+
* response: z.object({ approved: z.boolean() }),
|
|
2207
|
+
* },
|
|
2208
|
+
* });
|
|
2209
|
+
*
|
|
2210
|
+
* on(AgentSubjects.toolApprove, (context) => {
|
|
2211
|
+
* const { toolName } = context.payload; // ✅ fully typed
|
|
2212
|
+
* context.setResult({ approved: true });
|
|
2213
|
+
* });
|
|
2214
|
+
* ```
|
|
2215
|
+
* @example Middleware pattern for request chain
|
|
2216
|
+
* ```typescript
|
|
2217
|
+
* on(AgentSubjects.toolApprove, async (context) => {
|
|
2218
|
+
* console.debug('Before approval');
|
|
2219
|
+
* await context.next();
|
|
2220
|
+
* console.debug('After approval');
|
|
2221
|
+
* });
|
|
2222
|
+
* ```
|
|
2223
|
+
*/
|
|
2224
|
+
on<Subject extends Subjects & StrictNamespace, IsChannel = Subject['$meta']['channel']>(subject: IsChannel extends true ? never : Subject, handler: Subject extends SubjectDefinition ? HandlerForSubjectDefinition<Subject> : never, options?: OnOptions): () => void; /** Register an interceptor that runs BEFORE handlers (payload transform, blocking, priority). */
|
|
2225
|
+
intercept<Subject extends Subjects & StrictNamespace>(subject: Subject, handler: InterceptorHandler<Subject['$meta']['payload']>, options?: InterceptOptions): () => void;
|
|
2226
|
+
/**
|
|
2227
|
+
* Register a one-time event or request handler that auto-unsubscribes after first invocation.
|
|
2228
|
+
*
|
|
2229
|
+
* Wraps the `on()` method to automatically unsubscribe after the handler fires once.
|
|
2230
|
+
* The handler is removed BEFORE being invoked to prevent re-entrance issues if the
|
|
2231
|
+
* handler triggers the same event.
|
|
2232
|
+
*
|
|
2233
|
+
* **Events:** Fire-and-forget - handler executes once then auto-unsubscribes.
|
|
2234
|
+
* **Requests:** Request-response - handler executes once then auto-unsubscribes.
|
|
2235
|
+
*
|
|
2236
|
+
* **Wildcard Support:** Like `on()`, supports `.$all` property for namespace-level patterns.
|
|
2237
|
+
* @param subject - SubjectDefinition object (exact or wildcard)
|
|
2238
|
+
* @param handler - Handler function (EventHandler for events, RequestHandler for requests)
|
|
2239
|
+
* @returns Unsubscribe function for manual cleanup if needed
|
|
2240
|
+
* @example Basic one-time event handler
|
|
2241
|
+
* ```typescript
|
|
2242
|
+
* const { subjects: AgentSubjects } = MakaioBus.registerNamespace('agent', {
|
|
2243
|
+
* started: z.object({ agentId: z.string() }),
|
|
2244
|
+
* });
|
|
2245
|
+
*
|
|
2246
|
+
* once(AgentSubjects.started, (context) => {
|
|
2247
|
+
* context.payload.agentId; // ✅ string - fully typed
|
|
2248
|
+
* console.debug('Agent started once:', context.payload.agentId);
|
|
2249
|
+
* });
|
|
2250
|
+
*
|
|
2251
|
+
* await emit(AgentSubjects.started, { agentId: 'agent-123' }); // Handler fires
|
|
2252
|
+
* await emit(AgentSubjects.started, { agentId: 'agent-456' }); // Handler does NOT fire
|
|
2253
|
+
* ```
|
|
2254
|
+
* @example Manual unsubscribe before first fire
|
|
2255
|
+
* ```typescript
|
|
2256
|
+
* const unsubscribe = once(AgentSubjects.started, (context) => {
|
|
2257
|
+
* console.debug('This will never run');
|
|
2258
|
+
* });
|
|
2259
|
+
*
|
|
2260
|
+
* unsubscribe(); // Manually unsubscribe before event fires
|
|
2261
|
+
* await emit(AgentSubjects.started, { agentId: 'agent-123' }); // Handler does NOT fire
|
|
2262
|
+
* ```
|
|
2263
|
+
* @example Wildcard handler for one-time namespace monitoring
|
|
2264
|
+
* ```typescript
|
|
2265
|
+
* once(AgentSubjects.$all, (context) => {
|
|
2266
|
+
* context.payload; // unknown - must use type guards
|
|
2267
|
+
* console.debug('First agent event:', context.payload);
|
|
2268
|
+
* });
|
|
2269
|
+
* ```
|
|
2270
|
+
* @example One-time request handler
|
|
2271
|
+
* ```typescript
|
|
2272
|
+
* const { subjects: AgentSubjects } = MakaioBus.registerNamespace('agent', {
|
|
2273
|
+
* toolApprove: {
|
|
2274
|
+
* request: z.object({ toolName: z.string() }),
|
|
2275
|
+
* response: z.object({ approved: z.boolean() }),
|
|
2276
|
+
* },
|
|
2277
|
+
* });
|
|
2278
|
+
*
|
|
2279
|
+
* once(AgentSubjects.toolApprove, (context) => {
|
|
2280
|
+
* const { toolName } = context.payload; // ✅ fully typed
|
|
2281
|
+
* context.setResult({ approved: true });
|
|
2282
|
+
* });
|
|
2283
|
+
*
|
|
2284
|
+
* await request(AgentSubjects.toolApprove, { toolName: 'deleteFile' }); // Handler fires
|
|
2285
|
+
* await request(AgentSubjects.toolApprove, { toolName: 'createFile' }); // Handler does NOT fire
|
|
2286
|
+
* ```
|
|
2287
|
+
*/
|
|
2288
|
+
once<Subject extends Subjects & StrictNamespace, IsChannel = Subject['$meta']['channel']>(subject: IsChannel extends true ? never : Subject, handler: Subject extends SubjectDefinition ? HandlerForSubjectDefinition<Subject> : never): () => void;
|
|
2289
|
+
/**
|
|
2290
|
+
* Wait for an event to occur, returning a Promise.
|
|
2291
|
+
*
|
|
2292
|
+
* Note: Request subjects are not supported with the promise version of once().
|
|
2293
|
+
* Use the callback version for request handlers: `once(subject, handler)`
|
|
2294
|
+
* @param subject - Event SubjectDefinition object (exact or wildcard)
|
|
2295
|
+
* @param options - Options object with: timeoutMs (reject after timeout), filter (only resolve when filter returns true), signal (AbortSignal to cancel waiting)
|
|
2296
|
+
* @returns Promise that resolves with the event context
|
|
2297
|
+
* @example Simple await
|
|
2298
|
+
* ```typescript
|
|
2299
|
+
* const ctx = await bus.once(Subjects.init);
|
|
2300
|
+
* console.debug('Event received:', ctx.payload);
|
|
2301
|
+
* ```
|
|
2302
|
+
* @example With timeout
|
|
2303
|
+
* ```typescript
|
|
2304
|
+
* try {
|
|
2305
|
+
* const ctx = await bus.once(Subjects.init, { timeoutMs: 5000 });
|
|
2306
|
+
* } catch (err) {
|
|
2307
|
+
* if (err instanceof OnceTimeoutError) {
|
|
2308
|
+
* console.debug('Timed out waiting for event');
|
|
2309
|
+
* }
|
|
2310
|
+
* }
|
|
2311
|
+
* ```
|
|
2312
|
+
* @example With filter (waits for matching event)
|
|
2313
|
+
* ```typescript
|
|
2314
|
+
* const ctx = await bus.once(Subjects.message, {
|
|
2315
|
+
* filter: (payload) => payload.sessionId === expectedId
|
|
2316
|
+
* });
|
|
2317
|
+
* // Resolves only when a message with matching sessionId is received
|
|
2318
|
+
* ```
|
|
2319
|
+
* @example With AbortSignal
|
|
2320
|
+
* ```typescript
|
|
2321
|
+
* const controller = new AbortController();
|
|
2322
|
+
* const promise = bus.once(Subjects.init, { signal: controller.signal });
|
|
2323
|
+
* controller.abort(); // Cancels the wait
|
|
2324
|
+
* ```
|
|
2325
|
+
*/
|
|
2326
|
+
once<Subject extends Subjects & StrictNamespace, IsRequest = Subject['$meta']['isRequest'], IsChannel = Subject['$meta']['channel']>(subject: IsChannel extends true ? never : IsRequest extends false ? Subject : never, options?: Subject extends SubjectDefinition ? OnceOptions<Subject> : never): Promise<Subject extends SubjectDefinition ? Parameters<HandlerForSubjectDefinition<Subject>>[0] : never>;
|
|
2327
|
+
/**
|
|
2328
|
+
* Emit an event to all registered handlers.
|
|
2329
|
+
*
|
|
2330
|
+
* Events are fire-and-forget - all handlers execute in parallel.
|
|
2331
|
+
* Handler errors are logged but don't stop other handlers from executing.
|
|
2332
|
+
*
|
|
2333
|
+
* **Note:** You cannot emit to wildcard patterns. Use concrete subject keys only.
|
|
2334
|
+
* Handlers registered with wildcards will still receive the event if it matches.
|
|
2335
|
+
* @param subject - Concrete event subject (wildcards not allowed)
|
|
2336
|
+
* @param payload - Event payload
|
|
2337
|
+
* @param options - Emit options (messageId, correlationId, transports)
|
|
2338
|
+
*
|
|
2339
|
+
* ## Transport Routing
|
|
2340
|
+
* - `transports: undefined` - Send to ALL registered transports (default)
|
|
2341
|
+
* - `transports: []` - Local only, don't send to any transports
|
|
2342
|
+
* - `transports: ['ws', 'nats']` - Send only to specified transports
|
|
2343
|
+
* @example
|
|
2344
|
+
* ```typescript
|
|
2345
|
+
* const { subjects: AgentSubjects } = MakaioBus.registerNamespace('agent', {
|
|
2346
|
+
* started: z.object({ agentId: z.string() }),
|
|
2347
|
+
* });
|
|
2348
|
+
*
|
|
2349
|
+
* // Send to all transports (default)
|
|
2350
|
+
* await emit(AgentSubjects.started, { agentId: 'agent-123' });
|
|
2351
|
+
*
|
|
2352
|
+
* // Local only, no transports
|
|
2353
|
+
* await emit(
|
|
2354
|
+
* AgentSubjects.started,
|
|
2355
|
+
* { agentId: 'agent-123' },
|
|
2356
|
+
* { transports: [] }
|
|
2357
|
+
* );
|
|
2358
|
+
*
|
|
2359
|
+
* // Send to specific transports
|
|
2360
|
+
* await emit(
|
|
2361
|
+
* AgentSubjects.started,
|
|
2362
|
+
* { agentId: 'agent-123' },
|
|
2363
|
+
* { transports: ['websocket'] }
|
|
2364
|
+
* );
|
|
2365
|
+
*
|
|
2366
|
+
* // With tracking IDs:
|
|
2367
|
+
* await emit(
|
|
2368
|
+
* AgentSubjects.started,
|
|
2369
|
+
* { agentId: 'agent-123' },
|
|
2370
|
+
* { correlationId: 'user-action-123' }
|
|
2371
|
+
* );
|
|
2372
|
+
* ```
|
|
2373
|
+
*/
|
|
2374
|
+
emit<Subject extends Subjects & StrictNamespace, IsRequest = Subject['$meta']['isRequest'], IsWildcard = (Subject['subject'] extends WildcardSubject ? true : false), IsChannel = Subject['$meta']['channel']>(subject: IsChannel extends true ? never : IsRequest extends false ? IsWildcard extends false ? Subject : never : never, payload: Subject['$meta']['payload'], options?: EmitOptions): Promise<void>;
|
|
2375
|
+
/**
|
|
2376
|
+
* Execute a request and wait for a response.
|
|
2377
|
+
*
|
|
2378
|
+
* Requests follow a middleware chain pattern - handlers are called in order
|
|
2379
|
+
* until one calls setResult() or all handlers complete.
|
|
2380
|
+
*
|
|
2381
|
+
* **Note:** You cannot request via wildcard patterns. Use concrete subject keys only.
|
|
2382
|
+
* Handlers registered with wildcards will still match if the subject matches their pattern.
|
|
2383
|
+
* @param subject - Concrete request subject (wildcards not allowed)
|
|
2384
|
+
* @param payload - Request payload
|
|
2385
|
+
* @param options - Request options (timeout, correlationId, transports)
|
|
2386
|
+
* @returns Response value
|
|
2387
|
+
* @throws \{NoHandlerError\} If no handler is registered
|
|
2388
|
+
* @throws \{TimeoutError\} If request times out
|
|
2389
|
+
* @throws \{ValidationError\} If payload validation fails
|
|
2390
|
+
* @throws \{RequestError\} If handler throws an error
|
|
2391
|
+
*
|
|
2392
|
+
* ## Transport Routing
|
|
2393
|
+
* - `transports: undefined` - Send to ALL registered transports (default)
|
|
2394
|
+
* - `transports: []` - Local only, don't send to any transports
|
|
2395
|
+
* - `transports: ['ws', 'nats']` - Send only to specified transports
|
|
2396
|
+
* @example
|
|
2397
|
+
* ```typescript
|
|
2398
|
+
* // ✅ Concrete subject
|
|
2399
|
+
* const result = await request(
|
|
2400
|
+
* AgentSubjects.toolApprove,
|
|
2401
|
+
* { toolName: 'deleteFile', args: {}, toolCallId: 'call_123' },
|
|
2402
|
+
* { timeout: 10000 }
|
|
2403
|
+
* );
|
|
2404
|
+
* console.debug(result.approved);
|
|
2405
|
+
*
|
|
2406
|
+
* // ❌ Cannot use wildcards
|
|
2407
|
+
* // await request('agent.*', { ... }); // Type error
|
|
2408
|
+
*
|
|
2409
|
+
* // With specific transports
|
|
2410
|
+
* const result = await request(
|
|
2411
|
+
* AgentSubjects.toolApprove,
|
|
2412
|
+
* { toolName: 'deleteFile', args: {}, toolCallId: 'call_123' },
|
|
2413
|
+
* { transports: ['websocket'], timeout: 10000 }
|
|
2414
|
+
* );
|
|
2415
|
+
* ```
|
|
2416
|
+
*/
|
|
2417
|
+
request<Subject extends Subjects & StrictNamespace, IsRequest = Subject['$meta']['isRequest'], IsChannel = Subject['$meta']['channel']>(subject: IsChannel extends true ? never : IsRequest extends true ? Subject : never, payload: Subject['$meta']['payload']['request'], options?: RequestOptions): Promise<IsRequest extends true ? Subject['$meta']['payload']['response'] : never>;
|
|
2418
|
+
/**
|
|
2419
|
+
* Execute a request, returning a discriminated union instead of throwing for missing handlers.
|
|
2420
|
+
*
|
|
2421
|
+
* Use for optional services. Only NoHandlerError is caught - other errors propagate.
|
|
2422
|
+
* @see {@link OptionalResult} for return type details
|
|
2423
|
+
*/
|
|
2424
|
+
requestOptional<Subject extends Subjects & StrictNamespace, IsRequest = Subject['$meta']['isRequest'], IsChannel = Subject['$meta']['channel']>(subject: IsChannel extends true ? never : IsRequest extends true ? Subject : never, payload: Subject['$meta']['payload']['request'], options?: RequestOptions): Promise<OptionalResult<IsRequest extends true ? Subject['$meta']['payload']['response'] : never>>;
|
|
2425
|
+
/**
|
|
2426
|
+
* Execute a broadcast request and collect responses from ALL handlers.
|
|
2427
|
+
*
|
|
2428
|
+
* Unlike `request()` which uses a middleware chain and returns the first result,
|
|
2429
|
+
* `broadcast()` executes all handlers in parallel and aggregates their responses.
|
|
2430
|
+
*
|
|
2431
|
+
* Use for discovery patterns where multiple nodes may respond (e.g., fs.listSources).
|
|
2432
|
+
*
|
|
2433
|
+
* **Note:** You cannot broadcast via wildcard patterns. Use concrete subject keys only.
|
|
2434
|
+
* Handlers registered with wildcards will still match if the subject matches their pattern.
|
|
2435
|
+
*
|
|
2436
|
+
* **Handler Usage:**
|
|
2437
|
+
* Handlers should call `ctx.identify(nodeId)` before `ctx.setResult()` to tag their response.
|
|
2438
|
+
* If `identify()` is not called, the response is tagged as 'anonymous'.
|
|
2439
|
+
* @param subject - Concrete request subject (wildcards not allowed)
|
|
2440
|
+
* @param payload - Request payload
|
|
2441
|
+
* @param options - Request options (timeout, correlationId)
|
|
2442
|
+
* @returns Array of \{ nodeId, payload \} responses from all handlers
|
|
2443
|
+
* @example
|
|
2444
|
+
* ```typescript
|
|
2445
|
+
* // Discover all filesystem sources from all nodes
|
|
2446
|
+
* const results = await MakaioBus.broadcast(FileSystemSubjects.listSources, \{\});
|
|
2447
|
+
* // results: [
|
|
2448
|
+
* // \{ nodeId: 'local', payload: \{ sources: [...] \} \},
|
|
2449
|
+
* // \{ nodeId: 'container-1', payload: \{ sources: [...] \} \},
|
|
2450
|
+
* // ]
|
|
2451
|
+
*
|
|
2452
|
+
* // Aggregate sources
|
|
2453
|
+
* const allSources = results.flatMap(r => r.payload.sources);
|
|
2454
|
+
* ```
|
|
2455
|
+
*/
|
|
2456
|
+
broadcast<Subject extends Subjects & StrictNamespace, IsRequest = Subject['$meta']['isRequest'], IsChannel = Subject['$meta']['channel']>(subject: IsChannel extends true ? never : IsRequest extends true ? Subject : never, payload: Subject['$meta']['payload']['request'], options?: RequestOptions): Promise<BroadcastResult<IsRequest extends true ? Subject['$meta']['payload']['response'] : never>[]>;
|
|
2457
|
+
scoped: <Domain extends string, Subjects extends SubjectRecord, F, Sc extends Record<string, SubjectSchema>>(input: BusNamespace<Domain, Subjects, F, Sc>, context?: MakaioBusContext) => ScopedBus<Domain>;
|
|
2458
|
+
/**
|
|
2459
|
+
* Create a filtered bus with a base payload filter.
|
|
2460
|
+
*
|
|
2461
|
+
* The filter is automatically applied to all `on()` and `once()` calls.
|
|
2462
|
+
*
|
|
2463
|
+
* Optionally provide a type parameter for type-safe filter keys.
|
|
2464
|
+
* @param filter - Base filter to apply to all subscriptions
|
|
2465
|
+
* @returns FilteredBus with the specified filter
|
|
2466
|
+
* @example
|
|
2467
|
+
* ```typescript
|
|
2468
|
+
* // Untyped (loose) - any keys allowed
|
|
2469
|
+
* const agentBus = MakaioBus.withFilter({ agentId: this.agentId });
|
|
2470
|
+
*
|
|
2471
|
+
* // Type-safe filter keys
|
|
2472
|
+
* interface AgentPayload { agentId: string; sessionId: string }
|
|
2473
|
+
* const strictBus = MakaioBus.withFilter<AgentPayload>({ agentId: 'x' });
|
|
2474
|
+
* ```
|
|
2475
|
+
*/
|
|
2476
|
+
withFilter: <Payload = unknown>(filter: [unknown] extends [Payload] ? PayloadFilter : TypedPayloadFilter<Payload>) => IFilteredBus<NamespaceDomain extends string ? NamespaceDomain : string>;
|
|
2477
|
+
/**
|
|
2478
|
+
* Register a production-capable local message observer.
|
|
2479
|
+
*
|
|
2480
|
+
* Observers receive local `emit`, `request`, and `broadcast` API calls after
|
|
2481
|
+
* message validation has succeeded. Observers must not mutate the payload.
|
|
2482
|
+
* Unlike `__onAny`, this is not debug-only and is safe for runtime telemetry services.
|
|
2483
|
+
* @param observer - Observer callback.
|
|
2484
|
+
* @returns Cleanup function that unregisters the observer.
|
|
2485
|
+
* @example
|
|
2486
|
+
* ```typescript
|
|
2487
|
+
* const dispose = bus.observeMessages((message) => {
|
|
2488
|
+
* console.debug(`[${message.type}] ${message.namespace}.${message.subject}`);
|
|
2489
|
+
* });
|
|
2490
|
+
* ```
|
|
2491
|
+
*/
|
|
2492
|
+
observeMessages(observer: BusMessageObserver): () => void;
|
|
2493
|
+
/**
|
|
2494
|
+
* Register a handler that receives ALL messages (events and requests) across all namespaces.
|
|
2495
|
+
*
|
|
2496
|
+
* **Debugging/Testing Only:** Noops in production (process.env.NODE_ENV === 'production').
|
|
2497
|
+
* Useful for logging, debugging, and test assertions that need visibility into all bus activity.
|
|
2498
|
+
*
|
|
2499
|
+
* Handler receives complete metadata: type, subject, namespace, payload, messageId, correlationId.
|
|
2500
|
+
* @param handler - Function to invoke for every message
|
|
2501
|
+
* @returns Unsubscribe function (noop in production)
|
|
2502
|
+
* @example
|
|
2503
|
+
* ```typescript
|
|
2504
|
+
* const unsubscribe = bus.__onAny((context) => {
|
|
2505
|
+
* console.debug(`[${context.type}] ${context.namespace}:${context.subject}`, context.payload);
|
|
2506
|
+
* });
|
|
2507
|
+
* ```
|
|
2508
|
+
*/
|
|
2509
|
+
__onAny: (handler: AnyHandler) => () => void;
|
|
2510
|
+
__resetHandlers?: () => void;
|
|
2511
|
+
/**
|
|
2512
|
+
* Register a transport by its name property.
|
|
2513
|
+
*
|
|
2514
|
+
* Convenience method that delegates to `getContext().transportRegistry.registerTransport()`.
|
|
2515
|
+
* The transport's `name` property is used as the registry key.
|
|
2516
|
+
* @param transport - Transport to register
|
|
2517
|
+
* @returns Registration object with `unregister` and `ready` promise
|
|
2518
|
+
*/
|
|
2519
|
+
registerTransport(transport: BusTransport): TransportRegistration;
|
|
2520
|
+
/**
|
|
2521
|
+
* Unregister a transport by name.
|
|
2522
|
+
*
|
|
2523
|
+
* No-op if no transport is registered under that name.
|
|
2524
|
+
* @param name - Transport name to unregister
|
|
2525
|
+
*/
|
|
2526
|
+
unregisterTransport(name: string): void;
|
|
2527
|
+
/**
|
|
2528
|
+
* Disconnect all registered transports and clear the transport map.
|
|
2529
|
+
*
|
|
2530
|
+
* Convenience method for tearing down a bus instance. The inverse of
|
|
2531
|
+
* passing `transports` to `createBusInstance()` or calling
|
|
2532
|
+
* `registerTransport()` individually.
|
|
2533
|
+
*/
|
|
2534
|
+
disconnect(): void;
|
|
2535
|
+
/**
|
|
2536
|
+
* Trigger an immediate reconnection attempt on all disconnected transports.
|
|
2537
|
+
*
|
|
2538
|
+
* Delegates to each transport's `reconnect()` method if available. For
|
|
2539
|
+
* transports with exponential-backoff reconnection (e.g. WebSocket), this
|
|
2540
|
+
* wakes the backoff sleep and returns once the attempt is *initiated* — not
|
|
2541
|
+
* once the connection is established. For one-shot transports it resolves
|
|
2542
|
+
* after the connect attempt completes. Failures are logged but do not reject
|
|
2543
|
+
* this promise. No-op when all transports are already connected.
|
|
2544
|
+
*/
|
|
2545
|
+
reconnect(): Promise<void>;
|
|
2546
|
+
/**
|
|
2547
|
+
* Resolves when all transports registered at connect-time have completed
|
|
2548
|
+
* subscribe-sync. If {@link connect} was called with the default `awaitReady: true`,
|
|
2549
|
+
* this is already resolved when `connect()` returns. If `awaitReady: false` was used,
|
|
2550
|
+
* await this to ensure readiness before dispatching requests.
|
|
2551
|
+
*
|
|
2552
|
+
* Resolves immediately if no transports are registered or `connect()` has not been called.
|
|
2553
|
+
*/
|
|
2554
|
+
readonly ready: Promise<void>;
|
|
2555
|
+
/**
|
|
2556
|
+
* Connect all registered transports and optionally await subscribe-sync readiness.
|
|
2557
|
+
*
|
|
2558
|
+
* Calls `transport.connect()` on every transport registered by this bus instance.
|
|
2559
|
+
* If any transport fails to connect, all transports are disconnected and unregistered
|
|
2560
|
+
* (rollback) before the error is re-thrown. Pass `{ awaitReady: false }` to resolve
|
|
2561
|
+
* as soon as sockets are open without waiting for the subscribe-sync handshake.
|
|
2562
|
+
* Concurrent calls are safe — a second in-flight call awaits the same promise. Once
|
|
2563
|
+
* sockets are open, subsequent calls are no-ops unless a prior
|
|
2564
|
+
* `connect({ awaitReady: false })` left the readiness handshake pending; in that case,
|
|
2565
|
+
* default `connect()` still awaits `bus.ready`.
|
|
2566
|
+
* @param options - Connection options (see {@link ConnectOptions})
|
|
2567
|
+
* @throws If any transport's `connect()` or `ready` promise rejects (after rollback)
|
|
2568
|
+
*/
|
|
2569
|
+
connect(options?: ConnectOptions): Promise<void>;
|
|
2570
|
+
getContext(): MakaioBusContext;
|
|
2571
|
+
/**
|
|
2572
|
+
* Register a namespace from a `BusNamespaceDefinition` created by `createBusNamespace()`.
|
|
2573
|
+
*
|
|
2574
|
+
* Returns a `BusNamespace` that extends the definition with a `scopedBus()` method.
|
|
2575
|
+
* @param definition - Namespace definition created by `createBusNamespace()` from `@makaio/core`
|
|
2576
|
+
* @returns Registered namespace with `scopedBus()` and pre-computed FilterPayload type
|
|
2577
|
+
*/
|
|
2578
|
+
registerNamespace<Domain extends string, Schemas extends Record<string, SubjectSchema>>(definition: BusNamespaceDefinition<Domain, Schemas>): BusNamespace<Domain, SubjectRecordFromSchemaRecord<Schemas>, FilterablePayloadIntersection<SubjectRecordFromSchemaRecord<Schemas>>, Schemas>;
|
|
2579
|
+
/**
|
|
2580
|
+
* Register multiple namespaces in a single call.
|
|
2581
|
+
*
|
|
2582
|
+
* Convenience wrapper for composition roots that register a catalog of namespaces at boot:
|
|
2583
|
+
* ```typescript
|
|
2584
|
+
* MakaioBus.registerNamespaces(FrameworkContractNamespaces);
|
|
2585
|
+
* ```
|
|
2586
|
+
* @param definitions - Array of namespace definitions to register
|
|
2587
|
+
*/
|
|
2588
|
+
registerNamespaces(definitions: readonly RegistrableBusNamespaceDefinition[]): void; /** Get the schema for a registered subject, or undefined if not found. */
|
|
2589
|
+
getSchema<T extends SubjectDefinition>(subject: T | string): SubjectSchema | undefined;
|
|
2590
|
+
/**
|
|
2591
|
+
* Extend a registered subject's schema with additional fields.
|
|
2592
|
+
*
|
|
2593
|
+
* Adds new root-level fields to the Zod schema used for dev-mode validation and
|
|
2594
|
+
* widens the TypeScript payload type. Successive calls accumulate — two packages
|
|
2595
|
+
* can independently extend the same subject without overwriting each other.
|
|
2596
|
+
*
|
|
2597
|
+
* The returned value is the same runtime SubjectDefinition object — only the
|
|
2598
|
+
* TypeScript type is widened. Bus routing is unaffected.
|
|
2599
|
+
* @param subject - SubjectDefinition from a registered namespace
|
|
2600
|
+
* @param extensions - For request subjects: `{ request?: { field: z.string() }, response?: {...} }`.
|
|
2601
|
+
* For event subjects: `{ field: z.string() }` (flat record of additional Zod fields).
|
|
2602
|
+
* @returns The same SubjectDefinition with wider TypeScript types
|
|
2603
|
+
*/
|
|
2604
|
+
extendSubject<SD extends Subjects & StrictNamespace, Ext extends SubjectExtension<SD>>(subject: SD, extensions: Ext): ExtendedSubjectDefinition<SD, Ext>;
|
|
2605
|
+
};
|
|
2606
|
+
//#endregion
|
|
2607
|
+
//#region core/bus-core/src/utils/correlation-tracker.d.ts
|
|
2608
|
+
/**
|
|
2609
|
+
* Correlation tracker for request-response matching.
|
|
2610
|
+
*
|
|
2611
|
+
* Manages pending requests with timeout handling and automatic cleanup.
|
|
2612
|
+
*/
|
|
2613
|
+
/**
|
|
2614
|
+
* Tracks correlation IDs for request-response matching.
|
|
2615
|
+
*
|
|
2616
|
+
* Provides automatic timeout handling and cleanup for pending requests.
|
|
2617
|
+
* @example
|
|
2618
|
+
* ```typescript
|
|
2619
|
+
* const tracker = new CorrelationTracker();
|
|
2620
|
+
*
|
|
2621
|
+
* // Track a request with 5 second timeout
|
|
2622
|
+
* const promise = tracker.track('correlation-123', 5000);
|
|
2623
|
+
*
|
|
2624
|
+
* // Later, resolve when response arrives
|
|
2625
|
+
* tracker.resolve('correlation-123', { data: 'result' });
|
|
2626
|
+
*
|
|
2627
|
+
* // Or reject on error
|
|
2628
|
+
* tracker.reject('correlation-123', new Error('Failed'));
|
|
2629
|
+
* ```
|
|
2630
|
+
*/
|
|
2631
|
+
declare class CorrelationTracker {
|
|
2632
|
+
private pending;
|
|
2633
|
+
private static readonly DEFAULT_ABORT_MESSAGE;
|
|
2634
|
+
/**
|
|
2635
|
+
* Create a new correlation tracker.
|
|
2636
|
+
*/
|
|
2637
|
+
constructor();
|
|
2638
|
+
/**
|
|
2639
|
+
* Track a pending request.
|
|
2640
|
+
*
|
|
2641
|
+
* Returns a promise that resolves when the response arrives or rejects on timeout.
|
|
2642
|
+
* When `timeout` is `0`, no automatic timeout is set — the promise stays open
|
|
2643
|
+
* until `resolve()` or `reject()` is called externally (e.g. by the caller's
|
|
2644
|
+
* own `AbortSignal` or `pTimeout` wrapper).
|
|
2645
|
+
* @param correlationId - Correlation ID for the request
|
|
2646
|
+
* @param timeout - Timeout in milliseconds; `0` means no automatic timeout
|
|
2647
|
+
* @param signal - Optional AbortSignal to cancel and cleanup the pending entry
|
|
2648
|
+
* @returns Promise that resolves with the response result
|
|
2649
|
+
*/
|
|
2650
|
+
track(correlationId: string, timeout: number, signal?: AbortSignal): Promise<unknown>;
|
|
2651
|
+
/**
|
|
2652
|
+
* Convert AbortSignal reasons into Error instances while preserving reason detail.
|
|
2653
|
+
* @param signal - Abort signal associated with the pending request.
|
|
2654
|
+
* @returns Normalized abort error preserving the original reason when available.
|
|
2655
|
+
*/
|
|
2656
|
+
private getAbortError;
|
|
2657
|
+
/**
|
|
2658
|
+
* Resolve a pending request.
|
|
2659
|
+
*
|
|
2660
|
+
* Clears the timeout and removes the request from tracking.
|
|
2661
|
+
* @param correlationId - Correlation ID for the request
|
|
2662
|
+
* @param result - Response result
|
|
2663
|
+
*/
|
|
2664
|
+
resolve(correlationId: string, result: unknown): void;
|
|
2665
|
+
/**
|
|
2666
|
+
* Reject a pending request.
|
|
2667
|
+
*
|
|
2668
|
+
* Clears the timeout and removes the request from tracking.
|
|
2669
|
+
* @param correlationId - Correlation ID for the request
|
|
2670
|
+
* @param error - Error to reject with
|
|
2671
|
+
*/
|
|
2672
|
+
reject(correlationId: string, error: Error): void;
|
|
2673
|
+
/**
|
|
2674
|
+
* Cancel a pending request and remove its correlation entry.
|
|
2675
|
+
* @param correlationId - Correlation ID for the request
|
|
2676
|
+
* @param error - Optional cancellation error
|
|
2677
|
+
*/
|
|
2678
|
+
cancel(correlationId: string, error?: Error): void;
|
|
2679
|
+
/**
|
|
2680
|
+
* Clean up all pending requests.
|
|
2681
|
+
*
|
|
2682
|
+
* Clears all timeouts and rejects all pending requests with a disconnection error.
|
|
2683
|
+
*/
|
|
2684
|
+
cleanup(): void;
|
|
2685
|
+
}
|
|
2686
|
+
//#endregion
|
|
2687
|
+
//#region core/bus-core/src/utils/transport-helpers.d.ts
|
|
2688
|
+
/**
|
|
2689
|
+
* Singleton frozen origin for messages emitted within the current process.
|
|
2690
|
+
*
|
|
2691
|
+
* Shared across `emit`, `broadcast`, and `dispatch` to avoid a per-message
|
|
2692
|
+
* allocation on the hot path. Both variants are frozen to prevent accidental
|
|
2693
|
+
* mutation since they are module-level constants.
|
|
2694
|
+
*/
|
|
2695
|
+
declare const LOCAL_ORIGIN: MessageOrigin;
|
|
2696
|
+
/**
|
|
2697
|
+
* Singleton frozen origin for messages that arrived via a transport.
|
|
2698
|
+
*
|
|
2699
|
+
* Used by `emit`, `broadcast`, and `dispatch` when a `TransportReceiveContext`
|
|
2700
|
+
* is present (i.e. the message was forwarded from a remote caller).
|
|
2701
|
+
*/
|
|
2702
|
+
declare const REMOTE_ORIGIN: MessageOrigin;
|
|
2703
|
+
/**
|
|
2704
|
+
* Check if a client/tab wants to receive a message based on subscriptions and filters.
|
|
2705
|
+
*
|
|
2706
|
+
* **Filtering logic:**
|
|
2707
|
+
* - No subscriptions = receive all (default broadcast mode)
|
|
2708
|
+
* - With subscriptions: check if message subject matches any subscription pattern
|
|
2709
|
+
* - Apply payload filters if the client has filters for this subject
|
|
2710
|
+
* @param subject - The message subject (if any)
|
|
2711
|
+
* @param payload - The message payload (if any)
|
|
2712
|
+
* @param subscriptions - Set of subscription patterns
|
|
2713
|
+
* @param filters - Map of payload filters per subject
|
|
2714
|
+
* @returns true if the client should receive the message
|
|
2715
|
+
*/
|
|
2716
|
+
declare function shouldReceiveMessage(subject: string | undefined, payload: unknown, subscriptions: Set<string>, filters: Map<string, PayloadFilter>): boolean;
|
|
2717
|
+
/**
|
|
2718
|
+
* Handle response messages for correlation tracking.
|
|
2719
|
+
*
|
|
2720
|
+
* Processes both regular response and broadcast-response messages,
|
|
2721
|
+
* resolving or rejecting the corresponding correlation promise.
|
|
2722
|
+
* @param message - Decoded bus message
|
|
2723
|
+
* @param correlations - Correlation tracker instance
|
|
2724
|
+
* @returns true if the message was a response and was handled
|
|
2725
|
+
*/
|
|
2726
|
+
declare function handleCorrelationResponse(message: BusMessage, correlations: CorrelationTracker): boolean;
|
|
2727
|
+
/**
|
|
2728
|
+
* Track correlation for request/broadcast messages and return appropriate result type.
|
|
2729
|
+
*
|
|
2730
|
+
* **Behavior by message type:**
|
|
2731
|
+
* - Request: Returns promise tracking correlation (resolves to response payload)
|
|
2732
|
+
* - Broadcast: Returns promise tracking correlation (resolves to array of results)
|
|
2733
|
+
* - Other: Returns true immediately (no correlation tracking needed)
|
|
2734
|
+
*
|
|
2735
|
+
* **Timeout semantics:**
|
|
2736
|
+
* Pass `0` to disable automatic timeout — the correlation entry stays open
|
|
2737
|
+
* until resolved or rejected externally. All callers must supply an explicit
|
|
2738
|
+
* value; there is no default so callers cannot accidentally rely on a hidden timeout.
|
|
2739
|
+
* @param message - Bus message to process
|
|
2740
|
+
* @param correlations - Correlation tracker instance
|
|
2741
|
+
* @param timeout - Timeout in milliseconds; `0` means no automatic timeout
|
|
2742
|
+
* @param signal - Optional AbortSignal forwarded to correlation tracking cleanup
|
|
2743
|
+
* @returns Promise resolving to response data, broadcast results, or boolean
|
|
2744
|
+
*/
|
|
2745
|
+
declare function trackMessageCorrelation<TMessage extends BusMessage>(message: TMessage, correlations: CorrelationTracker, timeout: number, signal?: AbortSignal): Promise<TMessage extends BusRequestMessage ? unknown : TMessage extends BusBroadcastMessage ? Array<{
|
|
2746
|
+
nodeId: string;
|
|
2747
|
+
payload: unknown;
|
|
2748
|
+
}> : boolean>;
|
|
2749
|
+
/**
|
|
2750
|
+
* Serialize an error into a transport-safe structure.
|
|
2751
|
+
*
|
|
2752
|
+
* Preserves `subject` alongside `code` so that `isNoHandlerErrorForSubject`
|
|
2753
|
+
* can match deserialized errors without fragile message-string comparisons.
|
|
2754
|
+
* @param error - The error to serialize
|
|
2755
|
+
* @returns Structured error payload
|
|
2756
|
+
*/
|
|
2757
|
+
declare function serializeTransportError(error: unknown): BusTransportError;
|
|
2758
|
+
//#endregion
|
|
2759
|
+
//#region core/bus-core/src/utils/transport.d.ts
|
|
2760
|
+
/**
|
|
2761
|
+
* Detects a "no handler" error for a specific request subject.
|
|
2762
|
+
*
|
|
2763
|
+
* Works for both in-process {@link NoHandlerError} instances and deserialized
|
|
2764
|
+
* errors that carry a `code` + `subject` after a transport round-trip.
|
|
2765
|
+
* The `subject` field is preserved by transport error serialization, so no
|
|
2766
|
+
* fragile message-string matching is needed.
|
|
2767
|
+
* @param error - Error from a relayed request or transport response
|
|
2768
|
+
* @param fullSubject - Full request subject key (namespace.subject)
|
|
2769
|
+
* @returns True when the error indicates no local handler for this subject
|
|
2770
|
+
*/
|
|
2771
|
+
declare function isNoHandlerErrorForSubject(error: unknown, fullSubject: string): boolean;
|
|
2772
|
+
/**
|
|
2773
|
+
* Extracts the full subject key from a bus message.
|
|
2774
|
+
*
|
|
2775
|
+
* Combines the namespace and subject into the full subject key format
|
|
2776
|
+
* (namespace.subject) used for handler lookups and subscription matching.
|
|
2777
|
+
* Returns null if the message doesn't contain the required fields.
|
|
2778
|
+
* @param message - Bus message (event or request)
|
|
2779
|
+
* @returns Full subject key in format "namespace.subject", or null if fields are missing
|
|
2780
|
+
* @example
|
|
2781
|
+
* ```typescript
|
|
2782
|
+
* const message: BusMessage = {
|
|
2783
|
+
* type: 'event',
|
|
2784
|
+
* subject: 'log',
|
|
2785
|
+
* namespace: 'adapter',
|
|
2786
|
+
* payload: { message: 'Hello' },
|
|
2787
|
+
* messageId: 'msg-123',
|
|
2788
|
+
* };
|
|
2789
|
+
*
|
|
2790
|
+
* const fullSubject = getSubjectFromBusMessage(message);
|
|
2791
|
+
* // Returns: "adapter.log"
|
|
2792
|
+
* ```
|
|
2793
|
+
*/
|
|
2794
|
+
declare function getSubjectFromBusMessage(message: BusMessage): string | null;
|
|
2795
|
+
/**
|
|
2796
|
+
* Reconstruct an Error from a structured transport error payload.
|
|
2797
|
+
*
|
|
2798
|
+
* Preserves `code` and arbitrary `data` properties so callers can
|
|
2799
|
+
* inspect them for programmatic error handling.
|
|
2800
|
+
* @param transportError - The structured error received over the wire
|
|
2801
|
+
* @returns An Error with `code` and data properties attached
|
|
2802
|
+
*/
|
|
2803
|
+
declare function deserializeTransportError(transportError: BusTransportError): Error;
|
|
2804
|
+
//#endregion
|
|
2805
|
+
//#region core/bus-core/src/utils/payload-filter.d.ts
|
|
2806
|
+
/**
|
|
2807
|
+
* Get a nested value from an object using dot-notation path.
|
|
2808
|
+
* @param obj - Object to traverse
|
|
2809
|
+
* @param path - Dot-notation path (e.g., 'raw.msg.type')
|
|
2810
|
+
* @returns Value at path, or undefined if not found
|
|
2811
|
+
* @example
|
|
2812
|
+
* ```typescript
|
|
2813
|
+
* const obj = { raw: { msg: { type: 'event' } } };
|
|
2814
|
+
* getPath(obj, 'raw.msg.type'); // 'event'
|
|
2815
|
+
* getPath(obj, 'raw.missing'); // undefined
|
|
2816
|
+
* ```
|
|
2817
|
+
*/
|
|
2818
|
+
declare function getPath(obj: unknown, path: string): unknown;
|
|
2819
|
+
/**
|
|
2820
|
+
* Check if a payload matches all filter conditions.
|
|
2821
|
+
*
|
|
2822
|
+
* All conditions are ANDed together - all must match for the filter to pass.
|
|
2823
|
+
* @param payload - Message payload to check
|
|
2824
|
+
* @param filter - Filter specification with field paths and operators
|
|
2825
|
+
* @returns true if payload matches all filter conditions
|
|
2826
|
+
* @example
|
|
2827
|
+
* ```typescript
|
|
2828
|
+
* const payload = {
|
|
2829
|
+
* agentId: 'agent-123',
|
|
2830
|
+
* raw: { msg: { type: 'session_configured' } },
|
|
2831
|
+
* status: 'active',
|
|
2832
|
+
* };
|
|
2833
|
+
*
|
|
2834
|
+
* // All conditions must match
|
|
2835
|
+
* matchesFilter(payload, {
|
|
2836
|
+
* agentId: 'agent-123',
|
|
2837
|
+
* 'raw.msg.type': 'session_configured',
|
|
2838
|
+
* }); // true
|
|
2839
|
+
*
|
|
2840
|
+
* // With operators
|
|
2841
|
+
* matchesFilter(payload, {
|
|
2842
|
+
* status: { $in: ['active', 'pending'] },
|
|
2843
|
+
* }); // true
|
|
2844
|
+
*
|
|
2845
|
+
* matchesFilter(payload, {
|
|
2846
|
+
* error: { $exists: false },
|
|
2847
|
+
* }); // true (no error field)
|
|
2848
|
+
* ```
|
|
2849
|
+
*/
|
|
2850
|
+
declare function matchesFilter(payload: unknown, filter: PayloadFilter): boolean;
|
|
2851
|
+
/**
|
|
2852
|
+
* Merge two payload filters together.
|
|
2853
|
+
*
|
|
2854
|
+
* Later filter values override earlier ones for the same path.
|
|
2855
|
+
* @param base - Base filter
|
|
2856
|
+
* @param override - Filter to merge in (overrides base)
|
|
2857
|
+
* @returns Merged filter
|
|
2858
|
+
*/
|
|
2859
|
+
declare function mergeFilters(base: PayloadFilter | undefined, override: PayloadFilter | undefined): PayloadFilter | undefined;
|
|
2860
|
+
//#endregion
|
|
2861
|
+
//#region core/bus-core/src/utils/url-config.d.ts
|
|
2862
|
+
/**
|
|
2863
|
+
* Bus URL configuration utilities.
|
|
2864
|
+
*
|
|
2865
|
+
* Provides consistent parsing of bus URL environment variables across
|
|
2866
|
+
* all consumers (Electron, Vite configs, etc.) with correct handling of:
|
|
2867
|
+
*
|
|
2868
|
+
* - Default localhost development URLs (explicit port 6252)
|
|
2869
|
+
* - User-provided production URLs (preserve protocol defaults like wss:// to 443)
|
|
2870
|
+
*/
|
|
2871
|
+
/**
|
|
2872
|
+
* Parsed bus URL configuration.
|
|
2873
|
+
*/
|
|
2874
|
+
interface BusUrlConfig {
|
|
2875
|
+
/**
|
|
2876
|
+
* The full URL href for client connections.
|
|
2877
|
+
* For default localhost, includes explicit port.
|
|
2878
|
+
* For user-provided URLs, preserves original (protocol defaults intact).
|
|
2879
|
+
*/
|
|
2880
|
+
href: string;
|
|
2881
|
+
/**
|
|
2882
|
+
* The port number for server binding.
|
|
2883
|
+
* - For default localhost: 6252
|
|
2884
|
+
* - For user-provided URLs with explicit port: that port
|
|
2885
|
+
* - For user-provided URLs without port: undefined (use protocol default)
|
|
2886
|
+
*/
|
|
2887
|
+
port: number | undefined;
|
|
2888
|
+
/**
|
|
2889
|
+
* Whether this is the default localhost URL (no env var set).
|
|
2890
|
+
*/
|
|
2891
|
+
isDefault: boolean;
|
|
2892
|
+
}
|
|
2893
|
+
/**
|
|
2894
|
+
* Parses the bus URL from environment variable with correct default handling.
|
|
2895
|
+
*
|
|
2896
|
+
* Key behaviors:
|
|
2897
|
+
* - No env var: Returns default `ws://localhost:6252/bus` with explicit port 6252
|
|
2898
|
+
* - Env var with explicit port: Uses that port
|
|
2899
|
+
* - Env var without port (e.g., `wss://bus.example.com/bus`): Preserves URL as-is,
|
|
2900
|
+
* returns `port: undefined` so protocol defaults (443 for wss://) are respected
|
|
2901
|
+
* @param envValue - The value of MAKAIO_BUS_URL environment variable (or undefined)
|
|
2902
|
+
* @returns Parsed configuration with href, port, and isDefault flag
|
|
2903
|
+
* @example
|
|
2904
|
+
* ```typescript
|
|
2905
|
+
* // No env var - local development
|
|
2906
|
+
* const config = parseBusUrl(undefined);
|
|
2907
|
+
* // { href: 'ws://localhost:6252/bus', port: 6252, isDefault: true }
|
|
2908
|
+
*
|
|
2909
|
+
* // Production with explicit port
|
|
2910
|
+
* const config = parseBusUrl('wss://bus.example.com:9000/bus');
|
|
2911
|
+
* // { href: 'wss://bus.example.com:9000/bus', port: 9000, isDefault: false }
|
|
2912
|
+
*
|
|
2913
|
+
* // Production with protocol default port
|
|
2914
|
+
* const config = parseBusUrl('wss://bus.example.com/bus');
|
|
2915
|
+
* // { href: 'wss://bus.example.com/bus', port: undefined, isDefault: false }
|
|
2916
|
+
* ```
|
|
2917
|
+
*/
|
|
2918
|
+
declare function parseBusUrl(envValue: string | undefined): BusUrlConfig;
|
|
2919
|
+
//#endregion
|
|
2920
|
+
//#region core/bus-core/src/utils/subscription-matching.d.ts
|
|
2921
|
+
/**
|
|
2922
|
+
* Subscription pattern matching utilities.
|
|
2923
|
+
*
|
|
2924
|
+
* Supports exact matches, subject wildcards (e.g., 'adapter.*'),
|
|
2925
|
+
* and namespace wildcards (e.g., 'adapter:*').
|
|
2926
|
+
*
|
|
2927
|
+
* ## Pattern Matching Decision Tree
|
|
2928
|
+
*
|
|
2929
|
+
* ```
|
|
2930
|
+
* Pattern ends with...?
|
|
2931
|
+
* │
|
|
2932
|
+
* ├─ No asterisk (e.g., 'adapter.log')
|
|
2933
|
+
* │ └─ Exact match: subject === pattern
|
|
2934
|
+
* │
|
|
2935
|
+
* ├─ ':*' (e.g., 'adapter:*', 'adapter:claudeCode:*')
|
|
2936
|
+
* │ └─ Namespace wildcard: matches child namespace subjects
|
|
2937
|
+
* │ • 'adapter:*' matches 'adapter:claudeCode.log'
|
|
2938
|
+
* │ • 'adapter:*' matches 'adapter:claudeCode:sdk.thinking'
|
|
2939
|
+
* │ • 'adapter:*' does NOT match 'adapter.log' (no child namespace)
|
|
2940
|
+
* │
|
|
2941
|
+
* └─ '.*' (e.g., 'adapter.*', 'adapter:claudeCode.*')
|
|
2942
|
+
* └─ Subject wildcard: matches subjects in specific namespace
|
|
2943
|
+
* • 'adapter.*' matches 'adapter.log', 'adapter.error'
|
|
2944
|
+
* • 'adapter.*' does NOT match 'adapter:claudeCode.log'
|
|
2945
|
+
* • 'adapter:claudeCode.*' matches 'adapter:claudeCode.log'
|
|
2946
|
+
* ```
|
|
2947
|
+
*
|
|
2948
|
+
* ## Colon vs Dot Semantics
|
|
2949
|
+
*
|
|
2950
|
+
* - **Colon (`:`)** = namespace hierarchy boundary
|
|
2951
|
+
* - `adapter:claudeCode` is a child namespace of `adapter`
|
|
2952
|
+
* - Wildcard `:*` crosses this boundary
|
|
2953
|
+
*
|
|
2954
|
+
* - **Dot (`.`)** = subject separator within namespace
|
|
2955
|
+
* - `adapter.log` is a subject in the `adapter` namespace
|
|
2956
|
+
* - Wildcard `.*` enumerates subjects, doesn't cross namespace boundaries
|
|
2957
|
+
*/
|
|
2958
|
+
/**
|
|
2959
|
+
* Check if a subject matches a subscription pattern.
|
|
2960
|
+
*
|
|
2961
|
+
* Patterns can be:
|
|
2962
|
+
* - Exact match: 'adapter:claudeCode.log' matches only 'adapter:claudeCode.log'
|
|
2963
|
+
* - Subject wildcard: 'adapter:claudeCode.*' matches 'adapter:claudeCode.log', 'adapter:claudeCode.initialized'
|
|
2964
|
+
* - Namespace wildcard: 'adapter:*' matches subjects from child namespaces
|
|
2965
|
+
* @param subject - Subject to match (e.g., 'adapter:claudeCode:sdk.thinking')
|
|
2966
|
+
* @param pattern - Subscription pattern (e.g., 'adapter:*', 'adapter:claudeCode.*', 'adapter:claudeCode.log')
|
|
2967
|
+
* @returns true if subject matches pattern
|
|
2968
|
+
* @example
|
|
2969
|
+
* ```typescript
|
|
2970
|
+
* // Exact match
|
|
2971
|
+
* matchesSubscription('adapter.log', 'adapter.log')
|
|
2972
|
+
* // → true
|
|
2973
|
+
*
|
|
2974
|
+
* // Subject wildcard - matches subjects in namespace
|
|
2975
|
+
* matchesSubscription('adapter.log', 'adapter.*')
|
|
2976
|
+
* // → true
|
|
2977
|
+
* matchesSubscription('adapter.initialized', 'adapter.*')
|
|
2978
|
+
* // → true
|
|
2979
|
+
* matchesSubscription('adapter:claudeCode.log', 'adapter.*')
|
|
2980
|
+
* // → false (different namespace - adapter:claudeCode vs adapter)
|
|
2981
|
+
*
|
|
2982
|
+
* // Namespace wildcard - matches child namespaces
|
|
2983
|
+
* matchesSubscription('adapter:claudeCode.initialized', 'adapter:*')
|
|
2984
|
+
* // → true (claudeCode is child of adapter)
|
|
2985
|
+
* matchesSubscription('adapter:claudeCode:sdk.thinking', 'adapter:*')
|
|
2986
|
+
* // → true (sdk is descendant of adapter)
|
|
2987
|
+
* matchesSubscription('adapter:gpt.initialized', 'adapter:*')
|
|
2988
|
+
* // → true (gpt is child of adapter)
|
|
2989
|
+
*
|
|
2990
|
+
* // Multi-level namespace wildcard
|
|
2991
|
+
* matchesSubscription('adapter:claudeCode:sdk.thinking', 'adapter:claudeCode:*')
|
|
2992
|
+
* // → true (sdk is child of adapter:claudeCode)
|
|
2993
|
+
* matchesSubscription('adapter:gpt.initialized', 'adapter:claudeCode:*')
|
|
2994
|
+
* // → false (different branch)
|
|
2995
|
+
* ```
|
|
2996
|
+
*/
|
|
2997
|
+
declare function matchesSubscription(subject: string, pattern: string): boolean;
|
|
2998
|
+
/**
|
|
2999
|
+
* Check if a subject matches any pattern in a collection.
|
|
3000
|
+
* @param subject - Subject to match
|
|
3001
|
+
* @param patterns - Collection of subscription patterns
|
|
3002
|
+
* @returns true if subject matches at least one pattern
|
|
3003
|
+
* @example
|
|
3004
|
+
* ```typescript
|
|
3005
|
+
* matchesAnySubscription('adapter.log', new Set(['adapter.*', 'agent.*']))
|
|
3006
|
+
* // → true (matches 'adapter.*')
|
|
3007
|
+
*
|
|
3008
|
+
* matchesAnySubscription('adapter:claudeCode.initialized', new Set(['adapter:*']))
|
|
3009
|
+
* // → true (matches 'adapter:*')
|
|
3010
|
+
*
|
|
3011
|
+
* matchesAnySubscription('session.started', new Set(['adapter.*', 'adapter:*']))
|
|
3012
|
+
* // → false (no match)
|
|
3013
|
+
*
|
|
3014
|
+
* matchesAnySubscription('adapter.log', new Set())
|
|
3015
|
+
* // → false (empty patterns)
|
|
3016
|
+
* ```
|
|
3017
|
+
*/
|
|
3018
|
+
declare function matchesAnySubscription(subject: string, patterns: Iterable<string>): boolean;
|
|
3019
|
+
//#endregion
|
|
3020
|
+
//#region core/bus-core/src/errors/bus-error.d.ts
|
|
3021
|
+
/**
|
|
3022
|
+
* Base error class for all bus-related errors.
|
|
3023
|
+
*/
|
|
3024
|
+
declare class BusError extends MakaioError {
|
|
3025
|
+
readonly subject?: string | undefined;
|
|
3026
|
+
/**
|
|
3027
|
+
* @param message - Human-readable error description
|
|
3028
|
+
* @param subject - Fully-qualified subject name (namespace.subject) for the failed operation
|
|
3029
|
+
*/
|
|
3030
|
+
constructor(message: string, subject?: string | undefined);
|
|
3031
|
+
}
|
|
3032
|
+
//#endregion
|
|
3033
|
+
//#region core/bus-core/src/errors/channel-auth-error.d.ts
|
|
3034
|
+
/**
|
|
3035
|
+
* Thrown when channel authentication fails during the handshake.
|
|
3036
|
+
* Indicates the provided token does not match the endpoint's expected token.
|
|
3037
|
+
*/
|
|
3038
|
+
declare class ChannelAuthError extends BusError {
|
|
3039
|
+
/**
|
|
3040
|
+
* @param endpoint - The endpoint name that failed authentication
|
|
3041
|
+
*/
|
|
3042
|
+
constructor(endpoint: string);
|
|
3043
|
+
}
|
|
3044
|
+
//#endregion
|
|
3045
|
+
//#region core/bus-core/src/errors/channel-closed-error.d.ts
|
|
3046
|
+
/**
|
|
3047
|
+
* Thrown when an operation is attempted on a closed DirectChannel.
|
|
3048
|
+
* All pending requests are rejected with this error when a channel closes.
|
|
3049
|
+
*/
|
|
3050
|
+
declare class ChannelClosedError extends BusError {
|
|
3051
|
+
/**
|
|
3052
|
+
* @param channelId - The identifier of the channel that is closed
|
|
3053
|
+
*/
|
|
3054
|
+
constructor(channelId: string);
|
|
3055
|
+
}
|
|
3056
|
+
//#endregion
|
|
3057
|
+
//#region core/bus-core/src/errors/channel-only-error.d.ts
|
|
3058
|
+
/**
|
|
3059
|
+
* Thrown when a channel-only subject is used directly on the public bus.
|
|
3060
|
+
* Channel subjects must be routed through a DirectChannel, not the public bus API.
|
|
3061
|
+
*/
|
|
3062
|
+
declare class ChannelOnlyError extends BusError {
|
|
3063
|
+
/**
|
|
3064
|
+
* @param subject - The channel-only subject that was used on the public bus
|
|
3065
|
+
*/
|
|
3066
|
+
constructor(subject: string);
|
|
3067
|
+
}
|
|
3068
|
+
//#endregion
|
|
3069
|
+
//#region core/bus-core/src/errors/local-subject-error.d.ts
|
|
3070
|
+
/**
|
|
3071
|
+
* Thrown when a remote peer attempts to invoke a local-only subject over a
|
|
3072
|
+
* transport. Local subjects are never serializable and must not be routed
|
|
3073
|
+
* across process or network boundaries.
|
|
3074
|
+
*/
|
|
3075
|
+
declare class LocalSubjectError extends BusError {
|
|
3076
|
+
/**
|
|
3077
|
+
* @param subject - The local-only subject that was invoked remotely
|
|
3078
|
+
*/
|
|
3079
|
+
constructor(subject: string);
|
|
3080
|
+
}
|
|
3081
|
+
//#endregion
|
|
3082
|
+
//#region core/bus-core/src/errors/no-handler-error.d.ts
|
|
3083
|
+
/**
|
|
3084
|
+
* Stable error code for "no handler registered" failures.
|
|
3085
|
+
*/
|
|
3086
|
+
declare const NO_HANDLER_ERROR_CODE: "NO_HANDLER";
|
|
3087
|
+
/**
|
|
3088
|
+
* Error thrown when no handler is registered for a request.
|
|
3089
|
+
*/
|
|
3090
|
+
declare class NoHandlerError extends BusError {
|
|
3091
|
+
readonly code: "NO_HANDLER";
|
|
3092
|
+
/**
|
|
3093
|
+
* @param subject - Fully-qualified subject name for which no handler was found
|
|
3094
|
+
*/
|
|
3095
|
+
constructor(subject: string);
|
|
3096
|
+
}
|
|
3097
|
+
//#endregion
|
|
3098
|
+
//#region core/bus-core/src/errors/request-error.d.ts
|
|
3099
|
+
/**
|
|
3100
|
+
* Generic error thrown when a request fails for any other reason.
|
|
3101
|
+
*/
|
|
3102
|
+
declare class RequestError extends BusError {
|
|
3103
|
+
readonly cause?: Error | undefined;
|
|
3104
|
+
/**
|
|
3105
|
+
* @param subject - Fully-qualified subject name for the failed request
|
|
3106
|
+
* @param message - Human-readable description of the failure
|
|
3107
|
+
* @param cause - Underlying error thrown by the handler, if any
|
|
3108
|
+
*/
|
|
3109
|
+
constructor(subject: string, message: string, cause?: Error | undefined);
|
|
3110
|
+
}
|
|
3111
|
+
//#endregion
|
|
3112
|
+
//#region core/bus-core/src/errors/timeout-error.d.ts
|
|
3113
|
+
/**
|
|
3114
|
+
* Error thrown when a request times out.
|
|
3115
|
+
*/
|
|
3116
|
+
declare class TimeoutError extends BusError {
|
|
3117
|
+
readonly timeoutMs: number;
|
|
3118
|
+
/**
|
|
3119
|
+
* @param subject - Fully-qualified subject name for the timed-out request
|
|
3120
|
+
* @param timeoutMs - Timeout duration in milliseconds that was exceeded
|
|
3121
|
+
*/
|
|
3122
|
+
constructor(subject: string, timeoutMs: number);
|
|
3123
|
+
}
|
|
3124
|
+
//#endregion
|
|
3125
|
+
//#region core/bus-core/src/errors/validation-error.d.ts
|
|
3126
|
+
/**
|
|
3127
|
+
* Error thrown when payload validation fails.
|
|
3128
|
+
*/
|
|
3129
|
+
declare class ValidationError extends BusError {
|
|
3130
|
+
readonly zodError: z.ZodError;
|
|
3131
|
+
/**
|
|
3132
|
+
* @param subject - Fully-qualified subject name for which validation failed
|
|
3133
|
+
* @param zodError - Zod validation error containing the individual issue details
|
|
3134
|
+
*/
|
|
3135
|
+
constructor(subject: string, zodError: z.ZodError);
|
|
3136
|
+
}
|
|
3137
|
+
//#endregion
|
|
3138
|
+
//#region core/bus-core/src/bus.d.ts
|
|
3139
|
+
/**
|
|
3140
|
+
* Creates a new bus context containing handler registries and shared state.
|
|
3141
|
+
*
|
|
3142
|
+
* Used internally by createBusInstance to manage event and request handlers.
|
|
3143
|
+
* Can be used to create isolated bus instances (e.g., for testing) by providing
|
|
3144
|
+
* separate handler maps per instance.
|
|
3145
|
+
* @returns A new MakaioBusContext instance with empty handler registries
|
|
3146
|
+
*/
|
|
3147
|
+
declare const createBusContext: () => MakaioBusContext;
|
|
3148
|
+
/**
|
|
3149
|
+
* Options for creating a bus instance.
|
|
3150
|
+
*/
|
|
3151
|
+
interface CreateBusOptions<Namespace extends string | undefined = undefined> {
|
|
3152
|
+
/** Pre-created context. Omit for a fresh one. */
|
|
3153
|
+
context?: MakaioBusContext;
|
|
3154
|
+
/** Namespace scope (e.g. 'adapter:claudeCode'). */
|
|
3155
|
+
namespace?: Namespace;
|
|
3156
|
+
/** Transports to register immediately after creation. */
|
|
3157
|
+
transports?: BusTransport[];
|
|
3158
|
+
}
|
|
3159
|
+
/**
|
|
3160
|
+
* Creates a new bus instance with optional context, namespace isolation, and transports.
|
|
3161
|
+
*
|
|
3162
|
+
* The bus instance provides methods for type-safe event emission, request/response
|
|
3163
|
+
* patterns, handler registration, and namespace management. Handlers use
|
|
3164
|
+
* SubjectDefinition objects (not strings) for full type safety and schema validation.
|
|
3165
|
+
* @param options - Optional creation options. `context` defaults to a fresh `createBusContext()`.
|
|
3166
|
+
* `namespace` scopes the instance (e.g. `'adapter:claudeCode'`). `transports` are registered
|
|
3167
|
+
* immediately after creation.
|
|
3168
|
+
* @returns A new IMakaioBus instance with methods for on, emit, request, scoped, and schema management
|
|
3169
|
+
*/
|
|
3170
|
+
declare function createBusInstance<Namespace extends string | undefined = undefined>(options?: CreateBusOptions<Namespace>): IMakaioBus<Namespace>;
|
|
3171
|
+
/**
|
|
3172
|
+
* Main bus instance with unified API for events and request/response flows.
|
|
3173
|
+
*
|
|
3174
|
+
* Provides a singleton bus that manages schema-backed messaging with type-safe
|
|
3175
|
+
* subjects, namespace isolation, and transport routing. Use this as the central
|
|
3176
|
+
* coordination point for all cross-component communication.
|
|
3177
|
+
*
|
|
3178
|
+
* **Core Methods:**
|
|
3179
|
+
* - `registerNamespace()` - Register typed subjects with Zod schemas
|
|
3180
|
+
* - `on()` - Subscribe to events or requests with typed handlers
|
|
3181
|
+
* - `emit()` - Fire-and-forget event broadcasting
|
|
3182
|
+
* - `request()` - Request-response with middleware chain
|
|
3183
|
+
* - `scoped()` - Create namespace-scoped bus instance
|
|
3184
|
+
*
|
|
3185
|
+
* **Key Features:**
|
|
3186
|
+
* - Type-safe SubjectDefinition objects (no raw strings)
|
|
3187
|
+
* - Runtime validation in development (Zod schemas)
|
|
3188
|
+
* - Wildcard pattern matching with `.$all`
|
|
3189
|
+
* - Transport-backed remote messaging
|
|
3190
|
+
* - Hierarchical namespace support (e.g., `adapter:claudeCode`)
|
|
3191
|
+
* - Middleware chains for request processing
|
|
3192
|
+
* @example Basic usage
|
|
3193
|
+
* ```typescript
|
|
3194
|
+
* import { MakaioBus } from '@makaio/framework/bus';
|
|
3195
|
+
* import { z } from 'zod';
|
|
3196
|
+
*
|
|
3197
|
+
* // Register namespace with typed subjects
|
|
3198
|
+
* const { subjects } = MakaioBus.registerNamespace('agent', {
|
|
3199
|
+
* started: z.object({ agentId: z.string() }),
|
|
3200
|
+
* toolApprove: {
|
|
3201
|
+
* request: z.object({ toolName: z.string() }),
|
|
3202
|
+
* response: z.object({ approved: z.boolean() }),
|
|
3203
|
+
* },
|
|
3204
|
+
* });
|
|
3205
|
+
*
|
|
3206
|
+
* // Subscribe to events
|
|
3207
|
+
* MakaioBus.on(subjects.started, (context) => {
|
|
3208
|
+
* console.debug('Agent started:', context.payload.agentId);
|
|
3209
|
+
* });
|
|
3210
|
+
*
|
|
3211
|
+
* // Emit events
|
|
3212
|
+
* await MakaioBus.emit(subjects.started, { agentId: 'agent-123' });
|
|
3213
|
+
*
|
|
3214
|
+
* // Handle requests
|
|
3215
|
+
* MakaioBus.on(subjects.toolApprove, (context) => {
|
|
3216
|
+
* context.setResult({ approved: true });
|
|
3217
|
+
* });
|
|
3218
|
+
*
|
|
3219
|
+
* // Make requests
|
|
3220
|
+
* const result = await MakaioBus.request(subjects.toolApprove, {
|
|
3221
|
+
* toolName: 'deleteFile',
|
|
3222
|
+
* });
|
|
3223
|
+
* ```
|
|
3224
|
+
*/
|
|
3225
|
+
declare const MakaioBus: IMakaioBus;
|
|
3226
|
+
//#endregion
|
|
3227
|
+
//#region core/bus-core/src/methods/on.d.ts
|
|
3228
|
+
/**
|
|
3229
|
+
* Wait until a handler registration has propagated to registered transports.
|
|
3230
|
+
*
|
|
3231
|
+
* `on()` still returns a plain cleanup function for public ergonomics, but
|
|
3232
|
+
* remote transports subscribe asynchronously. Callers that publish readiness
|
|
3233
|
+
* based on remote routability can await this helper before proceeding.
|
|
3234
|
+
* @param cleanup - Cleanup function returned by {@link on}.
|
|
3235
|
+
*/
|
|
3236
|
+
declare function waitForSubscriptionPropagation(cleanup: (() => void) | null | undefined): Promise<void>;
|
|
3237
|
+
//#endregion
|
|
3238
|
+
//#region core/bus-core/src/channel/types.d.ts
|
|
3239
|
+
/**
|
|
3240
|
+
* Encrypted point-to-point communication channel over the bus.
|
|
3241
|
+
*
|
|
3242
|
+
* Provides a bus-compatible interface (on, once, emit, request) where all
|
|
3243
|
+
* payloads are encrypted with a shared AES-256-GCM key derived via ECDH.
|
|
3244
|
+
* Observers, middleware, and transport loggers only see opaque `{ iv, data }` payloads.
|
|
3245
|
+
* Channel messages ride the normal bus transport layer unless the caller
|
|
3246
|
+
* explicitly constrains routing via the underlying bus configuration.
|
|
3247
|
+
*/
|
|
3248
|
+
interface IDirectChannel {
|
|
3249
|
+
/** Unique channel identifier (used in channel-scoped subject namespaces). */
|
|
3250
|
+
readonly channelId: string;
|
|
3251
|
+
/**
|
|
3252
|
+
* Register an event or request handler on this channel.
|
|
3253
|
+
* The handler receives decrypted payloads — encryption is transparent.
|
|
3254
|
+
* @param subject - Subject definition (channel or non-channel subjects both accepted)
|
|
3255
|
+
* @param handler - Handler function matching the subject's schema
|
|
3256
|
+
* @param options - Handler options (priority, etc.)
|
|
3257
|
+
* @returns Unsubscribe function
|
|
3258
|
+
*/
|
|
3259
|
+
on<Subject extends SubjectDefinition>(subject: Subject, handler: HandlerForSubjectDefinition<Subject>, options?: OnOptions): () => void;
|
|
3260
|
+
/**
|
|
3261
|
+
* Register a one-time handler that auto-unsubscribes after first invocation.
|
|
3262
|
+
* @param subject - Subject definition
|
|
3263
|
+
* @param handler - Handler function
|
|
3264
|
+
* @returns Unsubscribe function
|
|
3265
|
+
*/
|
|
3266
|
+
once<Subject extends SubjectDefinition>(subject: Subject, handler: HandlerForSubjectDefinition<Subject>): () => void;
|
|
3267
|
+
/**
|
|
3268
|
+
* Fire-and-forget encrypted event to the peer.
|
|
3269
|
+
* @param subject - Subject definition
|
|
3270
|
+
* @param payload - Event payload (will be encrypted before dispatch)
|
|
3271
|
+
*/
|
|
3272
|
+
emit<Subject extends SubjectDefinition>(subject: Subject, payload: Subject['$meta']['payload']): Promise<void>;
|
|
3273
|
+
/**
|
|
3274
|
+
* Encrypted request-response to the peer.
|
|
3275
|
+
* @param subject - Subject definition (must be a request subject)
|
|
3276
|
+
* @param payload - Request payload (will be encrypted before dispatch)
|
|
3277
|
+
* @param options - Request options (timeout, etc.)
|
|
3278
|
+
* @returns Decrypted response
|
|
3279
|
+
* @throws \{ChannelClosedError\} If the channel is closed
|
|
3280
|
+
* @throws \{NoHandlerError\} If the peer has no handler for this subject
|
|
3281
|
+
*/
|
|
3282
|
+
request<Subject extends SubjectDefinition>(subject: Subject, payload: Subject['$meta']['payload']['request'], options?: {
|
|
3283
|
+
timeout?: number;
|
|
3284
|
+
}): Promise<Subject['$meta']['payload']['response']>;
|
|
3285
|
+
/**
|
|
3286
|
+
* Encrypted request-response, returns `handled: false` instead of throwing NoHandlerError.
|
|
3287
|
+
* @param subject - Subject definition (must be a request subject)
|
|
3288
|
+
* @param payload - Request payload
|
|
3289
|
+
* @param options - Request options
|
|
3290
|
+
* @returns OptionalResult wrapping the response
|
|
3291
|
+
*/
|
|
3292
|
+
requestOptional<Subject extends SubjectDefinition>(subject: Subject, payload: Subject['$meta']['payload']['request'], options?: {
|
|
3293
|
+
timeout?: number;
|
|
3294
|
+
}): Promise<OptionalResult<Subject['$meta']['payload']['response']>>;
|
|
3295
|
+
/**
|
|
3296
|
+
* Close the channel. Notifies peer, rejects pending requests,
|
|
3297
|
+
* unsubscribes all handlers, and discards the shared encryption key.
|
|
3298
|
+
*/
|
|
3299
|
+
close(): void;
|
|
3300
|
+
}
|
|
3301
|
+
/**
|
|
3302
|
+
* Options for creating a channel endpoint.
|
|
3303
|
+
*/
|
|
3304
|
+
interface ChannelEndpointOptions {
|
|
3305
|
+
/** Capability token that clients must present to open this channel. */
|
|
3306
|
+
token: string;
|
|
3307
|
+
}
|
|
3308
|
+
/**
|
|
3309
|
+
* A registered channel endpoint that accepts incoming connections.
|
|
3310
|
+
*/
|
|
3311
|
+
interface ChannelEndpoint {
|
|
3312
|
+
/** The endpoint name (e.g., 'credentials'). */
|
|
3313
|
+
readonly name: string;
|
|
3314
|
+
/** The capability token clients need to open this channel. */
|
|
3315
|
+
readonly token: string;
|
|
3316
|
+
/** Unregister the endpoint, preventing new connections. */
|
|
3317
|
+
close(): void;
|
|
3318
|
+
}
|
|
3319
|
+
//#endregion
|
|
3320
|
+
//#region core/bus-core/src/channel/system-namespace.d.ts
|
|
3321
|
+
/**
|
|
3322
|
+
* Schema for the system.channel.open handshake request.
|
|
3323
|
+
*
|
|
3324
|
+
* This is the only public-bus subject the channel system introduces.
|
|
3325
|
+
* The handshake includes a capability token that acts as a bearer
|
|
3326
|
+
* credential. Public keys are not secret, but the token grants channel
|
|
3327
|
+
* access and should only travel over trusted transports. Callers should
|
|
3328
|
+
* prefer `transports: []` for same-process channels.
|
|
3329
|
+
*/
|
|
3330
|
+
declare const SystemChannelSchemas: {
|
|
3331
|
+
'channel.open': {
|
|
3332
|
+
request: z.ZodObject<{
|
|
3333
|
+
endpoint: z.ZodString;
|
|
3334
|
+
token: z.ZodString;
|
|
3335
|
+
clientPubKey: z.ZodString;
|
|
3336
|
+
transports: z.ZodArray<z.ZodString>;
|
|
3337
|
+
}, z.core.$strip>;
|
|
3338
|
+
response: z.ZodObject<{
|
|
3339
|
+
channelId: z.ZodString;
|
|
3340
|
+
endpointPubKey: z.ZodString;
|
|
3341
|
+
}, z.core.$strip>;
|
|
3342
|
+
};
|
|
3343
|
+
};
|
|
3344
|
+
//#endregion
|
|
3345
|
+
//#region core/bus-core/src/channel/channel-endpoint.d.ts
|
|
3346
|
+
/**
|
|
3347
|
+
* Register a channel endpoint that accepts encrypted point-to-point connections.
|
|
3348
|
+
*
|
|
3349
|
+
* Listens for `system.channel.open` requests. When a request arrives for this
|
|
3350
|
+
* endpoint name with the correct token:
|
|
3351
|
+
* 1. Performs the ECDH key exchange (generates a keypair, derives the shared secret).
|
|
3352
|
+
* 2. Instantiates an {@link IDirectChannel} for the endpoint side.
|
|
3353
|
+
* 3. Calls `callback` so the endpoint can register its channel-scoped handlers.
|
|
3354
|
+
* 4. Returns the channel ID and the endpoint public key to the client.
|
|
3355
|
+
*
|
|
3356
|
+
* Multiple endpoints can coexist on the same bus context; each handles only
|
|
3357
|
+
* requests whose `payload.endpoint` matches its own name.
|
|
3358
|
+
* @param context - Bus context to register the endpoint handler on
|
|
3359
|
+
* @param endpointName - Logical name for this endpoint (e.g., 'credentials')
|
|
3360
|
+
* @param callback - Called with the new {@link IDirectChannel} once the handshake
|
|
3361
|
+
* is complete; use this to register channel handlers before the client receives
|
|
3362
|
+
* the handshake response
|
|
3363
|
+
* @param options - Endpoint options including the shared capability token
|
|
3364
|
+
* @returns A {@link ChannelEndpoint} handle whose `close()` unregisters the endpoint
|
|
3365
|
+
*/
|
|
3366
|
+
declare function createChannelEndpoint(context: MakaioBusContext, endpointName: string, callback: (channel: IDirectChannel) => void, options: ChannelEndpointOptions): ChannelEndpoint;
|
|
3367
|
+
/**
|
|
3368
|
+
* Open an encrypted point-to-point channel to a registered endpoint.
|
|
3369
|
+
*
|
|
3370
|
+
* Performs the ECDH handshake via `system.channel.open`:
|
|
3371
|
+
* 1. Generates an ephemeral ECDH keypair.
|
|
3372
|
+
* 2. Sends the client public key and capability token to the endpoint.
|
|
3373
|
+
* 3. Receives the channel ID and endpoint public key.
|
|
3374
|
+
* 4. Derives the shared AES-256-GCM key from the client private key and endpoint
|
|
3375
|
+
* public key.
|
|
3376
|
+
* 5. Returns a `IDirectChannel` ready for encrypted communication.
|
|
3377
|
+
*
|
|
3378
|
+
* By default the handshake is dispatched over all registered transports so the
|
|
3379
|
+
* endpoint can reside in a different process. Pass `transports: []` to restrict
|
|
3380
|
+
* the handshake (and the resulting channel) to the local process only — this is
|
|
3381
|
+
* the correct choice whenever both sides are guaranteed to share the same bus
|
|
3382
|
+
* context (e.g., credential service and its same-process callers).
|
|
3383
|
+
* @param context - Bus context to use for the handshake request
|
|
3384
|
+
* @param endpointName - Logical name of the endpoint to connect to
|
|
3385
|
+
* @param options - Connection options including the shared capability token and
|
|
3386
|
+
* an optional transport allowlist (`transports: []` for local-only)
|
|
3387
|
+
* @returns Resolved `IDirectChannel` once the handshake completes
|
|
3388
|
+
* @throws \{RequestError\} If the handshake fails — for authentication failures, the
|
|
3389
|
+
* cause is a \{ChannelAuthError\}
|
|
3390
|
+
* @throws \{NoHandlerError\} If no endpoint with the given name is registered
|
|
3391
|
+
*/
|
|
3392
|
+
declare function openChannel(context: MakaioBusContext, endpointName: string, options: {
|
|
3393
|
+
token: string;
|
|
3394
|
+
transports?: ReadonlyArray<BusTransportKeys>;
|
|
3395
|
+
}): Promise<IDirectChannel>;
|
|
3396
|
+
//#endregion
|
|
3397
|
+
//#region core/bus-core/src/lifecycle-schemas.d.ts
|
|
3398
|
+
/** Payload emitted when a transport establishes or re-establishes a connection. */
|
|
3399
|
+
type ConnectedPayload = {
|
|
3400
|
+
transport: string;
|
|
3401
|
+
};
|
|
3402
|
+
/** Payload emitted when a transport loses connection unexpectedly. */
|
|
3403
|
+
type DisconnectedPayload = {
|
|
3404
|
+
transport: string;
|
|
3405
|
+
};
|
|
3406
|
+
//#endregion
|
|
3407
|
+
//#region core/bus-core/src/lifecycle.d.ts
|
|
3408
|
+
/**
|
|
3409
|
+
* Bus-level lifecycle subjects for subscribing to transport connection state changes.
|
|
3410
|
+
*
|
|
3411
|
+
* All subjects are local-only: they are never relayed across transports, as they
|
|
3412
|
+
* describe the local bus's own connection state.
|
|
3413
|
+
*
|
|
3414
|
+
* Registration happens per-context inside `createBus()`.
|
|
3415
|
+
* @example
|
|
3416
|
+
* ```typescript
|
|
3417
|
+
* import { BusLifecycle } from '@makaio/framework/bus';
|
|
3418
|
+
*
|
|
3419
|
+
* MakaioBus.on(BusLifecycle.connected, ({ payload }) => {
|
|
3420
|
+
* console.log('Transport connected:', payload.transport);
|
|
3421
|
+
* });
|
|
3422
|
+
*
|
|
3423
|
+
* MakaioBus.on(BusLifecycle.disconnected, ({ payload }) => {
|
|
3424
|
+
* console.warn('Transport disconnected:', payload.transport);
|
|
3425
|
+
* });
|
|
3426
|
+
* ```
|
|
3427
|
+
*/
|
|
3428
|
+
declare const BusLifecycle: BusSubjects<FlatSubjectDefinitions<"bus:lifecycle", {
|
|
3429
|
+
connected: LocalSubjectSchema<_$zod.ZodObject<{
|
|
3430
|
+
transport: _$zod.ZodString;
|
|
3431
|
+
}, _$zod_v4_core0.$strip>>;
|
|
3432
|
+
disconnected: LocalSubjectSchema<_$zod.ZodObject<{
|
|
3433
|
+
transport: _$zod.ZodString;
|
|
3434
|
+
}, _$zod_v4_core0.$strip>>;
|
|
3435
|
+
}>, "bus:lifecycle">;
|
|
3436
|
+
//#endregion
|
|
3437
|
+
//#region core/bus-core/src/extension-namespace-types.d.ts
|
|
3438
|
+
/**
|
|
3439
|
+
* Extension point for extension namespace extensions.
|
|
3440
|
+
*
|
|
3441
|
+
* Use declaration merging to add extension-specific metadata or capabilities:
|
|
3442
|
+
* @example
|
|
3443
|
+
* ```typescript
|
|
3444
|
+
* // In an extension package
|
|
3445
|
+
* declare module '@makaio/framework/bus' {
|
|
3446
|
+
* interface ExtensionNamespaceExtensions {
|
|
3447
|
+
* customMetadata?: {
|
|
3448
|
+
* version: string;
|
|
3449
|
+
* author: string;
|
|
3450
|
+
* };
|
|
3451
|
+
* }
|
|
3452
|
+
* }
|
|
3453
|
+
* ```
|
|
3454
|
+
*/
|
|
3455
|
+
interface ExtensionNamespaceExtensions {}
|
|
3456
|
+
/**
|
|
3457
|
+
* Extension namespace combines a pure bus namespace definition with
|
|
3458
|
+
* extensible extension-specific properties.
|
|
3459
|
+
*
|
|
3460
|
+
* Wraps BusNamespaceDefinition with:
|
|
3461
|
+
* - Automatic 'extension:' prefix for domain naming
|
|
3462
|
+
* - Extension point for extension metadata via declaration merging
|
|
3463
|
+
* @typeParam N - Extension name (without 'extension:' prefix)
|
|
3464
|
+
* @typeParam Subjects - Subject record type from schemas
|
|
3465
|
+
* @typeParam FilterPayload - Filter payload type for type-safe filtering
|
|
3466
|
+
* @typeParam Ext - Extension type preserving specific metadata types
|
|
3467
|
+
* @typeParam Schemas - Original schema record; drives narrow literal types on subjects.$meta
|
|
3468
|
+
*/
|
|
3469
|
+
interface ExtensionNamespace<N extends string = string, _Subjects extends SubjectRecord = SubjectRecord, _FilterPayload = unknown, Ext extends ExtensionNamespaceExtensions = ExtensionNamespaceExtensions, Schemas extends SchemaRecord = SchemaRecord> extends BusNamespaceDefinition<`extension:${N}`, Schemas> {
|
|
3470
|
+
/**
|
|
3471
|
+
* Extension name (without 'extension:' prefix).
|
|
3472
|
+
*/
|
|
3473
|
+
readonly domain: N;
|
|
3474
|
+
/**
|
|
3475
|
+
* Extension properties added via declaration merging.
|
|
3476
|
+
* @see ExtensionNamespaceExtensions
|
|
3477
|
+
*/
|
|
3478
|
+
readonly extensions: Ext;
|
|
3479
|
+
}
|
|
3480
|
+
/**
|
|
3481
|
+
* Configuration for creating an extension namespace.
|
|
3482
|
+
* @typeParam Schemas - Schema record type for bus subjects
|
|
3483
|
+
* @typeParam Ext - Extension type preserving specific metadata types
|
|
3484
|
+
*/
|
|
3485
|
+
interface ExtensionNamespaceConfig<Schemas extends SchemaRecord, Ext extends ExtensionNamespaceExtensions = ExtensionNamespaceExtensions> {
|
|
3486
|
+
/**
|
|
3487
|
+
* Bus subject schemas for extension operations.
|
|
3488
|
+
* Can include both request-response and event schemas.
|
|
3489
|
+
*/
|
|
3490
|
+
schemas: Schemas;
|
|
3491
|
+
/**
|
|
3492
|
+
* Extension properties (populated by declaration merging).
|
|
3493
|
+
* @see ExtensionNamespaceExtensions
|
|
3494
|
+
*/
|
|
3495
|
+
extensions?: Ext;
|
|
3496
|
+
}
|
|
3497
|
+
/**
|
|
3498
|
+
* Infer the extension namespace type from config.
|
|
3499
|
+
* @typeParam N - Extension name without the `extension:` prefix
|
|
3500
|
+
* @typeParam Schemas - Schema record type for bus subjects
|
|
3501
|
+
* @typeParam Ext - Extension type preserving specific metadata types
|
|
3502
|
+
*/
|
|
3503
|
+
type ExtensionNamespaceFromConfig<N extends string, Schemas extends SchemaRecord, Ext extends ExtensionNamespaceExtensions = ExtensionNamespaceExtensions> = ExtensionNamespace<N, SubjectRecordFromSchemaRecord<Schemas>, FilterablePayloadIntersection<SubjectRecordFromSchemaRecord<Schemas>>, Ext, Schemas>;
|
|
3504
|
+
//#endregion
|
|
3505
|
+
//#region core/bus-core/src/subscribe-message.d.ts
|
|
3506
|
+
/**
|
|
3507
|
+
* Per-subject subscription state tracked locally on a client transport.
|
|
3508
|
+
*/
|
|
3509
|
+
interface SubscriptionEntry {
|
|
3510
|
+
/** Optional payload filter for server-side smart-routing. */
|
|
3511
|
+
filter?: PayloadFilter;
|
|
3512
|
+
/** Handler priorities registered for this subject. Empty array = event-only. */
|
|
3513
|
+
priorities: number[];
|
|
3514
|
+
}
|
|
3515
|
+
/**
|
|
3516
|
+
* Build a BusSubscribeMessage from local subscription state.
|
|
3517
|
+
* @param subscriptions - Map of subject patterns to their subscription entries
|
|
3518
|
+
* @param ackId - Optional acknowledgement ID for dynamic subscription propagation
|
|
3519
|
+
* @returns Wire-format subscribe message
|
|
3520
|
+
*/
|
|
3521
|
+
declare function buildSubscribeMessage(subscriptions: Map<string, SubscriptionEntry>, ackId?: string): BusSubscribeMessage;
|
|
3522
|
+
/**
|
|
3523
|
+
* Build a BusUnsubscribeMessage for specific subjects and priorities.
|
|
3524
|
+
* @param subjects - Map of subject patterns to priorities being removed
|
|
3525
|
+
* @param ackId - Optional acknowledgement ID for dynamic unsubscription propagation
|
|
3526
|
+
* @returns Wire-format unsubscribe message
|
|
3527
|
+
*/
|
|
3528
|
+
declare function buildUnsubscribeMessage(subjects: Record<string, number[]>, ackId?: string): BusUnsubscribeMessage;
|
|
3529
|
+
//#endregion
|
|
3530
|
+
//#region core/bus-core/src/create-extension-namespace.d.ts
|
|
3531
|
+
type Whitespace = ' ' | '\n' | '\r' | '\t' | '\v' | '\f' | '\u00A0' | '\u1680' | '\u2000' | '\u2001' | '\u2002' | '\u2003' | '\u2004' | '\u2005' | '\u2006' | '\u2007' | '\u2008' | '\u2009' | '\u200A' | '\u2028' | '\u2029' | '\u202F' | '\u205F' | '\u3000' | '\uFEFF';
|
|
3532
|
+
type TrimLeft<T extends string> = T extends `${Whitespace}${infer Rest}` ? TrimLeft<Rest> : T;
|
|
3533
|
+
type TrimRight<T extends string> = T extends `${infer Rest}${Whitespace}` ? TrimRight<Rest> : T;
|
|
3534
|
+
type Trim<T extends string> = string extends T ? string : TrimLeft<TrimRight<T>>;
|
|
3535
|
+
/**
|
|
3536
|
+
* Creates an extension namespace with typed subject definitions.
|
|
3537
|
+
*
|
|
3538
|
+
* Pure wrapper around {@link createBusNamespace} that:
|
|
3539
|
+
* - Automatically prepends 'extension:' to the domain name
|
|
3540
|
+
* - Provides extension point for extension-specific metadata via declaration merging
|
|
3541
|
+
* - Preserves type-safe filtering capabilities
|
|
3542
|
+
* @param extensionName - Extension name (e.g., 'terminal' becomes 'extension:terminal')
|
|
3543
|
+
* @param config - Namespace configuration with schemas and optional extensions
|
|
3544
|
+
* @returns Extension namespace with typed subjects and extensions
|
|
3545
|
+
* @example
|
|
3546
|
+
* ```typescript
|
|
3547
|
+
* // Basic usage (bus-only)
|
|
3548
|
+
* const TerminalExtension = createExtensionNamespace('terminal', {
|
|
3549
|
+
* schemas: {
|
|
3550
|
+
* spawn: { request: z.object({ cwd: z.string() }), response: z.object({ terminalId: z.string() }) },
|
|
3551
|
+
* output: z.object({ terminalId: z.string(), data: z.string() }),
|
|
3552
|
+
* },
|
|
3553
|
+
* });
|
|
3554
|
+
*
|
|
3555
|
+
* // With custom extension (after importing extension package)
|
|
3556
|
+
* const MyExtension = createExtensionNamespace('my-extension', {
|
|
3557
|
+
* schemas: { ... },
|
|
3558
|
+
* extensions: {
|
|
3559
|
+
* customMetadata: { version: '1.0.0' },
|
|
3560
|
+
* },
|
|
3561
|
+
* });
|
|
3562
|
+
* ```
|
|
3563
|
+
*/
|
|
3564
|
+
declare function createExtensionNamespace<N extends string, Schemas extends SchemaRecord, Ext extends ExtensionNamespaceExtensions = ExtensionNamespaceExtensions>(extensionName: N, config: ExtensionNamespaceConfig<Schemas, Ext>): ExtensionNamespace<Trim<N>, SubjectRecordFromSchemaRecord<Schemas>, FilterablePayloadIntersection<SubjectRecordFromSchemaRecord<Schemas>>, Ext, Schemas>;
|
|
3565
|
+
//#endregion
|
|
3566
|
+
//#region core/bus-core/src/utils/warn-unregistered.d.ts
|
|
3567
|
+
/**
|
|
3568
|
+
* Reset the warned-subjects set between test runs.
|
|
3569
|
+
* @internal
|
|
3570
|
+
* @returns Reset function in test mode, undefined otherwise
|
|
3571
|
+
*/
|
|
3572
|
+
declare const __resetWarnedSubjects: (() => void) | undefined;
|
|
3573
|
+
//#endregion
|
|
3574
|
+
//#region core/contracts/src/canonical-model/selection.d.ts
|
|
3575
|
+
/**
|
|
3576
|
+
* Agent selection for `kind: 'canonical-model'`.
|
|
3577
|
+
*
|
|
3578
|
+
* The `model` field carries the canonical model reference string verbatim.
|
|
3579
|
+
* Resolution happens immediately at the `AgentResolutionSubjects.resolve`
|
|
3580
|
+
* chokepoint, so this kind never persists into runtime spawn paths.
|
|
3581
|
+
*/
|
|
3582
|
+
declare const CanonicalModelSelectionSchema: z.ZodObject<{
|
|
3583
|
+
providerConfigId: z.ZodOptional<z.ZodString>;
|
|
3584
|
+
reasoningEffort: z.ZodOptional<z.ZodEnum<{
|
|
3585
|
+
none: "none";
|
|
3586
|
+
low: "low";
|
|
3587
|
+
medium: "medium";
|
|
3588
|
+
high: "high";
|
|
3589
|
+
"extra-high": "extra-high";
|
|
3590
|
+
}>>;
|
|
3591
|
+
cwd: z.ZodOptional<z.ZodString>;
|
|
3592
|
+
systemPrompt: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
3593
|
+
mode: z.ZodLiteral<"append">;
|
|
3594
|
+
content: z.ZodString;
|
|
3595
|
+
}, z.core.$strip>]>>;
|
|
3596
|
+
allowedTools: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
3597
|
+
disallowedTools: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
3598
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
3599
|
+
mcpSessionContext: z.ZodOptional<z.ZodObject<{
|
|
3600
|
+
sessionId: z.ZodString;
|
|
3601
|
+
servers: z.ZodArray<z.ZodObject<{
|
|
3602
|
+
name: z.ZodString;
|
|
3603
|
+
transport: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
3604
|
+
type: z.ZodLiteral<"stdio">;
|
|
3605
|
+
command: z.ZodString;
|
|
3606
|
+
args: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
3607
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
3608
|
+
alwaysLoad: z.ZodOptional<z.ZodBoolean>;
|
|
3609
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
3610
|
+
url: z.ZodString;
|
|
3611
|
+
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
3612
|
+
tools: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
3613
|
+
name: z.ZodString;
|
|
3614
|
+
permission_policy: z.ZodEnum<{
|
|
3615
|
+
always_allow: "always_allow";
|
|
3616
|
+
always_ask: "always_ask";
|
|
3617
|
+
always_deny: "always_deny";
|
|
3618
|
+
}>;
|
|
3619
|
+
}, z.core.$strip>>>;
|
|
3620
|
+
alwaysLoad: z.ZodOptional<z.ZodBoolean>;
|
|
3621
|
+
type: z.ZodLiteral<"sse">;
|
|
3622
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
3623
|
+
url: z.ZodString;
|
|
3624
|
+
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
3625
|
+
tools: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
3626
|
+
name: z.ZodString;
|
|
3627
|
+
permission_policy: z.ZodEnum<{
|
|
3628
|
+
always_allow: "always_allow";
|
|
3629
|
+
always_ask: "always_ask";
|
|
3630
|
+
always_deny: "always_deny";
|
|
3631
|
+
}>;
|
|
3632
|
+
}, z.core.$strip>>>;
|
|
3633
|
+
alwaysLoad: z.ZodOptional<z.ZodBoolean>;
|
|
3634
|
+
type: z.ZodLiteral<"http">;
|
|
3635
|
+
}, z.core.$strip>], "type">;
|
|
3636
|
+
exposureMode: z.ZodEnum<{
|
|
3637
|
+
direct: "direct";
|
|
3638
|
+
discovery: "discovery";
|
|
3639
|
+
}>;
|
|
3640
|
+
}, z.core.$strip>>;
|
|
3641
|
+
directTools: z.ZodArray<z.ZodObject<{
|
|
3642
|
+
fullName: z.ZodString;
|
|
3643
|
+
originalName: z.ZodString;
|
|
3644
|
+
serverName: z.ZodString;
|
|
3645
|
+
description: z.ZodOptional<z.ZodString>;
|
|
3646
|
+
inputSchema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
3647
|
+
exposureMode: z.ZodEnum<{
|
|
3648
|
+
direct: "direct";
|
|
3649
|
+
discovery: "discovery";
|
|
3650
|
+
hidden: "hidden";
|
|
3651
|
+
}>;
|
|
3652
|
+
enabled: z.ZodBoolean;
|
|
3653
|
+
enabledBy: z.ZodOptional<z.ZodEnum<{
|
|
3654
|
+
discovery: "discovery";
|
|
3655
|
+
toolset: "toolset";
|
|
3656
|
+
}>>;
|
|
3657
|
+
enabledAt: z.ZodOptional<z.ZodNumber>;
|
|
3658
|
+
exposed: z.ZodBoolean;
|
|
3659
|
+
}, z.core.$strip>>;
|
|
3660
|
+
discoverableTools: z.ZodArray<z.ZodObject<{
|
|
3661
|
+
fullName: z.ZodString;
|
|
3662
|
+
originalName: z.ZodString;
|
|
3663
|
+
serverName: z.ZodString;
|
|
3664
|
+
description: z.ZodOptional<z.ZodString>;
|
|
3665
|
+
inputSchema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
3666
|
+
exposureMode: z.ZodEnum<{
|
|
3667
|
+
direct: "direct";
|
|
3668
|
+
discovery: "discovery";
|
|
3669
|
+
hidden: "hidden";
|
|
3670
|
+
}>;
|
|
3671
|
+
enabled: z.ZodBoolean;
|
|
3672
|
+
enabledBy: z.ZodOptional<z.ZodEnum<{
|
|
3673
|
+
discovery: "discovery";
|
|
3674
|
+
toolset: "toolset";
|
|
3675
|
+
}>>;
|
|
3676
|
+
enabledAt: z.ZodOptional<z.ZodNumber>;
|
|
3677
|
+
exposed: z.ZodBoolean;
|
|
3678
|
+
}, z.core.$strip>>;
|
|
3679
|
+
}, z.core.$strip>>;
|
|
3680
|
+
allowedDirectories: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
3681
|
+
kind: z.ZodLiteral<"canonical-model">;
|
|
3682
|
+
model: z.ZodString;
|
|
3683
|
+
}, z.core.$loose>;
|
|
3684
|
+
type CanonicalModelSelection = z.infer<typeof CanonicalModelSelectionSchema>;
|
|
3685
|
+
declare module '@makaio/framework/contracts' {
|
|
3686
|
+
interface AgentSelectionKindMap {
|
|
3687
|
+
'canonical-model': CanonicalModelSelection;
|
|
3688
|
+
}
|
|
3689
|
+
}
|
|
3690
|
+
//#endregion
|
|
3691
|
+
//#region core/contracts/src/skill/schemas.d.ts
|
|
3692
|
+
/** Trigger that activated or reinjected a skill. */
|
|
3693
|
+
declare const SkillActivationTriggerSchema: z.ZodEnum<{
|
|
3694
|
+
user: "user";
|
|
3695
|
+
auto: "auto";
|
|
3696
|
+
model: "model";
|
|
3697
|
+
reinjection: "reinjection";
|
|
3698
|
+
}>;
|
|
3699
|
+
/** Why a previously-active skill was removed from runtime state. */
|
|
3700
|
+
declare const SkillDeactivationReasonSchema: z.ZodEnum<{
|
|
3701
|
+
user: "user";
|
|
3702
|
+
cwd_changed: "cwd_changed";
|
|
3703
|
+
session_end: "session_end";
|
|
3704
|
+
replaced: "replaced";
|
|
3705
|
+
}>;
|
|
3706
|
+
type SkillActivationTrigger = z.infer<typeof SkillActivationTriggerSchema>;
|
|
3707
|
+
type SkillDeactivationReason = z.infer<typeof SkillDeactivationReasonSchema>;
|
|
3708
|
+
//#endregion
|
|
3709
|
+
//#region core/contracts/src/skill/types.d.ts
|
|
3710
|
+
declare module '@makaio/framework/contracts' {
|
|
3711
|
+
interface SessionEventTypeMap {
|
|
3712
|
+
/** Skill catalog built for a session agent. */
|
|
3713
|
+
'skill.catalog.built': {
|
|
3714
|
+
agentId: string;
|
|
3715
|
+
cwd: string;
|
|
3716
|
+
adapterId?: string;
|
|
3717
|
+
skillNames: string[];
|
|
3718
|
+
};
|
|
3719
|
+
/** Skill activated for a session agent. */
|
|
3720
|
+
'skill.activated': {
|
|
3721
|
+
agentId: string;
|
|
3722
|
+
skillName: string;
|
|
3723
|
+
trigger: SkillActivationTrigger;
|
|
3724
|
+
turnNumber?: number;
|
|
3725
|
+
};
|
|
3726
|
+
/** Skill deactivated for a session agent. */
|
|
3727
|
+
'skill.deactivated': {
|
|
3728
|
+
agentId: string;
|
|
3729
|
+
skillName: string;
|
|
3730
|
+
reason: SkillDeactivationReason;
|
|
3731
|
+
};
|
|
3732
|
+
}
|
|
3733
|
+
}
|
|
3734
|
+
//#endregion
|
|
3735
|
+
//#region core/contracts/src/telemetry/schemas.d.ts
|
|
3736
|
+
/**
|
|
3737
|
+
* Scalar attribute value allowed in a telemetry fact.
|
|
3738
|
+
*
|
|
3739
|
+
* Restricted to primitives and homogeneous primitive arrays so that the
|
|
3740
|
+
* telemetry sink can safely serialize without inspecting arbitrary objects.
|
|
3741
|
+
*/
|
|
3742
|
+
declare const SubjectTelemetryAttributeValueSchema: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull, z.ZodArray<z.ZodString>, z.ZodArray<z.ZodNumber>, z.ZodArray<z.ZodBoolean>, z.ZodArray<z.ZodNull>]>;
|
|
3743
|
+
/** Inferred TypeScript type for a sanitized attribute value. */
|
|
3744
|
+
type SubjectTelemetryAttributeValue = z.infer<typeof SubjectTelemetryAttributeValueSchema>;
|
|
3745
|
+
/**
|
|
3746
|
+
* Sanitized bus subject telemetry fact schema.
|
|
3747
|
+
*
|
|
3748
|
+
* A fact captures the observable, non-sensitive metadata of a single bus
|
|
3749
|
+
* message. All payload content is excluded; only correlation handles and
|
|
3750
|
+
* namespace-approved scalar attributes are present.
|
|
3751
|
+
*/
|
|
3752
|
+
declare const SubjectTelemetryFactSchema: z.ZodObject<{
|
|
3753
|
+
factId: z.ZodString;
|
|
3754
|
+
observedAt: z.ZodNumber;
|
|
3755
|
+
machineId: z.ZodOptional<z.ZodString>;
|
|
3756
|
+
namespace: z.ZodString;
|
|
3757
|
+
subject: z.ZodString;
|
|
3758
|
+
messageType: z.ZodEnum<{
|
|
3759
|
+
request: "request";
|
|
3760
|
+
event: "event";
|
|
3761
|
+
broadcast: "broadcast";
|
|
3762
|
+
}>;
|
|
3763
|
+
direction: z.ZodEnum<{
|
|
3764
|
+
local: "local";
|
|
3765
|
+
outbound: "outbound";
|
|
3766
|
+
inbound: "inbound";
|
|
3767
|
+
}>;
|
|
3768
|
+
messageId: z.ZodString;
|
|
3769
|
+
correlationId: z.ZodOptional<z.ZodString>;
|
|
3770
|
+
attributes: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull, z.ZodArray<z.ZodString>, z.ZodArray<z.ZodNumber>, z.ZodArray<z.ZodBoolean>, z.ZodArray<z.ZodNull>]>>;
|
|
3771
|
+
}, z.core.$strict>;
|
|
3772
|
+
/** Inferred TypeScript type for a sanitized bus subject telemetry fact. */
|
|
3773
|
+
type SubjectTelemetryFact = z.infer<typeof SubjectTelemetryFactSchema>;
|
|
3774
|
+
//#endregion
|
|
3775
|
+
//#region core/bus-core/src/observability/projector-registry.d.ts
|
|
3776
|
+
/**
|
|
3777
|
+
* Map of sanitized scalar attribute values approved for telemetry emission.
|
|
3778
|
+
*
|
|
3779
|
+
* Keys are attribute names; values are restricted to primitives and homogeneous
|
|
3780
|
+
* primitive arrays so that telemetry sinks can safely serialize without
|
|
3781
|
+
* inspecting arbitrary objects. `undefined` values are excluded during merge.
|
|
3782
|
+
*/
|
|
3783
|
+
type SubjectTelemetryAttributes = Record<string, SubjectTelemetryAttributeValue | undefined>;
|
|
3784
|
+
/**
|
|
3785
|
+
* Input provided to a {@link SubjectTelemetryProjector} when projecting
|
|
3786
|
+
* attributes from a bus message payload.
|
|
3787
|
+
*/
|
|
3788
|
+
interface SubjectTelemetryProjectorInput {
|
|
3789
|
+
/** Raw bus message payload (read-only; must not be mutated). */
|
|
3790
|
+
readonly payload: unknown;
|
|
3791
|
+
/** Bus namespace that owns the observed subject. */
|
|
3792
|
+
readonly namespace: string;
|
|
3793
|
+
/** Subject key within the namespace. */
|
|
3794
|
+
readonly subject: string;
|
|
3795
|
+
/** Bus message type for the observed message. */
|
|
3796
|
+
readonly messageType: 'event' | 'request' | 'broadcast';
|
|
3797
|
+
}
|
|
3798
|
+
/**
|
|
3799
|
+
* Namespace-owned sidecar projector that extracts sanitized telemetry attributes
|
|
3800
|
+
* from a bus message payload.
|
|
3801
|
+
*
|
|
3802
|
+
* The projector is responsible for ensuring that the returned attributes contain
|
|
3803
|
+
* no sensitive data. Only scalar values ({@link SubjectTelemetryAttributeValue})
|
|
3804
|
+
* should appear in the returned map.
|
|
3805
|
+
*/
|
|
3806
|
+
interface SubjectTelemetryProjector {
|
|
3807
|
+
/** Namespace that owns this projector. */
|
|
3808
|
+
readonly namespace: string;
|
|
3809
|
+
/** Subject within the namespace that this projector handles. */
|
|
3810
|
+
readonly subject: string;
|
|
3811
|
+
/**
|
|
3812
|
+
* Extract sanitized telemetry attributes from the message payload.
|
|
3813
|
+
* @param input - Message context including payload, namespace, subject, and message type.
|
|
3814
|
+
* @returns Map of attribute key to sanitized scalar value. `undefined` values are omitted.
|
|
3815
|
+
*/
|
|
3816
|
+
project(input: SubjectTelemetryProjectorInput): SubjectTelemetryAttributes;
|
|
3817
|
+
}
|
|
3818
|
+
/**
|
|
3819
|
+
* Registry of namespace-owned sidecar projectors, keyed by `namespace.subject`.
|
|
3820
|
+
*
|
|
3821
|
+
* Projectors may be registered by the namespace owner to provide sanitized
|
|
3822
|
+
* telemetry attributes that cannot be inferred purely from schema observability
|
|
3823
|
+
* metadata (e.g., when the payload contains nested structures that require
|
|
3824
|
+
* domain-specific extraction logic).
|
|
3825
|
+
*/
|
|
3826
|
+
interface SubjectTelemetryProjectorRegistry {
|
|
3827
|
+
/**
|
|
3828
|
+
* Register a projector for a specific namespace and subject.
|
|
3829
|
+
*
|
|
3830
|
+
* If a projector is already registered for the same key, it is replaced.
|
|
3831
|
+
* @param projector - Projector to register.
|
|
3832
|
+
* @returns Cleanup function that unregisters this projector instance.
|
|
3833
|
+
*/
|
|
3834
|
+
register(projector: SubjectTelemetryProjector): () => void;
|
|
3835
|
+
/**
|
|
3836
|
+
* Retrieve the registered projector for a namespace and subject, if any.
|
|
3837
|
+
* @param namespace - Namespace that owns the subject.
|
|
3838
|
+
* @param subject - Subject key within the namespace.
|
|
3839
|
+
* @returns The registered projector, or `undefined` if none is registered.
|
|
3840
|
+
*/
|
|
3841
|
+
get(namespace: string, subject: string): SubjectTelemetryProjector | undefined;
|
|
3842
|
+
}
|
|
3843
|
+
/**
|
|
3844
|
+
* Create a new {@link SubjectTelemetryProjectorRegistry}.
|
|
3845
|
+
*
|
|
3846
|
+
* Maintains a map of projectors keyed by `namespace.subject`. At most one
|
|
3847
|
+
* projector is stored per key; later registrations replace earlier ones.
|
|
3848
|
+
* @returns A new projector registry instance.
|
|
3849
|
+
*/
|
|
3850
|
+
declare function createSubjectTelemetryProjectorRegistry(): SubjectTelemetryProjectorRegistry;
|
|
3851
|
+
//#endregion
|
|
3852
|
+
//#region core/bus-core/src/observability/subject-telemetry-projector.d.ts
|
|
3853
|
+
/**
|
|
3854
|
+
* Union of the three projectable local bus message types.
|
|
3855
|
+
*
|
|
3856
|
+
* Only messages that enter the bus via the local API (`emit`, `request`,
|
|
3857
|
+
* `broadcast`) are candidates for telemetry projection. Transport-relayed
|
|
3858
|
+
* messages are excluded because their projection is the responsibility of
|
|
3859
|
+
* the originating runtime.
|
|
3860
|
+
*/
|
|
3861
|
+
type ProjectableBusMessage = BusEventMessage | BusRequestMessage | BusBroadcastMessage;
|
|
3862
|
+
/**
|
|
3863
|
+
* Input for {@link projectSubjectTelemetryFacts}.
|
|
3864
|
+
*
|
|
3865
|
+
* Carries all data needed to project a sanitized {@link SubjectTelemetryFact}
|
|
3866
|
+
* from a single observed bus message.
|
|
3867
|
+
*/
|
|
3868
|
+
interface SubjectTelemetryProjectionInput {
|
|
3869
|
+
/** The observed bus message to project. */
|
|
3870
|
+
readonly message: ProjectableBusMessage;
|
|
3871
|
+
/**
|
|
3872
|
+
* Flow direction of the observed message at the source runtime.
|
|
3873
|
+
* Typically `'local'` for messages that originate and are consumed within
|
|
3874
|
+
* the same process.
|
|
3875
|
+
*/
|
|
3876
|
+
readonly direction: 'local' | 'outbound' | 'inbound';
|
|
3877
|
+
/** Wall-clock timestamp in Unix milliseconds at the time of observation. */
|
|
3878
|
+
readonly observedAt: number;
|
|
3879
|
+
/** Optional source machine identifier for multi-node telemetry correlation. */
|
|
3880
|
+
readonly machineId?: string;
|
|
3881
|
+
/**
|
|
3882
|
+
* Namespace registry used to look up the schema for the observed subject.
|
|
3883
|
+
* Obtain via `bus.getContext().namespaceRegistry`.
|
|
3884
|
+
*/
|
|
3885
|
+
readonly namespaceRegistry: NamespaceRegistry;
|
|
3886
|
+
/**
|
|
3887
|
+
* Optional sidecar projector registry for namespace-owned attribute extraction.
|
|
3888
|
+
*
|
|
3889
|
+
* When a projector is registered for the message's namespace and subject it
|
|
3890
|
+
* takes precedence over schema-driven projection.
|
|
3891
|
+
*/
|
|
3892
|
+
readonly projectorRegistry?: SubjectTelemetryProjectorRegistry;
|
|
3893
|
+
}
|
|
3894
|
+
/**
|
|
3895
|
+
* Project a single bus message into an array of sanitized
|
|
3896
|
+
* {@link SubjectTelemetryFact} objects.
|
|
3897
|
+
*
|
|
3898
|
+
* Attributes are resolved in the following priority order:
|
|
3899
|
+
* 1. **Sidecar projector**: a namespace-owned projector registered in
|
|
3900
|
+
* `projectorRegistry` for the message's namespace and subject.
|
|
3901
|
+
* 2. **Schema-driven**: scalar fields projected via `traceAll` or explicit
|
|
3902
|
+
* `observability.attribute()` / `observability.hidden()` metadata on the
|
|
3903
|
+
* Zod schema stored in the namespace registry.
|
|
3904
|
+
* 3. **Trace-only**: when neither approach yields attributes, an empty
|
|
3905
|
+
* `attributes` map is produced (the fact still carries correlation handles).
|
|
3906
|
+
*
|
|
3907
|
+
* The function always returns exactly one fact per call. The array shape
|
|
3908
|
+
* is intentional — downstream aggregation layers may extend this to fan-out
|
|
3909
|
+
* multiple facts from a single message (e.g., per-field count metrics).
|
|
3910
|
+
* @param input - Projection input including the message, direction, timestamp,
|
|
3911
|
+
* namespace registry, and optional sidecar projector registry.
|
|
3912
|
+
* @returns Array containing exactly one {@link SubjectTelemetryFact}.
|
|
3913
|
+
*/
|
|
3914
|
+
declare function projectSubjectTelemetryFacts(input: SubjectTelemetryProjectionInput): SubjectTelemetryFact[];
|
|
3915
|
+
//#endregion
|
|
3916
|
+
//#region core/bus-core/src/observability/projected-telemetry-transport.d.ts
|
|
3917
|
+
/**
|
|
3918
|
+
* Configuration options for {@link createProjectedTelemetryTransport}.
|
|
3919
|
+
*/
|
|
3920
|
+
interface ProjectedTelemetryTransportOptions {
|
|
3921
|
+
/**
|
|
3922
|
+
* Unique name for this transport instance.
|
|
3923
|
+
*
|
|
3924
|
+
* Must be unique within a single bus instance (used as the registry key).
|
|
3925
|
+
*/
|
|
3926
|
+
readonly name: string;
|
|
3927
|
+
/**
|
|
3928
|
+
* The underlying transport that receives projected telemetry fact events.
|
|
3929
|
+
*
|
|
3930
|
+
* All projected facts are forwarded to this transport as
|
|
3931
|
+
* `subject-telemetry.fact` events. No raw application payloads are forwarded.
|
|
3932
|
+
*/
|
|
3933
|
+
readonly inner: BusTransport;
|
|
3934
|
+
/**
|
|
3935
|
+
* Namespace registry used to resolve schemas for attribute projection.
|
|
3936
|
+
*
|
|
3937
|
+
* Obtain via `bus.getContext().namespaceRegistry`.
|
|
3938
|
+
*/
|
|
3939
|
+
readonly namespaceRegistry: NamespaceRegistry;
|
|
3940
|
+
/**
|
|
3941
|
+
* Optional sidecar projector registry for namespace-owned attribute extraction.
|
|
3942
|
+
*
|
|
3943
|
+
* When provided, sidecar projectors registered for a message's namespace and
|
|
3944
|
+
* subject take precedence over schema-driven attribute projection.
|
|
3945
|
+
*/
|
|
3946
|
+
readonly projectorRegistry?: SubjectTelemetryProjectorRegistry;
|
|
3947
|
+
/**
|
|
3948
|
+
* Optional source machine identifier embedded in each projected fact.
|
|
3949
|
+
*
|
|
3950
|
+
* When omitted, the `machineId` field is absent from emitted facts.
|
|
3951
|
+
*/
|
|
3952
|
+
readonly machineId?: string;
|
|
3953
|
+
/**
|
|
3954
|
+
* Optional clock override for deterministic testing.
|
|
3955
|
+
*
|
|
3956
|
+
* When provided, called instead of `Date.now()` to obtain the `observedAt`
|
|
3957
|
+
* timestamp for each projected fact. Defaults to `Date.now`.
|
|
3958
|
+
* @returns Current Unix timestamp in milliseconds.
|
|
3959
|
+
*/
|
|
3960
|
+
readonly now?: () => number;
|
|
3961
|
+
}
|
|
3962
|
+
/**
|
|
3963
|
+
* Create a one-way outbound transport that projects bus messages into sanitized
|
|
3964
|
+
* {@link SubjectTelemetryFact} events and forwards only those facts upstream.
|
|
3965
|
+
*
|
|
3966
|
+
* ## Behavior
|
|
3967
|
+
*
|
|
3968
|
+
* **Outbound (send):**
|
|
3969
|
+
* - Projectable messages (`event`, `request`, `broadcast`) are projected into
|
|
3970
|
+
* `subject-telemetry.fact` events via {@link projectSubjectTelemetryFacts}
|
|
3971
|
+
* and forwarded to `inner.send()`. The raw application payload is never
|
|
3972
|
+
* forwarded.
|
|
3973
|
+
* - Non-projectable messages (`response`, `subscribe`, `heartbeat`, etc.) are
|
|
3974
|
+
* silently dropped. This transport is strictly outbound; control and response
|
|
3975
|
+
* messages must not be relayed to the upstream collector.
|
|
3976
|
+
*
|
|
3977
|
+
* **Inbound (onReceive):**
|
|
3978
|
+
* - The transport registers a receive handler on `inner` but silently drops all
|
|
3979
|
+
* inbound messages. Control messages (`heartbeat`, `subscribe-ack`,
|
|
3980
|
+
* `subscribe-sync-complete`) are consumed silently. Application messages
|
|
3981
|
+
* arriving from upstream are dropped to prevent raw remote data from
|
|
3982
|
+
* propagating into the local bus.
|
|
3983
|
+
*
|
|
3984
|
+
* Connection and readiness operations delegate to `inner`. Subscription
|
|
3985
|
+
* advertisement is deliberately not forwarded: this transport is telemetry-only
|
|
3986
|
+
* and must not make the upstream collector believe it can route application
|
|
3987
|
+
* subjects back to this runtime.
|
|
3988
|
+
* @param options - Configuration including the inner transport, namespace
|
|
3989
|
+
* registry, optional machine ID, and optional clock override.
|
|
3990
|
+
* @returns A {@link BusTransport} that emits only projected telemetry facts.
|
|
3991
|
+
*/
|
|
3992
|
+
declare function createProjectedTelemetryTransport(options: ProjectedTelemetryTransportOptions): BusTransport;
|
|
3993
|
+
//#endregion
|
|
3994
|
+
export { type BroadcastContext, type BroadcastResult, type BusBroadcastMessage, type BusBroadcastResponseMessage, BusError, type BusEventMessage, type BusHeartbeatMessage, BusLifecycle, type BusMessage, type BusMessageObserver, type BusNamespace, type BusReceiveHandler, type BusRequestMessage, type BusResponseMessage, type BusSubscribeMessage, type BusSubscribeSyncCompleteMessage, type BusSubscriptionAckMessage, type BusTransport, type BusTransportError, type BusTransportKeys, type BusTransportRegistry, type BusUnsubscribeMessage, type BusUrlConfig, type BusValidationMode, ChannelAuthError, ChannelClosedError, type ChannelEndpoint, type ChannelEndpointOptions, ChannelOnlyError, type ConnectOptions, type ConnectedPayload, CorrelationTracker, DEFAULT_REQUEST_TIMEOUT_MS, type DefinedSubjectExtension, type DisconnectedPayload, type EventSubjectExtension, type ExtendedSubjectDefinition, type ExtensionNamespace, type ExtensionNamespaceConfig, type ExtensionNamespaceExtensions, type ExtensionNamespaceFromConfig, type IDirectChannel, type IFilteredBus, type IMakaioBus, type InterceptorContext, LOCAL_ORIGIN, LocalSubjectError, MakaioBus, type MakaioBusContext, NO_HANDLER_ERROR_CODE, type NamespaceRegistrationOptions, NoHandlerError, type ObservedBusMessage, type OnOptions, OnceAbortError, type OptionalResult, type ProjectableBusMessage, type ProjectedTelemetryTransportOptions, REMOTE_ORIGIN, RequestError, type RequestSubjectExtension, type SchemaViolationCallback, type SchemaViolationReport, type ScopedBus, type ScopedBusFor, type SubjectExtension, type SubjectTelemetryAttributes, type SubjectTelemetryProjectionInput, type SubjectTelemetryProjector, type SubjectTelemetryProjectorInput, type SubjectTelemetryProjectorRegistry, type SubscriptionEntry, SystemChannelSchemas, TimeoutError, type TransportRegistration, ValidationError, __resetWarnedSubjects, buildSubscribeMessage, buildUnsubscribeMessage, channelSubject, collectorOnlySubject, createBusContext, createBusInstance, createChannelEndpoint, createExtensionNamespace, createFilteredBus, createProjectedTelemetryTransport, createSubjectTelemetryProjectorRegistry, defaultTransports, defineSubjectExtension, deserializeTransportError, extendSubjectImpl as extendSubject, getFullSubjectForSubjectDefinition, getPath, getSubjectFromBusMessage, handleCorrelationResponse, isNoHandlerErrorForSubject, isRequestSchema, localSubject, matchesAnySubscription, matchesFilter, matchesSubscription, mergeFilters, openChannel, parseBusUrl, projectSubjectTelemetryFacts, serializeTransportError, shouldReceiveMessage, trackMessageCorrelation, waitForSubscriptionPropagation };
|