ArcFlow
Company
Managed Services
Markets
  • News
  • LOG IN
  • GET STARTED

OZ brings Visual Intelligence to physical venues, a managed edge layer that lets real-world environments see, understand, and act in real time.

Talk to us

ArcFlow

  • World Models
  • Sensors

Managed Services

  • OZ VI Venue 1
  • Case Studies

Markets

  • Sports
  • Broadcasting
  • Robotics

Company

  • About
  • Technology
  • Careers
  • Contact

Ready to see it live?

Talk to the OZ team about deploying at your venues, from a single pilot match to a full regional rollout.

Schedule a deployment review

© 2026 OZ. All rights reserved.

LinkedIn
ArcFlow Docs
Get Started
  • Get Started
  • Quickstart
  • Installation
  • Project Setup
  • Platforms
  • Bindings
  • Licensing
  • Pricing
Capabilities
  • Vector Search
  • Graph Algorithms
  • Sync
  • MCP Server (AI Agents)
  • Live Queries
  • Programs
  • Temporal
  • Spatial
  • Trusted RAG
  • Behavior Graph
  • Agent-Native
  • Event Sourcing
  • GPU Acceleration
  • Intent Relay
Concepts
  • World Model
  • Graph Model
  • Query Language (GQL)
  • Graph Patterns
  • SQL vs GQL
  • Parameters
  • Query Results
  • Persistence & WAL
  • Error Handling
  • Observations & Evidence
  • Confidence & Provenance
  • Proof Artifacts & Gates
  • Skills
GQL / WorldCypher
  • Overview
  • MATCH
  • WHERE
  • RETURN
  • OPTIONAL MATCH
  • CREATE
  • SET
  • MERGE
  • DELETE
  • REMOVE
  • WITH
  • UNION
  • UNWIND
  • CASE
  • Spatial Queries
  • Temporal Queries
  • Algorithms Reference
  • Triggers
Schema
  • Overview
  • Indexes
  • Constraints
  • Data Types
Functions
  • Built-in Functions
  • Aggregations
  • Procedures
  • Shortest Path
  • EXPLAIN
  • PROFILE
Skills
  • Overview
  • CREATE SKILL
  • PROCESS NODE
  • REPROCESS EDGES
Operations
  • CLI
  • REPL Commands
  • Snapshot & Restore
  • Server Modes & PG Wire
  • Persistence
  • Import & Export
  • Docker
  • Architecture
  • Cloud Architecture
  • Sync Protocol (Deep Dive)
Guides
  • Agent Integration
  • World Model
  • Graph Model Fundamentals
  • Trusted RAG
  • Using Skills
  • Behavior Graphs
  • Swarm & Multi-Agent
  • Migration Guide
  • Filesystem Workspace
  • From SQL to GQL
  • ArcFlow for Coding Agents
  • Data Quality & Pipeline Integrity
  • Code Intelligence
Tutorials
  • Knowledge Graph
  • Entity Linking
  • Vector Search
  • Graph Algorithms
Recipes
  • CRUD
  • Multi-MATCH
  • MERGE (Upsert)
  • Full-Text Search
  • Temporal Queries
  • Batch Projection
  • GraphRAG
Use Cases
  • Agent Tooling
  • Knowledge Management
  • RAG Pipeline
  • Fraud Detection
  • Sports Analytics
  • Grounded Neural Objects
  • Behavior Graphs
  • Autonomous Systems
  • Digital Twins
  • Robotics & Perception
Reference
  • TypeScript API
  • GQL Conformance
  • Compatibility Matrix
  • Glossary
  • Data Types
  • Operators
  • Error Codes
  • Known Issues

Add ArcFlow to a Project

ArcFlow is infrastructure, not software — a spatial-temporal world model that runs in your process, no servers, no configuration. Every code block below is copy-pasteable and runnable.

Step 1: Install#

npm install arcflow

No other dependencies. No server to start. No Docker. No configuration files.

Step 2: Create a database#

import { openInMemory } from 'arcflow'
 
// In-memory (for development, testing, prototyping)
const db = openInMemory()
 
// Or persistent (for production — data survives restarts)
// import { open } from 'arcflow'
// const db = open('./data/world-model')

Step 3: Write data#

// Create a world model entity with epistemic state
db.mutate(`
  CREATE (e:Entity {
    id: 'unit-01',
    x: 12.4, y: 8.7, z: 0.0,
    _observation_class: 'observed',
    _confidence: 0.94
  })
`)
 
