Skip to content

opendecree/decree-typescript

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

91 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

OpenDecree TypeScript SDK

CI npm License Docs 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)
  • A running OpenDecree server (v0.8.0 – v0.x, pre-1.0)

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

Questions?

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

License

Apache License 2.0 -- see LICENSE.