Connections (Produces & Consumes)
Connections — Produces & Consumes
Tools rarely exist in isolation. A cost estimator produces a monthly burn figure that a runway calculator needs. A scoring tool produces aggregated ratings that a summary dashboard needs. The produces/consumes system wires these tools together reactively and offline-safely.
How it works
┌───────────────────────────┐ outputs:costs Y.Map ┌──────────────────────────┐
│ cost-estimator schema │ ─────────────────────► │ runway schema │
│ │ │ │
│ produces: │ │ consumes: │
│ monthly: derived.total │ │ upstreamCost: │
│ │ │ 'cost-estimator.monthly'│
└───────────────────────────┘ └──────────────────────────┘
- The upstream tool's
useProtoOutputswrites{ monthly: 12400 }intoY.Map 'outputs:cost-estimator' - The downstream tool's
useProtoOutputsreads from that map and exposes it asconnections.upstreamCost - Downstream
derivedfunctions receivectx.connections.upstreamCost = 12400 - When both tools share a
Y.Doc, this happens instantly and works fully offline
Declaring produces
// cost-estimator schema
produces: {
monthly: 'derived.monthlyTotal', // key → dot-path in compute context
annual: 'derived.annualTotal',
}
Supported path prefixes:
'derived.keyName'— a computed derived value'fields.keyName'— a raw field value'collections.keyName'— an entire collection items array
Declaring consumes
// runway schema
consumes: {
upstreamCost: 'cost-estimator.monthly', // localAlias: 'sourceKey.producedKey'
upstreamAnnual: 'cost-estimator.annual',
}
Format: 'sourceTool.sourceKey' where:
sourceTool— thekeyof the schema that declaredproducessourceKey— the key inside that schema'sproducesmap
Consumed values appear in ctx.connections under the local alias.
Using connections in derived
// runway schema
derived: {
effectiveMonthlyCost: {
compute: ({ fields, connections }) =>
// Use upstream value when available, fall back to local field
connections.upstreamCost ?? fields.localMonthlyCost,
},
runwayMonths: {
compute: ({ fields, derived }) =>
derived.effectiveMonthlyCost > 0
? Math.floor(fields.availableFunds / derived.effectiveMonthlyCost)
: Infinity,
format: { type: 'number', decimals: 0, suffix: ' months' },
},
}
Always guard against undefined connections — the upstream tool may not have run yet or may have no data.
Same-doc vs cross-doc
Same Y.Doc (recommended)
When all connected tools share a single Y.Doc, the produces/consumes flow is instant and fully offline-capable. useProtoOutputs reads and writes Y.Map entries in the shared document.
Y.Doc "my-workspace-xyz"
├── Y.Map "fields:cost-estimator" ← cost-estimator fields
├── Y.Map "outputs:cost-estimator" ← cost-estimator produces
├── Y.Map "fields:runway" ← runway fields
└── Y.Map "outputs:runway" ← runway produces
To share a Y.Doc across tools, pass the same doc object to each usePrototype call or use a common Pinia store that manages the shared Y.Doc.
Cross-doc (legacy watcher)
When tools have separate documents, useProtoConnections observes the source document and copies values reactively. This requires both documents to be open simultaneously. For offline use, prefer the same-doc pattern.
Example connection graph
A project management toolkit might have:
time-tracker ──produces──► cost-estimator (hourly totals)
cost-estimator ──produces──► runway (monthly burn)
cost-estimator ──produces──► profitability (monthly burn)
revenue-model ──produces──► profitability (monthly revenue)
profitability ──produces──► investor-summary (margin, breakeven)
Each tool is independently useful. The connections make them greater than the sum of their parts — and the whole graph works offline.
Building a connection map
If you have many tools, use buildConnectionMap to auto-generate the graph from schema declarations:
import { buildConnectionMap } from '~/utils/connectionMap'
import { allSchemas } from '~/schemas'
const map = buildConnectionMap(allSchemas)
const upstream = getUpstreamTools('runway', map) // ['cost-estimator']
const downstream = getDownstreamTools('cost-estimator', map) // ['runway', 'profitability']
Derived & Computed
Derived values are pure functions computed reactively from field values, other derived values, upstream connections, and collection items.
Visualizations & Layouts
Built-in visualization types (progress, bar chart, comparison table, feature matrix, timeline) and custom dashboard layouts with tabs, rows, and columns.