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
19 changes: 13 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,24 @@ pnpm build
```
ocpp-debugkit/
├── packages/
│ ├── core/ # Data model, parser, normalizer, timeline, failure detection
│ ├── scenarios/ # Predefined trace scenarios for testing
│ ├── reporter/ # Report generators (Markdown, HTML)
│ ├── cli/ # Command-line interface
│ ├── replay/ # Replay engine (v0.2+)
│ └── react/ # Reusable React components (v0.2+)
│ └── toolkit/ # Single npm package @ocpp-debugkit/toolkit
│ └── src/
│ ├── core/ # Data model, parser, normalizer, timeline, failure detection
│ ├── scenarios/ # Predefined trace scenarios for testing
│ ├── reporter/ # Report generators (Markdown, HTML)
│ ├── replay/ # Replay engine
│ ├── react/ # Reusable React components
│ └── cli/ # Command-line interface (bin: ocpp-debugkit)
├── apps/
│ └── web/ # Single Next.js app (landing, inspector, docs, blog)
└── ...
```

All modules ship in a single package, `@ocpp-debugkit/toolkit`, exposed via
subpath exports (`@ocpp-debugkit/toolkit/core`, `/scenarios`, `/reporter`,
`/replay`, `/react`, `/cli`, `/fixtures`). See
[ADR-0010](./docs/adr/0010-single-package-consolidation.md) for the rationale.

See [`AGENTS.md`](./AGENTS.md) for a detailed overview of the architecture,
build commands, and package dependency graph.

Expand Down
61 changes: 41 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,29 +37,33 @@ validate behavior against known scenarios.

## Architecture

