@urql/exchange-request-policy
Version:
An exchange for operation request-policy upgrading in urql
78 lines (72 loc) • 2.92 kB
JavaScript
Object.defineProperty(exports, '__esModule', { value: true });
var core = require('@urql/core');
var wonka = require('wonka');
var defaultTTL = 5 * 60 * 1000;
/** Input parameters for the {@link requestPolicyExchange}. */
/** Exchange factory that upgrades request policies to `cache-and-network` for queries outside of a defined `ttl`.
*
* @param options - An {@link Options} configuration object.
* @returns the created request-policy {@link Exchange}.
*
* @remarks
* The `requestPolicyExchange` upgrades query operations based on {@link Options.ttl}.
* The `ttl` defines a timeframe outside of which a query's request policy is set to
* `cache-and-network` to refetch it in the background.
*
* You may define a {@link Options.shouldUpgrade} function to selectively ignore some
* operations by returning `false` there.
*
* @example
* ```ts
* requestPolicyExchange({
* // Upgrade when we haven't seen this operation for 1 second
* ttl: 1000,
* // and only upgrade operations that query the `todos` field.
* shouldUpgrade: op => op.kind === 'query' && op.query.definitions[0].name?.value === 'todos'
* });
* ```
*/
var requestPolicyExchange = options => ({
forward
}) => {
var operations = new Map();
var TTL = (options || {}).ttl || defaultTTL;
var dispatched = new Map();
var counter = 0;
var processIncomingOperation = operation => {
if (operation.kind !== 'query' || operation.context.requestPolicy !== 'cache-first' && operation.context.requestPolicy !== 'cache-only') {
return operation;
}
var currentTime = new Date().getTime();
// When an operation passes by we track the current time
dispatched.set(operation.key, counter);
queueMicrotask(() => {
counter = counter + 1 | 0;
});
var lastOccurrence = operations.get(operation.key) || 0;
if (currentTime - lastOccurrence > TTL && (!options.shouldUpgrade || options.shouldUpgrade(operation))) {
return core.makeOperation(operation.kind, operation, {
...operation.context,
requestPolicy: 'cache-and-network'
});
}
return operation;
};
var processIncomingResults = result => {
// When we get a result for the operation we check whether it resolved
// synchronously by checking whether the counter is different from the
// dispatched counter.
var lastDispatched = dispatched.get(result.operation.key) || 0;
if (counter !== lastDispatched) {
// We only delete in the case of a miss to ensure that cache-and-network
// is properly taken care of
dispatched.delete(result.operation.key);
operations.set(result.operation.key, new Date().getTime());
}
};
return ops$ => {
return wonka.tap(processIncomingResults)(forward(wonka.map(processIncomingOperation)(ops$)));
};
};
exports.requestPolicyExchange = requestPolicyExchange;
//# sourceMappingURL=urql-exchange-request-policy.js.map