@collective-intelligence/extensions-sdk-frontend
v0.1.31
Published
Framework-neutral frontend declaration, catalog, and activation contracts for Collective Intelligence extension packages.
Downloads
5,006
Readme
@collective-intelligence/extensions-sdk-frontend
Framework-neutral declaration, catalog, and activation contracts for frontend extension packages. The package has no React or host-application dependency, so third-party extensions can publish declarations without depending on private platform packages.
import {
admitFrontendCatalog,
createFrontendCatalog,
declareFrontendCatalogContribution,
declareFrontendComponent,
declareFrontendPackage
} from "@collective-intelligence/extensions-sdk-frontend"
const field = declareFrontendComponent({
target: {
fqn: "com.acme.crm.fields.customer",
packageFqn: "com.acme.crm",
role: "render",
version: "1.0.0"
},
implementation: {
render: {
exportName: "CustomerField",
load: () => import("./customer-field"),
module: "./customer-field"
}
}
})
const packageDeclaration = declareFrontendPackage({
manifest: {
fqn: "com.acme.crm",
name: "Acme CRM",
version: "1.0.0"
},
components: [field]
})
const catalog = createFrontendCatalog()
catalog.activate([packageDeclaration])
export const studioCatalog = declareFrontendCatalogContribution({
fqn: "com.acme.crm.studio.catalog",
host: "studio",
load: () => import("./studio-catalog")
})
const admitted = await admitFrontendCatalog({
authority: {
logical: {
...studioCatalog.manifest,
contributionFqn: studioCatalog.manifest.fqn,
packageFqn: "com.acme.crm",
packageVersion: "1.0.0",
servingGeneration: 1
},
physical: {
...studioCatalog.manifest,
assetDigest: "a".repeat(64),
carrierPackageFqn: "com.acme.crm",
contributionFqn: studioCatalog.manifest.fqn,
extensionReleaseDigest: "b".repeat(64)
}
},
loadedModule: await studioCatalog.load()
})Use the optional load callback to make renderer imports visible to bundlers.
Hosts supporting this callback load its module namespace lazily, then select
exportName; module remains available for diagnostics and import fallback when
no callback is supplied. Declaration and catalog activation never invoke the
callback. The callback, module locator, and export name are runtime sidecars:
canonical frontend manifests and component identity exclude them.
The root entrypoint is the public import surface. Internally,
declarations/ owns immutable authoring values, catalog/ owns exact binding
validation and resolution, and admitFrontendCatalog owns dynamic loader and
authorized-result admission.
The /effect entrypoint is empty: this package has no I/O client and no
Expected Error, so it has no Effect service. Its loaders come from the host.
effect (^4.1.0) is a required peer dependency: the app installs one copy
of effect, and the package build keeps it external.
Every Dashboard or Studio release contribution uses
frontend-catalog/v1 and the fixed loadFrontendCatalog export. Admission
checks logical and physical provenance, callable and async loader behavior,
package/component ownership, and exact binding uniqueness before returning an
immutable declaration set. Admission keeps each component's load callback and
rejects a component whose load is not callable; a bundled Host cannot import a
renderer by module, because its chunk exports minified names. This contract
does not admit navigation, root-page, or shell contributions.
Declarations carry exact package, FQN, version, and role identity. Module
references are runtime sidecars and are excluded from canonical declaration
serialization. A component's target version identifies its own contract and may
differ from the containing package release version. Canonical JSON and package
identity come from
@collective-intelligence/extensions-sdk; React loading, rendering, and hosted
diagnostics live in
@collective-intelligence/extensions-sdk-frontend-react/frontend.
