@visual-platform/next 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters.d.ts +51 -0
- package/dist/adapters.d.ts.map +1 -0
- package/dist/adapters.js +79 -0
- package/dist/adapters.js.map +1 -0
- package/dist/client.d.ts +54 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +114 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +243 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +309 -11
- package/dist/index.js.map +1 -1
- package/dist/sources-entry.d.ts +4 -0
- package/dist/sources-entry.d.ts.map +1 -0
- package/dist/sources-entry.js +4 -0
- package/dist/sources-entry.js.map +1 -0
- package/dist/sources.d.ts +248 -0
- package/dist/sources.d.ts.map +1 -0
- package/dist/sources.js +352 -0
- package/dist/sources.js.map +1 -0
- package/dist/tokens.d.ts +17 -0
- package/dist/tokens.d.ts.map +1 -0
- package/dist/tokens.js +52 -0
- package/dist/tokens.js.map +1 -0
- package/package.json +12 -4
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { SourceResolveArgs } from "./sources.js";
|
|
2
|
+
/**
|
|
3
|
+
* Ready-made `resolve` functions (ADR-048 P5) for common backends — no extra dependencies.
|
|
4
|
+
* products: defineSource({ params, resolve: fromFetch({ url: process.env.CATALOG_URL + "/products", headers: { authorization: `Bearer ${process.env.CATALOG_TOKEN}` } }) })
|
|
5
|
+
* URLs and credentials come from your code/env — never from Studio or the page JSON. Every request
|
|
6
|
+
* gets the source's abort signal (timeout) and is read as JSON with a size cap.
|
|
7
|
+
*/
|
|
8
|
+
type Params = Record<string, unknown>;
|
|
9
|
+
export type FetchSourceOptions<P extends Params> = {
|
|
10
|
+
/** Fixed by you: a string, or built from the validated params. */
|
|
11
|
+
url: string | ((params: P, locale: string) => string);
|
|
12
|
+
method?: "GET" | "POST";
|
|
13
|
+
headers?: Record<string, string> | (() => Record<string, string>);
|
|
14
|
+
/** GET: params become query string (default). POST: JSON body (params + locale). */
|
|
15
|
+
sendParams?: "query" | "body" | "none";
|
|
16
|
+
/** Dot path of the part of the answer to return, e.g. "data.items". */
|
|
17
|
+
select?: string;
|
|
18
|
+
/** Map the answer (after select) to the shape your components expect. */
|
|
19
|
+
map?: (data: unknown, params: P) => unknown;
|
|
20
|
+
};
|
|
21
|
+
export declare function fromFetch<P extends Params = Params>(o: FetchSourceOptions<P>): ({ params, locale, signal }: SourceResolveArgs<P>) => Promise<unknown>;
|
|
22
|
+
export type SanitySourceOptions<P extends Params> = {
|
|
23
|
+
projectId: string;
|
|
24
|
+
dataset: string;
|
|
25
|
+
/** GROQ; params are passed as $variables (plus $locale). Never built from strings. */
|
|
26
|
+
query: string;
|
|
27
|
+
apiVersion?: string;
|
|
28
|
+
/** Read token for private datasets / drafts (server only). */
|
|
29
|
+
token?: string;
|
|
30
|
+
useCdn?: boolean;
|
|
31
|
+
map?: (result: unknown, params: P) => unknown;
|
|
32
|
+
};
|
|
33
|
+
/** Sanity Content Lake (HTTP Query API). */
|
|
34
|
+
export declare function fromSanity<P extends Params = Params>(o: SanitySourceOptions<P>): ({ params, locale, signal }: SourceResolveArgs<P>) => Promise<unknown>;
|
|
35
|
+
export type ContentfulSourceOptions<P extends Params> = {
|
|
36
|
+
space: string;
|
|
37
|
+
environment?: string;
|
|
38
|
+
/** Delivery API token (or Preview API token with preview: true). */
|
|
39
|
+
accessToken: string;
|
|
40
|
+
preview?: boolean;
|
|
41
|
+
contentType: string;
|
|
42
|
+
/** Extra query (e.g. { "fields.slug": params.slug, limit: 10 }), built from validated params. */
|
|
43
|
+
query?: (params: P, locale: string) => Record<string, string | number | boolean | undefined>;
|
|
44
|
+
/** Contentful locale for a page locale (default: same code). */
|
|
45
|
+
locale?: (pageLocale: string) => string;
|
|
46
|
+
map?: (items: Record<string, unknown>[], params: P) => unknown;
|
|
47
|
+
};
|
|
48
|
+
/** Contentful Content Delivery API: entries of one content type, linked assets/entries resolved one level. */
|
|
49
|
+
export declare function fromContentful<P extends Params = Params>(o: ContentfulSourceOptions<P>): ({ params, locale, signal }: SourceResolveArgs<P>) => Promise<unknown>;
|
|
50
|
+
export {};
|
|
51
|
+
//# sourceMappingURL=adapters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapters.d.ts","sourceRoot":"","sources":["../src/adapters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEtD;;;;;GAKG;AACH,KAAK,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAiBtC,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,MAAM,IAAI;IACjD,kEAAkE;IAClE,GAAG,EAAE,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC;IACtD,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAClE,oFAAoF;IACpF,UAAU,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IACvC,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC;CAC7C,CAAC;AAEF,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE,kBAAkB,CAAC,CAAC,CAAC,gCACjC,iBAAiB,CAAC,CAAC,CAAC,sBAe/D;AAED,MAAM,MAAM,mBAAmB,CAAC,CAAC,SAAS,MAAM,IAAI;IAClD,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,sFAAsF;IACtF,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC;CAC/C,CAAC;AAEF,4CAA4C;AAC5C,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE,mBAAmB,CAAC,CAAC,CAAC,gCAEnC,iBAAiB,CAAC,CAAC,CAAC,sBAS/D;AAED,MAAM,MAAM,uBAAuB,CAAC,CAAC,SAAS,MAAM,IAAI;IACtD,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oEAAoE;IACpE,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,iGAAiG;IACjG,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;IAC7F,gEAAgE;IAChE,MAAM,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;IACxC,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC;CAChE,CAAC;AAQF,8GAA8G;AAC9G,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE,uBAAuB,CAAC,CAAC,CAAC,gCAC3C,iBAAiB,CAAC,CAAC,CAAC,sBAkB/D"}
|
package/dist/adapters.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
const MAX_BYTES = 2_000_000;
|
|
2
|
+
async function readJson(res, what) {
|
|
3
|
+
if (!res.ok)
|
|
4
|
+
throw new Error(`${what} answered ${res.status}`);
|
|
5
|
+
const text = await res.text();
|
|
6
|
+
if (text.length > MAX_BYTES)
|
|
7
|
+
throw new Error(`${what} answered more than 2 MB`);
|
|
8
|
+
return JSON.parse(text);
|
|
9
|
+
}
|
|
10
|
+
const pick = (v, path) => {
|
|
11
|
+
if (!path)
|
|
12
|
+
return v;
|
|
13
|
+
let cur = v;
|
|
14
|
+
for (const seg of path.split("."))
|
|
15
|
+
cur = cur && typeof cur === "object" ? cur[seg] : undefined;
|
|
16
|
+
return cur;
|
|
17
|
+
};
|
|
18
|
+
export function fromFetch(o) {
|
|
19
|
+
return async ({ params, locale, signal }) => {
|
|
20
|
+
const method = o.method ?? "GET";
|
|
21
|
+
const send = o.sendParams ?? (method === "GET" ? "query" : "body");
|
|
22
|
+
let url = typeof o.url === "function" ? o.url(params, locale) : o.url;
|
|
23
|
+
if (send === "query") {
|
|
24
|
+
const u = new URL(url);
|
|
25
|
+
for (const [k, v] of Object.entries(params ?? {}))
|
|
26
|
+
if (v !== undefined && v !== null)
|
|
27
|
+
u.searchParams.set(k, String(v));
|
|
28
|
+
if (!u.searchParams.has("locale"))
|
|
29
|
+
u.searchParams.set("locale", locale);
|
|
30
|
+
url = u.toString();
|
|
31
|
+
}
|
|
32
|
+
const headers = { accept: "application/json", ...(typeof o.headers === "function" ? o.headers() : o.headers ?? {}), ...(send === "body" ? { "content-type": "application/json" } : {}) };
|
|
33
|
+
const res = await fetch(url, { method, headers, signal, ...(send === "body" ? { body: JSON.stringify({ ...params, locale }) } : {}), cache: "no-store" });
|
|
34
|
+
const data = pick(await readJson(res, new URL(url).host), o.select);
|
|
35
|
+
return o.map ? o.map(data, params) : data;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/** Sanity Content Lake (HTTP Query API). */
|
|
39
|
+
export function fromSanity(o) {
|
|
40
|
+
if (!/^[a-z0-9]+$/.test(o.projectId) || !/^[a-z0-9_-]+$/.test(o.dataset))
|
|
41
|
+
throw new Error("[visual] fromSanity: invalid projectId or dataset");
|
|
42
|
+
return async ({ params, locale, signal }) => {
|
|
43
|
+
const host = `https://${o.projectId}.${o.useCdn === false || o.token ? "api" : "apicdn"}.sanity.io`;
|
|
44
|
+
const u = new URL(`${host}/v${o.apiVersion ?? "2025-02-19"}/data/query/${o.dataset}`);
|
|
45
|
+
u.searchParams.set("query", o.query);
|
|
46
|
+
for (const [k, v] of Object.entries({ ...params, locale }))
|
|
47
|
+
if (v !== undefined)
|
|
48
|
+
u.searchParams.set(`$${k}`, JSON.stringify(v));
|
|
49
|
+
const res = await fetch(u, { headers: { accept: "application/json", ...(o.token ? { authorization: `Bearer ${o.token}` } : {}) }, signal, cache: "no-store" });
|
|
50
|
+
const result = (await readJson(res, "Sanity")).result;
|
|
51
|
+
return o.map ? o.map(result, params) : result;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/** Contentful Content Delivery API: entries of one content type, linked assets/entries resolved one level. */
|
|
55
|
+
export function fromContentful(o) {
|
|
56
|
+
return async ({ params, locale, signal }) => {
|
|
57
|
+
const u = new URL(`https://${o.preview ? "preview" : "cdn"}.contentful.com/spaces/${encodeURIComponent(o.space)}/environments/${encodeURIComponent(o.environment ?? "master")}/entries`);
|
|
58
|
+
u.searchParams.set("content_type", o.contentType);
|
|
59
|
+
u.searchParams.set("locale", o.locale ? o.locale(locale) : locale);
|
|
60
|
+
for (const [k, v] of Object.entries(o.query?.(params, locale) ?? {}))
|
|
61
|
+
if (v !== undefined)
|
|
62
|
+
u.searchParams.set(k, String(v));
|
|
63
|
+
const res = await fetch(u, { headers: { authorization: `Bearer ${o.accessToken}` }, signal, cache: "no-store" });
|
|
64
|
+
const body = (await readJson(res, "Contentful"));
|
|
65
|
+
const assets = new Map((body.includes?.Asset ?? []).map((a) => [a.sys.id, { url: a.fields.file?.url ? `https:${a.fields.file.url}` : "", alt: a.fields.title ?? "" }]));
|
|
66
|
+
const entries = new Map((body.includes?.Entry ?? []).map((e) => [e.sys.id, { id: e.sys.id, ...e.fields }]));
|
|
67
|
+
const link = (v) => {
|
|
68
|
+
if (Array.isArray(v))
|
|
69
|
+
return v.map(link);
|
|
70
|
+
const s = v?.sys;
|
|
71
|
+
if (s?.type === "Link" && s.id)
|
|
72
|
+
return s.linkType === "Asset" ? assets.get(s.id) ?? null : entries.get(s.id) ?? null;
|
|
73
|
+
return v;
|
|
74
|
+
};
|
|
75
|
+
const items = (body.items ?? []).map((e) => ({ id: e.sys.id, ...Object.fromEntries(Object.entries(e.fields).map(([k, v]) => [k, link(v)])) }));
|
|
76
|
+
return o.map ? o.map(items, params) : items;
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=adapters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapters.js","sourceRoot":"","sources":["../src/adapters.ts"],"names":[],"mappings":"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"}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { SourceStat, VisualSourceHandle } from "./sources.js";
|
|
3
|
+
/**
|
|
4
|
+
* Browser side of app sources (ADR-048 P3). `useVisual()` reads the context the app chose to expose
|
|
5
|
+
* (static, cache-safe values only); `useVisualSource(handle)` loads a `load: "client"` source through the
|
|
6
|
+
* app's own route with the signed handle the server render produced.
|
|
7
|
+
*/
|
|
8
|
+
type Ctx = {
|
|
9
|
+
context: Record<string, unknown>;
|
|
10
|
+
endpoint: string;
|
|
11
|
+
};
|
|
12
|
+
export declare function VisualClientProvider(p: {
|
|
13
|
+
context?: Record<string, unknown> | undefined;
|
|
14
|
+
endpoint?: string | undefined;
|
|
15
|
+
children?: ReactNode;
|
|
16
|
+
}): import("react").FunctionComponentElement<import("react").ProviderProps<Ctx>>;
|
|
17
|
+
/** The app context exposed to the browser (`context.expose` in createVisualNext). */
|
|
18
|
+
export declare function useVisual<T extends Record<string, unknown> = Record<string, unknown>>(): T;
|
|
19
|
+
export type VisualSourceState<T> = {
|
|
20
|
+
data: T | undefined;
|
|
21
|
+
error: string | undefined;
|
|
22
|
+
loading: boolean;
|
|
23
|
+
/** Load now (for when: "interaction"). */
|
|
24
|
+
load: () => void;
|
|
25
|
+
/** Reload (e.g. after your own mutation). */
|
|
26
|
+
refresh: () => void;
|
|
27
|
+
/** Attach to an element for when: "visible". */
|
|
28
|
+
ref: (el: Element | null) => void;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Data of a `load: "client"` source, given the handle your component received through `needs`.
|
|
32
|
+
* when: "load" (default) fetches after hydration, "idle" when the browser is idle, "visible" when `ref`
|
|
33
|
+
* scrolls into view, "interaction" only when you call `load()`.
|
|
34
|
+
*/
|
|
35
|
+
export declare function useVisualSource<T = unknown>(handle: VisualSourceHandle | null | undefined): VisualSourceState<T>;
|
|
36
|
+
/** Listens for "refresh" steps and changed sources after actions (ADR-048 P4) and refreshes server data. */
|
|
37
|
+
export declare function VisualRefresh(): null;
|
|
38
|
+
/** Development only: which sources this render resolved, how long they took, cache hits (ADR-048 P5). */
|
|
39
|
+
export declare function VisualDebug(p: {
|
|
40
|
+
stats: SourceStat[];
|
|
41
|
+
page: string;
|
|
42
|
+
dynamic: string[];
|
|
43
|
+
}): import("react").DetailedReactHTMLElement<{
|
|
44
|
+
"data-vp-debug": string;
|
|
45
|
+
style: {
|
|
46
|
+
position: "fixed";
|
|
47
|
+
insetInlineEnd: number;
|
|
48
|
+
bottom: number;
|
|
49
|
+
zIndex: number;
|
|
50
|
+
font: "12px/1.4 ui-monospace, Menlo, monospace";
|
|
51
|
+
};
|
|
52
|
+
}, HTMLElement> | null;
|
|
53
|
+
export {};
|
|
54
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA4G,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACjJ,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEnE;;;;GAIG;AACH,KAAK,GAAG,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAGlE,wBAAgB,oBAAoB,CAAC,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,gFAI7I;AAED,qFAAqF;AACrF,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,CAE1F;AAqCD,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAAI;IACjC,IAAI,EAAE,CAAC,GAAG,SAAS,CAAC;IACpB,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,0CAA0C;IAC1C,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,6CAA6C;IAC7C,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,gDAAgD;IAChD,GAAG,EAAE,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC;CACnC,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,kBAAkB,GAAG,IAAI,GAAG,SAAS,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAyBhH;AAED,4GAA4G;AAC5G,wBAAgB,aAAa,SAS5B;AAED,yGAAyG;AACzG,wBAAgB,WAAW,CAAC,CAAC,EAAE;IAAE,KAAK,EAAE,UAAU,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE;;;;;;;;;uBAatF"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useRouter } from "next/navigation";
|
|
3
|
+
import { createContext, createElement, useCallback, useContext, useEffect, useRef, useState, useSyncExternalStore } from "react";
|
|
4
|
+
const VisualClientContext = createContext({ context: {}, endpoint: "/api/visual/sources" });
|
|
5
|
+
export function VisualClientProvider(p) {
|
|
6
|
+
const parent = useContext(VisualClientContext);
|
|
7
|
+
const value = { context: { ...parent.context, ...(p.context ?? {}) }, endpoint: p.endpoint ?? parent.endpoint };
|
|
8
|
+
return createElement(VisualClientContext.Provider, { value }, p.children);
|
|
9
|
+
}
|
|
10
|
+
/** The app context exposed to the browser (`context.expose` in createVisualNext). */
|
|
11
|
+
export function useVisual() {
|
|
12
|
+
return useContext(VisualClientContext).context;
|
|
13
|
+
}
|
|
14
|
+
const store = new Map();
|
|
15
|
+
const notify = (e) => e.listeners.forEach((l) => l());
|
|
16
|
+
function entry(handle) {
|
|
17
|
+
let e = store.get(handle.$vpSource);
|
|
18
|
+
if (!e) {
|
|
19
|
+
e = { status: "idle", source: handle.source, listeners: new Set() };
|
|
20
|
+
store.set(handle.$vpSource, e);
|
|
21
|
+
}
|
|
22
|
+
return e;
|
|
23
|
+
}
|
|
24
|
+
function fetchEntry(token, e, endpoint) {
|
|
25
|
+
if (e.promise)
|
|
26
|
+
return e.promise;
|
|
27
|
+
e.status = "loading";
|
|
28
|
+
notify(e);
|
|
29
|
+
e.promise = fetch(endpoint, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ handle: token }), credentials: "same-origin" })
|
|
30
|
+
.then(async (r) => {
|
|
31
|
+
const j = (await r.json().catch(() => ({})));
|
|
32
|
+
if (!r.ok)
|
|
33
|
+
throw new Error(j.error ?? `HTTP ${r.status}`);
|
|
34
|
+
e.status = "success";
|
|
35
|
+
e.data = j.data;
|
|
36
|
+
e.error = undefined;
|
|
37
|
+
})
|
|
38
|
+
.catch((x) => { e.status = "error"; e.error = x instanceof Error ? x.message : String(x); })
|
|
39
|
+
.finally(() => { e.promise = undefined; notify(e); });
|
|
40
|
+
return e.promise;
|
|
41
|
+
}
|
|
42
|
+
if (typeof window !== "undefined") {
|
|
43
|
+
// Actions that changed data (ADR-048 P4) name the sources to reload.
|
|
44
|
+
window.addEventListener("vp:sources-changed", (ev) => {
|
|
45
|
+
const names = ev.detail?.names ?? [];
|
|
46
|
+
for (const [token, e] of store)
|
|
47
|
+
if (names.includes(e.source) && e.status !== "idle")
|
|
48
|
+
void fetchEntry(token, e, e.endpoint ?? "/api/visual/sources");
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Data of a `load: "client"` source, given the handle your component received through `needs`.
|
|
53
|
+
* when: "load" (default) fetches after hydration, "idle" when the browser is idle, "visible" when `ref`
|
|
54
|
+
* scrolls into view, "interaction" only when you call `load()`.
|
|
55
|
+
*/
|
|
56
|
+
export function useVisualSource(handle) {
|
|
57
|
+
const { endpoint } = useContext(VisualClientContext);
|
|
58
|
+
const e = handle ? entry(handle) : null;
|
|
59
|
+
if (e)
|
|
60
|
+
e.endpoint = endpoint;
|
|
61
|
+
const subscribe = useCallback((l) => { if (!e)
|
|
62
|
+
return () => { }; e.listeners.add(l); return () => { e.listeners.delete(l); }; }, [e]);
|
|
63
|
+
const snap = useSyncExternalStore(subscribe, () => (e ? `${e.status}:${e.error ?? ""}` : "none"), () => "idle:");
|
|
64
|
+
const load = useCallback(() => { if (handle && e && e.status !== "success")
|
|
65
|
+
void fetchEntry(handle.$vpSource, e, endpoint); }, [handle, e, endpoint]);
|
|
66
|
+
const refresh = useCallback(() => { if (handle && e)
|
|
67
|
+
void fetchEntry(handle.$vpSource, e, endpoint); }, [handle, e, endpoint]);
|
|
68
|
+
const observer = useRef(null);
|
|
69
|
+
const ref = useCallback((el) => {
|
|
70
|
+
observer.current?.disconnect();
|
|
71
|
+
if (!el || handle?.when !== "visible")
|
|
72
|
+
return;
|
|
73
|
+
observer.current = new IntersectionObserver((entries) => { if (entries.some((x) => x.isIntersecting)) {
|
|
74
|
+
observer.current?.disconnect();
|
|
75
|
+
load();
|
|
76
|
+
} }, { rootMargin: "200px" });
|
|
77
|
+
observer.current.observe(el);
|
|
78
|
+
}, [handle?.when, load]);
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
if (!handle || !e || e.status !== "idle")
|
|
81
|
+
return;
|
|
82
|
+
if (handle.when === "load")
|
|
83
|
+
load();
|
|
84
|
+
else if (handle.when === "idle") {
|
|
85
|
+
const ric = window.requestIdleCallback;
|
|
86
|
+
if (ric)
|
|
87
|
+
ric(load);
|
|
88
|
+
else
|
|
89
|
+
setTimeout(load, 200);
|
|
90
|
+
}
|
|
91
|
+
}, [handle, e, load]);
|
|
92
|
+
void snap;
|
|
93
|
+
return { data: e?.data, error: e?.error, loading: e?.status === "loading" || (e?.status === "idle" && handle?.when === "load"), load, refresh, ref };
|
|
94
|
+
}
|
|
95
|
+
/** Listens for "refresh" steps and changed sources after actions (ADR-048 P4) and refreshes server data. */
|
|
96
|
+
export function VisualRefresh() {
|
|
97
|
+
const router = useRouter();
|
|
98
|
+
useEffect(() => {
|
|
99
|
+
const on = () => router.refresh();
|
|
100
|
+
window.addEventListener("vp:refresh", on);
|
|
101
|
+
window.addEventListener("vp:sources-changed", on);
|
|
102
|
+
return () => { window.removeEventListener("vp:refresh", on); window.removeEventListener("vp:sources-changed", on); };
|
|
103
|
+
}, [router]);
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
/** Development only: which sources this render resolved, how long they took, cache hits (ADR-048 P5). */
|
|
107
|
+
export function VisualDebug(p) {
|
|
108
|
+
const [open, setOpen] = useState(false);
|
|
109
|
+
if (!p.stats.length && !p.dynamic.length)
|
|
110
|
+
return null;
|
|
111
|
+
const color = { hit: "#16a34a", memo: "#16a34a", value: "#6b7280", miss: "#d97706", private: "#7c3aed", client: "#2563eb", stream: "#2563eb", skipped: "#9ca3af", error: "#dc2626" };
|
|
112
|
+
return createElement("div", { "data-vp-debug": "", style: { position: "fixed", insetInlineEnd: 12, bottom: 12, zIndex: 2147483001, font: "12px/1.4 ui-monospace, Menlo, monospace" } }, createElement("button", { type: "button", onClick: () => setOpen((o) => !o), style: { background: "#111827", color: "#fff", border: 0, borderRadius: 6, padding: "6px 10px", cursor: "pointer" } }, `visual · ${p.stats.length} source${p.stats.length === 1 ? "" : "s"}${p.dynamic.length ? " · dynamic" : ""}`), open ? createElement("div", { style: { marginTop: 6, background: "#fff", color: "#111827", border: "1px solid #e5e7eb", borderRadius: 8, padding: 10, maxWidth: 420, boxShadow: "0 8px 24px rgba(0,0,0,.15)" } }, createElement("div", { style: { fontWeight: 600, marginBottom: 6 } }, p.page), p.dynamic.length ? createElement("div", { style: { color: "#7c3aed", marginBottom: 6 } }, `renders per visitor: ${p.dynamic.join(", ")}`) : null, ...p.stats.map((s, i) => createElement("div", { key: i, style: { display: "flex", gap: 8, justifyContent: "space-between" } }, createElement("span", null, s.input.startsWith("$need:") ? `needs → ${s.source}` : s.input === s.source ? s.input : `${s.input} ← ${s.source}`), createElement("span", { style: { color: color[s.cache] } }, `${s.cache}${s.ms ? ` · ${s.ms} ms` : ""}`)))) : null);
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.tsx"],"names":[],"mappings":"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"}
|