Skip to content

Rewrite @nyuchi/nyuchi-docs-search from Svelte to Astro + TypeScript #68

Description

@bryanfawcett

The rule

Per the framework doctrine (nyuchi/mzizi#269): the UI is Astro, underneath is
Rust first and TypeScript second, and there is no third UI framework — not
Svelte, not React, not Vue.

This package is one of only two surfaces in the estate still carrying Svelte.
mzizi.dev itself has zero .svelte files.

What has to change

@nyuchi/nyuchi-docs-search is the ⌘K search modal — Pagefind keyword search
plus an Ask-AI tab. Four Svelte components:

  • SearchModal.svelte
  • SearchResults.svelte
  • AiChat.svelte
  • plus the Search.astro Starlight override that mounts them

The non-UI half is already TypeScript and stays: lib/ai-client.ts (the SSE
client) and lib/pagefind.ts.

Why this is not a small change

It is a published package with external consumers. It ships to npm and is
consumed by bundu-labs/bundu-docs for docs.bundu.org — that shared
consumption is the stated reason this monorepo exists. Dropping the Svelte peer
dependency and changing the component entry points is a breaking change for
that consumer, so it needs a major version and a coordinated update, not a
silent swap.

The exports map is part of the contract too: ., ./plugin,
./SearchModal.svelte, ./Search.astro. Two of those name Svelte explicitly.

Starlight's Search component override is the mount point. Whatever
replaces the Svelte components has to satisfy the same override contract, and
the modal is genuinely interactive — keyboard navigation, focus trapping,
streaming SSE responses. Astro islands can do this, but "an Astro component with
a <script>" is not a drop-in for a Svelte component with reactive state; the
state management has to be rewritten rather than ported.

Knock-on

site/package.json also declares svelte — only to render this modal. Once the
package is Svelte-free, that dependency and the @astrojs/svelte integration
come out of the site too, which is the actual prize: docs.nyuchi.com builds
with no component framework at all.

Pre-existing defects to fix on the way through

Found while wiring up vp check (#67). Both are latent because this package
has never had a typecheck scriptbuild is svelte-package && publint:

  1. tsconfig.json sets types: ["vitest/globals", "@testing-library/jest-dom"].
    Neither entry point exists any more — Vitest 4 dropped globals.d.ts, jest-dom
    7 removed its root types entry, and tsc reports TS2688 for both. They are
    also redundant: the tests import from "vitest" explicitly and
    tests/setup.ts already uses import "@testing-library/jest-dom/vitest".
    Deleting the types array is the whole fix.
  2. svelte-check reports 2 errors: tests/manifest.test.ts asserts
    dependencies on a package.json that only has devDependencies, and
    vitest.config.ts passes a hot option Vitest 4 no longer accepts.

Fixing (1) and (2) is worth doing independently and immediately — they are small,
and they make the package type-checkable for the first time, which will matter a
great deal during the rewrite.

Acceptance

  • No .svelte files in the package
  • svelte gone from its package.json and from site/package.json
  • exports map has no Svelte entries; major version bumped
  • bundu-labs/bundu-docs updated in the same window
  • vp check runs with typeCheck: true (it is currently false precisely
    because tsgolint cannot resolve .svelte modules)
  • ⌘K, arrow-key navigation, focus trap and SSE streaming all still work

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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