@sanity/client 6.20.0 → 6.20.2-beta.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/index.browser.cjs +61 -7
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.d.cts +7 -0
- package/dist/index.browser.d.ts +7 -0
- package/dist/index.browser.js +61 -7
- package/dist/index.browser.js.map +1 -1
- package/dist/index.cjs +62 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +62 -7
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/src/config.ts +5 -0
- package/src/data/listen.ts +13 -1
- package/src/defineCreateClient.ts +1 -0
- package/src/http/browserMiddleware.ts +3 -1
- package/src/http/domainSharding.ts +96 -0
- package/src/http/nodeMiddleware.ts +3 -0
- package/src/types.ts +8 -0
- package/src/warnings.ts +5 -0
- package/umd/sanityClient.js +75 -26
- package/umd/sanityClient.min.js +3 -3
package/dist/index.browser.d.cts
CHANGED
|
@@ -336,6 +336,13 @@ export declare interface ClientConfig {
|
|
|
336
336
|
apiHost?: string
|
|
337
337
|
apiVersion?: string
|
|
338
338
|
proxy?: string
|
|
339
|
+
/**
|
|
340
|
+
* Spread the requests over a number of hostnames to work around HTTP/1.1 limitations.
|
|
341
|
+
* Only applicable in browsers, and for certain allowed projects.
|
|
342
|
+
*
|
|
343
|
+
* @alpha
|
|
344
|
+
*/
|
|
345
|
+
useDomainSharding?: boolean
|
|
339
346
|
/**
|
|
340
347
|
* Optional request tag prefix for all request tags
|
|
341
348
|
*/
|
package/dist/index.browser.d.ts
CHANGED
|
@@ -336,6 +336,13 @@ export declare interface ClientConfig {
|
|
|
336
336
|
apiHost?: string
|
|
337
337
|
apiVersion?: string
|
|
338
338
|
proxy?: string
|
|
339
|
+
/**
|
|
340
|
+
* Spread the requests over a number of hostnames to work around HTTP/1.1 limitations.
|
|
341
|
+
* Only applicable in browsers, and for certain allowed projects.
|
|
342
|
+
*
|
|
343
|
+
* @alpha
|
|
344
|
+
*/
|
|
345
|
+
useDomainSharding?: boolean
|
|
339
346
|
/**
|
|
340
347
|
* Optional request tag prefix for all request tags
|
|
341
348
|
*/
|
package/dist/index.browser.js
CHANGED
|
@@ -491,7 +491,10 @@ function once(fn) {
|
|
|
491
491
|
const createWarningPrinter = (message) => (
|
|
492
492
|
// eslint-disable-next-line no-console
|
|
493
493
|
once((...args) => console.warn(message.join(" "), ...args))
|
|
494
|
-
),
|
|
494
|
+
), printCdnAndWithCredentialsWarning = createWarningPrinter([
|
|
495
|
+
"Because you set `withCredentials` to true, we will override your `useCdn`",
|
|
496
|
+
"setting to be false since (cookie-based) credentials are never set on the CDN"
|
|
497
|
+
]), printCdnWarning = createWarningPrinter([
|
|
495
498
|
"Since you haven't set a value for `useCdn`, we will deliver content using our",
|
|
496
499
|
"global, edge-cached API-CDN. If you wish to have content delivered faster, set",
|
|
497
500
|
"`useCdn: false` to use the Live API. Note: You may incur higher costs using the live API."
|
|
@@ -569,7 +572,7 @@ const validateApiPerspective = function(perspective) {
|
|
|
569
572
|
`stega.studioUrl must be a string or a function, received ${newConfig.stega.studioUrl}`
|
|
570
573
|
);
|
|
571
574
|
const isBrowser = typeof window < "u" && window.location && window.location.hostname, isLocalhost = isBrowser && isLocal(window.location.hostname);
|
|
572
|
-
isBrowser && isLocalhost && newConfig.token && newConfig.ignoreBrowserTokenWarning !== !0 ? printBrowserTokenWarning() : typeof newConfig.useCdn > "u" && printCdnWarning(), projectBased && projectId(newConfig.projectId), newConfig.dataset && dataset(newConfig.dataset), "requestTagPrefix" in newConfig && (newConfig.requestTagPrefix = newConfig.requestTagPrefix ? requestTag(newConfig.requestTagPrefix).replace(/\.+$/, "") : void 0), newConfig.apiVersion = `${newConfig.apiVersion}`.replace(/^v/, ""), newConfig.isDefaultApi = newConfig.apiHost === defaultConfig.apiHost, newConfig.useCdn = newConfig.useCdn !== !1 && !newConfig.withCredentials, validateApiVersion(newConfig.apiVersion);
|
|
575
|
+
isBrowser && isLocalhost && newConfig.token && newConfig.ignoreBrowserTokenWarning !== !0 ? printBrowserTokenWarning() : typeof newConfig.useCdn > "u" && printCdnWarning(), projectBased && projectId(newConfig.projectId), newConfig.dataset && dataset(newConfig.dataset), "requestTagPrefix" in newConfig && (newConfig.requestTagPrefix = newConfig.requestTagPrefix ? requestTag(newConfig.requestTagPrefix).replace(/\.+$/, "") : void 0), newConfig.apiVersion = `${newConfig.apiVersion}`.replace(/^v/, ""), newConfig.isDefaultApi = newConfig.apiHost === defaultConfig.apiHost, newConfig.useCdn === !0 && newConfig.withCredentials && printCdnAndWithCredentialsWarning(), newConfig.useCdn = newConfig.useCdn !== !1 && !newConfig.withCredentials, validateApiVersion(newConfig.apiVersion);
|
|
573
576
|
const hostParts = newConfig.apiHost.split("://", 2), protocol = hostParts[0], host = hostParts[1], cdnHost = newConfig.isDefaultApi ? defaultCdnHost : host;
|
|
574
577
|
return newConfig.useProjectHostname ? (newConfig.url = `${protocol}://${newConfig.projectId}.${host}/v${newConfig.apiVersion}`, newConfig.cdnUrl = `${protocol}://${newConfig.projectId}.${cdnHost}/v${newConfig.apiVersion}`) : (newConfig.url = `${newConfig.apiHost}/v${newConfig.apiVersion}`, newConfig.cdnUrl = newConfig.url), newConfig;
|
|
575
578
|
}, projectHeader = "X-Sanity-Project-ID";
|
|
@@ -852,6 +855,55 @@ function optionsFromFile(opts, file) {
|
|
|
852
855
|
opts
|
|
853
856
|
);
|
|
854
857
|
}
|
|
858
|
+
const UNSHARDED_URL_RE = /^https:\/\/([a-z0-9]+)\.api\.(sanity\..*)/, SHARDED_URL_RE = /^https:\/\/[a-z0-9]+\.api\.s(\d+)\.sanity\.(.*)/, domainSharder = getDomainSharder();
|
|
859
|
+
function getDomainSharder(initialBuckets) {
|
|
860
|
+
const buckets = new Array(10).fill(0, 0);
|
|
861
|
+
function incrementBucketForUrl(url) {
|
|
862
|
+
const shard = getShardFromUrl(url);
|
|
863
|
+
shard !== null && buckets[shard]++;
|
|
864
|
+
}
|
|
865
|
+
function decrementBucketForUrl(url) {
|
|
866
|
+
const shard = getShardFromUrl(url);
|
|
867
|
+
shard !== null && buckets[shard]--;
|
|
868
|
+
}
|
|
869
|
+
function getShardedUrl(url) {
|
|
870
|
+
const [isMatch, projectId2, rest] = url.match(UNSHARDED_URL_RE) || [];
|
|
871
|
+
if (!isMatch)
|
|
872
|
+
return url;
|
|
873
|
+
const bucket = buckets.reduce(
|
|
874
|
+
(smallest, count, index) => count < buckets[smallest] ? index : smallest,
|
|
875
|
+
0
|
|
876
|
+
);
|
|
877
|
+
return `https://${projectId2}.api.s${bucket}.${rest}`;
|
|
878
|
+
}
|
|
879
|
+
function getShardFromUrl(url) {
|
|
880
|
+
const [isMatch, shard] = url.match(SHARDED_URL_RE) || [];
|
|
881
|
+
return isMatch ? parseInt(shard, 10) : null;
|
|
882
|
+
}
|
|
883
|
+
return {
|
|
884
|
+
middleware: {
|
|
885
|
+
processOptions: (options) => {
|
|
886
|
+
if (!useDomainSharding(options))
|
|
887
|
+
return options;
|
|
888
|
+
const url = getShardedUrl(options.url);
|
|
889
|
+
return options.url = url, options;
|
|
890
|
+
},
|
|
891
|
+
onRequest(req) {
|
|
892
|
+
return useDomainSharding(req.options) && incrementBucketForUrl(req.options.url), req;
|
|
893
|
+
},
|
|
894
|
+
onResponse(res, context) {
|
|
895
|
+
return useDomainSharding(context.options) && decrementBucketForUrl(context.options.url), res;
|
|
896
|
+
}
|
|
897
|
+
},
|
|
898
|
+
incrementBucketForUrl,
|
|
899
|
+
decrementBucketForUrl,
|
|
900
|
+
getShardedUrl,
|
|
901
|
+
getBuckets: () => buckets
|
|
902
|
+
};
|
|
903
|
+
}
|
|
904
|
+
function useDomainSharding(options) {
|
|
905
|
+
return "useDomainSharding" in options && options.useDomainSharding === !0;
|
|
906
|
+
}
|
|
855
907
|
var defaults = (obj, defaults2) => Object.keys(defaults2).concat(Object.keys(obj)).reduce((target, prop) => (target[prop] = typeof obj[prop] > "u" ? defaults2[prop] : obj[prop], target), {});
|
|
856
908
|
const pick = (obj, props) => props.reduce((selection, prop) => (typeof obj[prop] > "u" || (selection[prop] = obj[prop]), selection), {}), MAX_URL_LENGTH = 14800, possibleOptions = [
|
|
857
909
|
"includePreviousRevision",
|
|
@@ -863,15 +915,16 @@ const pick = (obj, props) => props.reduce((selection, prop) => (typeof obj[prop]
|
|
|
863
915
|
includeResult: !0
|
|
864
916
|
};
|
|
865
917
|
function _listen(query, params, opts = {}) {
|
|
866
|
-
const { url, token, withCredentials, requestTagPrefix } = this.config(), tag = opts.tag && requestTagPrefix ? [requestTagPrefix, opts.tag].join(".") : opts.tag, options = { ...defaults(opts, defaultOptions), tag }, listenOpts = pick(options, possibleOptions), qs = encodeQueryString({ query, params, options: { tag, ...listenOpts } })
|
|
867
|
-
|
|
918
|
+
const { url, token, withCredentials, requestTagPrefix } = this.config(), tag = opts.tag && requestTagPrefix ? [requestTagPrefix, opts.tag].join(".") : opts.tag, options = { ...defaults(opts, defaultOptions), tag }, listenOpts = pick(options, possibleOptions), qs = encodeQueryString({ query, params, options: { tag, ...listenOpts } });
|
|
919
|
+
let uri = `${url}${_getDataUrl(this, "listen", qs)}`;
|
|
920
|
+
if (this.config().useDomainSharding && (uri = domainSharder.getShardedUrl(uri)), uri.length > MAX_URL_LENGTH)
|
|
868
921
|
return new Observable((observer) => observer.error(new Error("Query too large for listener")));
|
|
869
922
|
const listenFor = options.events ? options.events : ["mutation"], shouldEmitReconnect = listenFor.indexOf("reconnect") !== -1, esOptions = {};
|
|
870
923
|
return (token || withCredentials) && (esOptions.withCredentials = !0), token && (esOptions.headers = {
|
|
871
924
|
Authorization: `Bearer ${token}`
|
|
872
925
|
}), new Observable((observer) => {
|
|
873
926
|
let es, reconnectTimer, stopped = !1, unsubscribed = !1;
|
|
874
|
-
open();
|
|
927
|
+
domainSharder.incrementBucketForUrl(uri), open();
|
|
875
928
|
function onError() {
|
|
876
929
|
stopped || (emitReconnect(), !stopped && es.readyState === es.CLOSED && (unsubscribe(), clearTimeout(reconnectTimer), reconnectTimer = setTimeout(open, 100)));
|
|
877
930
|
}
|
|
@@ -906,7 +959,7 @@ function _listen(query, params, opts = {}) {
|
|
|
906
959
|
});
|
|
907
960
|
}
|
|
908
961
|
function stop() {
|
|
909
|
-
stopped = !0, unsubscribe(), unsubscribed = !0;
|
|
962
|
+
stopped = !0, unsubscribe(), unsubscribed = !0, domainSharder.decrementBucketForUrl(uri);
|
|
910
963
|
}
|
|
911
964
|
return stop;
|
|
912
965
|
});
|
|
@@ -1517,6 +1570,7 @@ function defineCreateClientExports(envMiddleware2, ClassConstructor) {
|
|
|
1517
1570
|
maxRedirects: 0,
|
|
1518
1571
|
maxRetries: config.maxRetries,
|
|
1519
1572
|
retryDelay: config.retryDelay,
|
|
1573
|
+
useDomainSharding: config.useDomainSharding,
|
|
1520
1574
|
...options
|
|
1521
1575
|
}),
|
|
1522
1576
|
config
|
|
@@ -1527,7 +1581,7 @@ function defineDeprecatedCreateClient(createClient2) {
|
|
|
1527
1581
|
return printNoDefaultExport(), createClient2(config);
|
|
1528
1582
|
};
|
|
1529
1583
|
}
|
|
1530
|
-
var envMiddleware = [];
|
|
1584
|
+
var envMiddleware = [domainSharder.middleware];
|
|
1531
1585
|
const exp = defineCreateClientExports(envMiddleware, SanityClient), requester = exp.requester, createClient = exp.createClient, deprecatedCreateClient = defineDeprecatedCreateClient(createClient);
|
|
1532
1586
|
export {
|
|
1533
1587
|
BasePatch,
|