Loop Engine

Packages

@loop-engine/registry-client

@loop-engine/registry-client provides local-first loop definition lookup with optional network adapters.

Install

1npm install @loop-engine/registry-client

Local registry

1import { localRegistry } from "@loop-engine/registry-client"
2 
3const registry = localRegistry({
4 definitions: [customLoop],
5 loopsDir: "./loops",
6 watch: true
7})
  • definitions works in browser and Node.
  • loopsDir loads .yaml, .yml, and .json definitions in Node.
  • Browser usage with loopsDir logs a warning and ignores filesystem mode.

HTTP registry

1import { httpRegistry } from "@loop-engine/registry-client"
2 
3const registry = httpRegistry({
4 baseUrl: "https:">//registry.example.com",
5 headers: { Authorization: `Bearer ${token}` },
6 timeoutMs: 10_000,
7 retries: 2
8})

Expected server contract:

  • GET /loops
  • GET /loops?domain={domain}
  • GET /loops/{loopId}
  • GET /loops/{loopId}/{version}
  • POST /loops
  • DELETE /loops/{loopId}

Better Data adapter

1import { betterDataRegistry } from "@loop-engine/registry-client/betterdata"
2 
3const registry = betterDataRegistry({
4 apiKey: process.env.BD_API_KEY!,
5 orgId: "your-org-id",
6 env: "production"
7})

Registry interface

1interface LoopRegistry {
2 get(id: LoopId): Promise<LoopDefinition | null>
3 getVersion(id: LoopId, version: string): Promise<LoopDefinition | null>
4 list(options?: { domain?: string }): Promise<LoopDefinition[]>
5 has(id: LoopId): Promise<boolean>
6 register(definition: LoopDefinition, options?: { force?: boolean }): Promise<void>
7 remove(id: LoopId): Promise<boolean>
8}

SDK integration

createLoopSystem({ loops, registry }) merges registry results with local loops. Local loops[] definitions override matching registry IDs, and registry failures fall back to local-only startup.