utils.mjs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. // TYPES
  2. // UTILS
  3. const isServer = typeof window === 'undefined' || 'Deno' in window;
  4. function noop() {
  5. return undefined;
  6. }
  7. function functionalUpdate(updater, input) {
  8. return typeof updater === 'function' ? updater(input) : updater;
  9. }
  10. function isValidTimeout(value) {
  11. return typeof value === 'number' && value >= 0 && value !== Infinity;
  12. }
  13. function difference(array1, array2) {
  14. return array1.filter(x => !array2.includes(x));
  15. }
  16. function replaceAt(array, index, value) {
  17. const copy = array.slice(0);
  18. copy[index] = value;
  19. return copy;
  20. }
  21. function timeUntilStale(updatedAt, staleTime) {
  22. return Math.max(updatedAt + (staleTime || 0) - Date.now(), 0);
  23. }
  24. function parseQueryArgs(arg1, arg2, arg3) {
  25. if (!isQueryKey(arg1)) {
  26. return arg1;
  27. }
  28. if (typeof arg2 === 'function') {
  29. return { ...arg3,
  30. queryKey: arg1,
  31. queryFn: arg2
  32. };
  33. }
  34. return { ...arg2,
  35. queryKey: arg1
  36. };
  37. }
  38. function parseMutationArgs(arg1, arg2, arg3) {
  39. if (isQueryKey(arg1)) {
  40. if (typeof arg2 === 'function') {
  41. return { ...arg3,
  42. mutationKey: arg1,
  43. mutationFn: arg2
  44. };
  45. }
  46. return { ...arg2,
  47. mutationKey: arg1
  48. };
  49. }
  50. if (typeof arg1 === 'function') {
  51. return { ...arg2,
  52. mutationFn: arg1
  53. };
  54. }
  55. return { ...arg1
  56. };
  57. }
  58. function parseFilterArgs(arg1, arg2, arg3) {
  59. return isQueryKey(arg1) ? [{ ...arg2,
  60. queryKey: arg1
  61. }, arg3] : [arg1 || {}, arg2];
  62. }
  63. function parseMutationFilterArgs(arg1, arg2, arg3) {
  64. return isQueryKey(arg1) ? [{ ...arg2,
  65. mutationKey: arg1
  66. }, arg3] : [arg1 || {}, arg2];
  67. }
  68. function matchQuery(filters, query) {
  69. const {
  70. type = 'all',
  71. exact,
  72. fetchStatus,
  73. predicate,
  74. queryKey,
  75. stale
  76. } = filters;
  77. if (isQueryKey(queryKey)) {
  78. if (exact) {
  79. if (query.queryHash !== hashQueryKeyByOptions(queryKey, query.options)) {
  80. return false;
  81. }
  82. } else if (!partialMatchKey(query.queryKey, queryKey)) {
  83. return false;
  84. }
  85. }
  86. if (type !== 'all') {
  87. const isActive = query.isActive();
  88. if (type === 'active' && !isActive) {
  89. return false;
  90. }
  91. if (type === 'inactive' && isActive) {
  92. return false;
  93. }
  94. }
  95. if (typeof stale === 'boolean' && query.isStale() !== stale) {
  96. return false;
  97. }
  98. if (typeof fetchStatus !== 'undefined' && fetchStatus !== query.state.fetchStatus) {
  99. return false;
  100. }
  101. if (predicate && !predicate(query)) {
  102. return false;
  103. }
  104. return true;
  105. }
  106. function matchMutation(filters, mutation) {
  107. const {
  108. exact,
  109. fetching,
  110. predicate,
  111. mutationKey
  112. } = filters;
  113. if (isQueryKey(mutationKey)) {
  114. if (!mutation.options.mutationKey) {
  115. return false;
  116. }
  117. if (exact) {
  118. if (hashQueryKey(mutation.options.mutationKey) !== hashQueryKey(mutationKey)) {
  119. return false;
  120. }
  121. } else if (!partialMatchKey(mutation.options.mutationKey, mutationKey)) {
  122. return false;
  123. }
  124. }
  125. if (typeof fetching === 'boolean' && mutation.state.status === 'loading' !== fetching) {
  126. return false;
  127. }
  128. if (predicate && !predicate(mutation)) {
  129. return false;
  130. }
  131. return true;
  132. }
  133. function hashQueryKeyByOptions(queryKey, options) {
  134. const hashFn = (options == null ? void 0 : options.queryKeyHashFn) || hashQueryKey;
  135. return hashFn(queryKey);
  136. }
  137. /**
  138. * Default query keys hash function.
  139. * Hashes the value into a stable hash.
  140. */
  141. function hashQueryKey(queryKey) {
  142. return JSON.stringify(queryKey, (_, val) => isPlainObject(val) ? Object.keys(val).sort().reduce((result, key) => {
  143. result[key] = val[key];
  144. return result;
  145. }, {}) : val);
  146. }
  147. /**
  148. * Checks if key `b` partially matches with key `a`.
  149. */
  150. function partialMatchKey(a, b) {
  151. return partialDeepEqual(a, b);
  152. }
  153. /**
  154. * Checks if `b` partially matches with `a`.
  155. */
  156. function partialDeepEqual(a, b) {
  157. if (a === b) {
  158. return true;
  159. }
  160. if (typeof a !== typeof b) {
  161. return false;
  162. }
  163. if (a && b && typeof a === 'object' && typeof b === 'object') {
  164. return !Object.keys(b).some(key => !partialDeepEqual(a[key], b[key]));
  165. }
  166. return false;
  167. }
  168. /**
  169. * This function returns `a` if `b` is deeply equal.
  170. * If not, it will replace any deeply equal children of `b` with those of `a`.
  171. * This can be used for structural sharing between JSON values for example.
  172. */
  173. function replaceEqualDeep(a, b) {
  174. if (a === b) {
  175. return a;
  176. }
  177. const array = isPlainArray(a) && isPlainArray(b);
  178. if (array || isPlainObject(a) && isPlainObject(b)) {
  179. const aSize = array ? a.length : Object.keys(a).length;
  180. const bItems = array ? b : Object.keys(b);
  181. const bSize = bItems.length;
  182. const copy = array ? [] : {};
  183. let equalItems = 0;
  184. for (let i = 0; i < bSize; i++) {
  185. const key = array ? i : bItems[i];
  186. copy[key] = replaceEqualDeep(a[key], b[key]);
  187. if (copy[key] === a[key]) {
  188. equalItems++;
  189. }
  190. }
  191. return aSize === bSize && equalItems === aSize ? a : copy;
  192. }
  193. return b;
  194. }
  195. /**
  196. * Shallow compare objects. Only works with objects that always have the same properties.
  197. */
  198. function shallowEqualObjects(a, b) {
  199. if (a && !b || b && !a) {
  200. return false;
  201. }
  202. for (const key in a) {
  203. if (a[key] !== b[key]) {
  204. return false;
  205. }
  206. }
  207. return true;
  208. }
  209. function isPlainArray(value) {
  210. return Array.isArray(value) && value.length === Object.keys(value).length;
  211. } // Copied from: https://github.com/jonschlinkert/is-plain-object
  212. function isPlainObject(o) {
  213. if (!hasObjectPrototype(o)) {
  214. return false;
  215. } // If has modified constructor
  216. const ctor = o.constructor;
  217. if (typeof ctor === 'undefined') {
  218. return true;
  219. } // If has modified prototype
  220. const prot = ctor.prototype;
  221. if (!hasObjectPrototype(prot)) {
  222. return false;
  223. } // If constructor does not have an Object-specific method
  224. if (!prot.hasOwnProperty('isPrototypeOf')) {
  225. return false;
  226. } // Most likely a plain Object
  227. return true;
  228. }
  229. function hasObjectPrototype(o) {
  230. return Object.prototype.toString.call(o) === '[object Object]';
  231. }
  232. function isQueryKey(value) {
  233. return Array.isArray(value);
  234. }
  235. function isError(value) {
  236. return value instanceof Error;
  237. }
  238. function sleep(timeout) {
  239. return new Promise(resolve => {
  240. setTimeout(resolve, timeout);
  241. });
  242. }
  243. /**
  244. * Schedules a microtask.
  245. * This can be useful to schedule state updates after rendering.
  246. */
  247. function scheduleMicrotask(callback) {
  248. sleep(0).then(callback);
  249. }
  250. function getAbortController() {
  251. if (typeof AbortController === 'function') {
  252. return new AbortController();
  253. }
  254. return;
  255. }
  256. function replaceData(prevData, data, options) {
  257. // Use prev data if an isDataEqual function is defined and returns `true`
  258. if (options.isDataEqual != null && options.isDataEqual(prevData, data)) {
  259. return prevData;
  260. } else if (typeof options.structuralSharing === 'function') {
  261. return options.structuralSharing(prevData, data);
  262. } else if (options.structuralSharing !== false) {
  263. // Structurally share data between prev and new data if needed
  264. return replaceEqualDeep(prevData, data);
  265. }
  266. return data;
  267. }
  268. export { difference, functionalUpdate, getAbortController, hashQueryKey, hashQueryKeyByOptions, isError, isPlainArray, isPlainObject, isQueryKey, isServer, isValidTimeout, matchMutation, matchQuery, noop, parseFilterArgs, parseMutationArgs, parseMutationFilterArgs, parseQueryArgs, partialDeepEqual, partialMatchKey, replaceAt, replaceData, replaceEqualDeep, scheduleMicrotask, shallowEqualObjects, sleep, timeUntilStale };
  269. //# sourceMappingURL=utils.mjs.map