Skip to content

Constants Usage

What It Is

Constants Usage shows how to use Dagonizer’s exported runtime constants instead of hardcoded strings. The example exercises GatherStrategyName, MetadataKey, NodeType, Output, and ScatterOutput as guards and lookup values.

This is a small CLI example rather than a DAG demo. It exists for application code that needs to validate engine tokens, build selectors, or write tests that stay aligned with the schema-derived constants.

How It Works

Every exported constant has two surfaces: a frozen runtime lookup object and a TypeScript type derived from the schema. Application code can enumerate the runtime object for validation while preserving compile-time narrowing in TypeScript.

Diagrams, Examples, and Outputs

This page has no DAG diagram because it does not register or execute a graph. The runnable output is the CLI script proving that the constants can be used as runtime guards.

Run

bash
npx tsx examples/constants-usage.ts

What It Lets You Do

Typed constants let applications validate and compare engine string values without hardcoding routing tokens, metadata keys, node kinds, or gather names. Use them in custom validators, UI selectors, test fixtures, and guard code that must stay aligned with Dagonizer's schema-derived values.

Every typed constant from @studnicky/dagonizer/constants ships a frozen runtime lookup object (plural name, e.g. NodeTypes) and a FromSchema-derived TypeScript type (singular name, e.g. NodeType). This example exercises each constant as a runtime guard and prints the results — no dispatcher, no DAG execution required.

Constants demonstrated:

ConstantPurpose
Output'success' and 'error' — standard routing token names
NodeType'SingleNode', 'ScatterNode', 'EmbeddedDAGNode', 'TerminalNode', 'PhaseNode'
GatherStrategyName'map', 'append', 'collect', 'partition', 'discard', 'custom'
MetadataKey'currentItem', 'itemIndex', and 'gatherResults' — keys the engine writes into state.metadata
ScatterOutput'all-success', 'all-error', 'partial', 'empty' — outcome-reducer routing tokens

Code Samples

ts
/**
 * constants-usage: demonstrates every typed constant from
 * @studnicky/dagonizer/constants as runtime guards.
 *
 * Each constant in the package is both a frozen runtime lookup object and a
 * FromSchema-derived TypeScript type of the same name. This example calls the
 * helper functions defined in dags/constants-usage.ts directly — no dispatcher,
 * no DAG execution required — and prints which values pass each guard.
 *
 * DAG definition (guard helpers, CatalogueItem type): examples/dags/constants-usage.ts
 *
 * Run: npx tsx examples/constants-usage.ts
 */

import {
  MetadataKeys,
  NodeTypes,
  OutputNames,
  ScatterOutputNames,
  type MetadataKeyType,
} from '@studnicky/dagonizer/constants';
import type { CatalogueItem } from './dags/constants-usage.js';
import { ConstantUsage } from './dags/constants-usage.js';

// ── Exercise every guard and print results ──────────────────────────────────

process.stdout.write('\n=== @studnicky/dagonizer/constants typed-guard demo ===\n\n');

// OutputNames
process.stdout.write('Output values:\n');
for (const v of Object.values(OutputNames)) {
  process.stdout.write(`  OutputNames.${v} => "${ConstantUsage.describeOutput(v)}"\n`);
}

// NodeTypes
process.stdout.write('\nNodeType scatter check:\n');
for (const v of Object.values(NodeTypes)) {
  process.stdout.write(`  NodeTypes.${v} isScatter=${String(ConstantUsage.isScatterPlacement(v))}\n`);
}

// GatherStrategyName
process.stdout.write('\nGatherStrategyName guard:\n');
const candidates = ['map', 'collect', 'partition', 'top-n', 'unknown-strategy'];
for (const c of candidates) {
  process.stdout.write(`  "${c}" isKnown=${String(ConstantUsage.isKnownGatherStrategy(c))}\n`);
}

// MetadataKey
process.stdout.write('\nMetadataKey.CURRENT_ITEM read:\n');
const record: Partial<Record<MetadataKeyType, CatalogueItem>> = {
  [MetadataKeys.CURRENT_ITEM]: { title: 'The Archivist Compendium' },
};
process.stdout.write(`  currentItem=${JSON.stringify(ConstantUsage.readCurrentItem(record))}\n`);

// ScatterOutput
process.stdout.write('\nScatterOutput interpretations:\n');
for (const v of Object.values(ScatterOutputNames)) {
  process.stdout.write(`  ScatterOutputNames.${v} => "${ConstantUsage.interpretScatterOutput(v)}"\n`);
}

process.stdout.write('\nAll constant guards exercised.\n');

Details for Nerds

  • Frozen runtime objects. Object.values(GatherStrategyNames) enumerates all valid gather strategy names. Use this for validation or for building a selector that accepts only known strategies.
  • MetadataKeys.CURRENT_ITEM. The key the engine writes per scatter clone so nodes can read state.getMetadata(MetadataKeys.CURRENT_ITEM) (or a typed state.getter.* accessor) without hardcoding strings.
  • NodeType as a type guard. type === NodeTypes.SCATTER narrows the node shape to ScatterNode in TypeScript.
  • ScatterOutput routing tokens. all-success, all-error, partial, and empty are the outcome-reducer routing tokens. The constant ensures consuming code references the same string the reducer emits.

Watched over by the Order of Dagon.