Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 17 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,23 +53,23 @@ The published package:

The internal packages, private and bundled into `process-graph`:

| Package | What it is |
| -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`graph-dag`](packages/core/graph/dag/README.md) | Model-independent dependency-graph primitives over a node set and a `needs` accessor: layers, ancestors, descendants, cycles, transitive reduction, critical path. |
| [`graph-schema`](packages/core/graph/schema/README.md) | The process model: typed identifier spaces, `defineModel` with compile-time reference checking, structural validation. |
| [`graph-projection`](packages/core/graph/projection/README.md) | Projections of the model into a flowchart, swimlane, state machine and sequence diagram, plus derived hand-offs, and the inverses that turn an edited view into a diff against the model. |
| [`graph-domain`](packages/core/graph/domain/README.md) | Reasoning over the model and a run overlay: control graph, illegal cycles, three-valued status, ready set, blocked-by, impact, what-if and critical path. |
| [`graph-layout`](packages/core/graph/layout/README.md) | Layered layout of a projected flowchart, swimlane or state machine into positions in the model's `views` shape. |
| [`graph-source-contract`](packages/core/graph/source-contract/README.md) | The `GraphSource` port as an oRPC contract: versioned, paged and streamed sync of bound activities, participants, transitions and run state, resumable by cursor, typed filters and scope listings, with an in-memory fake and a conformance kit. |
| [`graph-source-github-issues`](packages/adapters/graph/source-github-issues/README.md) | The GitHub issues adapter for the `GraphSource` port: issues, `blockedBy` and `blocking`, sub-issues and assignees across organisations, repositories and Projects v2 boards, with server-side filters, a scope listing and per-owner tokens. |
| [`graph-store-contract`](packages/core/graph/store-contract/README.md) | The persistence port as an oRPC contract: save, load and delete models, set run state, upsert items and relations from a source, ready, blocked-chain, impact and hierarchy queries, a change feed; with an in-memory fake and a conformance kit. |
| [`graph-store-sqlite`](packages/adapters/graph/store-sqlite/README.md) | The store port on SQLite through Drizzle: one table definition, committed drizzle-kit migrations applied the same way in every runtime, recursive SQL for the structural queries, against Drizzle's async SQLite database so any driver plugs in. |
| [`graph-sqlite-node`](packages/adapters/graph/sqlite-node/README.md) | The SQLite store on Node's built-in `node:sqlite` through `drizzle-orm/node-sqlite`, for the command line and servers. |
| [`graph-sqlite-wasm`](packages/adapters/graph/sqlite-wasm/README.md) | The SQLite store in the browser: SQLite wasm in a dedicated worker on OPFS `opfs-sahpool`, shared between tabs under a Web Lock with no special headers, served to the page over oRPC. |
| [`graph-react`](packages/ui/graph/react/README.md) | Headless React hooks and unstyled components: follow a stored model, derive statuses, the ready set, blocked chains, impact and explanations, project views, filter, select and navigate by keyboard. |
| [`graph-ui`](packages/ui/graph/ui/README.md) | Styled components over `graph-react` and an SVG sequence diagram, in Vanilla Extract with a typed theme contract and light and dark themes, shipped as compiled CSS. |
| [`graph-react-flow`](packages/ui/graph/react-flow/README.md) | React Flow views of the model: flowchart, swimlane with lanes as group nodes, and state machine, laid out by `graph-layout`, showing each status and the critical path; sequence projections drawn by `graph-ui`. |
| [`graph-cli`](packages/targets/graph-cli/README.md) | The command line and its library entry: sync GitHub issues into the SQLite store, ready, blocked, impact, critical path, cycles, hand-offs and status explanations, and every view drawn in Mermaid or Graphviz DOT. |
| Package | What it is |
| -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [`graph-dag`](packages/core/graph/dag/README.md) | Model-independent dependency-graph primitives over a node set and a `needs` accessor: layers, ancestors, descendants, cycles, transitive reduction, critical path. |
| [`graph-schema`](packages/core/graph/schema/README.md) | The process model: typed identifier spaces, `defineModel` with compile-time reference checking, structural validation. |
| [`graph-projection`](packages/core/graph/projection/README.md) | Projections of the model into a flowchart, swimlane, state machine and sequence diagram, plus derived hand-offs, and the inverses that turn an edited view into a diff against the model. |
| [`graph-domain`](packages/core/graph/domain/README.md) | Reasoning over the model and a run overlay: control graph, illegal cycles, three-valued status, ready set, blocked-by, impact, what-if and critical path. |
| [`graph-layout`](packages/core/graph/layout/README.md) | Layered layout of a projected flowchart, swimlane or state machine into positions in the model's `views` shape. |
| [`graph-source-contract`](packages/core/graph/source-contract/README.md) | The `GraphSource` port as an oRPC contract: versioned, paged and streamed sync of bound activities, participants, transitions and run state, resumable by cursor, typed filters and scope listings, with an in-memory fake and a conformance kit. |
| [`graph-source-github-issues`](packages/adapters/graph/source-github-issues/README.md) | The GitHub issues adapter for the `GraphSource` port: issues, `blockedBy` and `blocking`, sub-issues and assignees across organisations, repositories and Projects v2 boards, with server-side filters, a scope listing and per-owner tokens. |
| [`graph-store-contract`](packages/core/graph/store-contract/README.md) | The persistence port as an oRPC contract: save, load and delete models, set run state and the facts a run reads (provided artefacts, condition values), upsert items and relations from a source, ready, blocked-chain, impact and hierarchy queries, a change feed; with an in-memory fake and a conformance kit. |
| [`graph-store-sqlite`](packages/adapters/graph/store-sqlite/README.md) | The store port on SQLite through Drizzle: one table definition, committed drizzle-kit migrations applied the same way in every runtime, recursive SQL for the structural queries, against Drizzle's async SQLite database so any driver plugs in. |
| [`graph-sqlite-node`](packages/adapters/graph/sqlite-node/README.md) | The SQLite store on Node's built-in `node:sqlite` through `drizzle-orm/node-sqlite`, for the command line and servers. |
| [`graph-sqlite-wasm`](packages/adapters/graph/sqlite-wasm/README.md) | The SQLite store in the browser: SQLite wasm in a dedicated worker on OPFS `opfs-sahpool`, shared between tabs under a Web Lock with no special headers, served to the page over oRPC. |
| [`graph-react`](packages/ui/graph/react/README.md) | Headless React hooks and unstyled components: follow a stored model, derive statuses, the ready set, blocked chains, impact and explanations, project views, filter, select and navigate by keyboard. |
| [`graph-ui`](packages/ui/graph/ui/README.md) | Styled components over `graph-react` and an SVG sequence diagram, in Vanilla Extract with a typed theme contract and light and dark themes, shipped as compiled CSS. |
| [`graph-react-flow`](packages/ui/graph/react-flow/README.md) | React Flow views of the model: flowchart, swimlane with lanes as group nodes, and state machine, laid out by `graph-layout`, showing each status and the critical path; sequence projections drawn by `graph-ui`. |
| [`graph-cli`](packages/targets/graph-cli/README.md) | The command line and its library entry: sync GitHub issues into the SQLite store, ready, blocked, impact, critical path, cycles, hand-offs and status explanations, and every view drawn in Mermaid or Graphviz DOT. |

