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 in your TypeScript code:
import { ChronicleConnection, ChronicleConnectionString } from '@cratis/chronicle.contracts';
// Using the Development connection string (includes default dev credentials)const connection = new ChronicleConnection({ connectionString: ChronicleConnectionString.Development});
// Or using a custom connection stringconst connection = new ChronicleConnection({ connectionString: 'chronicle://my-client:my-secret@localhost:5000'});
// Or using the legacy serverAddress (still supported)const connection = new ChronicleConnection({ serverAddress: 'localhost:5000'});
// Connect to Chronicleawait connection.connect();
// Use the services with full type safety and IDE completionconst eventStores = await connection.eventStores.GetEventStores({});console.log('Event stores:', eventStores.items);
// Access other servicesconst namespaces = await connection.namespaces.GetNamespaces({ EventStore: 'my-store' });
// Clean upconnection.dispose();Authentication
Section titled “Authentication”The package supports two authentication methods:
Client Credentials (OAuth 2.0):
// Connection string with credentialsconst connStr = new ChronicleConnectionString('chronicle://client-id:client-secret@localhost:5000');
// Or using helper methodconst connStr = ChronicleConnectionString.Default.withCredentials('client-id', 'client-secret');
const connection = new ChronicleConnection({ connectionString: connStr });API Key:
// Connection string with API key query parameterconst connStr = new ChronicleConnectionString('chronicle://localhost:5000?apiKey=my-api-key');
// Or using helper methodconst connStr = ChronicleConnectionString.Default.withApiKey('my-api-key');
const connection = new ChronicleConnection({ connectionString: connStr });Custom Authority:
// If using an external OAuth serverconst connection = new ChronicleConnection({ connectionString: connStr, authority: 'https://auth.example.com' // Defaults to Chronicle server if not specified});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