From f04915ee1de95a6d46b9ae5226976a0ea1f97ca5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerg=C5=91=20T=C3=B6rcsv=C3=A1ri?= Date: Sat, 13 Jun 2026 17:16:40 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20libs=200005=20=E2=80=94=20standalone=20?= =?UTF-8?q?sends=20the=20project=20header=20on=20lib=20requests=20(project?= =?UTF-8?q?-scoped=20server-side=20resolution);=20bump=20pcbjam-shared?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) --- web/pcbjam-shared | 2 +- web/standalone/src/components/WasmTool.tsx | 2 +- web/standalone/src/lib/config.ts | 4 +-- web/standalone/src/wasm/libs/remote-source.ts | 26 ++++++++++++------- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/web/pcbjam-shared b/web/pcbjam-shared index a1d18b5..df29729 160000 --- a/web/pcbjam-shared +++ b/web/pcbjam-shared @@ -1 +1 @@ -Subproject commit a1d18b53a7b976c219a824800027c289b9e9fe2c +Subproject commit df297291b0bdfd0228c900e9c1a0c7279ffd1533 diff --git a/web/standalone/src/components/WasmTool.tsx b/web/standalone/src/components/WasmTool.tsx index 0c7e0e5..c7d78fb 100644 --- a/web/standalone/src/components/WasmTool.tsx +++ b/web/standalone/src/components/WasmTool.tsx @@ -442,7 +442,7 @@ export function WasmTool({ log: append, onStatus: setStatus, onAbort: oom.onAbort, - libsSource: libsSourceConfig(), + libsSource: libsSourceConfig(projectId), }); // Register the save sink before the file opens: from here on, every // editor File→Save (MEMFS write) is routed onward through saveBytes. diff --git a/web/standalone/src/lib/config.ts b/web/standalone/src/lib/config.ts index 2190441..9a2acb6 100644 --- a/web/standalone/src/lib/config.ts +++ b/web/standalone/src/lib/config.ts @@ -69,14 +69,14 @@ export function libsOwner(): string { return import.meta.env.VITE_LIBS_OWNER ?? "local-user"; } -export function libsSourceConfig(): LibsSource | null { +export function libsSourceConfig(projectId?: string): LibsSource | null { const kind = import.meta.env.VITE_LIBS_SOURCE ?? "remote"; const base = kind === "off" ? null : kind === "static" ? staticLibsSource() - : remoteLibsSource(API_BASE_URL, libsOwner()); + : remoteLibsSource(API_BASE_URL, libsOwner(), projectId); // 0004-A spike: `?libwrite=1` adds one in-memory writable user lib so the // editor save path works with no backend (a dev/test aid). The real remote diff --git a/web/standalone/src/wasm/libs/remote-source.ts b/web/standalone/src/wasm/libs/remote-source.ts index 66a673c..a467286 100644 --- a/web/standalone/src/wasm/libs/remote-source.ts +++ b/web/standalone/src/wasm/libs/remote-source.ts @@ -1,4 +1,4 @@ -import { contract, OWNER_HEADER } from "@pcbjam/shared"; +import { contract, OWNER_HEADER, PROJECT_HEADER } from "@pcbjam/shared"; import { initClient } from "@ts-rest/core"; import type { LibInfo, LibItemInfo, LibsSource } from "./source"; @@ -7,16 +7,22 @@ import type { LibInfo, LibItemInfo, LibsSource } from "./source"; * server, or the GPL example backend). Read list ops go through the ts-rest * client; item bodies stream from the raw text route * `GET /api/libs/:lib/items/:kind/:name`, and writes hit the symmetric - * `PUT` route (binary/text doesn't round-trip ts-rest). The `owner` is carried - * on every request via `OWNER_HEADER` (thin per-user; absent ⇒ backend default). + * `PUT` route (binary/text doesn't round-trip ts-rest). Every request carries + * the `owner` (thin per-user) and the `project` (project-scoped server-side + * resolution) via `OWNER_HEADER`/`PROJECT_HEADER`; absent ⇒ backend default. */ -export function remoteLibsSource(apiBase: string, owner?: string): LibsSource { - const ownerHeaders: Record = owner - ? { [OWNER_HEADER]: owner } - : {}; +export function remoteLibsSource( + apiBase: string, + owner?: string, + project?: string, +): LibsSource { + const reqHeaders: Record = { + ...(owner ? { [OWNER_HEADER]: owner } : {}), + ...(project ? { [PROJECT_HEADER]: project } : {}), + }; const client = initClient(contract, { baseUrl: apiBase, - baseHeaders: ownerHeaders, + baseHeaders: reqHeaders, }); const itemUrl = (libId: string, kind: string, name: string) => @@ -47,7 +53,7 @@ export function remoteLibsSource(apiBase: string, owner?: string): LibsSource { name: string, ): Promise { const res = await fetch(itemUrl(libId, kind, name), { - headers: ownerHeaders, + headers: reqHeaders, }); if (!res.ok) return null; return await res.text(); @@ -61,7 +67,7 @@ export function remoteLibsSource(apiBase: string, owner?: string): LibsSource { ): Promise { const res = await fetch(itemUrl(libId, kind, name), { method: "PUT", - headers: { ...ownerHeaders, "Content-Type": "text/plain; charset=utf-8" }, + headers: { ...reqHeaders, "Content-Type": "text/plain; charset=utf-8" }, body, }); return res.ok;