@valbuild/shared 0.150.17 → 0.150.20
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 +18 -0
- package/client/dist/valbuild-shared-client.cjs.dev.js +2 -1
- package/client/dist/valbuild-shared-client.cjs.prod.js +2 -1
- package/client/dist/valbuild-shared-client.esm.js +1 -1
- package/dist/declarations/src/internal/quickPreview.d.ts +17 -1
- package/dist/declarations/src/publish/buildProposal.d.ts +62 -0
- package/dist/declarations/src/publish/index.d.ts +1 -1
- package/dist/{getSitemapTree-98642b57.cjs.dev.js → getSitemapTree-6dfa2f4e.cjs.dev.js} +19 -1
- package/dist/{getSitemapTree-97713490.cjs.prod.js → getSitemapTree-8a04f3cf.cjs.prod.js} +19 -1
- package/dist/{getSitemapTree-7c848c94.esm.js → getSitemapTree-fef55872.esm.js} +19 -2
- package/internal/dist/valbuild-shared-internal.cjs.dev.js +2 -1
- package/internal/dist/valbuild-shared-internal.cjs.prod.js +2 -1
- package/internal/dist/valbuild-shared-internal.esm.js +1 -1
- package/package.json +1 -1
- package/publish/dist/valbuild-shared-publish.cjs.dev.js +257 -0
- package/publish/dist/valbuild-shared-publish.cjs.prod.js +257 -0
- package/publish/dist/valbuild-shared-publish.esm.js +254 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @valbuild/shared
|
|
2
2
|
|
|
3
|
+
## 0.150.20
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#998](https://github.com/valbuild/val/pull/998) [`c597b3b`](https://github.com/valbuild/val/commit/c597b3bcb9f3bbda285ab6f4977d65ed7f5f161d) Thanks [@freekh](https://github.com/freekh)! - **A quick preview now shows layout changes, not only text.** A quick preview loads the proposal's new code into a page the last build rendered on the server. React kept that page's markup wherever only attributes differed, so a change to classes (a layout made horizontal, a gap, a colour already in the site's styles) showed nothing, while a change to text did. The page is now rendered from the new code instead.
|
|
8
|
+
|
|
9
|
+
The design tab's assistant no longer offers `screenshot_page`, whose picture never came back from the page. `read_page` gives it the computed styles, sizes and positions it was for.
|
|
10
|
+
|
|
11
|
+
The assistant builds a proposal far less often. A quick preview shows components, layout, styles, text and content. It builds only for what a quick preview can't show, such as an added or renamed route, code that runs on the server, a schema or dependencies, and otherwise once, when a request is finished.
|
|
12
|
+
|
|
13
|
+
## 0.150.18
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- [#994](https://github.com/valbuild/val/pull/994) [`43f72c8`](https://github.com/valbuild/val/commit/43f72c85c2114fe9a0ce536204858d2d3c05f962) Thanks [@freekh](https://github.com/freekh)! - **Proposals can be built by Val Build instead of in your browser.** When Val Build builds your project's proposals, the design tab's **Build** and the assistant's `build_proposal` in the design tab ask it to build the proposal, and the Studio waits until the build is served at the proposal's address. A small code change is built, checked and on the proposal's page in a few seconds, against around twenty for the build alone in the browser. Nothing is downloaded first, no builder tab opens on an iPhone or in Safari, and closing the tab does not stop the build.
|
|
18
|
+
|
|
19
|
+
Val Build is turning this on project by project, in the design tab first. Until it is on for yours, Build works as before, in the browser, and so does Build in the proposals bar.
|
|
20
|
+
|
|
3
21
|
## 0.150.17
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var getSitemapTree = require('../../dist/getSitemapTree-
|
|
5
|
+
var getSitemapTree = require('../../dist/getSitemapTree-6dfa2f4e.cjs.dev.js');
|
|
6
6
|
require('../../dist/createForOfIteratorHelper-f2d7ac6d.cjs.dev.js');
|
|
7
7
|
require('@valbuild/core');
|
|
8
8
|
|
|
@@ -11,6 +11,7 @@ require('@valbuild/core');
|
|
|
11
11
|
exports.DEFAULT_CANVAS_SELECTION = getSitemapTree.DEFAULT_CANVAS_SELECTION;
|
|
12
12
|
exports.DEFAULT_CANVAS_SELECTION_SOFT = getSitemapTree.DEFAULT_CANVAS_SELECTION_SOFT;
|
|
13
13
|
exports.QUICK_PREVIEW_PARAM = getSitemapTree.QUICK_PREVIEW_PARAM;
|
|
14
|
+
exports.QUICK_PREVIEW_RENDER_SCRIPT = getSitemapTree.QUICK_PREVIEW_RENDER_SCRIPT;
|
|
14
15
|
exports.QUICK_PREVIEW_SERVICE_WORKER_PATH = getSitemapTree.QUICK_PREVIEW_SERVICE_WORKER_PATH;
|
|
15
16
|
exports.QUICK_PREVIEW_SERVICE_WORKER_SOURCE = getSitemapTree.QUICK_PREVIEW_SERVICE_WORKER_SOURCE;
|
|
16
17
|
exports.QUICK_PREVIEW_STORE_MESSAGE = getSitemapTree.QUICK_PREVIEW_STORE_MESSAGE;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var getSitemapTree = require('../../dist/getSitemapTree-
|
|
5
|
+
var getSitemapTree = require('../../dist/getSitemapTree-8a04f3cf.cjs.prod.js');
|
|
6
6
|
require('../../dist/createForOfIteratorHelper-9ca2078d.cjs.prod.js');
|
|
7
7
|
require('@valbuild/core');
|
|
8
8
|
|
|
@@ -11,6 +11,7 @@ require('@valbuild/core');
|
|
|
11
11
|
exports.DEFAULT_CANVAS_SELECTION = getSitemapTree.DEFAULT_CANVAS_SELECTION;
|
|
12
12
|
exports.DEFAULT_CANVAS_SELECTION_SOFT = getSitemapTree.DEFAULT_CANVAS_SELECTION_SOFT;
|
|
13
13
|
exports.QUICK_PREVIEW_PARAM = getSitemapTree.QUICK_PREVIEW_PARAM;
|
|
14
|
+
exports.QUICK_PREVIEW_RENDER_SCRIPT = getSitemapTree.QUICK_PREVIEW_RENDER_SCRIPT;
|
|
14
15
|
exports.QUICK_PREVIEW_SERVICE_WORKER_PATH = getSitemapTree.QUICK_PREVIEW_SERVICE_WORKER_PATH;
|
|
15
16
|
exports.QUICK_PREVIEW_SERVICE_WORKER_SOURCE = getSitemapTree.QUICK_PREVIEW_SERVICE_WORKER_SOURCE;
|
|
16
17
|
exports.QUICK_PREVIEW_STORE_MESSAGE = getSitemapTree.QUICK_PREVIEW_STORE_MESSAGE;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { D as DEFAULT_CANVAS_SELECTION, e as DEFAULT_CANVAS_SELECTION_SOFT, Q as QUICK_PREVIEW_PARAM, u as QUICK_PREVIEW_SERVICE_WORKER_PATH,
|
|
1
|
+
export { D as DEFAULT_CANVAS_SELECTION, e as DEFAULT_CANVAS_SELECTION_SOFT, Q as QUICK_PREVIEW_PARAM, v as QUICK_PREVIEW_RENDER_SCRIPT, u as QUICK_PREVIEW_SERVICE_WORKER_PATH, z as QUICK_PREVIEW_SERVICE_WORKER_SOURCE, x as QUICK_PREVIEW_STORE_MESSAGE, b as VAL_AI_SESSION_STORAGE_KEY, d as VAL_CANVAS_MESSAGE, c as VAL_CANVAS_PARAM, V as VAL_CONFIG_SESSION_STORAGE_KEY, a as VAL_THEME_SESSION_STORAGE_KEY, j as attachElementPicker, k as createPickerOverlay, h as describeElement, l as elementLabel, q as findBySelector, G as formatRoutePattern, H as getNextAppRouterSourceFolder, L as getPageRouterSitemapTree, J as getPageRouterSourceFolder, M as getPatternFromModuleFilePath, I as getTanStackRouterSourceFolder, E as isDesignTabOrigin, y as isQuickPreviewFiles, K as isTanStackRoutesFolder, g as isValCanvasFrame, i as isValCanvasPageMessage, f as isValCanvasStudioMessage, m as modifierLabel, p as pageLocationOf, F as parseRoutePattern, C as quickPreviewSiteOrigin, o as readPageSnapshot, r as restoreScroll, t as screenshotPage, s as startElementPicking, A as storeQuickPreview, n as watchPageLocation, B as withQuickPreviewParam, w as withValCanvasParam } from '../../dist/getSitemapTree-fef55872.esm.js';
|
|
2
2
|
import '../../dist/createForOfIteratorHelper-9b80f1a2.esm.js';
|
|
3
3
|
import '@valbuild/core';
|
|
@@ -20,6 +20,14 @@
|
|
|
20
20
|
* document's `/_app/` requests from the files, and everything else from
|
|
21
21
|
* the network: the HTML is the last build's, rendered by its server, and
|
|
22
22
|
* the new code takes it over in the browser.
|
|
23
|
+
* 4. It takes it over by RENDERING it, not by hydrating it. Hydration keeps
|
|
24
|
+
* the markup the server sent wherever only an attribute differs -- React
|
|
25
|
+
* mends text, never a `className` -- so a change to classes and props,
|
|
26
|
+
* which is most of what the design tab changes, hydrated into the old
|
|
27
|
+
* page and showed nothing. The worker adds a script to the end of that
|
|
28
|
+
* document's `<body>` ({@link QUICK_PREVIEW_RENDER_SCRIPT}) that takes the
|
|
29
|
+
* server's markup out before the app's scripts run, so hydration finds
|
|
30
|
+
* nothing to keep and React renders the page with the new code.
|
|
23
31
|
*
|
|
24
32
|
* What it cannot show, and the tab says so: anything on the server. Server
|
|
25
33
|
* functions, API routes and loaders that run there are the last build's, as
|
|
@@ -34,6 +42,14 @@
|
|
|
34
42
|
export declare const QUICK_PREVIEW_PARAM = "val_quick";
|
|
35
43
|
/** Where Val's API serves the worker: under `/api/val`. */
|
|
36
44
|
export declare const QUICK_PREVIEW_SERVICE_WORKER_PATH = "/quick-preview-sw.js";
|
|
45
|
+
/**
|
|
46
|
+
* What a quick preview's document runs before the app's scripts: the
|
|
47
|
+
* server's markup out of `<body>`, every script left where it is -- the
|
|
48
|
+
* router's dehydrated state and the app's entry are among them. Hydration
|
|
49
|
+
* then finds the body empty and React renders the page, with the new code's
|
|
50
|
+
* attributes and classes, where it would have kept the old ones.
|
|
51
|
+
*/
|
|
52
|
+
export declare const QUICK_PREVIEW_RENDER_SCRIPT: string;
|
|
37
53
|
/** What the page sends the worker to store a preview's files. */
|
|
38
54
|
export declare const QUICK_PREVIEW_STORE_MESSAGE = "val-quick-preview-store";
|
|
39
55
|
/**
|
|
@@ -54,7 +70,7 @@ export declare function isQuickPreviewFiles(value: unknown): value is QuickPrevi
|
|
|
54
70
|
* The worker, as the source it is served as: plain, and small, because it is
|
|
55
71
|
* served as a file of its own (`demoServiceWorker.ts` is the same).
|
|
56
72
|
*/
|
|
57
|
-
export declare const QUICK_PREVIEW_SERVICE_WORKER_SOURCE
|
|
73
|
+
export declare const QUICK_PREVIEW_SERVICE_WORKER_SOURCE: string;
|
|
58
74
|
/**
|
|
59
75
|
* Store a preview's files in the worker, registering it first: what the
|
|
60
76
|
* bridge does when the tab sends `quickPreview`. `swUrl` is the worker's
|
|
@@ -10,6 +10,16 @@ export type BuiltProposal = {
|
|
|
10
10
|
hash: string;
|
|
11
11
|
inputs?: string | null;
|
|
12
12
|
} | null;
|
|
13
|
+
/**
|
|
14
|
+
* A build the platform was asked for and has not served
|
|
15
|
+
* (`buildProposalOnServer`): `pending`, or `failed` with why. Absent from
|
|
16
|
+
* content that does not build.
|
|
17
|
+
*/
|
|
18
|
+
serverBuild?: {
|
|
19
|
+
state: "pending" | "failed";
|
|
20
|
+
inputs: string;
|
|
21
|
+
error: string | null;
|
|
22
|
+
} | null;
|
|
13
23
|
};
|
|
14
24
|
/** The calls a build of a proposal makes. An error carries content's `status`. */
|
|
15
25
|
export type ProposalBuildClient<P extends BuiltProposal> = {
|
|
@@ -119,3 +129,55 @@ export declare function buildProposal<P extends BuiltProposal>(deps: {
|
|
|
119
129
|
now?: () => number;
|
|
120
130
|
sleep?: (ms: number) => Promise<void>;
|
|
121
131
|
}): Promise<ProposalBuildOutcome<P>>;
|
|
132
|
+
/** What content answers, in `details.code`, for a project it does not build yet. */
|
|
133
|
+
export declare const SERVER_BUILDS_OFF = "server-builds-off";
|
|
134
|
+
/** How often the proposal is read while the platform builds it. */
|
|
135
|
+
export declare const SERVER_BUILD_POLL_MS = 1000;
|
|
136
|
+
/**
|
|
137
|
+
* How long a build by the platform is waited for. It is seconds
|
|
138
|
+
* (valbuild/home `docs/plans/server-builds.md`); this is for the platform not
|
|
139
|
+
* answering, never for a build that is merely slow.
|
|
140
|
+
*/
|
|
141
|
+
export declare const SERVER_BUILD_WAIT_MS: number;
|
|
142
|
+
/**
|
|
143
|
+
* Where a build by the platform is (`buildProposalOnServer`): reading what is
|
|
144
|
+
* staged, then Val Build building, rendering and serving it. Its own type,
|
|
145
|
+
* not `ProposalBuildStep`'s, which every page that runs `buildProposal`
|
|
146
|
+
* switches over.
|
|
147
|
+
*/
|
|
148
|
+
export type ServerBuildStep = {
|
|
149
|
+
kind: "reading";
|
|
150
|
+
} | {
|
|
151
|
+
kind: "on-server";
|
|
152
|
+
since: number;
|
|
153
|
+
};
|
|
154
|
+
/** The calls a build by the platform makes. An error carries content's `status`. */
|
|
155
|
+
export type ServerBuildClient<P extends BuiltProposal> = Pick<ProposalBuildClient<P>, "get"> & {
|
|
156
|
+
/** Ask the platform to build the staged files `inputs` names: `/build` without a publish. */
|
|
157
|
+
askBuild(name: string, inputs: string): Promise<P>;
|
|
158
|
+
};
|
|
159
|
+
/**
|
|
160
|
+
* Have the platform build the proposal's staged files and serve the build at
|
|
161
|
+
* its address (valbuild/home `docs/plans/server-builds.md`): nothing is built
|
|
162
|
+
* in this tab, so no bundler is loaded, no builder tab is opened, and a tab
|
|
163
|
+
* that closes meanwhile loses nothing.
|
|
164
|
+
*
|
|
165
|
+
* Content answers at once and builds in a job; the proposal is read until it
|
|
166
|
+
* says the build of these inputs is served, or why it is not. `off` when
|
|
167
|
+
* content does not build this project yet: `buildProposal` builds it in the
|
|
168
|
+
* tab, as before.
|
|
169
|
+
*
|
|
170
|
+
* A cancel stops the waiting, not the build: the platform finishes it, and
|
|
171
|
+
* the proposal's address serves it when it renders.
|
|
172
|
+
*/
|
|
173
|
+
export declare function buildProposalOnServer<P extends BuiltProposal>(deps: {
|
|
174
|
+
name: string;
|
|
175
|
+
client: ServerBuildClient<P>;
|
|
176
|
+
onStep?: (step: ServerBuildStep) => void;
|
|
177
|
+
signal?: AbortSignal;
|
|
178
|
+
/** For tests: the clock, and waiting on it. */
|
|
179
|
+
now?: () => number;
|
|
180
|
+
sleep?: (ms: number) => Promise<void>;
|
|
181
|
+
}): Promise<ProposalBuildOutcome<P> | {
|
|
182
|
+
status: "off";
|
|
183
|
+
}>;
|
|
@@ -19,6 +19,6 @@ export { DEPLOY_STOPPED_MESSAGE, carriedInto, runStudioDeploy, splitBinaryFiles,
|
|
|
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 { BUILD_CANCELLED_MESSAGE, SERVE_POLL_MS, SERVE_WAIT_MS, buildProposal, withoutLockfiles, type BuiltProposal, type ProposalBuildClient, type ProposalBuildOutcome, type ProposalBuildStep, } from "./buildProposal.js";
|
|
22
|
+
export { BUILD_CANCELLED_MESSAGE, SERVER_BUILDS_OFF, SERVER_BUILD_POLL_MS, SERVER_BUILD_WAIT_MS, SERVE_POLL_MS, SERVE_WAIT_MS, buildProposal, buildProposalOnServer, withoutLockfiles, type BuiltProposal, type ServerBuildClient, type ServerBuildStep, type ProposalBuildClient, type ProposalBuildOutcome, type ProposalBuildStep, } from "./buildProposal.js";
|
|
23
23
|
export { proposalProject } from "./proposalProject.js";
|
|
24
24
|
export { buildQuickPreview, clientFilesOf, type QuickPreviewOutcome, } from "./buildQuickPreview.js";
|
|
@@ -47,6 +47,14 @@ var VAL_AI_SESSION_STORAGE_KEY = "val-ai-session";
|
|
|
47
47
|
* document's `/_app/` requests from the files, and everything else from
|
|
48
48
|
* the network: the HTML is the last build's, rendered by its server, and
|
|
49
49
|
* the new code takes it over in the browser.
|
|
50
|
+
* 4. It takes it over by RENDERING it, not by hydrating it. Hydration keeps
|
|
51
|
+
* the markup the server sent wherever only an attribute differs -- React
|
|
52
|
+
* mends text, never a `className` -- so a change to classes and props,
|
|
53
|
+
* which is most of what the design tab changes, hydrated into the old
|
|
54
|
+
* page and showed nothing. The worker adds a script to the end of that
|
|
55
|
+
* document's `<body>` ({@link QUICK_PREVIEW_RENDER_SCRIPT}) that takes the
|
|
56
|
+
* server's markup out before the app's scripts run, so hydration finds
|
|
57
|
+
* nothing to keep and React renders the page with the new code.
|
|
50
58
|
*
|
|
51
59
|
* What it cannot show, and the tab says so: anything on the server. Server
|
|
52
60
|
* functions, API routes and loaders that run there are the last build's, as
|
|
@@ -64,6 +72,15 @@ var QUICK_PREVIEW_PARAM = "val_quick";
|
|
|
64
72
|
/** Where Val's API serves the worker: under `/api/val`. */
|
|
65
73
|
var QUICK_PREVIEW_SERVICE_WORKER_PATH = "/quick-preview-sw.js";
|
|
66
74
|
|
|
75
|
+
/**
|
|
76
|
+
* What a quick preview's document runs before the app's scripts: the
|
|
77
|
+
* server's markup out of `<body>`, every script left where it is -- the
|
|
78
|
+
* router's dehydrated state and the app's entry are among them. Hydration
|
|
79
|
+
* then finds the body empty and React renders the page, with the new code's
|
|
80
|
+
* attributes and classes, where it would have kept the old ones.
|
|
81
|
+
*/
|
|
82
|
+
var QUICK_PREVIEW_RENDER_SCRIPT = "<script>(function(){var b=document.body;if(!b)return;" + "Array.prototype.slice.call(b.childNodes).forEach(function(n){" + 'if(n.nodeName!=="SCRIPT")b.removeChild(n)})})()</script>';
|
|
83
|
+
|
|
67
84
|
/** What the page sends the worker to store a preview's files. */
|
|
68
85
|
var QUICK_PREVIEW_STORE_MESSAGE = "val-quick-preview-store";
|
|
69
86
|
|
|
@@ -90,7 +107,7 @@ function isQuickPreviewFiles(value) {
|
|
|
90
107
|
* The worker, as the source it is served as: plain, and small, because it is
|
|
91
108
|
* served as a file of its own (`demoServiceWorker.ts` is the same).
|
|
92
109
|
*/
|
|
93
|
-
var QUICK_PREVIEW_SERVICE_WORKER_SOURCE = "\n\"use strict\";\nconst PARAM = \"".concat(QUICK_PREVIEW_PARAM, "\";\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 !== \"").concat(QUICK_PREVIEW_STORE_MESSAGE, "\") 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)
|
|
110
|
+
var QUICK_PREVIEW_SERVICE_WORKER_SOURCE = "\n\"use strict\";\nconst PARAM = \"".concat(QUICK_PREVIEW_PARAM, "\";\nconst RENDER = ").concat(JSON.stringify(QUICK_PREVIEW_RENDER_SCRIPT), ";\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 !== \"").concat(QUICK_PREVIEW_STORE_MESSAGE, "\") 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 const id = url.searchParams.get(PARAM);\n if (event.resultingClientId) byClient.set(event.resultingClientId, id);\n if (id) event.respondWith(rendered(event.request));\n return;\n }\n if (!url.pathname.startsWith(\"/_app/\")) return;\n event.respondWith(serve(event, url));\n});\n\n/** A quick preview's document, with the script that has it rendered, not hydrated. */\nasync function rendered(request) {\n const response = await fetch(request);\n const type = response.headers.get(\"Content-Type\") || \"\";\n if (!response.ok || !type.includes(\"text/html\")) return response;\n const html = await response.text();\n const at = html.lastIndexOf(\"</body>\");\n if (at === -1) return new Response(html, response);\n const headers = new Headers(response.headers);\n headers.delete(\"Content-Length\");\n headers.delete(\"Content-Encoding\");\n return new Response(html.slice(0, at) + RENDER + html.slice(at), {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\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");
|
|
94
111
|
|
|
95
112
|
/** How long the worker is given to install and store a preview. */
|
|
96
113
|
var STORE_TIMEOUT_MS = 30000;
|
|
@@ -1536,6 +1553,7 @@ function getPatternFromModuleFilePath(moduleFilePath, srcFolder) {
|
|
|
1536
1553
|
exports.DEFAULT_CANVAS_SELECTION = DEFAULT_CANVAS_SELECTION;
|
|
1537
1554
|
exports.DEFAULT_CANVAS_SELECTION_SOFT = DEFAULT_CANVAS_SELECTION_SOFT;
|
|
1538
1555
|
exports.QUICK_PREVIEW_PARAM = QUICK_PREVIEW_PARAM;
|
|
1556
|
+
exports.QUICK_PREVIEW_RENDER_SCRIPT = QUICK_PREVIEW_RENDER_SCRIPT;
|
|
1539
1557
|
exports.QUICK_PREVIEW_SERVICE_WORKER_PATH = QUICK_PREVIEW_SERVICE_WORKER_PATH;
|
|
1540
1558
|
exports.QUICK_PREVIEW_SERVICE_WORKER_SOURCE = QUICK_PREVIEW_SERVICE_WORKER_SOURCE;
|
|
1541
1559
|
exports.QUICK_PREVIEW_STORE_MESSAGE = QUICK_PREVIEW_STORE_MESSAGE;
|
|
@@ -47,6 +47,14 @@ var VAL_AI_SESSION_STORAGE_KEY = "val-ai-session";
|
|
|
47
47
|
* document's `/_app/` requests from the files, and everything else from
|
|
48
48
|
* the network: the HTML is the last build's, rendered by its server, and
|
|
49
49
|
* the new code takes it over in the browser.
|
|
50
|
+
* 4. It takes it over by RENDERING it, not by hydrating it. Hydration keeps
|
|
51
|
+
* the markup the server sent wherever only an attribute differs -- React
|
|
52
|
+
* mends text, never a `className` -- so a change to classes and props,
|
|
53
|
+
* which is most of what the design tab changes, hydrated into the old
|
|
54
|
+
* page and showed nothing. The worker adds a script to the end of that
|
|
55
|
+
* document's `<body>` ({@link QUICK_PREVIEW_RENDER_SCRIPT}) that takes the
|
|
56
|
+
* server's markup out before the app's scripts run, so hydration finds
|
|
57
|
+
* nothing to keep and React renders the page with the new code.
|
|
50
58
|
*
|
|
51
59
|
* What it cannot show, and the tab says so: anything on the server. Server
|
|
52
60
|
* functions, API routes and loaders that run there are the last build's, as
|
|
@@ -64,6 +72,15 @@ var QUICK_PREVIEW_PARAM = "val_quick";
|
|
|
64
72
|
/** Where Val's API serves the worker: under `/api/val`. */
|
|
65
73
|
var QUICK_PREVIEW_SERVICE_WORKER_PATH = "/quick-preview-sw.js";
|
|
66
74
|
|
|
75
|
+
/**
|
|
76
|
+
* What a quick preview's document runs before the app's scripts: the
|
|
77
|
+
* server's markup out of `<body>`, every script left where it is -- the
|
|
78
|
+
* router's dehydrated state and the app's entry are among them. Hydration
|
|
79
|
+
* then finds the body empty and React renders the page, with the new code's
|
|
80
|
+
* attributes and classes, where it would have kept the old ones.
|
|
81
|
+
*/
|
|
82
|
+
var QUICK_PREVIEW_RENDER_SCRIPT = "<script>(function(){var b=document.body;if(!b)return;" + "Array.prototype.slice.call(b.childNodes).forEach(function(n){" + 'if(n.nodeName!=="SCRIPT")b.removeChild(n)})})()</script>';
|
|
83
|
+
|
|
67
84
|
/** What the page sends the worker to store a preview's files. */
|
|
68
85
|
var QUICK_PREVIEW_STORE_MESSAGE = "val-quick-preview-store";
|
|
69
86
|
|
|
@@ -90,7 +107,7 @@ function isQuickPreviewFiles(value) {
|
|
|
90
107
|
* The worker, as the source it is served as: plain, and small, because it is
|
|
91
108
|
* served as a file of its own (`demoServiceWorker.ts` is the same).
|
|
92
109
|
*/
|
|
93
|
-
var QUICK_PREVIEW_SERVICE_WORKER_SOURCE = "\n\"use strict\";\nconst PARAM = \"".concat(QUICK_PREVIEW_PARAM, "\";\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 !== \"").concat(QUICK_PREVIEW_STORE_MESSAGE, "\") 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)
|
|
110
|
+
var QUICK_PREVIEW_SERVICE_WORKER_SOURCE = "\n\"use strict\";\nconst PARAM = \"".concat(QUICK_PREVIEW_PARAM, "\";\nconst RENDER = ").concat(JSON.stringify(QUICK_PREVIEW_RENDER_SCRIPT), ";\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 !== \"").concat(QUICK_PREVIEW_STORE_MESSAGE, "\") 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 const id = url.searchParams.get(PARAM);\n if (event.resultingClientId) byClient.set(event.resultingClientId, id);\n if (id) event.respondWith(rendered(event.request));\n return;\n }\n if (!url.pathname.startsWith(\"/_app/\")) return;\n event.respondWith(serve(event, url));\n});\n\n/** A quick preview's document, with the script that has it rendered, not hydrated. */\nasync function rendered(request) {\n const response = await fetch(request);\n const type = response.headers.get(\"Content-Type\") || \"\";\n if (!response.ok || !type.includes(\"text/html\")) return response;\n const html = await response.text();\n const at = html.lastIndexOf(\"</body>\");\n if (at === -1) return new Response(html, response);\n const headers = new Headers(response.headers);\n headers.delete(\"Content-Length\");\n headers.delete(\"Content-Encoding\");\n return new Response(html.slice(0, at) + RENDER + html.slice(at), {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\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");
|
|
94
111
|
|
|
95
112
|
/** How long the worker is given to install and store a preview. */
|
|
96
113
|
var STORE_TIMEOUT_MS = 30000;
|
|
@@ -1536,6 +1553,7 @@ function getPatternFromModuleFilePath(moduleFilePath, srcFolder) {
|
|
|
1536
1553
|
exports.DEFAULT_CANVAS_SELECTION = DEFAULT_CANVAS_SELECTION;
|
|
1537
1554
|
exports.DEFAULT_CANVAS_SELECTION_SOFT = DEFAULT_CANVAS_SELECTION_SOFT;
|
|
1538
1555
|
exports.QUICK_PREVIEW_PARAM = QUICK_PREVIEW_PARAM;
|
|
1556
|
+
exports.QUICK_PREVIEW_RENDER_SCRIPT = QUICK_PREVIEW_RENDER_SCRIPT;
|
|
1539
1557
|
exports.QUICK_PREVIEW_SERVICE_WORKER_PATH = QUICK_PREVIEW_SERVICE_WORKER_PATH;
|
|
1540
1558
|
exports.QUICK_PREVIEW_SERVICE_WORKER_SOURCE = QUICK_PREVIEW_SERVICE_WORKER_SOURCE;
|
|
1541
1559
|
exports.QUICK_PREVIEW_STORE_MESSAGE = QUICK_PREVIEW_STORE_MESSAGE;
|
|
@@ -27,6 +27,14 @@ var VAL_AI_SESSION_STORAGE_KEY = "val-ai-session";
|
|
|
27
27
|
* document's `/_app/` requests from the files, and everything else from
|
|
28
28
|
* the network: the HTML is the last build's, rendered by its server, and
|
|
29
29
|
* the new code takes it over in the browser.
|
|
30
|
+
* 4. It takes it over by RENDERING it, not by hydrating it. Hydration keeps
|
|
31
|
+
* the markup the server sent wherever only an attribute differs -- React
|
|
32
|
+
* mends text, never a `className` -- so a change to classes and props,
|
|
33
|
+
* which is most of what the design tab changes, hydrated into the old
|
|
34
|
+
* page and showed nothing. The worker adds a script to the end of that
|
|
35
|
+
* document's `<body>` ({@link QUICK_PREVIEW_RENDER_SCRIPT}) that takes the
|
|
36
|
+
* server's markup out before the app's scripts run, so hydration finds
|
|
37
|
+
* nothing to keep and React renders the page with the new code.
|
|
30
38
|
*
|
|
31
39
|
* What it cannot show, and the tab says so: anything on the server. Server
|
|
32
40
|
* functions, API routes and loaders that run there are the last build's, as
|
|
@@ -44,6 +52,15 @@ var QUICK_PREVIEW_PARAM = "val_quick";
|
|
|
44
52
|
/** Where Val's API serves the worker: under `/api/val`. */
|
|
45
53
|
var QUICK_PREVIEW_SERVICE_WORKER_PATH = "/quick-preview-sw.js";
|
|
46
54
|
|
|
55
|
+
/**
|
|
56
|
+
* What a quick preview's document runs before the app's scripts: the
|
|
57
|
+
* server's markup out of `<body>`, every script left where it is -- the
|
|
58
|
+
* router's dehydrated state and the app's entry are among them. Hydration
|
|
59
|
+
* then finds the body empty and React renders the page, with the new code's
|
|
60
|
+
* attributes and classes, where it would have kept the old ones.
|
|
61
|
+
*/
|
|
62
|
+
var QUICK_PREVIEW_RENDER_SCRIPT = "<script>(function(){var b=document.body;if(!b)return;" + "Array.prototype.slice.call(b.childNodes).forEach(function(n){" + 'if(n.nodeName!=="SCRIPT")b.removeChild(n)})})()</script>';
|
|
63
|
+
|
|
47
64
|
/** What the page sends the worker to store a preview's files. */
|
|
48
65
|
var QUICK_PREVIEW_STORE_MESSAGE = "val-quick-preview-store";
|
|
49
66
|
|
|
@@ -70,7 +87,7 @@ function isQuickPreviewFiles(value) {
|
|
|
70
87
|
* The worker, as the source it is served as: plain, and small, because it is
|
|
71
88
|
* served as a file of its own (`demoServiceWorker.ts` is the same).
|
|
72
89
|
*/
|
|
73
|
-
var QUICK_PREVIEW_SERVICE_WORKER_SOURCE = "\n\"use strict\";\nconst PARAM = \"".concat(QUICK_PREVIEW_PARAM, "\";\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 !== \"").concat(QUICK_PREVIEW_STORE_MESSAGE, "\") 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)
|
|
90
|
+
var QUICK_PREVIEW_SERVICE_WORKER_SOURCE = "\n\"use strict\";\nconst PARAM = \"".concat(QUICK_PREVIEW_PARAM, "\";\nconst RENDER = ").concat(JSON.stringify(QUICK_PREVIEW_RENDER_SCRIPT), ";\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 !== \"").concat(QUICK_PREVIEW_STORE_MESSAGE, "\") 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 const id = url.searchParams.get(PARAM);\n if (event.resultingClientId) byClient.set(event.resultingClientId, id);\n if (id) event.respondWith(rendered(event.request));\n return;\n }\n if (!url.pathname.startsWith(\"/_app/\")) return;\n event.respondWith(serve(event, url));\n});\n\n/** A quick preview's document, with the script that has it rendered, not hydrated. */\nasync function rendered(request) {\n const response = await fetch(request);\n const type = response.headers.get(\"Content-Type\") || \"\";\n if (!response.ok || !type.includes(\"text/html\")) return response;\n const html = await response.text();\n const at = html.lastIndexOf(\"</body>\");\n if (at === -1) return new Response(html, response);\n const headers = new Headers(response.headers);\n headers.delete(\"Content-Length\");\n headers.delete(\"Content-Encoding\");\n return new Response(html.slice(0, at) + RENDER + html.slice(at), {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\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");
|
|
74
91
|
|
|
75
92
|
/** How long the worker is given to install and store a preview. */
|
|
76
93
|
var STORE_TIMEOUT_MS = 30000;
|
|
@@ -1513,4 +1530,4 @@ function getPatternFromModuleFilePath(moduleFilePath, srcFolder) {
|
|
|
1513
1530
|
.replace("/page.val.ts", "").replace("/page.val.js", "");
|
|
1514
1531
|
}
|
|
1515
1532
|
|
|
1516
|
-
export {
|
|
1533
|
+
export { storeQuickPreview as A, withQuickPreviewParam as B, quickPreviewSiteOrigin as C, DEFAULT_CANVAS_SELECTION as D, isDesignTabOrigin as E, parseRoutePattern as F, formatRoutePattern as G, getNextAppRouterSourceFolder as H, getTanStackRouterSourceFolder as I, getPageRouterSourceFolder as J, isTanStackRoutesFolder as K, getPageRouterSitemapTree as L, getPatternFromModuleFilePath as M, QUICK_PREVIEW_PARAM as Q, VAL_CONFIG_SESSION_STORAGE_KEY as V, VAL_THEME_SESSION_STORAGE_KEY as a, VAL_AI_SESSION_STORAGE_KEY as b, VAL_CANVAS_PARAM as c, VAL_CANVAS_MESSAGE as d, DEFAULT_CANVAS_SELECTION_SOFT as e, isValCanvasStudioMessage as f, isValCanvasFrame as g, describeElement as h, isValCanvasPageMessage as i, attachElementPicker as j, createPickerOverlay as k, elementLabel as l, modifierLabel as m, watchPageLocation as n, readPageSnapshot as o, pageLocationOf as p, findBySelector as q, restoreScroll as r, startElementPicking as s, screenshotPage as t, QUICK_PREVIEW_SERVICE_WORKER_PATH as u, QUICK_PREVIEW_RENDER_SCRIPT as v, withValCanvasParam as w, QUICK_PREVIEW_STORE_MESSAGE as x, isQuickPreviewFiles as y, QUICK_PREVIEW_SERVICE_WORKER_SOURCE as z };
|
|
@@ -7,7 +7,7 @@ var core = require('@valbuild/core');
|
|
|
7
7
|
var zod = require('zod');
|
|
8
8
|
var protocol = require('../../dist/protocol-d0efb8cd.cjs.dev.js');
|
|
9
9
|
var zodValidationError = require('zod-validation-error');
|
|
10
|
-
var getSitemapTree = require('../../dist/getSitemapTree-
|
|
10
|
+
var getSitemapTree = require('../../dist/getSitemapTree-6dfa2f4e.cjs.dev.js');
|
|
11
11
|
var FlexSearch = require('flexsearch');
|
|
12
12
|
var wrapNativeSuper = require('../../dist/wrapNativeSuper-933f991e.cjs.dev.js');
|
|
13
13
|
var utils = require('../../dist/utils-d3d8b4b5.cjs.dev.js');
|
|
@@ -9575,6 +9575,7 @@ exports.parseVerify = protocol.parseVerify;
|
|
|
9575
9575
|
exports.DEFAULT_CANVAS_SELECTION = getSitemapTree.DEFAULT_CANVAS_SELECTION;
|
|
9576
9576
|
exports.DEFAULT_CANVAS_SELECTION_SOFT = getSitemapTree.DEFAULT_CANVAS_SELECTION_SOFT;
|
|
9577
9577
|
exports.QUICK_PREVIEW_PARAM = getSitemapTree.QUICK_PREVIEW_PARAM;
|
|
9578
|
+
exports.QUICK_PREVIEW_RENDER_SCRIPT = getSitemapTree.QUICK_PREVIEW_RENDER_SCRIPT;
|
|
9578
9579
|
exports.QUICK_PREVIEW_SERVICE_WORKER_PATH = getSitemapTree.QUICK_PREVIEW_SERVICE_WORKER_PATH;
|
|
9579
9580
|
exports.QUICK_PREVIEW_SERVICE_WORKER_SOURCE = getSitemapTree.QUICK_PREVIEW_SERVICE_WORKER_SOURCE;
|
|
9580
9581
|
exports.QUICK_PREVIEW_STORE_MESSAGE = getSitemapTree.QUICK_PREVIEW_STORE_MESSAGE;
|
|
@@ -7,7 +7,7 @@ var core = require('@valbuild/core');
|
|
|
7
7
|
var zod = require('zod');
|
|
8
8
|
var protocol = require('../../dist/protocol-b1055ef0.cjs.prod.js');
|
|
9
9
|
var zodValidationError = require('zod-validation-error');
|
|
10
|
-
var getSitemapTree = require('../../dist/getSitemapTree-
|
|
10
|
+
var getSitemapTree = require('../../dist/getSitemapTree-8a04f3cf.cjs.prod.js');
|
|
11
11
|
var FlexSearch = require('flexsearch');
|
|
12
12
|
var wrapNativeSuper = require('../../dist/wrapNativeSuper-8673414f.cjs.prod.js');
|
|
13
13
|
var utils = require('../../dist/utils-32bcaca2.cjs.prod.js');
|
|
@@ -9575,6 +9575,7 @@ exports.parseVerify = protocol.parseVerify;
|
|
|
9575
9575
|
exports.DEFAULT_CANVAS_SELECTION = getSitemapTree.DEFAULT_CANVAS_SELECTION;
|
|
9576
9576
|
exports.DEFAULT_CANVAS_SELECTION_SOFT = getSitemapTree.DEFAULT_CANVAS_SELECTION_SOFT;
|
|
9577
9577
|
exports.QUICK_PREVIEW_PARAM = getSitemapTree.QUICK_PREVIEW_PARAM;
|
|
9578
|
+
exports.QUICK_PREVIEW_RENDER_SCRIPT = getSitemapTree.QUICK_PREVIEW_RENDER_SCRIPT;
|
|
9578
9579
|
exports.QUICK_PREVIEW_SERVICE_WORKER_PATH = getSitemapTree.QUICK_PREVIEW_SERVICE_WORKER_PATH;
|
|
9579
9580
|
exports.QUICK_PREVIEW_SERVICE_WORKER_SOURCE = getSitemapTree.QUICK_PREVIEW_SERVICE_WORKER_SOURCE;
|
|
9580
9581
|
exports.QUICK_PREVIEW_STORE_MESSAGE = getSitemapTree.QUICK_PREVIEW_STORE_MESSAGE;
|
|
@@ -4,7 +4,7 @@ import { z } from 'zod';
|
|
|
4
4
|
import { _ as _objectWithoutProperties } from '../../dist/protocol-55cfa3cf.esm.js';
|
|
5
5
|
export { P as PublishProtocolError, b as parseArtifacts, p as parseBuildTarget, l as parseCancel, a as parseDeclare, m as parseDiscard, j as parseJob, n as parseNewestCiRun, h as parsePress, g as parseProblems, f as parseProjectSource, d as parsePromote, o as parsePublishToken, k as parseRenew, i as parseRequestStatus, e as parseStatus, q as parseUpdateTarget, c as parseVerify } from '../../dist/protocol-55cfa3cf.esm.js';
|
|
6
6
|
import { fromError } from 'zod-validation-error';
|
|
7
|
-
export { D as DEFAULT_CANVAS_SELECTION, e as DEFAULT_CANVAS_SELECTION_SOFT, Q as QUICK_PREVIEW_PARAM, u as QUICK_PREVIEW_SERVICE_WORKER_PATH,
|
|
7
|
+
export { D as DEFAULT_CANVAS_SELECTION, e as DEFAULT_CANVAS_SELECTION_SOFT, Q as QUICK_PREVIEW_PARAM, v as QUICK_PREVIEW_RENDER_SCRIPT, u as QUICK_PREVIEW_SERVICE_WORKER_PATH, z as QUICK_PREVIEW_SERVICE_WORKER_SOURCE, x as QUICK_PREVIEW_STORE_MESSAGE, b as VAL_AI_SESSION_STORAGE_KEY, d as VAL_CANVAS_MESSAGE, c as VAL_CANVAS_PARAM, V as VAL_CONFIG_SESSION_STORAGE_KEY, a as VAL_THEME_SESSION_STORAGE_KEY, j as attachElementPicker, k as createPickerOverlay, h as describeElement, l as elementLabel, q as findBySelector, G as formatRoutePattern, H as getNextAppRouterSourceFolder, L as getPageRouterSitemapTree, J as getPageRouterSourceFolder, M as getPatternFromModuleFilePath, I as getTanStackRouterSourceFolder, E as isDesignTabOrigin, y as isQuickPreviewFiles, K as isTanStackRoutesFolder, g as isValCanvasFrame, i as isValCanvasPageMessage, f as isValCanvasStudioMessage, m as modifierLabel, p as pageLocationOf, F as parseRoutePattern, C as quickPreviewSiteOrigin, o as readPageSnapshot, r as restoreScroll, t as screenshotPage, s as startElementPicking, A as storeQuickPreview, n as watchPageLocation, B as withQuickPreviewParam, w as withValCanvasParam } from '../../dist/getSitemapTree-fef55872.esm.js';
|
|
8
8
|
import FlexSearch from 'flexsearch';
|
|
9
9
|
import { a as _createClass, c as _classCallCheck } from '../../dist/wrapNativeSuper-639b12b7.esm.js';
|
|
10
10
|
import { b as base64DataUrlToUint8Array } from '../../dist/utils-00f3e1df.esm.js';
|
package/package.json
CHANGED
|
@@ -2309,6 +2309,8 @@ var SERVE_POLL_MS = 5000;
|
|
|
2309
2309
|
function buildProposal(_x) {
|
|
2310
2310
|
return _buildProposal.apply(this, arguments);
|
|
2311
2311
|
}
|
|
2312
|
+
|
|
2313
|
+
/** What content answers, in `details.code`, for a project it does not build yet. */
|
|
2312
2314
|
function _buildProposal() {
|
|
2313
2315
|
_buildProposal = createForOfIteratorHelper._asyncToGenerator(/*#__PURE__*/createForOfIteratorHelper._regenerator().m(function _callee3(deps) {
|
|
2314
2316
|
var _deps$now, _deps$sleep, _deps$onStep;
|
|
@@ -2569,6 +2571,257 @@ function _buildProposal() {
|
|
|
2569
2571
|
}));
|
|
2570
2572
|
return _buildProposal.apply(this, arguments);
|
|
2571
2573
|
}
|
|
2574
|
+
var SERVER_BUILDS_OFF = "server-builds-off";
|
|
2575
|
+
|
|
2576
|
+
/** How often the proposal is read while the platform builds it. */
|
|
2577
|
+
var SERVER_BUILD_POLL_MS = 1000;
|
|
2578
|
+
|
|
2579
|
+
/**
|
|
2580
|
+
* How long a build by the platform is waited for. It is seconds
|
|
2581
|
+
* (valbuild/home `docs/plans/server-builds.md`); this is for the platform not
|
|
2582
|
+
* answering, never for a build that is merely slow.
|
|
2583
|
+
*/
|
|
2584
|
+
var SERVER_BUILD_WAIT_MS = 4 * 60000;
|
|
2585
|
+
|
|
2586
|
+
/**
|
|
2587
|
+
* Where a build by the platform is (`buildProposalOnServer`): reading what is
|
|
2588
|
+
* staged, then Val Build building, rendering and serving it. Its own type,
|
|
2589
|
+
* not `ProposalBuildStep`'s, which every page that runs `buildProposal`
|
|
2590
|
+
* switches over.
|
|
2591
|
+
*/
|
|
2592
|
+
|
|
2593
|
+
/** The calls a build by the platform makes. An error carries content's `status`. */
|
|
2594
|
+
|
|
2595
|
+
/**
|
|
2596
|
+
* Whether an error is content saying it does not build this project yet --
|
|
2597
|
+
* or not knowing the request: content from before it built anything refuses
|
|
2598
|
+
* a build without a publish as an invalid body (400). Either way the tab
|
|
2599
|
+
* builds it, as it always did.
|
|
2600
|
+
*/
|
|
2601
|
+
function serverBuildsOff(error) {
|
|
2602
|
+
var status = statusOf(error);
|
|
2603
|
+
if (status === 400) return true;
|
|
2604
|
+
if (status !== 409) return false;
|
|
2605
|
+
var body = createForOfIteratorHelper._typeof(error) === "object" && error !== null && "body" in error ? error.body : null;
|
|
2606
|
+
var details = createForOfIteratorHelper._typeof(body) === "object" && body !== null && "details" in body ? body.details : null;
|
|
2607
|
+
return createForOfIteratorHelper._typeof(details) === "object" && details !== null && "code" in details && details.code === SERVER_BUILDS_OFF;
|
|
2608
|
+
}
|
|
2609
|
+
|
|
2610
|
+
/**
|
|
2611
|
+
* Have the platform build the proposal's staged files and serve the build at
|
|
2612
|
+
* its address (valbuild/home `docs/plans/server-builds.md`): nothing is built
|
|
2613
|
+
* in this tab, so no bundler is loaded, no builder tab is opened, and a tab
|
|
2614
|
+
* that closes meanwhile loses nothing.
|
|
2615
|
+
*
|
|
2616
|
+
* Content answers at once and builds in a job; the proposal is read until it
|
|
2617
|
+
* says the build of these inputs is served, or why it is not. `off` when
|
|
2618
|
+
* content does not build this project yet: `buildProposal` builds it in the
|
|
2619
|
+
* tab, as before.
|
|
2620
|
+
*
|
|
2621
|
+
* A cancel stops the waiting, not the build: the platform finishes it, and
|
|
2622
|
+
* the proposal's address serves it when it renders.
|
|
2623
|
+
*/
|
|
2624
|
+
function buildProposalOnServer(_x2) {
|
|
2625
|
+
return _buildProposalOnServer.apply(this, arguments);
|
|
2626
|
+
}
|
|
2627
|
+
function _buildProposalOnServer() {
|
|
2628
|
+
_buildProposalOnServer = createForOfIteratorHelper._asyncToGenerator(/*#__PURE__*/createForOfIteratorHelper._regenerator().m(function _callee4(deps) {
|
|
2629
|
+
var _deps$now2, _deps$sleep2, _deps$onStep2;
|
|
2630
|
+
var now, sleep, step, signal, read, staged, inputs, settled, asked, since, first, proposal, outcome, _t8, _t9, _t0, _t1, _t10;
|
|
2631
|
+
return createForOfIteratorHelper._regenerator().w(function (_context4) {
|
|
2632
|
+
while (1) switch (_context4.p = _context4.n) {
|
|
2633
|
+
case 0:
|
|
2634
|
+
now = (_deps$now2 = deps.now) !== null && _deps$now2 !== void 0 ? _deps$now2 : Date.now;
|
|
2635
|
+
sleep = (_deps$sleep2 = deps.sleep) !== null && _deps$sleep2 !== void 0 ? _deps$sleep2 : function (ms) {
|
|
2636
|
+
return new Promise(function (resolve) {
|
|
2637
|
+
return setTimeout(resolve, ms);
|
|
2638
|
+
});
|
|
2639
|
+
};
|
|
2640
|
+
step = (_deps$onStep2 = deps.onStep) !== null && _deps$onStep2 !== void 0 ? _deps$onStep2 : function () {};
|
|
2641
|
+
signal = deps.signal;
|
|
2642
|
+
step({
|
|
2643
|
+
kind: "reading"
|
|
2644
|
+
});
|
|
2645
|
+
// The proposal says what is staged: its files are not needed here
|
|
2646
|
+
_context4.p = 1;
|
|
2647
|
+
_context4.n = 2;
|
|
2648
|
+
return orAborted(deps.client.get(deps.name), signal);
|
|
2649
|
+
case 2:
|
|
2650
|
+
read = _context4.v;
|
|
2651
|
+
_context4.n = 4;
|
|
2652
|
+
break;
|
|
2653
|
+
case 3:
|
|
2654
|
+
_context4.p = 3;
|
|
2655
|
+
_t8 = _context4.v;
|
|
2656
|
+
return _context4.a(2, {
|
|
2657
|
+
status: "failed",
|
|
2658
|
+
message: messageOf(_t8)
|
|
2659
|
+
});
|
|
2660
|
+
case 4:
|
|
2661
|
+
if (!(read === ABORTED || signal !== null && signal !== void 0 && signal.aborted)) {
|
|
2662
|
+
_context4.n = 5;
|
|
2663
|
+
break;
|
|
2664
|
+
}
|
|
2665
|
+
return _context4.a(2, abortedOutcome(signal));
|
|
2666
|
+
case 5:
|
|
2667
|
+
staged = read.staged;
|
|
2668
|
+
if (!(!staged || staged.inputs === null)) {
|
|
2669
|
+
_context4.n = 6;
|
|
2670
|
+
break;
|
|
2671
|
+
}
|
|
2672
|
+
return _context4.a(2, {
|
|
2673
|
+
status: "nothing-staged"
|
|
2674
|
+
});
|
|
2675
|
+
case 6:
|
|
2676
|
+
if (staged.buildRequired) {
|
|
2677
|
+
_context4.n = 7;
|
|
2678
|
+
break;
|
|
2679
|
+
}
|
|
2680
|
+
return _context4.a(2, {
|
|
2681
|
+
status: "already-built",
|
|
2682
|
+
hash: null
|
|
2683
|
+
});
|
|
2684
|
+
case 7:
|
|
2685
|
+
inputs = staged.inputs;
|
|
2686
|
+
/** Where the proposal is: served, failed, replaced, or still being built. */
|
|
2687
|
+
settled = function settled(proposal) {
|
|
2688
|
+
var _proposal$built3, _proposal$serverBuild;
|
|
2689
|
+
if (((_proposal$built3 = proposal.built) === null || _proposal$built3 === void 0 ? void 0 : _proposal$built3.inputs) === inputs && proposal.built.hash) {
|
|
2690
|
+
return {
|
|
2691
|
+
status: "built",
|
|
2692
|
+
hash: proposal.built.hash,
|
|
2693
|
+
proposal: proposal
|
|
2694
|
+
};
|
|
2695
|
+
}
|
|
2696
|
+
if (((_proposal$serverBuild = proposal.serverBuild) === null || _proposal$serverBuild === void 0 ? void 0 : _proposal$serverBuild.inputs) === inputs && proposal.serverBuild.state === "failed") {
|
|
2697
|
+
var _proposal$serverBuild2;
|
|
2698
|
+
return {
|
|
2699
|
+
status: "failed",
|
|
2700
|
+
message: (_proposal$serverBuild2 = proposal.serverBuild.error) !== null && _proposal$serverBuild2 !== void 0 ? _proposal$serverBuild2 : "Val Build could not build it."
|
|
2701
|
+
};
|
|
2702
|
+
}
|
|
2703
|
+
// Staged again since (by anyone): this build is not the one to wait for
|
|
2704
|
+
if (proposal.staged && proposal.staged.inputs !== inputs) {
|
|
2705
|
+
return {
|
|
2706
|
+
status: "failed",
|
|
2707
|
+
message: "The proposal's files changed while it was being built. Build it again."
|
|
2708
|
+
};
|
|
2709
|
+
}
|
|
2710
|
+
return null;
|
|
2711
|
+
};
|
|
2712
|
+
_context4.p = 8;
|
|
2713
|
+
_context4.n = 9;
|
|
2714
|
+
return orAborted(deps.client.askBuild(deps.name, inputs), signal);
|
|
2715
|
+
case 9:
|
|
2716
|
+
asked = _context4.v;
|
|
2717
|
+
_context4.n = 12;
|
|
2718
|
+
break;
|
|
2719
|
+
case 10:
|
|
2720
|
+
_context4.p = 10;
|
|
2721
|
+
_t9 = _context4.v;
|
|
2722
|
+
if (!serverBuildsOff(_t9)) {
|
|
2723
|
+
_context4.n = 11;
|
|
2724
|
+
break;
|
|
2725
|
+
}
|
|
2726
|
+
return _context4.a(2, {
|
|
2727
|
+
status: "off"
|
|
2728
|
+
});
|
|
2729
|
+
case 11:
|
|
2730
|
+
return _context4.a(2, {
|
|
2731
|
+
status: "failed",
|
|
2732
|
+
message: messageOf(_t9)
|
|
2733
|
+
});
|
|
2734
|
+
case 12:
|
|
2735
|
+
if (!(asked === ABORTED)) {
|
|
2736
|
+
_context4.n = 13;
|
|
2737
|
+
break;
|
|
2738
|
+
}
|
|
2739
|
+
return _context4.a(2, abortedOutcome(signal));
|
|
2740
|
+
case 13:
|
|
2741
|
+
// Said only now: a project Val Build does not build never was building there
|
|
2742
|
+
since = now();
|
|
2743
|
+
step({
|
|
2744
|
+
kind: "on-server",
|
|
2745
|
+
since: since
|
|
2746
|
+
});
|
|
2747
|
+
first = settled(asked);
|
|
2748
|
+
if (!(first !== null)) {
|
|
2749
|
+
_context4.n = 14;
|
|
2750
|
+
break;
|
|
2751
|
+
}
|
|
2752
|
+
return _context4.a(2, first);
|
|
2753
|
+
case 14:
|
|
2754
|
+
if (!(now() - since < SERVER_BUILD_WAIT_MS)) {
|
|
2755
|
+
_context4.n = 24;
|
|
2756
|
+
break;
|
|
2757
|
+
}
|
|
2758
|
+
_context4.n = 15;
|
|
2759
|
+
return orAborted(sleep(SERVER_BUILD_POLL_MS), signal);
|
|
2760
|
+
case 15:
|
|
2761
|
+
_t0 = _context4.v;
|
|
2762
|
+
_t1 = ABORTED;
|
|
2763
|
+
if (!(_t0 === _t1)) {
|
|
2764
|
+
_context4.n = 16;
|
|
2765
|
+
break;
|
|
2766
|
+
}
|
|
2767
|
+
return _context4.a(2, abortedOutcome(signal));
|
|
2768
|
+
case 16:
|
|
2769
|
+
proposal = void 0;
|
|
2770
|
+
_context4.p = 17;
|
|
2771
|
+
_context4.n = 18;
|
|
2772
|
+
return orAborted(deps.client.get(deps.name), signal);
|
|
2773
|
+
case 18:
|
|
2774
|
+
proposal = _context4.v;
|
|
2775
|
+
_context4.n = 21;
|
|
2776
|
+
break;
|
|
2777
|
+
case 19:
|
|
2778
|
+
_context4.p = 19;
|
|
2779
|
+
_t10 = _context4.v;
|
|
2780
|
+
if (gatewayGaveUp(_t10)) {
|
|
2781
|
+
_context4.n = 20;
|
|
2782
|
+
break;
|
|
2783
|
+
}
|
|
2784
|
+
return _context4.a(2, {
|
|
2785
|
+
status: "failed",
|
|
2786
|
+
message: messageOf(_t10)
|
|
2787
|
+
});
|
|
2788
|
+
case 20:
|
|
2789
|
+
step({
|
|
2790
|
+
kind: "on-server",
|
|
2791
|
+
since: since
|
|
2792
|
+
});
|
|
2793
|
+
return _context4.a(3, 14);
|
|
2794
|
+
case 21:
|
|
2795
|
+
if (!(proposal === ABORTED)) {
|
|
2796
|
+
_context4.n = 22;
|
|
2797
|
+
break;
|
|
2798
|
+
}
|
|
2799
|
+
return _context4.a(2, abortedOutcome(signal));
|
|
2800
|
+
case 22:
|
|
2801
|
+
// Said again, so a watchdog sees it waiting, not stalled.
|
|
2802
|
+
step({
|
|
2803
|
+
kind: "on-server",
|
|
2804
|
+
since: since
|
|
2805
|
+
});
|
|
2806
|
+
outcome = settled(proposal);
|
|
2807
|
+
if (!(outcome !== null)) {
|
|
2808
|
+
_context4.n = 23;
|
|
2809
|
+
break;
|
|
2810
|
+
}
|
|
2811
|
+
return _context4.a(2, outcome);
|
|
2812
|
+
case 23:
|
|
2813
|
+
_context4.n = 14;
|
|
2814
|
+
break;
|
|
2815
|
+
case 24:
|
|
2816
|
+
return _context4.a(2, {
|
|
2817
|
+
status: "failed",
|
|
2818
|
+
message: "Val Build did not finish the build in ".concat(Math.round(SERVER_BUILD_WAIT_MS / 60000), " minutes. Try again.")
|
|
2819
|
+
});
|
|
2820
|
+
}
|
|
2821
|
+
}, _callee4, null, [[17, 19], [8, 10], [1, 3]]);
|
|
2822
|
+
}));
|
|
2823
|
+
return _buildProposalOnServer.apply(this, arguments);
|
|
2824
|
+
}
|
|
2572
2825
|
|
|
2573
2826
|
/*
|
|
2574
2827
|
* A quick preview's files: the proposal's app bundled in the tab, for the
|
|
@@ -2782,6 +3035,9 @@ exports.BUILD_CANCELLED_MESSAGE = BUILD_CANCELLED_MESSAGE;
|
|
|
2782
3035
|
exports.DEPLOY_STOPPED_MESSAGE = DEPLOY_STOPPED_MESSAGE;
|
|
2783
3036
|
exports.MergePrepareAnswer = MergePrepareAnswer;
|
|
2784
3037
|
exports.RENEW_EVERY_MS = RENEW_EVERY_MS;
|
|
3038
|
+
exports.SERVER_BUILDS_OFF = SERVER_BUILDS_OFF;
|
|
3039
|
+
exports.SERVER_BUILD_POLL_MS = SERVER_BUILD_POLL_MS;
|
|
3040
|
+
exports.SERVER_BUILD_WAIT_MS = SERVER_BUILD_WAIT_MS;
|
|
2785
3041
|
exports.SERVE_POLL_MS = SERVE_POLL_MS;
|
|
2786
3042
|
exports.SERVE_WAIT_MS = SERVE_WAIT_MS;
|
|
2787
3043
|
exports.STUDIO_OUT_OF_DATE = STUDIO_OUT_OF_DATE;
|
|
@@ -2789,6 +3045,7 @@ exports.STUDIO_OUT_OF_DATE_MESSAGE = STUDIO_OUT_OF_DATE_MESSAGE;
|
|
|
2789
3045
|
exports.StudioPublishError = StudioPublishError;
|
|
2790
3046
|
exports.StudioUploadError = StudioUploadError;
|
|
2791
3047
|
exports.buildProposal = buildProposal;
|
|
3048
|
+
exports.buildProposalOnServer = buildProposalOnServer;
|
|
2792
3049
|
exports.buildQuickPreview = buildQuickPreview;
|
|
2793
3050
|
exports.callJson = callJson;
|
|
2794
3051
|
exports.carriedInto = carriedInto;
|
|
@@ -2309,6 +2309,8 @@ var SERVE_POLL_MS = 5000;
|
|
|
2309
2309
|
function buildProposal(_x) {
|
|
2310
2310
|
return _buildProposal.apply(this, arguments);
|
|
2311
2311
|
}
|
|
2312
|
+
|
|
2313
|
+
/** What content answers, in `details.code`, for a project it does not build yet. */
|
|
2312
2314
|
function _buildProposal() {
|
|
2313
2315
|
_buildProposal = createForOfIteratorHelper._asyncToGenerator(/*#__PURE__*/createForOfIteratorHelper._regenerator().m(function _callee3(deps) {
|
|
2314
2316
|
var _deps$now, _deps$sleep, _deps$onStep;
|
|
@@ -2569,6 +2571,257 @@ function _buildProposal() {
|
|
|
2569
2571
|
}));
|
|
2570
2572
|
return _buildProposal.apply(this, arguments);
|
|
2571
2573
|
}
|
|
2574
|
+
var SERVER_BUILDS_OFF = "server-builds-off";
|
|
2575
|
+
|
|
2576
|
+
/** How often the proposal is read while the platform builds it. */
|
|
2577
|
+
var SERVER_BUILD_POLL_MS = 1000;
|
|
2578
|
+
|
|
2579
|
+
/**
|
|
2580
|
+
* How long a build by the platform is waited for. It is seconds
|
|
2581
|
+
* (valbuild/home `docs/plans/server-builds.md`); this is for the platform not
|
|
2582
|
+
* answering, never for a build that is merely slow.
|
|
2583
|
+
*/
|
|
2584
|
+
var SERVER_BUILD_WAIT_MS = 4 * 60000;
|
|
2585
|
+
|
|
2586
|
+
/**
|
|
2587
|
+
* Where a build by the platform is (`buildProposalOnServer`): reading what is
|
|
2588
|
+
* staged, then Val Build building, rendering and serving it. Its own type,
|
|
2589
|
+
* not `ProposalBuildStep`'s, which every page that runs `buildProposal`
|
|
2590
|
+
* switches over.
|
|
2591
|
+
*/
|
|
2592
|
+
|
|
2593
|
+
/** The calls a build by the platform makes. An error carries content's `status`. */
|
|
2594
|
+
|
|
2595
|
+
/**
|
|
2596
|
+
* Whether an error is content saying it does not build this project yet --
|
|
2597
|
+
* or not knowing the request: content from before it built anything refuses
|
|
2598
|
+
* a build without a publish as an invalid body (400). Either way the tab
|
|
2599
|
+
* builds it, as it always did.
|
|
2600
|
+
*/
|
|
2601
|
+
function serverBuildsOff(error) {
|
|
2602
|
+
var status = statusOf(error);
|
|
2603
|
+
if (status === 400) return true;
|
|
2604
|
+
if (status !== 409) return false;
|
|
2605
|
+
var body = createForOfIteratorHelper._typeof(error) === "object" && error !== null && "body" in error ? error.body : null;
|
|
2606
|
+
var details = createForOfIteratorHelper._typeof(body) === "object" && body !== null && "details" in body ? body.details : null;
|
|
2607
|
+
return createForOfIteratorHelper._typeof(details) === "object" && details !== null && "code" in details && details.code === SERVER_BUILDS_OFF;
|
|
2608
|
+
}
|
|
2609
|
+
|
|
2610
|
+
/**
|
|
2611
|
+
* Have the platform build the proposal's staged files and serve the build at
|
|
2612
|
+
* its address (valbuild/home `docs/plans/server-builds.md`): nothing is built
|
|
2613
|
+
* in this tab, so no bundler is loaded, no builder tab is opened, and a tab
|
|
2614
|
+
* that closes meanwhile loses nothing.
|
|
2615
|
+
*
|
|
2616
|
+
* Content answers at once and builds in a job; the proposal is read until it
|
|
2617
|
+
* says the build of these inputs is served, or why it is not. `off` when
|
|
2618
|
+
* content does not build this project yet: `buildProposal` builds it in the
|
|
2619
|
+
* tab, as before.
|
|
2620
|
+
*
|
|
2621
|
+
* A cancel stops the waiting, not the build: the platform finishes it, and
|
|
2622
|
+
* the proposal's address serves it when it renders.
|
|
2623
|
+
*/
|
|
2624
|
+
function buildProposalOnServer(_x2) {
|
|
2625
|
+
return _buildProposalOnServer.apply(this, arguments);
|
|
2626
|
+
}
|
|
2627
|
+
function _buildProposalOnServer() {
|
|
2628
|
+
_buildProposalOnServer = createForOfIteratorHelper._asyncToGenerator(/*#__PURE__*/createForOfIteratorHelper._regenerator().m(function _callee4(deps) {
|
|
2629
|
+
var _deps$now2, _deps$sleep2, _deps$onStep2;
|
|
2630
|
+
var now, sleep, step, signal, read, staged, inputs, settled, asked, since, first, proposal, outcome, _t8, _t9, _t0, _t1, _t10;
|
|
2631
|
+
return createForOfIteratorHelper._regenerator().w(function (_context4) {
|
|
2632
|
+
while (1) switch (_context4.p = _context4.n) {
|
|
2633
|
+
case 0:
|
|
2634
|
+
now = (_deps$now2 = deps.now) !== null && _deps$now2 !== void 0 ? _deps$now2 : Date.now;
|
|
2635
|
+
sleep = (_deps$sleep2 = deps.sleep) !== null && _deps$sleep2 !== void 0 ? _deps$sleep2 : function (ms) {
|
|
2636
|
+
return new Promise(function (resolve) {
|
|
2637
|
+
return setTimeout(resolve, ms);
|
|
2638
|
+
});
|
|
2639
|
+
};
|
|
2640
|
+
step = (_deps$onStep2 = deps.onStep) !== null && _deps$onStep2 !== void 0 ? _deps$onStep2 : function () {};
|
|
2641
|
+
signal = deps.signal;
|
|
2642
|
+
step({
|
|
2643
|
+
kind: "reading"
|
|
2644
|
+
});
|
|
2645
|
+
// The proposal says what is staged: its files are not needed here
|
|
2646
|
+
_context4.p = 1;
|
|
2647
|
+
_context4.n = 2;
|
|
2648
|
+
return orAborted(deps.client.get(deps.name), signal);
|
|
2649
|
+
case 2:
|
|
2650
|
+
read = _context4.v;
|
|
2651
|
+
_context4.n = 4;
|
|
2652
|
+
break;
|
|
2653
|
+
case 3:
|
|
2654
|
+
_context4.p = 3;
|
|
2655
|
+
_t8 = _context4.v;
|
|
2656
|
+
return _context4.a(2, {
|
|
2657
|
+
status: "failed",
|
|
2658
|
+
message: messageOf(_t8)
|
|
2659
|
+
});
|
|
2660
|
+
case 4:
|
|
2661
|
+
if (!(read === ABORTED || signal !== null && signal !== void 0 && signal.aborted)) {
|
|
2662
|
+
_context4.n = 5;
|
|
2663
|
+
break;
|
|
2664
|
+
}
|
|
2665
|
+
return _context4.a(2, abortedOutcome(signal));
|
|
2666
|
+
case 5:
|
|
2667
|
+
staged = read.staged;
|
|
2668
|
+
if (!(!staged || staged.inputs === null)) {
|
|
2669
|
+
_context4.n = 6;
|
|
2670
|
+
break;
|
|
2671
|
+
}
|
|
2672
|
+
return _context4.a(2, {
|
|
2673
|
+
status: "nothing-staged"
|
|
2674
|
+
});
|
|
2675
|
+
case 6:
|
|
2676
|
+
if (staged.buildRequired) {
|
|
2677
|
+
_context4.n = 7;
|
|
2678
|
+
break;
|
|
2679
|
+
}
|
|
2680
|
+
return _context4.a(2, {
|
|
2681
|
+
status: "already-built",
|
|
2682
|
+
hash: null
|
|
2683
|
+
});
|
|
2684
|
+
case 7:
|
|
2685
|
+
inputs = staged.inputs;
|
|
2686
|
+
/** Where the proposal is: served, failed, replaced, or still being built. */
|
|
2687
|
+
settled = function settled(proposal) {
|
|
2688
|
+
var _proposal$built3, _proposal$serverBuild;
|
|
2689
|
+
if (((_proposal$built3 = proposal.built) === null || _proposal$built3 === void 0 ? void 0 : _proposal$built3.inputs) === inputs && proposal.built.hash) {
|
|
2690
|
+
return {
|
|
2691
|
+
status: "built",
|
|
2692
|
+
hash: proposal.built.hash,
|
|
2693
|
+
proposal: proposal
|
|
2694
|
+
};
|
|
2695
|
+
}
|
|
2696
|
+
if (((_proposal$serverBuild = proposal.serverBuild) === null || _proposal$serverBuild === void 0 ? void 0 : _proposal$serverBuild.inputs) === inputs && proposal.serverBuild.state === "failed") {
|
|
2697
|
+
var _proposal$serverBuild2;
|
|
2698
|
+
return {
|
|
2699
|
+
status: "failed",
|
|
2700
|
+
message: (_proposal$serverBuild2 = proposal.serverBuild.error) !== null && _proposal$serverBuild2 !== void 0 ? _proposal$serverBuild2 : "Val Build could not build it."
|
|
2701
|
+
};
|
|
2702
|
+
}
|
|
2703
|
+
// Staged again since (by anyone): this build is not the one to wait for
|
|
2704
|
+
if (proposal.staged && proposal.staged.inputs !== inputs) {
|
|
2705
|
+
return {
|
|
2706
|
+
status: "failed",
|
|
2707
|
+
message: "The proposal's files changed while it was being built. Build it again."
|
|
2708
|
+
};
|
|
2709
|
+
}
|
|
2710
|
+
return null;
|
|
2711
|
+
};
|
|
2712
|
+
_context4.p = 8;
|
|
2713
|
+
_context4.n = 9;
|
|
2714
|
+
return orAborted(deps.client.askBuild(deps.name, inputs), signal);
|
|
2715
|
+
case 9:
|
|
2716
|
+
asked = _context4.v;
|
|
2717
|
+
_context4.n = 12;
|
|
2718
|
+
break;
|
|
2719
|
+
case 10:
|
|
2720
|
+
_context4.p = 10;
|
|
2721
|
+
_t9 = _context4.v;
|
|
2722
|
+
if (!serverBuildsOff(_t9)) {
|
|
2723
|
+
_context4.n = 11;
|
|
2724
|
+
break;
|
|
2725
|
+
}
|
|
2726
|
+
return _context4.a(2, {
|
|
2727
|
+
status: "off"
|
|
2728
|
+
});
|
|
2729
|
+
case 11:
|
|
2730
|
+
return _context4.a(2, {
|
|
2731
|
+
status: "failed",
|
|
2732
|
+
message: messageOf(_t9)
|
|
2733
|
+
});
|
|
2734
|
+
case 12:
|
|
2735
|
+
if (!(asked === ABORTED)) {
|
|
2736
|
+
_context4.n = 13;
|
|
2737
|
+
break;
|
|
2738
|
+
}
|
|
2739
|
+
return _context4.a(2, abortedOutcome(signal));
|
|
2740
|
+
case 13:
|
|
2741
|
+
// Said only now: a project Val Build does not build never was building there
|
|
2742
|
+
since = now();
|
|
2743
|
+
step({
|
|
2744
|
+
kind: "on-server",
|
|
2745
|
+
since: since
|
|
2746
|
+
});
|
|
2747
|
+
first = settled(asked);
|
|
2748
|
+
if (!(first !== null)) {
|
|
2749
|
+
_context4.n = 14;
|
|
2750
|
+
break;
|
|
2751
|
+
}
|
|
2752
|
+
return _context4.a(2, first);
|
|
2753
|
+
case 14:
|
|
2754
|
+
if (!(now() - since < SERVER_BUILD_WAIT_MS)) {
|
|
2755
|
+
_context4.n = 24;
|
|
2756
|
+
break;
|
|
2757
|
+
}
|
|
2758
|
+
_context4.n = 15;
|
|
2759
|
+
return orAborted(sleep(SERVER_BUILD_POLL_MS), signal);
|
|
2760
|
+
case 15:
|
|
2761
|
+
_t0 = _context4.v;
|
|
2762
|
+
_t1 = ABORTED;
|
|
2763
|
+
if (!(_t0 === _t1)) {
|
|
2764
|
+
_context4.n = 16;
|
|
2765
|
+
break;
|
|
2766
|
+
}
|
|
2767
|
+
return _context4.a(2, abortedOutcome(signal));
|
|
2768
|
+
case 16:
|
|
2769
|
+
proposal = void 0;
|
|
2770
|
+
_context4.p = 17;
|
|
2771
|
+
_context4.n = 18;
|
|
2772
|
+
return orAborted(deps.client.get(deps.name), signal);
|
|
2773
|
+
case 18:
|
|
2774
|
+
proposal = _context4.v;
|
|
2775
|
+
_context4.n = 21;
|
|
2776
|
+
break;
|
|
2777
|
+
case 19:
|
|
2778
|
+
_context4.p = 19;
|
|
2779
|
+
_t10 = _context4.v;
|
|
2780
|
+
if (gatewayGaveUp(_t10)) {
|
|
2781
|
+
_context4.n = 20;
|
|
2782
|
+
break;
|
|
2783
|
+
}
|
|
2784
|
+
return _context4.a(2, {
|
|
2785
|
+
status: "failed",
|
|
2786
|
+
message: messageOf(_t10)
|
|
2787
|
+
});
|
|
2788
|
+
case 20:
|
|
2789
|
+
step({
|
|
2790
|
+
kind: "on-server",
|
|
2791
|
+
since: since
|
|
2792
|
+
});
|
|
2793
|
+
return _context4.a(3, 14);
|
|
2794
|
+
case 21:
|
|
2795
|
+
if (!(proposal === ABORTED)) {
|
|
2796
|
+
_context4.n = 22;
|
|
2797
|
+
break;
|
|
2798
|
+
}
|
|
2799
|
+
return _context4.a(2, abortedOutcome(signal));
|
|
2800
|
+
case 22:
|
|
2801
|
+
// Said again, so a watchdog sees it waiting, not stalled.
|
|
2802
|
+
step({
|
|
2803
|
+
kind: "on-server",
|
|
2804
|
+
since: since
|
|
2805
|
+
});
|
|
2806
|
+
outcome = settled(proposal);
|
|
2807
|
+
if (!(outcome !== null)) {
|
|
2808
|
+
_context4.n = 23;
|
|
2809
|
+
break;
|
|
2810
|
+
}
|
|
2811
|
+
return _context4.a(2, outcome);
|
|
2812
|
+
case 23:
|
|
2813
|
+
_context4.n = 14;
|
|
2814
|
+
break;
|
|
2815
|
+
case 24:
|
|
2816
|
+
return _context4.a(2, {
|
|
2817
|
+
status: "failed",
|
|
2818
|
+
message: "Val Build did not finish the build in ".concat(Math.round(SERVER_BUILD_WAIT_MS / 60000), " minutes. Try again.")
|
|
2819
|
+
});
|
|
2820
|
+
}
|
|
2821
|
+
}, _callee4, null, [[17, 19], [8, 10], [1, 3]]);
|
|
2822
|
+
}));
|
|
2823
|
+
return _buildProposalOnServer.apply(this, arguments);
|
|
2824
|
+
}
|
|
2572
2825
|
|
|
2573
2826
|
/*
|
|
2574
2827
|
* A quick preview's files: the proposal's app bundled in the tab, for the
|
|
@@ -2782,6 +3035,9 @@ exports.BUILD_CANCELLED_MESSAGE = BUILD_CANCELLED_MESSAGE;
|
|
|
2782
3035
|
exports.DEPLOY_STOPPED_MESSAGE = DEPLOY_STOPPED_MESSAGE;
|
|
2783
3036
|
exports.MergePrepareAnswer = MergePrepareAnswer;
|
|
2784
3037
|
exports.RENEW_EVERY_MS = RENEW_EVERY_MS;
|
|
3038
|
+
exports.SERVER_BUILDS_OFF = SERVER_BUILDS_OFF;
|
|
3039
|
+
exports.SERVER_BUILD_POLL_MS = SERVER_BUILD_POLL_MS;
|
|
3040
|
+
exports.SERVER_BUILD_WAIT_MS = SERVER_BUILD_WAIT_MS;
|
|
2785
3041
|
exports.SERVE_POLL_MS = SERVE_POLL_MS;
|
|
2786
3042
|
exports.SERVE_WAIT_MS = SERVE_WAIT_MS;
|
|
2787
3043
|
exports.STUDIO_OUT_OF_DATE = STUDIO_OUT_OF_DATE;
|
|
@@ -2789,6 +3045,7 @@ exports.STUDIO_OUT_OF_DATE_MESSAGE = STUDIO_OUT_OF_DATE_MESSAGE;
|
|
|
2789
3045
|
exports.StudioPublishError = StudioPublishError;
|
|
2790
3046
|
exports.StudioUploadError = StudioUploadError;
|
|
2791
3047
|
exports.buildProposal = buildProposal;
|
|
3048
|
+
exports.buildProposalOnServer = buildProposalOnServer;
|
|
2792
3049
|
exports.buildQuickPreview = buildQuickPreview;
|
|
2793
3050
|
exports.callJson = callJson;
|
|
2794
3051
|
exports.carriedInto = carriedInto;
|
|
@@ -2306,6 +2306,8 @@ var SERVE_POLL_MS = 5000;
|
|
|
2306
2306
|
function buildProposal(_x) {
|
|
2307
2307
|
return _buildProposal.apply(this, arguments);
|
|
2308
2308
|
}
|
|
2309
|
+
|
|
2310
|
+
/** What content answers, in `details.code`, for a project it does not build yet. */
|
|
2309
2311
|
function _buildProposal() {
|
|
2310
2312
|
_buildProposal = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3(deps) {
|
|
2311
2313
|
var _deps$now, _deps$sleep, _deps$onStep;
|
|
@@ -2566,6 +2568,257 @@ function _buildProposal() {
|
|
|
2566
2568
|
}));
|
|
2567
2569
|
return _buildProposal.apply(this, arguments);
|
|
2568
2570
|
}
|
|
2571
|
+
var SERVER_BUILDS_OFF = "server-builds-off";
|
|
2572
|
+
|
|
2573
|
+
/** How often the proposal is read while the platform builds it. */
|
|
2574
|
+
var SERVER_BUILD_POLL_MS = 1000;
|
|
2575
|
+
|
|
2576
|
+
/**
|
|
2577
|
+
* How long a build by the platform is waited for. It is seconds
|
|
2578
|
+
* (valbuild/home `docs/plans/server-builds.md`); this is for the platform not
|
|
2579
|
+
* answering, never for a build that is merely slow.
|
|
2580
|
+
*/
|
|
2581
|
+
var SERVER_BUILD_WAIT_MS = 4 * 60000;
|
|
2582
|
+
|
|
2583
|
+
/**
|
|
2584
|
+
* Where a build by the platform is (`buildProposalOnServer`): reading what is
|
|
2585
|
+
* staged, then Val Build building, rendering and serving it. Its own type,
|
|
2586
|
+
* not `ProposalBuildStep`'s, which every page that runs `buildProposal`
|
|
2587
|
+
* switches over.
|
|
2588
|
+
*/
|
|
2589
|
+
|
|
2590
|
+
/** The calls a build by the platform makes. An error carries content's `status`. */
|
|
2591
|
+
|
|
2592
|
+
/**
|
|
2593
|
+
* Whether an error is content saying it does not build this project yet --
|
|
2594
|
+
* or not knowing the request: content from before it built anything refuses
|
|
2595
|
+
* a build without a publish as an invalid body (400). Either way the tab
|
|
2596
|
+
* builds it, as it always did.
|
|
2597
|
+
*/
|
|
2598
|
+
function serverBuildsOff(error) {
|
|
2599
|
+
var status = statusOf(error);
|
|
2600
|
+
if (status === 400) return true;
|
|
2601
|
+
if (status !== 409) return false;
|
|
2602
|
+
var body = _typeof(error) === "object" && error !== null && "body" in error ? error.body : null;
|
|
2603
|
+
var details = _typeof(body) === "object" && body !== null && "details" in body ? body.details : null;
|
|
2604
|
+
return _typeof(details) === "object" && details !== null && "code" in details && details.code === SERVER_BUILDS_OFF;
|
|
2605
|
+
}
|
|
2606
|
+
|
|
2607
|
+
/**
|
|
2608
|
+
* Have the platform build the proposal's staged files and serve the build at
|
|
2609
|
+
* its address (valbuild/home `docs/plans/server-builds.md`): nothing is built
|
|
2610
|
+
* in this tab, so no bundler is loaded, no builder tab is opened, and a tab
|
|
2611
|
+
* that closes meanwhile loses nothing.
|
|
2612
|
+
*
|
|
2613
|
+
* Content answers at once and builds in a job; the proposal is read until it
|
|
2614
|
+
* says the build of these inputs is served, or why it is not. `off` when
|
|
2615
|
+
* content does not build this project yet: `buildProposal` builds it in the
|
|
2616
|
+
* tab, as before.
|
|
2617
|
+
*
|
|
2618
|
+
* A cancel stops the waiting, not the build: the platform finishes it, and
|
|
2619
|
+
* the proposal's address serves it when it renders.
|
|
2620
|
+
*/
|
|
2621
|
+
function buildProposalOnServer(_x2) {
|
|
2622
|
+
return _buildProposalOnServer.apply(this, arguments);
|
|
2623
|
+
}
|
|
2624
|
+
function _buildProposalOnServer() {
|
|
2625
|
+
_buildProposalOnServer = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4(deps) {
|
|
2626
|
+
var _deps$now2, _deps$sleep2, _deps$onStep2;
|
|
2627
|
+
var now, sleep, step, signal, read, staged, inputs, settled, asked, since, first, proposal, outcome, _t8, _t9, _t0, _t1, _t10;
|
|
2628
|
+
return _regenerator().w(function (_context4) {
|
|
2629
|
+
while (1) switch (_context4.p = _context4.n) {
|
|
2630
|
+
case 0:
|
|
2631
|
+
now = (_deps$now2 = deps.now) !== null && _deps$now2 !== void 0 ? _deps$now2 : Date.now;
|
|
2632
|
+
sleep = (_deps$sleep2 = deps.sleep) !== null && _deps$sleep2 !== void 0 ? _deps$sleep2 : function (ms) {
|
|
2633
|
+
return new Promise(function (resolve) {
|
|
2634
|
+
return setTimeout(resolve, ms);
|
|
2635
|
+
});
|
|
2636
|
+
};
|
|
2637
|
+
step = (_deps$onStep2 = deps.onStep) !== null && _deps$onStep2 !== void 0 ? _deps$onStep2 : function () {};
|
|
2638
|
+
signal = deps.signal;
|
|
2639
|
+
step({
|
|
2640
|
+
kind: "reading"
|
|
2641
|
+
});
|
|
2642
|
+
// The proposal says what is staged: its files are not needed here
|
|
2643
|
+
_context4.p = 1;
|
|
2644
|
+
_context4.n = 2;
|
|
2645
|
+
return orAborted(deps.client.get(deps.name), signal);
|
|
2646
|
+
case 2:
|
|
2647
|
+
read = _context4.v;
|
|
2648
|
+
_context4.n = 4;
|
|
2649
|
+
break;
|
|
2650
|
+
case 3:
|
|
2651
|
+
_context4.p = 3;
|
|
2652
|
+
_t8 = _context4.v;
|
|
2653
|
+
return _context4.a(2, {
|
|
2654
|
+
status: "failed",
|
|
2655
|
+
message: messageOf(_t8)
|
|
2656
|
+
});
|
|
2657
|
+
case 4:
|
|
2658
|
+
if (!(read === ABORTED || signal !== null && signal !== void 0 && signal.aborted)) {
|
|
2659
|
+
_context4.n = 5;
|
|
2660
|
+
break;
|
|
2661
|
+
}
|
|
2662
|
+
return _context4.a(2, abortedOutcome(signal));
|
|
2663
|
+
case 5:
|
|
2664
|
+
staged = read.staged;
|
|
2665
|
+
if (!(!staged || staged.inputs === null)) {
|
|
2666
|
+
_context4.n = 6;
|
|
2667
|
+
break;
|
|
2668
|
+
}
|
|
2669
|
+
return _context4.a(2, {
|
|
2670
|
+
status: "nothing-staged"
|
|
2671
|
+
});
|
|
2672
|
+
case 6:
|
|
2673
|
+
if (staged.buildRequired) {
|
|
2674
|
+
_context4.n = 7;
|
|
2675
|
+
break;
|
|
2676
|
+
}
|
|
2677
|
+
return _context4.a(2, {
|
|
2678
|
+
status: "already-built",
|
|
2679
|
+
hash: null
|
|
2680
|
+
});
|
|
2681
|
+
case 7:
|
|
2682
|
+
inputs = staged.inputs;
|
|
2683
|
+
/** Where the proposal is: served, failed, replaced, or still being built. */
|
|
2684
|
+
settled = function settled(proposal) {
|
|
2685
|
+
var _proposal$built3, _proposal$serverBuild;
|
|
2686
|
+
if (((_proposal$built3 = proposal.built) === null || _proposal$built3 === void 0 ? void 0 : _proposal$built3.inputs) === inputs && proposal.built.hash) {
|
|
2687
|
+
return {
|
|
2688
|
+
status: "built",
|
|
2689
|
+
hash: proposal.built.hash,
|
|
2690
|
+
proposal: proposal
|
|
2691
|
+
};
|
|
2692
|
+
}
|
|
2693
|
+
if (((_proposal$serverBuild = proposal.serverBuild) === null || _proposal$serverBuild === void 0 ? void 0 : _proposal$serverBuild.inputs) === inputs && proposal.serverBuild.state === "failed") {
|
|
2694
|
+
var _proposal$serverBuild2;
|
|
2695
|
+
return {
|
|
2696
|
+
status: "failed",
|
|
2697
|
+
message: (_proposal$serverBuild2 = proposal.serverBuild.error) !== null && _proposal$serverBuild2 !== void 0 ? _proposal$serverBuild2 : "Val Build could not build it."
|
|
2698
|
+
};
|
|
2699
|
+
}
|
|
2700
|
+
// Staged again since (by anyone): this build is not the one to wait for
|
|
2701
|
+
if (proposal.staged && proposal.staged.inputs !== inputs) {
|
|
2702
|
+
return {
|
|
2703
|
+
status: "failed",
|
|
2704
|
+
message: "The proposal's files changed while it was being built. Build it again."
|
|
2705
|
+
};
|
|
2706
|
+
}
|
|
2707
|
+
return null;
|
|
2708
|
+
};
|
|
2709
|
+
_context4.p = 8;
|
|
2710
|
+
_context4.n = 9;
|
|
2711
|
+
return orAborted(deps.client.askBuild(deps.name, inputs), signal);
|
|
2712
|
+
case 9:
|
|
2713
|
+
asked = _context4.v;
|
|
2714
|
+
_context4.n = 12;
|
|
2715
|
+
break;
|
|
2716
|
+
case 10:
|
|
2717
|
+
_context4.p = 10;
|
|
2718
|
+
_t9 = _context4.v;
|
|
2719
|
+
if (!serverBuildsOff(_t9)) {
|
|
2720
|
+
_context4.n = 11;
|
|
2721
|
+
break;
|
|
2722
|
+
}
|
|
2723
|
+
return _context4.a(2, {
|
|
2724
|
+
status: "off"
|
|
2725
|
+
});
|
|
2726
|
+
case 11:
|
|
2727
|
+
return _context4.a(2, {
|
|
2728
|
+
status: "failed",
|
|
2729
|
+
message: messageOf(_t9)
|
|
2730
|
+
});
|
|
2731
|
+
case 12:
|
|
2732
|
+
if (!(asked === ABORTED)) {
|
|
2733
|
+
_context4.n = 13;
|
|
2734
|
+
break;
|
|
2735
|
+
}
|
|
2736
|
+
return _context4.a(2, abortedOutcome(signal));
|
|
2737
|
+
case 13:
|
|
2738
|
+
// Said only now: a project Val Build does not build never was building there
|
|
2739
|
+
since = now();
|
|
2740
|
+
step({
|
|
2741
|
+
kind: "on-server",
|
|
2742
|
+
since: since
|
|
2743
|
+
});
|
|
2744
|
+
first = settled(asked);
|
|
2745
|
+
if (!(first !== null)) {
|
|
2746
|
+
_context4.n = 14;
|
|
2747
|
+
break;
|
|
2748
|
+
}
|
|
2749
|
+
return _context4.a(2, first);
|
|
2750
|
+
case 14:
|
|
2751
|
+
if (!(now() - since < SERVER_BUILD_WAIT_MS)) {
|
|
2752
|
+
_context4.n = 24;
|
|
2753
|
+
break;
|
|
2754
|
+
}
|
|
2755
|
+
_context4.n = 15;
|
|
2756
|
+
return orAborted(sleep(SERVER_BUILD_POLL_MS), signal);
|
|
2757
|
+
case 15:
|
|
2758
|
+
_t0 = _context4.v;
|
|
2759
|
+
_t1 = ABORTED;
|
|
2760
|
+
if (!(_t0 === _t1)) {
|
|
2761
|
+
_context4.n = 16;
|
|
2762
|
+
break;
|
|
2763
|
+
}
|
|
2764
|
+
return _context4.a(2, abortedOutcome(signal));
|
|
2765
|
+
case 16:
|
|
2766
|
+
proposal = void 0;
|
|
2767
|
+
_context4.p = 17;
|
|
2768
|
+
_context4.n = 18;
|
|
2769
|
+
return orAborted(deps.client.get(deps.name), signal);
|
|
2770
|
+
case 18:
|
|
2771
|
+
proposal = _context4.v;
|
|
2772
|
+
_context4.n = 21;
|
|
2773
|
+
break;
|
|
2774
|
+
case 19:
|
|
2775
|
+
_context4.p = 19;
|
|
2776
|
+
_t10 = _context4.v;
|
|
2777
|
+
if (gatewayGaveUp(_t10)) {
|
|
2778
|
+
_context4.n = 20;
|
|
2779
|
+
break;
|
|
2780
|
+
}
|
|
2781
|
+
return _context4.a(2, {
|
|
2782
|
+
status: "failed",
|
|
2783
|
+
message: messageOf(_t10)
|
|
2784
|
+
});
|
|
2785
|
+
case 20:
|
|
2786
|
+
step({
|
|
2787
|
+
kind: "on-server",
|
|
2788
|
+
since: since
|
|
2789
|
+
});
|
|
2790
|
+
return _context4.a(3, 14);
|
|
2791
|
+
case 21:
|
|
2792
|
+
if (!(proposal === ABORTED)) {
|
|
2793
|
+
_context4.n = 22;
|
|
2794
|
+
break;
|
|
2795
|
+
}
|
|
2796
|
+
return _context4.a(2, abortedOutcome(signal));
|
|
2797
|
+
case 22:
|
|
2798
|
+
// Said again, so a watchdog sees it waiting, not stalled.
|
|
2799
|
+
step({
|
|
2800
|
+
kind: "on-server",
|
|
2801
|
+
since: since
|
|
2802
|
+
});
|
|
2803
|
+
outcome = settled(proposal);
|
|
2804
|
+
if (!(outcome !== null)) {
|
|
2805
|
+
_context4.n = 23;
|
|
2806
|
+
break;
|
|
2807
|
+
}
|
|
2808
|
+
return _context4.a(2, outcome);
|
|
2809
|
+
case 23:
|
|
2810
|
+
_context4.n = 14;
|
|
2811
|
+
break;
|
|
2812
|
+
case 24:
|
|
2813
|
+
return _context4.a(2, {
|
|
2814
|
+
status: "failed",
|
|
2815
|
+
message: "Val Build did not finish the build in ".concat(Math.round(SERVER_BUILD_WAIT_MS / 60000), " minutes. Try again.")
|
|
2816
|
+
});
|
|
2817
|
+
}
|
|
2818
|
+
}, _callee4, null, [[17, 19], [8, 10], [1, 3]]);
|
|
2819
|
+
}));
|
|
2820
|
+
return _buildProposalOnServer.apply(this, arguments);
|
|
2821
|
+
}
|
|
2569
2822
|
|
|
2570
2823
|
/*
|
|
2571
2824
|
* A quick preview's files: the proposal's app bundled in the tab, for the
|
|
@@ -2774,4 +3027,4 @@ function contentTypeOf(name) {
|
|
|
2774
3027
|
return (_CONTENT_TYPES$extens = CONTENT_TYPES[extension]) !== null && _CONTENT_TYPES$extens !== void 0 ? _CONTENT_TYPES$extens : "application/octet-stream";
|
|
2775
3028
|
}
|
|
2776
3029
|
|
|
2777
|
-
export { BUILD_CANCELLED_MESSAGE, DEPLOY_STOPPED_MESSAGE, MergePrepareAnswer, RENEW_EVERY_MS, SERVE_POLL_MS, SERVE_WAIT_MS, STUDIO_OUT_OF_DATE, STUDIO_OUT_OF_DATE_MESSAGE, StudioPublishError, StudioUploadError, buildProposal, buildQuickPreview, callJson, carriedInto, clientFilesOf, createStudioJobClient, createStudioPublishClient, isExpiredSlot, isMergeChange, isTransientPublishError, layerMoved, loadedLayer, markStudioOutOfDate, onPublishRefusal, publishApiOf, readLiveLayer, rememberLoadedLayer, resetLoadedLayerForTests, runJobToEnd, runStudioDeploy, runStudioJob, runStudioPublish, siteMovedSinceLoad, splitBinaryFiles, studioOutOfDateRefusals, subscribeStudioOutOfDate, withCommittedFiles, withoutLockfiles };
|
|
3030
|
+
export { BUILD_CANCELLED_MESSAGE, DEPLOY_STOPPED_MESSAGE, MergePrepareAnswer, RENEW_EVERY_MS, SERVER_BUILDS_OFF, SERVER_BUILD_POLL_MS, SERVER_BUILD_WAIT_MS, SERVE_POLL_MS, SERVE_WAIT_MS, STUDIO_OUT_OF_DATE, STUDIO_OUT_OF_DATE_MESSAGE, StudioPublishError, StudioUploadError, buildProposal, buildProposalOnServer, buildQuickPreview, callJson, carriedInto, clientFilesOf, createStudioJobClient, createStudioPublishClient, isExpiredSlot, isMergeChange, isTransientPublishError, layerMoved, loadedLayer, markStudioOutOfDate, onPublishRefusal, publishApiOf, readLiveLayer, rememberLoadedLayer, resetLoadedLayerForTests, runJobToEnd, runStudioDeploy, runStudioJob, runStudioPublish, siteMovedSinceLoad, splitBinaryFiles, studioOutOfDateRefusals, subscribeStudioOutOfDate, withCommittedFiles, withoutLockfiles };
|