@cmssy/core 12.9.0 → 12.11.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/dist/{content-client-COeyYJl1.d.cts → content-client-65N8ZRq9.d.cts} +11 -4
- package/dist/{content-client-COeyYJl1.d.ts → content-client-65N8ZRq9.d.ts} +11 -4
- package/dist/{csp-BDE0cAZL.d.ts → csp-BnOiGUhR.d.ts} +1 -1
- package/dist/{csp-BMP9bAZ9.d.cts → csp-RaStdD2i.d.cts} +1 -1
- package/dist/index.cjs +88 -23
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +88 -24
- package/dist/internal/locale.cjs +86 -22
- package/dist/internal/locale.d.cts +2 -2
- package/dist/internal/locale.d.ts +2 -2
- package/dist/internal/locale.js +86 -22
- package/dist/internal.cjs +92 -28
- package/dist/internal.d.cts +5 -5
- package/dist/internal.d.ts +5 -5
- package/dist/internal.js +92 -28
- package/dist/{locale-jxsO_8YF.d.ts → locale-D9KI4bND.d.ts} +2 -2
- package/dist/{locale-BM2fwE3O.d.cts → locale-JyBHqpAQ.d.cts} +2 -2
- package/dist/preflight.d.cts +1 -1
- package/dist/preflight.d.ts +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { C as CMSSY_LOCALE_HEADER, a as localeForPath, b as localeForPathname, l as localizeHref, c as resolveSiteLocales, s as splitCmssyLocale, d as splitLocaleFromPath } from '../locale-
|
|
1
|
+
export { C as CMSSY_LOCALE_HEADER, a as localeForPath, b as localeForPathname, l as localizeHref, c as resolveSiteLocales, s as splitCmssyLocale, d as splitLocaleFromPath } from '../locale-JyBHqpAQ.cjs';
|
|
2
2
|
export { CmssySiteLocales } from '@cmssy/types';
|
|
3
|
-
import '../content-client-
|
|
3
|
+
import '../content-client-65N8ZRq9.cjs';
|
|
4
4
|
|
|
5
5
|
declare function localizedPath(slug: string, locale: string, defaultLocale: string): string;
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { C as CMSSY_LOCALE_HEADER, a as localeForPath, b as localeForPathname, l as localizeHref, c as resolveSiteLocales, s as splitCmssyLocale, d as splitLocaleFromPath } from '../locale-
|
|
1
|
+
export { C as CMSSY_LOCALE_HEADER, a as localeForPath, b as localeForPathname, l as localizeHref, c as resolveSiteLocales, s as splitCmssyLocale, d as splitLocaleFromPath } from '../locale-D9KI4bND.js';
|
|
2
2
|
export { CmssySiteLocales } from '@cmssy/types';
|
|
3
|
-
import '../content-client-
|
|
3
|
+
import '../content-client-65N8ZRq9.js';
|
|
4
4
|
|
|
5
5
|
declare function localizedPath(slug: string, locale: string, defaultLocale: string): string;
|
|
6
6
|
|
package/dist/internal/locale.js
CHANGED
|
@@ -2,15 +2,64 @@
|
|
|
2
2
|
var CmssyRequestError = class extends Error {
|
|
3
3
|
status;
|
|
4
4
|
retryAfterMs;
|
|
5
|
-
|
|
5
|
+
waitedMs;
|
|
6
|
+
constructor(message, status, retryAfterMs2, waitedMs) {
|
|
6
7
|
super(message);
|
|
7
8
|
this.name = "CmssyRequestError";
|
|
8
9
|
this.status = status;
|
|
9
10
|
if (retryAfterMs2 !== void 0) this.retryAfterMs = retryAfterMs2;
|
|
11
|
+
if (waitedMs !== void 0) this.waitedMs = waitedMs;
|
|
10
12
|
}
|
|
11
13
|
};
|
|
12
|
-
var
|
|
14
|
+
var THROTTLE_STATUS = 429;
|
|
13
15
|
var CMSSY_RATE_LIMIT_WINDOW_MS = 6e4;
|
|
16
|
+
var CMSSY_RETRY_MODES = {
|
|
17
|
+
build: {
|
|
18
|
+
maxRetries: 4,
|
|
19
|
+
baseDelayMs: 300,
|
|
20
|
+
throttleBaseDelayMs: 1e3,
|
|
21
|
+
maxDelayMs: 2e4,
|
|
22
|
+
maxRetryAfterMs: CMSSY_RATE_LIMIT_WINDOW_MS,
|
|
23
|
+
maxTotalWaitMs: 18e4,
|
|
24
|
+
retryStatuses: Object.freeze([429, 503])
|
|
25
|
+
},
|
|
26
|
+
interactive: {
|
|
27
|
+
maxRetries: 2,
|
|
28
|
+
baseDelayMs: 50,
|
|
29
|
+
throttleBaseDelayMs: 500,
|
|
30
|
+
maxDelayMs: 1e3,
|
|
31
|
+
maxRetryAfterMs: 1e3,
|
|
32
|
+
maxTotalWaitMs: 2e3,
|
|
33
|
+
retryStatuses: Object.freeze([429, 503])
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
Object.freeze(CMSSY_RETRY_MODES.build);
|
|
37
|
+
Object.freeze(CMSSY_RETRY_MODES.interactive);
|
|
38
|
+
Object.freeze(CMSSY_RETRY_MODES);
|
|
39
|
+
function resolveRetryPolicy(retry) {
|
|
40
|
+
if (retry === false || retry === void 0) return null;
|
|
41
|
+
if (typeof retry === "string") {
|
|
42
|
+
const mode = CMSSY_RETRY_MODES[retry];
|
|
43
|
+
if (!mode) {
|
|
44
|
+
throw new Error(
|
|
45
|
+
`cmssy: unknown retry mode "${retry}" - use ${Object.keys(
|
|
46
|
+
CMSSY_RETRY_MODES
|
|
47
|
+
).map((name) => `"${name}"`).join(" or ")}, false, or a retry policy object`
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
return mode;
|
|
51
|
+
}
|
|
52
|
+
const base = CMSSY_RETRY_MODES.build;
|
|
53
|
+
return {
|
|
54
|
+
maxRetries: retry.maxRetries ?? base.maxRetries,
|
|
55
|
+
baseDelayMs: retry.baseDelayMs ?? base.baseDelayMs,
|
|
56
|
+
throttleBaseDelayMs: retry.throttleBaseDelayMs ?? base.throttleBaseDelayMs,
|
|
57
|
+
maxDelayMs: retry.maxDelayMs ?? base.maxDelayMs,
|
|
58
|
+
maxRetryAfterMs: retry.maxRetryAfterMs ?? base.maxRetryAfterMs,
|
|
59
|
+
maxTotalWaitMs: retry.maxTotalWaitMs ?? base.maxTotalWaitMs,
|
|
60
|
+
retryStatuses: retry.retryStatuses ?? base.retryStatuses
|
|
61
|
+
};
|
|
62
|
+
}
|
|
14
63
|
function retryAfterMs(response) {
|
|
15
64
|
const raw = response.headers?.get("retry-after");
|
|
16
65
|
if (!raw) return null;
|
|
@@ -37,28 +86,40 @@ function sleep(ms, signal) {
|
|
|
37
86
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
38
87
|
});
|
|
39
88
|
}
|
|
40
|
-
async function fetchWithRetry(doFetch, url, init, retry) {
|
|
41
|
-
|
|
42
|
-
|
|
89
|
+
async function fetchWithRetry(doFetch, url, init, retry, label) {
|
|
90
|
+
const policy = resolveRetryPolicy(retry);
|
|
91
|
+
if (policy === null) {
|
|
92
|
+
return { response: await doFetch(url, init), waitedMs: 0 };
|
|
43
93
|
}
|
|
44
|
-
const maxRetries = retry.maxRetries ?? 3;
|
|
45
|
-
const baseDelayMs = retry.baseDelayMs ?? 300;
|
|
46
|
-
const maxDelayMs = retry.maxDelayMs ?? 3e3;
|
|
47
|
-
const maxRetryAfterMs = retry.maxRetryAfterMs ?? CMSSY_RATE_LIMIT_WINDOW_MS;
|
|
48
|
-
const retryStatuses = retry.retryStatuses ?? DEFAULT_RETRY_STATUSES;
|
|
49
94
|
let response = await doFetch(url, init);
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
95
|
+
let waitedMs = 0;
|
|
96
|
+
for (let attempt = 0; attempt < policy.maxRetries; attempt++) {
|
|
97
|
+
if (response.ok || !policy.retryStatuses.includes(response.status)) {
|
|
98
|
+
return { response, waitedMs };
|
|
53
99
|
}
|
|
100
|
+
const throttled = response.status === THROTTLE_STATUS;
|
|
54
101
|
const asked = retryAfterMs(response);
|
|
55
|
-
if (asked !== null && asked > maxRetryAfterMs)
|
|
56
|
-
|
|
57
|
-
|
|
102
|
+
if (asked !== null && asked > policy.maxRetryAfterMs) {
|
|
103
|
+
return { response, waitedMs };
|
|
104
|
+
}
|
|
105
|
+
const base = throttled ? policy.throttleBaseDelayMs : policy.baseDelayMs;
|
|
106
|
+
const wait = Math.round(
|
|
107
|
+
asked !== null ? Math.min(
|
|
108
|
+
asked + Math.random() * policy.throttleBaseDelayMs,
|
|
109
|
+
policy.maxRetryAfterMs
|
|
110
|
+
) : Math.random() * Math.min(base * 2 ** attempt, policy.maxDelayMs)
|
|
111
|
+
);
|
|
112
|
+
if (waitedMs + wait > policy.maxTotalWaitMs) {
|
|
113
|
+
return { response, waitedMs };
|
|
114
|
+
}
|
|
115
|
+
console.warn(
|
|
116
|
+
`[cmssy] ${label} got ${response.status}, retrying in ${wait}ms (attempt ${attempt + 1}/${policy.maxRetries})`
|
|
117
|
+
);
|
|
58
118
|
await sleep(wait, init.signal);
|
|
119
|
+
waitedMs += wait;
|
|
59
120
|
response = await doFetch(url, init);
|
|
60
121
|
}
|
|
61
|
-
return response;
|
|
122
|
+
return { response, waitedMs };
|
|
62
123
|
}
|
|
63
124
|
async function postGraphql(url, query, variables, options) {
|
|
64
125
|
const doFetch = options.fetch ?? globalThis.fetch;
|
|
@@ -67,7 +128,7 @@ async function postGraphql(url, query, variables, options) {
|
|
|
67
128
|
"cmssy: no fetch implementation available - pass options.fetch"
|
|
68
129
|
);
|
|
69
130
|
}
|
|
70
|
-
const response = await fetchWithRetry(
|
|
131
|
+
const { response, waitedMs } = await fetchWithRetry(
|
|
71
132
|
doFetch,
|
|
72
133
|
url,
|
|
73
134
|
{
|
|
@@ -76,7 +137,8 @@ async function postGraphql(url, query, variables, options) {
|
|
|
76
137
|
body: JSON.stringify({ query, variables }),
|
|
77
138
|
signal: options.signal
|
|
78
139
|
},
|
|
79
|
-
options.retry
|
|
140
|
+
options.retry,
|
|
141
|
+
options.label
|
|
80
142
|
);
|
|
81
143
|
if (!response.ok) {
|
|
82
144
|
let detail = "";
|
|
@@ -90,10 +152,12 @@ async function postGraphql(url, query, variables, options) {
|
|
|
90
152
|
}
|
|
91
153
|
const asked = retryAfterMs(response);
|
|
92
154
|
const wait = asked !== null ? ` - retry after ${Math.ceil(asked / 1e3)}s` : "";
|
|
155
|
+
const spent = waitedMs > 0 ? ` - gave up after waiting ${waitedMs}ms` : "";
|
|
93
156
|
throw new CmssyRequestError(
|
|
94
|
-
`cmssy: ${options.label} failed (${response.status})${detail}${wait}`,
|
|
157
|
+
`cmssy: ${options.label} failed (${response.status})${detail}${wait}${spent}`,
|
|
95
158
|
response.status,
|
|
96
|
-
asked ?? void 0
|
|
159
|
+
asked ?? void 0,
|
|
160
|
+
waitedMs > 0 ? waitedMs : void 0
|
|
97
161
|
);
|
|
98
162
|
}
|
|
99
163
|
let json;
|
|
@@ -182,7 +246,7 @@ async function loadSiteLocales(config, options) {
|
|
|
182
246
|
config,
|
|
183
247
|
SITE_CONFIG_QUERY,
|
|
184
248
|
{ workspaceSlug: config.workspaceSlug },
|
|
185
|
-
{ ...options, public: true, retry: options?.retry ??
|
|
249
|
+
{ ...options, public: true, retry: options?.retry ?? "build" },
|
|
186
250
|
"site config"
|
|
187
251
|
);
|
|
188
252
|
value = localesFromSiteConfig(data.public?.siteConfig ?? null);
|
package/dist/internal.cjs
CHANGED
|
@@ -4,15 +4,64 @@
|
|
|
4
4
|
var CmssyRequestError = class extends Error {
|
|
5
5
|
status;
|
|
6
6
|
retryAfterMs;
|
|
7
|
-
|
|
7
|
+
waitedMs;
|
|
8
|
+
constructor(message, status, retryAfterMs2, waitedMs) {
|
|
8
9
|
super(message);
|
|
9
10
|
this.name = "CmssyRequestError";
|
|
10
11
|
this.status = status;
|
|
11
12
|
if (retryAfterMs2 !== void 0) this.retryAfterMs = retryAfterMs2;
|
|
13
|
+
if (waitedMs !== void 0) this.waitedMs = waitedMs;
|
|
12
14
|
}
|
|
13
15
|
};
|
|
14
|
-
var
|
|
16
|
+
var THROTTLE_STATUS = 429;
|
|
15
17
|
var CMSSY_RATE_LIMIT_WINDOW_MS = 6e4;
|
|
18
|
+
var CMSSY_RETRY_MODES = {
|
|
19
|
+
build: {
|
|
20
|
+
maxRetries: 4,
|
|
21
|
+
baseDelayMs: 300,
|
|
22
|
+
throttleBaseDelayMs: 1e3,
|
|
23
|
+
maxDelayMs: 2e4,
|
|
24
|
+
maxRetryAfterMs: CMSSY_RATE_LIMIT_WINDOW_MS,
|
|
25
|
+
maxTotalWaitMs: 18e4,
|
|
26
|
+
retryStatuses: Object.freeze([429, 503])
|
|
27
|
+
},
|
|
28
|
+
interactive: {
|
|
29
|
+
maxRetries: 2,
|
|
30
|
+
baseDelayMs: 50,
|
|
31
|
+
throttleBaseDelayMs: 500,
|
|
32
|
+
maxDelayMs: 1e3,
|
|
33
|
+
maxRetryAfterMs: 1e3,
|
|
34
|
+
maxTotalWaitMs: 2e3,
|
|
35
|
+
retryStatuses: Object.freeze([429, 503])
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
Object.freeze(CMSSY_RETRY_MODES.build);
|
|
39
|
+
Object.freeze(CMSSY_RETRY_MODES.interactive);
|
|
40
|
+
Object.freeze(CMSSY_RETRY_MODES);
|
|
41
|
+
function resolveRetryPolicy(retry) {
|
|
42
|
+
if (retry === false || retry === void 0) return null;
|
|
43
|
+
if (typeof retry === "string") {
|
|
44
|
+
const mode = CMSSY_RETRY_MODES[retry];
|
|
45
|
+
if (!mode) {
|
|
46
|
+
throw new Error(
|
|
47
|
+
`cmssy: unknown retry mode "${retry}" - use ${Object.keys(
|
|
48
|
+
CMSSY_RETRY_MODES
|
|
49
|
+
).map((name2) => `"${name2}"`).join(" or ")}, false, or a retry policy object`
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
return mode;
|
|
53
|
+
}
|
|
54
|
+
const base = CMSSY_RETRY_MODES.build;
|
|
55
|
+
return {
|
|
56
|
+
maxRetries: retry.maxRetries ?? base.maxRetries,
|
|
57
|
+
baseDelayMs: retry.baseDelayMs ?? base.baseDelayMs,
|
|
58
|
+
throttleBaseDelayMs: retry.throttleBaseDelayMs ?? base.throttleBaseDelayMs,
|
|
59
|
+
maxDelayMs: retry.maxDelayMs ?? base.maxDelayMs,
|
|
60
|
+
maxRetryAfterMs: retry.maxRetryAfterMs ?? base.maxRetryAfterMs,
|
|
61
|
+
maxTotalWaitMs: retry.maxTotalWaitMs ?? base.maxTotalWaitMs,
|
|
62
|
+
retryStatuses: retry.retryStatuses ?? base.retryStatuses
|
|
63
|
+
};
|
|
64
|
+
}
|
|
16
65
|
function retryAfterMs(response) {
|
|
17
66
|
const raw = response.headers?.get("retry-after");
|
|
18
67
|
if (!raw) return null;
|
|
@@ -39,28 +88,40 @@ function sleep(ms, signal) {
|
|
|
39
88
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
40
89
|
});
|
|
41
90
|
}
|
|
42
|
-
async function fetchWithRetry(doFetch, url, init, retry) {
|
|
43
|
-
|
|
44
|
-
|
|
91
|
+
async function fetchWithRetry(doFetch, url, init, retry, label) {
|
|
92
|
+
const policy = resolveRetryPolicy(retry);
|
|
93
|
+
if (policy === null) {
|
|
94
|
+
return { response: await doFetch(url, init), waitedMs: 0 };
|
|
45
95
|
}
|
|
46
|
-
const maxRetries = retry.maxRetries ?? 3;
|
|
47
|
-
const baseDelayMs = retry.baseDelayMs ?? 300;
|
|
48
|
-
const maxDelayMs = retry.maxDelayMs ?? 3e3;
|
|
49
|
-
const maxRetryAfterMs = retry.maxRetryAfterMs ?? CMSSY_RATE_LIMIT_WINDOW_MS;
|
|
50
|
-
const retryStatuses = retry.retryStatuses ?? DEFAULT_RETRY_STATUSES;
|
|
51
96
|
let response = await doFetch(url, init);
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
97
|
+
let waitedMs = 0;
|
|
98
|
+
for (let attempt = 0; attempt < policy.maxRetries; attempt++) {
|
|
99
|
+
if (response.ok || !policy.retryStatuses.includes(response.status)) {
|
|
100
|
+
return { response, waitedMs };
|
|
55
101
|
}
|
|
102
|
+
const throttled = response.status === THROTTLE_STATUS;
|
|
56
103
|
const asked = retryAfterMs(response);
|
|
57
|
-
if (asked !== null && asked > maxRetryAfterMs)
|
|
58
|
-
|
|
59
|
-
|
|
104
|
+
if (asked !== null && asked > policy.maxRetryAfterMs) {
|
|
105
|
+
return { response, waitedMs };
|
|
106
|
+
}
|
|
107
|
+
const base = throttled ? policy.throttleBaseDelayMs : policy.baseDelayMs;
|
|
108
|
+
const wait = Math.round(
|
|
109
|
+
asked !== null ? Math.min(
|
|
110
|
+
asked + Math.random() * policy.throttleBaseDelayMs,
|
|
111
|
+
policy.maxRetryAfterMs
|
|
112
|
+
) : Math.random() * Math.min(base * 2 ** attempt, policy.maxDelayMs)
|
|
113
|
+
);
|
|
114
|
+
if (waitedMs + wait > policy.maxTotalWaitMs) {
|
|
115
|
+
return { response, waitedMs };
|
|
116
|
+
}
|
|
117
|
+
console.warn(
|
|
118
|
+
`[cmssy] ${label} got ${response.status}, retrying in ${wait}ms (attempt ${attempt + 1}/${policy.maxRetries})`
|
|
119
|
+
);
|
|
60
120
|
await sleep(wait, init.signal);
|
|
121
|
+
waitedMs += wait;
|
|
61
122
|
response = await doFetch(url, init);
|
|
62
123
|
}
|
|
63
|
-
return response;
|
|
124
|
+
return { response, waitedMs };
|
|
64
125
|
}
|
|
65
126
|
async function postGraphql(url, query, variables, options) {
|
|
66
127
|
const doFetch = options.fetch ?? globalThis.fetch;
|
|
@@ -69,7 +130,7 @@ async function postGraphql(url, query, variables, options) {
|
|
|
69
130
|
"cmssy: no fetch implementation available - pass options.fetch"
|
|
70
131
|
);
|
|
71
132
|
}
|
|
72
|
-
const response = await fetchWithRetry(
|
|
133
|
+
const { response, waitedMs } = await fetchWithRetry(
|
|
73
134
|
doFetch,
|
|
74
135
|
url,
|
|
75
136
|
{
|
|
@@ -78,7 +139,8 @@ async function postGraphql(url, query, variables, options) {
|
|
|
78
139
|
body: JSON.stringify({ query, variables }),
|
|
79
140
|
signal: options.signal
|
|
80
141
|
},
|
|
81
|
-
options.retry
|
|
142
|
+
options.retry,
|
|
143
|
+
options.label
|
|
82
144
|
);
|
|
83
145
|
if (!response.ok) {
|
|
84
146
|
let detail = "";
|
|
@@ -92,10 +154,12 @@ async function postGraphql(url, query, variables, options) {
|
|
|
92
154
|
}
|
|
93
155
|
const asked = retryAfterMs(response);
|
|
94
156
|
const wait = asked !== null ? ` - retry after ${Math.ceil(asked / 1e3)}s` : "";
|
|
157
|
+
const spent = waitedMs > 0 ? ` - gave up after waiting ${waitedMs}ms` : "";
|
|
95
158
|
throw new CmssyRequestError(
|
|
96
|
-
`cmssy: ${options.label} failed (${response.status})${detail}${wait}`,
|
|
159
|
+
`cmssy: ${options.label} failed (${response.status})${detail}${wait}${spent}`,
|
|
97
160
|
response.status,
|
|
98
|
-
asked ?? void 0
|
|
161
|
+
asked ?? void 0,
|
|
162
|
+
waitedMs > 0 ? waitedMs : void 0
|
|
99
163
|
);
|
|
100
164
|
}
|
|
101
165
|
let json;
|
|
@@ -232,7 +296,7 @@ async function fetchPage(config, path, options = {}) {
|
|
|
232
296
|
fetch: options.fetch,
|
|
233
297
|
signal: options.signal,
|
|
234
298
|
headers,
|
|
235
|
-
retry: options.retry ??
|
|
299
|
+
retry: options.retry ?? "build",
|
|
236
300
|
label: "page fetch"
|
|
237
301
|
}
|
|
238
302
|
);
|
|
@@ -255,7 +319,7 @@ async function fetchPageById(config, pageId, options = {}) {
|
|
|
255
319
|
{
|
|
256
320
|
fetch: options.fetch,
|
|
257
321
|
signal: options.signal,
|
|
258
|
-
retry: options.retry ??
|
|
322
|
+
retry: options.retry ?? "build",
|
|
259
323
|
label: "page-by-id fetch"
|
|
260
324
|
}
|
|
261
325
|
);
|
|
@@ -276,7 +340,7 @@ async function fetchPages(config, options = {}) {
|
|
|
276
340
|
{
|
|
277
341
|
fetch: options.fetch,
|
|
278
342
|
signal: options.signal,
|
|
279
|
-
retry: options.retry ??
|
|
343
|
+
retry: options.retry ?? "build",
|
|
280
344
|
label: "pages fetch"
|
|
281
345
|
}
|
|
282
346
|
);
|
|
@@ -291,7 +355,7 @@ async function fetchPageMeta(config, path, options = {}) {
|
|
|
291
355
|
{
|
|
292
356
|
fetch: options.fetch,
|
|
293
357
|
signal: options.signal,
|
|
294
|
-
retry: options.retry ??
|
|
358
|
+
retry: options.retry ?? "build",
|
|
295
359
|
label: "page meta fetch"
|
|
296
360
|
}
|
|
297
361
|
);
|
|
@@ -308,7 +372,7 @@ async function fetchLayouts(config, path, options = {}) {
|
|
|
308
372
|
{
|
|
309
373
|
fetch: options.fetch,
|
|
310
374
|
signal: options.signal,
|
|
311
|
-
retry: options.retry ??
|
|
375
|
+
retry: options.retry ?? "build",
|
|
312
376
|
label: "layouts fetch"
|
|
313
377
|
}
|
|
314
378
|
);
|
|
@@ -434,7 +498,7 @@ async function fetchSiteConfig(config, options = {}) {
|
|
|
434
498
|
config,
|
|
435
499
|
SITE_CONFIG_QUERY,
|
|
436
500
|
{ workspaceSlug: config.workspaceSlug },
|
|
437
|
-
{ ...options, public: true, retry: options.retry ??
|
|
501
|
+
{ ...options, public: true, retry: options.retry ?? "build" },
|
|
438
502
|
"site config query"
|
|
439
503
|
);
|
|
440
504
|
return data.public?.siteConfig ?? null;
|
|
@@ -972,7 +1036,7 @@ async function loadSiteLocales(config, options) {
|
|
|
972
1036
|
config,
|
|
973
1037
|
SITE_CONFIG_QUERY,
|
|
974
1038
|
{ workspaceSlug: config.workspaceSlug },
|
|
975
|
-
{ ...options, public: true, retry: options?.retry ??
|
|
1039
|
+
{ ...options, public: true, retry: options?.retry ?? "build" },
|
|
976
1040
|
"site config"
|
|
977
1041
|
);
|
|
978
1042
|
value = localesFromSiteConfig(data.public?.siteConfig ?? null);
|
package/dist/internal.d.cts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { g as fetchLayouts, h as fetchPage, i as fetchPageById, j as fetchPageMeta, k as fetchPages, r as resolveApiUrl } from './content-client-65N8ZRq9.cjs';
|
|
2
2
|
import { CmssyFormDefinition, BuildBlockContextExtra, CmssyBlockContext, CmssyClientConfig, CmssySiteConfig, FieldDefinition, RawBlock } from '@cmssy/types';
|
|
3
3
|
export { CmssySiteLocales } from '@cmssy/types';
|
|
4
|
-
import { G as GraphqlRequestOptions } from './locale-
|
|
5
|
-
export { C as CMSSY_LOCALE_HEADER, a as localeForPath, b as localeForPathname, l as localizeHref, c as resolveSiteLocales, s as splitCmssyLocale, d as splitLocaleFromPath } from './locale-
|
|
6
|
-
import { Q as QueryScopedOptions } from './csp-
|
|
7
|
-
export { u as cmssyCspHeaders, v as isDevelopment, w as resolveInitialTarget, x as toCspOrigin } from './csp-
|
|
4
|
+
import { G as GraphqlRequestOptions } from './locale-JyBHqpAQ.cjs';
|
|
5
|
+
export { C as CMSSY_LOCALE_HEADER, a as localeForPath, b as localeForPathname, l as localizeHref, c as resolveSiteLocales, s as splitCmssyLocale, d as splitLocaleFromPath } from './locale-JyBHqpAQ.cjs';
|
|
6
|
+
import { Q as QueryScopedOptions } from './csp-RaStdD2i.cjs';
|
|
7
|
+
export { u as cmssyCspHeaders, v as isDevelopment, w as resolveInitialTarget, x as toCspOrigin } from './csp-RaStdD2i.cjs';
|
|
8
8
|
export { localizedPath } from './internal/locale.cjs';
|
|
9
9
|
|
|
10
10
|
declare const SITE_CONFIG_QUERY = "query PublicSiteConfig($workspaceSlug: String!) {\n public {\n siteConfig(workspaceSlug: $workspaceSlug) {\n id\n workspaceId\n siteName\n defaultLanguage\n enabledLanguages\n enabledFeatures\n notFoundPageId\n previewUrl\n branding {\n brandName\n logoUrl\n logoDarkUrl\n faviconUrl\n ogImageUrl\n }\n }\n }\n}";
|
package/dist/internal.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { g as fetchLayouts, h as fetchPage, i as fetchPageById, j as fetchPageMeta, k as fetchPages, r as resolveApiUrl } from './content-client-65N8ZRq9.js';
|
|
2
2
|
import { CmssyFormDefinition, BuildBlockContextExtra, CmssyBlockContext, CmssyClientConfig, CmssySiteConfig, FieldDefinition, RawBlock } from '@cmssy/types';
|
|
3
3
|
export { CmssySiteLocales } from '@cmssy/types';
|
|
4
|
-
import { G as GraphqlRequestOptions } from './locale-
|
|
5
|
-
export { C as CMSSY_LOCALE_HEADER, a as localeForPath, b as localeForPathname, l as localizeHref, c as resolveSiteLocales, s as splitCmssyLocale, d as splitLocaleFromPath } from './locale-
|
|
6
|
-
import { Q as QueryScopedOptions } from './csp-
|
|
7
|
-
export { u as cmssyCspHeaders, v as isDevelopment, w as resolveInitialTarget, x as toCspOrigin } from './csp-
|
|
4
|
+
import { G as GraphqlRequestOptions } from './locale-D9KI4bND.js';
|
|
5
|
+
export { C as CMSSY_LOCALE_HEADER, a as localeForPath, b as localeForPathname, l as localizeHref, c as resolveSiteLocales, s as splitCmssyLocale, d as splitLocaleFromPath } from './locale-D9KI4bND.js';
|
|
6
|
+
import { Q as QueryScopedOptions } from './csp-BnOiGUhR.js';
|
|
7
|
+
export { u as cmssyCspHeaders, v as isDevelopment, w as resolveInitialTarget, x as toCspOrigin } from './csp-BnOiGUhR.js';
|
|
8
8
|
export { localizedPath } from './internal/locale.js';
|
|
9
9
|
|
|
10
10
|
declare const SITE_CONFIG_QUERY = "query PublicSiteConfig($workspaceSlug: String!) {\n public {\n siteConfig(workspaceSlug: $workspaceSlug) {\n id\n workspaceId\n siteName\n defaultLanguage\n enabledLanguages\n enabledFeatures\n notFoundPageId\n previewUrl\n branding {\n brandName\n logoUrl\n logoDarkUrl\n faviconUrl\n ogImageUrl\n }\n }\n }\n}";
|
package/dist/internal.js
CHANGED
|
@@ -2,15 +2,64 @@
|
|
|
2
2
|
var CmssyRequestError = class extends Error {
|
|
3
3
|
status;
|
|
4
4
|
retryAfterMs;
|
|
5
|
-
|
|
5
|
+
waitedMs;
|
|
6
|
+
constructor(message, status, retryAfterMs2, waitedMs) {
|
|
6
7
|
super(message);
|
|
7
8
|
this.name = "CmssyRequestError";
|
|
8
9
|
this.status = status;
|
|
9
10
|
if (retryAfterMs2 !== void 0) this.retryAfterMs = retryAfterMs2;
|
|
11
|
+
if (waitedMs !== void 0) this.waitedMs = waitedMs;
|
|
10
12
|
}
|
|
11
13
|
};
|
|
12
|
-
var
|
|
14
|
+
var THROTTLE_STATUS = 429;
|
|
13
15
|
var CMSSY_RATE_LIMIT_WINDOW_MS = 6e4;
|
|
16
|
+
var CMSSY_RETRY_MODES = {
|
|
17
|
+
build: {
|
|
18
|
+
maxRetries: 4,
|
|
19
|
+
baseDelayMs: 300,
|
|
20
|
+
throttleBaseDelayMs: 1e3,
|
|
21
|
+
maxDelayMs: 2e4,
|
|
22
|
+
maxRetryAfterMs: CMSSY_RATE_LIMIT_WINDOW_MS,
|
|
23
|
+
maxTotalWaitMs: 18e4,
|
|
24
|
+
retryStatuses: Object.freeze([429, 503])
|
|
25
|
+
},
|
|
26
|
+
interactive: {
|
|
27
|
+
maxRetries: 2,
|
|
28
|
+
baseDelayMs: 50,
|
|
29
|
+
throttleBaseDelayMs: 500,
|
|
30
|
+
maxDelayMs: 1e3,
|
|
31
|
+
maxRetryAfterMs: 1e3,
|
|
32
|
+
maxTotalWaitMs: 2e3,
|
|
33
|
+
retryStatuses: Object.freeze([429, 503])
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
Object.freeze(CMSSY_RETRY_MODES.build);
|
|
37
|
+
Object.freeze(CMSSY_RETRY_MODES.interactive);
|
|
38
|
+
Object.freeze(CMSSY_RETRY_MODES);
|
|
39
|
+
function resolveRetryPolicy(retry) {
|
|
40
|
+
if (retry === false || retry === void 0) return null;
|
|
41
|
+
if (typeof retry === "string") {
|
|
42
|
+
const mode = CMSSY_RETRY_MODES[retry];
|
|
43
|
+
if (!mode) {
|
|
44
|
+
throw new Error(
|
|
45
|
+
`cmssy: unknown retry mode "${retry}" - use ${Object.keys(
|
|
46
|
+
CMSSY_RETRY_MODES
|
|
47
|
+
).map((name2) => `"${name2}"`).join(" or ")}, false, or a retry policy object`
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
return mode;
|
|
51
|
+
}
|
|
52
|
+
const base = CMSSY_RETRY_MODES.build;
|
|
53
|
+
return {
|
|
54
|
+
maxRetries: retry.maxRetries ?? base.maxRetries,
|
|
55
|
+
baseDelayMs: retry.baseDelayMs ?? base.baseDelayMs,
|
|
56
|
+
throttleBaseDelayMs: retry.throttleBaseDelayMs ?? base.throttleBaseDelayMs,
|
|
57
|
+
maxDelayMs: retry.maxDelayMs ?? base.maxDelayMs,
|
|
58
|
+
maxRetryAfterMs: retry.maxRetryAfterMs ?? base.maxRetryAfterMs,
|
|
59
|
+
maxTotalWaitMs: retry.maxTotalWaitMs ?? base.maxTotalWaitMs,
|
|
60
|
+
retryStatuses: retry.retryStatuses ?? base.retryStatuses
|
|
61
|
+
};
|
|
62
|
+
}
|
|
14
63
|
function retryAfterMs(response) {
|
|
15
64
|
const raw = response.headers?.get("retry-after");
|
|
16
65
|
if (!raw) return null;
|
|
@@ -37,28 +86,40 @@ function sleep(ms, signal) {
|
|
|
37
86
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
38
87
|
});
|
|
39
88
|
}
|
|
40
|
-
async function fetchWithRetry(doFetch, url, init, retry) {
|
|
41
|
-
|
|
42
|
-
|
|
89
|
+
async function fetchWithRetry(doFetch, url, init, retry, label) {
|
|
90
|
+
const policy = resolveRetryPolicy(retry);
|
|
91
|
+
if (policy === null) {
|
|
92
|
+
return { response: await doFetch(url, init), waitedMs: 0 };
|
|
43
93
|
}
|
|
44
|
-
const maxRetries = retry.maxRetries ?? 3;
|
|
45
|
-
const baseDelayMs = retry.baseDelayMs ?? 300;
|
|
46
|
-
const maxDelayMs = retry.maxDelayMs ?? 3e3;
|
|
47
|
-
const maxRetryAfterMs = retry.maxRetryAfterMs ?? CMSSY_RATE_LIMIT_WINDOW_MS;
|
|
48
|
-
const retryStatuses = retry.retryStatuses ?? DEFAULT_RETRY_STATUSES;
|
|
49
94
|
let response = await doFetch(url, init);
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
95
|
+
let waitedMs = 0;
|
|
96
|
+
for (let attempt = 0; attempt < policy.maxRetries; attempt++) {
|
|
97
|
+
if (response.ok || !policy.retryStatuses.includes(response.status)) {
|
|
98
|
+
return { response, waitedMs };
|
|
53
99
|
}
|
|
100
|
+
const throttled = response.status === THROTTLE_STATUS;
|
|
54
101
|
const asked = retryAfterMs(response);
|
|
55
|
-
if (asked !== null && asked > maxRetryAfterMs)
|
|
56
|
-
|
|
57
|
-
|
|
102
|
+
if (asked !== null && asked > policy.maxRetryAfterMs) {
|
|
103
|
+
return { response, waitedMs };
|
|
104
|
+
}
|
|
105
|
+
const base = throttled ? policy.throttleBaseDelayMs : policy.baseDelayMs;
|
|
106
|
+
const wait = Math.round(
|
|
107
|
+
asked !== null ? Math.min(
|
|
108
|
+
asked + Math.random() * policy.throttleBaseDelayMs,
|
|
109
|
+
policy.maxRetryAfterMs
|
|
110
|
+
) : Math.random() * Math.min(base * 2 ** attempt, policy.maxDelayMs)
|
|
111
|
+
);
|
|
112
|
+
if (waitedMs + wait > policy.maxTotalWaitMs) {
|
|
113
|
+
return { response, waitedMs };
|
|
114
|
+
}
|
|
115
|
+
console.warn(
|
|
116
|
+
`[cmssy] ${label} got ${response.status}, retrying in ${wait}ms (attempt ${attempt + 1}/${policy.maxRetries})`
|
|
117
|
+
);
|
|
58
118
|
await sleep(wait, init.signal);
|
|
119
|
+
waitedMs += wait;
|
|
59
120
|
response = await doFetch(url, init);
|
|
60
121
|
}
|
|
61
|
-
return response;
|
|
122
|
+
return { response, waitedMs };
|
|
62
123
|
}
|
|
63
124
|
async function postGraphql(url, query, variables, options) {
|
|
64
125
|
const doFetch = options.fetch ?? globalThis.fetch;
|
|
@@ -67,7 +128,7 @@ async function postGraphql(url, query, variables, options) {
|
|
|
67
128
|
"cmssy: no fetch implementation available - pass options.fetch"
|
|
68
129
|
);
|
|
69
130
|
}
|
|
70
|
-
const response = await fetchWithRetry(
|
|
131
|
+
const { response, waitedMs } = await fetchWithRetry(
|
|
71
132
|
doFetch,
|
|
72
133
|
url,
|
|
73
134
|
{
|
|
@@ -76,7 +137,8 @@ async function postGraphql(url, query, variables, options) {
|
|
|
76
137
|
body: JSON.stringify({ query, variables }),
|
|
77
138
|
signal: options.signal
|
|
78
139
|
},
|
|
79
|
-
options.retry
|
|
140
|
+
options.retry,
|
|
141
|
+
options.label
|
|
80
142
|
);
|
|
81
143
|
if (!response.ok) {
|
|
82
144
|
let detail = "";
|
|
@@ -90,10 +152,12 @@ async function postGraphql(url, query, variables, options) {
|
|
|
90
152
|
}
|
|
91
153
|
const asked = retryAfterMs(response);
|
|
92
154
|
const wait = asked !== null ? ` - retry after ${Math.ceil(asked / 1e3)}s` : "";
|
|
155
|
+
const spent = waitedMs > 0 ? ` - gave up after waiting ${waitedMs}ms` : "";
|
|
93
156
|
throw new CmssyRequestError(
|
|
94
|
-
`cmssy: ${options.label} failed (${response.status})${detail}${wait}`,
|
|
157
|
+
`cmssy: ${options.label} failed (${response.status})${detail}${wait}${spent}`,
|
|
95
158
|
response.status,
|
|
96
|
-
asked ?? void 0
|
|
159
|
+
asked ?? void 0,
|
|
160
|
+
waitedMs > 0 ? waitedMs : void 0
|
|
97
161
|
);
|
|
98
162
|
}
|
|
99
163
|
let json;
|
|
@@ -230,7 +294,7 @@ async function fetchPage(config, path, options = {}) {
|
|
|
230
294
|
fetch: options.fetch,
|
|
231
295
|
signal: options.signal,
|
|
232
296
|
headers,
|
|
233
|
-
retry: options.retry ??
|
|
297
|
+
retry: options.retry ?? "build",
|
|
234
298
|
label: "page fetch"
|
|
235
299
|
}
|
|
236
300
|
);
|
|
@@ -253,7 +317,7 @@ async function fetchPageById(config, pageId, options = {}) {
|
|
|
253
317
|
{
|
|
254
318
|
fetch: options.fetch,
|
|
255
319
|
signal: options.signal,
|
|
256
|
-
retry: options.retry ??
|
|
320
|
+
retry: options.retry ?? "build",
|
|
257
321
|
label: "page-by-id fetch"
|
|
258
322
|
}
|
|
259
323
|
);
|
|
@@ -274,7 +338,7 @@ async function fetchPages(config, options = {}) {
|
|
|
274
338
|
{
|
|
275
339
|
fetch: options.fetch,
|
|
276
340
|
signal: options.signal,
|
|
277
|
-
retry: options.retry ??
|
|
341
|
+
retry: options.retry ?? "build",
|
|
278
342
|
label: "pages fetch"
|
|
279
343
|
}
|
|
280
344
|
);
|
|
@@ -289,7 +353,7 @@ async function fetchPageMeta(config, path, options = {}) {
|
|
|
289
353
|
{
|
|
290
354
|
fetch: options.fetch,
|
|
291
355
|
signal: options.signal,
|
|
292
|
-
retry: options.retry ??
|
|
356
|
+
retry: options.retry ?? "build",
|
|
293
357
|
label: "page meta fetch"
|
|
294
358
|
}
|
|
295
359
|
);
|
|
@@ -306,7 +370,7 @@ async function fetchLayouts(config, path, options = {}) {
|
|
|
306
370
|
{
|
|
307
371
|
fetch: options.fetch,
|
|
308
372
|
signal: options.signal,
|
|
309
|
-
retry: options.retry ??
|
|
373
|
+
retry: options.retry ?? "build",
|
|
310
374
|
label: "layouts fetch"
|
|
311
375
|
}
|
|
312
376
|
);
|
|
@@ -432,7 +496,7 @@ async function fetchSiteConfig(config, options = {}) {
|
|
|
432
496
|
config,
|
|
433
497
|
SITE_CONFIG_QUERY,
|
|
434
498
|
{ workspaceSlug: config.workspaceSlug },
|
|
435
|
-
{ ...options, public: true, retry: options.retry ??
|
|
499
|
+
{ ...options, public: true, retry: options.retry ?? "build" },
|
|
436
500
|
"site config query"
|
|
437
501
|
);
|
|
438
502
|
return data.public?.siteConfig ?? null;
|
|
@@ -970,7 +1034,7 @@ async function loadSiteLocales(config, options) {
|
|
|
970
1034
|
config,
|
|
971
1035
|
SITE_CONFIG_QUERY,
|
|
972
1036
|
{ workspaceSlug: config.workspaceSlug },
|
|
973
|
-
{ ...options, public: true, retry: options?.retry ??
|
|
1037
|
+
{ ...options, public: true, retry: options?.retry ?? "build" },
|
|
974
1038
|
"site config"
|
|
975
1039
|
);
|
|
976
1040
|
value = localesFromSiteConfig(data.public?.siteConfig ?? null);
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { CmssyClientConfig, CmssyLocaleContext, CmssySiteLocales } from '@cmssy/types';
|
|
2
|
-
import { F as FetchLike, R as
|
|
2
|
+
import { F as FetchLike, R as RetryOption } from './content-client-65N8ZRq9.js';
|
|
3
3
|
|
|
4
4
|
interface GraphqlRequestOptions {
|
|
5
5
|
fetch?: FetchLike;
|
|
6
6
|
signal?: AbortSignal;
|
|
7
7
|
headers?: Record<string, string>;
|
|
8
8
|
public?: boolean;
|
|
9
|
-
retry?:
|
|
9
|
+
retry?: RetryOption;
|
|
10
10
|
}
|
|
11
11
|
declare function graphqlRequest<T>(config: CmssyClientConfig, query: string, variables: Record<string, unknown>, options?: GraphqlRequestOptions, label?: string): Promise<T>;
|
|
12
12
|
|