@journeeze/sdk 0.0.0-stage → 0.1.0-rc.2
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/AGENTS.md +67 -0
- package/CHANGELOG.md +30 -0
- package/LICENSE.md +27 -0
- package/README.md +164 -2
- package/dist/THIRD_PARTY_LICENSES.txt +246 -0
- package/dist/consent-CoKD33Rm.js +170 -0
- package/dist/context-UnG6_X61.js +17 -0
- package/dist/contract.js +10 -0
- package/dist/feedback-C4CYtS2A.js +196 -0
- package/dist/help-C1x-y2f9.js +878 -0
- package/dist/hook-BdG4UL4k.js +91 -0
- package/dist/index-B_nob8S0.js +2091 -0
- package/dist/index-CfCbJJXa.js +20 -0
- package/dist/index.js +10 -0
- package/dist/loader-Ba4X-WNl.js +95 -0
- package/dist/react.js +70 -0
- package/dist/resolve-BfWByuTp.js +97 -0
- package/dist/script.js +13 -0
- package/dist/signals-E3VEdmWH.js +477 -0
- package/dist/telemetry-Cik-cYzw.js +140 -0
- package/dist/transport-B5YJFQEF.js +60 -0
- package/dist/types/config.d.ts +17 -0
- package/dist/types/context.d.ts +6 -0
- package/dist/types/contract.d.ts +13 -0
- package/dist/types/help/core/client.d.ts +26 -0
- package/dist/types/help/core/controller.d.ts +175 -0
- package/dist/types/help/core/events.d.ts +8 -0
- package/dist/types/help/core/help.d.ts +24 -0
- package/dist/types/help/core/highlight.d.ts +38 -0
- package/dist/types/help/core/panel.d.ts +11 -0
- package/dist/types/help/core/search.d.ts +7 -0
- package/dist/types/help/ui/callout.d.ts +2 -0
- package/dist/types/help/ui/panel.d.ts +3 -0
- package/dist/types/help/ui/request.d.ts +2 -0
- package/dist/types/help/ui/styles.d.ts +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/invite.d.ts +4 -0
- package/dist/types/loader.d.ts +57 -0
- package/dist/types/mask.d.ts +10 -0
- package/dist/types/react.d.ts +9 -0
- package/dist/types/resolve/resolve.d.ts +12 -0
- package/dist/types/script.d.ts +6 -0
- package/dist/types/signals/cel.d.ts +8 -0
- package/dist/types/signals/hook.d.ts +10 -0
- package/dist/types/signals/signals.conformance.d.ts +2 -0
- package/dist/types/signals/signals.d.ts +145 -0
- package/dist/types/telemetry/telemetry.d.ts +63 -0
- package/dist/types/transport.d.ts +30 -0
- package/dist/types/types.d.ts +391 -0
- package/dist/types/widget/anchor.d.ts +11 -0
- package/dist/types/widget/capture.d.ts +28 -0
- package/dist/types/widget/consent.d.ts +25 -0
- package/dist/types/widget/feedback.d.ts +36 -0
- package/dist/types/widget/icons.d.ts +14 -0
- package/dist/types/widget/outbox.d.ts +69 -0
- package/dist/types/widget/styles.d.ts +1 -0
- package/dist/types/widget.d.ts +27 -0
- package/dist/types/wire.d.ts +66 -0
- package/dist/widget-DQZm8sAC.js +1599 -0
- package/package.json +68 -4
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { CollectorError } from "../wire";
|
|
2
|
+
import type { SubmitFeedbackRequest } from "../types";
|
|
3
|
+
/** Stored feedback older than this is stale and is dropped when claimed (§9). */
|
|
4
|
+
export declare const OUTBOX_TTL_MS: number;
|
|
5
|
+
export type Outcome = "sent" | "queued" | "dropped";
|
|
6
|
+
export interface OutboxDeps {
|
|
7
|
+
send(request: SubmitFeedbackRequest): Promise<void>;
|
|
8
|
+
storage: Storage | undefined;
|
|
9
|
+
storageKey: string;
|
|
10
|
+
/** Which reviewer queued the items ({@link ownerTag}); only matching items are claimed. */
|
|
11
|
+
owner: string;
|
|
12
|
+
/** Scheduling seam for tests. */
|
|
13
|
+
schedule?: (fn: () => void, ms: number) => unknown;
|
|
14
|
+
cancel?: (handle: unknown) => void;
|
|
15
|
+
/** Called when an item is dropped as permanently refused. */
|
|
16
|
+
onDropped?: (error: CollectorError) => void;
|
|
17
|
+
/** The signed-in user (opaque id) an item is stored under, kept with it for attribution (J6). */
|
|
18
|
+
user?: () => string | undefined;
|
|
19
|
+
/** Clock seam for tests; defaults to `Date.now`. */
|
|
20
|
+
now?: () => number;
|
|
21
|
+
}
|
|
22
|
+
export declare function backoffMs(attempt: number): number;
|
|
23
|
+
export declare function isPermanent(error: unknown): error is CollectorError;
|
|
24
|
+
export declare class Outbox {
|
|
25
|
+
private readonly deps;
|
|
26
|
+
private items;
|
|
27
|
+
private inFlight;
|
|
28
|
+
private attempt;
|
|
29
|
+
private flushing;
|
|
30
|
+
private timer;
|
|
31
|
+
private disposed;
|
|
32
|
+
private readonly schedule;
|
|
33
|
+
private readonly cancel;
|
|
34
|
+
private readonly now;
|
|
35
|
+
constructor(deps: OutboxDeps);
|
|
36
|
+
get size(): number;
|
|
37
|
+
/** Queues and flushes; resolves once this item was sent, dropped, or left queued for retry. */
|
|
38
|
+
enqueue(request: SubmitFeedbackRequest): Promise<Outcome>;
|
|
39
|
+
/** Queues without sending (used while the page is being hidden). */
|
|
40
|
+
stash(request: SubmitFeedbackRequest): void;
|
|
41
|
+
/** Sends queued items in order. One flush at a time; a pending retry timer is replaced. */
|
|
42
|
+
flush(): Promise<void>;
|
|
43
|
+
/** Hands unsent items to storage (appending to what is there) and forgets them here. */
|
|
44
|
+
persist(): void;
|
|
45
|
+
/** Takes over this reviewer's items stored by earlier pages (this or another tab). Items of
|
|
46
|
+
* another reviewer stay stored: they are never sent under the wrong reviewer's token. */
|
|
47
|
+
claim(): void;
|
|
48
|
+
/** Stops sending and stores what is unsent so a later widget can deliver it. */
|
|
49
|
+
dispose(): void;
|
|
50
|
+
private add;
|
|
51
|
+
private drain;
|
|
52
|
+
/**
|
|
53
|
+
* Stored items older than {@link OUTBOX_TTL_MS} are dropped (contract §9). An item without a
|
|
54
|
+
* time was queued by a v0 SDK before the upgrade: it is sent once rather than lost.
|
|
55
|
+
*/
|
|
56
|
+
private fresh;
|
|
57
|
+
private remove;
|
|
58
|
+
private read;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Non-reversible tag of the reviewer token (FNV-1a, 32 bits) so stored items are claimed only
|
|
62
|
+
* by the same reviewer. 32 bits of a 256-bit token reveal nothing usable; "" means anonymous.
|
|
63
|
+
*/
|
|
64
|
+
export declare function ownerTag(token: string | undefined): string;
|
|
65
|
+
/**
|
|
66
|
+
* Logout (contract §8, v1.1): removes this owner's stored items from storage now, whatever happens
|
|
67
|
+
* next, and returns their requests (those still within {@link OUTBOX_TTL_MS}) to be sent once.
|
|
68
|
+
*/
|
|
69
|
+
export declare function takeOwned(storage: Storage | undefined, storageKey: string, owner: string, now?: number): SubmitFeedbackRequest[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const CSS = "\n:host { all: initial; }\n.jz {\n --jz-canvas:#F7F7F5; --jz-surface:#FFFFFF; --jz-raised:#F0F0EC; --jz-ink:#1D2024; --jz-muted:#5D636B;\n --jz-faint:#8A9099; --jz-rule:rgb(29 32 36 / 12%); --jz-accent:#3D63C9; --jz-accent-ink:#FFFFFF;\n --jz-accent-soft:rgb(61 99 201 / 10%); --jz-polished:#2F7D4F; --jz-broken:#B42318; --jz-confused:#6E4FC2;\n --jz-shadow:0 1px 3px rgb(0 0 0 / 12%);\n font: 400 13px/1.45 Inter, ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", sans-serif;\n color: var(--jz-ink); -webkit-font-smoothing: antialiased;\n}\n@media (prefers-color-scheme: dark) {\n .jz { --jz-canvas:#111316; --jz-surface:#181B1F; --jz-raised:#20242A; --jz-ink:#E8EAED; --jz-muted:#A3A9B2;\n --jz-faint:#6F7680; --jz-rule:rgb(232 234 237 / 12%); --jz-accent:#7F9CF0; --jz-accent-ink:#111316;\n --jz-accent-soft:rgb(127 156 240 / 14%); --jz-confused:#A48BEA; --jz-polished:#5DBB84; }\n}\n.jz *, .jz *::before, .jz *::after { box-sizing: border-box; }\n/* Zero specificity: a component's own colour (.toggle, .primary, ...) must always win. */\n:where(.jz button) { font: inherit; color: inherit; cursor: pointer; }\n.jz :focus-visible { outline: 2px solid var(--jz-accent); outline-offset: 2px; }\n.mono { font-family: \"JetBrains Mono\", ui-monospace, SFMono-Regular, Menlo, monospace; }\n.sr { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; }\n\n.toggle { position:fixed; right:32px; bottom:32px; z-index:2147483646; height:44px; padding:0 16px; display:flex; align-items:center;\n gap:8px; border:0; border-radius:999px; background:#1D2024; color:#FFFFFF; box-shadow:var(--jz-shadow); font-weight:500; }\n.toggle .dot { width:8px; height:8px; border-radius:50%; background:var(--jz-polished); }\n.toggle .exit { color:#8A9099; }\n.toggle:hover .exit { color:#FFFFFF; }\n\n.layer { position:fixed; inset:0; z-index:2147483640; pointer-events:none; }\n.hl { position:fixed; display:none; outline:1px solid var(--jz-accent); outline-offset:-1px; border-radius:2px; }\n.hl.masked { outline:1px dashed var(--jz-faint);\n background:repeating-linear-gradient(45deg, rgb(138 144 153 / 10%) 0 4px, rgb(138 144 153 / 20%) 4px 8px); }\n.tag { position:absolute; left:0; top:-18px; padding:1px 6px; border-radius:2px; background:var(--jz-accent); color:#FFFFFF;\n font-size:10px; line-height:16px; white-space:nowrap; max-width:280px; overflow:hidden; text-overflow:ellipsis; }\n.hl.masked .tag { background:var(--jz-muted); text-transform:uppercase; letter-spacing:.06em; }\n.pin { position:fixed; width:24px; height:24px; margin:-12px 0 0 -12px; border-radius:50%; display:flex; align-items:center;\n justify-content:center; background:var(--jz-accent); color:#FFFFFF; font-size:12px; font-weight:500; box-shadow:var(--jz-shadow); }\n\n.pop, .sheet, .checkin, .toast { position:fixed; z-index:2147483645; background:var(--jz-surface); color:var(--jz-ink);\n border:1px solid var(--jz-rule); box-shadow:var(--jz-shadow); }\n.pop { width:400px; max-width:calc(100vw - 32px); max-height:calc(100vh - 32px); overflow:auto; padding:24px; border-radius:10px;\n animation: jz-in 180ms ease-out; }\n@keyframes jz-in { from { opacity:0; transform:translateY(4px); } to { opacity:1; transform:none; } }\n.pop-head { display:flex; align-items:center; justify-content:space-between; gap:8px; margin-bottom:20px; }\n.pop h2 { margin:0; font-size:14px; font-weight:500; }\n.close { width:32px; height:32px; display:flex; align-items:center; justify-content:center; border:0; border-radius:6px;\n background:transparent; color:var(--jz-faint); }\n.close:hover { color:var(--jz-ink); }\n.chips { display:flex; flex-wrap:wrap; gap:8px; margin-bottom:20px; }\n.chip { display:inline-flex; align-items:center; gap:4px; padding:2px 8px; border-radius:999px; background:var(--jz-raised);\n color:var(--jz-muted); font-size:11px; }\n.reactions { display:flex; border:1px solid var(--jz-rule); border-radius:8px; overflow:hidden; margin-bottom:20px; }\n.reaction { flex:1; min-height:56px; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:4px;\n padding:12px 4px; border:0; border-right:1px solid var(--jz-rule); background:transparent; color:var(--jz-muted); }\n.reaction:last-child { border-right:0; }\n.reaction:hover { background:var(--jz-canvas); }\n.reaction span { font-size:10px; font-weight:500; }\n.reaction[data-r=\"confused\"] { color:var(--jz-confused); }\n.reaction[aria-checked=\"true\"] { background:var(--jz-accent-soft); color:var(--jz-accent); }\n.reaction[data-r=\"confused\"][aria-checked=\"true\"] { background:rgb(110 79 194 / 10%); color:var(--jz-confused); }\n.comment { display:block; width:100%; height:112px; padding:16px; margin-bottom:20px; resize:none; border:1px solid var(--jz-rule);\n border-radius:8px; background:var(--jz-surface); color:var(--jz-ink); font:inherit; }\n.comment::placeholder { color:var(--jz-faint); }\n.comment:focus { outline:none; box-shadow:0 0 0 1px var(--jz-accent); }\n.foot { display:flex; align-items:center; justify-content:space-between; gap:12px; }\n.shot { display:flex; align-items:center; gap:12px; min-width:0; }\n.thumb { flex:none; width:80px; height:48px; border-radius:8px; border:1px solid var(--jz-rule); background:var(--jz-canvas);\n overflow:hidden; display:flex; align-items:center; justify-content:center; color:var(--jz-faint); font-size:8px; }\n.thumb img { width:100%; height:100%; object-fit:cover; }\n.thumb.hatch { background:repeating-linear-gradient(45deg, rgb(138 144 153 / 10%) 0 4px, rgb(138 144 153 / 20%) 4px 8px); }\n.shot-open { display:block; width:100%; height:100%; padding:0; border:0; background:transparent; }\n.optout-row { display:flex; align-items:center; gap:8px; margin-bottom:16px; color:var(--jz-muted); font-size:12px; }\n.optout-row[hidden] { display:none; }\n.note { font-size:11px; color:var(--jz-faint); line-height:1.3; }\n.shot-full { position:fixed; inset:0; z-index:2147483647; display:flex; align-items:center; justify-content:center; padding:24px; background:rgb(0 0 0 / 72%); }\n.shot-full img { max-width:100%; max-height:100%; object-fit:contain; border-radius:6px; background:var(--jz-surface); }\n.shot-full .close { position:absolute; top:16px; right:16px; background:var(--jz-surface); color:var(--jz-ink); }\n.primary { min-height:44px; padding:0 24px; border:0; border-radius:8px; background:var(--jz-accent); color:var(--jz-accent-ink); font-weight:500; }\n.primary:disabled { opacity:.45; cursor:not-allowed; }\n.secondary { min-height:44px; padding:0 16px; border:1px solid var(--jz-rule); border-radius:6px; background:transparent;\n color:var(--jz-muted); font-weight:500; }\n\n.sheet { left:32px; bottom:32px; width:340px; max-width:calc(100vw - 32px); padding:24px; border-radius:10px; }\n.sheet h2 { display:flex; align-items:center; gap:8px; margin:0 0 12px; font-size:14px; font-weight:500; }\n.sheet h2 svg { color:var(--jz-accent); }\n.sheet p { margin:0 0 12px; color:var(--jz-muted); line-height:1.6; }\n.sheet ul { margin:0 0 20px; padding-left:18px; color:var(--jz-muted); }\n.row { display:flex; gap:8px; }\n.row > * { flex:1; }\n\n.checkin { right:32px; bottom:140px; display:flex; align-items:center; gap:8px; padding:8px 8px 8px 16px; border-radius:10px; }\n.checkin .secondary { min-height:36px; }\n.toast { right:32px; bottom:88px; padding:10px 16px; border-radius:10px; }\n.toast.err { border-color:var(--jz-broken); }\n\n@media (max-width: 479px) {\n .toggle { right:24px; bottom:24px; height:48px; padding:0 20px; background:var(--jz-accent); color:var(--jz-accent-ink); }\n .toggle .dot { background:var(--jz-accent-ink); }\n .toggle .exit { color:inherit; opacity:.8; }\n .pop { left:0 !important; right:0; top:auto !important; bottom:0; width:auto; max-width:none; max-height:85vh;\n border-radius:16px 16px 0 0; border-width:1px 0 0; padding:12px 24px 34px; }\n .pop::before { content:\"\"; display:block; width:48px; height:4px; margin:0 auto 16px; border-radius:999px; background:var(--jz-raised); }\n .chip { border-radius:4px; border:1px solid var(--jz-rule); }\n .reactions { display:grid; grid-template-columns:repeat(4, 1fr); gap:12px; border:0; overflow:visible; }\n .reaction { border:1px solid var(--jz-rule); border-radius:8px; padding:16px 4px; }\n .reaction:last-child { border-right:1px solid var(--jz-rule); }\n .reaction[aria-checked=\"true\"] { border:2px solid var(--jz-accent); }\n .reaction span { font-size:11px; }\n .foot { flex-direction:column; align-items:stretch; }\n .foot .primary { width:100%; min-height:52px; font-size:15px; }\n .sheet { left:16px; right:16px; bottom:16px; width:auto; }\n .toast { left:16px; right:16px; bottom:84px; }\n .checkin { left:16px; right:16px; bottom:136px; }\n}\n@media (prefers-reduced-motion: reduce) {\n .jz *, .jz *::before, .jz *::after { animation-duration:1ms !important; transition-duration:1ms !important; }\n}\n";
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { WidgetModule } from "./loader";
|
|
2
|
+
import { type JourneezeContext, type WireFeedbackContext } from "./types";
|
|
3
|
+
export { maskedSnapshotSvg } from "./widget/capture";
|
|
4
|
+
/**
|
|
5
|
+
* The PUT target for a screenshot: `uploadUrl` is a path relative to the collector endpoint
|
|
6
|
+
* (collector.proto). Image bytes only ever go to the collector's own origin.
|
|
7
|
+
*/
|
|
8
|
+
export declare function uploadTarget(uploadUrl: string, endpoint: string): string | undefined;
|
|
9
|
+
/** Strips empty values; adds the page path and device class the widget derives. */
|
|
10
|
+
export declare function wireContext(ctx: Readonly<JourneezeContext>, href: string, width: number, tflowId?: string): WireFeedbackContext;
|
|
11
|
+
/**
|
|
12
|
+
* The host's signature over the user id (contract §4, v1.3), only while it is well formed and
|
|
13
|
+
* unexpired; otherwise the id travels unsigned (sites that require signed identity then treat
|
|
14
|
+
* the request as anonymous). Fixed into the request when it is written, like the id.
|
|
15
|
+
*/
|
|
16
|
+
export declare function signedIdentity(o: {
|
|
17
|
+
userIdSig?: string | undefined;
|
|
18
|
+
userIdExp?: number | undefined;
|
|
19
|
+
signature?: {
|
|
20
|
+
sig: string;
|
|
21
|
+
exp: number;
|
|
22
|
+
} | "" | undefined;
|
|
23
|
+
}): {
|
|
24
|
+
userIdSig?: string;
|
|
25
|
+
userIdExp?: number;
|
|
26
|
+
};
|
|
27
|
+
export declare const mount: WidgetModule["mount"];
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
export declare class CollectorError extends Error {
|
|
2
|
+
readonly code: string;
|
|
3
|
+
/** HTTP status of the response (0 when there was none). */
|
|
4
|
+
readonly status: number;
|
|
5
|
+
/** The response's `Retry-After`, in milliseconds (C0b §6), when it sent one. */
|
|
6
|
+
readonly retryAfterMs?: number | undefined;
|
|
7
|
+
constructor(code: string, message: string,
|
|
8
|
+
/** HTTP status of the response (0 when there was none). */
|
|
9
|
+
status?: number,
|
|
10
|
+
/** The response's `Retry-After`, in milliseconds (C0b §6), when it sent one. */
|
|
11
|
+
retryAfterMs?: number | undefined);
|
|
12
|
+
}
|
|
13
|
+
/** The collector a v1 page talks to when the host names none (C0a §5, C0b §1: direct mode). */
|
|
14
|
+
export declare const DEFAULT_API_HOST = "https://app.journeeze.dev";
|
|
15
|
+
export declare const TIMEOUT_MS = 15000;
|
|
16
|
+
/** `init` plus a timeout signal where the browser supports `AbortSignal.timeout`. */
|
|
17
|
+
export declare function withTimeout(init: RequestInit, ms?: number): RequestInit;
|
|
18
|
+
export interface CallOptions {
|
|
19
|
+
/** Let the request finish after the page unloads (small bodies only, < 64 KB). */
|
|
20
|
+
keepalive?: boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The collector base URL from the v0 `endpoint` option: an explicit (relative or absolute)
|
|
24
|
+
* endpoint is resolved against the page; without one, v1 talks to the Journeeze collector
|
|
25
|
+
* directly ({@link DEFAULT_API_HOST}, C0a §5 "Change [J3c]"). A v0 host that relied on its own
|
|
26
|
+
* same-origin proxy without setting `endpoint` must now set `apiHost: location.origin`.
|
|
27
|
+
*/
|
|
28
|
+
export declare function resolveEndpoint(endpoint: string | undefined, base?: string): string;
|
|
29
|
+
/** Whether `endpoint` is another origin than the page's (direct mode: CORS rules apply). */
|
|
30
|
+
export declare function isCrossOrigin(endpoint: string, page?: string): boolean;
|
|
31
|
+
/** The content type of every direct-mode body (C0b §2.1): CORS-safelisted, UTF-8. */
|
|
32
|
+
export declare const TEXT_PLAIN = "text/plain;charset=UTF-8";
|
|
33
|
+
/** The unary RPC URL under `endpoint`. */
|
|
34
|
+
export declare function rpcUrl(endpoint: string, method: string): string;
|
|
35
|
+
/**
|
|
36
|
+
* The request headers of a unary call: direct mode sends only `text/plain` (a simple request, no
|
|
37
|
+
* preflight); a help read's `If-None-Match` is added in both modes (that one read preflights,
|
|
38
|
+
* and the preflight is cached for two hours). Same origin keeps Connect JSON.
|
|
39
|
+
*/
|
|
40
|
+
export declare function unaryHeaders(endpoint: string, etag?: string): Record<string, string>;
|
|
41
|
+
/** No wait (backoff or `Retry-After`) is longer than 60 s (C0b §6). */
|
|
42
|
+
export declare const RETRY_CAP_MS = 60000;
|
|
43
|
+
/** `Retry-After` (whole seconds or an HTTP date) in milliseconds, capped at 60 s (C0b §6). */
|
|
44
|
+
export declare function retryAfterMs(header: string | null, now?: number): number | undefined;
|
|
45
|
+
export declare function callCollector<Res>(endpoint: string, method: string, body: unknown, fetchImpl?: typeof fetch, opts?: CallOptions): Promise<Res>;
|
|
46
|
+
/** A help read (`GetHelpIndex`, `GetGuide`): fresh data with its ETag, or "unchanged". */
|
|
47
|
+
export type Revalidated<Res> = {
|
|
48
|
+
notModified: false;
|
|
49
|
+
value: Res;
|
|
50
|
+
etag?: string;
|
|
51
|
+
} | {
|
|
52
|
+
notModified: true;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* A read-only collector call that revalidates: sends `If-None-Match` with a previous ETag and
|
|
56
|
+
* returns `notModified` on `304`. Same rules as {@link callCollector}. Browsers do not cache
|
|
57
|
+
* POST responses: keep the last value in memory for the response's `max-age`, then revalidate.
|
|
58
|
+
*/
|
|
59
|
+
export declare function callCollectorRevalidating<Res>(endpoint: string, method: string, body: unknown, etag: string | undefined, fetchImpl?: typeof fetch): Promise<Revalidated<Res>>;
|
|
60
|
+
/** A guide asset path (relative to the collector endpoint) as an absolute URL, or `undefined`. */
|
|
61
|
+
export declare function assetUrl(endpoint: string, path: string | undefined): string | undefined;
|
|
62
|
+
/**
|
|
63
|
+
* Connect code for an HTTP error without a Connect body (proxies, load balancers, framework
|
|
64
|
+
* rejections). A bare 404 is treated as transient (a deploy or a proxy), never as permanent.
|
|
65
|
+
*/
|
|
66
|
+
export declare function codeForStatus(status: number): string;
|