Promenade in fifteen minutes
The data path
Section titled “The data path”File → File.slice() stream → incremental parser → Arrow batches → DuckDB-wasm → COPY … TO Parquet (zstd) → browser file systemNothing reads the whole file into memory. The parser is incremental, results land in a real columnar engine, and artifacts persist as compressed Parquet — measured at roughly 45:1 against OCEL JSON, and 28:1 against XES.
DuckDB itself is ephemeral: on start, the Parquet files are registered as views. Nothing is copied and nothing is decoded, which is why reopening a workspace is fast regardless of its size.
Artifacts and provenance
Section titled “Artifacts and provenance”An artifact is a reference plus metadata — never its contents in the JS heap. A log, a discovered model, an alignment result and a filtered log are all artifacts of different types.
Provenance is a DAG, not a chain. An execution node records:
inputsasRecord<role, ArtifactId[]>— multi-input is first class, which is what conformance needs (a log and a model),outputsas a list — multi-output is first class too,- the parameters used,
- the runtime and version that executed it.
The practical consequence: re-running with one parameter changed produces a sibling artifact rather than overwriting, so a parameter sweep leaves a comparable set of results with their settings attached rather than a folder of ambiguous exports.
Types you will recognize
Section titled “Types you will recognize”EventLog, OcelLog, DirectlyFollowsGraph, ProcessTree, AcceptingPetriNet (net plus initial and final marking, as one object), CausalNet, AlignmentSet, ObjectCentricPetriNet, ObjectCentricProcessTree, OCDFG, TotemModel.
Actions declare the types they consume and produce, so the application knows which plugin can act on which artifact without either side knowing about the other.
The single data door
Section titled “The single data door”A plugin does not receive the log. It queries it, through a read-only SQL interface (host.sql()), or through the engine-independent relational API for plugins that would rather express a query as a contract than as DuckDB text.
This is the boundary that makes the rest work: because data access is one narrow, auditable interface, the same plugin binary can execute against an in-browser DuckDB or against an engine holding a terabyte, with no change to the plugin.
Vocabulary map
Section titled “Vocabulary map”If you have worked with desktop research toolkits or with Python process-mining libraries, the translation is short:
| What you call it | Here |
|---|---|
| Workspace of loaded objects | The artifact tree, with a provenance DAG behind it |
| A plugin, installed into the tool | A signed .pmplugin bundle, installed from a registry |
| A visualiser | A view plugin, rendering in a sandboxed iframe |
| A Python analysis script | A Pyodide plugin — the library runs unmodified, in the page |
| A DataFrame handed to an algorithm | A read-only SQL view over the log |
| Running on a bigger machine | Pointing the workspace at another engine |