aboutsummaryrefslogtreecommitdiff
path: root/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'README.md')
-rw-r--r--README.md280
1 files changed, 280 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..1d90963
--- /dev/null
+++ b/README.md
@@ -0,0 +1,280 @@
+# wmap-parser
+
+A high-performance JavaScript parser for wmap formatted Wardley Map files.
+
+## Features
+
+- **Zero dependencies** (dev dependencies only for testing and benchmarking)
+- **High performance** state machine parser
+- **TypeScript-friendly** with comprehensive JSDoc type definitions
+- **Cross-platform** line ending support (LF, CRLF, CR)
+- **Robust** error handling - invalid lines are gracefully ignored
+
+## Installation
+
+```bash
+npm install wmap-parser
+```
+
+Or with pnpm:
+
+```bash
+pnpm add wmap-parser
+```
+
+## Usage
+
+```javascript
+import { parse } from "wmap-parser";
+
+const wmapSource = `
+[I] 0.25
+[II] 0.5
+[III] 0.75
+[IV] 1.0
+
+Tea (0.9, 0.5) [Circle]
+Cup (0.8, 0.4)
+Hot Water (0.6, 0.2)
+
+Tea -> Cup
+Cup -> Hot Water
+
+[Note] (0.5, 0.5) Supply chain for tea
+[Group] Tea, Cup
+[Inertia] Cup
+[Evolution] Tea + 0.1
+`;
+
+const map = await parse(wmapSource);
+
+console.log(map.entities);
+// [
+// { type: 'stage', number: 'i', value: 0.25 },
+// { type: 'stage', number: 'ii', value: 0.5 },
+// { type: 'component', label: 'Tea', coordinates: [0.9, 0.5], shape: 'circle' },
+// { type: 'dependency', from: 'Tea', to: 'Cup', isDirected: true },
+// ...
+// ]
+```
+
+## API
+
+### `parse(source: string): Promise<Map>`
+
+Parses a wmap formatted string and returns a Map object.
+
+**Parameters:**
+
+- `source` (string): The wmap source code to parse
+
+**Returns:**
+
+- `Promise<Map>`: A promise that resolves to a Map object
+
+### Type Definitions
+
+#### Map
+
+```typescript
+{
+ entities: Entity[]
+}
+```
+
+#### Entity
+
+Union type of: `Component | Dependency | Note | Stage | Group | Inertia | Evolution`
+
+#### Component
+
+```typescript
+{
+ type: "component";
+ label: string;
+ coordinates: [number, number];
+ shape: string | null; // 'x' | 'square' | 'triangle' | 'circle' | null
+}
+```
+
+#### Dependency
+
+```typescript
+{
+ type: "dependency";
+ from: string;
+ to: string;
+ isDirected: boolean; // true for ->, false for --
+}
+```
+
+#### Note
+
+```typescript
+{
+ type: "note";
+ coordinates: [number, number];
+ text: string;
+}
+```
+
+#### Stage
+
+```typescript
+{
+ type: "stage";
+ number: string; // 'i' | 'ii' | 'iii' | 'iv'
+ value: number;
+}
+```
+
+#### Group
+
+```typescript
+{
+ type: 'group'
+ vertices: string[]
+}
+```
+
+#### Inertia
+
+```typescript
+{
+ type: "inertia";
+ vertex: string;
+}
+```
+
+#### Evolution
+
+```typescript
+{
+ type: "evolution";
+ vertex: string;
+ isPositive: boolean;
+ value: number;
+}
+```
+
+## Format Specification
+
+The wmap format supports the following entity types:
+
+### Components (Vertices)
+
+```
+ComponentName (x, y)
+ComponentName (x, y) [Shape]
+```
+
+- Coordinates are decimal numbers (0-100 range typical)
+- Optional shape: `x`, `Square`, `Triangle`, or `Circle` (case-insensitive)
+
+### Dependencies (Edges)
+
+```
+Source -> Target # Directed dependency
+Source -- Target # Undirected dependency
+```
+
+### Notes
+
+```
+[Note] (x, y) Note text content
+```
+
+### Stages
+
+```
+[I] 0.25
+[II] 0.5
+[III] 0.75
+[IV] 1.0
+```
+
+- Stage numbers: `I`, `II`, `III`, or `IV` (case-insensitive)
+
+### Groups
+
+```
+[Group] Component1, Component2, Component3
+```
+
+### Inertia
+
+```
+[Inertia] ComponentName
+```
+
+### Evolution
+
+```
+[Evolution] ComponentName + 0.5
+[Evolution] ComponentName - 0.3
+```
+
+See the [formal EBNF specification](doc/wmap-spec.ebnf) for complete grammar details.
+
+## Performance
+
+The parser uses a character-by-character state machine approach for optimal performance:
+
+- **No regex overhead** - direct character comparisons
+- **Minimal allocations** - efficient string operations
+- **Single-pass parsing** - each line processed once
+- **Cache-friendly** - sequential memory access
+
+Benchmark on a typical map with ~120 entities:
+
+- **~50,000+ operations/second**
+- **~0.02ms average parse time**
+
+Run benchmarks yourself:
+
+```bash
+npm run benchmark
+```
+
+## Error Handling
+
+The parser is designed to be fault-tolerant:
+
+- Invalid lines are silently ignored
+- Partial entities are not added to the result
+- Empty lines and whitespace are handled gracefully
+- Different line endings (LF, CRLF, CR) are all supported
+
+## Development
+
+### Running Tests
+
+```bash
+npm test
+```
+
+Tests use Node's built-in test runner (`node:test`) with no external dependencies.
+
+### Running Benchmarks
+
+```bash
+npm run benchmark
+```
+
+## License
+
+AGPL-v3
+
+## Contributing
+
+This is a focused, performance-oriented parser. Contributions should maintain:
+
+- Zero runtime dependencies
+- High performance characteristics
+- Simple, readable code
+- Comprehensive test coverage
+
+## See Also
+
+- [wmap specification](doc/wmap-spec.ebnf) - Formal grammar
+- [Wardley Maps](https://wardleymaps.com/) - Learn about Wardley Mapping