process-graph 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -19
- package/dist/bin.js +4 -3
- package/dist/cli.d.ts +42 -10
- package/dist/cli.js +3 -2
- package/dist/data-file-BVMxkTug.js +95 -0
- package/dist/dist-81kTKnMq.js +3 -0
- package/dist/{dist-BxHnxpcT.js → dist-BI01yxFA.js} +82 -84
- package/dist/{dist-BpCBmnMl.js → dist-arkejVz2.js} +2 -112
- package/dist/{graphql-C1j5wQFz.d.ts → graphql-BE7xm5dB.d.ts} +3 -2
- package/dist/{index-BUheRLdG.d.ts → index-9Au8pAmP.d.ts} +4 -4
- package/dist/{index-CrM5qWUA.d.ts → index-BC4tmAuQ.d.ts} +2 -2
- package/dist/{index-DxWOY8f9.d.ts → index-CR8xUK3S.d.ts} +5 -572
- package/dist/{index-CoA6vXqe.d.ts → index-D06bcdfw.d.ts} +1 -1
- package/dist/{index-BH1aFqkJ.d.ts → index-D4CnOhNf.d.ts} +1 -1
- package/dist/{index-CmZOswkx.d.ts → index-Dvz_I_uQ.d.ts} +17 -8
- package/dist/{index-CptUHq6F.d.ts → index-hri2a13-.d.ts} +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -2
- package/dist/layout.d.ts +1 -1
- package/dist/{parse-CuipC_2K.js → parse-C1Q1zsGt.js} +1 -1
- package/dist/react-flow.d.ts +5 -5
- package/dist/react-flow.js +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/{router-DvGGLnNt.js → router-Dk91O_9p.js} +2 -2
- package/dist/{schema-CVnS6HiX.js → schema-BPT8fmfa.js} +2 -2
- package/dist/source/github/node.d.ts +1 -1
- package/dist/source/github.d.ts +2 -2
- package/dist/source/github.js +1 -1
- package/dist/{source-DRDpEA8Q.js → source-D51N7K3A.js} +23 -3
- package/dist/store/node.d.ts +27 -2
- package/dist/store/node.js +2 -2
- package/dist/store/wasm/worker.js +2 -2
- package/dist/store/wasm.d.ts +1 -1
- package/dist/{store-BJILV4JS.js → store-DKzvLGgl.js} +1 -1
- package/dist/store.d.ts +1 -1
- package/dist/store.js +2 -2
- package/dist/theme-values-BJJhAkUn-ORyRUrPf.js +114 -0
- package/dist/theme-values-BybZ-cle.d.ts +116 -0
- package/dist/ui/theme.d.ts +2 -0
- package/dist/ui/theme.js +2 -0
- package/dist/ui.d.ts +6 -120
- package/dist/ui.js +2 -1
- package/dist/version-Dagrkvwt.js +5 -0
- package/package.json +28 -23
- package/dist/dist-Cw63tKU9.js +0 -3
- package/dist/open-BF-UHqeW.js +0 -29
package/README.md
CHANGED
|
@@ -40,24 +40,26 @@ deriveStatuses(model, { submit: "done" }, facts); // Map { "submit" => "done", "
|
|
|
40
40
|
|
|
41
41
|
The package is built from the repository's internal packages, which are bundled into it and not published on their own; each internal package's README documents its functions and rules. Each subpath loads only the code it reaches.
|
|
42
42
|
|
|
43
|
-
| Import | What it is
|
|
44
|
-
| ------------------------------------ |
|
|
45
|
-
| `process-graph` | The model (`defineModel`, `parseModel`, `validate`), its projections and inverses, and the reasoning over a run (statuses, ready set, blocked-by, impact, what-if, critical path).
|
|
46
|
-
| `process-graph/layout` | `layout`: positions for a projected flowchart, swimlane or state machine, in the model's `views` shape, through elkjs.
|
|
47
|
-
| `process-graph/source/github` | The `GraphSource` port (contract, schemas, router, pagination and an in-memory fake) and the GitHub issues adapter, `createGitHubIssuesSource`.
|
|
48
|
-
| `process-graph/source/github/node` | `githubTokenFromEnvironment`: a token port reading `GITHUB_TOKEN` or the GitHub CLI's token.
|
|
49
|
-
| `process-graph/store` | The `GraphStore` port (contract, schemas, router, change feed, structural queries and an in-memory fake) and the SQLite store over any Drizzle SQLite database.
|
|
50
|
-
| `process-graph/store/node` | `openNodeGraphStore`: the SQLite store on Node's built-in `node:sqlite
|
|
51
|
-
| `process-graph/store/wasm` | `connectGraphStore`: connects a page to the store a dedicated worker serves.
|
|
52
|
-
| `process-graph/store/wasm/worker` | `serveGraphStoreInWorker`: serves the store from a dedicated worker on SQLite wasm and OPFS, shared between tabs with no special headers.
|
|
53
|
-
| `process-graph/react` | Headless React hooks and unstyled components: follow a stored model, derive its run, project, filter and select.
|
|
54
|
-
| `process-graph/ui` | Styled components over `process-graph/react`, the SVG sequence diagram and the theme contract with light and dark themes.
|
|
55
|
-
| `process-graph/ui/
|
|
56
|
-
| `process-graph/
|
|
57
|
-
| `process-graph/react-flow
|
|
58
|
-
| `process-graph/
|
|
59
|
-
|
|
60
|
-
|
|
43
|
+
| Import | What it is | Runs in |
|
|
44
|
+
| ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
|
|
45
|
+
| `process-graph` | The model (`defineModel`, `parseModel`, `validate`), its projections and inverses, and the reasoning over a run (statuses, ready set, blocked-by, impact, what-if, critical path). | Browser, Worker, Node |
|
|
46
|
+
| `process-graph/layout` | `layout`: positions for a projected flowchart, swimlane or state machine, in the model's `views` shape, through elkjs. | Browser, Worker, Node |
|
|
47
|
+
| `process-graph/source/github` | The `GraphSource` port (contract, schemas, router, pagination and an in-memory fake) and the GitHub issues adapter, `createGitHubIssuesSource`. | Browser, Worker, Node |
|
|
48
|
+
| `process-graph/source/github/node` | `githubTokenFromEnvironment`: a token port reading `GITHUB_TOKEN` or the GitHub CLI's token. | Node |
|
|
49
|
+
| `process-graph/store` | The `GraphStore` port (contract, schemas, router, change feed, structural queries and an in-memory fake) and the SQLite store over any Drizzle SQLite database. | Browser, Worker, Node |
|
|
50
|
+
| `process-graph/store/node` | `openNodeGraphStore`: the SQLite store on Node's built-in `node:sqlite`; `prepareDataFile`: makes its data file and directory private before it opens. | Node |
|
|
51
|
+
| `process-graph/store/wasm` | `connectGraphStore`: connects a page to the store a dedicated worker serves. | Browser |
|
|
52
|
+
| `process-graph/store/wasm/worker` | `serveGraphStoreInWorker`: serves the store from a dedicated worker on SQLite wasm and OPFS, shared between tabs with no special headers. | Dedicated worker |
|
|
53
|
+
| `process-graph/react` | Headless React hooks and unstyled components: follow a stored model, derive its run, project, filter and select. | Browser |
|
|
54
|
+
| `process-graph/ui` | Styled components over `process-graph/react`, the SVG sequence diagram and the theme contract with light and dark themes. | Browser |
|
|
55
|
+
| `process-graph/ui/theme` | The theme contract `vars`, `lightTheme`, `darkTheme`, `lightValues` and `darkValues` without the components, for a Vanilla Extract stylesheet that themes `process-graph/ui` without loading React. | Any |
|
|
56
|
+
| `process-graph/ui/style.css` | The compiled styles for `process-graph/ui`. | Browser |
|
|
57
|
+
| `process-graph/react-flow` | React Flow views of a flowchart, swimlane or state machine, laid out by `process-graph/layout`. | Browser |
|
|
58
|
+
| `process-graph/react-flow/style.css` | The compiled styles for `process-graph/react-flow`, React Flow's own included. | Browser |
|
|
59
|
+
| `process-graph/cli` | The command line as a library: `runCli` over injected ports, `nodePorts` for a Node process, each command's operation returning plain data, and `version`, this package's own. | Node |
|
|
60
|
+
| `process-graph/package.json` | The package's manifest, for reading its version or anything else it declares. | Any |
|
|
61
|
+
|
|
62
|
+
`zod` and `trilean`, which the root entry needs, are dependencies; a project with an install age gate exempts `trilean` and `trilean-regex` beside `process-graph` (see [Install](../../../README.md#install)). The libraries only other subpaths need are optional peer dependencies, so installing `process-graph` for its root entry pulls in nothing else; install the peers of each subpath you import beside it:
|
|
61
63
|
|
|
62
64
|
| Subpath | Peer dependencies |
|
|
63
65
|
| ------------------- | ---------------------------------------------------------------------------- |
|
|
@@ -69,10 +71,11 @@ The package is built from the repository's internal packages, which are bundled
|
|
|
69
71
|
| `store/wasm/worker` | `@orpc/contract`, `@orpc/server`, `drizzle-orm`, `@sqlite.org/sqlite-wasm` |
|
|
70
72
|
| `react` | `react` |
|
|
71
73
|
| `ui` | `react`, `@vanilla-extract/recipes`, `@vanilla-extract/css` (types) |
|
|
74
|
+
| `ui/theme` | `@vanilla-extract/css` (types) |
|
|
72
75
|
| `react-flow` | `react`, `react-dom`, `@xyflow/react`, `elkjs`, `@vanilla-extract/recipes` |
|
|
73
76
|
| `cli` and the bin | `commander`, `@orpc/client`, `@orpc/contract`, `@orpc/server`, `drizzle-orm` |
|
|
74
77
|
|
|
75
|
-
The versions are the ones `package.json` declares under `peerDependencies`.
|
|
78
|
+
The versions are the ones `package.json` declares under `peerDependencies`. A peer with a stable version is a caret range whose floor is the version this package is tested against, so any later compatible release satisfies it. The oRPC packages, `drizzle-orm` and `@sqlite.org/sqlite-wasm` are prereleases, which have no compatible-range semantics (a range on one admits only later prereleases of the same version, which may break anything), so each is declared at the exact version tested.
|
|
76
79
|
|
|
77
80
|
With Vite, exclude `@sqlite.org/sqlite-wasm` from dependency pre-bundling (`optimizeDeps.exclude`), since it loads its `.wasm` file relative to itself. A worker module serving the browser store is one call:
|
|
78
81
|
|
package/dist/bin.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { t as exitCodes } from "./exit-codes-0ultCqdS.js";
|
|
3
|
+
import { t as version } from "./version-Dagrkvwt.js";
|
|
3
4
|
import { readFileSync } from "node:fs";
|
|
4
5
|
//#region src/missing-peers.ts
|
|
5
6
|
/**
|
|
@@ -66,7 +67,7 @@ const manifest = new URL("../package.json", import.meta.url);
|
|
|
66
67
|
const declaredPeers = () => {
|
|
67
68
|
const parsed = JSON.parse(readFileSync(manifest, "utf8"));
|
|
68
69
|
if (typeof parsed !== "object" || parsed === null || !("peerDependencies" in parsed) || typeof parsed.peerDependencies !== "object" || parsed.peerDependencies === null) throw new Error(`${manifest.pathname} declares no peerDependencies`);
|
|
69
|
-
return new Map(Object.entries(parsed.peerDependencies).flatMap(([name,
|
|
70
|
+
return new Map(Object.entries(parsed.peerDependencies).flatMap(([name, specifier]) => typeof specifier === "string" ? [[name, specifier]] : []));
|
|
70
71
|
};
|
|
71
72
|
/** Whether a package resolves from this bin's own location, as the command line's imports would. Only a package that is not installed counts as missing; any other resolution error is the import's to report. */
|
|
72
73
|
const resolves = (name) => {
|
|
@@ -83,10 +84,10 @@ if (missing.length > 0) {
|
|
|
83
84
|
process.stderr.write(missingPeersMessage(missing, declaredPeers(), process.env.npm_config_user_agent));
|
|
84
85
|
process.exitCode = exitCodes.missingPeers;
|
|
85
86
|
} else {
|
|
86
|
-
const {
|
|
87
|
+
const { runProcess } = await import("./dist-81kTKnMq.js");
|
|
87
88
|
process.exitCode = await runProcess({
|
|
88
89
|
name: "process-graph",
|
|
89
|
-
version
|
|
90
|
+
version
|
|
90
91
|
});
|
|
91
92
|
}
|
|
92
93
|
//#endregion
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { A as Facts, B as Status, _ as StatusRule, k as FactRecord, m as IncomingBasis, p as ArtefactBasis } from "./index-
|
|
2
|
-
import {
|
|
3
|
-
import { C as Gap, n as GraphqlFetch, t as GitHubTokenPort, v as GraphSourceClient } from "./graphql-
|
|
4
|
-
import { ut as GraphStoreClient } from "./index-
|
|
5
|
-
import "./index-
|
|
6
|
-
import { A as Flowchart, E as Swimlane, M as Handoff, g as SequenceDiagram, x as StateMachine } from "./index-
|
|
1
|
+
import { A as Facts, B as Status, _ as StatusRule, k as FactRecord, m as IncomingBasis, p as ArtefactBasis } from "./index-D4CnOhNf.js";
|
|
2
|
+
import { A as Transition, C as EventDef, D as Participant, I as OverlayStatus, K as IdSpace, S as Element, _ as Model, o as Overlay, q as OpenIds, x as ArtefactDef } from "./index-Dvz_I_uQ.js";
|
|
3
|
+
import { C as Gap, n as GraphqlFetch, t as GitHubTokenPort, v as GraphSourceClient } from "./graphql-BE7xm5dB.js";
|
|
4
|
+
import { ut as GraphStoreClient } from "./index-CR8xUK3S.js";
|
|
5
|
+
import "./index-hri2a13-.js";
|
|
6
|
+
import { A as Flowchart, E as Swimlane, M as Handoff, g as SequenceDiagram, x as StateMachine } from "./index-D06bcdfw.js";
|
|
7
7
|
import { ComputedValue } from "trilean";
|
|
8
8
|
//#region ../graph-cli/dist/exit-codes.d.ts
|
|
9
9
|
/**
|
|
@@ -118,6 +118,10 @@ interface NodePortsOptions {
|
|
|
118
118
|
readonly env?: Readonly<Record<string, string | undefined>>;
|
|
119
119
|
/** The home directory the default data path falls back on; the user's when absent. */
|
|
120
120
|
readonly home?: string;
|
|
121
|
+
/**
|
|
122
|
+
* A data file the host owns, such as one under its own home directory. It becomes the default data path in place of `PROCESS_GRAPH_DATA` and the XDG data file, and it gets the treatment the command line gives its own XDG data file: its directory, and any missing directories above it, are created readable by the owner only and kept that way, the database is created owner-only before SQLite opens it, and an existing store others can read is narrowed, with a warning on standard error (see `prepareDataFile` in `process-graph/store/node`). A path given with `--data` still wins, and is treated as the user's. The XDG data file when absent.
|
|
123
|
+
*/
|
|
124
|
+
readonly dataPath?: string;
|
|
121
125
|
/** Supplies GitHub tokens; `GITHUB_TOKEN` or the GitHub CLI's token (`githubTokenFromEnvironment`) when absent. */
|
|
122
126
|
readonly token?: GitHubTokenPort;
|
|
123
127
|
/** How requests reach GitHub; the global `fetch` when absent. */
|
|
@@ -150,7 +154,7 @@ export declare const defaultDataPath: (env: Readonly<Record<string, string | und
|
|
|
150
154
|
*/
|
|
151
155
|
export declare const packageVersion: (manifest: URL) => string;
|
|
152
156
|
/**
|
|
153
|
-
* The ports for a Node process: the SQLite store over `node:sqlite` (creating the data file's directory when needed), the GitHub issues source for `github:` scopes, the file system and the process's streams.
|
|
157
|
+
* The ports for a Node process: the SQLite store over `node:sqlite` (creating the data file's directory when needed, private when the command line or the host owns it), the GitHub issues source for `github:` scopes, the file system and the process's streams.
|
|
154
158
|
* @param options - Replacements for any of the defaults.
|
|
155
159
|
* @returns The ports.
|
|
156
160
|
*/
|
|
@@ -485,6 +489,30 @@ interface SyncRequest {
|
|
|
485
489
|
/** A cursor from an interrupted sync: the first source's sync continues after it. */
|
|
486
490
|
readonly after?: string;
|
|
487
491
|
}
|
|
492
|
+
/** Where a sync a source interrupted carries on, as data a host acts on; the command line renders it as the commands to run. */
|
|
493
|
+
interface SyncInterruption {
|
|
494
|
+
/** The request that continues the failing source: its scopes, after the cursor of the last page read from it, or from the start when none was read. */
|
|
495
|
+
readonly resume: SyncRequest;
|
|
496
|
+
/** The scopes of the sources after the failing one, which were not read; sync them afresh once `resume` has finished. */
|
|
497
|
+
readonly remaining: readonly string[];
|
|
498
|
+
/** Whether pages read before the failure were written to the model. */
|
|
499
|
+
readonly saved: boolean;
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Thrown by `sync` when a source fails part way. Its exit status and message are the source's failure, classified as `failureOf` classifies it; its cause is the error underneath that failure, such as the token port's own error; and what to run next is data, in `resume` and `remaining`, never text.
|
|
503
|
+
*/
|
|
504
|
+
export declare class SyncInterruptedError extends CliError implements SyncInterruption {
|
|
505
|
+
readonly resume: SyncRequest;
|
|
506
|
+
readonly remaining: readonly string[];
|
|
507
|
+
readonly saved: boolean;
|
|
508
|
+
/**
|
|
509
|
+
* @param exitCode - The exit status the source's failure maps to.
|
|
510
|
+
* @param message - The source's failure.
|
|
511
|
+
* @param interruption - Where the sync carries on.
|
|
512
|
+
* @param options - The underlying error, kept as the cause.
|
|
513
|
+
*/
|
|
514
|
+
constructor(exitCode: CliError["exitCode"], message: string, interruption: SyncInterruption, options?: ErrorOptions);
|
|
515
|
+
}
|
|
488
516
|
/** What a sync wrote. */
|
|
489
517
|
interface SyncResult {
|
|
490
518
|
readonly modelId: string;
|
|
@@ -500,12 +528,12 @@ interface SyncResult {
|
|
|
500
528
|
/**
|
|
501
529
|
* Reads every page of the scopes from their sources and merges them into the session's model in one write, creating the model when the store has none. Records already in the model are replaced by identifier and the rest are kept, so syncing again refreshes what changed.
|
|
502
530
|
*
|
|
503
|
-
* When a source fails part way, the pages read before the failure are still written, and the error
|
|
531
|
+
* When a source fails part way, the pages read before the failure are still written, and the error carries where to carry on: the request that resumes the failing source after the cursor of its last page read, and the scopes of the sources not reached.
|
|
504
532
|
* @param session - The store and model.
|
|
505
533
|
* @param sources - The source for each identifier prefix.
|
|
506
534
|
* @param request - The scopes, and a cursor to resume after.
|
|
507
535
|
* @returns What was written, and the gaps the sources reported.
|
|
508
|
-
* @throws CliError with `usage` for a scope with no source prefix, a prefix no source serves, or `after` with scopes of more than one source; and with the source's failure
|
|
536
|
+
* @throws CliError with `usage` for a scope with no source prefix, a prefix no source serves, or `after` with scopes of more than one source; and SyncInterruptedError, with the source's failure and where to carry on, when a source fails part way.
|
|
509
537
|
*/
|
|
510
538
|
export declare const sync: (session: GraphSession, sources: SourceLookup, request: SyncRequest) => Promise<SyncResult>;
|
|
511
539
|
//#endregion
|
|
@@ -563,4 +591,8 @@ export declare const stateMachineToDot: <I extends IdSpace>(view: StateMachine<I
|
|
|
563
591
|
*/
|
|
564
592
|
export declare const sequenceToDot: <I extends IdSpace>(view: SequenceDiagram<I>, participantLabel: (participant: I["actor"]) => string) => string;
|
|
565
593
|
//#endregion
|
|
566
|
-
|
|
594
|
+
//#region src/version.d.ts
|
|
595
|
+
/** The version of the installed `process-graph` package, as its manifest names it. The bundler writes it in when the package is built, so reading it touches no file. */
|
|
596
|
+
export declare const version: string;
|
|
597
|
+
//#endregion
|
|
598
|
+
export type { Addition, ArtefactState, BlockedResult, CliPorts, CyclesResult, ElementStatus, ElementSummary, ExitCode, FactsResult, Failure, FormatName, GraphSession, HandoffsResult, ImpactResult, NodePortsOptions, OpenedStore, PathResult, ProgramIdentity, ProjectedView, ReadyResult, SetArtefactResult, SetFactResult, SetResult, ShowRequest, ShowResult, SourceLookup, StoredRun, SyncInterruption, SyncRequest, SyncResult, ValidateResult, ValidationIssue, ViewName, WhyLink, WhyResult, Written };
|
package/dist/cli.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import { t as exitCodes } from "./exit-codes-0ultCqdS.js";
|
|
2
|
-
import { A as
|
|
3
|
-
|
|
2
|
+
import { A as why, B as CliError, C as swimlaneToMermaid, D as impactOf, E as handoffsOf, F as setFact, I as setState, L as findRun, M as artefactStates, N as factsOf, O as path, P as setArtefact, R as loadRun, S as stateMachineToMermaid, T as cycles, V as failureOf, _ as sequenceToDot, a as defaultModelId, b as flowchartToMermaid, c as validateStored, d as emit, f as formatNames, g as flowchartToDot, h as viewNames, i as runProcess, j as add, k as ready, l as SyncInterruptedError, m as show, n as nodePorts, o as runCli, p as project, r as packageVersion, s as validateDocument, t as defaultDataPath, u as sync, v as stateMachineToDot, w as blocked, x as sequenceToMermaid, y as swimlaneToDot, z as runFacts } from "./dist-BI01yxFA.js";
|
|
3
|
+
import { t as version } from "./version-Dagrkvwt.js";
|
|
4
|
+
export { CliError, SyncInterruptedError, add, artefactStates, blocked, cycles, defaultDataPath, defaultModelId, emit, exitCodes, factsOf, failureOf, findRun, flowchartToDot, flowchartToMermaid, formatNames, handoffsOf, impactOf, loadRun, nodePorts, packageVersion, path, project, ready, runCli, runFacts, runProcess, sequenceToDot, sequenceToMermaid, setArtefact, setFact, setState, show, stateMachineToDot, stateMachineToMermaid, swimlaneToDot, swimlaneToMermaid, sync, validateDocument, validateStored, version, viewNames, why };
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { t as createSqliteGraphStore } from "./store-DKzvLGgl.js";
|
|
2
|
+
import { sql } from "drizzle-orm";
|
|
3
|
+
import { DatabaseSync } from "node:sqlite";
|
|
4
|
+
import { drizzle } from "drizzle-orm/node-sqlite";
|
|
5
|
+
import { chmodSync, closeSync, mkdirSync, openSync, statSync } from "node:fs";
|
|
6
|
+
import { dirname } from "node:path";
|
|
7
|
+
//#region ../../adapters/graph/sqlite-node/dist/open.js
|
|
8
|
+
/** The path `node:sqlite` reads as a private database in memory rather than a file. */
|
|
9
|
+
const inMemory = ":memory:";
|
|
10
|
+
/**
|
|
11
|
+
* Opens a graph store on a SQLite database file, creating the file when it does not exist. The schema is migrated on the store's first operation.
|
|
12
|
+
*
|
|
13
|
+
* A file database is switched to write-ahead logging, so readers in other processes (a command line beside a server) are not blocked by a writer. Each process's change feed sees only its own writes.
|
|
14
|
+
* @param path - The database file, or `":memory:"` for a private database that lives as long as the store.
|
|
15
|
+
* @param options - `node:sqlite` options passed through unchanged, such as `timeout` for how long a write waits for another process's lock.
|
|
16
|
+
* @returns The store, its database and a way to close it.
|
|
17
|
+
*/
|
|
18
|
+
const openNodeGraphStore = (path, options = {}) => {
|
|
19
|
+
const client = new DatabaseSync(path, options);
|
|
20
|
+
const db = drizzle({ client });
|
|
21
|
+
if (path !== inMemory) db.run(sql`PRAGMA journal_mode = WAL`);
|
|
22
|
+
return {
|
|
23
|
+
store: createSqliteGraphStore({ db }),
|
|
24
|
+
db,
|
|
25
|
+
close: () => {
|
|
26
|
+
client.close();
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region ../../adapters/graph/sqlite-node/dist/data-file.js
|
|
32
|
+
/** The data directory's mode: only its owner may list or enter it, since the store holds synced work (titles, relationships) that other users on the host must not read. */
|
|
33
|
+
const privateDirectoryMode = 448;
|
|
34
|
+
/** The data file's mode: only its owner may read or write it. SQLite creates the `-wal` and `-shm` files beside it with the same mode on Unix. */
|
|
35
|
+
const privateFileMode = 384;
|
|
36
|
+
/** The permission bits of a file mode, without its type. */
|
|
37
|
+
const permissionBits = 511;
|
|
38
|
+
/** The bits that give the file's group or anyone else any access. */
|
|
39
|
+
const groupAndOtherBits = 63;
|
|
40
|
+
/** The SQLite files a store at `path` uses: the database and its write-ahead log and shared-memory index. */
|
|
41
|
+
const storeFiles = (path) => [
|
|
42
|
+
path,
|
|
43
|
+
`${path}-wal`,
|
|
44
|
+
`${path}-shm`
|
|
45
|
+
];
|
|
46
|
+
/** Whether an error is the file system's report that a path does not exist, or already does. */
|
|
47
|
+
const hasCode = (error, code) => error instanceof Error && "code" in error && error.code === code;
|
|
48
|
+
/**
|
|
49
|
+
* Narrows a path's mode to `mode` when its group or others have any access.
|
|
50
|
+
* @param path - The path.
|
|
51
|
+
* @param mode - The private mode it should have.
|
|
52
|
+
* @returns Whether the mode was changed; `false` too when the path does not exist.
|
|
53
|
+
*/
|
|
54
|
+
const tighten = (path, mode) => {
|
|
55
|
+
let current;
|
|
56
|
+
try {
|
|
57
|
+
current = statSync(path).mode & permissionBits;
|
|
58
|
+
} catch (error) {
|
|
59
|
+
if (hasCode(error, "ENOENT")) return false;
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
if ((current & groupAndOtherBits) === 0) return false;
|
|
63
|
+
chmodSync(path, mode);
|
|
64
|
+
return true;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Makes a data file ready for `openNodeGraphStore` to open, so a store holding synced work is never readable by other users on the host. Call it before opening the store; it does not open the database itself.
|
|
68
|
+
*
|
|
69
|
+
* The directory is created when missing (with any missing parents), with `privateDirectoryMode` when it is the caller's own. The database file is created with `privateFileMode` when missing, before SQLite opens it, so the file and the `-wal` and `-shm` files SQLite derives from it are never readable by others, whatever the umask. A file that already exists is left alone unless the directory is the caller's own; there, an existing directory or store file (database, `-wal` or `-shm`) that group or others can read is narrowed to the private mode. On Windows, where file modes mean nothing, only the directory is created.
|
|
70
|
+
* @param path - The database file; not `":memory:"`, which has no file.
|
|
71
|
+
* @param options - Whether the caller owns the directory, and the platform.
|
|
72
|
+
* @returns One warning line naming what was narrowed, for the caller to show, or nothing when nothing was.
|
|
73
|
+
* @throws Error from the file system when the directory or file cannot be created or its mode read or changed.
|
|
74
|
+
*/
|
|
75
|
+
const prepareDataFile = (path, options) => {
|
|
76
|
+
const directory = dirname(path);
|
|
77
|
+
if (options.platform === "win32") {
|
|
78
|
+
mkdirSync(directory, { recursive: true });
|
|
79
|
+
return [];
|
|
80
|
+
}
|
|
81
|
+
mkdirSync(directory, options.ownsDirectory ? {
|
|
82
|
+
recursive: true,
|
|
83
|
+
mode: 448
|
|
84
|
+
} : { recursive: true });
|
|
85
|
+
try {
|
|
86
|
+
closeSync(openSync(path, "wx", 384));
|
|
87
|
+
} catch (error) {
|
|
88
|
+
if (!hasCode(error, "EEXIST")) throw error;
|
|
89
|
+
}
|
|
90
|
+
if (!options.ownsDirectory) return [];
|
|
91
|
+
const narrowed = [...tighten(directory, 448) ? [directory] : [], ...storeFiles(path).filter((file) => tighten(file, 384))];
|
|
92
|
+
return narrowed.length === 0 ? [] : [`made ${narrowed.join(", ")} readable by its owner only, since other users could read the synced work in it`];
|
|
93
|
+
};
|
|
94
|
+
//#endregion
|
|
95
|
+
export { openNodeGraphStore as i, privateDirectoryMode as n, privateFileMode as r, prepareDataFile as t };
|
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
import { a as validateOverlay, d as overlayStatuses, f as participantKinds } from "./schema-
|
|
1
|
+
import { a as validateOverlay, d as overlayStatuses, f as participantKinds } from "./schema-BPT8fmfa.js";
|
|
2
2
|
import { t as validate } from "./validate-DF3mQZww.js";
|
|
3
|
-
import { n as parseModel, t as ModelParseError } from "./parse-
|
|
3
|
+
import { n as parseModel, t as ModelParseError } from "./parse-C1Q1zsGt.js";
|
|
4
4
|
import { c as deriveStatuses, f as toStateMachine, g as handoffs, h as toFlowchart, i as readySet, n as criticalPath, p as toSwimlane, r as impact, s as explainStatus, t as blockedBy, u as toSequence } from "./queries-C8kIDRiY.js";
|
|
5
5
|
import { S as UnknownNodeError, f as layeredFacts, n as illegalCycles, u as factsFrom, x as CycleError } from "./control-DiygoEhm.js";
|
|
6
|
-
import { l as assembleSync, t as createGitHubIssuesSource, u as createGraphSourceRouter } from "./source-
|
|
6
|
+
import { l as assembleSync, t as createGitHubIssuesSource, u as createGraphSourceRouter } from "./source-D51N7K3A.js";
|
|
7
|
+
import { t as GraphSourceError } from "./errors-BZe5WzCn.js";
|
|
7
8
|
import { t as githubTokenFromEnvironment } from "./node-AchI1T-K.js";
|
|
8
|
-
import { g as emptyModel } from "./store-
|
|
9
|
-
import { t as createGraphStoreRouter } from "./router-
|
|
10
|
-
import {
|
|
9
|
+
import { g as emptyModel } from "./store-DKzvLGgl.js";
|
|
10
|
+
import { t as createGraphStoreRouter } from "./router-Dk91O_9p.js";
|
|
11
|
+
import { i as openNodeGraphStore, t as prepareDataFile } from "./data-file-BVMxkTug.js";
|
|
11
12
|
import { t as exitCodes } from "./exit-codes-0ultCqdS.js";
|
|
12
13
|
import { ORPCError, createRouterClient } from "@orpc/server";
|
|
14
|
+
import { readFileSync } from "node:fs";
|
|
15
|
+
import { join } from "node:path";
|
|
13
16
|
import { Argument, Command, CommanderError, Option } from "commander";
|
|
14
|
-
import { chmodSync, closeSync, mkdirSync, openSync, readFileSync, statSync } from "node:fs";
|
|
15
17
|
import { readFile } from "node:fs/promises";
|
|
16
18
|
import { homedir } from "node:os";
|
|
17
|
-
import { dirname, join } from "node:path";
|
|
18
19
|
//#region ../graph-cli/dist/errors.js
|
|
19
20
|
/** A failure the command line reports with its own exit status and message, and nothing else. */
|
|
20
21
|
var CliError = class extends Error {
|
|
@@ -46,6 +47,16 @@ const issueLines = (data) => {
|
|
|
46
47
|
return data.issues.flatMap((issue) => typeof issue === "object" && issue !== null && "code" in issue && "message" in issue && typeof issue.code === "string" && typeof issue.message === "string" ? [`${issue.code}: ${issue.message}`] : []);
|
|
47
48
|
};
|
|
48
49
|
/**
|
|
50
|
+
* The error underneath a source's failure, for a failure's cause. A source called in process through oRPC fails with an `ORPCError` whose cause is the `GraphSourceError` the source threw, whose own cause, when it has one, is what went wrong underneath, such as a token port's error. Those two layers say nothing more than the failure's message and exit status already do, so the innermost error is the one worth keeping.
|
|
51
|
+
* @param error - What the source call threw.
|
|
52
|
+
* @returns The `GraphSourceError`'s cause when it has one, otherwise that `GraphSourceError`; anything else as it is.
|
|
53
|
+
*/
|
|
54
|
+
const underlyingCause = (error) => {
|
|
55
|
+
const sourceError = error instanceof ORPCError && error.cause instanceof GraphSourceError ? error.cause : error;
|
|
56
|
+
if (!(sourceError instanceof GraphSourceError)) return error;
|
|
57
|
+
return sourceError.cause === void 0 ? sourceError : sourceError.cause;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
49
60
|
* Classifies anything a command threw into its exit status and the message for standard error. A commander usage error has already printed its own message, so it is reported with an empty one.
|
|
50
61
|
* @param error - What was thrown.
|
|
51
62
|
* @returns The exit status and message.
|
|
@@ -471,6 +482,21 @@ const renderSetFact = (result) => lines([`set fact ${result.fact} to ${result.va
|
|
|
471
482
|
const renderFacts = (result) => lines([...Object.entries(result.facts.artefacts).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0).map(([id, provided]) => `artefact\t${id}\t${provided ? "provided" : "absent"}`), ...Object.entries(result.facts.values).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0).map(([name, value]) => `fact\t${name}\t${valueText(value)}`)]);
|
|
472
483
|
/** `sync`: what was written, then each gap as its reason, target and message. */
|
|
473
484
|
const renderSync = (result) => lines([`synced ${String(result.activities)} activities, ${String(result.transitions)} transitions and ${String(result.participants)} participants into "${result.modelId}" at revision ${String(result.revision)}`, ...result.gaps.map((gap) => `gap\t${gap.reason}\t${gap.target}\t${gap.message}`)]);
|
|
485
|
+
/**
|
|
486
|
+
* A sync a source interrupted: the source's failure, whether the pages read before it were saved, and the commands that carry on, `resume with: sync <scopes> --after <cursor>` for the failing source and `then: sync <scopes>` for the sources not reached.
|
|
487
|
+
* @param message - The source's failure.
|
|
488
|
+
* @param interruption - Where the sync carries on.
|
|
489
|
+
* @returns The lines for standard error, without a final line break.
|
|
490
|
+
*/
|
|
491
|
+
const renderSyncInterruption = (message, interruption) => {
|
|
492
|
+
const { resume, remaining, saved } = interruption;
|
|
493
|
+
return [
|
|
494
|
+
message,
|
|
495
|
+
...saved ? ["the pages read before the failure are saved"] : [],
|
|
496
|
+
`resume with: sync ${resume.scopes.join(" ")}${resume.after === void 0 ? "" : ` --after ${resume.after}`}`,
|
|
497
|
+
...remaining.length === 0 ? [] : [`then: sync ${remaining.join(" ")}`]
|
|
498
|
+
].join("\n");
|
|
499
|
+
};
|
|
474
500
|
/** `validate`: `valid`, or each issue as its code, its JSON pointer when it has one, and its message. */
|
|
475
501
|
const renderValidate = (result) => result.valid ? lines(["valid"]) : lines(result.issues.map((issue) => issue.pointer === void 0 ? `${issue.code}\t${issue.message}` : `${issue.code}\t${issue.pointer === "" ? "/" : issue.pointer}\t${issue.message}`));
|
|
476
502
|
//#endregion
|
|
@@ -882,6 +908,27 @@ const show = async (session, request) => {
|
|
|
882
908
|
};
|
|
883
909
|
//#endregion
|
|
884
910
|
//#region ../graph-cli/dist/sync.js
|
|
911
|
+
/**
|
|
912
|
+
* Thrown by `sync` when a source fails part way. Its exit status and message are the source's failure, classified as `failureOf` classifies it; its cause is the error underneath that failure, such as the token port's own error; and what to run next is data, in `resume` and `remaining`, never text.
|
|
913
|
+
*/
|
|
914
|
+
var SyncInterruptedError = class extends CliError {
|
|
915
|
+
resume;
|
|
916
|
+
remaining;
|
|
917
|
+
saved;
|
|
918
|
+
/**
|
|
919
|
+
* @param exitCode - The exit status the source's failure maps to.
|
|
920
|
+
* @param message - The source's failure.
|
|
921
|
+
* @param interruption - Where the sync carries on.
|
|
922
|
+
* @param options - The underlying error, kept as the cause.
|
|
923
|
+
*/
|
|
924
|
+
constructor(exitCode, message, interruption, options) {
|
|
925
|
+
super(exitCode, message, options);
|
|
926
|
+
this.name = "SyncInterruptedError";
|
|
927
|
+
this.resume = interruption.resume;
|
|
928
|
+
this.remaining = interruption.remaining;
|
|
929
|
+
this.saved = interruption.saved;
|
|
930
|
+
}
|
|
931
|
+
};
|
|
885
932
|
const scopeSeparator = ":";
|
|
886
933
|
/** Groups scopes by their source prefix, keeping the order in which each prefix first appears. */
|
|
887
934
|
const bySource = (scopes) => {
|
|
@@ -917,12 +964,12 @@ const boundActivities = (pages) => {
|
|
|
917
964
|
/**
|
|
918
965
|
* Reads every page of the scopes from their sources and merges them into the session's model in one write, creating the model when the store has none. Records already in the model are replaced by identifier and the rest are kept, so syncing again refreshes what changed.
|
|
919
966
|
*
|
|
920
|
-
* When a source fails part way, the pages read before the failure are still written, and the error
|
|
967
|
+
* When a source fails part way, the pages read before the failure are still written, and the error carries where to carry on: the request that resumes the failing source after the cursor of its last page read, and the scopes of the sources not reached.
|
|
921
968
|
* @param session - The store and model.
|
|
922
969
|
* @param sources - The source for each identifier prefix.
|
|
923
970
|
* @param request - The scopes, and a cursor to resume after.
|
|
924
971
|
* @returns What was written, and the gaps the sources reported.
|
|
925
|
-
* @throws CliError with `usage` for a scope with no source prefix, a prefix no source serves, or `after` with scopes of more than one source; and with the source's failure
|
|
972
|
+
* @throws CliError with `usage` for a scope with no source prefix, a prefix no source serves, or `after` with scopes of more than one source; and SyncInterruptedError, with the source's failure and where to carry on, when a source fails part way.
|
|
926
973
|
*/
|
|
927
974
|
const sync = async (session, sources, request) => {
|
|
928
975
|
const groups = bySource(request.scopes);
|
|
@@ -969,13 +1016,14 @@ const sync = async (session, sources, request) => {
|
|
|
969
1016
|
const failure = failureOf(error);
|
|
970
1017
|
const saved = pages.length > 0;
|
|
971
1018
|
if (saved) await write();
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
1019
|
+
throw new SyncInterruptedError(failure.exitCode, failure.message, {
|
|
1020
|
+
resume: cursor === void 0 ? { scopes: group.scopes } : {
|
|
1021
|
+
scopes: group.scopes,
|
|
1022
|
+
after: cursor
|
|
1023
|
+
},
|
|
1024
|
+
remaining: clients.slice(index + 1).flatMap((next) => next.scopes),
|
|
1025
|
+
saved
|
|
1026
|
+
}, { cause: underlyingCause(error) });
|
|
979
1027
|
}
|
|
980
1028
|
await readFrom(index + 1);
|
|
981
1029
|
};
|
|
@@ -1137,14 +1185,19 @@ const runCli = async (args, ports, identity) => {
|
|
|
1137
1185
|
program.command("sync").description("read the scopes from their sources and merge them into the model").argument("<scope...>", "source-qualified scopes, such as github:owner or github:owner/repo").option("--after <cursor>", "resume an interrupted sync after this cursor").action(async (scopes, options, command) => {
|
|
1138
1186
|
const { after } = options;
|
|
1139
1187
|
await withSession(async (session) => {
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1188
|
+
try {
|
|
1189
|
+
const result = await sync(session, ports.source, typeof after === "string" ? {
|
|
1190
|
+
scopes,
|
|
1191
|
+
after
|
|
1192
|
+
} : { scopes });
|
|
1193
|
+
return {
|
|
1194
|
+
json: result,
|
|
1195
|
+
text: renderSync(result)
|
|
1196
|
+
};
|
|
1197
|
+
} catch (error) {
|
|
1198
|
+
if (error instanceof SyncInterruptedError) throw new CliError(error.exitCode, renderSyncInterruption(error.message, error), { cause: error });
|
|
1199
|
+
throw error;
|
|
1200
|
+
}
|
|
1148
1201
|
})(command);
|
|
1149
1202
|
});
|
|
1150
1203
|
program.command("ready").description("list the work that can start now").action(async (_options, command) => {
|
|
@@ -1388,61 +1441,6 @@ const runCli = async (args, ports, identity) => {
|
|
|
1388
1441
|
}
|
|
1389
1442
|
return exitCode;
|
|
1390
1443
|
};
|
|
1391
|
-
/** The permission bits of a file mode, without its type. */
|
|
1392
|
-
const permissionBits = 511;
|
|
1393
|
-
/** The bits that give the file's group or anyone else any access. */
|
|
1394
|
-
const groupAndOtherBits = 63;
|
|
1395
|
-
/** The SQLite files a store at `path` uses: the database and its write-ahead log and shared-memory index. */
|
|
1396
|
-
const storeFiles = (path) => [
|
|
1397
|
-
path,
|
|
1398
|
-
`${path}-wal`,
|
|
1399
|
-
`${path}-shm`
|
|
1400
|
-
];
|
|
1401
|
-
/** Whether an error is the file system's report that a path does not exist, or already does. */
|
|
1402
|
-
const hasCode = (error, code) => error instanceof Error && "code" in error && error.code === code;
|
|
1403
|
-
/**
|
|
1404
|
-
* Narrows a path's mode to `mode` when its group or others have any access.
|
|
1405
|
-
* @param path - The path.
|
|
1406
|
-
* @param mode - The private mode it should have.
|
|
1407
|
-
* @returns Whether the mode was changed; `false` too when the path does not exist.
|
|
1408
|
-
*/
|
|
1409
|
-
const tighten = (path, mode) => {
|
|
1410
|
-
let current;
|
|
1411
|
-
try {
|
|
1412
|
-
current = statSync(path).mode & permissionBits;
|
|
1413
|
-
} catch (error) {
|
|
1414
|
-
if (hasCode(error, "ENOENT")) return false;
|
|
1415
|
-
throw error;
|
|
1416
|
-
}
|
|
1417
|
-
if ((current & groupAndOtherBits) === 0) return false;
|
|
1418
|
-
chmodSync(path, mode);
|
|
1419
|
-
return true;
|
|
1420
|
-
};
|
|
1421
|
-
/**
|
|
1422
|
-
* Makes a data file ready for SQLite to open. The directory is created when missing, private when it is the command line's own. The database file is created private when missing, before SQLite opens it, so the file and the sidecars SQLite derives from it are never readable by others, whatever the umask; a file that already exists is left alone unless the directory is the command line's own. In its own directory, an existing directory or store file that group or others can read is narrowed to the private mode.
|
|
1423
|
-
* @param path - The database file.
|
|
1424
|
-
* @param options - How much of the path the command line owns, and the platform.
|
|
1425
|
-
* @returns One warning line naming what was narrowed, or nothing.
|
|
1426
|
-
*/
|
|
1427
|
-
const prepareDataFile = (path, options) => {
|
|
1428
|
-
const directory = dirname(path);
|
|
1429
|
-
if (options.platform === "win32") {
|
|
1430
|
-
mkdirSync(directory, { recursive: true });
|
|
1431
|
-
return [];
|
|
1432
|
-
}
|
|
1433
|
-
mkdirSync(directory, options.ownsDirectory ? {
|
|
1434
|
-
recursive: true,
|
|
1435
|
-
mode: 448
|
|
1436
|
-
} : { recursive: true });
|
|
1437
|
-
try {
|
|
1438
|
-
closeSync(openSync(path, "wx", 384));
|
|
1439
|
-
} catch (error) {
|
|
1440
|
-
if (!hasCode(error, "EEXIST")) throw error;
|
|
1441
|
-
}
|
|
1442
|
-
if (!options.ownsDirectory) return [];
|
|
1443
|
-
const narrowed = [...tighten(directory, 448) ? [directory] : [], ...storeFiles(path).filter((file) => tighten(file, 384))];
|
|
1444
|
-
return narrowed.length === 0 ? [] : [`made ${narrowed.join(", ")} readable by its owner only, since other users could read the synced work in it`];
|
|
1445
|
-
};
|
|
1446
1444
|
//#endregion
|
|
1447
1445
|
//#region ../graph-cli/dist/node.js
|
|
1448
1446
|
/** The variable that names the data file outright. */
|
|
@@ -1485,7 +1483,7 @@ const packageVersion = (manifest) => {
|
|
|
1485
1483
|
return parsed.version;
|
|
1486
1484
|
};
|
|
1487
1485
|
/**
|
|
1488
|
-
* The ports for a Node process: the SQLite store over `node:sqlite` (creating the data file's directory when needed), the GitHub issues source for `github:` scopes, the file system and the process's streams.
|
|
1486
|
+
* The ports for a Node process: the SQLite store over `node:sqlite` (creating the data file's directory when needed, private when the command line or the host owns it), the GitHub issues source for `github:` scopes, the file system and the process's streams.
|
|
1489
1487
|
* @param options - Replacements for any of the defaults.
|
|
1490
1488
|
* @returns The ports.
|
|
1491
1489
|
*/
|
|
@@ -1493,7 +1491,7 @@ const nodePorts = (options = {}) => {
|
|
|
1493
1491
|
const env = options.env ?? process.env;
|
|
1494
1492
|
const token = options.token ?? githubTokenFromEnvironment({ env });
|
|
1495
1493
|
const home = options.home ?? homedir();
|
|
1496
|
-
const ownDataPath = xdgDataPath(env, home);
|
|
1494
|
+
const ownDataPath = options.dataPath ?? xdgDataPath(env, home);
|
|
1497
1495
|
return {
|
|
1498
1496
|
stdout: options.stdout ?? ((text) => {
|
|
1499
1497
|
process.stdout.write(text);
|
|
@@ -1501,7 +1499,7 @@ const nodePorts = (options = {}) => {
|
|
|
1501
1499
|
stderr: options.stderr ?? ((text) => {
|
|
1502
1500
|
process.stderr.write(text);
|
|
1503
1501
|
}),
|
|
1504
|
-
defaultDataPath: defaultDataPath(env, home),
|
|
1502
|
+
defaultDataPath: options.dataPath ?? defaultDataPath(env, home),
|
|
1505
1503
|
openStore: (path) => {
|
|
1506
1504
|
const warnings = path === inMemory ? [] : prepareDataFile(path, {
|
|
1507
1505
|
ownsDirectory: path === ownDataPath,
|
|
@@ -1540,4 +1538,4 @@ const runProcess = async (identity) => {
|
|
|
1540
1538
|
return runCli(process.argv.slice(2), nodePorts({ signal: controller.signal }), identity);
|
|
1541
1539
|
};
|
|
1542
1540
|
//#endregion
|
|
1543
|
-
export {
|
|
1541
|
+
export { why as A, CliError as B, swimlaneToMermaid as C, impactOf as D, handoffsOf as E, setFact as F, setState as I, findRun as L, artefactStates as M, factsOf as N, path as O, setArtefact as P, loadRun as R, stateMachineToMermaid as S, cycles as T, failureOf as V, sequenceToDot as _, defaultModelId as a, flowchartToMermaid as b, validateStored as c, emit as d, formatNames as f, flowchartToDot as g, viewNames as h, runProcess as i, add as j, ready as k, SyncInterruptedError as l, show as m, nodePorts as n, runCli as o, project as p, packageVersion as r, validateDocument as s, defaultDataPath as t, sync as u, stateMachineToDot as v, blocked as w, sequenceToMermaid as x, swimlaneToDot as y, runFacts as z };
|