every-plugin 2.10.1 → 3.0.0-rc.3
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 +50 -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 +9 -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 +13 -26
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.cts +57 -24
- package/dist/plugin.d.cts.map +1 -1
- package/dist/plugin.d.mts +58 -25
- package/dist/plugin.d.mts.map +1 -1
- package/dist/plugin.mjs +16 -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 +159 -33
- package/dist/runtime/errors.cjs.map +1 -1
- package/dist/runtime/errors.d.cts +64 -7
- package/dist/runtime/errors.d.cts.map +1 -1
- package/dist/runtime/errors.d.mts +64 -7
- package/dist/runtime/errors.d.mts.map +1 -1
- package/dist/runtime/errors.mjs +154 -30
- 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 +57 -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 +57 -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 +56 -30
- 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 +55 -31
- 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 +25 -41
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +25 -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 +17 -18
- package/src/identity.ts +36 -0
- package/src/index.ts +4 -0
- package/src/plugin.ts +88 -91
- package/src/remote-entry.ts +171 -0
- package/src/runtime/errors.ts +229 -26
- package/src/runtime/index.ts +132 -43
- package/src/runtime/mf-config.ts +12 -107
- package/src/runtime/services/module-federation.service.ts +218 -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 +271 -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 +25 -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 -248
- package/dist/build/rspack/dev-server-middleware.cjs.map +0 -1
- package/dist/build/rspack/dev-server-middleware.mjs +0 -247
- 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 -324
- 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/src/types.ts
CHANGED
|
@@ -4,9 +4,10 @@ import type {
|
|
|
4
4
|
InferSchemaInput,
|
|
5
5
|
InferSchemaOutput,
|
|
6
6
|
} from "@orpc/contract";
|
|
7
|
-
import type {
|
|
8
|
-
import type { Scope } from "effect";
|
|
7
|
+
import type { ContractedRouter, RouterClient } from "@orpc/server";
|
|
8
|
+
import type { Context, Scope } from "effect";
|
|
9
9
|
import type { Plugin } from "./plugin";
|
|
10
|
+
import type { PluginWarningInfo } from "./runtime/errors";
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Registry bindings interface - populated via module augmentation
|
|
@@ -26,7 +27,7 @@ export interface RegisteredPlugins {}
|
|
|
26
27
|
/**
|
|
27
28
|
* Base type for any plugin instance.
|
|
28
29
|
*/
|
|
29
|
-
export type AnyPlugin = Plugin<AnyContractRouter, AnySchema, AnySchema, AnySchema | undefined
|
|
30
|
+
export type AnyPlugin = Plugin<AnyContractRouter, AnySchema, AnySchema, AnySchema | undefined>;
|
|
30
31
|
|
|
31
32
|
/**
|
|
32
33
|
* Loaded plugin constructor with binding information
|
|
@@ -100,13 +101,23 @@ export type PluginContext<T> = T extends {
|
|
|
100
101
|
* Extract router type from plugin binding
|
|
101
102
|
* Uses 'any' for context to support nested router compositions
|
|
102
103
|
*/
|
|
103
|
-
export type PluginRouterType<T> =
|
|
104
|
+
export type PluginRouterType<T> = ContractedRouter<PluginContract<T>, any>;
|
|
104
105
|
|
|
105
106
|
/**
|
|
106
107
|
* Extract client type from plugin binding
|
|
107
108
|
*/
|
|
108
109
|
export type PluginClientType<T> = RouterClient<PluginRouterType<T>>;
|
|
109
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Sibling plugin entry passed to `initialize` and `createRouter`.
|
|
113
|
+
* `client` creates a typed in-process client for the plugin's router;
|
|
114
|
+
* `router` is the raw implemented router for cross-plugin merging.
|
|
115
|
+
*/
|
|
116
|
+
export type PluginServicesEntry<T = any> = {
|
|
117
|
+
client: (context?: PluginContextInput<T>) => PluginClientType<T>;
|
|
118
|
+
router: PluginRouterType<T>;
|
|
119
|
+
};
|
|
120
|
+
|
|
110
121
|
/**
|
|
111
122
|
* Extract plugin type from registered plugins by key
|
|
112
123
|
* @param K - The plugin key
|
|
@@ -121,15 +132,10 @@ export type RegisteredPlugin<K extends keyof R, R = RegisteredPlugins> = R[K] ex
|
|
|
121
132
|
secrets: infer S extends AnySchema;
|
|
122
133
|
context: infer TRequestContext extends AnySchema | undefined;
|
|
123
134
|
}
|
|
124
|
-
? Plugin<C, V, S, TRequestContext
|
|
135
|
+
? Plugin<C, V, S, TRequestContext>
|
|
125
136
|
: never
|
|
126
137
|
: never;
|
|
127
138
|
|
|
128
|
-
/**
|
|
129
|
-
* Extract plugin constructor type from registry entry
|
|
130
|
-
*/
|
|
131
|
-
export type PluginConstructor<K extends keyof R, R = RegisteredPlugins> = RegisteredPlugin<K, R>;
|
|
132
|
-
|
|
133
139
|
/**
|
|
134
140
|
* Extract context input type from plugin binding (for client creation)
|
|
135
141
|
*/
|
|
@@ -144,14 +150,6 @@ export type PluginConfigInput<T> = {
|
|
|
144
150
|
secrets: InferSchemaInput<PluginSecrets<T>>;
|
|
145
151
|
};
|
|
146
152
|
|
|
147
|
-
/**
|
|
148
|
-
* Extract deps context type from plugin instance (used for initialization)
|
|
149
|
-
*/
|
|
150
|
-
export type ContextOf<T extends AnyPlugin> =
|
|
151
|
-
T extends Plugin<AnyContractRouter, AnySchema, AnySchema, AnySchema | undefined, infer TDeps>
|
|
152
|
-
? TDeps
|
|
153
|
-
: never;
|
|
154
|
-
|
|
155
153
|
/**
|
|
156
154
|
* Plugin metadata for remote loading
|
|
157
155
|
*/
|
|
@@ -166,11 +164,6 @@ export type PluginMetadata = {
|
|
|
166
164
|
*/
|
|
167
165
|
export type PluginRegistry = Record<string, PluginRegistryEntry>;
|
|
168
166
|
|
|
169
|
-
/**
|
|
170
|
-
* Legacy metadata-only registry (for backwards compatibility)
|
|
171
|
-
*/
|
|
172
|
-
export type PluginMetadataRegistry = Record<string, PluginMetadata>;
|
|
173
|
-
|
|
174
167
|
/**
|
|
175
168
|
* Configuration for secrets injection.
|
|
176
169
|
* Secrets are hydrated into plugin configs using template replacement.
|
|
@@ -205,8 +198,15 @@ export interface InitializedPlugin<T extends AnyPlugin = AnyPlugin> {
|
|
|
205
198
|
variables: InferSchemaOutput<T["configSchema"]["variables"]>;
|
|
206
199
|
secrets: InferSchemaOutput<T["configSchema"]["secrets"]>;
|
|
207
200
|
};
|
|
208
|
-
|
|
209
|
-
|
|
201
|
+
/**
|
|
202
|
+
* Built Effect context from the plugin's initialize Layer. Provided to
|
|
203
|
+
* handlers as `effect/context` — `.effect()` handlers `yield* Tag`,
|
|
204
|
+
* plain handlers use `Context.get(context["effect/context"], Tag)`.
|
|
205
|
+
*/
|
|
206
|
+
readonly effectContext: Context.Context<any>;
|
|
207
|
+
readonly scope: Scope.Closeable;
|
|
208
|
+
/** Non-fatal config warnings collected during initialization (empty when none). */
|
|
209
|
+
readonly warnings: PluginWarningInfo[];
|
|
210
210
|
}
|
|
211
211
|
|
|
212
212
|
/**
|
|
@@ -240,18 +240,6 @@ export type UsePluginResult<K extends keyof R, R = RegisteredPlugins> =
|
|
|
240
240
|
}
|
|
241
241
|
: VerifyPluginBinding<K, R>;
|
|
242
242
|
|
|
243
|
-
/**
|
|
244
|
-
* Runtime options
|
|
245
|
-
*/
|
|
246
|
-
export interface RuntimeOptions {
|
|
247
|
-
isolation?: "strict" | "shared" | "none";
|
|
248
|
-
memoryLimit?: string;
|
|
249
|
-
concurrency?: number;
|
|
250
|
-
resourceTimeout?: string;
|
|
251
|
-
debug?: boolean;
|
|
252
|
-
metrics?: boolean;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
243
|
/**
|
|
256
244
|
* Extract registry type from runtime instance or use type directly
|
|
257
245
|
* This allows EveryPlugin.Infer to work with both:
|
|
@@ -295,15 +283,4 @@ export interface PluginRuntimeConfig<
|
|
|
295
283
|
> {
|
|
296
284
|
registry: R;
|
|
297
285
|
secrets?: SecretsConfig;
|
|
298
|
-
options?: RuntimeOptions;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Legacy plugin runtime configuration (metadata-only registry)
|
|
303
|
-
* @deprecated Use PluginRuntimeConfig with module/remote entries instead
|
|
304
|
-
*/
|
|
305
|
-
export interface LegacyPluginRuntimeConfig {
|
|
306
|
-
registry: PluginMetadataRegistry;
|
|
307
|
-
secrets?: SecretsConfig;
|
|
308
|
-
options?: RuntimeOptions;
|
|
309
286
|
}
|
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
import type { AnyRoute } from "@tanstack/react-router";
|
|
2
|
+
import { createRootRoute, createRoute, Outlet, redirect } from "@tanstack/react-router";
|
|
3
|
+
import { digestOf } from "./descriptor";
|
|
4
|
+
import type { PluginManifest, RouteRecord } from "./manifest-schema";
|
|
5
|
+
import { MOUNT_REGISTRY, type MountDef, type MountId, resolveMountSegment } from "./mount-registry";
|
|
6
|
+
import { compareNavItems, type NavDeclaration, type NavItem, type NavManifest } from "./nav";
|
|
7
|
+
import { ROUTE_OPTION_KEYS, type RouteConfigModule, type RouteOptionsBundle } from "./route-config";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Host-side route-graph construction (ADR 0008 §1): manifests + route
|
|
11
|
+
* configs in → host-built tree out. The host constructs ITS OWN Route
|
|
12
|
+
* objects from validated manifest data via public `createRoute` APIs; no
|
|
13
|
+
* foreign route object is ever mutated. Gates are attached HOST-side from
|
|
14
|
+
* the mount registry — plugins cannot ship a route that escapes its
|
|
15
|
+
* mount's gate because plugins never construct route objects.
|
|
16
|
+
*
|
|
17
|
+
* Mounts are the ONLY cross-source parenting points: a root-level
|
|
18
|
+
* pathless layout file (`_public.tsx`) declares the mount for the whole
|
|
19
|
+
* composition (exactly one declaring source per mount); every other
|
|
20
|
+
* source's routes live under the same `_mount/` directory prefix and
|
|
21
|
+
* parent onto the shared mount route. This module executes inside the
|
|
22
|
+
* core ui's module graph (production MF expose `./compose`, dev source
|
|
23
|
+
* import) so constructed routes are minted by the same react/router
|
|
24
|
+
* instance that renders them.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* TanStack's Route generics are intentionally invariant — routes built from
|
|
29
|
+
* manifest data can't satisfy them structurally. One named boundary for
|
|
30
|
+
* handing a constructed route to the tree-building APIs.
|
|
31
|
+
*/
|
|
32
|
+
function toAnyRoute(route: unknown): AnyRoute {
|
|
33
|
+
return route as AnyRoute;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface GateUser {
|
|
37
|
+
id: string;
|
|
38
|
+
name?: string;
|
|
39
|
+
/** Better Auth user role — "admin" gates the admin mount. */
|
|
40
|
+
role?: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface HostContext {
|
|
44
|
+
user?: GateUser;
|
|
45
|
+
session?: { user?: GateUser };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
type GateFn = (args: {
|
|
49
|
+
context: HostContext;
|
|
50
|
+
location: { pathname: string; searchStr: string };
|
|
51
|
+
}) => void;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Gate redirects are absolute: gates attach to root-level mount routes, and
|
|
55
|
+
* relatives would silently shift if a mount ever moved deeper in the tree.
|
|
56
|
+
* The login surface is plugin-owned, never core-known.
|
|
57
|
+
*/
|
|
58
|
+
const LOGIN_TO: string = "/login";
|
|
59
|
+
const HOME_TO: string = "/";
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Gate implementations by mount gate kind. Only `session` and `admin` are
|
|
63
|
+
* implemented (ADR 0008 §3); unimplemented mounts are rejected during mount
|
|
64
|
+
* declaration before any gate lookup, and gates are optional by type — a
|
|
65
|
+
* mount without an entry (or `none`) renders ungated.
|
|
66
|
+
*/
|
|
67
|
+
const GATES: Partial<Record<MountDef["gate"], GateFn>> = {
|
|
68
|
+
session: ({ context, location }) => {
|
|
69
|
+
const user = userOf(context);
|
|
70
|
+
if (!user) {
|
|
71
|
+
throw redirect({
|
|
72
|
+
to: LOGIN_TO,
|
|
73
|
+
search: { redirect: location.pathname + location.searchStr } as never,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
admin: ({ context }) => {
|
|
78
|
+
const user = userOf(context);
|
|
79
|
+
if (!user) throw redirect({ to: LOGIN_TO });
|
|
80
|
+
if (user.role !== "admin") throw redirect({ to: HOME_TO });
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const userOf = (context: HostContext | undefined): GateUser | undefined =>
|
|
85
|
+
context?.user ?? context?.session?.user;
|
|
86
|
+
|
|
87
|
+
export interface ConstructPluginRef {
|
|
88
|
+
/** composition identity — plugin key; participates in the digest */
|
|
89
|
+
key: string;
|
|
90
|
+
/** deployment identity — the MF container name loadRemote targets */
|
|
91
|
+
mfName: string;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface ResolvedPlugin {
|
|
95
|
+
key: string;
|
|
96
|
+
manifest: PluginManifest;
|
|
97
|
+
routeConfig: RouteConfigModule;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export interface ConstructInput {
|
|
101
|
+
name: string;
|
|
102
|
+
plugins: ReadonlyArray<ConstructPluginRef>;
|
|
103
|
+
resolve: (ref: ConstructPluginRef) => Promise<ResolvedPlugin>;
|
|
104
|
+
/** core ui `__root` options — component/error/notFound + head baseline */
|
|
105
|
+
rootOptions?: RouteOptionsBundle;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export interface ConstructedTree {
|
|
109
|
+
rootRoute: AnyRoute;
|
|
110
|
+
routeTree: AnyRoute;
|
|
111
|
+
digest: string;
|
|
112
|
+
manifests: PluginManifest[];
|
|
113
|
+
nav: NavManifest;
|
|
114
|
+
/** constructed route count per mount id */
|
|
115
|
+
mountCounts: Record<string, number>;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
interface MountDeclaration {
|
|
119
|
+
key: string;
|
|
120
|
+
record: RouteRecord;
|
|
121
|
+
options: RouteOptionsBundle;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function joinPath(a: string | undefined, b: string | undefined): string {
|
|
125
|
+
const left = a && a !== "/" ? a.replace(/\/+$/, "") : "";
|
|
126
|
+
const right = b && b !== "/" ? b.replace(/^\/+/, "") : "";
|
|
127
|
+
if (!left) return right ? `/${right}` : "/";
|
|
128
|
+
if (!right) return left;
|
|
129
|
+
return `${left}/${right}`;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const navOf = (options: RouteOptionsBundle): NavDeclaration | undefined => {
|
|
133
|
+
const nav = options.staticData?.nav;
|
|
134
|
+
if (nav && typeof nav === "object" && typeof (nav as NavDeclaration).label === "string") {
|
|
135
|
+
return nav as NavDeclaration;
|
|
136
|
+
}
|
|
137
|
+
return undefined;
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
/** Layout routes (mount or pathless) pass their authored options through,
|
|
141
|
+
* like every other route kind. On mount routes the registry gate composes
|
|
142
|
+
* BEFORE the declaration's own beforeLoad so a source can never escape its
|
|
143
|
+
* mount's gate (ADR 0008 §3), while the declaration's return value still
|
|
144
|
+
* flows to children as route context. */
|
|
145
|
+
function layoutBeforeLoad(
|
|
146
|
+
gate: GateFn | undefined,
|
|
147
|
+
declared: RouteOptionsBundle["beforeLoad"],
|
|
148
|
+
): RouteOptionsBundle["beforeLoad"] {
|
|
149
|
+
if (!gate) return declared;
|
|
150
|
+
return (args) => {
|
|
151
|
+
gate(args);
|
|
152
|
+
return declared?.(args);
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const AUTHORED_OPTION_KEYS = ROUTE_OPTION_KEYS.filter(
|
|
157
|
+
(key) => key !== "beforeLoad" && key !== "component",
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
function authoredOptions(options: RouteOptionsBundle): Partial<RouteOptionsBundle> {
|
|
161
|
+
const authored: Partial<Record<keyof RouteOptionsBundle, unknown>> = {};
|
|
162
|
+
for (const key of AUTHORED_OPTION_KEYS) {
|
|
163
|
+
if (options[key] !== undefined) authored[key] = options[key];
|
|
164
|
+
}
|
|
165
|
+
return authored as Partial<RouteOptionsBundle>;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function rootAuthoredOptions(options: RouteOptionsBundle): Partial<RouteOptionsBundle> {
|
|
169
|
+
const { params: _params, ...authored } = authoredOptions(options);
|
|
170
|
+
return authored;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export async function constructTree(input: ConstructInput): Promise<ConstructedTree> {
|
|
174
|
+
const refs = [...input.plugins].sort((a, b) => a.key.localeCompare(b.key));
|
|
175
|
+
const resolved: ResolvedPlugin[] = [];
|
|
176
|
+
for (const ref of refs) {
|
|
177
|
+
resolved.push(await input.resolve(ref));
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const optionsByPlugin = new Map<string, Map<string, RouteOptionsBundle>>();
|
|
181
|
+
for (const plugin of resolved) {
|
|
182
|
+
const optionsById = new Map<string, RouteOptionsBundle>();
|
|
183
|
+
await Promise.all(
|
|
184
|
+
plugin.manifest.routes.map(async (record) => {
|
|
185
|
+
const loader = plugin.routeConfig.routeConfigLoaders[record.id];
|
|
186
|
+
if (!loader) {
|
|
187
|
+
throw new Error(`routeConfig for "${plugin.key}" has no loader for route "${record.id}"`);
|
|
188
|
+
}
|
|
189
|
+
optionsById.set(record.id, await loader());
|
|
190
|
+
}),
|
|
191
|
+
);
|
|
192
|
+
optionsByPlugin.set(plugin.key, optionsById);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const declarations = new Map<MountId, MountDeclaration>();
|
|
196
|
+
for (const plugin of resolved) {
|
|
197
|
+
for (const record of plugin.manifest.routes) {
|
|
198
|
+
if (!record.mount) continue;
|
|
199
|
+
const mountId = record.mount as MountId;
|
|
200
|
+
const def = MOUNT_REGISTRY[mountId];
|
|
201
|
+
if (!def.implemented) {
|
|
202
|
+
throw new Error(
|
|
203
|
+
`mount "${record.mount}" is declared vocabulary but unimplemented (ADR 0008 §3) — declared by "${plugin.key}"`,
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
const existing = declarations.get(mountId);
|
|
207
|
+
if (existing) {
|
|
208
|
+
throw new Error(
|
|
209
|
+
`mount "${mountId}" declared by multiple sources: "${existing.key}" (${existing.record.file}) and "${plugin.key}" (${record.file})`,
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
declarations.set(mountId, {
|
|
213
|
+
key: plugin.key,
|
|
214
|
+
record,
|
|
215
|
+
options: optionsByPlugin.get(plugin.key)!.get(record.id)!,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const rootRoute = toAnyRoute(
|
|
221
|
+
createRootRoute({
|
|
222
|
+
...(input.rootOptions ? rootAuthoredOptions(input.rootOptions) : {}),
|
|
223
|
+
component: input.rootOptions?.component ?? Outlet,
|
|
224
|
+
...(input.rootOptions?.beforeLoad ? { beforeLoad: input.rootOptions.beforeLoad } : {}),
|
|
225
|
+
}),
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
const mountRoutes = new Map<MountId, AnyRoute>();
|
|
229
|
+
for (const mountId of Object.keys(MOUNT_REGISTRY) as MountId[]) {
|
|
230
|
+
const declaration = declarations.get(mountId);
|
|
231
|
+
if (!declaration) continue;
|
|
232
|
+
const def = MOUNT_REGISTRY[mountId]!;
|
|
233
|
+
const gate = GATES[def.gate];
|
|
234
|
+
const options = declaration.options;
|
|
235
|
+
const route = createRoute({
|
|
236
|
+
id: `__mount_${mountId}`,
|
|
237
|
+
getParentRoute: () => rootRoute,
|
|
238
|
+
...(gate || options.beforeLoad
|
|
239
|
+
? { beforeLoad: layoutBeforeLoad(gate, options.beforeLoad) }
|
|
240
|
+
: {}),
|
|
241
|
+
...authoredOptions(options),
|
|
242
|
+
component: options.component ?? Outlet,
|
|
243
|
+
});
|
|
244
|
+
mountRoutes.set(mountId, toAnyRoute(route));
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const mountByLayoutId = new Map<string, MountId>();
|
|
248
|
+
for (const [mountId, declaration] of declarations) {
|
|
249
|
+
mountByLayoutId.set(declaration.record.id, mountId);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const nav: NavItem[] = [];
|
|
253
|
+
const mountCounts: Record<string, number> = {};
|
|
254
|
+
const childrenByParent = new Map<AnyRoute, AnyRoute[]>();
|
|
255
|
+
/** cross-plugin path-collision guard: claimed paths per parent route */
|
|
256
|
+
const claimedPathsByParent = new Map<AnyRoute, Map<string, string>>();
|
|
257
|
+
const attach = (parent: AnyRoute, child: AnyRoute) => {
|
|
258
|
+
const list = childrenByParent.get(parent) ?? [];
|
|
259
|
+
list.push(child);
|
|
260
|
+
childrenByParent.set(parent, list);
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
for (const plugin of resolved) {
|
|
264
|
+
const optionsById = optionsByPlugin.get(plugin.key)!;
|
|
265
|
+
const fullPathById = new Map<string, string>();
|
|
266
|
+
const mountById = new Map<string, MountId>();
|
|
267
|
+
const byId = new Map<string, { record: RouteRecord; route: AnyRoute }>();
|
|
268
|
+
|
|
269
|
+
const parentFor = (
|
|
270
|
+
record: RouteRecord,
|
|
271
|
+
): { route: AnyRoute; fullPath: string; mount: MountId } => {
|
|
272
|
+
if (record.parentId) {
|
|
273
|
+
const local = byId.get(record.parentId);
|
|
274
|
+
if (local) {
|
|
275
|
+
return {
|
|
276
|
+
route: local.route,
|
|
277
|
+
fullPath: fullPathById.get(record.parentId)!,
|
|
278
|
+
mount: mountById.get(record.parentId)!,
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
const mount = mountByLayoutId.get(record.parentId);
|
|
282
|
+
if (mount) return { route: mountRoutes.get(mount)!, fullPath: "", mount };
|
|
283
|
+
throw new Error(
|
|
284
|
+
`unresolvable parent "${record.parentId}" for "${record.id}" in "${plugin.key}" — mounts are the only cross-source parenting points`,
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
const firstSegment = record.id.split("/")[0] ?? "";
|
|
288
|
+
if (firstSegment.startsWith("_")) {
|
|
289
|
+
const mount = resolveMountSegment(firstSegment.slice(1));
|
|
290
|
+
if (mount && mountRoutes.has(mount))
|
|
291
|
+
return { route: mountRoutes.get(mount)!, fullPath: "", mount };
|
|
292
|
+
if (mount) {
|
|
293
|
+
throw new Error(
|
|
294
|
+
`mount "${mount}" is not declared by any source (route "${record.id}" in "${plugin.key}")`,
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
throw new Error(
|
|
298
|
+
`unknown mount "_${firstSegment.slice(1)}" (route "${record.id}" in "${plugin.key}")`,
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
throw new Error(`route "${record.id}" in "${plugin.key}" must live under a mount`);
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
const pending = plugin.manifest.routes.filter((record) => !record.mount);
|
|
305
|
+
let progressed = true;
|
|
306
|
+
while (pending.length > 0 && progressed) {
|
|
307
|
+
progressed = false;
|
|
308
|
+
for (let i = 0; i < pending.length; i += 1) {
|
|
309
|
+
const record = pending[i]!;
|
|
310
|
+
if (
|
|
311
|
+
record.parentId &&
|
|
312
|
+
!byId.has(record.parentId) &&
|
|
313
|
+
!mountByLayoutId.has(record.parentId)
|
|
314
|
+
) {
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
pending.splice(i, 1);
|
|
318
|
+
progressed = true;
|
|
319
|
+
|
|
320
|
+
const options = optionsById.get(record.id)!;
|
|
321
|
+
const parent = parentFor(record);
|
|
322
|
+
const routePath = record.path;
|
|
323
|
+
const isLayoutRoute = record.type === "layout" || routePath === undefined;
|
|
324
|
+
if (!isLayoutRoute) {
|
|
325
|
+
const siblings = claimedPathsByParent.get(parent.route) ?? new Map<string, string>();
|
|
326
|
+
const claimant = siblings.get(routePath);
|
|
327
|
+
if (claimant) {
|
|
328
|
+
throw new Error(
|
|
329
|
+
`path collision: "${plugin.key}" route "${record.id}" declares "${routePath}" which is already claimed by "${claimant}" under the same parent`,
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
siblings.set(routePath, `${plugin.key}:${record.id}`);
|
|
333
|
+
claimedPathsByParent.set(parent.route, siblings);
|
|
334
|
+
}
|
|
335
|
+
const fullPath = joinPath(parent.fullPath, routePath);
|
|
336
|
+
let route: AnyRoute;
|
|
337
|
+
if (isLayoutRoute) {
|
|
338
|
+
route = createRoute({
|
|
339
|
+
id: `${plugin.key}__${record.id}`,
|
|
340
|
+
getParentRoute: () => parent.route,
|
|
341
|
+
...authoredOptions(options),
|
|
342
|
+
...(options.beforeLoad ? { beforeLoad: options.beforeLoad } : {}),
|
|
343
|
+
component: options.component ?? Outlet,
|
|
344
|
+
});
|
|
345
|
+
} else {
|
|
346
|
+
route = createRoute({
|
|
347
|
+
path: routePath,
|
|
348
|
+
getParentRoute: () => parent.route,
|
|
349
|
+
...authoredOptions(options),
|
|
350
|
+
...(options.beforeLoad ? { beforeLoad: options.beforeLoad } : {}),
|
|
351
|
+
component: options.component ?? Outlet,
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
byId.set(record.id, { record, route: toAnyRoute(route) });
|
|
356
|
+
fullPathById.set(record.id, fullPath);
|
|
357
|
+
mountById.set(record.id, parent.mount);
|
|
358
|
+
attach(parent.route, toAnyRoute(route));
|
|
359
|
+
mountCounts[parent.mount] = (mountCounts[parent.mount] ?? 0) + 1;
|
|
360
|
+
|
|
361
|
+
const navDeclaration = navOf(options);
|
|
362
|
+
if (navDeclaration && navDeclaration.hidden !== true) {
|
|
363
|
+
nav.push({
|
|
364
|
+
id: `${plugin.key}:${record.id}`,
|
|
365
|
+
label: navDeclaration.label,
|
|
366
|
+
...(typeof navDeclaration.icon === "string" ? { icon: navDeclaration.icon } : {}),
|
|
367
|
+
...(typeof navDeclaration.group === "string" ? { group: navDeclaration.group } : {}),
|
|
368
|
+
...(typeof navDeclaration.order === "number" ? { order: navDeclaration.order } : {}),
|
|
369
|
+
to: navDeclaration.to ?? fullPath,
|
|
370
|
+
plugin: plugin.key,
|
|
371
|
+
mount: parent.mount,
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
break;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
if (pending.length > 0) {
|
|
378
|
+
throw new Error(
|
|
379
|
+
`unresolvable parentage in "${plugin.key}": ${pending.map((record) => record.id).join(", ")}`,
|
|
380
|
+
);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
for (const [parent, children] of childrenByParent) {
|
|
385
|
+
(parent as { addChildren: (children: AnyRoute[]) => void }).addChildren(children);
|
|
386
|
+
}
|
|
387
|
+
rootRoute.addChildren([...mountRoutes.values()] as AnyRoute[]);
|
|
388
|
+
nav.sort(compareNavItems);
|
|
389
|
+
|
|
390
|
+
const digest = await digestOf({
|
|
391
|
+
plugins: refs.map((ref) => ({ key: ref.key, mfName: ref.mfName })),
|
|
392
|
+
manifests: resolved.map((plugin) => plugin.manifest),
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
return {
|
|
396
|
+
rootRoute,
|
|
397
|
+
routeTree: rootRoute,
|
|
398
|
+
digest,
|
|
399
|
+
manifests: resolved.map((plugin) => plugin.manifest),
|
|
400
|
+
nav: { items: nav },
|
|
401
|
+
mountCounts,
|
|
402
|
+
};
|
|
403
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-workspace composition contract: file names, MF expose names, and the
|
|
3
|
+
* core's identity — the literals every consumer of the composed tree must
|
|
4
|
+
* agree on. Browser-safe, node-safe, zero imports.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** The core ui's composition key — `bos.config.json`'s `app.ui` identity. */
|
|
8
|
+
export const CORE_UI_PLUGIN_KEY = "ui";
|
|
9
|
+
|
|
10
|
+
export const UI_REMOTE_ENTRY_FILENAME = "remoteEntry.js";
|
|
11
|
+
export const UI_REMOTE_SERVER_ENTRY_FILENAME = "remoteEntry.server.js";
|
|
12
|
+
export const MANIFEST_FILENAME = "manifest.gen.json";
|
|
13
|
+
export const ROUTE_CONFIG_FILENAME = "routeConfig.gen.ts";
|
|
14
|
+
|
|
15
|
+
/** Canonical MF exposes every manifest-composed ui source ships. */
|
|
16
|
+
export const UI_EXPOSES = {
|
|
17
|
+
routeConfig: "./routeConfig",
|
|
18
|
+
compose: "./compose",
|
|
19
|
+
router: "./Router",
|
|
20
|
+
} as const;
|
|
21
|
+
|
|
22
|
+
/** Exposes a PLUGIN ui source ships (the core additionally exposes compose/Router). */
|
|
23
|
+
export const PLUGIN_UI_SHARED_EXPOSES = {
|
|
24
|
+
routeConfig: UI_EXPOSES.routeConfig,
|
|
25
|
+
} as const;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* MF container naming rule shared by the build (rsbuild config) and runtime
|
|
29
|
+
* config resolution — the host must register remotes under exactly the name
|
|
30
|
+
* the built container declares. Delegates to the canonical identity module
|
|
31
|
+
* (`every-plugin/identity`), which owns the derivation.
|
|
32
|
+
*/
|
|
33
|
+
export { containerName as sanitizeContainerName } from "../../identity";
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { MOUNT_REGISTRY_VERSION } from "./mount-registry";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Shape-of-028 descriptor slice (ADR 0005 / plan 028) — composition-resolver
|
|
5
|
+
* surface only. Pure data: `App({...})` returns a typed object. `extends`
|
|
6
|
+
* resolves child-wins over the base app's plugins (publish-time flattening
|
|
7
|
+
* model of wayfinder ticket 08). Plan 028 will declaration-merge
|
|
8
|
+
* `KnownPlugins` from generated types; until then the interface is empty and
|
|
9
|
+
* `Plugin("bogus")` does not compile.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export interface RemoteSource {
|
|
13
|
+
kind: "local" | "remote";
|
|
14
|
+
path?: string;
|
|
15
|
+
mfName?: string;
|
|
16
|
+
url?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface PluginRef {
|
|
20
|
+
key: string;
|
|
21
|
+
source: RemoteSource;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface ResolvedApp {
|
|
25
|
+
name: string;
|
|
26
|
+
plugins: Record<string, PluginRef>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface PluginRefInput {
|
|
30
|
+
name: string;
|
|
31
|
+
source: RemoteSource;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface AppInput {
|
|
35
|
+
name: string;
|
|
36
|
+
extends?: string;
|
|
37
|
+
plugins: Record<string, PluginRefInput>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Declaration-merged from generated types by plan 028 — must stay an interface (types cannot merge). */
|
|
41
|
+
// biome-ignore lint/suspicious/noEmptyInterface: declaration-merge surface
|
|
42
|
+
export interface KnownPlugins {}
|
|
43
|
+
|
|
44
|
+
export function App(input: AppInput): AppInput {
|
|
45
|
+
return input;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function Plugin<K extends Extract<keyof KnownPlugins, string>>(
|
|
49
|
+
name: K,
|
|
50
|
+
): {
|
|
51
|
+
local: (path: string) => PluginRefInput;
|
|
52
|
+
remote: (mfName: string, url: string) => PluginRefInput;
|
|
53
|
+
} {
|
|
54
|
+
return {
|
|
55
|
+
local: (path) => ({ name, source: { kind: "local", path } }),
|
|
56
|
+
remote: (mfName, url) => ({ name, source: { kind: "remote", mfName, url } }),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Flatten an app against the registry of apps: `extends` inherits the base's plugins, child wins. */
|
|
61
|
+
export function resolveApp(input: AppInput, apps: Record<string, AppInput>): ResolvedApp {
|
|
62
|
+
const base = input.extends ? apps[input.extends] : undefined;
|
|
63
|
+
if (input.extends && !base) throw new Error(`extends target "${input.extends}" not found`);
|
|
64
|
+
const plugins: Record<string, PluginRef> = {};
|
|
65
|
+
for (const [key, ref] of Object.entries(base?.plugins ?? {})) {
|
|
66
|
+
plugins[key] = { key, ...ref };
|
|
67
|
+
}
|
|
68
|
+
for (const [key, ref] of Object.entries(input.plugins)) {
|
|
69
|
+
plugins[key] = { key, ...ref };
|
|
70
|
+
}
|
|
71
|
+
return { name: input.name, plugins };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface CompositionDigestInput {
|
|
75
|
+
/** optional app label — deliberately NOT a tree-identity input; omit for server/client parity */
|
|
76
|
+
appName?: string;
|
|
77
|
+
plugins: Array<{ key: string; mfName: string }>;
|
|
78
|
+
manifests: Array<unknown>;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Composition digest — sha256 (WebCrypto) over everything that determines
|
|
83
|
+
* the tree: app name, plugin keys, MF names, manifests, and the imported
|
|
84
|
+
* `MOUNT_REGISTRY_VERSION`. Deployment URLs are deliberately excluded so
|
|
85
|
+
* disk and prod paths digest identically (hydration parity).
|
|
86
|
+
*/
|
|
87
|
+
export async function digestOf(input: CompositionDigestInput): Promise<string> {
|
|
88
|
+
const bytes = new TextEncoder().encode(
|
|
89
|
+
JSON.stringify({ ...input, mountRegistryVersion: MOUNT_REGISTRY_VERSION }),
|
|
90
|
+
);
|
|
91
|
+
const hash = await crypto.subtle.digest("SHA-256", bytes);
|
|
92
|
+
return Array.from(new Uint8Array(hash))
|
|
93
|
+
.map((b) => b.toString(16).padStart(2, "0"))
|
|
94
|
+
.join("")
|
|
95
|
+
.slice(0, 16);
|
|
96
|
+
}
|