Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Yare

Yare models APIs as intents: named outcomes with a declared state machine. Start one and you get a typed stream of frames, one per state transition, until it reaches a terminal state.

REST and GraphQL model the API as data. tRPC and RPC model it as procedures. Yare models it as the outcome you're trying to reach.

The name is archaic English for nimble, responsive, ready to move, historically said of ships that handle well.

This is a research project, not a product. The bet is that the combination of intent, state machine, durable execution, and exhaustive client matching is worth its own library. Don't treat any of the API decisions as settled.

Status

Four packages, exercised end-to-end by eight runnable examples:

  • @yare/core: intent, state, ref, Frame, schema-derived type helpers, runtime + type-level validation, a superjson-backed wire codec.
  • @yare/server: handler() + serve() over Bun WebSockets. Handler context: transition, sleep, waitFor, signal. Optional bun:sqlite persistence so the frame log, current state, and pending notifies all survive a process restart.
  • @yare/client: createClient(), async-iterable Flow<S> per intent, resume(schema, intentId, sinceSeq?), notify, optional autoReconnect.
  • @yare/react: <YareProvider> and useIntent(schema) returning an exhaustive match over the schema's states plus idle.

CLAUDE.md has the design rationale, what's deferred, and the scaffold's known sharp edges.

Structure

packages/
  core/      @yare/core    schema DSL, wire codec, types
  server/    @yare/server  handler runtime, transport, durability
  client/    @yare/client  framework-agnostic client, frames as async iterator
  react/     @yare/react   useIntent hook with exhaustive match
examples/
  basic/         single terminal state
  checkout/      multi-state with retries and sleep
  resume/        reattach after disconnect
  gate/          waitFor + out-of-band notify
  cancel/        flow.cancel() aborts an in-flight sleep
  reconnect/     autoReconnect keeps a flow alive across socket drops
  durable/       SQLite-backed; server2 picks up where server1 crashed
  durable-gate/  durability + waitFor; a notify survives a restart

Getting started

bun install
bun run typecheck
bun run build
bun run example:basic

Every example is one Bun process running both server and client, so the round trip fits in a single file:

  • basic: fires a one-state user.ping intent; prints its single terminal frame.
  • checkout: checkout.complete retries a flaky mock-Stripe charge twice before settling. Doubles as proof that Date round-trips through the wire codec.
  • resume: client A drops after three frames; client B reattaches via client.resume(schema, intentId, lastSeq) and consumes the rest of the log, terminal frame included.
  • gate: handler pauses on await waitFor('decision'); an out-of-band client.notify(intentId, 'decision', { ... }) resolves it. The Temporal-shaped pattern in about fifty lines.
  • cancel: flow.cancel() aborts the handler's in-flight sleep(5000) via AbortSignal. Sleep rejects in under 300ms instead of running the full five seconds.
  • reconnect: with autoReconnect: true, a long-running flow survives its underlying socket dropping. The client opens a fresh connection, replays the gap, and the caller sees a continuous frame stream.
  • durable: server1 starts an intent with db: './yare-durable.db', sees a few frames, then stops mid-execution. Server2 opens the same file, picks the intent up at its persisted state, and a new client resumes by intentId to watch it finish.
  • durable-gate: durability plus waitFor. A notify('decision', { approved: true, approver: ... }) arrives while the handler is in a pre-waitFor state; server1 crashes before the handler ever reaches the waitFor. Server2 opens the same database, hydrates the persisted notify, re-runs the handler, and the resumed waitFor consumes the pre-restart payload to transition into approved. The approval crossed the restart boundary.

License

TBD.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages