TypeScript gRPC Package Generation
This document explains the TypeScript gRPC package generation and publishing setup for Chronicle.
Overview
Section titled “Overview”The Chronicle TypeScript gRPC package (@cratis/chronicle.contracts) provides strongly-typed TypeScript bindings for Chronicle’s gRPC services. The package generation process consists of two main steps:
- Generate .proto files from C# gRPC service definitions (see Protobuf Extraction)
- Generate TypeScript code from proto files and publish the npm package
Components
Section titled “Components”1. TypeScript Package (Source/Clients/TypeScript)
Section titled “1. TypeScript Package (Source/Clients/TypeScript)”An npm package that provides strongly-typed TypeScript bindings for the Chronicle gRPC services.
Structure:
package.json- Package configuration with @cratis/chronicle.contracts as the package nametsconfig.json- TypeScript compiler configurationrollup.config.mjs- Rollup bundler configuration for ESM and CJS buildsindex.ts- Main entry point that exports all generated servicesChronicleConnection.ts- Connection manager for Chronicle servicesChronicleServices.ts- Interface for all available servicesgenerated/- Directory containing TypeScript files generated from proto definitionsREADME.md- Package documentation
How it works:
- Uses
ts-prototo generate TypeScript files from proto definitions - Generates proto
int64/uint64fields as TypeScriptbigint(forceLong=bigint) - Generates strongly-typed clients with full IDE support and IntelliSense
- Provides
ChronicleConnectionclass for easy connection management - Provides
ChronicleConnectionStringclass for connection string parsing - Implements OAuth 2.0 client credentials flow for authentication
- Exports all service clients and types
- Builds both ESM and CJS versions using Rollup
Key classes:
ChronicleConnection- Main connection manager with service accessChronicleConnectionString- Connection string parser supportingchronicle://URI schemeChronicleServices- Interface defining all available servicesTokenProvider- OAuth token management (client credentials and API key)
2. GitHub Workflows
Section titled “2. GitHub Workflows”Build Workflow (.github/workflows/typescript-build.yml)
Section titled “Build Workflow (.github/workflows/typescript-build.yml)”Validates the TypeScript package on every PR and push to main.
Triggers:
- Push to main branch
- Pull requests to any branch
- Changes to TypeScript client, Contracts, Protobuf, or ProtoGenerator
Steps:
- Setup .NET 10 and Node.js 23
- Install protoc (Protocol Buffer Compiler)
- Build the Contracts assembly
- Run ProtoGenerator to generate .proto files
- Install TypeScript dependencies
- Generate TypeScript files from proto definitions using ts-proto
- Build TypeScript package
Publish Workflow (.github/workflows/publish.yml)
Section titled “Publish Workflow (.github/workflows/publish.yml)”Publishes the TypeScript package to NPM alongside .NET packages during releases.
Triggers:
- Release published
Steps:
- Setup .NET 10 and Node.js 23
- Install protoc
- Build the Contracts assembly
- Run ProtoGenerator to generate .proto files
- Install TypeScript dependencies
- Generate TypeScript files using ts-proto
- Build TypeScript package
- Publish to NPM
- Commit and push updated proto and TypeScript files back to repository
Required Secrets:
NPM_TOKEN- NPM authentication token for publishing
Prerequisites
Section titled “Prerequisites”Proto files must be generated first. See Protobuf Extraction for details on generating proto files from C# contracts.
Building TypeScript Package Locally
Section titled “Building TypeScript Package Locally”cd Source/Clients/TypeScriptyarn installyarn buildUsing the Published Package
Section titled “Using the Published Package”Install the package:
npm install @cratis/chronicle.contracts# oryarn add @cratis/chronicle.contractsUse the generated service definitions from your gRPC transport code:
import { EventStoresDefinition } from '@cratis/chronicle.contracts';
const eventStoresService = EventStoresDefinition.fullName;const eventStoresMethods = Object.keys(EventStoresDefinition.methods);
console.log(`Generated service ${eventStoresService} exposes: ${eventStoresMethods.join(', ')}`);The package also includes generated request and response message helpers:
import { EnsureEventStore, EnsureNamespace, GetNamespacesRequest } from '@cratis/chronicle.contracts';
const eventStore = EnsureEventStore.create({ Name: 'shopping' });const namespace = EnsureNamespace.create({ EventStore: eventStore.Name, Name: 'tenant-one' });const namespaces = GetNamespacesRequest.create({ EventStore: eventStore.Name });
console.log(eventStore, namespace, namespaces);Service Definitions
Section titled “Service Definitions”Service definitions expose the protobuf service name and generated method definitions:
import { NamespacesDefinition } from '@cratis/chronicle.contracts';
const getNamespacesMethod = NamespacesDefinition.methods.getNamespaces;
console.log(`${NamespacesDefinition.fullName}.${getNamespacesMethod.name}`);Typed Clients
Section titled “Typed Clients”When a gRPC transport creates clients from the generated definitions, use the generated client interfaces for type safety:
import { EventStoresClient, NamespacesClient } from '@cratis/chronicle.contracts';
async function readAvailableNamespaces(eventStores: EventStoresClient, namespaces: NamespacesClient): Promise<string[]> { await eventStores.ensure({ Name: 'shopping' }); const result = await namespaces.getNamespaces({ EventStore: 'shopping' });
return result.items;}Publishing a New Version
Section titled “Publishing a New Version”The TypeScript package is automatically published to NPM when a new GitHub release is created. The publish workflow will:
- Generate fresh proto files from C# contracts
- Generate TypeScript code from proto files
- Build the TypeScript package
- Publish to NPM with the release version tag
- Commit updated proto and TypeScript files back to the repository
Generated Files
Section titled “Generated Files”Proto files: Source/Kernel/Protobuf/*.proto
See Protobuf Extraction for the complete list of generated proto files.
TypeScript files: Source/Clients/TypeScript/generated/*.ts
The TypeScript generation creates:
- Service client interfaces and implementations
- Request and response message types
- Enum definitions
- Type definitions for all Chronicle concepts
Maintenance
Section titled “Maintenance”When adding new gRPC services to the C# Contracts:
- Ensure services are decorated with
[Service]attribute - Ensure methods are decorated with
[Operation]attribute - Regenerate proto files (see Protobuf Extraction)
- Run the TypeScript generation to create new TypeScript clients
- The TypeScript package will automatically include the new services with full type safety
- Publish a new version of the npm package by creating a GitHub release
Package Structure
Section titled “Package Structure”The published npm package includes:
- ESM build (
dist/esm/) - ES modules for modern bundlers - CJS build (
dist/cjs/) - CommonJS for Node.js compatibility - Type definitions (
dist/types/) - TypeScript .d.ts files for IntelliSense - Source maps - For debugging support
- README.md - Package documentation
Dependencies
Section titled “Dependencies”The TypeScript package has the following runtime dependencies:
@grpc/grpc-js- gRPC client for Node.js@grpc/proto-loader- Protocol buffer loading (for metadata)
Development dependencies include:
ts-proto- TypeScript code generation from proto filestypescript- TypeScript compilerrollup- Module bundler for builds- Various Rollup plugins for TypeScript and module resolution