resolve architecture review round 2: criticals, warnings, suggestions
- C-05: Add flowgraph-api.md with complete public API surface - C-06: Document <Map> component in workflow-templates.md - C-07: Specify Conditional else-branch behavior - C-08: Add lifecycle/ownership section to reactive-execution.md - C-09: Add consumer-integration.md end-to-end walkthrough - W-02: Add reactive error boundary semantics (3 levels) - W-03: Complete ReactiveContext interface definition - W-04: Add template composition rules (8 rules) - W-05: Document removeChild for both HostConfigs - W-06: Document signal/effect disposal lifecycle - W-07: Add ADR-004 (no schema version field) - W-08: Add type compatibility depth/contract to analysis.md - W-11: Add performance characteristics section - S-01: Getting Started merged into consumer-integration.md - S-02: Add flow diagrams for template rendering pipeline - S-03: Add node status state machine diagram - S-04: Add testing strategy section - S-06: Validate source structure cross-references Review round 2 fixes: - Define TemplateNodeAttrs as alias for OperationNodeAttrs - Document CallEventMapValue and CallResult types in schema.md - Standardize CycleError naming (replace CircularDependencyError) - Add function form to Map.over type definition - Define Map aggregate completion/failure semantics - Fix immutability claim for fromCallEvents - Clarify edgeType storage alongside OperationEdgeAttrs - Clarify WorkflowNode.status === statusMap (same Signal) - Add component-to-tag mapping for WorkflowTag
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
---
|
||||
status: draft
|
||||
last_updated: 2026-05-19
|
||||
last_updated: 2026-05-20
|
||||
---
|
||||
|
||||
# Build & Distribution
|
||||
@@ -17,6 +17,7 @@ Package structure, exports map, dependencies, and platform targets.
|
||||
│ │ ├── sequential.ts # <Sequential> component
|
||||
│ │ ├── parallel.ts # <Parallel> component
|
||||
│ │ ├── conditional.ts # <Conditional> component
|
||||
│ │ ├── map.ts # <Map> component
|
||||
│ │ └── index.ts
|
||||
│ ├── host/
|
||||
│ │ ├── graphology.ts # GraphologyHostConfig
|
||||
@@ -133,7 +134,7 @@ Following the taskgraph pattern, each module has a sub-path export:
|
||||
| Sub-path | Content | Use case |
|
||||
|----------|---------|----------|
|
||||
| `@alkdev/flowgraph` | Barrel export (everything) | Full import |
|
||||
| `@alkdev/flowgraph/component` | `<Operation>`, `<Sequential>`, `<Parallel>`, `<Conditional>` | Template authoring |
|
||||
| `@alkdev/flowgraph/component` | `<Operation>`, `<Sequential>`, `<Parallel>`, `<Conditional>`, `<Map>` | Template authoring |
|
||||
| `@alkdev/flowgraph/host` | `GraphologyHostConfig`, `ReactiveHostConfig` | ujsx HostConfig implementations |
|
||||
| `@alkdev/flowgraph/schema` | TypeBox schemas, enums, types | Schema-only import (no graph dependency) |
|
||||
| `@alkdev/flowgraph/graph` | `FlowGraph` class, construction, mutation, queries | Core graph operations |
|
||||
@@ -272,6 +273,81 @@ The sub-path export structure enables effective tree-shaking:
|
||||
|
||||
The barrel export (`@alkdev/flowgraph`) re-exports everything for convenience, but consumers concerned about bundle size should use sub-path imports.
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
### Unit Test Categories
|
||||
|
||||
| Category | What to test | How |
|
||||
|----------|-------------|-----|
|
||||
| Schema validation | TypeBox schemas validate/correct shapes | `Value.Check()` / `Value.Errors()` |
|
||||
| Graph construction | `fromSpecs`, `fromCallEvents`, `fromJSON` | Build graphs, assert node/edge counts |
|
||||
| Graph mutations | `addNode`, `addEdge`, `updateStatus` | Assert success, assert throws on violations |
|
||||
| Graph queries | `topologicalOrder`, `ancestors`, `descendants` | Known graphs, expected results |
|
||||
| Type compatibility | `typeCompat` for known schema pairs | Compatible/incompatible/unknown |
|
||||
| Template validation | `validateTemplate` against known graphs | Known valid/invalid templates |
|
||||
| Error hierarchy | `CycleError`, `InvalidTransitionError`, etc. | Assert throw types, assert message format |
|
||||
| Reactive execution | Signal propagation, preconditions, abort cascade | Set up mini reactive graph, assert state transitions |
|
||||
|
||||
### Testing Reactive Graphs
|
||||
|
||||
Testing signal-based state propagation requires specific patterns:
|
||||
|
||||
1. **Setup**: Create a `WorkflowReactiveRoot` with a known DAG. Assert initial state (all nodes `idle`).
|
||||
|
||||
2. **Transition**: Set a node's status signal to a known value. Assert that dependents' `preconditions` and `blockedByFailure` computeds update correctly.
|
||||
|
||||
3. **Assertion**: Check `node.status.value`, `node.preconditions.value`, `node.blockedByFailure.value` at each step.
|
||||
|
||||
```typescript
|
||||
// Example test pattern
|
||||
const root = new WorkflowReactiveRoot(dag);
|
||||
const nodeA = root.statusMap.get("A")!;
|
||||
const nodeB = root.statusMap.get("B")!;
|
||||
|
||||
// Initially: both idle
|
||||
expect(nodeA.value).toBe("idle");
|
||||
expect(nodeB.preconditions.value).toBe(false); // A not completed yet
|
||||
|
||||
// Complete A → B's preconditions met
|
||||
nodeA.value = "completed";
|
||||
expect(nodeB.preconditions.value).toBe(true);
|
||||
```
|
||||
|
||||
4. **Cleanup**: Call `root.dispose()` after each test to prevent signal leaks.
|
||||
|
||||
### Testing Template Rendering
|
||||
|
||||
Template rendering tests follow the same pattern for both HostConfigs:
|
||||
|
||||
1. Define a template
|
||||
2. Render to the target (graphology or reactive)
|
||||
3. Assert the output (graph structure or signal state)
|
||||
|
||||
```typescript
|
||||
// GraphologyHostConfig test
|
||||
const host = new GraphologyHostConfig();
|
||||
const root = createRoot(host, new DirectedGraph());
|
||||
root.render(template);
|
||||
const graph = root.ctx.graph;
|
||||
expect(graph.nodes()).toEqual(["A", "B", "C"]);
|
||||
expect(graph.edges()).toEqual(["A->B", "B->C"]);
|
||||
|
||||
// ReactiveHostConfig test
|
||||
const reactiveHost = new ReactiveHostConfig(registry, workflowRoot);
|
||||
const reactiveRoot = createRoot(reactiveHost, {});
|
||||
reactiveRoot.render(template);
|
||||
expect(workflowRoot.statusMap.size).toBe(3);
|
||||
```
|
||||
|
||||
### Testing Error Paths
|
||||
|
||||
All error paths should be tested:
|
||||
|
||||
- Cycle detection: adding a cycle-creating edge throws `CycleError`
|
||||
- Duplicate node/edge: adding duplicates throws `ConstructionError`
|
||||
- Invalid status transition: `updateStatus(completed → running)` throws `InvalidTransitionError`
|
||||
- Validation errors: `validateGraph()` returns arrays, never throws
|
||||
|
||||
## Constraints
|
||||
|
||||
- **No filesystem access** — flowgraph is a pure computation library. Persistence is the hub's concern.
|
||||
|
||||
Reference in New Issue
Block a user