Build composable Camino packages with explicit type and source dependencies

This commit is contained in:
Timothy J. Aveni
2026-09-22 14:42:54 -07:00
parent 7173751f37
commit 82a4542746
30 changed files with 736 additions and 420 deletions
+9 -5
View File
@@ -137,6 +137,7 @@ export function generatePackageQueryClientBindings(
export function generateComponentClientBindings(plan: ExecutionPlan, packageRevision: string): string {
const pkg = plan.definition.workspace.packageImports.find((pkg) => pkg.revisionId === packageRevision);
const components = plan.definition.packages.find((pkg) => pkg.revision === packageRevision)?.components;
const modules = plan.definition.packages.find((pkg) => pkg.revision === packageRevision)?.modules ?? [];
if (!pkg || !components?.length)
throw new ExecutionPlanError("NO_COMPONENT_CONTRACT", packageRevision, "Package declares no component entries");
const byId = new Map(plan.definition.workspace.interfaceImports.map((iface) => [iface.revisionId as string, iface]));
@@ -166,12 +167,15 @@ export function generateComponentClientBindings(plan: ExecutionPlan, packageRevi
subjectBindings +
"\n" +
queries +
"\nexport interface Components {\n" +
"\nexport interface ModuleProps {}\n" +
"export type ExtraModuleProps<K extends string> = K extends keyof ModuleProps ? ModuleProps[K] : {};\n" +
"export interface Modules {\n" +
components
.map(
(component) =>
`${JSON.stringify(component.displayName)}: ComponentType<ComponentProps<${JSON.stringify(component.subject)}>>;`,
)
.map((component) => {
const module = modules.find((module) => module.id === component.id)!;
const key = JSON.stringify([module.interfaceRevisionId, module.memberId]);
return `${JSON.stringify(component.displayName)}: ComponentType<ComponentProps<${JSON.stringify(component.subject)}> & ExtraModuleProps<${JSON.stringify(key)}>>;`;
})
.join("\n") +
"\n}\n"
);
+7 -1
View File
@@ -39,7 +39,13 @@ export function expectedArtifactReceipt(
// A process service may implement transactions in any language. Only the
// checked JS module path promises generated TypeScript adapter evidence.
const available = new Set(
manifest.implementations.filter((i) => i.compatibility === "quixos-js-module-v1").map((i) => i.target),
manifest.implementations
.filter(
(i) =>
i.compatibility === "quixos-js-module-v1" &&
i.exports.some((id) => pkg.exports.some((entry) => entry.id === id && entry.execution.kind !== "remote")),
)
.map((i) => i.target),
);
const targets = [
...new Set(