Framework-agnostic Node.js reactor for Capsium
packages: serves a .cap archive (or an unpacked package directory) over
node:http or as Connect/Express middleware, per the canonical schemas in
the Capsium org architecture decisions (../../../ARCHITECTURE.md):
Cache-Control: public, max-age=31536000 default (route-level headers
override it wholesale);/api/v1/data/ served as JSON;.capsium-tombstones deletions
resolve 404) and §4a composite packages (capsium://<guid>/<path>
dependency resources resolved from a package store; only exported
resources are visible; remap/responseRewrite/responseHeaders
inheritance attributes honored);/api/v1/introspect/
(metadata, routes, content-hashes, content-validity);501 (not executed by this reactor);405 with an Allow header;404 ({"error": "..."}).Init is fail-fast: the package is loaded and verified (§6 SHA-256 checksums,
§6a digital signatures, §4a dependency resolution) before the handler is
returned; problems throw typed errors (PackageConfigError,
PackageIntegrityError, SignatureMismatchError, EncryptedPackageError,
DependencyResolutionError, ...).
npm install @capsium/reactor-node
Plain node:http:
import { createServer } from 'node:http';
import { createReactor } from '@capsium/reactor-node';
const handler = await createReactor({ package: './my-package.cap' });
createServer((req, res) => void handler(req, res)).listen(8864);
As Express/Connect middleware (the reactor owns its URL space — mount it at
the path the package should be served from; next(err) is called only for
unexpected internal errors):
import express from 'express';
import { createReactor } from '@capsium/reactor-node';
const app = express();
app.use('/my-package', await createReactor({ package: './my-package.cap' }));
app.listen(3000); // package served under /my-package
await createReactor({
// Package directory, .cap archive path, or an already-read
// PackageReader result (CapsiumPackage model).
package: './my-package.cap',
// §4a store directory for composite packages (default: CAPSIUM_STORE env).
store: './store',
// Cache-Control default for static resources (route headers override).
cacheControl: 'public, max-age=31536000',
// RSA private key PEM for §6b encrypted packages.
decryptionKeyPem: process.env.CAPSIUM_KEY,
});
Instant local serving over a plain node:http server (default port 8864,
--port 0 picks an ephemeral port):
capsium-reactor-node ./my-package.cap --port 8080 --store ./store
# or from a checkout: node packages/reactor-node/dist/bin.js ./my-package.cap
corepack yarn install
corepack yarn workspaces foreach -A --include @capsium/reactor-node run test
Tests drive the handler through real node:http servers bound to ephemeral
ports (supertest-style); no Express dependency is used anywhere.