paged.data — database publishing
The database-publishing plugin — a binding DSL, a sync engine, record-flow pagination, and batch automation over DuckDB-WASM, publishing datasets other plugins can consume.
In short paged.data turns data into pages — a binding-expression DSL, a
resolution/sync engine, record-flow lowering with grouping and per-group footers,
and end-to-end print automation, all over a vendored DuckDB-WASM. It also
publishes governed datasets that other plugins (e.g.
paged.sheet) consume.
What it does
- A publishing-grammar binding DSL (53 registry-driven functions) and a binding/sync engine (Linked / Pinned / Overridden / Stale states).
- Record flow / pagination: nested grouping, multi-level per-group footers, parent-path on spill.
- Print automation: per-record / per-group / one-catalog batch plans, plus a CLI and a sandboxed Boa scripting path.
- A data-provider contract: register as a provider and publish a record set without knowing its consumers; governed extracts with column metadata.
- In development: InDesign Data Merge (planning, merging and export as a Data Merge template), a SQL query panel over DuckDB, local JSON, Parquet and XLSX sources, row diffs and sync review, and binding any object property to data (the universal binding round).
How it's built
A Cargo workspace (data-core, data-expr, data-sources, data-query,
data-bind, data-lower, automation crates, data-js) plus a TS bundle, with
DuckDB-WASM vendored behind an Arrow seam.
Capability state
● shipped & verified · ○ shipped, re-test pending · ◍ shipped, untested · ◐ partial · ✗ failing · · planned
Plugin · data 39 features · 100% green
| Feature | Shell | Data |
|---|---|---|
Print automation / batch generation (per-record / per-group / one catalog)data.automation.batch | · | ● |
Barcode / QR symbologies — clean-room EAN-13/UPC-A, Code-128, QR encoders + binding + VECTOR lowering (§9.7)data.barcode.symbology | ● | |
Bindings authoring — first-class add-binding flow in the bindings paneldata.bind.authoring | ● | |
Change-highlighting on refresh — per-binding "what changed since last sync" report (§8)data.bind.change-report | ● | |
Binding + synchronization engine — resolution graph, sync states, identity diffdata.bind.engine | ● | |
Field-mapping wizard — map source columns → variable bindings one-click (§9)data.bind.field-mapping | ● | |
Record-preview stepper — resolve a binding against a chosen record index N (§9)data.bind.preview-step | ● | |
Universal property binding — any host.objects property bound to data, one undo step per apply (ADR 558)data.bind.property | ● | |
Row diff since the document was last written — added, removed and changed rows, and the bindings they reachdata.bind.row-diff | ● | |
Sync states per binding, with pin, unpin and accept-sourcedata.bind.sync-review | ● | |
Variable bindings are custom InDesign text variables; one Set re-bakes every instance (ADR 559, protocol 71)data.bind.text-variables | ● | |
Illustrator-compatible variable-library XML — import + export (§16.4)data.dataset.library-xml | ● | |
Data sets — capture / switch / delete, applied as ONE undo step (§16.4)data.dataset.palette | ● | |
Export as InDesign Data Merge template (native placeholders + UTF-16 data source)data.export.datamerge | ● | |
Binding-expression DSL — lexer, parser, evaluator and function library, registry-driven dispatchdata.expr.engine | ● | |
Governed-extract source (governed tables + optional metadata sidecar -> catalog)data.governed.extract | ◐ | |
Locale-aware display formatting (en/de v1)data.i18n.display | ● | |
Locales as a data table (CLDR values), per-field locale and display patternsdata.i18n.locale-table | ● | |
Placeholder lowering — variable replacement + single-region dynamic tabledata.lower.content | ◐ | |
Data Merge planner — Single and Multiple Records laid out by InDesign's ruledata.lower.merge-plan | ● | |
Data Merge writer — merge the records into the document, matching InDesigndata.lower.merge-writer | ◐ | |
Record flow lowers into text frames on pages added as the flow needs themdata.lower.recordflow-writer | ◐ | |
Re-lowering a table, barcode, record flow or merge updates its content in placedata.lower.relower-in-place | ◐ | |
v43 lowering consumers — in-text variables (D-01), image place (D-14), live record-flow (D-12), rules (D-13)data.lower.v43-consumers | ◐ | |
paged.data's own objects in host.objects — sources, queries, bindings, data sets, variables and typed commandsdata.object-model | ● | |
Performance gates (§12.5) — engine-tier perf assertionsdata.perf.gates | ◐ | |
Bindings live in the document's labels; the session part is a cache; restore from an InDesign re-save (ADR 559)data.persist.labels | ● | |
paged.data bundle (media.paged.data) — manifest + activate + 3 panels + DuckDB query gluedata.plugin.bundle | ◐ | |
The data session is saved with the document and restored on opendata.plugin.persistence | ● | |
Register as an SDK data provider (publish RecordSet to other consumers, e.g. sheets)data.provider.contract | ● | |
Data query panel — SQL with DuckDB diagnostics, filter/sort/group builders, preview griddata.query.panel | ◐ | |
Query engine (DuckDB-WASM) + RecordSet shape/order/hash — the Arrow seamdata.query.seam | ◐ | |
Rule editor — checked condition, firing preview, document style, per-record paragraphsdata.rule.authoring | ● | |
Capability-gated data access + threat model (the suite's largest surface)data.security.gates | ◐ | |
Source adapters (inline + file at M0) + capability/consent gate + visible manifestdata.source.adapters | ◐ | |
D-11 DB attach (SQLite/Postgres/MySQL) + DuckDB-WASM first-class engine + refresh-policy + remotedata.source.db-attach | ◐ | |
Local import of JSON, NDJSON, Parquet and XLSX into DuckDB (data-xlsx for workbooks)data.source.local-formats | ◐ | |
Refresh policies per source — manual, on open, interval (remote, consented), neverdata.source.refresh-policy | ◐ | |
Illustrator "Variables" — the four traits, mapped onto the shipped binding model (§16.4)data.variable.traits | ◐ |
Recent activity
- 2026-10-18README: moved to paged-media/paged (modules/data) [skip ci]c93810b
- 2026-10-17Merge pull request #8 from paged-media/fix/p71-test-timeout11799a6
- 2026-10-17test: the protocol-71 real-stack cases get 30 s each578fa9a
- 2026-10-17Merge pull request #6 from paged-media/fix/gesture-reflowa32b5a2
- 2026-10-17Merge origin/main into fix/gesture-reflow0e59314
- 2026-10-17Merge pull request #7 from paged-media/fix/zip-advisories-calamine1bedaeb
- 2026-10-17deny: ignore the zip extract() advisories for calamine's zip 8 only3892928
- 2026-10-17test: a record flow re-paginates after a handle resize15b0877
paged.sheet — spreadsheets
The spreadsheet plugin — a Rust/WASM calc engine with spill, structured tables, charts, and XLSX round-trip, lowered to native print-grade tables and editable in-frame.
paged.doc — Word documents
The Word plugin — .docx read into native frames and styles, placed into a layout or opened on its own, with byte-level save-back that keeps everything paged did not change.