Skip to content

Phase 1.4: migrate generators to lower-document consumption#25

Merged
avanelsas merged 1 commit intomainfrom
feature/phase-1-4-lower-document-consumption
May 2, 2026
Merged

Phase 1.4: migrate generators to lower-document consumption#25
avanelsas merged 1 commit intomainfrom
feature/phase-1-4-lower-document-consumption

Conversation

@avanelsas
Copy link
Copy Markdown
Owner

Summary

Lands the final piece of the Hickey-style refactor roadmap (audit

One commit, all four CI gates green, 747 tests passing.

What's in this PR

cljs_project.cljs

  • Top-level generate calls em/lower-document once and threads
    the result as lowered to every per-group generator.
  • generate-db / generate-subs / generate-events / generate-views / generate-core / generate-root-db switch from
    (collect-group-data doc instance-ids all-groups) to (:data g),
    from (template-group? doc g) to (:template? g), from
    (stateful-group? doc g) to (not (:template? g)), and from
    inline (field-owner-index doc all-groups) /
    (name->ns-name-map doc all-groups) to the precomputed
    (:field-owner-ns lowered) / (:name->ns-name lowered).
  • view-context (the data-assembly helper for views) loses its
    per-call template-names set / owner-idx / name->ns
    derivations — all three come off lowered.
  • Five private aliases (collect-group-data, template-group?,
    stateful-group?, field-owner-index, name->ns-name-map)
    deleted — no longer referenced.

vanilla_js plugin

  • plugin/generate calls lower-document once and threads it
    through assert-supported!, emit-app-js, and the four
    emit-group-* helpers.
  • assert-supported! drops its doc parameter and walks
    (:data g) instead of re-deriving via collect-group-data.
  • codegen/emit-group-db / -subs / -events / -views / -app-js
    consume :data / :template? / lowered :field-owner-ns /
    :template-names directly. The internal helper chain
    (field-of-group, step-mutator-expr, step-needs-qualify?,
    uses-qualify?, emit-action, source-field-of-group,
    template-view, stateful-view, template-sub-imports)
    cascades the same simplification — doc / all-groups drop
    out of signatures wherever the lowered data covers them.

Tests

vanilla_js_test's two assert-supported! call sites switch
from (em/detect-groups doc) + the old 2-arg signature to
(em/lower-document doc) + the new 1-arg signature. No other
test changed — the lowered output is byte-identical (same data
just resolved once instead of N times).

What this completes

After this PR, the Hickey-style refactor roadmap (#20 audit) is
fully landed. No outstanding items from that scope.

Test plan

  • clj-kondo --lint src test scripts — 0 errors, 0 warnings
  • cljfmt check — clean
  • npx shadow-cljs compile test — 747 tests, 0 failures, 0 errors
  • npx shadow-cljs release app — 0 warnings
  • Output stays byte-identical — every existing fixture-driven
    substring/regex test passes unchanged.

Related

🤖 Generated with Claude Code

Lands the final piece of the Hickey-style refactor roadmap (audit
+ sub emitters in #20, inspector field-as-data in #21, hiccup
event emitters in #23, hiccup data migration in #24). Every export
plugin's per-group generators now consume the canonical lowered
representation produced once at the entry point — no more
re-deriving group classification, field owners, name→ns maps, or
per-group `:data` inside each generator.

All four CI gates green, 747 tests passing.

## What's in this PR

### cljs_project.cljs

- Top-level `generate` calls `em/lower-document` once and threads
  the result as `lowered` to every per-group generator.
- `generate-db / generate-subs / generate-events / generate-views /
  generate-core / generate-root-db` switch from
  `(collect-group-data doc instance-ids all-groups)` to `(:data g)`,
  from `(template-group? doc g)` to `(:template? g)`, from
  `(stateful-group? doc g)` to `(not (:template? g))`, and from
  inline `(field-owner-index doc all-groups)` /
  `(name->ns-name-map doc all-groups)` to the precomputed
  `(:field-owner-ns lowered)` / `(:name->ns-name lowered)`.
- `view-context` (the data-assembly helper for views) loses its
  per-call `template-names` set / `owner-idx` / `name->ns`
  derivations — all three come off `lowered`.
- Five private aliases (`collect-group-data`, `template-group?`,
  `stateful-group?`, `field-owner-index`, `name->ns-name-map`)
  deleted — no longer referenced.

### vanilla_js plugin

- `plugin/generate` calls `lower-document` once and threads it
  through `assert-supported!`, `emit-app-js`, and the four
  `emit-group-*` helpers.
- `assert-supported!` drops its `doc` parameter and walks
  `(:data g)` instead of re-deriving via `collect-group-data`.
- `codegen/emit-group-db / -subs / -events / -views / -app-js`
  consume `:data` / `:template?` / lowered `:field-owner-ns` /
  `:template-names` directly. The internal helper chain
  (`field-of-group`, `step-mutator-expr`, `step-needs-qualify?`,
  `uses-qualify?`, `emit-action`, `source-field-of-group`,
  `template-view`, `stateful-view`, `template-sub-imports`)
  cascades the same simplification — `doc` / `all-groups` drop
  out of signatures wherever the lowered data covers them.

### Tests

`vanilla_js_test`'s two `assert-supported!` call sites switch
from `(em/detect-groups doc)` + the old 2-arg signature to
`(em/lower-document doc)` + the new 1-arg signature. No other
test changed — the lowered output is byte-identical (same data
just resolved once instead of N times).

## What this completes

After this PR, the Hickey-style refactor roadmap (#20 audit) is
fully landed. No outstanding items.

## Test plan

- [x] `clj-kondo --lint src test scripts` — 0 errors, 0 warnings
- [x] `cljfmt check` — clean
- [x] `npx shadow-cljs compile test` — 747 tests, 0 failures, 0 errors
- [x] `npx shadow-cljs release app` — 0 warnings
- [x] Output stays byte-identical — every existing fixture-driven
      substring/regex test passes unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@avanelsas avanelsas merged commit 4df19df into main May 2, 2026
1 check passed
@avanelsas avanelsas deleted the feature/phase-1-4-lower-document-consumption branch May 2, 2026 18:02
avanelsas added a commit that referenced this pull request May 2, 2026
The four-pillar audit lens that produced PRs #20 / #21 / #23 /
#24 / #25 wasn't actually written down anywhere — the philosophy
section described the pure/effectful split (the structural
enforcement) but not the framework we use to *evaluate* new code
or describe smells. Capture the vocabulary so future reviews can
name what they're objecting to.

## What's in this PR

### New "Design lens (Hickey-style)" section

Drops in right after the Pure / Effectful zone split. Names the
shared vocabulary the audit prompt uses — incidental complexity,
simple vs. easy, complecting, braided — and walks the four
pillars one by one:

1. **De-complecting & orthogonality** — one job per function;
   pull pure transformations out of effectful sites.
2. **Information as data** — plain maps, not totems; generic
   functions on generic data.
3. **Epochal time model** — one atom, calculations isolated
   from actions, no PLOP.
4. **Language over plumbing** — domain logic as composable
   data + small primitives, not bespoke imperative glue.

Each pillar references an existing in-tree exemplar
(`dnd.resolve` planner, `clj-form` + `lower-document`,
`state.cljs` epochal commit, inspector field-as-data) so a
reviewer can read the corresponding code to see what the
pillar looks like in practice.

Closes with an "Audit lens for new work" — four review
questions (complected? data behind a wall? state flowing as
values? DSL or plumbing?) that any non-trivial PR should pass
before it lands.

### Anti-patterns list annotated

Each existing bullet now carries its Hickey-style label —
PLOP, calculation/action complecting, UI/domain complecting,
totem, braided — so a review comment can point at the term
and the matching anti-pattern.

## What's NOT in this PR

The audit's *output format* (Complexity Score / Critical Red
Flags / Refactoring Roadmap) is intentionally not codified.
Those make sense as one-off audit deliverables (PR #20 produced
them), not as standing rules.

## Test plan

Documentation-only — no code touched, no gates run.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@avanelsas avanelsas mentioned this pull request May 2, 2026
4 tasks
avanelsas added a commit that referenced this pull request May 2, 2026
* Release v0.3.0 — minor release with multi-step actions, State
panel, inline binding chip, templates revamp + Hickey-style
export pipeline refactor

Promotes the [Unreleased] section in CHANGELOG.md to a tagged
[0.3.0] — 2026-05-02 entry, adds the standard ### Verified
block, and refreshes the comparison links at the bottom.
package.json's version bumps 0.2.0 → 0.3.0 to match.

This is a minor (not patch) release because PRs #16-#19, #21
add substantial editor surfaces (multi-step actions, live
State panel, inline binding chip, templates panel revamp with
five new starters, inspector field-as-data foundation), and
PRs #20 / #23 / #24 / #25 land the full Hickey-style refactor
of the export pipeline (clj-form data values for every codegen
path; lower-document as the canonical lowered model every
plugin consumes). PRs #15 and #22 fix three reconciler bugs
along the way. Saved project files are unchanged; every export
target stays at parity.

Verified locally:
- 747 tests / 2243 assertions / 0 failures / 0 errors.
- npx shadow-cljs release app — 0 warnings under Closure Advanced.
- clj-kondo --lint src test scripts — 0 errors, 0 warnings.
- cljfmt check — all files formatted.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* CHANGELOG: tighten v0.3.0 entry

Drop the per-PR detail in favour of a brief summary. Each
bullet is one line / one short paragraph; the inline rationales
and namespace-level notes move out of the changelog (commit
messages and PR descriptions are the canonical record for those).

Net: 165 lines of v0.3.0 entry → 60 lines.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant