@valbuild/shared 0.150.20 → 0.151.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +236 -0
- package/client/dist/valbuild-shared-client.cjs.dev.js +1 -1
- package/client/dist/valbuild-shared-client.cjs.prod.js +1 -1
- package/client/dist/valbuild-shared-client.esm.js +1 -1
- package/dist/declarations/src/internal/ApiRoutes.d.ts +253 -2
- package/dist/declarations/src/internal/content/applyChain.d.ts +124 -0
- package/dist/declarations/src/internal/content/buildRegistry.d.ts +36 -0
- package/dist/declarations/src/internal/content/jsonValuesOps.d.ts +110 -0
- package/dist/declarations/src/internal/content/moduleStore.d.ts +119 -0
- package/dist/declarations/src/internal/content/source.d.ts +71 -0
- package/dist/declarations/src/internal/content/version.d.ts +151 -0
- package/dist/declarations/src/internal/index.d.ts +8 -1
- package/dist/declarations/src/internal/publish/projectSource.d.ts +28 -0
- package/dist/declarations/src/internal/search/searchIndex.d.ts +34 -3
- package/dist/declarations/src/internal/server/types.d.ts +9 -1
- package/dist/declarations/src/internal/valCanvasProtocol.d.ts +46 -0
- package/dist/declarations/src/internal/valClientHeader.d.ts +36 -0
- package/dist/declarations/src/publish/callJson.d.ts +15 -0
- package/dist/declarations/src/publish/jobClient.d.ts +7 -1
- package/dist/declarations/src/publish/publishClient.d.ts +2 -14
- package/dist/{getSitemapTree-fef55872.esm.js → getSitemapTree-3c1b9e57.esm.js} +18 -2
- package/dist/{getSitemapTree-6dfa2f4e.cjs.dev.js → getSitemapTree-59c5ed5d.cjs.dev.js} +18 -2
- package/dist/{getSitemapTree-8a04f3cf.cjs.prod.js → getSitemapTree-6b9024d1.cjs.prod.js} +18 -2
- package/dist/{protocol-d0efb8cd.cjs.dev.js → projectSource-2a58ef15.cjs.dev.js} +221 -0
- package/dist/{protocol-55cfa3cf.esm.js → projectSource-7f0ee83c.esm.js} +216 -1
- package/dist/{protocol-b1055ef0.cjs.prod.js → projectSource-ed6aec39.cjs.prod.js} +221 -0
- package/internal/dist/valbuild-shared-internal.cjs.dev.js +2387 -189
- package/internal/dist/valbuild-shared-internal.cjs.prod.js +2387 -189
- package/internal/dist/valbuild-shared-internal.esm.js +2332 -172
- package/package.json +3 -3
- package/publish/dist/valbuild-shared-publish.cjs.dev.js +48 -155
- package/publish/dist/valbuild-shared-publish.cjs.prod.js +48 -155
- package/publish/dist/valbuild-shared-publish.esm.js +17 -123
- package/dist/declarations/src/internal/server/requestScopedMemo.d.ts +0 -49
|
@@ -57,6 +57,28 @@ export type SearchIndex = {
|
|
|
57
57
|
* re-indexing one module exists to avoid.
|
|
58
58
|
*/
|
|
59
59
|
docsByModule: Map<ModuleFilePath, Set<string>>;
|
|
60
|
+
/**
|
|
61
|
+
* For a module whose root is a record: each entry's documents, and the
|
|
62
|
+
* value they were made from, by key -- so indexing it again walks only the
|
|
63
|
+
* entries whose value is a different object (see {@link indexModule}).
|
|
64
|
+
*/
|
|
65
|
+
/**
|
|
66
|
+
* What each module was last indexed from, whole: the same source object
|
|
67
|
+
* under a schema that says the same is not walked again. Removing a
|
|
68
|
+
* document from a big index is slow (FlexSearch looks for it everywhere),
|
|
69
|
+
* so indexing an unchanged module again was the cost of a pass.
|
|
70
|
+
*/
|
|
71
|
+
walkedByModule: Map<ModuleFilePath, {
|
|
72
|
+
source: Json;
|
|
73
|
+
schema: string;
|
|
74
|
+
}>;
|
|
75
|
+
entriesByModule: Map<ModuleFilePath, {
|
|
76
|
+
schema: SerializedSchema;
|
|
77
|
+
entries: Map<string, {
|
|
78
|
+
source: Json;
|
|
79
|
+
docs: string[];
|
|
80
|
+
}>;
|
|
81
|
+
}>;
|
|
60
82
|
};
|
|
61
83
|
/** An index with nothing in it. Fill it with {@link indexModule}. */
|
|
62
84
|
export declare function createSearchIndex(): SearchIndex;
|
|
@@ -70,10 +92,19 @@ export declare function createSearchIndex(): SearchIndex;
|
|
|
70
92
|
* `.jsonValues()` entries are indexed only once their content is loaded — an
|
|
71
93
|
* un-loaded entry is an opaque marker that {@link traverseSchemaSource} skips, so
|
|
72
94
|
* the index is naturally PARTIAL and grows as batches land. That is why the search
|
|
73
|
-
* UI loads the entries on the first query and re-indexes
|
|
74
|
-
*
|
|
95
|
+
* UI loads the entries on the first query and re-indexes as they arrive, rather
|
|
96
|
+
* than pretending an empty result set is an answer -- and why a module whose
|
|
97
|
+
* root is a record is re-indexed by entry ({@link indexRecordModule}): a pass
|
|
98
|
+
* per batch walks the batch, not the record.
|
|
99
|
+
*/
|
|
100
|
+
export declare function indexModule(searchIndex: SearchIndex, moduleFilePath: ModuleFilePath, source: Json, schema: SerializedSchema,
|
|
101
|
+
/**
|
|
102
|
+
* Stop by this time (`performance.now()`), for a caller that must not hold
|
|
103
|
+
* the thread: answers `false` when it stopped with entries of a record
|
|
104
|
+
* module still to walk, and the same call again goes on from there. A
|
|
105
|
+
* module that is not a record is walked whole, whatever the time.
|
|
75
106
|
*/
|
|
76
|
-
|
|
107
|
+
until?: number): boolean;
|
|
77
108
|
/**
|
|
78
109
|
* Drop everything indexed for one module.
|
|
79
110
|
*
|
|
@@ -45,7 +45,15 @@ export type ValServerJsonResult<Body extends Json | never = never, Error extends
|
|
|
45
45
|
status: 400;
|
|
46
46
|
json: Error;
|
|
47
47
|
} : never);
|
|
48
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Nothing moved since the ETag the caller sent back: no body, as HTTP
|
|
50
|
+
* requires of a 304.
|
|
51
|
+
*/
|
|
52
|
+
export type ValServerNotModified = {
|
|
53
|
+
status: 304;
|
|
54
|
+
headers?: Record<string, string | undefined>;
|
|
55
|
+
};
|
|
56
|
+
export type ValServerGenericResult = ValServerNotModified | ValServerJsonResult<Json> | ValServerError | ValServerRedirectResult<ValCookiesNames> | ValServerResult<ValCookiesNames, string | ReadableStream<Uint8Array>>;
|
|
49
57
|
export type ValUIRequestHandler = (path: string, url: string) => Promise<ValServerGenericResult>;
|
|
50
58
|
export type ValSession = {
|
|
51
59
|
mode: "unauthorized";
|
|
@@ -93,6 +93,26 @@ export type ValCanvasPageMessage = {
|
|
|
93
93
|
draftMode: boolean;
|
|
94
94
|
/** The URL the frame ended up on, which a redirect may have changed. */
|
|
95
95
|
url: string;
|
|
96
|
+
/**
|
|
97
|
+
* The modules the page holds a draft of: what its server read for this
|
|
98
|
+
* request (`<ValProvider draft>`). The studio sends each of them in its
|
|
99
|
+
* catch-up, pending or not, so a draft that stopped being the draft
|
|
100
|
+
* before the studio was there to say so -- discarded, published -- is
|
|
101
|
+
* replaced rather than kept. Absent from a page of the release before,
|
|
102
|
+
* and from a page that read no draft.
|
|
103
|
+
*/
|
|
104
|
+
holds?: ModuleFilePath[];
|
|
105
|
+
/**
|
|
106
|
+
* The version the page holds each of {@link holds} at, where its draft
|
|
107
|
+
* says (`draftHoldsVersions`): the studio does not send one it would
|
|
108
|
+
* send at the same version -- the same content. Absent from a page of
|
|
109
|
+
* the release before, which is sent everything it holds, as before.
|
|
110
|
+
*/
|
|
111
|
+
holdsVersions?: Partial<Record<ModuleFilePath, {
|
|
112
|
+
schema: string;
|
|
113
|
+
base: string;
|
|
114
|
+
chain: string;
|
|
115
|
+
}>>;
|
|
96
116
|
} | {
|
|
97
117
|
val: typeof VAL_CANVAS_MESSAGE;
|
|
98
118
|
type: "elements";
|
|
@@ -257,8 +277,18 @@ export type ValCanvasStudioMessage = {
|
|
|
257
277
|
/**
|
|
258
278
|
* The whole module source. `unknown` because the page's own types are the
|
|
259
279
|
* ones that give it meaning; nothing in between should be interpreting it.
|
|
280
|
+
*
|
|
281
|
+
* @deprecated A page of this release reads `read`; this is for a page
|
|
282
|
+
* of the release before. Goes in the release after the one that ships
|
|
283
|
+
* `read`, with the bridges' fallback that reads it: see
|
|
284
|
+
* "Release-delayed deletions" in `docs/plans/one-content-model.md`.
|
|
260
285
|
*/
|
|
261
286
|
source: unknown;
|
|
287
|
+
/**
|
|
288
|
+
* The same module as a read (`ModuleRead`), which the page keeps as it
|
|
289
|
+
* is. Optional: a Studio from the release before sends `source` alone.
|
|
290
|
+
*/
|
|
291
|
+
read?: unknown;
|
|
262
292
|
} | {
|
|
263
293
|
/**
|
|
264
294
|
* Everything the studio holds has been sent.
|
|
@@ -276,6 +306,22 @@ export type ValCanvasStudioMessage = {
|
|
|
276
306
|
*/
|
|
277
307
|
val: typeof VAL_CANVAS_MESSAGE;
|
|
278
308
|
type: "sourcesSynced";
|
|
309
|
+
} | {
|
|
310
|
+
/**
|
|
311
|
+
* The server holds the editor's changes up to this version (`seq`, the
|
|
312
|
+
* server's `ProjectVersion.seq`; `null` from a server that reports
|
|
313
|
+
* none). Sent once after `sourcesSynced`, then every time it moves.
|
|
314
|
+
*
|
|
315
|
+
* What the page re-reads its server-rendered content on (a loader, a
|
|
316
|
+
* server component): those only show an edit once the server has it,
|
|
317
|
+
* so a refresh sent when the edit was typed raced the write and came
|
|
318
|
+
* back without it -- which a ten second safety refresh used to catch.
|
|
319
|
+
* A bridge of the release before ignores it, as it ignores any type it
|
|
320
|
+
* does not know.
|
|
321
|
+
*/
|
|
322
|
+
val: typeof VAL_CANVAS_MESSAGE;
|
|
323
|
+
type: "confirmed";
|
|
324
|
+
seq: number | null;
|
|
279
325
|
} | {
|
|
280
326
|
/**
|
|
281
327
|
* What colour to outline the page's content in.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which Val package, at which version, sent a request to Val Build.
|
|
3
|
+
*
|
|
4
|
+
* Sent on every request a Val package makes to Val's own services from a
|
|
5
|
+
* server or a CLI -- the content host, `/api/login`, the analytics ingest --
|
|
6
|
+
* so Val Build can tell which versions are still out there and which old
|
|
7
|
+
* endpoints they still call. Without it an endpoint can never be retired with
|
|
8
|
+
* any confidence: a request from a site nobody has upgraded in a year looks
|
|
9
|
+
* exactly like one from yesterday's release.
|
|
10
|
+
*
|
|
11
|
+
* The value is a product token, `@valbuild/server@0.152.0`: the package whose
|
|
12
|
+
* code built the request, because that is what decides which endpoints are
|
|
13
|
+
* called. Not the framework binding or the app: those do not choose URLs.
|
|
14
|
+
*
|
|
15
|
+
* NOT sent from the browser. A custom header on a cross-origin request makes
|
|
16
|
+
* the browser send a CORS preflight, and a host that does not list the header
|
|
17
|
+
* in `Access-Control-Allow-Headers` refuses the request outright -- so adding
|
|
18
|
+
* it there is a change to every such host first.
|
|
19
|
+
*
|
|
20
|
+
* It identifies the code, not the caller: anyone can send any value, so it is
|
|
21
|
+
* for counting, never for deciding what a request may do.
|
|
22
|
+
*/
|
|
23
|
+
export declare const VAL_CLIENT_HEADER = "x-val-client";
|
|
24
|
+
/** Packages that send {@link VAL_CLIENT_HEADER}. */
|
|
25
|
+
export type ValClientPackage = "@valbuild/server" | "@valbuild/cli";
|
|
26
|
+
/**
|
|
27
|
+
* `{ "x-val-client": "@valbuild/server@0.152.0" }`, to spread into a
|
|
28
|
+
* request's headers.
|
|
29
|
+
*
|
|
30
|
+
* A version that could not be read is sent as `unknown` rather than leaving
|
|
31
|
+
* the header out: "a server too broken to know its version" is still a thing
|
|
32
|
+
* worth counting, and it is not the same as "a version older than the header".
|
|
33
|
+
*/
|
|
34
|
+
export declare function valClientHeaders(pkg: ValClientPackage, version: string | null | undefined): {
|
|
35
|
+
[VAL_CLIENT_HEADER]: string;
|
|
36
|
+
};
|
|
@@ -19,3 +19,18 @@ export declare function isTransientPublishError(error: unknown): boolean;
|
|
|
19
19
|
* `StudioPublishError` carrying the answer's own message.
|
|
20
20
|
*/
|
|
21
21
|
export declare function callJson(fetchImpl: typeof fetch, url: string, method: "GET" | "POST", body?: unknown): Promise<unknown>;
|
|
22
|
+
/**
|
|
23
|
+
* One JSON READ through this origin, BY VERSION: `held` is the answer the
|
|
24
|
+
* caller holds, with its `ETag`, which goes as `If-None-Match`. While the
|
|
25
|
+
* answer is still that one (a 304, with no body) it is `held` again;
|
|
26
|
+
* otherwise the new body, `parse`d, with its `ETag` -- `null` when the answer
|
|
27
|
+
* named none, so there is nothing to hold it by. Errors as {@link callJson}
|
|
28
|
+
* throws them.
|
|
29
|
+
*/
|
|
30
|
+
export declare function readJsonByVersion<T>(fetchImpl: typeof fetch, url: string, held: {
|
|
31
|
+
etag: string;
|
|
32
|
+
value: T;
|
|
33
|
+
} | null, parse: (body: unknown) => T): Promise<{
|
|
34
|
+
etag: string | null;
|
|
35
|
+
value: T;
|
|
36
|
+
}>;
|
|
@@ -24,7 +24,13 @@ export type StudioJobClient = {
|
|
|
24
24
|
* failed: `types`, an upgrade's new type errors (Publish anyway on home's
|
|
25
25
|
* upgrade page). Content refuses it over anything else.
|
|
26
26
|
*/
|
|
27
|
-
anyway?: "types"[]
|
|
27
|
+
anyway?: "types"[],
|
|
28
|
+
/**
|
|
29
|
+
* The message of the commit Publish makes first, in a project connected
|
|
30
|
+
* to git (the proposal's branch, before it merges): from the project's
|
|
31
|
+
* `studio.commitMessage` setting. Absent: content's default.
|
|
32
|
+
*/
|
|
33
|
+
commitMessage?: string): Promise<PressResponse>;
|
|
28
34
|
/** Try again: resume a paused queue and press anew. */
|
|
29
35
|
tryAgain(requestId: string, tab: string): Promise<PressResponse>;
|
|
30
36
|
/** Where a press is. */
|
|
@@ -22,8 +22,9 @@
|
|
|
22
22
|
* own authorisation and a cookie sent to a storage host is a cookie leaked to
|
|
23
23
|
* one.
|
|
24
24
|
*/
|
|
25
|
-
import { ArtifactsResponse, BuildTargetResponse, DeclareBody, DeclareResponse, PromoteResponse, StatusResponse, UploadSlot, VerifyResponse } from "../internal/index.js";
|
|
25
|
+
import { ArtifactsResponse, BuildTargetResponse, DeclareBody, DeclareResponse, PromoteResponse, StatusResponse, UploadSlot, VerifyResponse, publishApiOf, type PublishApiAt } from "../internal/index.js";
|
|
26
26
|
export { StudioPublishError, callJson, isTransientPublishError, } from "./callJson.js";
|
|
27
|
+
export { publishApiOf, type PublishApiAt };
|
|
27
28
|
/** An artifact the live build has and this publish re-declares by hash. */
|
|
28
29
|
export type CarriedArtifact = {
|
|
29
30
|
key: string;
|
|
@@ -77,19 +78,6 @@ export type StudioPublishClient = {
|
|
|
77
78
|
* short of the finish.
|
|
78
79
|
*/
|
|
79
80
|
export declare function isExpiredSlot(error: unknown): boolean;
|
|
80
|
-
/**
|
|
81
|
-
* Where content's publish API is reached: through Val's proxy on this origin
|
|
82
|
-
* (`api`, the Studio), or directly (`publishApi`, `<content>/v1`: home's
|
|
83
|
-
* upgrade page, whose `fetchImpl` adds the project token).
|
|
84
|
-
*/
|
|
85
|
-
export type PublishApiAt = {
|
|
86
|
-
/** Val's API root on this origin, e.g. `/api/val`. */
|
|
87
|
-
api: string;
|
|
88
|
-
} | {
|
|
89
|
-
/** Content's publish API itself, e.g. `https://content.val.build/v1`. */
|
|
90
|
-
publishApi: string;
|
|
91
|
-
};
|
|
92
|
-
export declare function publishApiOf(at: PublishApiAt): string;
|
|
93
81
|
export declare function createStudioPublishClient(options: PublishApiAt & {
|
|
94
82
|
fetchImpl?: typeof fetch;
|
|
95
83
|
}): StudioPublishClient;
|
|
@@ -339,7 +339,23 @@ function isValCanvasPageMessage(data) {
|
|
|
339
339
|
if (_typeof(data) !== "object" || data === null) return false;
|
|
340
340
|
var message = data;
|
|
341
341
|
if (message.val !== VAL_CANVAS_MESSAGE) return false;
|
|
342
|
-
return message.type === "ready" || message.type === "elements" || message.type === "clicked" || message.type === "pinch" || message.type === "zoom" || message.type === "refreshing" || message.type === "elementPickingStopped" || message.type === "elementPicked" && isPickedElement(data.element) || message.type === "location" && isPageLocation(data) || message.type === "pageRead" && typeof data.requestId === "string" || message.type === "pageScreenshot" && typeof data.requestId === "string" || message.type === "quickPreviewStored" && typeof data.id === "string";
|
|
342
|
+
return message.type === "ready" && isModulePathList(data.holds) && isHeldVersions(data.holdsVersions) || message.type === "elements" || message.type === "clicked" || message.type === "pinch" || message.type === "zoom" || message.type === "refreshing" || message.type === "elementPickingStopped" || message.type === "elementPicked" && isPickedElement(data.element) || message.type === "location" && isPageLocation(data) || message.type === "pageRead" && typeof data.requestId === "string" || message.type === "pageScreenshot" && typeof data.requestId === "string" || message.type === "quickPreviewStored" && typeof data.id === "string";
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/** `holdsVersions` on `ready`: absent, or a version per module path. */
|
|
346
|
+
function isHeldVersions(value) {
|
|
347
|
+
if (value === undefined) return true;
|
|
348
|
+
if (_typeof(value) !== "object" || value === null) return false;
|
|
349
|
+
return Object.values(value).every(function (version) {
|
|
350
|
+
return _typeof(version) === "object" && version !== null && typeof version.schema === "string" && typeof version.base === "string" && typeof version.chain === "string";
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/** `holds` on `ready`: absent, or a list of module paths. */
|
|
355
|
+
function isModulePathList(value) {
|
|
356
|
+
return value === undefined || Array.isArray(value) && value.every(function (path) {
|
|
357
|
+
return typeof path === "string";
|
|
358
|
+
});
|
|
343
359
|
}
|
|
344
360
|
function isPageLocation(value) {
|
|
345
361
|
var location = value;
|
|
@@ -404,7 +420,7 @@ function isValCanvasStudioMessage(data) {
|
|
|
404
420
|
var read = data;
|
|
405
421
|
return typeof read.requestId === "string" && (read.selector === undefined || typeof read.selector === "string") && (read.maxItems === undefined || typeof read.maxItems === "number");
|
|
406
422
|
}
|
|
407
|
-
return message.type === "rescan" || message.type === "highlight" || message.type === "setPicking" || message.type === "sourceUpdate" || message.type === "sourcesSynced";
|
|
423
|
+
return message.type === "rescan" || message.type === "highlight" || message.type === "setPicking" || message.type === "sourceUpdate" || message.type === "sourcesSynced" || message.type === "confirmed" && (data.seq === null || typeof data.seq === "number");
|
|
408
424
|
}
|
|
409
425
|
|
|
410
426
|
/**
|
|
@@ -359,7 +359,23 @@ function isValCanvasPageMessage(data) {
|
|
|
359
359
|
if (createForOfIteratorHelper._typeof(data) !== "object" || data === null) return false;
|
|
360
360
|
var message = data;
|
|
361
361
|
if (message.val !== VAL_CANVAS_MESSAGE) return false;
|
|
362
|
-
return message.type === "ready" || message.type === "elements" || message.type === "clicked" || message.type === "pinch" || message.type === "zoom" || message.type === "refreshing" || message.type === "elementPickingStopped" || message.type === "elementPicked" && isPickedElement(data.element) || message.type === "location" && isPageLocation(data) || message.type === "pageRead" && typeof data.requestId === "string" || message.type === "pageScreenshot" && typeof data.requestId === "string" || message.type === "quickPreviewStored" && typeof data.id === "string";
|
|
362
|
+
return message.type === "ready" && isModulePathList(data.holds) && isHeldVersions(data.holdsVersions) || message.type === "elements" || message.type === "clicked" || message.type === "pinch" || message.type === "zoom" || message.type === "refreshing" || message.type === "elementPickingStopped" || message.type === "elementPicked" && isPickedElement(data.element) || message.type === "location" && isPageLocation(data) || message.type === "pageRead" && typeof data.requestId === "string" || message.type === "pageScreenshot" && typeof data.requestId === "string" || message.type === "quickPreviewStored" && typeof data.id === "string";
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/** `holdsVersions` on `ready`: absent, or a version per module path. */
|
|
366
|
+
function isHeldVersions(value) {
|
|
367
|
+
if (value === undefined) return true;
|
|
368
|
+
if (createForOfIteratorHelper._typeof(value) !== "object" || value === null) return false;
|
|
369
|
+
return Object.values(value).every(function (version) {
|
|
370
|
+
return createForOfIteratorHelper._typeof(version) === "object" && version !== null && typeof version.schema === "string" && typeof version.base === "string" && typeof version.chain === "string";
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/** `holds` on `ready`: absent, or a list of module paths. */
|
|
375
|
+
function isModulePathList(value) {
|
|
376
|
+
return value === undefined || Array.isArray(value) && value.every(function (path) {
|
|
377
|
+
return typeof path === "string";
|
|
378
|
+
});
|
|
363
379
|
}
|
|
364
380
|
function isPageLocation(value) {
|
|
365
381
|
var location = value;
|
|
@@ -424,7 +440,7 @@ function isValCanvasStudioMessage(data) {
|
|
|
424
440
|
var read = data;
|
|
425
441
|
return typeof read.requestId === "string" && (read.selector === undefined || typeof read.selector === "string") && (read.maxItems === undefined || typeof read.maxItems === "number");
|
|
426
442
|
}
|
|
427
|
-
return message.type === "rescan" || message.type === "highlight" || message.type === "setPicking" || message.type === "sourceUpdate" || message.type === "sourcesSynced";
|
|
443
|
+
return message.type === "rescan" || message.type === "highlight" || message.type === "setPicking" || message.type === "sourceUpdate" || message.type === "sourcesSynced" || message.type === "confirmed" && (data.seq === null || typeof data.seq === "number");
|
|
428
444
|
}
|
|
429
445
|
|
|
430
446
|
/**
|
|
@@ -359,7 +359,23 @@ function isValCanvasPageMessage(data) {
|
|
|
359
359
|
if (createForOfIteratorHelper._typeof(data) !== "object" || data === null) return false;
|
|
360
360
|
var message = data;
|
|
361
361
|
if (message.val !== VAL_CANVAS_MESSAGE) return false;
|
|
362
|
-
return message.type === "ready" || message.type === "elements" || message.type === "clicked" || message.type === "pinch" || message.type === "zoom" || message.type === "refreshing" || message.type === "elementPickingStopped" || message.type === "elementPicked" && isPickedElement(data.element) || message.type === "location" && isPageLocation(data) || message.type === "pageRead" && typeof data.requestId === "string" || message.type === "pageScreenshot" && typeof data.requestId === "string" || message.type === "quickPreviewStored" && typeof data.id === "string";
|
|
362
|
+
return message.type === "ready" && isModulePathList(data.holds) && isHeldVersions(data.holdsVersions) || message.type === "elements" || message.type === "clicked" || message.type === "pinch" || message.type === "zoom" || message.type === "refreshing" || message.type === "elementPickingStopped" || message.type === "elementPicked" && isPickedElement(data.element) || message.type === "location" && isPageLocation(data) || message.type === "pageRead" && typeof data.requestId === "string" || message.type === "pageScreenshot" && typeof data.requestId === "string" || message.type === "quickPreviewStored" && typeof data.id === "string";
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/** `holdsVersions` on `ready`: absent, or a version per module path. */
|
|
366
|
+
function isHeldVersions(value) {
|
|
367
|
+
if (value === undefined) return true;
|
|
368
|
+
if (createForOfIteratorHelper._typeof(value) !== "object" || value === null) return false;
|
|
369
|
+
return Object.values(value).every(function (version) {
|
|
370
|
+
return createForOfIteratorHelper._typeof(version) === "object" && version !== null && typeof version.schema === "string" && typeof version.base === "string" && typeof version.chain === "string";
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/** `holds` on `ready`: absent, or a list of module paths. */
|
|
375
|
+
function isModulePathList(value) {
|
|
376
|
+
return value === undefined || Array.isArray(value) && value.every(function (path) {
|
|
377
|
+
return typeof path === "string";
|
|
378
|
+
});
|
|
363
379
|
}
|
|
364
380
|
function isPageLocation(value) {
|
|
365
381
|
var location = value;
|
|
@@ -424,7 +440,7 @@ function isValCanvasStudioMessage(data) {
|
|
|
424
440
|
var read = data;
|
|
425
441
|
return typeof read.requestId === "string" && (read.selector === undefined || typeof read.selector === "string") && (read.maxItems === undefined || typeof read.maxItems === "number");
|
|
426
442
|
}
|
|
427
|
-
return message.type === "rescan" || message.type === "highlight" || message.type === "setPicking" || message.type === "sourceUpdate" || message.type === "sourcesSynced";
|
|
443
|
+
return message.type === "rescan" || message.type === "highlight" || message.type === "setPicking" || message.type === "sourceUpdate" || message.type === "sourcesSynced" || message.type === "confirmed" && (data.seq === null || typeof data.seq === "number");
|
|
428
444
|
}
|
|
429
445
|
|
|
430
446
|
/**
|
|
@@ -1,9 +1,176 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var createForOfIteratorHelper = require('./createForOfIteratorHelper-f2d7ac6d.cjs.dev.js');
|
|
3
4
|
var wrapNativeSuper = require('./wrapNativeSuper-933f991e.cjs.dev.js');
|
|
4
5
|
var zod = require('zod');
|
|
5
6
|
var zodValidationError = require('zod-validation-error');
|
|
6
7
|
|
|
8
|
+
/*
|
|
9
|
+
* The one JSON call the Studio makes through its own origin's publish proxy,
|
|
10
|
+
* and the errors it throws. Apart from `publishClient.ts` (which re-exports
|
|
11
|
+
* all three) so that a worker can make the same call without importing the
|
|
12
|
+
* publish client's parsers, and `@valbuild/shared` with them.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Who hears of a refusal's body before it is thrown: the Studio's shell, which
|
|
17
|
+
* says a refusal of the project's plan with the next step (`planRefusal.ts` in
|
|
18
|
+
* `@valbuild/ui`). One listener; setting it again replaces it.
|
|
19
|
+
*/
|
|
20
|
+
var refusalListener = null;
|
|
21
|
+
function onPublishRefusal(listener) {
|
|
22
|
+
refusalListener = listener;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** The publish API refused, and said why. */
|
|
26
|
+
var StudioPublishError = /*#__PURE__*/function (_Error) {
|
|
27
|
+
function StudioPublishError(statusCode, message, body) {
|
|
28
|
+
var _this;
|
|
29
|
+
wrapNativeSuper._classCallCheck(this, StudioPublishError);
|
|
30
|
+
_this = wrapNativeSuper._callSuper(this, StudioPublishError, [message]);
|
|
31
|
+
createForOfIteratorHelper._defineProperty(_this, "statusCode", void 0);
|
|
32
|
+
createForOfIteratorHelper._defineProperty(_this, "body", void 0);
|
|
33
|
+
_this.name = "StudioPublishError";
|
|
34
|
+
_this.statusCode = statusCode;
|
|
35
|
+
_this.body = body;
|
|
36
|
+
return _this;
|
|
37
|
+
}
|
|
38
|
+
wrapNativeSuper._inherits(StudioPublishError, _Error);
|
|
39
|
+
return wrapNativeSuper._createClass(StudioPublishError);
|
|
40
|
+
}(/*#__PURE__*/wrapNativeSuper._wrapNativeSuper(Error));
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Was this a failure that asking again could get past?
|
|
44
|
+
*
|
|
45
|
+
* No answer at all (the request never got through) and the answers that mean
|
|
46
|
+
* "not now" -- a timeout, too many requests, a server or gateway error. Every
|
|
47
|
+
* other status is content answering, and the same request gets the same
|
|
48
|
+
* answer.
|
|
49
|
+
*/
|
|
50
|
+
function isTransientPublishError(error) {
|
|
51
|
+
if (!(error instanceof StudioPublishError)) return true;
|
|
52
|
+
return error.statusCode >= 500 || error.statusCode === 408 || error.statusCode === 429;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* One JSON call through this origin, with the session cookie: its body, or a
|
|
57
|
+
* `StudioPublishError` carrying the answer's own message.
|
|
58
|
+
*/
|
|
59
|
+
function callJson(_x, _x2, _x3, _x4) {
|
|
60
|
+
return _callJson.apply(this, arguments);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* One JSON READ through this origin, BY VERSION: `held` is the answer the
|
|
65
|
+
* caller holds, with its `ETag`, which goes as `If-None-Match`. While the
|
|
66
|
+
* answer is still that one (a 304, with no body) it is `held` again;
|
|
67
|
+
* otherwise the new body, `parse`d, with its `ETag` -- `null` when the answer
|
|
68
|
+
* named none, so there is nothing to hold it by. Errors as {@link callJson}
|
|
69
|
+
* throws them.
|
|
70
|
+
*/
|
|
71
|
+
function _callJson() {
|
|
72
|
+
_callJson = createForOfIteratorHelper._asyncToGenerator(/*#__PURE__*/createForOfIteratorHelper._regenerator().m(function _callee(fetchImpl, url, method, body) {
|
|
73
|
+
var res;
|
|
74
|
+
return createForOfIteratorHelper._regenerator().w(function (_context) {
|
|
75
|
+
while (1) switch (_context.n) {
|
|
76
|
+
case 0:
|
|
77
|
+
_context.n = 1;
|
|
78
|
+
return fetchImpl(url, createForOfIteratorHelper._objectSpread2({
|
|
79
|
+
method: method,
|
|
80
|
+
// The session cookie is the whole credential this end has.
|
|
81
|
+
credentials: "same-origin"
|
|
82
|
+
}, body === undefined ? {} : {
|
|
83
|
+
headers: {
|
|
84
|
+
"Content-Type": "application/json"
|
|
85
|
+
},
|
|
86
|
+
body: JSON.stringify(body)
|
|
87
|
+
}));
|
|
88
|
+
case 1:
|
|
89
|
+
res = _context.v;
|
|
90
|
+
return _context.a(2, answerOf(res));
|
|
91
|
+
}
|
|
92
|
+
}, _callee);
|
|
93
|
+
}));
|
|
94
|
+
return _callJson.apply(this, arguments);
|
|
95
|
+
}
|
|
96
|
+
function readJsonByVersion(_x5, _x6, _x7, _x8) {
|
|
97
|
+
return _readJsonByVersion.apply(this, arguments);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** An answer's JSON body, or a `StudioPublishError` with its own message. */
|
|
101
|
+
function _readJsonByVersion() {
|
|
102
|
+
_readJsonByVersion = createForOfIteratorHelper._asyncToGenerator(/*#__PURE__*/createForOfIteratorHelper._regenerator().m(function _callee2(fetchImpl, url, held, parse) {
|
|
103
|
+
var res, value, _t;
|
|
104
|
+
return createForOfIteratorHelper._regenerator().w(function (_context2) {
|
|
105
|
+
while (1) switch (_context2.n) {
|
|
106
|
+
case 0:
|
|
107
|
+
_context2.n = 1;
|
|
108
|
+
return fetchImpl(url, createForOfIteratorHelper._objectSpread2({
|
|
109
|
+
method: "GET",
|
|
110
|
+
// The session cookie is the whole credential this end has.
|
|
111
|
+
credentials: "same-origin"
|
|
112
|
+
}, held !== null ? {
|
|
113
|
+
headers: {
|
|
114
|
+
"If-None-Match": held.etag
|
|
115
|
+
}
|
|
116
|
+
} : {}));
|
|
117
|
+
case 1:
|
|
118
|
+
res = _context2.v;
|
|
119
|
+
if (!(res.status === 304 && held !== null)) {
|
|
120
|
+
_context2.n = 2;
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
return _context2.a(2, held);
|
|
124
|
+
case 2:
|
|
125
|
+
_t = parse;
|
|
126
|
+
_context2.n = 3;
|
|
127
|
+
return answerOf(res);
|
|
128
|
+
case 3:
|
|
129
|
+
value = _t(_context2.v);
|
|
130
|
+
return _context2.a(2, {
|
|
131
|
+
etag: res.headers.get("etag"),
|
|
132
|
+
value: value
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}, _callee2);
|
|
136
|
+
}));
|
|
137
|
+
return _readJsonByVersion.apply(this, arguments);
|
|
138
|
+
}
|
|
139
|
+
function answerOf(_x9) {
|
|
140
|
+
return _answerOf.apply(this, arguments);
|
|
141
|
+
}
|
|
142
|
+
function _answerOf() {
|
|
143
|
+
_answerOf = createForOfIteratorHelper._asyncToGenerator(/*#__PURE__*/createForOfIteratorHelper._regenerator().m(function _callee3(res) {
|
|
144
|
+
var text, parsed, _refusalListener, message;
|
|
145
|
+
return createForOfIteratorHelper._regenerator().w(function (_context3) {
|
|
146
|
+
while (1) switch (_context3.n) {
|
|
147
|
+
case 0:
|
|
148
|
+
_context3.n = 1;
|
|
149
|
+
return res.text();
|
|
150
|
+
case 1:
|
|
151
|
+
text = _context3.v;
|
|
152
|
+
try {
|
|
153
|
+
parsed = text === "" ? undefined : JSON.parse(text);
|
|
154
|
+
} catch (_unused) {
|
|
155
|
+
parsed = undefined;
|
|
156
|
+
}
|
|
157
|
+
if (res.ok) {
|
|
158
|
+
_context3.n = 2;
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
// A publish the plan does not allow (a trial's 3 publishes, a trial that
|
|
162
|
+
// ended): the shell says it, with the next step. See `planRefusal`.
|
|
163
|
+
(_refusalListener = refusalListener) === null || _refusalListener === void 0 || _refusalListener(parsed);
|
|
164
|
+
message = createForOfIteratorHelper._typeof(parsed) === "object" && parsed !== null && "message" in parsed && typeof parsed.message === "string" ? parsed.message : "The publish API answered ".concat(res.status, ".");
|
|
165
|
+
throw new StudioPublishError(res.status, message, parsed);
|
|
166
|
+
case 2:
|
|
167
|
+
return _context3.a(2, parsed);
|
|
168
|
+
}
|
|
169
|
+
}, _callee3);
|
|
170
|
+
}));
|
|
171
|
+
return _answerOf.apply(this, arguments);
|
|
172
|
+
}
|
|
173
|
+
|
|
7
174
|
function _objectWithoutPropertiesLoose(r, e) {
|
|
8
175
|
if (null == r) return {};
|
|
9
176
|
var t = {};
|
|
@@ -412,8 +579,61 @@ function parse(schema, body, call) {
|
|
|
412
579
|
return parsed.data;
|
|
413
580
|
}
|
|
414
581
|
|
|
582
|
+
/**
|
|
583
|
+
* Where content's publish API is reached: through Val's proxy on this origin
|
|
584
|
+
* (`api`, the Studio), or directly (`publishApi`, `<content>/v1`: home's
|
|
585
|
+
* upgrade page, whose `fetchImpl` adds the project token).
|
|
586
|
+
*/
|
|
587
|
+
|
|
588
|
+
function publishApiOf(at) {
|
|
589
|
+
return "publishApi" in at ? at.publishApi.replace(/\/+$/, "") : "".concat(at.api.replace(/\/+$/, ""), "/publish-api");
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
/**
|
|
593
|
+
* The site's live source, BY VERSION: for a reader that asks again and again
|
|
594
|
+
* over a long life -- the Studio's code tools, on every tool call -- rather
|
|
595
|
+
* than once per deploy, as {@link createStudioPublishClient}'s memo does.
|
|
596
|
+
*
|
|
597
|
+
* Each call asks `/project-source` with the `ETag` of the answer it holds
|
|
598
|
+
* (`If-None-Match`), and content answers 304 while it is still that one
|
|
599
|
+
* (valbuild/home sends the tag: the sha256 of its answer). So a publish in
|
|
600
|
+
* between is seen on the next call, and the whole source is sent only when
|
|
601
|
+
* it changed. An answer without a tag (an older content service) is not
|
|
602
|
+
* held: every call reads it again, which is right, if dearer.
|
|
603
|
+
*/
|
|
604
|
+
function createProjectSourceReader(options) {
|
|
605
|
+
var _options$fetchImpl;
|
|
606
|
+
var fetchImpl = (_options$fetchImpl = options.fetchImpl) !== null && _options$fetchImpl !== void 0 ? _options$fetchImpl : fetch;
|
|
607
|
+
var url = "".concat(publishApiOf(options), "/project-source");
|
|
608
|
+
var held = null;
|
|
609
|
+
return /*#__PURE__*/createForOfIteratorHelper._asyncToGenerator(/*#__PURE__*/createForOfIteratorHelper._regenerator().m(function _callee() {
|
|
610
|
+
var answer;
|
|
611
|
+
return createForOfIteratorHelper._regenerator().w(function (_context) {
|
|
612
|
+
while (1) switch (_context.n) {
|
|
613
|
+
case 0:
|
|
614
|
+
_context.n = 1;
|
|
615
|
+
return readJsonByVersion(fetchImpl, url, held, function (body) {
|
|
616
|
+
return parseProjectSource(body).files;
|
|
617
|
+
});
|
|
618
|
+
case 1:
|
|
619
|
+
answer = _context.v;
|
|
620
|
+
held = answer.etag !== null ? {
|
|
621
|
+
etag: answer.etag,
|
|
622
|
+
value: answer.value
|
|
623
|
+
} : null;
|
|
624
|
+
return _context.a(2, answer.value);
|
|
625
|
+
}
|
|
626
|
+
}, _callee);
|
|
627
|
+
}));
|
|
628
|
+
}
|
|
629
|
+
|
|
415
630
|
exports.PublishProtocolError = PublishProtocolError;
|
|
631
|
+
exports.StudioPublishError = StudioPublishError;
|
|
416
632
|
exports._objectWithoutProperties = _objectWithoutProperties;
|
|
633
|
+
exports.callJson = callJson;
|
|
634
|
+
exports.createProjectSourceReader = createProjectSourceReader;
|
|
635
|
+
exports.isTransientPublishError = isTransientPublishError;
|
|
636
|
+
exports.onPublishRefusal = onPublishRefusal;
|
|
417
637
|
exports.parseArtifacts = parseArtifacts;
|
|
418
638
|
exports.parseBuildTarget = parseBuildTarget;
|
|
419
639
|
exports.parseCancel = parseCancel;
|
|
@@ -431,3 +651,4 @@ exports.parseRequestStatus = parseRequestStatus;
|
|
|
431
651
|
exports.parseStatus = parseStatus;
|
|
432
652
|
exports.parseUpdateTarget = parseUpdateTarget;
|
|
433
653
|
exports.parseVerify = parseVerify;
|
|
654
|
+
exports.publishApiOf = publishApiOf;
|