Skip to content

Add generic runtime-island package producer (+ carry inline island JS)#262

Merged
chubes4 merged 1 commit into
trunkfrom
cook/runtime-island-package-producer
Jun 28, 2026
Merged

Add generic runtime-island package producer (+ carry inline island JS)#262
chubes4 merged 1 commit into
trunkfrom
cook/runtime-island-package-producer

Conversation

@chubes4

@chubes4 chubes4 commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

What

"Slice 2" of the runtime-island pipeline: a generic, product-neutral producer that packages transformer runtime-island output into a materialization payload a downstream consumer (e.g. SSI's companion-plugin scaffold) can turn into per-block render + scoped JS enqueue. This is the missing piece that lets the 537 script islands be carried as accepted preserved islands rather than dead fallbacks.

Changes (php-transformer)

  • src/ArtifactCompiler/RuntimeIslandPackageBuilder.php (new) — projects compiled-site runtime-island data into a generic envelope blocks-engine/php-transformer/runtime-island-package/v1: { schema, islands[], totals }. Per island: content-addressed id, kind/selector/tag, verbatim markup, preservation reason, disposition (preserve|drop), js_handling (preserve_verbatim|drop — the Feature parity: explicit preserve-vs-rebuild decision per interactive region (verbatim JS only on verbatim markup) #224 encoding), a stable enqueue handle_hint, and scripts[] (external src / inline content, role classification, telemetry droppable). Wired into ArtifactCompiler::compile() next to the existing runtime_islands report.
  • Upstream loss-fix in src/HtmlToBlocks/Diagnostics/FallbackEmitter.phpsafeFallbackHtml() stripped <script> bodies from source_snippet, so inline script islands carried no JS at the island level. captureScriptFallback() now preserves the bounded verbatim inline body on the island (script_body/body_bytes/body_truncated), mirroring template islands. Fixed at the root rather than worked around.

Boundary

Product-neutral — schema, class, fields, and comments carry no SSI/companion-plugin/Studio names. The consumer mapping (generic package → SSI preserved_js/per-block render) stays in SSI as the next slice. (Note: a pre-existing src/ArtifactCompiler/CompanionPluginPayload.php on trunk already carries product names — flagged for separate cleanup, untouched here.)

Verification

  • composer test + composer parity → green, 128 fixtures. New contract fixture + section covering a verbatim-preserved first-party inline island, a dropped telemetry script, and an island carrying both external+inline scripts, plus product-neutrality assertions.

AI assistance

  • AI assistance: Yes
  • Tool(s): Claude Code (Claude Opus 4.8, 1M context)
  • Used for: Design + implementation + tests under human review.

Adds RuntimeIslandPackageBuilder: a generic, product-neutral producer that
projects compiled-site runtime-island metadata into an actionable carry-forward
envelope (schema blocks-engine/php-transformer/runtime-island-package/v1). Per
preserved island it carries a stable id, the verbatim source markup, the
associated script assets (external src + scoped inline JS, resolved against the
artifact), a generic enqueue handle hint, a preserve-vs-rebuild signal, and a
role classification so telemetry/analytics scripts are dropped rather than
carried. Wired into ArtifactCompiler::compile() alongside the existing
runtime_islands report; emitted only when islands exist.

Preserve-vs-rebuild (#224): runtime islands carry verbatim markup, so their JS
may be carried verbatim (js_handling=preserve_verbatim). Transformed regions are
not islands and never reach this package. Telemetry scripts get disposition=drop
and per-script droppable=true.

Upstream fix: inline <script> islands carried no JS because safeFallbackHtml()
strips script bodies from source_snippet. FallbackEmitter::captureScriptFallback
now preserves the bounded verbatim inline body on the script island
(script_body/body_bytes/body_truncated), mirroring how template islands carry
template_body, so inline script islands are no longer lossy.

The package is intentionally product-neutral: it names no consumer, plugin, or
host product. A downstream consumer maps it to its own materialization payload.

Adds a contract fixture (tests/fixtures/contract/runtime-island-package.json)
and contract-test coverage for the three representative island shapes: a
verbatim-preserved first-party inline script island, a dropped telemetry
external script, and a canvas island carrying both an external (materialized)
and an inline script. composer test + composer parity green (128 parity
fixtures).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@chubes4 chubes4 merged commit 976dc3a into trunk Jun 28, 2026
1 check passed
@chubes4 chubes4 deleted the cook/runtime-island-package-producer branch June 28, 2026 01:10
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