@valbuild/shared 0.150.10 → 0.150.12
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/CHANGELOG.md +33 -0
- package/client/dist/valbuild-shared-client.cjs.dev.js +16 -2
- package/client/dist/valbuild-shared-client.cjs.prod.js +16 -2
- package/client/dist/valbuild-shared-client.esm.js +2 -2
- package/dist/{acquireTypes-dd976839.cjs.prod.js → acquireTypes-6250a305.cjs.prod.js} +46 -46
- package/dist/{acquireTypes-6e2f7961.esm.js → acquireTypes-c2227b23.esm.js} +2 -2
- package/dist/{acquireTypes-84a4077a.cjs.dev.js → acquireTypes-c9e757a1.cjs.dev.js} +46 -46
- package/dist/{slicedToArray-22567815.esm.js → createForOfIteratorHelper-9b80f1a2.esm.js} +136 -106
- package/dist/{slicedToArray-d99b4e2e.cjs.prod.js → createForOfIteratorHelper-9ca2078d.cjs.prod.js} +142 -111
- package/dist/{slicedToArray-c8a29f6b.cjs.dev.js → createForOfIteratorHelper-f2d7ac6d.cjs.dev.js} +142 -111
- package/dist/declarations/src/client/index.d.ts +2 -0
- package/dist/declarations/src/internal/ApiRoutes.d.ts +35 -0
- package/dist/declarations/src/internal/index.d.ts +2 -0
- package/dist/declarations/src/internal/pageInspection.d.ts +117 -0
- package/dist/declarations/src/internal/quickPreview.d.ts +91 -0
- package/dist/declarations/src/internal/valCanvasProtocol.d.ts +53 -0
- package/dist/declarations/src/publish/buildProposal.d.ts +16 -1
- package/dist/declarations/src/publish/buildQuickPreview.d.ts +46 -0
- package/dist/declarations/src/publish/index.d.ts +3 -2
- package/dist/declarations/src/publish/runStudioDeploy.d.ts +10 -0
- package/dist/getSitemapTree-5354ce90.cjs.prod.js +1421 -0
- package/dist/getSitemapTree-97b3166f.esm.js +1381 -0
- package/dist/getSitemapTree-d934ff9c.cjs.dev.js +1421 -0
- package/dist/{proposalProject-689c24cc.esm.js → proposalProject-5da177d5.esm.js} +1 -2
- package/dist/{proposalProject-926f2c68.cjs.dev.js → proposalProject-76caa377.cjs.prod.js} +2 -3
- package/dist/{proposalProject-fab0c026.cjs.prod.js → proposalProject-81fee08f.cjs.dev.js} +2 -3
- package/dist/{protocol-7ddc1a71.esm.js → protocol-55cfa3cf.esm.js} +1 -1
- package/dist/{protocol-4e2a455b.cjs.prod.js → protocol-b1055ef0.cjs.prod.js} +6 -6
- package/dist/{protocol-ac1c3ec7.cjs.dev.js → protocol-d0efb8cd.cjs.dev.js} +6 -6
- package/dist/wrapNativeSuper-639b12b7.esm.js +107 -0
- package/dist/wrapNativeSuper-8673414f.cjs.prod.js +113 -0
- package/dist/wrapNativeSuper-933f991e.cjs.dev.js +113 -0
- package/internal/dist/valbuild-shared-internal.cjs.dev.js +94 -34
- package/internal/dist/valbuild-shared-internal.cjs.prod.js +94 -34
- package/internal/dist/valbuild-shared-internal.esm.js +52 -6
- package/package.json +2 -2
- package/publish/dist/valbuild-shared-publish.cjs.dev.js +589 -237
- package/publish/dist/valbuild-shared-publish.cjs.prod.js +589 -237
- package/publish/dist/valbuild-shared-publish.esm.js +504 -155
- package/typecheck/dist/valbuild-shared-typecheck.cjs.dev.js +34 -34
- package/typecheck/dist/valbuild-shared-typecheck.cjs.prod.js +34 -34
- package/typecheck/dist/valbuild-shared-typecheck.esm.js +5 -5
- package/typecheck/testing/dist/valbuild-shared-typecheck-testing.cjs.dev.js +7 -7
- package/typecheck/testing/dist/valbuild-shared-typecheck-testing.cjs.prod.js +7 -7
- package/typecheck/testing/dist/valbuild-shared-typecheck-testing.esm.js +3 -3
- package/dist/createForOfIteratorHelper-666a6d17.esm.js +0 -137
- package/dist/createForOfIteratorHelper-87a33eff.cjs.dev.js +0 -145
- package/dist/createForOfIteratorHelper-fef4fa7d.cjs.prod.js +0 -145
- package/dist/getSitemapTree-873f7266.cjs.prod.js +0 -743
- package/dist/getSitemapTree-b6161fd8.esm.js +0 -717
- package/dist/getSitemapTree-be70d9fc.cjs.dev.js +0 -743
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Looking at a page from the design tab (valbuild/home `docs/design-tab.md`):
|
|
3
|
+
* where it is -- its path and scroll, so a new build opens at the same place
|
|
4
|
+
* -- and what is on it, so the assistant can check its own change
|
|
5
|
+
* (`read_page`).
|
|
6
|
+
*
|
|
7
|
+
* Plain DOM and in `shared` for the reason `elementPicker.ts` is: the canvas
|
|
8
|
+
* bridge (`@valbuild/next`, `@valbuild/tanstack`) runs it inside the
|
|
9
|
+
* proposal's page, which is another origin than the tab and the only place
|
|
10
|
+
* the page can be read. Only what is returned here crosses the frame
|
|
11
|
+
* (`valCanvasProtocol.ts`).
|
|
12
|
+
*/
|
|
13
|
+
/** Where the page is: what a new build is opened at. */
|
|
14
|
+
export type PageLocation = {
|
|
15
|
+
/** Its path and query, without the canvas's own parameter. */
|
|
16
|
+
path: string;
|
|
17
|
+
scrollX: number;
|
|
18
|
+
scrollY: number;
|
|
19
|
+
};
|
|
20
|
+
/** A box on the page, in CSS pixels from the top of the document. */
|
|
21
|
+
export type PageBox = {
|
|
22
|
+
x: number;
|
|
23
|
+
y: number;
|
|
24
|
+
width: number;
|
|
25
|
+
height: number;
|
|
26
|
+
};
|
|
27
|
+
/** One thing a reader would notice on the page, in document order. */
|
|
28
|
+
export type PageOutlineItem = {
|
|
29
|
+
kind: "heading" | "text" | "link" | "button" | "image" | "input" | "section";
|
|
30
|
+
tag: string;
|
|
31
|
+
/** How to find it again: `read_page` with this `selector`. */
|
|
32
|
+
selector: string;
|
|
33
|
+
/** The words in it, shortened. Absent for an image or an empty element. */
|
|
34
|
+
text?: string;
|
|
35
|
+
/** `h1` is 1. */
|
|
36
|
+
level?: number;
|
|
37
|
+
href?: string;
|
|
38
|
+
alt?: string;
|
|
39
|
+
src?: string;
|
|
40
|
+
box: PageBox;
|
|
41
|
+
};
|
|
42
|
+
/** One element in detail: what `read_page` answers for a `selector`. */
|
|
43
|
+
export type PageElementDetail = {
|
|
44
|
+
selector: string;
|
|
45
|
+
tag: string;
|
|
46
|
+
text: string;
|
|
47
|
+
box: PageBox;
|
|
48
|
+
/** How many lines its text wraps to, when it can be told. */
|
|
49
|
+
lines?: number;
|
|
50
|
+
/** The computed styles a change to a design is usually about. */
|
|
51
|
+
styles: Record<string, string>;
|
|
52
|
+
/** Its children, one level down. */
|
|
53
|
+
children: Array<{
|
|
54
|
+
tag: string;
|
|
55
|
+
selector: string;
|
|
56
|
+
text?: string;
|
|
57
|
+
box: PageBox;
|
|
58
|
+
}>;
|
|
59
|
+
};
|
|
60
|
+
export type PageSnapshot = {
|
|
61
|
+
/** The page's own address. */
|
|
62
|
+
url: string;
|
|
63
|
+
title: string;
|
|
64
|
+
viewport: {
|
|
65
|
+
width: number;
|
|
66
|
+
height: number;
|
|
67
|
+
scrollY: number;
|
|
68
|
+
/** How tall the whole page is. */
|
|
69
|
+
pageHeight: number;
|
|
70
|
+
};
|
|
71
|
+
outline: PageOutlineItem[];
|
|
72
|
+
/** Cut short at `maxItems`: narrow with a `selector`. */
|
|
73
|
+
truncated?: true;
|
|
74
|
+
/** The element asked for by `selector`. */
|
|
75
|
+
element?: PageElementDetail;
|
|
76
|
+
/** The `selector` matched nothing. */
|
|
77
|
+
notFound?: string;
|
|
78
|
+
};
|
|
79
|
+
/** Where `win` is now. */
|
|
80
|
+
export declare function pageLocationOf(win: Window): PageLocation;
|
|
81
|
+
/**
|
|
82
|
+
* Report where the page is as it moves: on scroll, a little after it settles,
|
|
83
|
+
* and when it navigates -- which a client-side router does without an event,
|
|
84
|
+
* so the address is also looked at now and then. Returns the way to stop.
|
|
85
|
+
*/
|
|
86
|
+
export declare function watchPageLocation(win: Window, onChange: (location: PageLocation) => void, options?: {
|
|
87
|
+
settleMs?: number;
|
|
88
|
+
pollMs?: number;
|
|
89
|
+
}): () => void;
|
|
90
|
+
/**
|
|
91
|
+
* Scroll to where the last build was, once the page is tall enough to: a page
|
|
92
|
+
* that is still loading its content is shorter than it will be, so this tries
|
|
93
|
+
* again each frame for a while rather than stopping at the bottom of half a
|
|
94
|
+
* page. Returns the way to stop trying.
|
|
95
|
+
*/
|
|
96
|
+
export declare function restoreScroll(win: Window, x: number, y: number, options?: {
|
|
97
|
+
withinMs?: number;
|
|
98
|
+
}): () => void;
|
|
99
|
+
/**
|
|
100
|
+
* What is on the page, as a reader would take it in: headings, text, links,
|
|
101
|
+
* buttons, images and inputs, in order, each with where it is. With a
|
|
102
|
+
* `selector`, that element in detail -- its computed styles, how many lines
|
|
103
|
+
* its text wraps to, and its children.
|
|
104
|
+
*
|
|
105
|
+
* `root` is what selectors are written from: the body, as `describeElement`
|
|
106
|
+
* writes them for a picked element.
|
|
107
|
+
*/
|
|
108
|
+
export declare function readPageSnapshot(doc: Document, options?: {
|
|
109
|
+
selector?: string;
|
|
110
|
+
maxItems?: number;
|
|
111
|
+
}): PageSnapshot;
|
|
112
|
+
/**
|
|
113
|
+
* The element a selector names, written as `describeElement` writes them --
|
|
114
|
+
* from the body down, or from an element with an id -- or any selector a
|
|
115
|
+
* person would write.
|
|
116
|
+
*/
|
|
117
|
+
export declare function findBySelector(root: Element, selector: string): Element | null;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A quick preview: a proposal's page, running the proposal's CLIENT code
|
|
3
|
+
* built in the design tab, without a build being uploaded or served
|
|
4
|
+
* (valbuild/home `docs/design-tab.md`).
|
|
5
|
+
*
|
|
6
|
+
* A full build of a proposal bundles the app for the server and the browser,
|
|
7
|
+
* uploads it, and has the platform render every page before it is served --
|
|
8
|
+
* minutes. Most of what the design tab changes is components and styles,
|
|
9
|
+
* which the browser half alone shows. So the tab bundles the app in its
|
|
10
|
+
* builder worker, and a service worker on the proposal's address hands the
|
|
11
|
+
* page that bundle instead of the served one:
|
|
12
|
+
*
|
|
13
|
+
* 1. The tab sends the files (`/_app/app.js`, its chunks, the stylesheet and
|
|
14
|
+
* assets) to the page in the preview, over the canvas protocol.
|
|
15
|
+
* 2. The page -- the bridge, which is the only thing at that origin the tab
|
|
16
|
+
* can talk to -- registers {@link QUICK_PREVIEW_SERVICE_WORKER_SOURCE}
|
|
17
|
+
* and stores the files in it (Cache Storage, so a worker the browser
|
|
18
|
+
* stopped still has them).
|
|
19
|
+
* 3. The tab opens the page with `?val_quick=<id>`. The worker serves that
|
|
20
|
+
* document's `/_app/` requests from the files, and everything else from
|
|
21
|
+
* the network: the HTML is the last build's, rendered by its server, and
|
|
22
|
+
* the new code takes it over in the browser.
|
|
23
|
+
*
|
|
24
|
+
* What it cannot show, and the tab says so: anything on the server. Server
|
|
25
|
+
* functions, API routes and loaders that run there are the last build's, as
|
|
26
|
+
* is the page's first render and its `head`. A new dependency is not there
|
|
27
|
+
* either. A build is still what decides, before Publish.
|
|
28
|
+
*
|
|
29
|
+
* Only a document opened with the parameter is served from the files, so a
|
|
30
|
+
* visitor to the proposal's address -- even in the same browser -- is never
|
|
31
|
+
* given them.
|
|
32
|
+
*/
|
|
33
|
+
/** The parameter a quick preview's page is opened with. */
|
|
34
|
+
export declare const QUICK_PREVIEW_PARAM = "val_quick";
|
|
35
|
+
/** Where Val's API serves the worker: under `/api/val`. */
|
|
36
|
+
export declare const QUICK_PREVIEW_SERVICE_WORKER_PATH = "/quick-preview-sw.js";
|
|
37
|
+
/** What the page sends the worker to store a preview's files. */
|
|
38
|
+
export declare const QUICK_PREVIEW_STORE_MESSAGE = "val-quick-preview-store";
|
|
39
|
+
/**
|
|
40
|
+
* A preview's files, by their path under `/_app/`: `app.js`, `c-<hash>.js`,
|
|
41
|
+
* `app.css`, `a/<hash>.png`. A binary file is base64.
|
|
42
|
+
*/
|
|
43
|
+
export type QuickPreviewFiles = Record<string, {
|
|
44
|
+
body: string;
|
|
45
|
+
contentType: string;
|
|
46
|
+
base64?: true;
|
|
47
|
+
}>;
|
|
48
|
+
/**
|
|
49
|
+
* The files of a quick preview: paths under `/_app/` with no way out of it,
|
|
50
|
+
* each a string body and a type.
|
|
51
|
+
*/
|
|
52
|
+
export declare function isQuickPreviewFiles(value: unknown): value is QuickPreviewFiles;
|
|
53
|
+
/**
|
|
54
|
+
* The worker, as the source it is served as: plain, and small, because it is
|
|
55
|
+
* served as a file of its own (`demoServiceWorker.ts` is the same).
|
|
56
|
+
*/
|
|
57
|
+
export declare const QUICK_PREVIEW_SERVICE_WORKER_SOURCE = "\n\"use strict\";\nconst PARAM = \"val_quick\";\nconst CACHE = \"val-quick-preview\";\nconst PREFIX = \"/__val_quick/\";\nconst INDEX = PREFIX + \"index\";\nconst KEEP = 4;\n\nself.addEventListener(\"install\", () => self.skipWaiting());\nself.addEventListener(\"activate\", (event) => {\n event.waitUntil(self.clients.claim());\n});\n\nself.addEventListener(\"message\", (event) => {\n const data = event.data;\n if (!data || data.type !== \"val-quick-preview-store\") return;\n const port = event.ports && event.ports[0];\n event.waitUntil(\n store(data.id, data.files).then(\n () => port && port.postMessage({ ok: true }),\n (error) =>\n port &&\n port.postMessage({\n ok: false,\n message: String((error && error.message) || error),\n }),\n ),\n );\n});\n\nfunction keyOf(id, path) {\n return PREFIX + id + \"/\" + path;\n}\n\nasync function store(id, files) {\n const cache = await caches.open(CACHE);\n for (const path of Object.keys(files)) {\n const file = files[path];\n const body = file.base64\n ? Uint8Array.from(atob(file.body), (c) => c.charCodeAt(0))\n : file.body;\n await cache.put(\n keyOf(id, path),\n new Response(body, {\n headers: { \"Content-Type\": file.contentType, \"Cache-Control\": \"no-store\" },\n }),\n );\n }\n // The newest few previews are kept; older ones are deleted.\n const index = await cache.match(INDEX);\n const ids = [id].concat(\n (index ? await index.json() : []).filter((other) => other !== id),\n );\n const dropped = ids.slice(KEEP);\n if (dropped.length > 0) {\n for (const request of await cache.keys()) {\n const path = new URL(request.url).pathname;\n if (dropped.some((old) => path.startsWith(PREFIX + old + \"/\"))) {\n await cache.delete(request);\n }\n }\n }\n await cache.put(INDEX, new Response(JSON.stringify(ids.slice(0, KEEP))));\n}\n\n/** Which preview a document is: by its id, or by the address it was opened at. */\nconst byClient = new Map();\nasync function previewOf(clientId) {\n if (!clientId) return null;\n if (byClient.has(clientId)) return byClient.get(clientId);\n const client = await self.clients.get(clientId);\n const id = client ? new URL(client.url).searchParams.get(PARAM) : null;\n byClient.set(clientId, id);\n return id;\n}\n\nself.addEventListener(\"fetch\", (event) => {\n const url = new URL(event.request.url);\n if (url.origin !== self.location.origin) return;\n if (event.request.mode === \"navigate\") {\n if (event.resultingClientId) {\n byClient.set(event.resultingClientId, url.searchParams.get(PARAM));\n }\n return;\n }\n if (!url.pathname.startsWith(\"/_app/\")) return;\n event.respondWith(serve(event, url));\n});\n\nasync function serve(event, url) {\n const id = await previewOf(event.clientId);\n if (id) {\n const hit = await caches.match(keyOf(id, url.pathname.slice(6)), {\n cacheName: CACHE,\n });\n if (hit) return hit;\n }\n return fetch(event.request);\n}\n";
|
|
58
|
+
/**
|
|
59
|
+
* Store a preview's files in the worker, registering it first: what the
|
|
60
|
+
* bridge does when the tab sends `quickPreview`. `swUrl` is the worker's
|
|
61
|
+
* address on this origin (`/api/val` + {@link QUICK_PREVIEW_SERVICE_WORKER_PATH}).
|
|
62
|
+
*/
|
|
63
|
+
export declare function storeQuickPreview(id: string, files: QuickPreviewFiles, options: {
|
|
64
|
+
swUrl: string;
|
|
65
|
+
container?: ServiceWorkerContainer;
|
|
66
|
+
}): Promise<void>;
|
|
67
|
+
/** The address of a page as a quick preview `id`. */
|
|
68
|
+
export declare function withQuickPreviewParam(url: string, id: string): string;
|
|
69
|
+
/**
|
|
70
|
+
* The one origin allowed to send this page a quick preview: the site's, where
|
|
71
|
+
* the design tab is, as this page's own Val server says it (the proposals
|
|
72
|
+
* list's `siteUrl`). `null` when it does not say.
|
|
73
|
+
*
|
|
74
|
+
* A quick preview is code that runs on this address, so the bridge takes one
|
|
75
|
+
* only from its parent, and only when that parent is the site: a page that
|
|
76
|
+
* framed this one could otherwise post a script into the worker and open
|
|
77
|
+
* the frame on it.
|
|
78
|
+
*/
|
|
79
|
+
export declare function quickPreviewSiteOrigin(api: string, fetchImpl?: typeof fetch): Promise<string | null>;
|
|
80
|
+
/**
|
|
81
|
+
* Whether `origin` may ask this page for what only the design tab should
|
|
82
|
+
* have -- what is on it (`readPage`), or code to run (`quickPreview`): this
|
|
83
|
+
* page's own origin (the Studio's canvas), or the site's, where the design
|
|
84
|
+
* tab is ({@link quickPreviewSiteOrigin}). Asked of the server once, and
|
|
85
|
+
* again only while it has not said.
|
|
86
|
+
*/
|
|
87
|
+
export declare function isDesignTabOrigin(origin: string, options: {
|
|
88
|
+
api: string;
|
|
89
|
+
own: string;
|
|
90
|
+
fetchImpl?: typeof fetch;
|
|
91
|
+
}): Promise<boolean>;
|
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
*/
|
|
22
22
|
import type { ModuleFilePath, SourcePath } from "@valbuild/core";
|
|
23
23
|
import type { PickedElement, PickModifier } from "./elementPicker.js";
|
|
24
|
+
import type { PageLocation, PageSnapshot } from "./pageInspection.js";
|
|
25
|
+
import { type QuickPreviewFiles } from "./quickPreview.js";
|
|
24
26
|
/** Marks a page load as the studio's canvas frame. */
|
|
25
27
|
export declare const VAL_CANVAS_PARAM = "val_canvas";
|
|
26
28
|
/**
|
|
@@ -188,6 +190,30 @@ export type ValCanvasPageMessage = {
|
|
|
188
190
|
*/
|
|
189
191
|
val: typeof VAL_CANVAS_MESSAGE;
|
|
190
192
|
type: "elementPickingStopped";
|
|
193
|
+
} | ({
|
|
194
|
+
/**
|
|
195
|
+
* Where the page is: its path and scroll, as it moves. The design tab
|
|
196
|
+
* opens a new build there (`scrollTo`), so a new version replaces the
|
|
197
|
+
* page in place rather than starting over at the top of the front page.
|
|
198
|
+
*/
|
|
199
|
+
val: typeof VAL_CANVAS_MESSAGE;
|
|
200
|
+
type: "location";
|
|
201
|
+
} & PageLocation) | {
|
|
202
|
+
/** What `readPage` asked for, or why it could not be read. */
|
|
203
|
+
val: typeof VAL_CANVAS_MESSAGE;
|
|
204
|
+
type: "pageRead";
|
|
205
|
+
requestId: string;
|
|
206
|
+
snapshot: PageSnapshot | null;
|
|
207
|
+
error?: string;
|
|
208
|
+
} | {
|
|
209
|
+
/**
|
|
210
|
+
* A quick preview's files are stored in the page's worker, and a page
|
|
211
|
+
* opened with its id is served them (`quickPreview.ts`) -- or why not.
|
|
212
|
+
*/
|
|
213
|
+
val: typeof VAL_CANVAS_MESSAGE;
|
|
214
|
+
type: "quickPreviewStored";
|
|
215
|
+
id: string;
|
|
216
|
+
error?: string;
|
|
191
217
|
};
|
|
192
218
|
/** What the studio tells the page. */
|
|
193
219
|
export type ValCanvasStudioMessage = {
|
|
@@ -291,6 +317,33 @@ export type ValCanvasStudioMessage = {
|
|
|
291
317
|
modifier: PickModifier;
|
|
292
318
|
/** Whether the studio still holds the last pick: false takes its outline down. */
|
|
293
319
|
keepPicked: boolean;
|
|
320
|
+
} | {
|
|
321
|
+
/** Scroll to where the page before this one was (`location`). */
|
|
322
|
+
val: typeof VAL_CANVAS_MESSAGE;
|
|
323
|
+
type: "scrollTo";
|
|
324
|
+
x: number;
|
|
325
|
+
y: number;
|
|
326
|
+
} | {
|
|
327
|
+
/**
|
|
328
|
+
* Read what is on the page (`readPageSnapshot`): the assistant's
|
|
329
|
+
* `read_page`. Answered with `pageRead` and the same `requestId`. A
|
|
330
|
+
* bridge that predates it never answers, and the tab says so.
|
|
331
|
+
*/
|
|
332
|
+
val: typeof VAL_CANVAS_MESSAGE;
|
|
333
|
+
type: "readPage";
|
|
334
|
+
requestId: string;
|
|
335
|
+
selector?: string;
|
|
336
|
+
maxItems?: number;
|
|
337
|
+
} | {
|
|
338
|
+
/**
|
|
339
|
+
* Store a quick preview's files in this origin's worker
|
|
340
|
+
* (`storeQuickPreview`): the tab cannot, being another origin.
|
|
341
|
+
* Answered with `quickPreviewStored`.
|
|
342
|
+
*/
|
|
343
|
+
val: typeof VAL_CANVAS_MESSAGE;
|
|
344
|
+
type: "quickPreview";
|
|
345
|
+
id: string;
|
|
346
|
+
files: QuickPreviewFiles;
|
|
294
347
|
};
|
|
295
348
|
/** Narrow an unknown `event.data` to a message from the page. */
|
|
296
349
|
export declare function isValCanvasPageMessage(data: unknown): data is ValCanvasPageMessage;
|
|
@@ -45,7 +45,14 @@ export type ProposalBuildOutcome<P> = {
|
|
|
45
45
|
} | {
|
|
46
46
|
status: "failed";
|
|
47
47
|
message: string;
|
|
48
|
+
/**
|
|
49
|
+
* Stopped by whoever started it (`signal`), not by anything wrong with
|
|
50
|
+
* the build: nothing to fix, and nothing to show as an error.
|
|
51
|
+
*/
|
|
52
|
+
cancelled?: true;
|
|
48
53
|
};
|
|
54
|
+
/** What a cancelled build answers. */
|
|
55
|
+
export declare const BUILD_CANCELLED_MESSAGE = "The build was cancelled.";
|
|
49
56
|
/**
|
|
50
57
|
* Where a build of the proposal is, around the deploy: the deploy's own steps
|
|
51
58
|
* are the Studio's deploy state (`useStudioDeployState`), and these are the
|
|
@@ -93,13 +100,21 @@ export declare function buildProposal<P extends BuiltProposal>(deps: {
|
|
|
93
100
|
* on the layer content had built for it; `undefined` builds on the site's,
|
|
94
101
|
* as every build of a proposal did before.
|
|
95
102
|
*/
|
|
96
|
-
deploy: (files: Record<string, string | null>, target: BuildTargetResponse | undefined) => Promise<StudioDeployResult>;
|
|
103
|
+
deploy: (files: Record<string, string | null>, target: BuildTargetResponse | undefined, signal: AbortSignal | undefined) => Promise<StudioDeployResult>;
|
|
97
104
|
/**
|
|
98
105
|
* Whether this document can build at all (`canBuildHere`): Safari cannot,
|
|
99
106
|
* and a proposal's build has no builder tab to hand off to yet.
|
|
100
107
|
*/
|
|
101
108
|
canBuildHere: () => boolean;
|
|
102
109
|
onStep?: (step: ProposalBuildStep) => void;
|
|
110
|
+
/**
|
|
111
|
+
* Stops the build: Cancel, or a watchdog that saw it stall. Answered at
|
|
112
|
+
* once, whatever the build was waiting on, and nothing after it is done --
|
|
113
|
+
* a build stopped while it uploads is never served. Aborted with an `Error`
|
|
114
|
+
* of its own, the build fails with that error's message; otherwise it is
|
|
115
|
+
* `cancelled`.
|
|
116
|
+
*/
|
|
117
|
+
signal?: AbortSignal;
|
|
103
118
|
/** For tests: the clock, and waiting on it. */
|
|
104
119
|
now?: () => number;
|
|
105
120
|
sleep?: (ms: number) => Promise<void>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { BuildOutput } from "@valbuild/tanstack-build";
|
|
2
|
+
import type { BuildTargetResponse } from "../internal/index.js";
|
|
3
|
+
import type { QuickPreviewFiles } from "../internal/quickPreview.js";
|
|
4
|
+
import type { StudioBuilder } from "./builder.js";
|
|
5
|
+
export type QuickPreviewOutcome = {
|
|
6
|
+
status: "built";
|
|
7
|
+
files: QuickPreviewFiles;
|
|
8
|
+
/** What the proposal's files were staged as: the build is of these. */
|
|
9
|
+
inputs: string | null;
|
|
10
|
+
} | {
|
|
11
|
+
status: "failed";
|
|
12
|
+
message: string;
|
|
13
|
+
};
|
|
14
|
+
export declare function buildQuickPreview(deps: {
|
|
15
|
+
name: string;
|
|
16
|
+
/** The proposal's files, and what they build on. */
|
|
17
|
+
proposals: {
|
|
18
|
+
files(name: string): Promise<{
|
|
19
|
+
files: Record<string, string | null>;
|
|
20
|
+
staged: {
|
|
21
|
+
inputs: string | null;
|
|
22
|
+
};
|
|
23
|
+
}>;
|
|
24
|
+
buildTarget(name: string): Promise<{
|
|
25
|
+
target: BuildTargetResponse;
|
|
26
|
+
layer: "site" | "own";
|
|
27
|
+
}>;
|
|
28
|
+
};
|
|
29
|
+
/** The site's source, which the proposal's files are laid over. */
|
|
30
|
+
siteSource: () => Promise<Record<string, string> | null>;
|
|
31
|
+
/** The site's build target: what the proposal's address serves. */
|
|
32
|
+
siteTarget: () => Promise<BuildTargetResponse>;
|
|
33
|
+
loadBuilder: () => Promise<StudioBuilder>;
|
|
34
|
+
/** Generates `src/routeTree.gen.ts`: see `runStudioDeploy`. */
|
|
35
|
+
generateRouteTree?: (files: Record<string, string>) => Promise<Record<string, string>>;
|
|
36
|
+
/** Each step as it begins: for the tab's progress and timings. */
|
|
37
|
+
onStep?: (label: string) => void;
|
|
38
|
+
signal?: AbortSignal;
|
|
39
|
+
}): Promise<QuickPreviewOutcome>;
|
|
40
|
+
/**
|
|
41
|
+
* The browser half of a build, as the worker serves it under `/_app/`. The
|
|
42
|
+
* stylesheet only when the tab compiled one: an empty one is the case where a
|
|
43
|
+
* build ships the site's live stylesheet (`liveStylesheet` on
|
|
44
|
+
* `runStudioDeploy`), and the page already has that.
|
|
45
|
+
*/
|
|
46
|
+
export declare function clientFilesOf(build: BuildOutput): QuickPreviewFiles;
|
|
@@ -15,9 +15,10 @@ export type { StudioBuilder } from "./builder.js";
|
|
|
15
15
|
export { StudioPublishError, callJson, isTransientPublishError, onPublishRefusal, } from "./callJson.js";
|
|
16
16
|
export { StudioUploadError, createStudioPublishClient, isExpiredSlot, publishApiOf, type CarriedArtifact, type LivePublicFiles, type PublishApiAt, type StudioPublishClient, } from "./publishClient.js";
|
|
17
17
|
export { runStudioPublish, type PublishPhase, type StudioPublishResult, } from "./runStudioPublish.js";
|
|
18
|
-
export { carriedInto, runStudioDeploy, splitBinaryFiles, withCommittedFiles, type CommittedBinaryFiles, type DeployPhase, type StudioDeployOptions, type StudioDeployResult, } from "./runStudioDeploy.js";
|
|
18
|
+
export { DEPLOY_STOPPED_MESSAGE, carriedInto, runStudioDeploy, splitBinaryFiles, withCommittedFiles, type CommittedBinaryFiles, type DeployPhase, type StudioDeployOptions, type StudioDeployResult, } from "./runStudioDeploy.js";
|
|
19
19
|
export { STUDIO_OUT_OF_DATE, STUDIO_OUT_OF_DATE_MESSAGE, layerMoved, loadedLayer, markStudioOutOfDate, readLiveLayer, rememberLoadedLayer, resetLoadedLayerForTests, siteMovedSinceLoad, studioOutOfDateRefusals, subscribeStudioOutOfDate, type LayerReading, } from "./loadedLayer.js";
|
|
20
20
|
export { MergePrepareAnswer, createStudioJobClient, isMergeChange, type PreparedJob, type StudioJobClient, } from "./jobClient.js";
|
|
21
21
|
export { RENEW_EVERY_MS, runJobToEnd, runStudioJob, type JobPhase, type StudioJobResult, } from "./runStudioJob.js";
|
|
22
|
-
export { SERVE_POLL_MS, SERVE_WAIT_MS, buildProposal, withoutLockfiles, type BuiltProposal, type ProposalBuildClient, type ProposalBuildOutcome, type ProposalBuildStep, } from "./buildProposal.js";
|
|
22
|
+
export { BUILD_CANCELLED_MESSAGE, SERVE_POLL_MS, SERVE_WAIT_MS, buildProposal, withoutLockfiles, type BuiltProposal, type ProposalBuildClient, type ProposalBuildOutcome, type ProposalBuildStep, } from "./buildProposal.js";
|
|
23
23
|
export { proposalProject } from "./proposalProject.js";
|
|
24
|
+
export { buildQuickPreview, clientFilesOf, type QuickPreviewOutcome, } from "./buildQuickPreview.js";
|
|
@@ -211,6 +211,14 @@ export interface StudioDeployOptions {
|
|
|
211
211
|
*/
|
|
212
212
|
generateRouteTree?: (files: Record<string, string>) => Promise<Record<string, string>>;
|
|
213
213
|
onPhase: (phase: DeployPhase) => void;
|
|
214
|
+
/**
|
|
215
|
+
* Stops the deploy between its steps: a cancelled proposal build. What is
|
|
216
|
+
* in flight is the caller's to stop -- the requests, through the client's
|
|
217
|
+
* `fetchImpl`; the builder, by stopping its worker -- and nothing after the
|
|
218
|
+
* step it was on is started, so a build stopped before its upload is never
|
|
219
|
+
* declared.
|
|
220
|
+
*/
|
|
221
|
+
signal?: AbortSignal;
|
|
214
222
|
}
|
|
215
223
|
export declare function runStudioDeploy(options: StudioDeployOptions): Promise<StudioDeployResult>;
|
|
216
224
|
/**
|
|
@@ -242,3 +250,5 @@ export declare function splitBinaryFiles(files: Record<string, string>): {
|
|
|
242
250
|
export declare function carriedInto(built: ReadonlyArray<{
|
|
243
251
|
key: string;
|
|
244
252
|
}>, carried: ReadonlyArray<CarriedArtifact>, committed: Record<string, string | null> | null): CarriedArtifact[];
|
|
253
|
+
/** What a deploy stopped by its `signal` answers. */
|
|
254
|
+
export declare const DEPLOY_STOPPED_MESSAGE = "The build was stopped.";
|