// Create with parameters (always use this for dynamic values)
db.mutate(
  "CREATE (e:Entity {id: $id, x: $x, y: $y, _observation_class: $cls, _confidence: $conf})",
  { id: 'contact-x', x: 80.0, y: 90.0, cls: 'predicted', conf: 0.38 }
)
 
// Create a relationship with provenance
db.mutate(`
  MATCH (a:Entity {id: 'unit-01'})
  MATCH (b:Entity {id: 'contact-x'})
  MERGE (a)-[:DETECTS {sensor: 'lidar-1', _confidence: 0.91}]->(b)
`)
 
// Batch create (faster for bulk operations)
db.batchMutate([
  "MERGE (e:Entity {id: 'sensor-1', x: 0.0, y: 0.0})",
  "MERGE (e:Entity {id: 'sensor-2', x: 50.0, y: 0.0})",
  "MERGE (z:Zone {id: 'zone-alpha', name: 'Perimeter'})",
])

Step 4: Read data#

// Query returns typed results — numbers are numbers, not strings
const result = db.query(`
  MATCH (e:Entity)
  WHERE e._observation_class = 'observed' AND e._confidence > 0.8
  RETURN e.id, e.x, e.y, e._confidence
  ORDER BY e._confidence DESC
`)
 
// Access by column name
for (const row of result.rows) {
  const id: string = row.get('e.id') as string
  const conf: number = row.get('e._confidence') as number  // 0.94 (number, not "0.94")
}
 
// Access as objects
const entities = result.rows.map(row => row.toObject())
 
// Result metadata
result.columns    // ['e.id', 'e.x', 'e.y', 'e._confidence']
result.rowCount   // number of rows returned
result.computeMs  // 0.3 (milliseconds)

Step 5: Query with parameters#

// Always use parameters for dynamic values — prevents injection
const result = db.query(
  "MATCH (e:Entity {id: $id}) RETURN e.x, e.y, e._confidence",
  { id: 'unit-01' }
)
// result.rows[0].get('e._confidence') → 0.94
 
// Parameters work with all types
db.query(
  "MATCH (e:Entity) WHERE e._confidence > $threshold RETURN e.id",
  { threshold: 0.85 }
)
db.query(
  "MATCH (e:Entity {_observation_class: $cls}) RETURN e.id",
  { cls: 'observed' }
)

Step 6: Update and delete#

// Update position (entity moved)
db.mutate(
  "MATCH (e:Entity {id: $id}) SET e.x = $x, e.y = $y",
  { id: 'unit-01', x: 14.2, y: 9.1 }
)
 
// Upsert (create if not exists, update if exists)
db.mutate(
  "MERGE (e:Entity {id: $id}) SET e._confidence = $conf",
  { id: 'unit-01', conf: 0.97 }
)
 
// Delete a node
db.mutate("MATCH (e:Entity {id: 'contact-x'}) DELETE e")
 
// Delete a node and all its relationships
db.mutate("MATCH (e:Entity {id: 'contact-x'}) DETACH DELETE e")
 
// Remove a property
db.mutate("MATCH (e:Entity {id: 'unit-01'}) REMOVE e.stale_field")

Step 7: Run algorithms#

// No setup, no projection, no catalog — just call it
const pr = db.query("CALL algo.pageRank()")
for (const row of pr.rows) {
  console.log(row.get('name'), row.get('rank'))
}
 
// Community detection
db.query("CALL algo.louvain()")
 
// Centrality
db.query("CALL algo.betweenness()")
 
// Graph stats
db.query("CALL db.stats()")

Step 8: Vector search#

// Create index
db.mutate("CREATE VECTOR INDEX docs FOR (n:Doc) ON (n.embedding) OPTIONS {dimensions: 1536, similarity: 'cosine'}")
 
// Add data with embeddings
db.mutate("CREATE (d:Doc {title: 'AI Intro', embedding: '[0.1, 0.2, 0.3, ...]'})")
 
// Search by similarity
const results = db.query(
  "CALL algo.vectorSearch('docs', $vec, 10)",
  { vec: JSON.stringify([0.1, 0.2, 0.3]) }
)

Step 9: Handle errors#

import { ArcflowError } from 'arcflow'
 
try {
  db.query("INVALID SYNTAX")
} catch (e) {
  if (e instanceof ArcflowError) {
    e.code        // "EXPECTED_KEYWORD" — machine-readable
    e.category    // "parse" | "validation" | "execution" | "integration"
    e.message     // "Expected MATCH or CREATE, got ..."
    e.suggestion  // "Expected MATCH or CREATE" — fix hint
  }
}

Error codes you'll encounter:

