Two cleanups, one cause each.
The root tsconfig.json carried the compilerOptions directly with no `include`,
which made `tsc -b` treat the whole repository as one project: it ignored each
package's `outDir` and emitted .js/.d.ts next to every source file, which then
got committed. So every typecheck dirtied the tree and the build output was in
git. The root is now a solution file that only references the real projects,
shared options moved to tsconfig.base.json, and the six emitted files are
removed from the index. Output goes to packages/ts-types/dist, which was
already gitignored.
@sinclair/typebox is now pinned exactly rather than by caret range. It is
load-bearing in a way a range should not be allowed near: continuum-backend's
Elysia requires it at runtime without declaring it as a dependency at all, and
@continuum/ts-types resolves its own copy from here, so two different versions
mean two structurally incompatible TSchema types and nothing from this package
validates anything there.
Worth recording what that looked like, because the error pointed elsewhere.
Elysia accepts `TSchema | StandardSchemaV1Like`; when the TSchema branch failed
on the version skew, TypeScript reported the *other* branch's failure,
`'~standard' is missing`. That reads as "Elysia wants a Standard Schema
validator, TypeBox is wrong here", which is not true - Elysia is TypeBox-native
and Standard Schema is just the alternative for Zod/Valibot users. The fix was
only ever to make the versions match.
0.34.52 rather than 0.33.x because Elysia 1.4 calls `t.Module`, which 0.34
introduced. continuum-backend pins the identical version and
tests/dependency_identity.test.ts there fails if the two ever drift again.
continuum-proxy and continuum-backend each had their own idea of what the
edge WebSocket carried, and the two did not overlap anywhere: the backend
expected an `auth` handshake the gateway never sends, telemetry shaped one
printer per message where the gateway sends a batch, and UUID printer ids a
gateway has no way to know. Neither end had a command path that matched the
other. Nothing failed, because nothing was written down for both sides to
mirror. This is that document.
schemas/continuum/v1/edge/ is canonical: client_message, server_message,
printer_telemetry and printer_command. packages/ts-types gets its first
real TypeBox mirror - the placeholder there said to add one "once something
actually consumes it", and continuum-backend's edge route now does. The
Rust mirror stays in continuum-proxy/src/uplink/protocol.rs rather than
packages/rust-types, since the gateway is its only Rust consumer.
Two decisions worth recording:
Field names are snake_case, unlike the backend's HTTP routes. The other end
is serde-derived Rust, and snake_case is what those structs produce without
a rename attribute on every field. It is also what the rest of this
repository already uses.
Optional fields accept an explicit null as well as being absent. A gateway
omits what it has no value for, which is what these schemas describe - but
serde emits null by default unless every field is annotated, and a single
such field would otherwise fail validation and take a whole farm's
telemetry batch down with it. Strict in what we send, liberal in what we
accept; the contract tests on both sides pin down each half.
Also bumps this package's @sinclair/typebox to ^0.33.12 to match what
continuum-backend already pins. It was on ^0.32.0, which resolved to a
separate 0.32.37 install - two TypeBox versions means two incompatible
TSchema identities, and Elysia rejected every schema from here on those
grounds alone.
Continuum is intended to be sold, so every dependency has to permit
distribution in closed-source commercial software. Nothing recorded that
before: our own crates and npm packages carried no licence field at all,
which made `cargo deny` report them as `unlicensed` errors and left the
actual policy nowhere.
Crates now declare `LicenseRef-Proprietary` with `publish = false`.
That string is deliberately not a real SPDX identifier, so it must never
appear in a `deny.toml` allow list - a third-party crate claiming it
would be a genuine finding. npm packages use `"license": "UNLICENSED"`,
the equivalent convention there.
`deny.toml` holds the permissive-only allow list. The policy itself, the
audit, and the three categories cargo-deny cannot see (external
binaries, ML model weights, self-hosted servers) are documented in
continuum-common's docs/LICENSES.md.
Nothing imported the proto-generated code (zero references to
continuum-rust-types or @continuum/ts-types's proto export in any
consumer repo), and protobuf's real value - one schema compiled to a
compact binary wire format for both languages - never applied: BE<->proxy
and FE<->BE are both JSON. Also fixes 8 broken $ref paths in the bambulab
schemas and a root tsconfig.json that was sweeping the gitignored
examples/ directory into typecheck.
- proto/continuum/v1/*.proto -> schemas/continuum/v1/*.schema.json
- packages/rust-types: hand-written serde structs instead of
prost-build codegen
- packages/ts-types: drop the generated/ proto barrel export, keep the
hand-written TypeBox schemas as the TS source of truth
- root package.json: drop build:ts, protoc, ts-proto
protoc warned that print_job.proto imported template.proto without using it
- removed. ts-types/package.json was missing protobufjs and long, which the
ts-proto-generated code imports at runtime - tsc failed with 'cannot find
module'. src/index.ts also re-exports './generated' as a namespace, but
ts-proto wasn't configured to emit an index barrel file for it - added
outputIndex=true to the protoc invocation.
Verified with a clean 'bun run build' (both TS and Rust codegen) and
'tsc -b'.
Protobuf data model (Template/PrintJob/MaterialProfile/PrintParameters)
with codegen targets for TypeBox+TS types (packages/ts-types) and
prost-derived Rust structs (packages/rust-types).