Skip to content

fix(release): inline bundled assets as string modules so JSR publish accepts them#139

Merged
rickylabs merged 1 commit into
mainfrom
fix/publish-text-imports-as-strings
Jun 26, 2026
Merged

fix(release): inline bundled assets as string modules so JSR publish accepts them#139
rickylabs merged 1 commit into
mainfrom
fix/publish-text-imports-as-strings

Conversation

@rickylabs

Copy link
Copy Markdown
Owner

Fix partial publish of v0.0.1-alpha.5 — inline bundled assets as string modules

The v0.0.1-alpha.5 whole-workspace JSR publish partial-failed: 23 of 31 members published, but @netscript/fresh-ui and @netscript/plugin were rejected and 6 dependents (incl. @netscript/cli) were skipped:

failed to build module graph: The import attribute type of 'text' is unsupported

Root cause — a deno publish defect, not a config gap

The bundled-asset barrels embedded each asset via a with { type: 'text' } import attribute. The deno publish module-graph build (the deno_graph crate) never sets unstable_text_imports, so it rejects text-attribute imports — even though text imports are otherwise stable and pass deno check, deno info, and deno publish --dry-run.

There is no flag or deno.json lever that force-enables it on the publish path:

  • Text imports are stable, so there is deliberately no CLI flag for them.
  • --unstable-raw-imports only toggles the separate bytes feature, which this workspace does not use. The flag added in a prior attempt was a no-op for the text error and is reverted here.
  • deno publish --dry-run does not enforce the restriction, so publish:dry-run stayed green while the real publish failed — a true dry-run blind spot.

Fix

The assets-barrel generator now inlines each asset's content as a plain string constant:

const template_000 = ".ns-alert { ... }";   // was: import template_000 from '...' with { type: 'text' }
  • The three generated barrels keep their exact export shapesEMBEDDED_TEMPLATE_CONTENT, PLUGIN_SKELETON_TEMPLATE_CONTENT, FRESH_UI_REGISTRY_CONTENT (Record<…, string>) — so every consumer is unchanged and the runtime asset-read path is identical.
  • Plain string constants carry no import attribute, so the publish graph builder has nothing to reject.
  • The generator pipes its rendered output through deno fmt before writing, so the committed barrels are already fmt-canonical — check:assets-barrel (regen + git diff --exit-code) and fmt:check stay byte-stable.
  • Removes the now-dead raw-imports from the workspace-root unstable list (no bytes imports exist repo-wide; text imports are stable).

Gates (all green)

Gate Result
check:assets-barrel exit 0 (deterministic regen)
deno task check 0 findings / 1735 files
deno task lint 0 occurrences
deno task fmt:check 0 findings
fresh-ui barrel + consumer deno check exit 0
asset consumer unit tests 5/5 (incl. "reads embedded content without hydration", "no direct Deno.read")

Why re-publish is safe

deno publish skips versions already on the registry, so re-running after the partial publish is idempotent — the 23 already-published members are skipped; only fresh-ui, plugin, cli, and the 6 skipped dependents publish at alpha.5.

Follow-ups (tracked)

🤖 Generated with Claude Code

…accepts them

The v0.0.1-alpha.5 whole-workspace publish partial-failed: @netscript/fresh-ui
and @netscript/plugin were rejected with "The import attribute type of 'text'
is unsupported", which also skipped @netscript/cli and 5 other dependents
(23 of 31 members published).

Root cause is a deno publish defect, not a config gap. The publish module-graph
build (deno_graph crate) never sets unstable_text_imports, so it rejects
`with { type: 'text' }` import attributes even though text imports are otherwise
stable and pass deno check / deno info / deno publish --dry-run. No CLI flag or
deno.json lever force-enables it on the publish path: text imports are stable
(so there is deliberately no flag), and --unstable-raw-imports only toggles the
separate `bytes` feature, which this workspace does not use. The flag added in a
prior attempt was therefore a no-op for the text error and is reverted here.

