Skip to content

Upstreaming audit: the path to 'a new jspod-type thing in ~100 LOC on jss' #77

Description

@melvincarvalho

Audit of jspod's ~900 LOC of wrapper code (index.js + lib/) against the jss 0.0.204 surface, toward the goal: a new jspod-type distribution should be buildable as little more than a pages dir + a defaults object + a banner. No code changes proposed here — this is the map. Sequencing is deliberately slow (jspod is in daily use).

A. Already upstream — jspod side now redundant (delegate when comfortable)

  1. Install plumbing (~250 LOC)runInstall, parseAppSpec, loadBundle/resolveBundleSource, install help. jss 0.0.204 ships jss install with the same spec forms (name, org/repo, URL, #ref, =rename), --bundle (JSON-LD, schema:itemListElement), bearer + NIP-98 auth, dual-push. This is Refactor: delegate jspod install to jss install (consolidate install plumbing) #48; its hold conditions (--bundle landed, releases passed) now look satisfied. Keep jspod's policy (bare install → default bundle) as a one-liner.
  2. Token-secret management (~30 LOC) — jss now has its own persisted secret (src/auth/token-secret.js: ~/.jss/token.secret, atomic write, 0600, TOKEN_SECRET env wins). jspod still maintains a parallel implementation at <root>/.token-secret and injects TOKEN_SECRET into the child env. Two secret files on disk, duplicated logic. Caution: existing pods have working <root>/.token-secret files — any consolidation needs a migration story (e.g. upstream a --token-secret-file flag so per-pod scoping survives, then delete jspod's copy).

B. Not in jss — generic wrapper machinery that should go upstream

These are the bits every jspod-type thing would otherwise reimplement (verified absent from jss 0.0.204):

  1. Seed/branding hook — the big one. jss's seedServerRoot() seeds only its own /index.html (skip-if-exists), with no template-override hook; jspod must overwrite pages after boot (seedPodFiles(), 33 LOC + the race it implies). Upstream proposal: --seed-dir <path> (or createServer({seedDir})) taking a directory of pages with an overwrite/skip-if-exists manifest. A distribution then ships pages, not seeding code.
  2. Free-port finding (12 LOC) — jss binds and dies on EADDRINUSE. Upstream --port-retry N (Vite-style shift-up).
  3. Readiness signal (15 LOC of HTTP polling) — no /health endpoint, no structured ready marker on stdout; wrappers must poll. Upstream either a /health route or a machine-readable READY line.
  4. First-run bundle bootstrap (20 LOC) — jspod spawns install --bundle default after first boot. Upstream --bootstrap-bundle <source> on jss start so distros get first-run apps declaratively.
  5. Browser auto-open + TTY/CI/SSH heuristics (24 LOC) — classic dev-server nicety; upstream --open.
  6. In-process start — jss's createServer(options) already covers the full feature set (IdP/git/nostr/MCP in-process), so Embeddable in-process start (no spawn) so jspod can wrap JSS on mobile/single-process runtimes #58 is mostly a jspod-side mapping of jssArgs → options. The one upstream gap: onReady-style hooks aren't reachable by callers, which matters once seeding (item 3) is composable.

C. jspod product identity — stays in the wrapper (what a new distro would swap)

Banner/help (~150 LOC), opinionated defaults (port 5444, me/me, git on), the pages themselves (756 LOC of HTML/ACL), data-browser assets + CDN version pinning (549 LOC), apps/pilot bundle, choice of default bundle, MCP dev tools.

End state

With A delegated and B upstreamed, jspod's lib/start.js collapses to roughly: defaults → map options → createServer()/spawn → done. A new jspod-type thing = jss dep + seed-dir of pages + defaults + banner ≈ 100 LOC.

Suggested order (low risk first)

  1. Upstream items 4, 5, 7 (additive jss flags; jspod unchanged until ready)
  2. Upstream 3 (--seed-dir), then switch jspod to it and delete seedPodFiles()
  3. Upstream 6, switch jspod's bootstrap to the flag
  4. Refactor: delegate jspod install to jss install (consolidate install plumbing) #48 (install delegation) — already specced
  5. Token-secret consolidation (2) — last, needs migration care
  6. Embeddable in-process start (no spawn) so jspod can wrap JSS on mobile/single-process runtimes #58 in-process mode — unlocked by the above

Refs: #48, #58, #60, JSS#464

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions