diff options
Diffstat (limited to 'README.md')
| -rw-r--r-- | README.md | 280 |
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 |