Fix: the assets-barrel generator now inlines each asset's content as a plain
string constant (`const template_NNN = "...";`) instead of importing it via
`with { type: 'text' }`. The three generated barrels keep their exact export
shapes (EMBEDDED_TEMPLATE_CONTENT, PLUGIN_SKELETON_TEMPLATE_CONTENT,
FRESH_UI_REGISTRY_CONTENT as Record<..., string>), so every consumer is
unchanged and the runtime asset-read path is identical. Plain string constants
carry no import attribute, so the publish graph builder has nothing to reject.

To keep determinism and formatting green, the generator pipes its rendered
output through `deno fmt` before writing, so the committed barrels are already
fmt-canonical: check:assets-barrel (regen + git diff --exit-code) and fmt:check
both stay byte-stable.

Also removes the now-dead `raw-imports` entry from the workspace-root unstable
list (no bytes imports exist repo-wide and text imports are stable).

Gates: check:assets-barrel exit 0 (deterministic), deno task check 0 findings
(1735 files), lint 0, fmt:check 0 findings, fresh-ui barrel+consumer type-check
exit 0, asset consumer unit tests 5/5 (including "reads embedded content without
hydration" and "no direct Deno.read").

Follow-up: deno publish --dry-run is a blind spot for this failure class (it
tolerates text imports the real publish rejects); a real-publish-equivalent
preflight is tracked under the deterministic JSR release/publish e2e (#114). An
upstream deno issue for the publish-graph unstable_text_imports gap will be filed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014gW4zfhMMQU6txC828ijct
@rickylabs
rickylabs merged commit 16abc86 into main Jun 26, 2026
6 checks passed
@rickylabs
rickylabs deleted the fix/publish-text-imports-as-strings branch June 26, 2026 17:03
rickylabs added a commit that referenced this pull request Jun 26, 2026
…to 0.0.1-alpha.6 (#142)

Revert the #139 string-const asset embedding and return to `with { type: 'text' }`
imports in the generated barrels (cli/fresh-ui/plugin) — text imports keep the
asset content in the module graph so it resolves over https from JSR, and are the
cleaner mechanism. They are runtime-stable in Deno 2.8+ and the real publish-graph
build accepts them (verified locally and in CI on Deno 2.9.0).

The #141 publish preflight is kept: it runs the real `deno publish` graph build
(no upload) before the Publish step, so if the text-import graph build is ever
rejected the job reds before any upload — no half-publish. The alpha.5 text-import
rejection was not reproducible locally or in CI on the same Deno 2.9.0.

Bump 0.0.1-alpha.5 -> 0.0.1-alpha.6 across all workspace members, the root
deno.json, and the deno.lock @netscript range mirror.

Gates: check:assets-barrel (deterministic regen) PASS; local publish preflight
(real graph build over all 31 members incl. fresh-ui + plugin text imports) PASS.


Claude-Session: https://claude.ai/code/session_014gW4zfhMMQU6txC828ijct

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
rickylabs added a commit that referenced this pull request Jun 26, 2026
… embedding (#143)

* Revert "chore(release): restore text-import asset embedding + bump workspace to 0.0.1-alpha.6 (#142)"

This reverts commit 571cef9.

* chore(release): bump workspace to 0.0.1-alpha.7

Recovery release for the alpha.6 half-publish. The alpha.6 authenticated
`deno publish` rejected `@netscript/fresh-ui` and `@netscript/plugin` with
"The import attribute type of 'text' is unsupported", leaving 23/31 members
live at alpha.6.

Root cause now understood: `deno publish` validates the bearer token BEFORE
building each member's publish-tarball graph, so neither `--dry-run` (looser
local graph) nor the invalid-token preflight (short-circuits at auth) exercises
the strict authenticated graph build that rejects `with { type: 'text' }`. Only
the real authenticated publish builds it — which is why the failure looked
"non-reproducible". It reproduces 100% in the authenticated publish.

This release reverts to the #139 string-const asset embedding (no import
attributes -> nothing for the publish graph to reject) and bumps every member,
the root deno.json, and the deno.lock @netscript range mirror 0.0.1-alpha.5 ->
0.0.1-alpha.7 to publish all 31 members cleanly at one consistent version.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014gW4zfhMMQU6txC828ijct

---------

Co-authored-by: Claude Opus 4.8 <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