@wireio/cluster-tool-shared
v0.1.7
Published
Shared zod schema-first shapes (persisted configs and wire envelopes) behind SchemaCodec
Readme
@wireio/cluster-tool-shared
The shared data contract for WIRE test clusters — the plain-TypeScript
shapes that describe a cluster's persisted layout, consumed by both the
harness (@wireio/cluster-tool) and the debugging surface
(@wireio/debugging-shared, debugging-server, the TUI). Types only — no
runtime behavior lives here. Hydration/resolution of these shapes is owned by
cluster-tool's provider namespaces (ClusterConfigProvider,
BindConfigProvider).
Why this package exists
cluster-tool depends on debugging-shared, so debugging-shared cannot
import the harness's types without forming a cycle. Historically that forced
hand-maintained structural mirrors of the config shapes — a drift hazard. This
package sits below both: each shape is declared exactly once, and every
other expression of it (caller options, runtime providers) is derived from or
typed against these declarations.
Contents
| Path | Contents |
|---|---|
| src/cluster/ClusterFiles.ts | ClusterFiles — the on-disk filenames (cluster-config.json, cluster-state.json, cluster-keys.json) |
| src/cluster/ClusterState.ts | ClusterState / ClusterStateNode / ClusterStateNodePorts / ClusterStateNodeRole (bios / producer / operator / api) — the secret-free post-bootstrap snapshot (cluster-state.json) |
| src/config/BindConfig.ts | BindConfig + the BindConfig* shape family (including the nodeop.ports.api list — one port pair per API node), BindOverrides<T> (the derived caller-options projection), Bind*Options, ClusterTopologyOptions |
| src/config/ClusterConfig.ts | ClusterConfig (the cluster-config.json shape) + ClusterConfig* nested family, CollateralRequirement, ClusterExecutablePaths |
| src/config/NodeopReadMode.ts | NodeopReadMode — nodeop's read-mode values (head / irreversible / speculative) |
| src/config/QueryEngineConfig.ts | QueryEngineConfig / QueryEngineReadMode / QueryEngineLimits — the query-engine config of a cluster's API nodes (persisted as ClusterConfig.queryEngine) and of a standalone create-api-node artifact: the read mode plus the twelve query-* limits, every member null unless set |
| src/process/ProcessSignals.ts | ProcessSignalName (the POSIX signal identity enum) + ProcessSignals (name → number) / ProcessSignalNumber — the ONE signal spelling of the harness process managers and the wql CLI / TUI signal handlers |
| src/rpc/JsonRPCProtocol.ts | JsonRPCProtocol (Version "2.0", HttpMethod, RequestHeaders, the five standard ErrorCodes) + JsonRPCVersionSchema / JsonRPCIdSchema / JsonRPCErrorSchema / JsonRPCResponseEnvelopeSchema and its SchemaCodec — the ONE JSON-RPC 2.0 spelling shared by the debugging server/client and the query-engine client (server enums reference ErrorCode for the standard members) |
| src/rpc/JsonRPCTransport.ts | JsonRPCTransport.invoke — the ONE JSON-RPC-over-HTTP pipeline (POST the serialized envelope → 2xx with a body → parse once → validate with the response codec → id check) returning the decoded envelope; each client branches on result/error and maps failures itself |
| src/rpc/JsonRPCTransportError.ts | JsonRPCTransportError + JsonRPCTransportStage (request / status / read / decode / id) — the transport's typed failure, carrying the parsed body of a decode failure for client-specific probing |
| src/types/ChainTokenAmount.ts | ChainTokenAmount — harness-local (chain, token) amount tuple |
Design rules
- Data only — one exception. No process state and no resolution logic —
those live in
cluster-tool's providers. The single I/O surface isJsonRPCTransport.invoke, the wire pipeline every JSON-RPC client shares; it takes itsfetchfrom the caller and holds no state. - Derivations over mirrors. Caller-option shapes are derived from the
resolved shapes via
BindOverrides<T>(recursive all-optional projection with pin-whole atoms) — never hand-written in parallel. - Enum→literal assignability. Fields that project identity string enums
(
Report.Format,Level,LogFileAppender.Format) are typed as literal unions; the enum values satisfy them structurally, so producers need no mapping code. - Secret hygiene.
cluster-state.jsonshapes here are secret-free by design; key material (cluster-keys.json) iscluster-tool-private and has no type here.
Consuming
// package.json
"dependencies": { "@wireio/cluster-tool-shared": "workspace:*" }import {
ClusterConfig,
ClusterFiles,
ClusterState
} from "@wireio/cluster-tool-shared"Add a project reference to ../cluster-tool-shared/tsconfig.json in the
consumer's tsconfig.cjs.json; the root tsconfig paths map and each jest
moduleNameMapper already resolve the alias to source.
Build & test
pnpm build # tsc -b + hybrid ESM/CJS output fixup
pnpm test # jest (tests/ mirrors src/)