The web app, private and not bundled into `process-graph`:

Expand Down
4 changes: 2 additions & 2 deletions packages/adapters/graph/store-sqlite/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const store = createRouterClient(

`src/tables.ts` is the one table definition. Every record a model declares is a row keyed by model id and record id, with a `position` column keeping the declared order; enumerated columns take their values from graph-schema's own vocabulary, and nested values are JSON text. Rows never reach the contract: `src/rows.ts` flattens a model into rows and reassembles it, parsing the result with graph-schema's `modelSchema`, so what leaves the store is checked to be a model. A unit test derives the row schemas with `drizzle-orm/zod` and asserts they agree with the model schema on every shared scalar field.

Relations kept beside a model (`child-of`, `assigned-to`, `part-of`) are rows of their own, keyed by model, kind and both ends so a relation sent twice is stored once, with a position keeping the order they were first stored. Each transition row records whether graph-domain's `loopTransitions` counts it as a decision's loop edge, so the structural queries can leave loop edges out without loading the model. No foreign keys are declared, because SQLite enforces them only on connections that enable them; the store writes and deletes a model's rows together in one transaction instead.
Relations kept beside a model (`child-of`, `assigned-to`, `part-of`) are rows of their own, keyed by model, kind and both ends so a relation sent twice is stored once, with a position keeping the order they were first stored. A model's fact record is two tables beside the overlay: `artefact_facts`, one row per artefact whose provision is known with a boolean `provided`, and `named_facts`, one row per named fact with its trilean value as JSON text, parsed with the contract's `factRecordSchema` on every read. An artefact or name with no row is unknown. Each transition row records whether graph-domain's `loopTransitions` counts it as a decision's loop edge, so the structural queries can leave loop edges out without loading the model. No foreign keys are declared, because SQLite enforces them only on connections that enable them; the store writes and deletes a model's rows together in one transaction instead.

## Migrations

Expand All @@ -30,7 +30,7 @@ The build embeds them in the package (`scripts/embed-migrations.ts`, parsed by d

## Writes and queries

Every write runs `checkStored` from the contract before it commits, takes the next value of the store-wide revision sequence, rewrites the model's rows in one transaction and publishes the change to the store's `ChangeFeed` once it has committed. A failed check or an aborted signal rolls the transaction back.
Every write runs `checkStored` (and `factIssues` for the facts it keeps) from the contract before it commits, takes the next value of the store-wide revision sequence, rewrites the model's rows in one transaction and publishes the change to the store's `ChangeFeed` once it has committed. A failed check or an aborted signal rolls the transaction back.

`query.ready`, `query.blockedChain` and `query.impact` are single `WITH RECURSIVE` queries through Drizzle's `sql` template over `transitions`, `elements` and `overlay`, with the contract's semantics (control elements passed through, loop edges left out, traversal stopping at done work). `query.descendants` and `query.ancestors` are the same kind of query over the `child-of` rows of `relations`, and `query.children` a plain one. The walks cap distances at the model's element count, which is longer than any shortest path and ends the recursion on a cycle no decision closes, or a cycle of `child-of` relations.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CREATE TABLE `artefact_facts` (
`model_id` text NOT NULL,
`artefact` text NOT NULL,
`provided` integer NOT NULL,
CONSTRAINT `artefact_facts_pk` PRIMARY KEY(`model_id`, `artefact`)
);
--> statement-breakpoint
CREATE TABLE `named_facts` (
`model_id` text NOT NULL,
`name` text NOT NULL,
`value` text NOT NULL,
CONSTRAINT `named_facts_pk` PRIMARY KEY(`model_id`, `name`)
);
Loading