OCPP DebugKit is a pnpm monorepo with independently versioned packages.
OCPP DebugKit is a pnpm monorepo. All modules ship in a single npm package,
`@ocpp-debugkit/toolkit`, exposed via [subpath exports](https://nodejs.org/api/packages.html#subpath-exports).

```
core ← everything depends on this
/ | \
scenarios | reporter | replay
\ | / |
cli |
| |
apps/web (single Next.js app)
@ocpp-debugkit/toolkit
├── core ← data model, parser, normalizer, timeline, failure detection
├── scenarios ← predefined trace scenarios (depends on core)
├── reporter ← report generators — Markdown, HTML (depends on core)
├── replay ← replay engine (depends on core)
├── react ← reusable React components (depends on core, scenarios, reporter)
└── cli ← command-line interface (depends on core, scenarios, reporter)
└── apps/web (single Next.js app)
```

| Package | Description | Version |
|---------|-------------|---------|
| `@ocpp-debugkit/core` | Data model, trace parser, event normalizer, timeline, failure detection | [![npm](https://img.shields.io/npm/v/@ocpp-debugkit/core.svg)](https://www.npmjs.com/package/@ocpp-debugkit/core) |
| `@ocpp-debugkit/scenarios` | Predefined trace scenarios for testing | [![npm](https://img.shields.io/npm/v/@ocpp-debugkit/scenarios.svg)](https://www.npmjs.com/package/@ocpp-debugkit/scenarios) |
| `@ocpp-debugkit/reporter` | Report generators (Markdown) | [![npm](https://img.shields.io/npm/v/@ocpp-debugkit/reporter.svg)](https://www.npmjs.com/package/@ocpp-debugkit/reporter) |
| `@ocpp-debugkit/cli` | Command-line interface | [![npm](https://img.shields.io/npm/v/@ocpp-debugkit/cli.svg)](https://www.npmjs.com/package/@ocpp-debugkit/cli) |
| `@ocpp-debugkit/replay` | Replay engine | _planned (v0.2.0)_ |
| `@ocpp-debugkit/react` | Reusable React components | _planned (v0.2.0)_ |
| `apps/web` | Single Next.js app (landing, inspector, docs) | — |
| Import path | Description |
|-------------|-------------|
| `@ocpp-debugkit/toolkit/core` | Data model, trace parser, event normalizer, timeline, failure detection |
| `@ocpp-debugkit/toolkit/scenarios` | Predefined trace scenarios for testing |
| `@ocpp-debugkit/toolkit/reporter` | Report generators (Markdown) |
| `@ocpp-debugkit/toolkit/replay` | Replay engine |
| `@ocpp-debugkit/toolkit/react` | Reusable React components |
| `@ocpp-debugkit/toolkit/cli` | Programmatic CLI entry (`bin: ocpp-debugkit`) |
| `@ocpp-debugkit/toolkit/fixtures` | Trace fixtures for testing |
| `apps/web` | Single Next.js app (landing, inspector, docs) |

**Build order:** core → scenarios/reporter/replay → cli → app
**Build order:** toolkit (all internal modules in one `tsc` pass) → app

## Quickstart

Expand All @@ -74,13 +78,19 @@ pnpm build

### CLI

Packages are published to npm under the `@ocpp-debugkit` scope:
Install the single package globally to get the `ocpp-debugkit` binary:

```bash
npm install -g @ocpp-debugkit/cli
npm install -g @ocpp-debugkit/toolkit
ocpp-debugkit inspect trace.json
```

Or use `npx` without installing:

```bash
npx ocpp-debugkit inspect trace.json
```

Other commands:

```bash
Expand All @@ -89,6 +99,17 @@ ocpp-debugkit scenario list
ocpp-debugkit scenario run failed-auth
```

### Programmatic Usage

```ts
import { parseTrace, detectFailures } from '@ocpp-debugkit/toolkit/core';
import { scenarios } from '@ocpp-debugkit/toolkit/scenarios';
import { generateMarkdownReport } from '@ocpp-debugkit/toolkit/reporter';
```

See the [Migration Guide](./docs/migration.md) if you are upgrading from the
old multi-package layout.

### Web App

Visit [ocppdebugkit.com/inspector](https://ocppdebugkit.com/inspector) to
Expand Down
154 changes: 154 additions & 0 deletions docs/adr/0010-single-package-consolidation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
# ADR-0010: Single Package Consolidation

## Status

Accepted

## Context

OCPP DebugKit was originally published as four independent npm packages under
the `@ocpp-debugkit` scope:

- `@ocpp-debugkit/core` — data model, trace parser, event normalizer, timeline,
failure detection
- `@ocpp-debugkit/scenarios` — predefined trace scenarios for testing
- `@ocpp-debugkit/reporter` — report generators (Markdown)
- `@ocpp-debugkit/cli` — command-line interface

Two additional packages — `@ocpp-debugkit/replay` (replay engine) and
`@ocpp-debugkit/react` (reusable React components) — were planned for v0.2.0.

This multi-package layout created several problems:

1. **Version drift.** Each package was independently versioned. Consumers had
to keep peer versions in sync, and a mismatch between `core` and `scenarios`
could cause subtle runtime failures that were hard to diagnose.

2. **Cross-package coupling.** `scenarios`, `reporter`, and `cli` all depend on
`core` types. A change to a `core` type required coordinated releases across
all dependent packages, defeating the supposed independence.

3. **Installation friction.** Consumers needed to install and list multiple
packages:

```bash
npm install @ocpp-debugkit/core @ocpp-debugkit/scenarios @ocpp-debugkit/reporter
```

4. **Release overhead.** Each release required changeset coordination across
multiple packages, multiple `npm publish` calls, and CI that had to build
and test the full dependency graph in order.

5. **Small project, not a library ecosystem.** The packages are tightly coupled
and maintained by a single team. The independence promised by the
multi-package layout was theoretical — in practice, every meaningful change
touched multiple packages simultaneously.

6. **Internal module boundaries are enough.** The actual source code already
lives in a single `packages/toolkit` directory with subdirectories (`core`,
`scenarios`, `reporter`, `replay`, `react`, `cli`). The npm package
boundaries were a publishing artifact, not an architectural one.

## Decision

**Consolidate all four published packages into a single npm package,
`@ocpp-debugkit/toolkit`, exposed via subpath exports.**

### Package structure

```
@ocpp-debugkit/toolkit
exports:
. # umbrella entry (re-exports core + scenarios)
./core # data model, parser, normalizer, timeline, failure detection
./scenarios # predefined trace scenarios
./reporter # report generators (Markdown, HTML)
./replay # replay engine
./react # reusable React components
./cli # programmatic CLI entry
./fixtures # trace fixtures (moved from core/fixtures)
bin:
ocpp-debugkit # CLI binary
```

### Subpath exports

Consumers import from `@ocpp-debugkit/toolkit/<module>` instead of
`@ocpp-debugkit/<module>`:

```ts
// Before
import { parseTrace } from '@ocpp-debugkit/core';
import { scenarios } from '@ocpp-debugkit/scenarios';
import { generateMarkdownReport } from '@ocpp-debugkit/reporter';

// After
import { parseTrace } from '@ocpp-debugkit/toolkit/core';
import { scenarios } from '@ocpp-debugkit/toolkit/scenarios';
import { generateMarkdownReport } from '@ocpp-debugkit/toolkit/reporter';
```

### Binary

The CLI binary name remains `ocpp-debugkit`. Consumers install one package and
get the CLI:

```bash
npm install -g @ocpp-debugkit/toolkit
ocpp-debugkit inspect trace.json
```

For `npx`:

```bash
npx ocpp-debugkit inspect trace.json
```

### Deprecation of old packages

The four old packages (`@ocpp-debugkit/core`, `@ocpp-debugkit/scenarios`,
`@ocpp-debugkit/reporter`, `@ocpp-debugkit/cli`) remain on npm with a
`deprecated` flag in their latest published versions. They will not receive new
features or bug fixes. A migration guide is provided at
[`docs/migration.md`](../migration.md).

### Single version

`@ocpp-debugkit/toolkit` is a single versioned unit. No more peer-dependency
mismatches — one version, one install, one release.

## Consequences

### Positive

- **Simpler installation.** One package to install: `npm install
@ocpp-debugkit/toolkit`.
- **No version drift.** All modules share a single version. Mismatches are
structurally impossible.
- **Faster releases.** One package, one publish, one changeset — instead of
coordinated multi-package releases.
- **Cleaner dependency graph.** Internal modules depend on each other via
TypeScript path aliases, not npm dependencies. The build is a single `tsc`
pass.
- **Better tree-shaking.** Subpath exports let bundlers include only the
modules a consumer actually imports. A consumer using only `core` doesn't pull
in `react` or `cli`.
- **Module boundaries preserved.** The `core` / `scenarios` / `reporter` /
`replay` / `react` / `cli` separation still exists as directories and export
paths — the architectural boundary is intact, only the npm boundary is gone.

### Negative

- **Breaking change for existing consumers.** Anyone importing
`@ocpp-debugkit/core` must update to `@ocpp-debugkit/toolkit/core`. The
migration guide and deprecated old packages ease this.
- **Larger single package.** The npm tarball is larger, though consumers only
pay for what they import at runtime via subpath exports and tree-shaking.
- **No independent versioning.** A bug fix to `reporter` bumps the version for
all modules. Given the tight coupling, this is acceptable — a `reporter` fix
often depends on a `core` change anyway.

### Neutral

- The old packages stay on npm indefinitely for backward compatibility, but
they are deprecated and frozen.
1 change: 1 addition & 0 deletions docs/adr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ significant architectural decision, its context, and its consequences.
| [ADR-0007](0007-malformed-trace-handling.md) | Malformed Trace Handling | Accepted |
| [ADR-0008](0008-browser-local-processing.md) | Browser-Local Processing & Privacy | Accepted |
| [ADR-0009](0009-protocol-extensibility.md) | Future Protocol-Version Extensibility | Accepted |
| [ADR-0010](0010-single-package-consolidation.md) | Single Package Consolidation | Accepted |

## Format

Expand Down
Loading
Loading