feat: libs 0005 — standalone sends the project header on lib requests (project-scoped server-side resolution); bump pcbjam-shared
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
fa7984b192
commit
f04915ee1d
4 changed files with 20 additions and 14 deletions
|
|
@ -1 +1 @@
|
||||||
Subproject commit a1d18b53a7b976c219a824800027c289b9e9fe2c
|
Subproject commit df297291b0bdfd0228c900e9c1a0c7279ffd1533
|
||||||
|
|
@ -442,7 +442,7 @@ export function WasmTool({
|
||||||
log: append,
|
log: append,
|
||||||
onStatus: setStatus,
|
onStatus: setStatus,
|
||||||
onAbort: oom.onAbort,
|
onAbort: oom.onAbort,
|
||||||
libsSource: libsSourceConfig(),
|
libsSource: libsSourceConfig(projectId),
|
||||||
});
|
});
|
||||||
// Register the save sink before the file opens: from here on, every
|
// Register the save sink before the file opens: from here on, every
|
||||||
// editor File→Save (MEMFS write) is routed onward through saveBytes.
|
// editor File→Save (MEMFS write) is routed onward through saveBytes.
|
||||||
|
|
|
||||||
|
|
@ -69,14 +69,14 @@ export function libsOwner(): string {
|
||||||
return import.meta.env.VITE_LIBS_OWNER ?? "local-user";
|
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 kind = import.meta.env.VITE_LIBS_SOURCE ?? "remote";
|
||||||
const base =
|
const base =
|
||||||
kind === "off"
|
kind === "off"
|
||||||
? null
|
? null
|
||||||
: kind === "static"
|
: kind === "static"
|
||||||
? staticLibsSource()
|
? 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
|
// 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
|
// editor save path works with no backend (a dev/test aid). The real remote
|
||||||
|
|
|
||||||
|
|
@ -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 { initClient } from "@ts-rest/core";
|
||||||
import type { LibInfo, LibItemInfo, LibsSource } from "./source";
|
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
|
* server, or the GPL example backend). Read list ops go through the ts-rest
|
||||||
* client; item bodies stream from the raw text route
|
* client; item bodies stream from the raw text route
|
||||||
* `GET /api/libs/:lib/items/:kind/:name`, and writes hit the symmetric
|
* `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
|
* `PUT` route (binary/text doesn't round-trip ts-rest). Every request carries
|
||||||
* on every request via `OWNER_HEADER` (thin per-user; absent ⇒ backend default).
|
* 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 {
|
export function remoteLibsSource(
|
||||||
const ownerHeaders: Record<string, string> = owner
|
apiBase: string,
|
||||||
? { [OWNER_HEADER]: owner }
|
owner?: string,
|
||||||
: {};
|
project?: string,
|
||||||
|
): LibsSource {
|
||||||
|
const reqHeaders: Record<string, string> = {
|
||||||
|
...(owner ? { [OWNER_HEADER]: owner } : {}),
|
||||||
|
...(project ? { [PROJECT_HEADER]: project } : {}),
|
||||||
|
};
|
||||||
const client = initClient(contract, {
|
const client = initClient(contract, {
|
||||||
baseUrl: apiBase,
|
baseUrl: apiBase,
|
||||||
baseHeaders: ownerHeaders,
|
baseHeaders: reqHeaders,
|
||||||
});
|
});
|
||||||
|
|
||||||
const itemUrl = (libId: string, kind: string, name: string) =>
|
const itemUrl = (libId: string, kind: string, name: string) =>
|
||||||
|
|
@ -47,7 +53,7 @@ export function remoteLibsSource(apiBase: string, owner?: string): LibsSource {
|
||||||
name: string,
|
name: string,
|
||||||
): Promise<string | null> {
|
): Promise<string | null> {
|
||||||
const res = await fetch(itemUrl(libId, kind, name), {
|
const res = await fetch(itemUrl(libId, kind, name), {
|
||||||
headers: ownerHeaders,
|
headers: reqHeaders,
|
||||||
});
|
});
|
||||||
if (!res.ok) return null;
|
if (!res.ok) return null;
|
||||||
return await res.text();
|
return await res.text();
|
||||||
|
|
@ -61,7 +67,7 @@ export function remoteLibsSource(apiBase: string, owner?: string): LibsSource {
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const res = await fetch(itemUrl(libId, kind, name), {
|
const res = await fetch(itemUrl(libId, kind, name), {
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
headers: { ...ownerHeaders, "Content-Type": "text/plain; charset=utf-8" },
|
headers: { ...reqHeaders, "Content-Type": "text/plain; charset=utf-8" },
|
||||||
body,
|
body,
|
||||||
});
|
});
|
||||||
return res.ok;
|
return res.ok;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue