Skip to content

opendecree/decree-typescript

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

78 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

OpenDecree TypeScript SDK

CI npm Node Downloads License Project Status: WIP codecov Open in GitHub Codespaces

TypeScript SDK for OpenDecree -- schema-driven configuration management.

Alpha -- This SDK is under active development. APIs and behavior may change without notice between versions.

Requirements

  • Node.js β‰₯ 22 (ESM-only package β€” CommonJS is not supported)

Install

npm install @opendecree/sdk

Quick Start

The SDK implements Symbol.dispose / Symbol.asyncDispose, so you can use TypeScript 5.2's using statement for automatic cleanup β€” no try/finally needed.

import { ConfigClient } from '@opendecree/sdk';

// `using` closes the gRPC channel automatically when the block exits
await using client = new ConfigClient('localhost:9090', { subject: 'myapp' });

// Get config values (default: string)
const fee = await client.get('tenant-id', 'payments.fee');

// Typed gets via runtime converters
const retries = await client.get('tenant-id', 'payments.retries', Number);
const enabled = await client.get('tenant-id', 'payments.enabled', Boolean);

// Nullable gets
const optional = await client.get('tenant-id', 'payments.fee', Number, { nullable: true });

// Set values
await client.set('tenant-id', 'payments.fee', '0.5%');

// Set multiple values atomically
await client.setMany('tenant-id', {
  'payments.fee': '0.5%',
  'payments.retries': '3',
});
Prefer try/finally?
const client = new ConfigClient('localhost:9090', { subject: 'myapp' });
try {
  const fee = await client.get('tenant-id', 'payments.fee');
  // ...
} finally {
  client.close();
}

Watch for Changes

ConfigWatcher also supports await using for automatic stop + close:

import { ConfigClient } from '@opendecree/sdk';

await using client = new ConfigClient('localhost:9090', { subject: 'myapp' });
await using watcher = client.watch('tenant-id');

// Register fields before starting
const fee = watcher.field('payments.fee', Number, { default: 0.01 });
const enabled = watcher.field('payments.enabled', Boolean, { default: false });

// Load snapshot + start streaming
await watcher.start();

// Synchronous access to current values
console.log(fee.value);     // number
console.log(enabled.value); // boolean

// EventEmitter pattern
fee.on('change', (oldVal, newVal) => {
  console.log(`Fee changed: ${oldVal} -> ${newVal}`);
});

// Or async iteration (yields Change objects)
for await (const change of fee) {
  console.log(change.fieldPath, change.newValue);
}
// watcher.stop() + client.close() called automatically

Examples

Runnable examples in the examples/ directory:

Example What it shows
quickstart using / await using, type converters (Number, Boolean)
live-config ConfigWatcher, .on('change'), for await...of
nextjs-integration Singleton watcher for server-side config
error-handling RetryConfig, { nullable: true }, instanceof narrowing

Documentation

  • πŸ“– API Reference -- full TypeDoc API reference
  • Quick Start -- install, first get/set, typed gets, error handling
  • Configuration -- all client options, auth, TLS, retry, timeouts
  • Watching -- ConfigWatcher, WatchedField, EventEmitter, async iteration

Requirements

  • Node.js 22+
  • A running OpenDecree server (v0.8.0 – v0.x, pre-1.0)

Questions?

Head to OpenDecree Discussions -- our community hub covers all OpenDecree repos.

License

Apache License 2.0 -- see LICENSE.