Quick Start
This guide walks through building a plan, running it, and inspecting the results.
-
Install the package
Terminal window npm install @origints/core -
Create a plan
A plan defines what data to extract and how to structure the output. Plans are immutable — once compiled, they can be run multiple times.
import { Planner, load } from '@origints/core'const plan = new Planner().in(load({ name: 'Alice', age: 30, role: 'admin' })).emit((out, $) => out.add('name', $.get('name').string()).add('age', $.get('age').number()).add('role', $.get('role').string())).compile() -
Run the plan
import { run } from '@origints/core'const result = await run(plan) -
Handle the result
The result is a discriminated union — never a thrown exception:
if (result.ok) {console.log(result.value)// { name: 'Alice', age: 30, role: 'admin' }} else {for (const failure of result.failures) {console.error(`[${failure.kind}] ${failure.message}`)}} -
Inspect lineage
Every run records provenance, regardless of success or failure:
import { formatLineageAsString } from '@origints/core'console.log(formatLineageAsString(result.lineage, plan.ast))
Extract from files
Section titled “Extract from files”File inputs produce byte streams. Decoding must be explicit via transforms.
import { Planner, loadFile, run, parseJson } from '@origints/core'
const plan = new Planner() .in(loadFile('data.json')) .mapIn(parseJson()) .emit((out, $) => out .add('id', $.get('id').number()) .add('name', $.get('name').string()) ) .compile()
const result = await run(plan, { readFile: (path) => fs.promises.readFile(path),})Nested paths and arrays
Section titled “Nested paths and arrays”// Nested accessconst plan = new Planner() .in(load({ user: { profile: { email: 'alice@example.com' } } })) .emit((out, $) => out .add('email', $.get('user').get('profile').get('email').string()) ) .compile()
// Array mappingconst plan2 = new Planner() .in(load({ users: [ { name: 'Alice', age: 30 }, { name: 'Bob', age: 25 }, ], })) .emit((out, $) => out .add('names', $.get('users').array(u => u.get('name').string())) ) .compile()
const result = await run(plan2)// result.value: { names: ['Alice', 'Bob'] }Multiple inputs
Section titled “Multiple inputs”A single plan can pull data from multiple sources:
const plan = new Planner() .in(loadFile('config.json')) .mapIn(parseJson()) .emit((out, $) => out.add('host', $.get('host').string())) .in(loadFile('users.json')) .mapIn(parseJson()) .emit((out, $) => out .add('users', $.get('data').array(u => u.get('name').string())) ) .compile()Schema validation
Section titled “Schema validation”Validate inputs against a Standard Schema (Zod, Valibot, etc.):
import { z } from 'zod'
const UserSchema = z.object({ name: z.string(), age: z.number().min(0),})
const plan = new Planner() .in(load({ name: 'Bob', age: 25 }).validate(UserSchema)) .emit((out, $) => out .add('name', $.get('name').string()) .add('age', $.get('age').number()) ) .compile()Next steps
Section titled “Next steps”- Two-Phase Architecture — understand the build/run separation
- Extraction System — learn the unified spec model
- Conditional Extraction — handle missing data and fallbacks
- Format Packages — explore all supported formats