Name the script for what it does, now that it serves two providers
`link-polyfill.ts` handled one provider. It now handles two through a registry, one of which is not a polyfill, so both the filename and the `link:` verb said something false — and a name that is short but wrong misleads more than an opaque one would. It becomes `overlay-local-checkout.ts`, which is the operation: it copy-overlays a local package checkout into node_modules for development. "link" also implied a symlink, which is precisely what the script exists NOT to do — its own header spends a paragraph on why. No behaviour changed: same registry, same copy, same `--once`, same watch loop, same assertion. Both providers exercised afterwards, each reporting the singletons it must preserve — one package for the data layer, two for the indexing package, whose own checkout carries `file:` links and would otherwise smuggle in a second verifier. Seven references repaired by rewriting the sentence that carried them rather than swapping a path, across the script, `package.json`, `.env.example` and four doctrine leaves. No compatibility alias left behind: an old name kept "just in case" would restore exactly the ambiguity being removed.
This commit is contained in:
@@ -1,8 +0,0 @@
|
||||
# Doc-debt — tech-stack
|
||||
|
||||
> Presence of a block = doc to update. Processed → delete the block; no blocks left → delete this file.
|
||||
> One block = one "big change": `why` + `files` + `verify` (leaves to review).
|
||||
|
||||
## Raw markers (consolidate into blocks, then delete)
|
||||
- TOUCHED package.json @2026-08-17 (session 0b064e8b-1717-421f-a20e-a4318ad217b1)
|
||||
- TOUCHED scripts/link-polyfill.ts @2026-08-17 (session 0b064e8b-1717-421f-a20e-a4318ad217b1)
|
||||
@@ -6,7 +6,7 @@ last_checked: 2026-08-16
|
||||
|
||||
# Pitfall: refreshing the data-layer package never reaches a running dev server, not even across a rebuild
|
||||
|
||||
`pnpm run link:polyfill` overlays the local package into `node_modules/@ng-eventually/polyfill/` as real files, and keeps them current. **That is all it does.** A `bun run dev` already running goes on serving the package it loaded at startup, however many times the overlay is rewritten underneath it, and however many rebuilds happen in between.
|
||||
`pnpm run overlay:polyfill` (or `overlay:indexing`, for the other provider) overlays the local checkout into `node_modules/<package>/` as real files, and keeps them current. **That is all it does.** A `bun run dev` already running goes on serving the package it loaded at startup, however many times the overlay is rewritten underneath it, and however many rebuilds happen in between.
|
||||
|
||||
**VERIFIED, controlled sandbox test with this project's own bun.** A dependency resolving to copy A, overlaid with copy B: the running server still serves A at +3 s and +13 s after the overlay. An edit to **application source** then triggers a genuine rebuild — a new bundle hash confirms it — and the rebuilt bundle **still serves A**. Only a restart serves B. So the mechanism is not "the watcher never fires because `node_modules` is excluded" — a rebuild the watcher DOES trigger still carries the stale dependency forward; the server's resolution of that import is pinned at process start, and a rebuild does not re-resolve it.
|
||||
|
||||
@@ -18,7 +18,7 @@ VERIFIED 2026-08-16, and it cost about an hour. A defect had been fixed on the p
|
||||
|
||||
The dev server had been running for **six days**. It predated the package rename and the whole migration, and it was serving code from before the fix. The browser was running a different application from the one under test.
|
||||
|
||||
Two things made it hard to see. The failure mode is **silence** — nothing warns that the served code is old. And `scripts/link-polyfill.ts` explicitly promised the opposite, that `bun --hot` would reload the copied file live; that claim is now corrected in the script, but a reader who trusted it would rule out the true cause first, which is exactly what happened.
|
||||
Two things made it hard to see. The failure mode is **silence** — nothing warns that the served code is old. And `scripts/overlay-local-checkout.ts` explicitly promised the opposite, that `bun --hot` would reload the copied file live; that claim is now corrected in the script, but a reader who trusted it would rule out the true cause first, which is exactly what happened.
|
||||
|
||||
## The reflex to build
|
||||
|
||||
|
||||
@@ -58,4 +58,4 @@ A `Dockerfile` exists (multi-stage Bun Alpine). **Installation goes through pnpm
|
||||
|
||||
`bun run dev` = **`portless festipod bun --hot src/index.ts`** — it goes through the **`portless`** wrapper (an external port-management tool), not a bare `bun --hot`. HMR is active outside production.
|
||||
|
||||
**Reactive local link to the SDK**: in production the `@ng-eventually/polyfill` dependency comes from Gitea (git+https, pinned by `pnpm-lock.yaml`). When the provider's package has to be exercised from a local checkout, `pnpm run link:polyfill` (script `scripts/link-polyfill.ts`) replaces `node_modules/@ng-eventually/polyfill` with a **real copy** of that checkout (location overridable with `NG_EVENTUALLY_LOCAL`) — **without** its own `node_modules/@ng-org` — and resyncs on every edit. Copying rather than symlinking is what keeps **a single `@ng-org/*` instance** installed: a symlink would drag in a second one and the SDK would stop working. To go back to the committed state: `pnpm install`.
|
||||
**Reactive local overlay for the SDK**: in production the `@ng-eventually/polyfill` dependency comes from Gitea (git+https, pinned by `pnpm-lock.yaml`), and `@ng-helpers/indexing` likewise. When a provider's package has to be exercised from a local checkout, `pnpm run overlay:polyfill` or `pnpm run overlay:indexing` (script `scripts/overlay-local-checkout.ts`, one provider per run) replaces `node_modules/<package>` with a **real copy** of that checkout (location overridable with `NG_EVENTUALLY_LOCAL` / `NG_HELPERS_LOCAL`) — **without** its own `node_modules/*` — and resyncs on every edit. Copying rather than symlinking is what keeps a **single instance** of every package the provider shares with Festipod installed (`@ng-org/*`, and for `indexing`, `@ng-eventually/polyfill` itself): a symlink would drag in a second one and the SDK would stop working. To go back to the committed state: `pnpm install`.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
type: knowledge
|
||||
summary: Stack components (Bun runtime/build/test, install through pnpm, React, NextGraph, Storybook, Cucumber, Tailwind-inside-the-build) and the real list of package.json scripts, quirks included (cucumber through node+tsx, link:polyfill for the reactive local link)
|
||||
summary: Stack components (Bun runtime/build/test, install through pnpm, React, NextGraph, Storybook, Cucumber, Tailwind-inside-the-build) and the real list of package.json scripts, quirks included (cucumber through node+tsx, overlay:polyfill/overlay:indexing for the reactive local overlay)
|
||||
---
|
||||
|
||||
# Stack & commands
|
||||
@@ -33,7 +33,7 @@ summary: Stack components (Bun runtime/build/test, install through pnpm, React,
|
||||
| `steps:extract` | `bun scripts/extract-step-definitions.ts` |
|
||||
| `build:orm` | `rdf-orm build --input ./src/shared/shapes/shex --output ./src/shared/shapes/orm` |
|
||||
| `build:ng` | `bash scripts/build-ng-packages.sh` — (re)builds the NextGraph packages from a local source (optional tool) |
|
||||
| `link:polyfill` | `bun scripts/link-polyfill.ts` — **reactive** local link to `@ng-eventually/polyfill` (copy-overlay + watcher). Details in [[knowledge_deployment]]. |
|
||||
| `overlay:polyfill` / `overlay:indexing` | `bun scripts/overlay-local-checkout.ts <provider>` — **reactive** local overlay of a provider's checkout (`@ng-eventually/polyfill` or `@ng-helpers/indexing`; copy-overlay + watcher, `--once` for a single pass). Details in [[knowledge_deployment]]. |
|
||||
| `storybook` / `build-storybook` | Storybook dev (6006) / static build |
|
||||
|
||||
## Pitfalls
|
||||
|
||||
@@ -30,7 +30,7 @@ API details: [[knowledge_bun-apis]].
|
||||
|
||||
**Dependencies are installed with `pnpm install`, not `bun install`.** Everything else stays on Bun: **runtime, build, test, scripts** (`bun run dev`, `bun build`, `bun test`, `bunx`). Only the installation step changes package manager.
|
||||
|
||||
**Why.** The data SDK is installed from a Gitea repository as a **subdirectory** git dependency: `git+https://…/ng-eventually.git#main&path:/packages/polyfill`. pnpm (≥ 10.26) resolves that `#<ref>&path:/…` format and guarantees a **single** instance of `@ng-org/*`; `bun install` does not handle this workflow cleanly. The reference lockfile is therefore `pnpm-lock.yaml`, and the reactive local link goes through `pnpm run link:polyfill` (see [[knowledge_deployment]]).
|
||||
**Why.** The data SDK is installed from a Gitea repository as a **subdirectory** git dependency: `git+https://…/ng-eventually.git#main&path:/packages/polyfill`. pnpm (≥ 10.26) resolves that `#<ref>&path:/…` format and guarantees a **single** instance of `@ng-org/*`; `bun install` does not handle this workflow cleanly. The reference lockfile is therefore `pnpm-lock.yaml`, and the reactive local overlay goes through `pnpm run overlay:polyfill` (`overlay:indexing` for the other provider; see [[knowledge_deployment]]).
|
||||
|
||||
**Practical consequence.** npm scripts that relied on `node_modules/.bin/*` may break (pnpm puts shell shims there, not JS entries) — call the package's actual JS entry (e.g. `node_modules/@cucumber/cucumber/bin/cucumber.js`) rather than the `.bin/` shim.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user