Initial boilerplate scaffold for continuum-schemas

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).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-28 16:12:03 +00:00
commit 660855ecd6
21 changed files with 309 additions and 0 deletions
+15
View File
@@ -0,0 +1,15 @@
[package]
name = "continuum-rust-types"
version = "0.1.0"
edition = "2021"
[lib]
name = "continuum_types"
path = "src/lib.rs"
[dependencies]
prost = "0.13"
serde = { version = "1", features = ["derive"] }
[build-dependencies]
prost-build = "0.13"
+27
View File
@@ -0,0 +1,27 @@
use std::path::PathBuf;
fn main() {
let proto_root = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("../../proto")
.canonicalize()
.expect("proto root must exist");
let proto_files = [
proto_root.join("continuum/v1/material.proto"),
proto_root.join("continuum/v1/print_params.proto"),
proto_root.join("continuum/v1/template.proto"),
proto_root.join("continuum/v1/print_job.proto"),
];
for file in &proto_files {
println!("cargo:rerun-if-changed={}", file.display());
}
let mut config = prost_build::Config::new();
config.type_attribute(".", "#[derive(serde::Serialize, serde::Deserialize)]");
config.type_attribute(".", "#[serde(rename_all = \"camelCase\")]");
config
.compile_protos(&proto_files, &[proto_root])
.expect("failed to compile continuum .proto sources");
}
+9
View File
@@ -0,0 +1,9 @@
pub mod continuum {
pub mod v1 {
include!(concat!(env!("OUT_DIR"), "/continuum.v1.rs"));
}
}
pub use continuum::v1::{
MaterialProfile, PrintJob, PrintJobStatus, PrintParameters, Template,
};
+14
View File
@@ -0,0 +1,14 @@
{
"name": "@continuum/ts-types",
"version": "0.1.0",
"private": true,
"type": "module",
"main": "./src/index.ts",
"types": "./src/index.ts",
"exports": {
".": "./src/index.ts"
},
"dependencies": {
"@sinclair/typebox": "^0.32.0"
}
}
+7
View File
@@ -0,0 +1,7 @@
export * from "./schemas";
// `src/generated/**` is produced by `npm run build:ts` (protoc + ts-proto)
// from the .proto sources in /proto and is not committed. Re-export it
// here once generated so consumers get both the TypeBox runtime schemas
// and the proto-derived TS types from a single package entry point.
export * as proto from "./generated";
+4
View File
@@ -0,0 +1,4 @@
export * from "./material";
export * from "./print-params";
export * from "./template";
export * from "./print-job";
+13
View File
@@ -0,0 +1,13 @@
import { Type, type Static } from "@sinclair/typebox";
export const MaterialProfileSchema = Type.Object({
id: Type.String({ format: "uuid" }),
name: Type.String({ minLength: 1 }),
filamentType: Type.String({ minLength: 1 }),
nozzleTempC: Type.Number(),
bedTempC: Type.Number(),
densityGCm3: Type.Number(),
colorHex: Type.String({ pattern: "^#[0-9a-fA-F]{6}$" }),
});
export type MaterialProfile = Static<typeof MaterialProfileSchema>;
@@ -0,0 +1,27 @@
import { Type, type Static } from "@sinclair/typebox";
export const PrintJobStatusSchema = Type.Union([
Type.Literal("PRINT_JOB_STATUS_UNSPECIFIED"),
Type.Literal("PRINT_JOB_STATUS_QUEUED"),
Type.Literal("PRINT_JOB_STATUS_PRINTING"),
Type.Literal("PRINT_JOB_STATUS_PAUSED"),
Type.Literal("PRINT_JOB_STATUS_COMPLETED"),
Type.Literal("PRINT_JOB_STATUS_FAILED"),
Type.Literal("PRINT_JOB_STATUS_CANCELLED"),
]);
export type PrintJobStatus = Static<typeof PrintJobStatusSchema>;
export const PrintJobSchema = Type.Object({
id: Type.String({ format: "uuid" }),
farmId: Type.String({ format: "uuid" }),
printerId: Type.String({ format: "uuid" }),
templateId: Type.String({ format: "uuid" }),
status: PrintJobStatusSchema,
progressPercent: Type.Number({ minimum: 0, maximum: 100 }),
startedAtUnix: Type.Integer(),
completedAtUnix: Type.Integer(),
gcodeFileKey: Type.String({ minLength: 1 }),
});
export type PrintJob = Static<typeof PrintJobSchema>;
@@ -0,0 +1,12 @@
import { Type, type Static } from "@sinclair/typebox";
export const PrintParametersSchema = Type.Object({
layerHeightMm: Type.Number({ minimum: 0.04, maximum: 1.0 }),
infillPercent: Type.Integer({ minimum: 0, maximum: 100 }),
infillPattern: Type.String({ minLength: 1 }),
printSpeedMmS: Type.Number({ minimum: 0 }),
supportsEnabled: Type.Boolean(),
wallCount: Type.Integer({ minimum: 0 }),
});
export type PrintParameters = Static<typeof PrintParametersSchema>;
+18
View File
@@ -0,0 +1,18 @@
import { Type, type Static } from "@sinclair/typebox";
import { MaterialProfileSchema } from "./material";
import { PrintParametersSchema } from "./print-params";
export const TemplateSchema = Type.Object({
id: Type.String({ format: "uuid" }),
name: Type.String({ minLength: 1 }),
description: Type.String(),
ownerId: Type.String({ format: "uuid" }),
modelFileKey: Type.String({ minLength: 1 }),
material: MaterialProfileSchema,
printParameters: PrintParametersSchema,
createdAtUnix: Type.Integer(),
updatedAtUnix: Type.Integer(),
tags: Type.Array(Type.String()),
});
export type Template = Static<typeof TemplateSchema>;
+8
View File
@@ -0,0 +1,8 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src"]
}