every-plugin 2.10.0 → 3.0.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/every-plugin-serve.mjs +12 -0
- package/bin/every-plugin.mjs +59 -0
- package/dist/_virtual/_rolldown/runtime.cjs +1 -2
- package/dist/build/artifact-names.cjs +119 -0
- package/dist/build/artifact-names.cjs.map +1 -0
- package/dist/build/artifact-names.d.cts +68 -0
- package/dist/build/artifact-names.d.cts.map +1 -0
- package/dist/build/artifact-names.d.mts +68 -0
- package/dist/build/artifact-names.d.mts.map +1 -0
- package/dist/build/artifact-names.mjs +102 -0
- package/dist/build/artifact-names.mjs.map +1 -0
- package/dist/build/contract-types.cjs +89 -0
- package/dist/build/contract-types.cjs.map +1 -0
- package/dist/build/contract-types.mjs +81 -0
- package/dist/build/contract-types.mjs.map +1 -0
- package/dist/build/rspack/build-report-plugin.cjs +37 -0
- package/dist/build/rspack/build-report-plugin.cjs.map +1 -0
- package/dist/build/rspack/build-report-plugin.d.cts +18 -0
- package/dist/build/rspack/build-report-plugin.d.cts.map +1 -0
- package/dist/build/rspack/build-report-plugin.d.mts +18 -0
- package/dist/build/rspack/build-report-plugin.d.mts.map +1 -0
- package/dist/build/rspack/build-report-plugin.mjs +37 -0
- package/dist/build/rspack/build-report-plugin.mjs.map +1 -0
- package/dist/build/rspack/chunk-completeness-plugin.cjs +47 -0
- package/dist/build/rspack/chunk-completeness-plugin.cjs.map +1 -0
- package/dist/build/rspack/chunk-completeness-plugin.mjs +47 -0
- package/dist/build/rspack/chunk-completeness-plugin.mjs.map +1 -0
- package/dist/build/rspack/compose.cjs +69 -0
- package/dist/build/rspack/compose.cjs.map +1 -0
- package/dist/build/rspack/compose.d.cts +20 -0
- package/dist/build/rspack/compose.d.cts.map +1 -0
- package/dist/build/rspack/compose.d.mts +20 -0
- package/dist/build/rspack/compose.d.mts.map +1 -0
- package/dist/build/rspack/compose.mjs +65 -0
- package/dist/build/rspack/compose.mjs.map +1 -0
- package/dist/build/rspack/fix-mf-data-uri-plugin.cjs +11 -11
- package/dist/build/rspack/fix-mf-data-uri-plugin.cjs.map +1 -1
- package/dist/build/rspack/fix-mf-data-uri-plugin.d.cts +2 -0
- package/dist/build/rspack/fix-mf-data-uri-plugin.d.cts.map +1 -1
- package/dist/build/rspack/fix-mf-data-uri-plugin.d.mts +2 -0
- package/dist/build/rspack/fix-mf-data-uri-plugin.d.mts.map +1 -1
- package/dist/build/rspack/fix-mf-data-uri-plugin.mjs +11 -10
- package/dist/build/rspack/fix-mf-data-uri-plugin.mjs.map +1 -1
- package/dist/build/rspack/generated-config.cjs +35 -0
- package/dist/build/rspack/generated-config.cjs.map +1 -0
- package/dist/build/rspack/generated-config.mjs +32 -0
- package/dist/build/rspack/generated-config.mjs.map +1 -0
- package/dist/build/rspack/index.cjs +8 -5
- package/dist/build/rspack/index.d.cts +5 -3
- package/dist/build/rspack/index.d.mts +5 -3
- package/dist/build/rspack/index.mjs +5 -3
- package/dist/build/rspack/module-federation.cjs +2 -2
- package/dist/build/rspack/module-federation.cjs.map +1 -1
- package/dist/build/rspack/module-federation.mjs +1 -1
- package/dist/build/rspack/module-federation.mjs.map +1 -1
- package/dist/build/rspack/plugin.cjs +44 -69
- package/dist/build/rspack/plugin.cjs.map +1 -1
- package/dist/build/rspack/plugin.d.cts +4 -13
- package/dist/build/rspack/plugin.d.cts.map +1 -1
- package/dist/build/rspack/plugin.d.mts +4 -13
- package/dist/build/rspack/plugin.d.mts.map +1 -1
- package/dist/build/rspack/plugin.mjs +44 -69
- package/dist/build/rspack/plugin.mjs.map +1 -1
- package/dist/build/rspack/utils.cjs +7 -5
- package/dist/build/rspack/utils.cjs.map +1 -1
- package/dist/build/rspack/utils.mjs +7 -6
- package/dist/build/rspack/utils.mjs.map +1 -1
- package/dist/build/ui/factory.cjs +88 -0
- package/dist/build/ui/factory.cjs.map +1 -0
- package/dist/build/ui/factory.d.cts +11 -0
- package/dist/build/ui/factory.d.cts.map +1 -0
- package/dist/build/ui/factory.d.mts +11 -0
- package/dist/build/ui/factory.d.mts.map +1 -0
- package/dist/build/ui/factory.mjs +80 -0
- package/dist/build/ui/factory.mjs.map +1 -0
- package/dist/build/ui/generated-config.cjs +118 -0
- package/dist/build/ui/generated-config.cjs.map +1 -0
- package/dist/build/ui/generated-config.d.cts +33 -0
- package/dist/build/ui/generated-config.d.cts.map +1 -0
- package/dist/build/ui/generated-config.d.mts +33 -0
- package/dist/build/ui/generated-config.d.mts.map +1 -0
- package/dist/build/ui/generated-config.mjs +111 -0
- package/dist/build/ui/generated-config.mjs.map +1 -0
- package/dist/build/ui/hash-artifacts-plugin.cjs +61 -0
- package/dist/build/ui/hash-artifacts-plugin.cjs.map +1 -0
- package/dist/build/ui/hash-artifacts-plugin.d.cts +20 -0
- package/dist/build/ui/hash-artifacts-plugin.d.cts.map +1 -0
- package/dist/build/ui/hash-artifacts-plugin.d.mts +20 -0
- package/dist/build/ui/hash-artifacts-plugin.d.mts.map +1 -0
- package/dist/build/ui/hash-artifacts-plugin.mjs +58 -0
- package/dist/build/ui/hash-artifacts-plugin.mjs.map +1 -0
- package/dist/build/ui/index.cjs +90 -0
- package/dist/build/ui/index.cjs.map +1 -0
- package/dist/build/ui/index.d.cts +29 -0
- package/dist/build/ui/index.d.cts.map +1 -0
- package/dist/build/ui/index.d.mts +29 -0
- package/dist/build/ui/index.d.mts.map +1 -0
- package/dist/build/ui/index.mjs +68 -0
- package/dist/build/ui/index.mjs.map +1 -0
- package/dist/build/ui/manifest-plugin.cjs +37 -0
- package/dist/build/ui/manifest-plugin.cjs.map +1 -0
- package/dist/build/ui/manifest-plugin.d.cts +19 -0
- package/dist/build/ui/manifest-plugin.d.cts.map +1 -0
- package/dist/build/ui/manifest-plugin.d.mts +19 -0
- package/dist/build/ui/manifest-plugin.d.mts.map +1 -0
- package/dist/build/ui/manifest-plugin.mjs +37 -0
- package/dist/build/ui/manifest-plugin.mjs.map +1 -0
- package/dist/build/ui/rsbuild-config.cjs +203 -0
- package/dist/build/ui/rsbuild-config.cjs.map +1 -0
- package/dist/build/ui/rsbuild-config.d.cts +45 -0
- package/dist/build/ui/rsbuild-config.d.cts.map +1 -0
- package/dist/build/ui/rsbuild-config.d.mts +45 -0
- package/dist/build/ui/rsbuild-config.d.mts.map +1 -0
- package/dist/build/ui/rsbuild-config.mjs +200 -0
- package/dist/build/ui/rsbuild-config.mjs.map +1 -0
- package/dist/build/ui/stubs.cjs +107 -0
- package/dist/build/ui/stubs.cjs.map +1 -0
- package/dist/build/ui/stubs.d.cts +25 -0
- package/dist/build/ui/stubs.d.cts.map +1 -0
- package/dist/build/ui/stubs.d.mts +25 -0
- package/dist/build/ui/stubs.d.mts.map +1 -0
- package/dist/build/ui/stubs.mjs +106 -0
- package/dist/build/ui/stubs.mjs.map +1 -0
- package/dist/cli.cjs +83 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +6 -0
- package/dist/cli.d.cts.map +1 -0
- package/dist/cli.d.mts +6 -0
- package/dist/cli.d.mts.map +1 -0
- package/dist/cli.mjs +82 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/dev/serve.cjs +390 -0
- package/dist/dev/serve.cjs.map +1 -0
- package/dist/dev/serve.d.cts +23 -0
- package/dist/dev/serve.d.cts.map +1 -0
- package/dist/dev/serve.d.mts +23 -0
- package/dist/dev/serve.d.mts.map +1 -0
- package/dist/dev/serve.mjs +384 -0
- package/dist/dev/serve.mjs.map +1 -0
- package/dist/dev/watch-kill.cjs +39 -0
- package/dist/dev/watch-kill.cjs.map +1 -0
- package/dist/dev/watch-kill.mjs +38 -0
- package/dist/dev/watch-kill.mjs.map +1 -0
- package/dist/effect-helpers.cjs +23 -0
- package/dist/effect-helpers.cjs.map +1 -0
- package/dist/effect-helpers.d.cts +20 -0
- package/dist/effect-helpers.d.cts.map +1 -0
- package/dist/effect-helpers.d.mts +20 -0
- package/dist/effect-helpers.d.mts.map +1 -0
- package/dist/effect-helpers.mjs +22 -0
- package/dist/effect-helpers.mjs.map +1 -0
- package/dist/errors.cjs +49 -69
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.cts +13 -96
- package/dist/errors.d.cts.map +1 -1
- package/dist/errors.d.mts +13 -96
- package/dist/errors.d.mts.map +1 -1
- package/dist/errors.mjs +16 -34
- package/dist/errors.mjs.map +1 -1
- package/dist/identity.cjs +19 -0
- package/dist/identity.cjs.map +1 -0
- package/dist/identity.d.cts +33 -0
- package/dist/identity.d.cts.map +1 -0
- package/dist/identity.d.mts +33 -0
- package/dist/identity.d.mts.map +1 -0
- package/dist/identity.mjs +16 -0
- package/dist/identity.mjs.map +1 -0
- package/dist/index.cjs +8 -5
- package/dist/index.d.cts +8 -6
- package/dist/index.d.mts +8 -6
- package/dist/index.mjs +6 -4
- package/dist/plugin.cjs +12 -26
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.cts +44 -25
- package/dist/plugin.d.cts.map +1 -1
- package/dist/plugin.d.mts +45 -26
- package/dist/plugin.d.mts.map +1 -1
- package/dist/plugin.mjs +15 -29
- package/dist/plugin.mjs.map +1 -1
- package/dist/remote-entry.cjs +103 -0
- package/dist/remote-entry.cjs.map +1 -0
- package/dist/remote-entry.d.cts +53 -0
- package/dist/remote-entry.d.cts.map +1 -0
- package/dist/remote-entry.d.mts +53 -0
- package/dist/remote-entry.d.mts.map +1 -0
- package/dist/remote-entry.mjs +98 -0
- package/dist/remote-entry.mjs.map +1 -0
- package/dist/runtime/errors.cjs +140 -34
- package/dist/runtime/errors.cjs.map +1 -1
- package/dist/runtime/errors.d.cts +42 -7
- package/dist/runtime/errors.d.cts.map +1 -1
- package/dist/runtime/errors.d.mts +42 -7
- package/dist/runtime/errors.d.mts.map +1 -1
- package/dist/runtime/errors.mjs +136 -31
- package/dist/runtime/errors.mjs.map +1 -1
- package/dist/runtime/index.cjs +95 -23
- package/dist/runtime/index.cjs.map +1 -1
- package/dist/runtime/index.d.cts +16 -0
- package/dist/runtime/index.d.cts.map +1 -1
- package/dist/runtime/index.d.mts +16 -0
- package/dist/runtime/index.d.mts.map +1 -1
- package/dist/runtime/index.mjs +98 -26
- package/dist/runtime/index.mjs.map +1 -1
- package/dist/runtime/mf-config.cjs +3 -78
- package/dist/runtime/mf-config.cjs.map +1 -1
- package/dist/runtime/mf-config.d.cts +3 -49
- package/dist/runtime/mf-config.d.cts.map +1 -1
- package/dist/runtime/mf-config.d.mts +3 -49
- package/dist/runtime/mf-config.d.mts.map +1 -1
- package/dist/runtime/mf-config.mjs +5 -78
- package/dist/runtime/mf-config.mjs.map +1 -1
- package/dist/runtime/services/module-federation.service.cjs +63 -12
- package/dist/runtime/services/module-federation.service.cjs.map +1 -1
- package/dist/runtime/services/module-federation.service.d.cts +4 -13
- package/dist/runtime/services/module-federation.service.d.mts +4 -13
- package/dist/runtime/services/module-federation.service.mjs +63 -14
- package/dist/runtime/services/module-federation.service.mjs.map +1 -1
- package/dist/runtime/services/normalize.cjs +2 -22
- package/dist/runtime/services/normalize.d.cts +2 -21
- package/dist/runtime/services/normalize.d.mts +2 -21
- package/dist/runtime/services/normalize.mjs +2 -21
- package/dist/runtime/services/plugin-lifecycle.service.cjs +9 -11
- package/dist/runtime/services/plugin-lifecycle.service.cjs.map +1 -1
- package/dist/runtime/services/plugin-lifecycle.service.d.cts +3 -16
- package/dist/runtime/services/plugin-lifecycle.service.d.mts +3 -16
- package/dist/runtime/services/plugin-lifecycle.service.mjs +10 -13
- package/dist/runtime/services/plugin-lifecycle.service.mjs.map +1 -1
- package/dist/runtime/services/plugin-loader.service.cjs +30 -29
- package/dist/runtime/services/plugin-loader.service.cjs.map +1 -1
- package/dist/runtime/services/plugin-loader.service.d.cts +6 -53
- package/dist/runtime/services/plugin-loader.service.d.mts +6 -53
- package/dist/runtime/services/plugin-loader.service.mjs +29 -30
- package/dist/runtime/services/plugin-loader.service.mjs.map +1 -1
- package/dist/runtime/services/plugin.service.cjs +10 -12
- package/dist/runtime/services/plugin.service.cjs.map +1 -1
- package/dist/runtime/services/plugin.service.d.cts +14 -36
- package/dist/runtime/services/plugin.service.d.cts.map +1 -1
- package/dist/runtime/services/plugin.service.d.mts +14 -36
- package/dist/runtime/services/plugin.service.d.mts.map +1 -1
- package/dist/runtime/services/plugin.service.mjs +14 -18
- package/dist/runtime/services/plugin.service.mjs.map +1 -1
- package/dist/runtime/services/secrets.service.cjs +12 -12
- package/dist/runtime/services/secrets.service.cjs.map +1 -1
- package/dist/runtime/services/secrets.service.d.cts +3 -15
- package/dist/runtime/services/secrets.service.d.mts +3 -15
- package/dist/runtime/services/secrets.service.mjs +12 -13
- package/dist/runtime/services/secrets.service.mjs.map +1 -1
- package/dist/runtime/services/shared-identity.cjs +40 -0
- package/dist/runtime/services/shared-identity.cjs.map +1 -0
- package/dist/runtime/services/shared-identity.mjs +38 -0
- package/dist/runtime/services/shared-identity.mjs.map +1 -0
- package/dist/runtime/validation.cjs +2 -2
- package/dist/runtime/validation.cjs.map +1 -1
- package/dist/runtime/validation.mjs +2 -2
- package/dist/runtime/validation.mjs.map +1 -1
- package/dist/shared-deps-spec.cjs +384 -0
- package/dist/shared-deps-spec.cjs.map +1 -0
- package/dist/shared-deps-spec.d.cts +182 -0
- package/dist/shared-deps-spec.d.cts.map +1 -0
- package/dist/shared-deps-spec.d.mts +182 -0
- package/dist/shared-deps-spec.d.mts.map +1 -0
- package/dist/shared-deps-spec.mjs +368 -0
- package/dist/shared-deps-spec.mjs.map +1 -0
- package/dist/types.d.cts +22 -41
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +22 -41
- package/dist/types.d.mts.map +1 -1
- package/dist/ui/manifest/construct.cjs +268 -0
- package/dist/ui/manifest/construct.cjs.map +1 -0
- package/dist/ui/manifest/construct.d.cts +48 -0
- package/dist/ui/manifest/construct.d.cts.map +1 -0
- package/dist/ui/manifest/construct.d.mts +48 -0
- package/dist/ui/manifest/construct.d.mts.map +1 -0
- package/dist/ui/manifest/construct.mjs +268 -0
- package/dist/ui/manifest/construct.mjs.map +1 -0
- package/dist/ui/manifest/contract.cjs +34 -0
- package/dist/ui/manifest/contract.cjs.map +1 -0
- package/dist/ui/manifest/contract.d.cts +26 -0
- package/dist/ui/manifest/contract.d.cts.map +1 -0
- package/dist/ui/manifest/contract.d.mts +26 -0
- package/dist/ui/manifest/contract.d.mts.map +1 -0
- package/dist/ui/manifest/contract.mjs +26 -0
- package/dist/ui/manifest/contract.mjs.map +1 -0
- package/dist/ui/manifest/descriptor.cjs +64 -0
- package/dist/ui/manifest/descriptor.cjs.map +1 -0
- package/dist/ui/manifest/descriptor.d.cts +60 -0
- package/dist/ui/manifest/descriptor.d.cts.map +1 -0
- package/dist/ui/manifest/descriptor.d.mts +60 -0
- package/dist/ui/manifest/descriptor.d.mts.map +1 -0
- package/dist/ui/manifest/descriptor.mjs +61 -0
- package/dist/ui/manifest/descriptor.mjs.map +1 -0
- package/dist/ui/manifest/generator.cjs +128 -0
- package/dist/ui/manifest/generator.cjs.map +1 -0
- package/dist/ui/manifest/generator.d.cts +41 -0
- package/dist/ui/manifest/generator.d.cts.map +1 -0
- package/dist/ui/manifest/generator.d.mts +41 -0
- package/dist/ui/manifest/generator.d.mts.map +1 -0
- package/dist/ui/manifest/generator.mjs +125 -0
- package/dist/ui/manifest/generator.mjs.map +1 -0
- package/dist/ui/manifest/index.cjs +35 -0
- package/dist/ui/manifest/index.d.cts +9 -0
- package/dist/ui/manifest/index.d.mts +9 -0
- package/dist/ui/manifest/index.mjs +9 -0
- package/dist/ui/manifest/manifest-schema.cjs +97 -0
- package/dist/ui/manifest/manifest-schema.cjs.map +1 -0
- package/dist/ui/manifest/manifest-schema.d.cts +132 -0
- package/dist/ui/manifest/manifest-schema.d.cts.map +1 -0
- package/dist/ui/manifest/manifest-schema.d.mts +132 -0
- package/dist/ui/manifest/manifest-schema.d.mts.map +1 -0
- package/dist/ui/manifest/manifest-schema.mjs +90 -0
- package/dist/ui/manifest/manifest-schema.mjs.map +1 -0
- package/dist/ui/manifest/mount-registry.cjs +52 -0
- package/dist/ui/manifest/mount-registry.cjs.map +1 -0
- package/dist/ui/manifest/mount-registry.d.cts +61 -0
- package/dist/ui/manifest/mount-registry.d.cts.map +1 -0
- package/dist/ui/manifest/mount-registry.d.mts +61 -0
- package/dist/ui/manifest/mount-registry.d.mts.map +1 -0
- package/dist/ui/manifest/mount-registry.mjs +48 -0
- package/dist/ui/manifest/mount-registry.mjs.map +1 -0
- package/dist/ui/manifest/nav.cjs +13 -0
- package/dist/ui/manifest/nav.cjs.map +1 -0
- package/dist/ui/manifest/nav.d.cts +34 -0
- package/dist/ui/manifest/nav.d.cts.map +1 -0
- package/dist/ui/manifest/nav.d.mts +34 -0
- package/dist/ui/manifest/nav.d.mts.map +1 -0
- package/dist/ui/manifest/nav.mjs +13 -0
- package/dist/ui/manifest/nav.mjs.map +1 -0
- package/dist/ui/manifest/route-config.cjs +33 -0
- package/dist/ui/manifest/route-config.cjs.map +1 -0
- package/dist/ui/manifest/route-config.d.cts +40 -0
- package/dist/ui/manifest/route-config.d.cts.map +1 -0
- package/dist/ui/manifest/route-config.d.mts +40 -0
- package/dist/ui/manifest/route-config.d.mts.map +1 -0
- package/dist/ui/manifest/route-config.mjs +33 -0
- package/dist/ui/manifest/route-config.mjs.map +1 -0
- package/dist/version-manifest.cjs +65 -0
- package/dist/version-manifest.cjs.map +1 -0
- package/dist/version-manifest.d.cts +52 -0
- package/dist/version-manifest.d.cts.map +1 -0
- package/dist/version-manifest.d.mts +52 -0
- package/dist/version-manifest.d.mts.map +1 -0
- package/dist/version-manifest.mjs +63 -0
- package/dist/version-manifest.mjs.map +1 -0
- package/package.json +165 -68
- package/skills/plugin-client/SKILL.md +24 -5
- package/skills/plugin-development/SKILL.md +79 -47
- package/skills/plugin-testing/SKILL.md +41 -12
- package/src/build/artifact-names.ts +117 -0
- package/src/build/contract-types.ts +101 -0
- package/src/build/rspack/build-report-plugin.ts +34 -0
- package/src/build/rspack/chunk-completeness-plugin.ts +57 -0
- package/src/build/rspack/compose.ts +87 -0
- package/src/build/rspack/fix-mf-data-uri-plugin.ts +23 -12
- package/src/build/rspack/generated-config.ts +35 -0
- package/src/build/rspack/index.ts +10 -5
- package/src/build/rspack/module-federation.ts +1 -1
- package/src/build/rspack/plugin.ts +103 -105
- package/src/build/rspack/utils.ts +8 -2
- package/src/build/ui/factory.ts +96 -0
- package/src/build/ui/generated-config.ts +133 -0
- package/src/build/ui/hash-artifacts-plugin.ts +79 -0
- package/src/build/ui/index.ts +98 -0
- package/src/build/ui/manifest-plugin.ts +54 -0
- package/src/build/ui/rsbuild-config.ts +256 -0
- package/src/build/ui/stubs.ts +103 -0
- package/src/cli.ts +100 -0
- package/src/dev/serve.ts +477 -0
- package/src/dev/watch-kill.ts +58 -0
- package/src/effect-helpers.ts +25 -0
- package/src/errors.ts +16 -18
- package/src/identity.ts +36 -0
- package/src/index.ts +4 -0
- package/src/plugin.ts +70 -92
- package/src/remote-entry.ts +171 -0
- package/src/runtime/errors.ts +186 -27
- package/src/runtime/index.ts +132 -43
- package/src/runtime/mf-config.ts +12 -107
- package/src/runtime/services/module-federation.service.ts +221 -117
- package/src/runtime/services/normalize.ts +1 -18
- package/src/runtime/services/plugin-lifecycle.service.ts +66 -75
- package/src/runtime/services/plugin-loader.service.ts +239 -212
- package/src/runtime/services/plugin.service.ts +61 -43
- package/src/runtime/services/secrets.service.ts +20 -15
- package/src/runtime/services/shared-identity.ts +68 -0
- package/src/runtime/validation.ts +5 -7
- package/src/shared-deps-spec.ts +478 -0
- package/src/types.ts +22 -48
- package/src/ui/manifest/construct.ts +403 -0
- package/src/ui/manifest/contract.ts +33 -0
- package/src/ui/manifest/descriptor.ts +96 -0
- package/src/ui/manifest/generator.ts +238 -0
- package/src/ui/manifest/index.ts +55 -0
- package/src/ui/manifest/manifest-schema.ts +107 -0
- package/src/ui/manifest/mount-registry.ts +50 -0
- package/src/ui/manifest/nav.ts +43 -0
- package/src/ui/manifest/route-config.ts +82 -0
- package/src/version-manifest.ts +88 -0
- package/dist/build/rspack/dev-server-middleware.cjs +0 -194
- package/dist/build/rspack/dev-server-middleware.cjs.map +0 -1
- package/dist/build/rspack/dev-server-middleware.mjs +0 -193
- package/dist/build/rspack/dev-server-middleware.mjs.map +0 -1
- package/dist/build/shared-deps.cjs +0 -83
- package/dist/build/shared-deps.cjs.map +0 -1
- package/dist/build/shared-deps.d.cts +0 -67
- package/dist/build/shared-deps.d.cts.map +0 -1
- package/dist/build/shared-deps.d.mts +0 -67
- package/dist/build/shared-deps.d.mts.map +0 -1
- package/dist/build/shared-deps.mjs +0 -79
- package/dist/build/shared-deps.mjs.map +0 -1
- package/dist/effect.cjs +0 -9
- package/dist/effect.d.cts +0 -1
- package/dist/effect.d.mts +0 -1
- package/dist/effect.mjs +0 -3
- package/dist/orpc-openapi.cjs +0 -17
- package/dist/orpc-openapi.d.cts +0 -2
- package/dist/orpc-openapi.d.mts +0 -2
- package/dist/orpc-openapi.mjs +0 -5
- package/dist/orpc.cjs +0 -46
- package/dist/orpc.d.cts +0 -7
- package/dist/orpc.d.mts +0 -7
- package/dist/orpc.mjs +0 -11
- package/dist/package.cjs +0 -23
- package/dist/package.cjs.map +0 -1
- package/dist/package.mjs +0 -17
- package/dist/package.mjs.map +0 -1
- package/dist/runtime/services/module-federation.service.d.cts.map +0 -1
- package/dist/runtime/services/module-federation.service.d.mts.map +0 -1
- package/dist/runtime/services/normalize.cjs.map +0 -1
- package/dist/runtime/services/normalize.d.cts.map +0 -1
- package/dist/runtime/services/normalize.d.mts.map +0 -1
- package/dist/runtime/services/normalize.mjs.map +0 -1
- package/dist/runtime/services/plugin-lifecycle.service.d.cts.map +0 -1
- package/dist/runtime/services/plugin-lifecycle.service.d.mts.map +0 -1
- package/dist/runtime/services/plugin-loader.service.d.cts.map +0 -1
- package/dist/runtime/services/plugin-loader.service.d.mts.map +0 -1
- package/dist/runtime/services/secrets.service.d.cts.map +0 -1
- package/dist/runtime/services/secrets.service.d.mts.map +0 -1
- package/dist/testing/index.cjs +0 -57
- package/dist/testing/index.cjs.map +0 -1
- package/dist/testing/index.d.cts +0 -54
- package/dist/testing/index.d.cts.map +0 -1
- package/dist/testing/index.d.mts +0 -54
- package/dist/testing/index.d.mts.map +0 -1
- package/dist/testing/index.mjs +0 -55
- package/dist/testing/index.mjs.map +0 -1
- package/dist/zod-core.cjs +0 -9
- package/dist/zod-core.d.cts +0 -1
- package/dist/zod-core.d.mts +0 -1
- package/dist/zod-core.mjs +0 -3
- package/dist/zod.cjs +0 -11
- package/dist/zod.d.cts +0 -2
- package/dist/zod.d.mts +0 -2
- package/dist/zod.mjs +0 -3
- package/src/build/rspack/dev-server-middleware.ts +0 -250
- package/src/build/shared-deps.ts +0 -102
- package/src/effect.ts +0 -1
- package/src/orpc-openapi.ts +0 -2
- package/src/orpc.ts +0 -9
- package/src/testing/index.ts +0 -87
- package/src/testing/mocks/module-federation.service.ts +0 -41
- package/src/zod-core.ts +0 -1
- package/src/zod.ts +0 -3
package/dist/runtime/errors.mjs
CHANGED
|
@@ -1,10 +1,27 @@
|
|
|
1
|
-
import { ORPCError } from "@orpc/contract";
|
|
2
1
|
import { Cause, Data } from "effect";
|
|
2
|
+
import { ORPCError } from "@orpc/server";
|
|
3
3
|
|
|
4
4
|
//#region src/runtime/errors.ts
|
|
5
|
-
var PluginRuntimeError = class extends Data.TaggedError("PluginRuntimeError") {
|
|
5
|
+
var PluginRuntimeError = class extends Data.TaggedError("PluginRuntimeError") {
|
|
6
|
+
get message() {
|
|
7
|
+
return this.cause?.message ?? "Plugin operation failed";
|
|
8
|
+
}
|
|
9
|
+
};
|
|
6
10
|
var ModuleFederationError = class extends Data.TaggedError("ModuleFederationError") {};
|
|
7
11
|
var ValidationError = class extends Data.TaggedError("ValidationError") {};
|
|
12
|
+
const stringifyUnknown = (value) => {
|
|
13
|
+
if (value === null) return "null";
|
|
14
|
+
if (value === void 0) return "undefined";
|
|
15
|
+
if (value instanceof Error) return value.message;
|
|
16
|
+
if (typeof value === "string") return value;
|
|
17
|
+
if (typeof value === "number" || typeof value === "bigint" || typeof value === "boolean") return `${value}`;
|
|
18
|
+
if (typeof value === "symbol") return value.description ?? "";
|
|
19
|
+
try {
|
|
20
|
+
return JSON.stringify(value) ?? "[Unserializable value]";
|
|
21
|
+
} catch {
|
|
22
|
+
return "[Unserializable value]";
|
|
23
|
+
}
|
|
24
|
+
};
|
|
8
25
|
const extractErrorMessage = (error) => {
|
|
9
26
|
if (!error) return "Unknown error";
|
|
10
27
|
if (error instanceof Error) {
|
|
@@ -13,7 +30,25 @@ const extractErrorMessage = (error) => {
|
|
|
13
30
|
}
|
|
14
31
|
if (error instanceof AggregateError && error.errors?.length) return error.errors.map((e) => extractErrorMessage(e)).join("; ");
|
|
15
32
|
if (typeof error === "object" && "message" in error) return String(error.message);
|
|
16
|
-
return
|
|
33
|
+
return stringifyUnknown(error);
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* The deepest Error along the cause chain — the original throw site. Wrapper
|
|
37
|
+
* errors (PluginRuntimeError, ModuleFederationError) carry their own stacks
|
|
38
|
+
* (the wrapping frames); diagnosis needs the cause's stack (the actual
|
|
39
|
+
* failing module inside the evaluated remote entry).
|
|
40
|
+
*/
|
|
41
|
+
const deepestErrorStack = (error) => {
|
|
42
|
+
let current = error;
|
|
43
|
+
let deepest;
|
|
44
|
+
let hops = 0;
|
|
45
|
+
while (current instanceof Error && hops < 8) {
|
|
46
|
+
if (current.stack) deepest = current.stack;
|
|
47
|
+
current = current.cause;
|
|
48
|
+
hops += 1;
|
|
49
|
+
}
|
|
50
|
+
if (current instanceof Error && current.stack) deepest = current.stack;
|
|
51
|
+
return deepest;
|
|
17
52
|
};
|
|
18
53
|
const formatValidationIssue = (issue, index, maxDisplay) => {
|
|
19
54
|
if (index >= maxDisplay) return "";
|
|
@@ -33,7 +68,7 @@ const formatDataPreview = (data, maxLength = 100) => {
|
|
|
33
68
|
}
|
|
34
69
|
return `${str.slice(0, maxLength)}...`;
|
|
35
70
|
} catch {
|
|
36
|
-
return
|
|
71
|
+
return stringifyUnknown(data).slice(0, maxLength);
|
|
37
72
|
}
|
|
38
73
|
};
|
|
39
74
|
const formatORPCValidationError = (error) => {
|
|
@@ -59,18 +94,31 @@ const formatORPCValidationError = (error) => {
|
|
|
59
94
|
lines.push(`╰${"─".repeat(50)}\n`);
|
|
60
95
|
return lines;
|
|
61
96
|
};
|
|
97
|
+
const formatUnknownError = (error) => {
|
|
98
|
+
if (!error) return null;
|
|
99
|
+
const message = extractErrorMessage(error);
|
|
100
|
+
const lines = [];
|
|
101
|
+
lines.push(`\n╭─ Unhandled error ${"─".repeat(37)}`);
|
|
102
|
+
for (const line of message.split("\n")) lines.push(`│ ${line}`);
|
|
103
|
+
const stack = error instanceof Error ? error.stack?.split("\n").slice(1, 6) : void 0;
|
|
104
|
+
if (stack && stack.length > 0) {
|
|
105
|
+
lines.push(`│`);
|
|
106
|
+
for (const line of stack) lines.push(`│ ${line.trim()}`);
|
|
107
|
+
}
|
|
108
|
+
lines.push(`╰${"─".repeat(50)}\n`);
|
|
109
|
+
return lines.join("\n");
|
|
110
|
+
};
|
|
62
111
|
const formatORPCError = (error) => {
|
|
63
|
-
if (!(error instanceof ORPCError)) return
|
|
112
|
+
if (!(error instanceof ORPCError)) return formatUnknownError(error);
|
|
64
113
|
const validationLines = formatORPCValidationError(error);
|
|
65
114
|
if (validationLines) return validationLines.join("\n");
|
|
66
115
|
const lines = [];
|
|
67
116
|
const code = error.code || "UNKNOWN";
|
|
68
|
-
const status = error.status || 500;
|
|
69
117
|
const message = error.message || "An error occurred";
|
|
70
118
|
lines.push(`\n╭─ oRPC Error ${"─".repeat(40)}`);
|
|
71
119
|
const messageLines = message.split("\n");
|
|
72
120
|
for (const line of messageLines) lines.push(`│ ${line}`);
|
|
73
|
-
lines.push(`│ Code: ${code}
|
|
121
|
+
lines.push(`│ Code: ${code}`);
|
|
74
122
|
lines.push(`│`);
|
|
75
123
|
if (error.data) {
|
|
76
124
|
if (typeof error.data === "object" && error.data !== null) {
|
|
@@ -95,38 +143,96 @@ const formatORPCError = (error) => {
|
|
|
95
143
|
case "GATEWAY_TIMEOUT":
|
|
96
144
|
lines.push(`│ → The service may be temporarily unavailable`);
|
|
97
145
|
break;
|
|
98
|
-
case "TIMEOUT":
|
|
99
|
-
lines.push(`│ → The operation took too long`);
|
|
100
|
-
break;
|
|
146
|
+
case "TIMEOUT": lines.push(`│ → The operation took too long`);
|
|
101
147
|
}
|
|
102
148
|
lines.push(`╰${"─".repeat(50)}\n`);
|
|
103
149
|
return lines.join("\n");
|
|
104
150
|
};
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
151
|
+
const NETWORK_RETRYABLE_PATTERNS = [
|
|
152
|
+
"ETIMEDOUT",
|
|
153
|
+
"ECONNRESET",
|
|
154
|
+
"timeout",
|
|
155
|
+
"503",
|
|
156
|
+
"429"
|
|
157
|
+
];
|
|
158
|
+
const NETWORK_DEAD_PATTERNS = [
|
|
159
|
+
"ECONNREFUSED",
|
|
160
|
+
"ENOTFOUND",
|
|
161
|
+
"EHOSTUNREACH"
|
|
162
|
+
];
|
|
163
|
+
const RETRYABLE_ORPC_CODES = /* @__PURE__ */ new Set([
|
|
164
|
+
"TOO_MANY_REQUESTS",
|
|
165
|
+
"SERVICE_UNAVAILABLE",
|
|
166
|
+
"BAD_GATEWAY",
|
|
167
|
+
"GATEWAY_TIMEOUT",
|
|
168
|
+
"TIMEOUT"
|
|
169
|
+
]);
|
|
170
|
+
/**
|
|
171
|
+
* One classification for plugin lifecycle failures across MF / validation /
|
|
172
|
+
* network sources. This is the recovery policy — nothing in the runtime
|
|
173
|
+
* retries on it today by design (the host degrades and runs without a failed
|
|
174
|
+
* plugin); consumers (host bootstrap messages, the dev server retry loop)
|
|
175
|
+
* read kind / retryable / suggestion to decide what to tell the author.
|
|
176
|
+
*/
|
|
177
|
+
const classifyPluginFailure = (error) => {
|
|
178
|
+
let current = extractFromFiberFailure(error);
|
|
179
|
+
let hops = 0;
|
|
180
|
+
while (current && typeof current === "object" && hops < 8) {
|
|
181
|
+
if (current instanceof ModuleFederationError) return {
|
|
182
|
+
kind: "mf",
|
|
183
|
+
retryable: false,
|
|
184
|
+
message: extractErrorMessage(current),
|
|
185
|
+
suggestion: "Run bos mf check — the deployed plugin bundle is likely stale (sharedDep / pluginVersion skew), then redeploy the plugin and bos publish --deploy --packages local"
|
|
186
|
+
};
|
|
187
|
+
if (current instanceof ValidationError) return {
|
|
188
|
+
kind: "validation",
|
|
189
|
+
retryable: false,
|
|
190
|
+
message: `${current.stage}: ${extractErrorMessage(current.zodError)}`,
|
|
191
|
+
suggestion: `Fix the plugin's ${current.stage} schema at plugins/${current.pluginId}`
|
|
192
|
+
};
|
|
193
|
+
if (current instanceof ORPCError) {
|
|
194
|
+
const retryableByCode = RETRYABLE_ORPC_CODES.has(current.code);
|
|
195
|
+
return {
|
|
196
|
+
kind: "network",
|
|
197
|
+
retryable: retryableByCode,
|
|
198
|
+
message: current.message,
|
|
199
|
+
suggestion: retryableByCode ? "The plugin procedure failed transiently — retry the call" : void 0
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
current = current.cause;
|
|
203
|
+
hops += 1;
|
|
122
204
|
}
|
|
205
|
+
const message = extractErrorMessage(error);
|
|
206
|
+
const lower = message.toLowerCase();
|
|
207
|
+
if (NETWORK_RETRYABLE_PATTERNS.some((p) => lower.includes(p.toLowerCase()))) return {
|
|
208
|
+
kind: "network",
|
|
209
|
+
retryable: true,
|
|
210
|
+
message,
|
|
211
|
+
suggestion: "The remote may be temporarily unavailable — retry after redeploying the plugin"
|
|
212
|
+
};
|
|
213
|
+
if (NETWORK_DEAD_PATTERNS.some((p) => lower.includes(p.toLowerCase()))) return {
|
|
214
|
+
kind: "network",
|
|
215
|
+
retryable: false,
|
|
216
|
+
message,
|
|
217
|
+
suggestion: "The plugin host is unreachable — check plugins.<id> entry URLs in bos.config.json"
|
|
218
|
+
};
|
|
219
|
+
if (lower.includes("integrity") || lower.includes("sri")) return {
|
|
220
|
+
kind: "integrity",
|
|
221
|
+
retryable: true,
|
|
222
|
+
message,
|
|
223
|
+
suggestion: "The deployed bundle content does not match its recorded integrity — redeploy the plugin so bos.config.json is republished with a fresh hash"
|
|
224
|
+
};
|
|
225
|
+
return {
|
|
226
|
+
kind: "unknown",
|
|
227
|
+
retryable: false,
|
|
228
|
+
message
|
|
229
|
+
};
|
|
123
230
|
};
|
|
124
231
|
const wrapORPCError = (orpcError, pluginId, procedureName, operation) => {
|
|
125
232
|
return new PluginRuntimeError({
|
|
126
233
|
pluginId,
|
|
127
234
|
operation,
|
|
128
235
|
procedureName,
|
|
129
|
-
retryable: isRetryableORPCCode(orpcError.code),
|
|
130
236
|
cause: orpcError
|
|
131
237
|
});
|
|
132
238
|
};
|
|
@@ -148,18 +254,17 @@ const extractFromFiberFailure = (error) => {
|
|
|
148
254
|
}
|
|
149
255
|
return error;
|
|
150
256
|
};
|
|
151
|
-
const toPluginRuntimeError = (error, pluginId, procedureName, operation
|
|
257
|
+
const toPluginRuntimeError = (error, pluginId, procedureName, operation) => {
|
|
152
258
|
if (error instanceof ORPCError) return wrapORPCError(error, pluginId, procedureName, operation);
|
|
153
259
|
if (error instanceof PluginRuntimeError) return error;
|
|
154
260
|
return new PluginRuntimeError({
|
|
155
261
|
pluginId,
|
|
156
262
|
operation,
|
|
157
263
|
procedureName,
|
|
158
|
-
retryable: defaultRetryable || isRetryableError(extractErrorMessage(error)),
|
|
159
264
|
cause: error instanceof Error ? error : new Error(extractErrorMessage(error))
|
|
160
265
|
});
|
|
161
266
|
};
|
|
162
267
|
|
|
163
268
|
//#endregion
|
|
164
|
-
export { ModuleFederationError, PluginRuntimeError, ValidationError, extractFromFiberFailure, formatORPCError,
|
|
269
|
+
export { ModuleFederationError, PluginRuntimeError, ValidationError, classifyPluginFailure, deepestErrorStack, extractFromFiberFailure, formatORPCError, toPluginRuntimeError, wrapORPCError };
|
|
165
270
|
//# sourceMappingURL=errors.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.mjs","names":[],"sources":["../../src/runtime/errors.ts"],"sourcesContent":["import { ORPCError } from \"@orpc/contract\";\nimport { Cause, Data } from \"effect\";\nimport type { z } from \"zod\";\n\nexport class PluginRuntimeError extends Data.TaggedError(\"PluginRuntimeError\")<{\n readonly pluginId?: string;\n readonly operation?: string;\n readonly procedureName?: string;\n readonly cause?: Error;\n readonly retryable: boolean;\n}> {}\n\nexport class ModuleFederationError extends Data.TaggedError(\"ModuleFederationError\")<{\n readonly pluginId: string;\n readonly remoteUrl: string;\n readonly cause?: Error;\n}> {}\n\nexport class ValidationError extends Data.TaggedError(\"ValidationError\")<{\n readonly pluginId: string;\n readonly stage: \"config\" | \"input\" | \"output\" | \"state\";\n readonly zodError: z.ZodError;\n}> {}\n\nconst extractErrorMessage = (error: unknown): string => {\n if (!error) return \"Unknown error\";\n\n if (error instanceof Error) {\n if (error.message) return error.message;\n if ((error as any).cause instanceof Error) {\n return extractErrorMessage((error as any).cause);\n }\n }\n\n if (error instanceof AggregateError && error.errors?.length) {\n return error.errors.map((e) => extractErrorMessage(e)).join(\"; \");\n }\n\n if (typeof error === \"object\" && \"message\" in error) {\n return String((error as any).message);\n }\n\n return String(error);\n};\n\nconst formatValidationIssue = (issue: any, index: number, maxDisplay: number): string => {\n if (index >= maxDisplay) return \"\";\n\n const path =\n Array.isArray(issue.path) && issue.path.length > 0\n ? issue.path.join(\".\")\n : issue.path || \"root\";\n\n const message = issue.message || \"Validation failed\";\n\n return `│ ${index + 1}. ${path}: ${message}`;\n};\n\nconst formatDataPreview = (data: unknown, maxLength = 100): string => {\n if (!data) return \"undefined\";\n\n try {\n const str = JSON.stringify(data);\n if (str.length <= maxLength) return str;\n\n if (typeof data === \"object\" && data !== null) {\n if (Array.isArray(data)) {\n return `Array(${data.length}) [...]`;\n }\n const keys = Object.keys(data);\n return `{ ${keys.slice(0, 3).join(\", \")}${keys.length > 3 ? \", ...\" : \"\"} }`;\n }\n\n return `${str.slice(0, maxLength)}...`;\n } catch {\n return String(data).slice(0, maxLength);\n }\n};\n\nconst formatORPCValidationError = (error: any): string[] | null => {\n const cause = error?.cause || error;\n\n if (!cause?.issues || !Array.isArray(cause.issues) || cause.issues.length === 0) {\n return null;\n }\n\n const lines: string[] = [];\n const errorType = error?.message || cause?.message || \"Validation failed\";\n\n lines.push(`\\n╭─ oRPC Validation Error ${\"─\".repeat(30)}`);\n lines.push(`│ ${errorType}`);\n lines.push(`│`);\n\n const maxDisplay = 10;\n const totalIssues = cause.issues.length;\n\n lines.push(`│ Issues (${totalIssues}):`);\n\n const displayedIssues = cause.issues.slice(0, maxDisplay);\n displayedIssues.forEach((issue: any, idx: number) => {\n const formatted = formatValidationIssue(issue, idx, maxDisplay);\n if (formatted) lines.push(formatted);\n });\n\n if (totalIssues > maxDisplay) {\n lines.push(`│ ... and ${totalIssues - maxDisplay} more`);\n }\n\n if (cause.data !== undefined) {\n lines.push(`│`);\n lines.push(`│ Data preview: ${formatDataPreview(cause.data, 80)}`);\n }\n\n lines.push(`╰${\"─\".repeat(50)}\\n`);\n\n return lines;\n};\n\nexport const formatORPCError = (error: any): string | null => {\n if (!(error instanceof ORPCError)) {\n return null;\n }\n\n const validationLines = formatORPCValidationError(error);\n if (validationLines) {\n return validationLines.join(\"\\n\");\n }\n\n const lines: string[] = [];\n const code = error.code || \"UNKNOWN\";\n const status = error.status || 500;\n const message = error.message || \"An error occurred\";\n\n lines.push(`\\n╭─ oRPC Error ${\"─\".repeat(40)}`);\n const messageLines = message.split(\"\\n\");\n for (const line of messageLines) {\n lines.push(`│ ${line}`);\n }\n lines.push(`│ Code: ${code} (${status})`);\n lines.push(`│`);\n\n if (error.data) {\n const dataType = typeof error.data;\n if (dataType === \"object\" && error.data !== null) {\n if (\"retryAfter\" in error.data) {\n lines.push(`│ Retry after: ${error.data.retryAfter} seconds`);\n }\n if (\"remainingRequests\" in error.data) {\n lines.push(`│ Remaining: ${error.data.remainingRequests} requests`);\n }\n if (\"host\" in error.data) {\n lines.push(`│ Host: ${error.data.host}`);\n }\n if (\"port\" in error.data) {\n lines.push(`│ Port: ${error.data.port}`);\n }\n if (\"suggestion\" in error.data) {\n lines.push(`│ → ${error.data.suggestion}`);\n }\n if (\"resource\" in error.data) {\n lines.push(`│ Resource: ${error.data.resource}`);\n }\n if (\"resourceId\" in error.data) {\n lines.push(`│ ID: ${error.data.resourceId}`);\n }\n }\n }\n\n switch (code) {\n case \"UNAUTHORIZED\":\n lines.push(`│ → Check your API key or credentials`);\n break;\n case \"TOO_MANY_REQUESTS\":\n lines.push(`│ → Wait before retrying`);\n break;\n case \"SERVICE_UNAVAILABLE\":\n case \"BAD_GATEWAY\":\n case \"GATEWAY_TIMEOUT\":\n lines.push(`│ → The service may be temporarily unavailable`);\n break;\n case \"TIMEOUT\":\n lines.push(`│ → The operation took too long`);\n break;\n }\n\n lines.push(`╰${\"─\".repeat(50)}\\n`);\n return lines.join(\"\\n\");\n};\n\nconst isRetryableError = (message: string): boolean => {\n const retryablePatterns = [\"ETIMEDOUT\", \"ECONNRESET\", \"timeout\", \"503\", \"429\"];\n return retryablePatterns.some((p) => message.toLowerCase().includes(p.toLowerCase()));\n};\n\n// Helper to determine if an oRPC error code is retryable\nexport const isRetryableORPCCode = (code: string): boolean => {\n switch (code) {\n case \"TOO_MANY_REQUESTS\":\n case \"SERVICE_UNAVAILABLE\":\n case \"BAD_GATEWAY\":\n case \"GATEWAY_TIMEOUT\":\n case \"TIMEOUT\":\n return true;\n default:\n return false;\n }\n};\n\n// Convert ORPC errors from plugin procedures to PluginRuntimeError\nexport const wrapORPCError = (\n orpcError: ORPCError<string, unknown>,\n pluginId?: string,\n procedureName?: string,\n operation?: string,\n): PluginRuntimeError => {\n return new PluginRuntimeError({\n pluginId,\n operation,\n procedureName,\n retryable: isRetryableORPCCode(orpcError.code),\n cause: orpcError as Error,\n });\n};\n\n/**\n * Extracts the underlying error from Effect's FiberFailure wrapper.\n * When Effect.runPromise rejects, errors are wrapped in FiberFailure.\n * This extracts the original error so oRPC can handle it properly.\n */\nexport const extractFromFiberFailure = (error: unknown): unknown => {\n if (!error || typeof error !== \"object\") return error;\n\n if (\"cause\" in error) {\n const cause = (error as { cause?: unknown }).cause;\n\n if (cause && typeof cause === \"object\" && \"_tag\" in cause) {\n try {\n const squashed = Cause.squash(cause as Cause.Cause<unknown>);\n if (squashed instanceof ORPCError) {\n return squashed;\n }\n return squashed;\n } catch {\n // Not a valid Cause\n }\n }\n\n if (cause instanceof ORPCError) {\n return cause;\n }\n }\n\n return error;\n};\n\n// Universal error converter for the runtime\nexport const toPluginRuntimeError = (\n error: unknown,\n pluginId?: string,\n procedureName?: string,\n operation?: string,\n defaultRetryable = false,\n): PluginRuntimeError => {\n if (error instanceof ORPCError) {\n return wrapORPCError(error, pluginId, procedureName, operation);\n }\n\n if (error instanceof PluginRuntimeError) {\n return error;\n }\n\n return new PluginRuntimeError({\n pluginId,\n operation,\n procedureName,\n retryable: defaultRetryable || isRetryableError(extractErrorMessage(error)),\n cause: error instanceof Error ? error : new Error(extractErrorMessage(error)),\n });\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"errors.mjs","names":[],"sources":["../../src/runtime/errors.ts"],"sourcesContent":["import { ORPCError } from \"@orpc/server\";\nimport { Cause, Data } from \"effect\";\nimport type { z } from \"zod\";\n\nexport class PluginRuntimeError extends Data.TaggedError(\"PluginRuntimeError\")<{\n readonly pluginId?: string;\n readonly operation?: string;\n readonly procedureName?: string;\n readonly cause?: Error;\n}> {\n override get message() {\n return this.cause?.message ?? \"Plugin operation failed\";\n }\n}\n\nexport class ModuleFederationError extends Data.TaggedError(\"ModuleFederationError\")<{\n readonly pluginId: string;\n readonly remoteUrl: string;\n readonly cause?: Error;\n}> {}\n\nexport class ValidationError extends Data.TaggedError(\"ValidationError\")<{\n readonly pluginId: string;\n readonly stage: \"config\" | \"input\" | \"output\" | \"state\";\n readonly zodError: z.ZodError;\n}> {}\n\nconst stringifyUnknown = (value: unknown): string => {\n if (value === null) return \"null\";\n if (value === undefined) return \"undefined\";\n if (value instanceof Error) return value.message;\n if (typeof value === \"string\") return value;\n if (typeof value === \"number\" || typeof value === \"bigint\" || typeof value === \"boolean\") {\n return `${value}`;\n }\n if (typeof value === \"symbol\") return value.description ?? \"\";\n try {\n return JSON.stringify(value) ?? \"[Unserializable value]\";\n } catch {\n return \"[Unserializable value]\";\n }\n};\n\nconst extractErrorMessage = (error: unknown): string => {\n if (!error) return \"Unknown error\";\n\n if (error instanceof Error) {\n if (error.message) return error.message;\n if ((error as any).cause instanceof Error) {\n return extractErrorMessage((error as any).cause);\n }\n }\n\n if (error instanceof AggregateError && error.errors?.length) {\n return error.errors.map((e) => extractErrorMessage(e)).join(\"; \");\n }\n\n if (typeof error === \"object\" && \"message\" in error) {\n return String((error as any).message);\n }\n\n return stringifyUnknown(error);\n};\n\n/**\n * The deepest Error along the cause chain — the original throw site. Wrapper\n * errors (PluginRuntimeError, ModuleFederationError) carry their own stacks\n * (the wrapping frames); diagnosis needs the cause's stack (the actual\n * failing module inside the evaluated remote entry).\n */\nexport const deepestErrorStack = (error: unknown): string | undefined => {\n let current = error;\n let deepest: string | undefined;\n let hops = 0;\n while (current instanceof Error && hops < 8) {\n if (current.stack) deepest = current.stack;\n current = (current as { cause?: unknown }).cause as unknown;\n hops += 1;\n }\n if (current instanceof Error && current.stack) deepest = current.stack;\n return deepest;\n};\n\nconst formatValidationIssue = (issue: any, index: number, maxDisplay: number): string => {\n if (index >= maxDisplay) return \"\";\n\n const path =\n Array.isArray(issue.path) && issue.path.length > 0\n ? issue.path.join(\".\")\n : issue.path || \"root\";\n\n const message = issue.message || \"Validation failed\";\n\n return `│ ${index + 1}. ${path}: ${message}`;\n};\n\nconst formatDataPreview = (data: unknown, maxLength = 100): string => {\n if (!data) return \"undefined\";\n\n try {\n const str = JSON.stringify(data);\n if (str.length <= maxLength) return str;\n\n if (typeof data === \"object\" && data !== null) {\n if (Array.isArray(data)) {\n return `Array(${data.length}) [...]`;\n }\n const keys = Object.keys(data);\n return `{ ${keys.slice(0, 3).join(\", \")}${keys.length > 3 ? \", ...\" : \"\"} }`;\n }\n\n return `${str.slice(0, maxLength)}...`;\n } catch {\n return stringifyUnknown(data).slice(0, maxLength);\n }\n};\n\nconst formatORPCValidationError = (error: any): string[] | null => {\n const cause = error?.cause || error;\n\n if (!cause?.issues || !Array.isArray(cause.issues) || cause.issues.length === 0) {\n return null;\n }\n\n const lines: string[] = [];\n const errorType = error?.message || cause?.message || \"Validation failed\";\n\n lines.push(`\\n╭─ oRPC Validation Error ${\"─\".repeat(30)}`);\n lines.push(`│ ${errorType}`);\n lines.push(`│`);\n\n const maxDisplay = 10;\n const totalIssues = cause.issues.length;\n\n lines.push(`│ Issues (${totalIssues}):`);\n\n const displayedIssues = cause.issues.slice(0, maxDisplay);\n displayedIssues.forEach((issue: any, idx: number) => {\n const formatted = formatValidationIssue(issue, idx, maxDisplay);\n if (formatted) lines.push(formatted);\n });\n\n if (totalIssues > maxDisplay) {\n lines.push(`│ ... and ${totalIssues - maxDisplay} more`);\n }\n\n if (cause.data !== undefined) {\n lines.push(`│`);\n lines.push(`│ Data preview: ${formatDataPreview(cause.data, 80)}`);\n }\n\n lines.push(`╰${\"─\".repeat(50)}\\n`);\n\n return lines;\n};\n\nconst formatUnknownError = (error: any): string | null => {\n if (!error) return null;\n const message = extractErrorMessage(error);\n const lines: string[] = [];\n lines.push(`\\n╭─ Unhandled error ${\"─\".repeat(37)}`);\n for (const line of message.split(\"\\n\")) {\n lines.push(`│ ${line}`);\n }\n const stack = error instanceof Error ? error.stack?.split(\"\\n\").slice(1, 6) : undefined;\n if (stack && stack.length > 0) {\n lines.push(`│`);\n for (const line of stack) {\n lines.push(`│ ${line.trim()}`);\n }\n }\n lines.push(`╰${\"─\".repeat(50)}\\n`);\n return lines.join(\"\\n\");\n};\n\nexport const formatORPCError = (error: any): string | null => {\n if (!(error instanceof ORPCError)) {\n // Unknown errors used to return null, leaving internal failures (e.g. a\n // storage backend throw) invisible in host logs while oRPC serialized\n // them client-side as a bare INTERNAL_SERVER_ERROR.\n return formatUnknownError(error);\n }\n\n const validationLines = formatORPCValidationError(error);\n if (validationLines) {\n return validationLines.join(\"\\n\");\n }\n\n const lines: string[] = [];\n const code = error.code || \"UNKNOWN\";\n const message = error.message || \"An error occurred\";\n\n lines.push(`\\n╭─ oRPC Error ${\"─\".repeat(40)}`);\n const messageLines = message.split(\"\\n\");\n for (const line of messageLines) {\n lines.push(`│ ${line}`);\n }\n lines.push(`│ Code: ${code}`);\n lines.push(`│`);\n\n if (error.data) {\n const dataType = typeof error.data;\n if (dataType === \"object\" && error.data !== null) {\n if (\"retryAfter\" in error.data) {\n lines.push(`│ Retry after: ${error.data.retryAfter} seconds`);\n }\n if (\"remainingRequests\" in error.data) {\n lines.push(`│ Remaining: ${error.data.remainingRequests} requests`);\n }\n if (\"host\" in error.data) {\n lines.push(`│ Host: ${error.data.host}`);\n }\n if (\"port\" in error.data) {\n lines.push(`│ Port: ${error.data.port}`);\n }\n if (\"suggestion\" in error.data) {\n lines.push(`│ → ${error.data.suggestion}`);\n }\n if (\"resource\" in error.data) {\n lines.push(`│ Resource: ${error.data.resource}`);\n }\n if (\"resourceId\" in error.data) {\n lines.push(`│ ID: ${error.data.resourceId}`);\n }\n }\n }\n\n switch (code) {\n case \"UNAUTHORIZED\":\n lines.push(`│ → Check your API key or credentials`);\n break;\n case \"TOO_MANY_REQUESTS\":\n lines.push(`│ → Wait before retrying`);\n break;\n case \"SERVICE_UNAVAILABLE\":\n case \"BAD_GATEWAY\":\n case \"GATEWAY_TIMEOUT\":\n lines.push(`│ → The service may be temporarily unavailable`);\n break;\n case \"TIMEOUT\":\n lines.push(`│ → The operation took too long`);\n break;\n }\n\n lines.push(`╰${\"─\".repeat(50)}\\n`);\n return lines.join(\"\\n\");\n};\n\nexport type PluginFailureKind =\n | \"mf\"\n | \"integrity\"\n | \"config\"\n | \"validation\"\n | \"network\"\n | \"unknown\";\n\nexport interface PluginFailureClassification {\n kind: PluginFailureKind;\n retryable: boolean;\n message: string;\n suggestion?: string;\n}\n\n/**\n * Structured report of one plugin-load failure, built by a loader (the host's\n * plugin boot, the dev server) from a `PluginFailureClassification` plus\n * loader context. This is the shape health endpoints and dashboards consume —\n * keep it serializable.\n */\nexport interface PluginLoadFailureInfo {\n /** loader-side key (host entry key, dev plugin id) */\n pluginKey: string;\n pluginUrl?: string;\n /** failing runtime stage when the cause is stage-attributed */\n operation?: string;\n kind: string;\n retryable: boolean;\n message: string;\n suggestion?: string;\n /** loader context: which env secret the plugin's DB binding expects */\n dbSecret?: string;\n dbUrlMasked?: string;\n}\n\nconst NETWORK_RETRYABLE_PATTERNS = [\"ETIMEDOUT\", \"ECONNRESET\", \"timeout\", \"503\", \"429\"] as const;\nconst NETWORK_DEAD_PATTERNS = [\"ECONNREFUSED\", \"ENOTFOUND\", \"EHOSTUNREACH\"] as const;\nconst RETRYABLE_ORPC_CODES = new Set([\n \"TOO_MANY_REQUESTS\",\n \"SERVICE_UNAVAILABLE\",\n \"BAD_GATEWAY\",\n \"GATEWAY_TIMEOUT\",\n \"TIMEOUT\",\n]);\n\n/**\n * One classification for plugin lifecycle failures across MF / validation /\n * network sources. This is the recovery policy — nothing in the runtime\n * retries on it today by design (the host degrades and runs without a failed\n * plugin); consumers (host bootstrap messages, the dev server retry loop)\n * read kind / retryable / suggestion to decide what to tell the author.\n */\nexport const classifyPluginFailure = (error: unknown): PluginFailureClassification => {\n let current: unknown = extractFromFiberFailure(error);\n let hops = 0;\n while (current && typeof current === \"object\" && hops < 8) {\n if (current instanceof ModuleFederationError) {\n return {\n kind: \"mf\",\n retryable: false,\n message: extractErrorMessage(current),\n suggestion:\n \"Run bos mf check — the deployed plugin bundle is likely stale (sharedDep / pluginVersion skew), then redeploy the plugin and bos publish --deploy --packages local\",\n };\n }\n if (current instanceof ValidationError) {\n return {\n kind: \"validation\",\n retryable: false,\n message: `${current.stage}: ${extractErrorMessage(current.zodError)}`,\n suggestion: `Fix the plugin's ${current.stage} schema at plugins/${current.pluginId}`,\n };\n }\n if (current instanceof ORPCError) {\n const retryableByCode = RETRYABLE_ORPC_CODES.has(current.code);\n return {\n kind: \"network\",\n retryable: retryableByCode,\n message: current.message,\n suggestion: retryableByCode\n ? \"The plugin procedure failed transiently — retry the call\"\n : undefined,\n };\n }\n current = (current as { cause?: unknown }).cause;\n hops += 1;\n }\n\n const message = extractErrorMessage(error);\n const lower = message.toLowerCase();\n\n if (NETWORK_RETRYABLE_PATTERNS.some((p) => lower.includes(p.toLowerCase()))) {\n return {\n kind: \"network\",\n retryable: true,\n message,\n suggestion: \"The remote may be temporarily unavailable — retry after redeploying the plugin\",\n };\n }\n if (NETWORK_DEAD_PATTERNS.some((p) => lower.includes(p.toLowerCase()))) {\n return {\n kind: \"network\",\n retryable: false,\n message,\n suggestion:\n \"The plugin host is unreachable — check plugins.<id> entry URLs in bos.config.json\",\n };\n }\n if (lower.includes(\"integrity\") || lower.includes(\"sri\")) {\n return {\n kind: \"integrity\",\n retryable: true,\n message,\n suggestion:\n \"The deployed bundle content does not match its recorded integrity — redeploy the plugin so bos.config.json is republished with a fresh hash\",\n };\n }\n\n return { kind: \"unknown\", retryable: false, message };\n};\n\n// Convert ORPC errors from plugin procedures to PluginRuntimeError\nexport const wrapORPCError = (\n orpcError: ORPCError<string, unknown>,\n pluginId?: string,\n procedureName?: string,\n operation?: string,\n): PluginRuntimeError => {\n return new PluginRuntimeError({\n pluginId,\n operation,\n procedureName,\n cause: orpcError as Error,\n });\n};\n\n/**\n * Extracts the underlying error from Effect's FiberFailure wrapper.\n * When Effect.runPromise rejects, errors are wrapped in FiberFailure.\n * This extracts the original error so oRPC can handle it properly.\n */\nexport const extractFromFiberFailure = (error: unknown): unknown => {\n if (!error || typeof error !== \"object\") return error;\n\n if (\"cause\" in error) {\n const cause = (error as { cause?: unknown }).cause;\n\n if (cause && typeof cause === \"object\" && \"_tag\" in cause) {\n try {\n const squashed = Cause.squash(cause as unknown as Cause.Cause<unknown>);\n if (squashed instanceof ORPCError) {\n return squashed;\n }\n return squashed;\n } catch {\n // Not a valid Cause\n }\n }\n\n if (cause instanceof ORPCError) {\n return cause;\n }\n }\n\n return error;\n};\n\n// Universal error converter for the runtime\nexport const toPluginRuntimeError = (\n error: unknown,\n pluginId?: string,\n procedureName?: string,\n operation?: string,\n): PluginRuntimeError => {\n if (error instanceof ORPCError) {\n return wrapORPCError(error, pluginId, procedureName, operation);\n }\n\n if (error instanceof PluginRuntimeError) {\n return error;\n }\n\n return new PluginRuntimeError({\n pluginId,\n operation,\n procedureName,\n cause: error instanceof Error ? error : new Error(extractErrorMessage(error)),\n });\n};\n"],"mappings":"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"}
|
package/dist/runtime/index.cjs
CHANGED
|
@@ -1,35 +1,85 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
const require_errors = require('./errors.cjs');
|
|
3
|
+
const require_build_artifact_names = require('../build/artifact-names.cjs');
|
|
3
4
|
const require_plugin_service = require('./services/plugin.service.cjs');
|
|
5
|
+
require("@orpc/openapi/extensions/route");
|
|
4
6
|
let effect = require("effect");
|
|
5
7
|
let _orpc_server = require("@orpc/server");
|
|
8
|
+
require("@orpc/experimental-effect/extensions/effect");
|
|
6
9
|
|
|
7
10
|
//#region src/runtime/index.ts
|
|
11
|
+
const MAX_CACHE_KEY_DEPTH = 32;
|
|
8
12
|
var PluginRuntime = class {
|
|
9
13
|
runtime;
|
|
10
14
|
registry;
|
|
11
15
|
__registryType;
|
|
12
16
|
pluginCache = /* @__PURE__ */ new Map();
|
|
17
|
+
routerCache = /* @__PURE__ */ new Map();
|
|
18
|
+
cacheLeafIds = /* @__PURE__ */ new WeakMap();
|
|
19
|
+
nextCacheLeafId = 0;
|
|
13
20
|
constructor(runtime, registry) {
|
|
14
21
|
this.runtime = runtime;
|
|
15
22
|
this.registry = registry;
|
|
16
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Cache key for plugin instances: JSON-equal configs share one plugin
|
|
26
|
+
* instance (variables and secrets originate from bos.config.json, so they
|
|
27
|
+
* are JSON values). Values outside the JSON domain follow Effect's Hash
|
|
28
|
+
* semantics — symbols key by description, functions and class instances by
|
|
29
|
+
* reference identity — and the host creates its pluginsClient map once per
|
|
30
|
+
* boot, making identity the correct equivalence for function-bearing
|
|
31
|
+
* configs.
|
|
32
|
+
*/
|
|
17
33
|
generateCacheKey(pluginId, config) {
|
|
18
|
-
return `${pluginId}:${
|
|
34
|
+
return `${pluginId}:${this.canonicalizeConfig(config, 0, /* @__PURE__ */ new Set())}`;
|
|
35
|
+
}
|
|
36
|
+
canonicalizeConfig(value, depth, ancestors) {
|
|
37
|
+
switch (typeof value) {
|
|
38
|
+
case "undefined": return "undefined";
|
|
39
|
+
case "string": return `string:${JSON.stringify(value)}`;
|
|
40
|
+
case "number": return `number:${Object.is(value, -0) ? "-0" : String(value)}`;
|
|
41
|
+
case "bigint": return `bigint:${value.toString()}`;
|
|
42
|
+
case "boolean": return `boolean:${value}`;
|
|
43
|
+
case "symbol": return `symbol:${String(value)}`;
|
|
44
|
+
case "function": return `ref:${this.getCacheLeafId(value)}`;
|
|
45
|
+
case "object": {
|
|
46
|
+
if (value === null) return "null";
|
|
47
|
+
if (ancestors.has(value) || depth >= MAX_CACHE_KEY_DEPTH) return `ref:${this.getCacheLeafId(value)}`;
|
|
48
|
+
if (Array.isArray(value)) {
|
|
49
|
+
ancestors.add(value);
|
|
50
|
+
const serialized = `[${value.map((item) => this.canonicalizeConfig(item, depth + 1, ancestors)).join(",")}]`;
|
|
51
|
+
ancestors.delete(value);
|
|
52
|
+
return serialized;
|
|
53
|
+
}
|
|
54
|
+
const prototype = Object.getPrototypeOf(value);
|
|
55
|
+
if (prototype !== Object.prototype && prototype !== null) return `ref:${this.getCacheLeafId(value)}`;
|
|
56
|
+
const record = value;
|
|
57
|
+
ancestors.add(value);
|
|
58
|
+
const serialized = `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${this.canonicalizeConfig(record[key], depth + 1, ancestors)}`).join(",")}}`;
|
|
59
|
+
ancestors.delete(value);
|
|
60
|
+
return serialized;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
getCacheLeafId(value) {
|
|
65
|
+
const existing = this.cacheLeafIds.get(value);
|
|
66
|
+
if (existing !== void 0) return existing;
|
|
67
|
+
const id = this.nextCacheLeafId++;
|
|
68
|
+
this.cacheLeafIds.set(value, id);
|
|
69
|
+
return id;
|
|
19
70
|
}
|
|
20
71
|
validatePluginId(pluginId) {
|
|
21
72
|
if (!(pluginId in this.registry)) return effect.Effect.fail(new require_errors.PluginRuntimeError({
|
|
22
73
|
pluginId: String(pluginId),
|
|
23
74
|
operation: "validate-plugin-id",
|
|
24
|
-
cause: /* @__PURE__ */ new Error(`Plugin ID '${String(pluginId)}' not found in registry.`)
|
|
25
|
-
retryable: false
|
|
75
|
+
cause: /* @__PURE__ */ new Error(`Plugin ID '${String(pluginId)}' not found in registry.`)
|
|
26
76
|
}));
|
|
27
77
|
return effect.Effect.succeed(String(pluginId));
|
|
28
78
|
}
|
|
29
79
|
async runPromise(effect$1) {
|
|
30
80
|
const exit = await this.runtime.runPromiseExit(effect$1);
|
|
31
81
|
if (effect.Exit.isFailure(exit)) {
|
|
32
|
-
const error = effect.Cause.
|
|
82
|
+
const error = effect.Cause.findErrorOption(exit.cause);
|
|
33
83
|
if (effect.Option.isSome(error)) throw error.value;
|
|
34
84
|
throw effect.Cause.squash(exit.cause);
|
|
35
85
|
}
|
|
@@ -42,7 +92,7 @@ var PluginRuntime = class {
|
|
|
42
92
|
});
|
|
43
93
|
let cachedPlugin = this.pluginCache.get(cacheKey);
|
|
44
94
|
if (!cachedPlugin) {
|
|
45
|
-
const operation = effect.Effect.gen(this, function* () {
|
|
95
|
+
const operation = effect.Effect.gen({ self: this }, function* () {
|
|
46
96
|
const pluginService = yield* require_plugin_service.PluginService;
|
|
47
97
|
const validatedId = yield* this.validatePluginId(pluginId);
|
|
48
98
|
const ctor = yield* pluginService.loadPlugin(validatedId);
|
|
@@ -50,19 +100,32 @@ var PluginRuntime = class {
|
|
|
50
100
|
const initialized = yield* pluginService.initializePlugin(instance, config, plugins);
|
|
51
101
|
yield* pluginService.registerPlugin(initialized);
|
|
52
102
|
return initialized;
|
|
53
|
-
})
|
|
54
|
-
cachedPlugin =
|
|
103
|
+
});
|
|
104
|
+
cachedPlugin = this.runPromise(operation);
|
|
55
105
|
this.pluginCache.set(cacheKey, cachedPlugin);
|
|
56
106
|
}
|
|
57
107
|
let initialized;
|
|
58
108
|
try {
|
|
59
|
-
initialized = await
|
|
109
|
+
initialized = await cachedPlugin;
|
|
60
110
|
} catch (error) {
|
|
61
|
-
this.pluginCache.
|
|
111
|
+
if (this.pluginCache.get(cacheKey) === cachedPlugin) {
|
|
112
|
+
this.pluginCache.delete(cacheKey);
|
|
113
|
+
this.routerCache.delete(cacheKey);
|
|
114
|
+
}
|
|
62
115
|
throw error;
|
|
63
116
|
}
|
|
64
|
-
|
|
65
|
-
|
|
117
|
+
let router = this.routerCache.get(cacheKey);
|
|
118
|
+
if (!router) try {
|
|
119
|
+
router = initialized.plugin.createRouter(plugins ?? {});
|
|
120
|
+
this.routerCache.set(cacheKey, router);
|
|
121
|
+
} catch (error) {
|
|
122
|
+
await this.evictPlugin(pluginId, config, plugins);
|
|
123
|
+
throw error;
|
|
124
|
+
}
|
|
125
|
+
const createClient = (context) => (0, _orpc_server.createRouterClient)(router, { context: {
|
|
126
|
+
...context,
|
|
127
|
+
"effect/context": initialized.effectContext
|
|
128
|
+
} });
|
|
66
129
|
return {
|
|
67
130
|
createClient,
|
|
68
131
|
router,
|
|
@@ -73,13 +136,13 @@ var PluginRuntime = class {
|
|
|
73
136
|
async loadPlugin(pluginId) {
|
|
74
137
|
const effect$2 = effect.Effect.gen(function* () {
|
|
75
138
|
return yield* (yield* require_plugin_service.PluginService).loadPlugin(pluginId);
|
|
76
|
-
})
|
|
139
|
+
});
|
|
77
140
|
return this.runPromise(effect$2);
|
|
78
141
|
}
|
|
79
142
|
async instantiatePlugin(pluginId, loadedPlugin) {
|
|
80
143
|
const effect$3 = effect.Effect.gen(function* () {
|
|
81
144
|
return yield* (yield* require_plugin_service.PluginService).instantiatePlugin(pluginId, loadedPlugin);
|
|
82
|
-
})
|
|
145
|
+
});
|
|
83
146
|
return this.runPromise(effect$3);
|
|
84
147
|
}
|
|
85
148
|
async initializePlugin(instance, config, plugins) {
|
|
@@ -88,30 +151,39 @@ var PluginRuntime = class {
|
|
|
88
151
|
const initialized = yield* pluginService.initializePlugin(instance, config, plugins);
|
|
89
152
|
yield* pluginService.registerPlugin(initialized);
|
|
90
153
|
return initialized;
|
|
91
|
-
})
|
|
154
|
+
});
|
|
92
155
|
return this.runPromise(effect$4);
|
|
93
156
|
}
|
|
94
157
|
async shutdown() {
|
|
95
158
|
const effect$5 = effect.Effect.gen(function* () {
|
|
96
|
-
yield* (yield* require_plugin_service.PluginService).cleanup
|
|
159
|
+
yield* (yield* require_plugin_service.PluginService).cleanup;
|
|
97
160
|
});
|
|
98
|
-
|
|
99
|
-
|
|
161
|
+
try {
|
|
162
|
+
await this.runPromise(effect$5);
|
|
163
|
+
} finally {
|
|
164
|
+
this.pluginCache.clear();
|
|
165
|
+
this.routerCache.clear();
|
|
166
|
+
await this.runtime.dispose();
|
|
167
|
+
}
|
|
100
168
|
}
|
|
101
169
|
async evictPlugin(pluginId, config, plugins) {
|
|
102
170
|
const cacheKey = this.generateCacheKey(pluginId, {
|
|
103
171
|
...config,
|
|
104
172
|
__plugins: plugins ?? {}
|
|
105
173
|
});
|
|
106
|
-
const effect$6 = effect.Effect.gen(this, function* () {
|
|
174
|
+
const effect$6 = effect.Effect.gen({ self: this }, function* () {
|
|
107
175
|
const pluginService = yield* require_plugin_service.PluginService;
|
|
108
176
|
const cachedPlugin = this.pluginCache.get(cacheKey);
|
|
109
177
|
if (cachedPlugin) {
|
|
110
178
|
this.pluginCache.delete(cacheKey);
|
|
111
|
-
|
|
112
|
-
|
|
179
|
+
this.routerCache.delete(cacheKey);
|
|
180
|
+
const pluginResult = yield* effect.Effect.tryPromise({
|
|
181
|
+
try: () => cachedPlugin,
|
|
182
|
+
catch: (error) => require_errors.toPluginRuntimeError(error, pluginId, void 0, "evict-plugin")
|
|
183
|
+
}).pipe(effect.Effect.orElseSucceed(() => null));
|
|
184
|
+
if (pluginResult) yield* pluginService.shutdownPlugin(pluginResult);
|
|
113
185
|
}
|
|
114
|
-
})
|
|
186
|
+
});
|
|
115
187
|
return this.runPromise(effect$6);
|
|
116
188
|
}
|
|
117
189
|
};
|
|
@@ -122,7 +194,7 @@ var PluginRuntime = class {
|
|
|
122
194
|
function normalizeRemoteUrl(url) {
|
|
123
195
|
if (!url) return url;
|
|
124
196
|
if (url.endsWith(".js") || url.endsWith(".json")) return url;
|
|
125
|
-
return `${url.endsWith("/") ? url.slice(0, -1) : url}
|
|
197
|
+
return `${url.endsWith("/") ? url.slice(0, -1) : url}/${require_build_artifact_names.DEV_ENTRY_FILENAME}`;
|
|
126
198
|
}
|
|
127
199
|
/**
|
|
128
200
|
* Extract plugin map (module constructors) from registry entries
|
|
@@ -169,7 +241,7 @@ function createPluginRuntime(config) {
|
|
|
169
241
|
const secrets = config.secrets || {};
|
|
170
242
|
const normalizedRegistry = normalizeRegistry(config.registry);
|
|
171
243
|
const pluginMap = extractPluginMap(config.registry);
|
|
172
|
-
const layer = require_plugin_service.
|
|
244
|
+
const layer = require_plugin_service.PluginServiceLive(normalizedRegistry, secrets, pluginMap);
|
|
173
245
|
const runtime = effect.ManagedRuntime.make(layer);
|
|
174
246
|
return new PluginRuntime(runtime, normalizedRegistry);
|
|
175
247
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["Hash","Effect","PluginRuntimeError","effect","Exit","Cause","Option","PluginService","ManagedRuntime"],"sources":["../../src/runtime/index.ts"],"sourcesContent":["import { createRouterClient } from \"@orpc/server\";\nimport { Cause, Effect, Exit, Hash, ManagedRuntime, Option } from \"effect\";\nimport type {\n AnyPlugin,\n AnyPluginConstructor,\n InferRegistryFromEntries,\n InitializedPlugin,\n LoadedPlugin,\n PluginConfigInput,\n PluginInstance,\n PluginRegistry,\n PluginRegistryEntry,\n PluginRouterType,\n PluginRuntimeConfig,\n RegisteredPlugin,\n RegisteredPlugins,\n UsePluginResult,\n} from \"../types\";\nimport { PluginRuntimeError } from \"./errors\";\nimport { PluginService } from \"./services/plugin.service\";\n\nexport class PluginRuntime<R = RegisteredPlugins> {\n readonly __registryType?: R;\n\n private pluginCache = new Map<\n string,\n Effect.Effect<InitializedPlugin<AnyPlugin>, PluginRuntimeError>\n >();\n\n constructor(\n private runtime: ManagedRuntime.ManagedRuntime<PluginService, never>,\n private registry: PluginRegistry,\n ) {}\n\n private generateCacheKey(pluginId: string, config: unknown): string {\n const configHash = Hash.structure(config as object).toString();\n return `${pluginId}:${configHash}`;\n }\n\n private validatePluginId(pluginId: string): Effect.Effect<string, PluginRuntimeError> {\n if (!(pluginId in this.registry)) {\n return Effect.fail(\n new PluginRuntimeError({\n pluginId: String(pluginId),\n operation: \"validate-plugin-id\",\n cause: new Error(`Plugin ID '${String(pluginId)}' not found in registry.`),\n retryable: false,\n }),\n );\n }\n return Effect.succeed(String(pluginId));\n }\n\n private async runPromise<A, E>(effect: Effect.Effect<A, E, PluginService>): Promise<A> {\n const exit = await this.runtime.runPromiseExit(effect);\n\n if (Exit.isFailure(exit)) {\n const error = Cause.failureOption(exit.cause);\n if (Option.isSome(error)) {\n throw error.value;\n }\n throw Cause.squash(exit.cause);\n }\n\n return exit.value;\n }\n\n async usePlugin<K extends keyof R & string>(\n pluginId: K,\n config: PluginConfigInput<R[K]>,\n plugins?: Record<string, unknown>,\n ): Promise<UsePluginResult<K, R>> {\n const cacheKey = this.generateCacheKey(pluginId, { ...config, __plugins: plugins ?? {} });\n\n let cachedPlugin = this.pluginCache.get(cacheKey);\n if (!cachedPlugin) {\n const operation = Effect.gen(this, function* () {\n const pluginService = yield* PluginService;\n const validatedId = yield* this.validatePluginId(pluginId);\n\n // Load → Instantiate → Initialize → Register\n const ctor = yield* pluginService.loadPlugin(validatedId);\n const instance = yield* pluginService.instantiatePlugin(pluginId, ctor);\n const initialized = yield* pluginService.initializePlugin(instance, config, plugins);\n yield* pluginService.registerPlugin(initialized);\n\n return initialized;\n }).pipe(Effect.annotateLogs({ plugin: pluginId }), Effect.provide(this.runtime));\n\n cachedPlugin = Effect.cached(operation).pipe(Effect.flatten);\n this.pluginCache.set(cacheKey, cachedPlugin);\n }\n\n let initialized: InitializedPlugin<AnyPlugin>;\n try {\n initialized = await this.runPromise(cachedPlugin);\n } catch (error) {\n // Evict failed initializations so the next call retries instead\n // of returning the permanently-cached failure from Effect.cached.\n this.pluginCache.delete(cacheKey);\n throw error;\n }\n\n // Construct the router once per plugin instance, not per client/request.\n const router = initialized.plugin.createRouter(initialized.context) as PluginRouterType<R[K]>;\n\n // Create client factory that accepts request context\n const createClient = (context?: any) => createRouterClient(router, { context: context ?? {} });\n\n return {\n createClient: createClient as any,\n router,\n metadata: initialized.metadata,\n initialized: initialized as InitializedPlugin<RegisteredPlugin<K, R>>,\n } as UsePluginResult<K, R>;\n }\n\n async loadPlugin<K extends keyof R & string>(\n pluginId: K,\n ): Promise<LoadedPlugin<RegisteredPlugin<K, R>>> {\n const effect = Effect.gen(function* () {\n const pluginService = yield* PluginService;\n return yield* pluginService.loadPlugin(pluginId);\n }).pipe(Effect.annotateLogs({ plugin: pluginId }));\n return this.runPromise(effect) as Promise<LoadedPlugin<RegisteredPlugin<K, R>>>;\n }\n\n async instantiatePlugin<K extends keyof R & string>(\n pluginId: K,\n loadedPlugin: LoadedPlugin<RegisteredPlugin<K, R>>,\n ): Promise<PluginInstance<RegisteredPlugin<K, R>>> {\n const effect = Effect.gen(function* () {\n const pluginService = yield* PluginService;\n return yield* pluginService.instantiatePlugin(pluginId, loadedPlugin);\n }).pipe(Effect.annotateLogs({ plugin: pluginId }));\n return this.runPromise(effect) as Promise<PluginInstance<RegisteredPlugin<K, R>>>;\n }\n\n async initializePlugin<T extends AnyPlugin>(\n instance: PluginInstance<T>,\n config: any,\n plugins?: Record<string, unknown>,\n ): Promise<InitializedPlugin<T>> {\n const effect = Effect.gen(function* () {\n const pluginService = yield* PluginService;\n const initialized = yield* pluginService.initializePlugin(instance, config, plugins);\n yield* pluginService.registerPlugin(initialized);\n return initialized;\n }).pipe(Effect.annotateLogs({ plugin: instance.plugin.id }));\n return this.runPromise(effect);\n }\n\n async shutdown(): Promise<void> {\n const effect = Effect.gen(function* () {\n const pluginService = yield* PluginService;\n yield* pluginService.cleanup();\n });\n await this.runPromise(effect);\n await this.runtime.dispose();\n }\n\n async evictPlugin<K extends keyof R & string>(\n pluginId: K,\n config: PluginConfigInput<R[K]>,\n plugins?: Record<string, unknown>,\n ): Promise<void> {\n const cacheKey = this.generateCacheKey(pluginId, { ...config, __plugins: plugins ?? {} });\n\n const effect = Effect.gen(this, function* () {\n const pluginService = yield* PluginService;\n const cachedPlugin = this.pluginCache.get(cacheKey);\n\n if (cachedPlugin) {\n this.pluginCache.delete(cacheKey);\n\n const pluginResult = yield* cachedPlugin.pipe(Effect.catchAll(() => Effect.succeed(null)));\n\n if (pluginResult) {\n yield* pluginService\n .shutdownPlugin(pluginResult)\n .pipe(\n Effect.catchAll((error) =>\n Effect.logWarning(`Failed to shutdown evicted plugin ${pluginId}`, error),\n ),\n );\n }\n }\n }).pipe(\n Effect.catchAll((error) =>\n Effect.logWarning(`Plugin eviction failed for ${pluginId}`, error),\n ),\n );\n\n return this.runPromise(effect);\n }\n}\n\n/**\n * Normalizes a remote URL to ensure it points to remoteEntry.js\n * If the URL doesn't end with a file extension, appends /remoteEntry.js\n */\nfunction normalizeRemoteUrl(url: string): string {\n if (!url) return url;\n if (url.endsWith(\".js\") || url.endsWith(\".json\")) return url;\n return `${url.endsWith(\"/\") ? url.slice(0, -1) : url}/remoteEntry.js`;\n}\n\n/**\n * Extract plugin map (module constructors) from registry entries\n */\nfunction extractPluginMap(\n registry: Record<string, PluginRegistryEntry>,\n): Record<string, AnyPluginConstructor> {\n const pluginMap: Record<string, AnyPluginConstructor> = {};\n\n for (const [pluginId, entry] of Object.entries(registry)) {\n if (\"module\" in entry && entry.module) {\n pluginMap[pluginId] = entry.module;\n }\n }\n\n return pluginMap;\n}\n\n/**\n * Normalize registry entries - ensure remote URLs are properly formatted\n */\nfunction normalizeRegistry(registry: Record<string, PluginRegistryEntry>): PluginRegistry {\n const normalized: Record<string, PluginRegistryEntry> = {};\n\n for (const [pluginId, entry] of Object.entries(registry)) {\n if (\"module\" in entry) {\n normalized[pluginId] = {\n ...entry,\n remote: entry.remote ? normalizeRemoteUrl(entry.remote) : undefined,\n };\n } else {\n normalized[pluginId] = {\n ...entry,\n remote: normalizeRemoteUrl(entry.remote),\n };\n }\n }\n\n return normalized as PluginRegistry;\n}\n\n/**\n * Creates a plugin runtime with support for both module and remote plugin entries.\n *\n * @example\n * ```typescript\n * // With module entries (types inferred automatically)\n * const runtime = createPluginRuntime({\n * registry: {\n * telegram: { module: TelegramPlugin },\n * gopher: { remote: \"https://cdn.example.com/gopher/remoteEntry.js\" }\n * },\n * secrets: { API_KEY: \"...\" }\n * });\n *\n * // Types are automatically inferred from module entries!\n * const { router } = await runtime.usePlugin(\"telegram\", config);\n * ```\n */\nexport function createPluginRuntime<TRegistry extends Record<string, PluginRegistryEntry>>(\n config: PluginRuntimeConfig<TRegistry>,\n): PluginRuntime<InferRegistryFromEntries<TRegistry>> {\n const secrets = config.secrets || {};\n const normalizedRegistry = normalizeRegistry(config.registry);\n const pluginMap = extractPluginMap(config.registry);\n\n const layer = PluginService.Live(normalizedRegistry, secrets, pluginMap);\n const runtime = ManagedRuntime.make(layer);\n\n return new PluginRuntime(runtime, normalizedRegistry) as PluginRuntime<\n InferRegistryFromEntries<TRegistry>\n >;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["Effect","PluginRuntimeError","effect","Exit","Cause","Option","PluginService","createRouterClient","toPluginRuntimeError","DEV_ENTRY_FILENAME","PluginServiceLive","ManagedRuntime"],"sources":["../../src/runtime/index.ts"],"sourcesContent":["import \"@orpc/experimental-effect/extensions/effect\";\nimport \"@orpc/openapi/extensions/route\";\n\nimport { createRouterClient } from \"@orpc/server\";\nimport { Cause, Effect, Exit, ManagedRuntime, Option } from \"effect\";\nimport { DEV_ENTRY_FILENAME } from \"../build/artifact-names\";\nimport type {\n AnyPlugin,\n AnyPluginConstructor,\n InferRegistryFromEntries,\n InitializedPlugin,\n LoadedPlugin,\n PluginConfigInput,\n PluginInstance,\n PluginRegistry,\n PluginRegistryEntry,\n PluginRouterType,\n PluginRuntimeConfig,\n RegisteredPlugin,\n RegisteredPlugins,\n UsePluginResult,\n} from \"../types\";\nimport { PluginRuntimeError, toPluginRuntimeError } from \"./errors\";\nimport { PluginService, PluginServiceLive } from \"./services/plugin.service\";\n\nconst MAX_CACHE_KEY_DEPTH = 32;\n\nexport class PluginRuntime<R = RegisteredPlugins> {\n readonly __registryType?: R;\n\n private pluginCache = new Map<string, Promise<InitializedPlugin<AnyPlugin>>>();\n private routerCache = new Map<string, PluginRouterType<any>>();\n private cacheLeafIds = new WeakMap<object, number>();\n private nextCacheLeafId = 0;\n\n constructor(\n private runtime: ManagedRuntime.ManagedRuntime<PluginService, never>,\n private registry: PluginRegistry,\n ) {}\n\n /**\n * Cache key for plugin instances: JSON-equal configs share one plugin\n * instance (variables and secrets originate from bos.config.json, so they\n * are JSON values). Values outside the JSON domain follow Effect's Hash\n * semantics — symbols key by description, functions and class instances by\n * reference identity — and the host creates its pluginsClient map once per\n * boot, making identity the correct equivalence for function-bearing\n * configs.\n */\n private generateCacheKey(pluginId: string, config: unknown): string {\n return `${pluginId}:${this.canonicalizeConfig(config, 0, new Set())}`;\n }\n\n private canonicalizeConfig(value: unknown, depth: number, ancestors: Set<object>): string {\n switch (typeof value) {\n case \"undefined\":\n return \"undefined\";\n case \"string\":\n return `string:${JSON.stringify(value)}`;\n case \"number\":\n return `number:${Object.is(value, -0) ? \"-0\" : String(value)}`;\n case \"bigint\":\n return `bigint:${value.toString()}`;\n case \"boolean\":\n return `boolean:${value}`;\n case \"symbol\":\n return `symbol:${String(value)}`;\n case \"function\":\n return `ref:${this.getCacheLeafId(value)}`;\n case \"object\": {\n if (value === null) return \"null\";\n if (ancestors.has(value) || depth >= MAX_CACHE_KEY_DEPTH) {\n return `ref:${this.getCacheLeafId(value)}`;\n }\n\n if (Array.isArray(value)) {\n ancestors.add(value);\n const serialized = `[${value\n .map((item) => this.canonicalizeConfig(item, depth + 1, ancestors))\n .join(\",\")}]`;\n ancestors.delete(value);\n return serialized;\n }\n\n const prototype = Object.getPrototypeOf(value);\n if (prototype !== Object.prototype && prototype !== null) {\n return `ref:${this.getCacheLeafId(value)}`;\n }\n\n const record = value as Record<string, unknown>;\n ancestors.add(value);\n const serialized = `{${Object.keys(record)\n .sort()\n .map(\n (key) =>\n `${JSON.stringify(key)}:${this.canonicalizeConfig(record[key], depth + 1, ancestors)}`,\n )\n .join(\",\")}}`;\n ancestors.delete(value);\n return serialized;\n }\n }\n }\n\n private getCacheLeafId(value: object): number {\n const existing = this.cacheLeafIds.get(value);\n if (existing !== undefined) return existing;\n const id = this.nextCacheLeafId++;\n this.cacheLeafIds.set(value, id);\n return id;\n }\n\n private validatePluginId(pluginId: string): Effect.Effect<string, PluginRuntimeError> {\n if (!(pluginId in this.registry)) {\n return Effect.fail(\n new PluginRuntimeError({\n pluginId: String(pluginId),\n operation: \"validate-plugin-id\",\n cause: new Error(`Plugin ID '${String(pluginId)}' not found in registry.`),\n }),\n );\n }\n return Effect.succeed(String(pluginId));\n }\n\n private async runPromise<A, E>(effect: Effect.Effect<A, E, PluginService>): Promise<A> {\n const exit = await this.runtime.runPromiseExit(effect);\n\n if (Exit.isFailure(exit)) {\n const error = Cause.findErrorOption(exit.cause);\n if (Option.isSome(error)) {\n throw error.value;\n }\n throw Cause.squash(exit.cause);\n }\n\n return exit.value;\n }\n\n async usePlugin<K extends keyof R & string>(\n pluginId: K,\n config: PluginConfigInput<R[K]>,\n plugins?: Record<string, unknown>,\n ): Promise<UsePluginResult<K, R>> {\n const cacheKey = this.generateCacheKey(pluginId, { ...config, __plugins: plugins ?? {} });\n\n let cachedPlugin = this.pluginCache.get(cacheKey);\n if (!cachedPlugin) {\n const operation = Effect.gen({ self: this }, function* () {\n const pluginService = yield* PluginService;\n const validatedId = yield* this.validatePluginId(pluginId);\n\n // Load → Instantiate → Initialize → Register\n const ctor = yield* pluginService.loadPlugin(validatedId);\n const instance = yield* pluginService.instantiatePlugin(pluginId, ctor);\n const initialized = yield* pluginService.initializePlugin(instance, config, plugins);\n yield* pluginService.registerPlugin(initialized);\n\n return initialized;\n });\n\n cachedPlugin = this.runPromise(operation);\n this.pluginCache.set(cacheKey, cachedPlugin);\n }\n\n let initialized: InitializedPlugin<AnyPlugin>;\n try {\n initialized = await cachedPlugin;\n } catch (error) {\n if (this.pluginCache.get(cacheKey) === cachedPlugin) {\n this.pluginCache.delete(cacheKey);\n this.routerCache.delete(cacheKey);\n }\n throw error;\n }\n\n // Construct the router once per plugin instance, not per client/request.\n let router = this.routerCache.get(cacheKey);\n if (!router) {\n try {\n router = initialized.plugin.createRouter(plugins ?? {}) as PluginRouterType<R[K]>;\n this.routerCache.set(cacheKey, router);\n } catch (error) {\n await this.evictPlugin(pluginId, config, plugins);\n throw error;\n }\n }\n\n // Create client factory that accepts request context. The plugin's\n // Effect context is injected so `.effect()` handlers resolve services\n // on in-process (server-side / SSR) calls.\n const createClient = (context?: any) =>\n createRouterClient(router, {\n context: {\n ...context,\n \"effect/context\": initialized.effectContext,\n },\n });\n\n return {\n createClient: createClient as any,\n router,\n metadata: initialized.metadata,\n initialized: initialized as InitializedPlugin<RegisteredPlugin<K, R>>,\n } as UsePluginResult<K, R>;\n }\n\n async loadPlugin<K extends keyof R & string>(\n pluginId: K,\n ): Promise<LoadedPlugin<RegisteredPlugin<K, R>>> {\n const effect = Effect.gen(function* () {\n const pluginService = yield* PluginService;\n return yield* pluginService.loadPlugin(pluginId);\n });\n return this.runPromise(effect) as Promise<LoadedPlugin<RegisteredPlugin<K, R>>>;\n }\n\n async instantiatePlugin<K extends keyof R & string>(\n pluginId: K,\n loadedPlugin: LoadedPlugin<RegisteredPlugin<K, R>>,\n ): Promise<PluginInstance<RegisteredPlugin<K, R>>> {\n const effect = Effect.gen(function* () {\n const pluginService = yield* PluginService;\n return yield* pluginService.instantiatePlugin(pluginId, loadedPlugin);\n });\n return this.runPromise(effect) as Promise<PluginInstance<RegisteredPlugin<K, R>>>;\n }\n\n async initializePlugin<T extends AnyPlugin>(\n instance: PluginInstance<T>,\n config: any,\n plugins?: Record<string, unknown>,\n ): Promise<InitializedPlugin<T>> {\n const effect = Effect.gen(function* () {\n const pluginService = yield* PluginService;\n const initialized = yield* pluginService.initializePlugin(instance, config, plugins);\n yield* pluginService.registerPlugin(initialized);\n return initialized;\n });\n return this.runPromise(effect);\n }\n\n async shutdown(): Promise<void> {\n const effect = Effect.gen(function* () {\n const pluginService = yield* PluginService;\n yield* pluginService.cleanup;\n });\n try {\n await this.runPromise(effect);\n } finally {\n this.pluginCache.clear();\n this.routerCache.clear();\n await this.runtime.dispose();\n }\n }\n\n async evictPlugin<K extends keyof R & string>(\n pluginId: K,\n config: PluginConfigInput<R[K]>,\n plugins?: Record<string, unknown>,\n ): Promise<void> {\n const cacheKey = this.generateCacheKey(pluginId, { ...config, __plugins: plugins ?? {} });\n\n const effect = Effect.gen({ self: this }, function* () {\n const pluginService = yield* PluginService;\n const cachedPlugin = this.pluginCache.get(cacheKey);\n\n if (cachedPlugin) {\n this.pluginCache.delete(cacheKey);\n this.routerCache.delete(cacheKey);\n\n const pluginResult = yield* Effect.tryPromise({\n try: () => cachedPlugin,\n catch: (error) => toPluginRuntimeError(error, pluginId, undefined, \"evict-plugin\"),\n }).pipe(Effect.orElseSucceed(() => null));\n\n if (pluginResult) {\n yield* pluginService.shutdownPlugin(pluginResult);\n }\n }\n });\n\n return this.runPromise(effect);\n }\n}\n\n/**\n * Normalizes a remote URL to ensure it points to remoteEntry.js\n * If the URL doesn't end with a file extension, appends /remoteEntry.js\n */\nfunction normalizeRemoteUrl(url: string): string {\n if (!url) return url;\n if (url.endsWith(\".js\") || url.endsWith(\".json\")) return url;\n return `${url.endsWith(\"/\") ? url.slice(0, -1) : url}/${DEV_ENTRY_FILENAME}`;\n}\n\n/**\n * Extract plugin map (module constructors) from registry entries\n */\nfunction extractPluginMap(\n registry: Record<string, PluginRegistryEntry>,\n): Record<string, AnyPluginConstructor> {\n const pluginMap: Record<string, AnyPluginConstructor> = {};\n\n for (const [pluginId, entry] of Object.entries(registry)) {\n if (\"module\" in entry && entry.module) {\n pluginMap[pluginId] = entry.module;\n }\n }\n\n return pluginMap;\n}\n\n/**\n * Normalize registry entries - ensure remote URLs are properly formatted\n */\nfunction normalizeRegistry(registry: Record<string, PluginRegistryEntry>): PluginRegistry {\n const normalized: Record<string, PluginRegistryEntry> = {};\n\n for (const [pluginId, entry] of Object.entries(registry)) {\n if (\"module\" in entry) {\n normalized[pluginId] = {\n ...entry,\n remote: entry.remote ? normalizeRemoteUrl(entry.remote) : undefined,\n };\n } else {\n normalized[pluginId] = {\n ...entry,\n remote: normalizeRemoteUrl(entry.remote),\n };\n }\n }\n\n return normalized as PluginRegistry;\n}\n\n/**\n * Creates a plugin runtime with support for both module and remote plugin entries.\n *\n * @example\n * ```typescript\n * // With module entries (types inferred automatically)\n * const runtime = createPluginRuntime({\n * registry: {\n * telegram: { module: TelegramPlugin },\n * gopher: { remote: \"https://cdn.example.com/gopher/remoteEntry.js\" }\n * },\n * secrets: { API_KEY: \"...\" }\n * });\n *\n * // Types are automatically inferred from module entries!\n * const { router } = await runtime.usePlugin(\"telegram\", config);\n * ```\n */\nexport function createPluginRuntime<TRegistry extends Record<string, PluginRegistryEntry>>(\n config: PluginRuntimeConfig<TRegistry>,\n): PluginRuntime<InferRegistryFromEntries<TRegistry>> {\n const secrets = config.secrets || {};\n const normalizedRegistry = normalizeRegistry(config.registry);\n const pluginMap = extractPluginMap(config.registry);\n\n const layer = PluginServiceLive(normalizedRegistry, secrets, pluginMap);\n const runtime = ManagedRuntime.make(layer);\n\n return new PluginRuntime(runtime, normalizedRegistry) as PluginRuntime<\n InferRegistryFromEntries<TRegistry>\n >;\n}\n"],"mappings":"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"}
|
package/dist/runtime/index.d.cts
CHANGED
|
@@ -1,14 +1,30 @@
|
|
|
1
1
|
import { AnyPlugin, InferRegistryFromEntries, InitializedPlugin, LoadedPlugin, PluginConfigInput, PluginInstance, PluginRegistry, PluginRegistryEntry, PluginRuntimeConfig, RegisteredPlugin, RegisteredPlugins, UsePluginResult } from "../types.cjs";
|
|
2
2
|
import { PluginService } from "./services/plugin.service.cjs";
|
|
3
3
|
import { ManagedRuntime } from "effect";
|
|
4
|
+
import "@orpc/openapi/extensions/route";
|
|
5
|
+
import "@orpc/experimental-effect/extensions/effect";
|
|
4
6
|
//#region src/runtime/index.d.ts
|
|
5
7
|
declare class PluginRuntime<R = RegisteredPlugins> {
|
|
6
8
|
private runtime;
|
|
7
9
|
private registry;
|
|
8
10
|
readonly __registryType?: R;
|
|
9
11
|
private pluginCache;
|
|
12
|
+
private routerCache;
|
|
13
|
+
private cacheLeafIds;
|
|
14
|
+
private nextCacheLeafId;
|
|
10
15
|
constructor(runtime: ManagedRuntime.ManagedRuntime<PluginService, never>, registry: PluginRegistry);
|
|
16
|
+
/**
|
|
17
|
+
* Cache key for plugin instances: JSON-equal configs share one plugin
|
|
18
|
+
* instance (variables and secrets originate from bos.config.json, so they
|
|
19
|
+
* are JSON values). Values outside the JSON domain follow Effect's Hash
|
|
20
|
+
* semantics — symbols key by description, functions and class instances by
|
|
21
|
+
* reference identity — and the host creates its pluginsClient map once per
|
|
22
|
+
* boot, making identity the correct equivalence for function-bearing
|
|
23
|
+
* configs.
|
|
24
|
+
*/
|
|
11
25
|
private generateCacheKey;
|
|
26
|
+
private canonicalizeConfig;
|
|
27
|
+
private getCacheLeafId;
|
|
12
28
|
private validatePluginId;
|
|
13
29
|
private runPromise;
|
|
14
30
|
usePlugin<K extends keyof R & string>(pluginId: K, config: PluginConfigInput<R[K]>, plugins?: Record<string, unknown>): Promise<UsePluginResult<K, R>>;
|