UNPKG

@urql/exchange-request-policy

Version:

An exchange for operation request-policy upgrading in urql

78 lines (72 loc) 2.92 kB
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