@squadbase/vantage 0.6.2-dev1.02aab78 → 0.6.2-dev1.0ad29b0
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/{build-YOPOGPQB.js → build-A23M4GCH.js} +4 -4
- package/dist/{build-YOPOGPQB.js.map → build-A23M4GCH.js.map} +1 -1
- package/dist/{chunk-V3LF7BE7.js → chunk-ANZLVSEP.js} +4 -5
- package/dist/chunk-ANZLVSEP.js.map +1 -0
- package/dist/{chunk-XQUSGIDG.js → chunk-CKWPK4RO.js} +10 -3
- package/dist/chunk-CKWPK4RO.js.map +1 -0
- package/dist/{chunk-7652CGJJ.js → chunk-SDJTTMLK.js} +57 -7
- package/dist/chunk-SDJTTMLK.js.map +1 -0
- package/dist/{chunk-R6MTJAHX.js → chunk-SHZM3EXB.js} +15 -4
- package/dist/chunk-SHZM3EXB.js.map +1 -0
- package/dist/cli.js +3 -3
- package/dist/client/index.d.ts +2 -0
- package/dist/client/index.js +8 -2
- package/dist/client/index.js.map +1 -1
- package/dist/{dev-GUKQT6U6.js → dev-H4I2JL63.js} +4 -4
- package/dist/{dev-GUKQT6U6.js.map → dev-H4I2JL63.js.map} +1 -1
- package/dist/query/index.js +2 -2
- package/dist/table/index.js +2 -2
- package/dist/{upgrade-7ZXMCTTR.js → upgrade-6DT7ADRP.js} +3 -3
- package/dist/{upgrade-7ZXMCTTR.js.map → upgrade-6DT7ADRP.js.map} +1 -1
- package/dist/vite/index.js +2 -2
- package/package.json +2 -2
- package/dist/chunk-7652CGJJ.js.map +0 -1
- package/dist/chunk-R6MTJAHX.js.map +0 -1
- package/dist/chunk-V3LF7BE7.js.map +0 -1
- package/dist/chunk-XQUSGIDG.js.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { runDiagnostics } from './chunk-5C2SEDPH.js';
|
|
2
2
|
import './chunk-UWSQUHX6.js';
|
|
3
|
-
import { vantagePlugin } from './chunk-
|
|
4
|
-
import { generateArtifacts } from './chunk-
|
|
3
|
+
import { vantagePlugin } from './chunk-SDJTTMLK.js';
|
|
4
|
+
import { generateArtifacts } from './chunk-SHZM3EXB.js';
|
|
5
5
|
import './chunk-S5MDTHH7.js';
|
|
6
6
|
import { scanProject, timedAsync } from './chunk-RNTDBX6S.js';
|
|
7
7
|
import './chunk-46QI6GFC.js';
|
|
@@ -104,5 +104,5 @@ function writeDeployManifest(root, model) {
|
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
export { build };
|
|
107
|
-
//# sourceMappingURL=build-
|
|
108
|
-
//# sourceMappingURL=build-
|
|
107
|
+
//# sourceMappingURL=build-A23M4GCH.js.map
|
|
108
|
+
//# sourceMappingURL=build-A23M4GCH.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/build.ts"],"names":["viteBuild"],"mappings":"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","file":"build-
|
|
1
|
+
{"version":3,"sources":["../src/cli/build.ts"],"names":["viteBuild"],"mappings":"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","file":"build-A23M4GCH.js","sourcesContent":["import fs from \"node:fs\"\nimport path from \"node:path\"\nimport { build as viteBuild, loadEnv } from \"vite\"\nimport { MANIFEST_SCHEMA_VERSION, VANTAGE_DIR } from \"../core/constants\"\nimport { runDiagnostics } from \"../core/diagnostics\"\nimport { generateArtifacts } from \"../core/generate\"\nimport { timedAsync } from \"../core/profile\"\nimport { scanProject } from \"../core/scan\"\nimport type { RouteModel } from \"../core/types\"\nimport { vantagePlugin } from \"../vite/index\"\nimport { applyApiBaseUrlFlag, log, printDiagnostics, type ParsedArgs } from \"./util\"\n\nconst SERVER_ENTRY = `// AUTO-GENERATED by @squadbase/vantage.\nimport path from \"node:path\"\nimport { fileURLToPath } from \"node:url\"\nimport { startNodeServer } from \"@squadbase/vantage/server/node\"\nimport { apiRoutes } from \"./server-routes.gen\"\n\nconst clientDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), \"../client\")\nstartNodeServer({ apiRoutes, clientDir })\n`\n\n/** `vantage build` — build client and (optionally) server into dist/. */\nexport async function build(root: string, args: ParsedArgs): Promise<number> {\n const model = scanProject(root)\n const errors = runDiagnostics(root, model).filter((d) => d.severity === \"error\")\n if (errors.length) {\n printDiagnostics(errors)\n log.error(\"Fix the errors above before building.\")\n return 1\n }\n\n const mode = \"production\"\n // `--api-base-url` feeds the client's PUBLIC_API_BASE_URL. Setting it on\n // process.env (before loadEnv/Vite read env) makes the flag win over any .env\n // value and keeps the single env-prefix mechanism — no Vite `define`.\n applyApiBaseUrlFlag(args)\n const env = { ...process.env, ...loadEnv(mode, root, \"\") }\n const quiet = Boolean(args.flags.json)\n\n // Write .vantage/ up front instead of letting the plugin do it at\n // configResolved: the server bundle reads server-routes.gen.ts, so once the\n // artifacts exist the two builds no longer depend on each other and can run\n // at the same time (they write to dist/client and dist/server respectively).\n generateArtifacts({ root, model })\n\n if (!quiet) log.step(model.hasServer ? \"Building client and server…\" : \"Building client…\")\n\n const clientBuild = timedAsync(\"build:client\", async () => {\n await viteBuild({\n configFile: false,\n root,\n mode,\n plugins: [vantagePlugin({ root, env, model, artifactsWritten: true })],\n logLevel: quiet ? \"silent\" : args.flags.verbose ? \"info\" : \"warn\",\n })\n // The HTML input lives in .vantage/, so Vite emits it to dist/client/.vantage/.\n // Hoist it to dist/client/index.html (asset URLs are already root-absolute).\n relocateClientHtml(root)\n })\n\n const serverBuild = model.hasServer\n ? timedAsync(\"build:server\", () => buildServer(root))\n : Promise.resolve()\n\n await Promise.all([clientBuild, serverBuild])\n\n writeDeployManifest(root, model)\n if (!quiet) log.ok(`Build complete → ${path.relative(process.cwd(), path.join(root, \"dist\")) || \"dist\"}/`)\n\n if (args.flags.json) {\n process.stdout.write(\n JSON.stringify({\n ok: true,\n mode: model.hasServer ? \"fullstack\" : \"spa\",\n output: \"dist\",\n pages: model.pages.length,\n apis: model.apis.length,\n }) + \"\\n\",\n )\n }\n return 0\n}\n\nfunction relocateClientHtml(root: string): void {\n const clientDir = path.join(root, \"dist\", \"client\")\n const nested = path.join(clientDir, VANTAGE_DIR, \"index.html\")\n const target = path.join(clientDir, \"index.html\")\n if (fs.existsSync(nested)) {\n fs.mkdirSync(clientDir, { recursive: true })\n fs.renameSync(nested, target)\n fs.rmSync(path.join(clientDir, VANTAGE_DIR), { recursive: true, force: true })\n }\n}\n\nasync function buildServer(root: string): Promise<void> {\n // Loaded here, not at module scope: an SPA project never builds a server and\n // should not pay for esbuild's binary being brought up.\n const { build: esbuildBuild } = await import(\"esbuild\")\n const vantageDir = path.join(root, VANTAGE_DIR)\n const entry = path.join(vantageDir, \"server-entry.ts\")\n fs.writeFileSync(entry, SERVER_ENTRY)\n await esbuildBuild({\n entryPoints: [entry],\n outfile: path.join(root, \"dist\", \"server\", \"index.mjs\"),\n bundle: true,\n platform: \"node\",\n format: \"esm\",\n target: \"node20\",\n logLevel: \"warning\",\n banner: { js: \"// @squadbase/vantage server bundle\" },\n })\n}\n\nfunction writeDeployManifest(root: string, model: RouteModel): void {\n const dist = path.join(root, \"dist\")\n fs.mkdirSync(dist, { recursive: true })\n const manifest = {\n schemaVersion: MANIFEST_SCHEMA_VERSION,\n mode: model.hasServer ? \"fullstack\" : \"spa\",\n client: \"./client\",\n ...(model.hasServer ? { server: \"./server/index.mjs\" } : {}),\n spaFallback: \"./client/index.html\",\n runtime: \"node\",\n }\n fs.writeFileSync(path.join(dist, \"vantage-manifest.json\"), JSON.stringify(manifest, null, 2) + \"\\n\")\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isDraftActive } from './chunk-
|
|
1
|
+
import { isDraftActive, API_QUERY_KEY } from './chunk-CKWPK4RO.js';
|
|
2
2
|
import { useQuery, useMutation } from '@tanstack/react-query';
|
|
3
3
|
export { QueryClient, keepPreviousData, useInfiniteQuery, useIsFetching, useIsMutating, useMutation, useQueries, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
4
4
|
|
|
@@ -74,7 +74,6 @@ async function apiJson(path, init) {
|
|
|
74
74
|
}
|
|
75
75
|
return body;
|
|
76
76
|
}
|
|
77
|
-
var API_KEY = "api";
|
|
78
77
|
var MISSING_API_POLL_MS = 2e3;
|
|
79
78
|
function isMissingApi(error) {
|
|
80
79
|
return error instanceof ApiError && error.status === 404;
|
|
@@ -83,7 +82,7 @@ function useApiQuery(path, options = {}) {
|
|
|
83
82
|
const { search, init, queryKey, refetchInterval, ...rest } = options;
|
|
84
83
|
const url = apiPath(path, search);
|
|
85
84
|
const result = useQuery({
|
|
86
|
-
queryKey: queryKey ?? [
|
|
85
|
+
queryKey: queryKey ?? [API_QUERY_KEY, url],
|
|
87
86
|
// The signal comes from TanStack so an unmounted/refetched query aborts;
|
|
88
87
|
// a caller-supplied signal wins.
|
|
89
88
|
queryFn: ({ signal }) => apiJson(url, { ...init, signal: init?.signal ?? signal }),
|
|
@@ -123,5 +122,5 @@ function useApiMutation(path, options = {}) {
|
|
|
123
122
|
}
|
|
124
123
|
|
|
125
124
|
export { ApiError, apiBaseUrl, apiFetch, apiJson, apiPath, apiUrl, useApiMutation, useApiQuery };
|
|
126
|
-
//# sourceMappingURL=chunk-
|
|
127
|
-
//# sourceMappingURL=chunk-
|
|
125
|
+
//# sourceMappingURL=chunk-ANZLVSEP.js.map
|
|
126
|
+
//# sourceMappingURL=chunk-ANZLVSEP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/query/api.ts","../src/query/hooks.ts"],"names":[],"mappings":"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","file":"chunk-ANZLVSEP.js","sourcesContent":["/**\n * The one seam for calling the API from client code. All `/api/*` requests go\n * through here so a split deployment (client on S3/CloudFront, server on Lambda)\n * can point the client at a different origin without touching page code.\n *\n * The base is read from `import.meta.env.PUBLIC_API_BASE_URL` — a `PUBLIC_`\n * prefixed var so it is inlined into the client bundle (see envPrefix in the\n * Vite plugin). It can be set in `.env` or injected at build time via\n * `vantage build --api-base-url <url>`. When unset it is empty, so requests stay\n * same-origin relative paths — identical to hand-written `fetch(\"/api/...\")`.\n */\nimport { isDraftActive } from \"../client/draft-state\"\n\n/** The configured API base URL (no trailing slash), or \"\" for same-origin. */\nexport function apiBaseUrl(): string {\n // `import.meta.env` is typed in the generated .vantage/types, not here.\n const env = (import.meta as { env?: Record<string, string | undefined> }).env\n const raw = env?.PUBLIC_API_BASE_URL ?? \"\"\n return raw.replace(/\\/+$/, \"\")\n}\n\n/**\n * Build a full API URL. Pass the path exactly as it maps to `server/api/**`,\n * including the `/api` prefix — e.g. `apiUrl(\"/api/customers\")`. With no base\n * configured this returns the relative path unchanged.\n */\nexport function apiUrl(path: string): string {\n const rel = path.startsWith(\"/\") ? path : `/${path}`\n return apiBaseUrl() + rel\n}\n\n/**\n * Thin `fetch` wrapper that resolves the path against the API base. Returns the\n * raw `Response` — parsing and error handling stay with the caller, matching the\n * existing `queryFn` style.\n */\nexport function apiFetch(path: string, init?: RequestInit): Promise<Response> {\n return fetch(apiUrl(path), init)\n}\n\n/** Query-string values accepted by the API helpers. */\nexport type ApiSearch = Record<\n string,\n string | number | boolean | null | undefined | (string | number)[]\n>\n\n/**\n * Append a query string to an API path. `undefined`/`null` entries are dropped\n * so an unset filter leaves the URL — and the query key — unchanged. Array\n * values repeat the key, matching `URLSearchParams.getAll` on the server.\n */\nexport function apiPath(path: string, search?: ApiSearch): string {\n if (!search) return path\n const params = new URLSearchParams()\n // Sorted so two calls with the same filters produce the same query key.\n for (const key of Object.keys(search).sort()) {\n const value = search[key]\n if (value === undefined || value === null) continue\n if (Array.isArray(value)) {\n for (const item of value) params.append(key, String(item))\n } else {\n params.append(key, String(value))\n }\n }\n const qs = params.toString()\n if (!qs) return path\n return path + (path.includes(\"?\") ? \"&\" : \"?\") + qs\n}\n\n/**\n * A non-2xx response from `server/api`. `message` is the server's `HttpError`\n * message when there was one; anything else surfaces as a generic status text,\n * mirroring what the server chose to disclose.\n */\nexport class ApiError extends Error {\n /** HTTP status of the response. */\n readonly status: number\n /** Parsed response body, when there was one. */\n readonly body: unknown\n /** `x-vantage-request-id`, to correlate with the server's terminal log. */\n readonly requestId: string | undefined\n\n constructor(message: string, status: number, body: unknown, requestId?: string) {\n super(message)\n this.name = \"ApiError\"\n this.status = status\n this.body = body\n this.requestId = requestId\n }\n}\n\n/**\n * Fetch an API route and parse its JSON, throwing `ApiError` on a non-2xx.\n * This is what the API hooks call; use it directly in a loader or an event\n * handler where a hook doesn't fit.\n */\nexport async function apiJson<T = unknown>(path: string, init?: RequestInit): Promise<T> {\n const res = await apiFetch(path, init)\n const requestId = res.headers.get(\"x-vantage-request-id\") ?? undefined\n\n // Read as text first: an error response may be HTML from a proxy, and a 204\n // has no body at all — neither should throw a JSON parse error at the caller.\n const text = await res.text()\n let body: unknown\n if (text) {\n try {\n body = JSON.parse(text)\n } catch {\n body = text\n }\n }\n\n // While a draft is showing, an API the page calls may not exist yet. Without\n // `server/` the dev server answers any GET with the app shell, a 200 that\n // would otherwise pass for data; call it what it is (a missing route).\n if (res.ok && isDraftActive() && (res.headers.get(\"content-type\") ?? \"\").includes(\"text/html\")) {\n throw new ApiError(\"API route not found\", 404, body, requestId)\n }\n\n if (!res.ok) {\n const serverMessage =\n typeof body === \"object\" && body !== null && typeof (body as { error?: unknown }).error === \"string\"\n ? (body as { error: string }).error\n : undefined\n throw new ApiError(\n serverMessage ?? `${res.status} ${res.statusText || \"Request failed\"}`,\n res.status,\n body,\n requestId,\n )\n }\n\n return body as T\n}\n","/**\n * Hooks for the app's own `server/api` routes. They are `useQuery`/`useMutation`\n * with the parts every page was repeating — base URL, JSON parsing, non-2xx to\n * `ApiError`, a query key derived from the URL — moved into the framework.\n * Everything else about TanStack Query stays available through the options.\n */\nimport { useMutation, useQuery } from \"@tanstack/react-query\"\nimport type {\n QueryKey,\n UseMutationOptions,\n UseMutationResult,\n UseQueryOptions,\n UseQueryResult,\n} from \"@tanstack/react-query\"\nimport { isDraftActive } from \"../client/draft-state\"\nimport { API_QUERY_KEY as API_KEY } from \"./client\"\nimport { apiJson, apiPath, ApiError as ApiErrorClass, type ApiError, type ApiSearch } from \"./api\"\n\n\n/** How often a query whose API route does not exist yet looks again, while a draft is showing. */\nconst MISSING_API_POLL_MS = 2000\n\n/** An API route that is not there (yet): a 404 from `server/api`, or the app shell standing in for it. */\nfunction isMissingApi(error: unknown): boolean {\n return error instanceof ApiErrorClass && error.status === 404\n}\n\nexport interface ApiQueryOptions<TData>\n extends Omit<UseQueryOptions<TData, ApiError>, \"queryKey\" | \"queryFn\"> {\n /** Query-string values; `undefined` entries are omitted. */\n search?: ApiSearch\n /** Extra `fetch` init (headers, credentials, …). */\n init?: RequestInit\n /** Override the derived `[\"api\", url]` key. */\n queryKey?: QueryKey\n}\n\n/**\n * GET an API route.\n *\n * ```tsx\n * const { data, isPending, error } = useApiQuery<Monthly>(\"/api/monthly-analysis\")\n * const filtered = useApiQuery<Row[]>(\"/api/customers\", { search: { segment } })\n * ```\n *\n * The key defaults to `[\"api\", <url with query string>]`, so changing `search`\n * refetches and `invalidateQueries({ queryKey: [\"api\"] })` clears everything.\n */\nexport function useApiQuery<TData = unknown>(\n path: string,\n options: ApiQueryOptions<TData> = {},\n): UseQueryResult<TData, ApiError> {\n const { search, init, queryKey, refetchInterval, ...rest } = options\n const url = apiPath(path, search)\n const result = useQuery<TData, ApiError>({\n queryKey: queryKey ?? [API_KEY, url],\n // The signal comes from TanStack so an unmounted/refetched query aborts;\n // a caller-supplied signal wins.\n queryFn: ({ signal }) => apiJson<TData>(url, { ...init, signal: init?.signal ?? signal }),\n // While a draft is showing, a route that does not exist yet is looked for\n // again until it does; otherwise the caller's interval applies untouched.\n refetchInterval: (query) =>\n isDraftActive() && isMissingApi(query.state.error)\n ? MISSING_API_POLL_MS\n : typeof refetchInterval === \"function\"\n ? refetchInterval(query)\n : refetchInterval,\n ...rest,\n })\n // A page written before its API is still loading as far as the page can tell:\n // it keeps its loading state instead of drawing an error for a route the\n // agent has not written yet.\n if (isDraftActive() && isMissingApi(result.error)) {\n return {\n ...result,\n status: \"pending\",\n error: null,\n isError: false,\n isLoadingError: false,\n isPending: true,\n isLoading: true,\n } as UseQueryResult<TData, ApiError>\n }\n return result\n}\n\nexport interface ApiMutationOptions<TData, TVariables>\n extends Omit<UseMutationOptions<TData, ApiError, TVariables>, \"mutationFn\"> {\n /** HTTP method (default `\"POST\"`). */\n method?: \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\"\n /** Extra `fetch` init (headers, credentials, …). */\n init?: RequestInit\n}\n\n/**\n * Write to an API route. The mutation variables are sent as the JSON body.\n *\n * ```tsx\n * const save = useApiMutation<Customer, { id: string; name: string }>(\n * (vars) => `/api/customers/${vars.id}`,\n * { method: \"PUT\" },\n * )\n * save.mutate({ id: \"1\", name: \"Northwind\" })\n * ```\n */\nexport function useApiMutation<TData = unknown, TVariables = void>(\n path: string | ((variables: TVariables) => string),\n options: ApiMutationOptions<TData, TVariables> = {},\n): UseMutationResult<TData, ApiError, TVariables> {\n const { method = \"POST\", init, ...rest } = options\n return useMutation<TData, ApiError, TVariables>({\n mutationFn: (variables: TVariables) => {\n const url = typeof path === \"function\" ? path(variables) : path\n const hasBody = variables !== undefined && variables !== null\n return apiJson<TData>(url, {\n method,\n ...init,\n headers: hasBody\n ? { \"content-type\": \"application/json\", ...(init?.headers as Record<string, string>) }\n : init?.headers,\n ...(hasBody ? { body: JSON.stringify(variables) } : {}),\n })\n },\n ...rest,\n })\n}\n"]}
|
|
@@ -2,6 +2,13 @@ import { QueryClient } from '@tanstack/react-query';
|
|
|
2
2
|
|
|
3
3
|
// @squadbase/vantage — generated build. Do not edit.
|
|
4
4
|
|
|
5
|
+
var API_QUERY_KEY = "api";
|
|
6
|
+
var API_REFRESH_DEBOUNCE_MS = 300;
|
|
7
|
+
function refreshApiQueries(client) {
|
|
8
|
+
return client.invalidateQueries({
|
|
9
|
+
predicate: (query) => query.queryKey[0] === API_QUERY_KEY || query.state.status === "error"
|
|
10
|
+
});
|
|
11
|
+
}
|
|
5
12
|
function createQueryClient() {
|
|
6
13
|
return new QueryClient({
|
|
7
14
|
defaultOptions: {
|
|
@@ -38,6 +45,6 @@ function setDraftActive(active) {
|
|
|
38
45
|
window.__VANTAGE_DRAFT__ = { active };
|
|
39
46
|
}
|
|
40
47
|
|
|
41
|
-
export { SETTLING_MS, createQueryClient, isDraftActive, isDraftSettling, setDraftActive };
|
|
42
|
-
//# sourceMappingURL=chunk-
|
|
43
|
-
//# sourceMappingURL=chunk-
|
|
48
|
+
export { API_QUERY_KEY, API_REFRESH_DEBOUNCE_MS, SETTLING_MS, createQueryClient, isDraftActive, isDraftSettling, refreshApiQueries, setDraftActive };
|
|
49
|
+
//# sourceMappingURL=chunk-CKWPK4RO.js.map
|
|
50
|
+
//# sourceMappingURL=chunk-CKWPK4RO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/query/client.ts","../src/client/draft-state.ts"],"names":[],"mappings":";;;;AAGO,IAAM,aAAA,GAAgB;AAOtB,IAAM,uBAAA,GAA0B;AAOhC,SAAS,kBAAkB,MAAA,EAAoC;AACpE,EAAA,OAAO,OAAO,iBAAA,CAAkB;AAAA,IAC9B,SAAA,EAAW,CAAC,KAAA,KAAU,KAAA,CAAM,QAAA,CAAS,CAAC,CAAA,KAAM,aAAA,IAAiB,KAAA,CAAM,KAAA,CAAM,MAAA,KAAW;AAAA,GACrF,CAAA;AACH;AAOO,SAAS,iBAAA,GAAiC;AAC/C,EAAA,OAAO,IAAI,WAAA,CAAY;AAAA,IACrB,cAAA,EAAgB;AAAA,MACd,OAAA,EAAS;AAAA,QACP,SAAA,EAAW,GAAA;AAAA,QACX,KAAA,EAAO,CAAA;AAAA,QACP,oBAAA,EAAsB,KAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAOtB,WAAA,EAAa;AAAA,OACf;AAAA,MACA,SAAA,EAAW;AAAA,QACT,WAAA,EAAa;AAAA;AACf;AACF,GACD,CAAA;AACH;;;AC3BO,IAAM,WAAA,GAAc;AAEpB,SAAS,aAAA,GAAyB;AACvC,EAAA,OAAO,OAAO,MAAA,KAAW,WAAA,IAAe,MAAA,CAAO,mBAAmB,MAAA,KAAW,IAAA;AAC/E;AAOO,SAAS,eAAA,GAA2B;AACzC,EAAA,IAAI,aAAA,IAAiB,OAAO,IAAA;AAC5B,EAAA,OAAO,OAAO,MAAA,KAAW,WAAA,IAAe,KAAK,GAAA,EAAI,IAAK,OAAO,gCAAA,IAAoC,CAAA,CAAA;AACnG;AAEO,SAAS,eAAe,MAAA,EAAuB;AACpD,EAAA,IAAI,CAAC,UAAU,aAAA,EAAc,SAAU,gCAAA,GAAmC,IAAA,CAAK,KAAI,GAAI,WAAA;AACvF,EAAA,MAAA,CAAO,iBAAA,GAAoB,EAAE,MAAA,EAAO;AACtC","file":"chunk-CKWPK4RO.js","sourcesContent":["import { QueryClient } from \"@tanstack/react-query\"\n\n/** Query-key namespace of `useApiQuery`, so `invalidateQueries({ queryKey: [\"api\"] })` works. */\nexport const API_QUERY_KEY = \"api\"\n\n/**\n * Debounce for the api-change refetch. The changed `paths` cannot be mapped to\n * query keys reliably (custom `queryKey`s, dynamic segments), so every burst of\n * changes is coalesced into a single refetch of all API/errored queries.\n */\nexport const API_REFRESH_DEBOUNCE_MS = 300\n\n/**\n * An API module came, went or changed on the dev server: refetch the active API\n * queries, plus any query that is in an error state (a custom `queryKey` that\n * failed because the route did not exist yet still recovers).\n */\nexport function refreshApiQueries(client: QueryClient): Promise<void> {\n return client.invalidateQueries({\n predicate: (query) => query.queryKey[0] === API_QUERY_KEY || query.state.status === \"error\",\n })\n}\n\n/**\n * Create the QueryClient with Vantage defaults. Individual queries may override\n * these, but replacing the QueryClient wholesale is intentionally not exposed —\n * Squadbase relies on a single managed client for auth, logging and telemetry.\n */\nexport function createQueryClient(): QueryClient {\n return new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: 30_000,\n retry: 1,\n refetchOnWindowFocus: false,\n // A dashboard talks to its own origin (or the configured API base), so\n // the browser's offline heuristic says nothing useful about whether a\n // request can succeed. Under the default \"online\" mode a failed request\n // is *paused* rather than retried whenever that heuristic reads\n // offline, and the page sits on its loading state forever instead of\n // showing the error.\n networkMode: \"always\",\n },\n mutations: {\n networkMode: \"always\",\n },\n },\n })\n}\n","/**\n * Whether the preview is currently showing a draft. The server announces it\n * (`vantage:draft-state`); until the first announcement `window.__VANTAGE_DRAFT__`\n * does not exist at all, which is how an app without the draft layer behaves.\n *\n * Kept free of React and of module state: `client/` and `query/` are separate\n * published entries, so the one thing they share is this global.\n */\nexport interface DraftWindowState {\n active: boolean\n}\n\ndeclare global {\n interface Window {\n __VANTAGE_DRAFT__?: DraftWindowState\n /** Until when (ms epoch) a draft that just ended still counts for failures (see `isDraftSettling`). */\n __VANTAGE_DRAFT_SETTLING_UNTIL__?: number\n }\n}\n\n/** How long after a draft ends a failure is still taken to be the draft's. */\nexport const SETTLING_MS = 1500\n\nexport function isDraftActive(): boolean {\n return typeof window !== \"undefined\" && window.__VANTAGE_DRAFT__?.active === true\n}\n\n/**\n * A draft is showing, or ended a moment ago. The server announces the end before\n * the version it fell back to reaches the page, and a failing draft drawn once\n * more in that gap must still be held back, not shown as an error page.\n */\nexport function isDraftSettling(): boolean {\n if (isDraftActive()) return true\n return typeof window !== \"undefined\" && Date.now() < (window.__VANTAGE_DRAFT_SETTLING_UNTIL__ ?? 0)\n}\n\nexport function setDraftActive(active: boolean): void {\n if (!active && isDraftActive()) window.__VANTAGE_DRAFT_SETTLING_UNTIL__ = Date.now() + SETTLING_MS\n window.__VANTAGE_DRAFT__ = { active }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { generateArtifacts, setDraftArtifacts, restoreClientEntry } from './chunk-
|
|
1
|
+
import { API_CHANGE_EVENT, generateArtifacts, setDraftArtifacts, restoreClientEntry } from './chunk-SHZM3EXB.js';
|
|
2
2
|
import { extractAppLang } from './chunk-S5MDTHH7.js';
|
|
3
3
|
import { scanProject, resolvePageRoot, stripExt, splitPageVariant, fileToSegments, displayPath } from './chunk-RNTDBX6S.js';
|
|
4
4
|
import { corsMiddleware, matchApiRoute, dispatchApi, sortApiRoutes } from './chunk-46QI6GFC.js';
|
|
@@ -221,6 +221,7 @@ function boundNames(sf) {
|
|
|
221
221
|
else if (ts.isImportEqualsDeclaration(node)) names.add(node.name.text);
|
|
222
222
|
else if (ts.isVariableDeclaration(node) || ts.isParameter(node) || ts.isBindingElement(node))
|
|
223
223
|
bindingNames(node.name, names);
|
|
224
|
+
else if (ts.isTypeParameterDeclaration(node)) names.add(node.name.text);
|
|
224
225
|
else if ((ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isClassDeclaration(node) || ts.isClassExpression(node) || ts.isEnumDeclaration(node)) && node.name)
|
|
225
226
|
names.add(node.name.text);
|
|
226
227
|
ts.forEachChild(node, visit);
|
|
@@ -917,6 +918,7 @@ var DRAFT_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx", ".mts", ".mjs"];
|
|
|
917
918
|
var DRAFTABLE_EXTENSIONS = [".ts", ".tsx"];
|
|
918
919
|
var MAX_BODY_BYTES = 1024 * 1024;
|
|
919
920
|
var DRAFT_IDLE_DISCARD_MS = 6e4;
|
|
921
|
+
var MAX_HANDOVER_RETRIES = 10;
|
|
920
922
|
var ROLLBACK_DEBOUNCE_MS = 150;
|
|
921
923
|
var PREV_QUERY = "vantage-draft-prev";
|
|
922
924
|
var SKELETON_PREFIX = "\0vantage-draft-skeleton:";
|
|
@@ -936,6 +938,7 @@ function draftPreviewPlugin(options) {
|
|
|
936
938
|
const lastSeq = /* @__PURE__ */ new Map();
|
|
937
939
|
const idleTimers = /* @__PURE__ */ new Map();
|
|
938
940
|
const rolledBackAt = /* @__PURE__ */ new Map();
|
|
941
|
+
const handovers = /* @__PURE__ */ new Map();
|
|
939
942
|
const skeletons = /* @__PURE__ */ new Map();
|
|
940
943
|
const borrowed = new BorrowedVersions(PREV_QUERY);
|
|
941
944
|
let lastApplied;
|
|
@@ -1078,6 +1081,7 @@ function draftPreviewPlugin(options) {
|
|
|
1078
1081
|
const forget = async (file, opts) => {
|
|
1079
1082
|
drafts.delete(file);
|
|
1080
1083
|
rolledBackAt.delete(file);
|
|
1084
|
+
handovers.delete(file);
|
|
1081
1085
|
borrowed.drop(file);
|
|
1082
1086
|
tailwind.remove(file);
|
|
1083
1087
|
newFiles.delete(file);
|
|
@@ -1112,7 +1116,27 @@ function draftPreviewPlugin(options) {
|
|
|
1112
1116
|
if (drafts.has(target.file)) touchIdle(target);
|
|
1113
1117
|
return result;
|
|
1114
1118
|
};
|
|
1115
|
-
const
|
|
1119
|
+
const diskTransforms = async ({ file, url }) => {
|
|
1120
|
+
const history = drafts.get(file);
|
|
1121
|
+
if (history === void 0) return void 0;
|
|
1122
|
+
drafts.delete(file);
|
|
1123
|
+
invalidate(file);
|
|
1124
|
+
try {
|
|
1125
|
+
await server.environments.client.transformRequest(url);
|
|
1126
|
+
return void 0;
|
|
1127
|
+
} catch (err) {
|
|
1128
|
+
drafts.set(file, history);
|
|
1129
|
+
invalidate(file);
|
|
1130
|
+
return firstLine(err);
|
|
1131
|
+
}
|
|
1132
|
+
};
|
|
1133
|
+
const keepDraft = (target, reason) => {
|
|
1134
|
+
handovers.set(target.file, { target, retries: handovers.get(target.file)?.retries ?? 0 });
|
|
1135
|
+
touchIdle(target);
|
|
1136
|
+
return { applied: false, reason: `disk version does not transform yet: ${reason}` };
|
|
1137
|
+
};
|
|
1138
|
+
const finalize = async (target) => {
|
|
1139
|
+
const { file } = target;
|
|
1116
1140
|
if (!fs3.existsSync(file)) {
|
|
1117
1141
|
const had = drafts.has(file);
|
|
1118
1142
|
await forget(file, { committed: false });
|
|
@@ -1120,6 +1144,8 @@ function draftPreviewPlugin(options) {
|
|
|
1120
1144
|
notifyState();
|
|
1121
1145
|
return { applied: false, reason: had ? "file was not written" : "file does not exist" };
|
|
1122
1146
|
}
|
|
1147
|
+
const broken = await diskTransforms(target);
|
|
1148
|
+
if (broken !== void 0) return keepDraft(target, broken);
|
|
1123
1149
|
await forget(file, { committed: true });
|
|
1124
1150
|
notifyState();
|
|
1125
1151
|
invalidate(file);
|
|
@@ -1127,7 +1153,8 @@ function draftPreviewPlugin(options) {
|
|
|
1127
1153
|
await refreshSkeletons([], file);
|
|
1128
1154
|
return { applied: true };
|
|
1129
1155
|
};
|
|
1130
|
-
const discard = async (
|
|
1156
|
+
const discard = async (target) => {
|
|
1157
|
+
const { file } = target;
|
|
1131
1158
|
if (!drafts.has(file)) return { applied: false, reason: "no draft" };
|
|
1132
1159
|
await forget(file, { committed: false });
|
|
1133
1160
|
notifyState();
|
|
@@ -1135,9 +1162,21 @@ function draftPreviewPlugin(options) {
|
|
|
1135
1162
|
if (fs3.existsSync(file)) await pushUpdate(file);
|
|
1136
1163
|
return { applied: true };
|
|
1137
1164
|
};
|
|
1165
|
+
const retryHandovers = () => {
|
|
1166
|
+
for (const [file, pending] of [...handovers]) {
|
|
1167
|
+
void enqueue(async () => {
|
|
1168
|
+
if (handovers.get(file) !== pending || !drafts.has(file)) return;
|
|
1169
|
+
pending.retries++;
|
|
1170
|
+
if (pending.retries > MAX_HANDOVER_RETRIES) await discard(pending.target);
|
|
1171
|
+
else await finalize(pending.target);
|
|
1172
|
+
}).catch(() => {
|
|
1173
|
+
});
|
|
1174
|
+
}
|
|
1175
|
+
};
|
|
1138
1176
|
const draft = async (target, req) => {
|
|
1139
1177
|
const { file, rel, url, exists } = target;
|
|
1140
1178
|
if (typeof req.content !== "string") return { applied: false, reason: "content is required" };
|
|
1179
|
+
handovers.delete(file);
|
|
1141
1180
|
const pageDir = options.getModel().pageDir;
|
|
1142
1181
|
const previous = shown(file);
|
|
1143
1182
|
const base = previous?.served ?? diskText(file);
|
|
@@ -1374,6 +1413,7 @@ function draftPreviewPlugin(options) {
|
|
|
1374
1413
|
// The borrowed versions share the drafted file but are not what changed.
|
|
1375
1414
|
hotUpdate({ modules, file }) {
|
|
1376
1415
|
if (tailwind?.owns(file)) return [];
|
|
1416
|
+
if (enabled && handovers.size > 0) retryHandovers();
|
|
1377
1417
|
if (enabled && file === path6.join(root, VANTAGE_DIR, "client-entry.tsx")) {
|
|
1378
1418
|
restoreClientEntry(root);
|
|
1379
1419
|
return [];
|
|
@@ -1759,10 +1799,19 @@ function vantagePlugin(options) {
|
|
|
1759
1799
|
});
|
|
1760
1800
|
const isStylesFile = (file) => path6.relative(pageRoot(), file) === "styles.css";
|
|
1761
1801
|
const rootMoved = () => resolvePageRoot(root).dir !== model.pageDir;
|
|
1802
|
+
const notifyApiChange = (file) => {
|
|
1803
|
+
if (!isApiFile(root, file)) return;
|
|
1804
|
+
server.ws.send({ type: "custom", event: API_CHANGE_EVENT, data: { paths: [path6.relative(root, file)] } });
|
|
1805
|
+
};
|
|
1762
1806
|
const onStructural = (file) => {
|
|
1763
1807
|
const moved = rootMoved();
|
|
1764
|
-
|
|
1808
|
+
const clientFacing = moved || isRoutedFile(pageRoot(), file) || isStylesFile(file);
|
|
1809
|
+
if (clientFacing || isApiFile(root, file)) {
|
|
1765
1810
|
regenerate();
|
|
1811
|
+
if (!clientFacing) {
|
|
1812
|
+
notifyApiChange(file);
|
|
1813
|
+
return;
|
|
1814
|
+
}
|
|
1766
1815
|
if (!moved && getDraftRoutes(server)?.isSuppressed(file)) return;
|
|
1767
1816
|
server.ws.send({ type: "full-reload" });
|
|
1768
1817
|
}
|
|
@@ -1781,12 +1830,13 @@ function vantagePlugin(options) {
|
|
|
1781
1830
|
server.watcher.on("unlinkDir", (dir) => {
|
|
1782
1831
|
if (!rootMoved() && !isRouteDir(dir)) return;
|
|
1783
1832
|
regenerate();
|
|
1784
|
-
server.ws.send({ type: "full-reload" });
|
|
1833
|
+
if (!isServerFile(root, dir)) server.ws.send({ type: "full-reload" });
|
|
1785
1834
|
});
|
|
1786
1835
|
server.watcher.on("change", (file) => {
|
|
1787
1836
|
if (isServerFile(root, file)) {
|
|
1788
1837
|
const mods = server.moduleGraph.getModulesByFile(file);
|
|
1789
1838
|
if (mods) for (const m of mods) server.moduleGraph.invalidateModule(m);
|
|
1839
|
+
notifyApiChange(file);
|
|
1790
1840
|
return;
|
|
1791
1841
|
}
|
|
1792
1842
|
if (isFilePageFile(pageRoot(), file)) server.ws.send({ type: "full-reload" });
|
|
@@ -1823,5 +1873,5 @@ function vantagePlugin(options) {
|
|
|
1823
1873
|
}
|
|
1824
1874
|
|
|
1825
1875
|
export { vantagePlugin };
|
|
1826
|
-
//# sourceMappingURL=chunk-
|
|
1827
|
-
//# sourceMappingURL=chunk-
|
|
1876
|
+
//# sourceMappingURL=chunk-SDJTTMLK.js.map
|
|
1877
|
+
//# sourceMappingURL=chunk-SDJTTMLK.js.map
|