CodeCategoryMeaningFix
EXPECTED_KEYWORDparseQuery syntax wrongCheck MATCH/CREATE/MERGE spelling
UNKNOWN_FUNCTIONvalidationFunction doesn't existRun CALL db.help() to see available
UNKNOWN_PROCEDUREvalidationProcedure doesn't existRun CALL db.procedures
WORKFLOW_NOT_FOUNDvalidationWorkflow name not foundRun CALL arcflow.workflow.list
EXECUTION_CONTEXT_MISMATCHintegrationContext guard failedRun CALL db.setExecutionContext(...) first
DB_CLOSEDintegrationCalled after db.close()Don't use db after closing

Step 10: Close#

db.close()
// After this, all operations throw ArcflowError with code 'DB_CLOSED'

Complete example#

import { openInMemory, ArcflowError } from 'arcflow'
 
const db = openInMemory()
 
try {
  // Build a world model
  db.batchMutate([
    "MERGE (e:Entity {id: 'unit-01', x: 12.4, y: 8.7, _observation_class: 'observed', _confidence: 0.94})",
    "MERGE (e:Entity {id: 'unit-02', x: 45.0, y: 22.3, _observation_class: 'observed', _confidence: 0.88})",
    "MERGE (e:Entity {id: 'contact-x', x: 80.0, y: 90.0, _observation_class: 'predicted', _confidence: 0.38})",
    "MERGE (z:Zone {id: 'zone-alpha', name: 'Perimeter'})",
  ])
  db.mutate(`
    MATCH (a:Entity {id: 'unit-01'}) MATCH (b:Entity {id: 'contact-x'})
    MERGE (a)-[:DETECTS {sensor: 'lidar-1', _confidence: 0.91}]->(b)
  `)
 
  // Query high-confidence observed entities
  const trusted = db.query(`
    MATCH (e:Entity)
    WHERE e._observation_class = 'observed' AND e._confidence > 0.85
    RETURN e.id, e.x, e.y, e._confidence
    ORDER BY e._confidence DESC
  `)
  console.log(`${trusted.rowCount} trusted entities in world model`)
 
  // Temporal: what did the world model show 5 seconds ago?
  const past = db.query(
    "MATCH (e:Entity) AS OF seq $seq RETURN e.id, e._confidence",
    { seq: 10 }
  )
 
  // Centrality: which entities are most connected?
  const pr = db.query("CALL algo.pageRank()")
 
  const stats = db.stats()
  console.log(`${stats.nodes} nodes, ${stats.relationships} relationships`)
 
} catch (e) {
  if (e instanceof ArcflowError) {
    console.error(`${e.code}: ${e.message}`)
  }
} finally {
  db.close()
}

Testing pattern#

import { describe, it, expect } from 'vitest'  // or jest, node:test
import { openInMemory } from 'arcflow'
 
describe('my feature', () => {
  it('does something with a graph', () => {
    const db = openInMemory()  // fresh graph per test
 
    db.mutate("CREATE (n:Item {name: 'test', value: 42})")
    const result = db.query("MATCH (n:Item) RETURN n.value")
    expect(result.rows[0].get('value')).toBe(42)
 
    db.close()  // cleanup is optional — GC handles it
  })
})

Express/Fastify pattern#

import { open } from 'arcflow'
import express from 'express'
 
const db = open('./data/graph')
const app = express()
 
app.get('/api/people', (req, res) => {
  const result = db.query("MATCH (n:Person) RETURN n.name, n.age")
  res.json(result.rows.map(r => r.toObject()))
})
 
app.post('/api/people', express.json(), (req, res) => {
  const { name, age } = req.body
  db.mutate("CREATE (n:Person {name: $name, age: $age})", { name, age })
  res.json({ ok: true })
})
 
process.on('SIGTERM', () => { db.close(); process.exit(0) })
 
app.listen(3000)

What to remember#

  1. openInMemory() for dev/test, open(path) for production
  2. Always use $params for user input — prevents injection
  3. row.get('column') returns typed values — numbers, booleans, null, not strings
  4. Algorithms: just CALL algo.pageRank() — no setup
  5. Errors are structured: e.code, e.category, e.suggestion
  6. No server needed. No Docker. No connection strings.

See Also#

  • Agent-Native Database — filesystem workspace, CLI binary, watch mode, batch execution
  • ArcFlow for Coding Agents — CLI patterns, structured errors, and checkpointing
  • Swarm & Multi-Agent — coordinating multiple agents on a shared world model
  • TypeScript API Reference — full method signatures and types
Try it
Open ↗⌘↵ to run
Loading engine…
← PreviousSync Protocol (Deep Dive)Next →World Model