react-redux-cache 0.19.2 → 0.19.4-rc.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.
Files changed (57) hide show
  1. package/README.md +25 -7
  2. package/dist/cjs/createActions.js +65 -0
  3. package/dist/cjs/createCache.js +208 -0
  4. package/dist/cjs/createCacheReducer.js +285 -0
  5. package/dist/cjs/createSelectors.js +68 -0
  6. package/dist/cjs/index.js +83 -0
  7. package/dist/cjs/mutate.js +161 -0
  8. package/dist/cjs/query.js +180 -0
  9. package/dist/cjs/types.js +2 -0
  10. package/dist/cjs/useMutation.js +82 -0
  11. package/dist/cjs/useQuery.js +121 -0
  12. package/dist/cjs/utilsAndConstants.js +189 -0
  13. package/dist/esm/createActions.js +61 -0
  14. package/dist/esm/createCache.js +203 -0
  15. package/dist/esm/createCacheReducer.js +271 -0
  16. package/dist/esm/createSelectors.js +64 -0
  17. package/dist/esm/index.js +3 -0
  18. package/dist/esm/mutate.js +157 -0
  19. package/dist/esm/query.js +169 -0
  20. package/dist/esm/types.js +1 -0
  21. package/dist/esm/useMutation.js +88 -0
  22. package/dist/esm/useQuery.js +125 -0
  23. package/dist/esm/utilsAndConstants.js +168 -0
  24. package/dist/types/createActions.d.ts +106 -0
  25. package/dist/types/createCache.d.ts +712 -0
  26. package/dist/types/createCacheReducer.d.ts +11 -0
  27. package/dist/types/createSelectors.d.ts +79 -0
  28. package/dist/types/index.d.ts +3 -0
  29. package/dist/types/mutate.d.ts +94 -0
  30. package/dist/types/query.d.ts +122 -0
  31. package/dist/types/types.d.ts +322 -0
  32. package/dist/types/useMutation.d.ts +39 -0
  33. package/dist/types/useQuery.d.ts +40 -0
  34. package/dist/types/utilsAndConstants.d.ts +39 -0
  35. package/package.json +22 -10
  36. package/dist/createActions.d.ts +0 -83
  37. package/dist/createActions.js +0 -64
  38. package/dist/createCache.d.ts +0 -378
  39. package/dist/createCache.js +0 -185
  40. package/dist/createCacheReducer.d.ts +0 -3
  41. package/dist/createCacheReducer.js +0 -243
  42. package/dist/createSelectors.d.ts +0 -18
  43. package/dist/createSelectors.js +0 -61
  44. package/dist/index.d.ts +0 -3
  45. package/dist/index.js +0 -53
  46. package/dist/mutate.d.ts +0 -4
  47. package/dist/mutate.js +0 -98
  48. package/dist/query.d.ts +0 -4
  49. package/dist/query.js +0 -107
  50. package/dist/types.d.ts +0 -187
  51. package/dist/types.js +0 -3
  52. package/dist/useMutation.d.ts +0 -4
  53. package/dist/useMutation.js +0 -61
  54. package/dist/useQuery.d.ts +0 -4
  55. package/dist/useQuery.js +0 -77
  56. package/dist/utilsAndConstants.d.ts +0 -20
  57. package/dist/utilsAndConstants.js +0 -161
@@ -0,0 +1,88 @@
1
+ var __awaiter =
2
+ (this && this.__awaiter) ||
3
+ function (thisArg, _arguments, P, generator) {
4
+ function adopt(value) {
5
+ return value instanceof P
6
+ ? value
7
+ : new P(function (resolve) {
8
+ resolve(value)
9
+ })
10
+ }
11
+ return new (P || (P = Promise))(function (resolve, reject) {
12
+ function fulfilled(value) {
13
+ try {
14
+ step(generator.next(value))
15
+ } catch (e) {
16
+ reject(e)
17
+ }
18
+ }
19
+ function rejected(value) {
20
+ try {
21
+ step(generator['throw'](value))
22
+ } catch (e) {
23
+ reject(e)
24
+ }
25
+ }
26
+ function step(result) {
27
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected)
28
+ }
29
+ step((generator = generator.apply(thisArg, _arguments || [])).next())
30
+ })
31
+ }
32
+ import {useMemo} from 'react'
33
+
34
+ import {mutate as mutateImpl} from './mutate'
35
+ import {EMPTY_OBJECT, log} from './utilsAndConstants'
36
+
37
+ export const useMutation = (cache, actions, selectors, options, abortControllers) => {
38
+ var _a
39
+ const {mutation: mutationKey, onCompleted, onSuccess, onError} = options
40
+ const store = cache.storeHooks.useStore()
41
+ const [mutationStateSelector, mutate, abort] = useMemo(() => {
42
+ return [
43
+ (state) => {
44
+ cache.options.logsEnabled &&
45
+ log('mutationStateSelector', {
46
+ state,
47
+ cacheState: cache.cacheStateSelector(state),
48
+ })
49
+ return cache.cacheStateSelector(state).mutations[mutationKey]
50
+ },
51
+ (params) =>
52
+ __awaiter(void 0, void 0, void 0, function* () {
53
+ return yield mutateImpl(
54
+ 'useMutation.mutate',
55
+ store,
56
+ cache,
57
+ actions,
58
+ selectors,
59
+ mutationKey,
60
+ params,
61
+ abortControllers,
62
+ onCompleted,
63
+ onSuccess,
64
+ onError
65
+ )
66
+ }),
67
+ () => {
68
+ var _a
69
+ const abortController =
70
+ (_a = abortControllers.get(store)) === null || _a === void 0 ? void 0 : _a[mutationKey]
71
+ if (abortController === undefined || abortController.signal.aborted) {
72
+ return false
73
+ }
74
+ abortController.abort()
75
+ store.dispatch(actions.updateMutationStateAndEntities(mutationKey, {loading: undefined}))
76
+ return true
77
+ },
78
+ ]
79
+ }, [mutationKey, store])
80
+ const mutationState =
81
+ (_a = cache.storeHooks.useSelector(mutationStateSelector)) !== null && _a !== void 0 ? _a : EMPTY_OBJECT
82
+ cache.options.logsEnabled &&
83
+ log('useMutation', {
84
+ options,
85
+ mutationState,
86
+ })
87
+ return [mutate, mutationState, abort]
88
+ }
@@ -0,0 +1,125 @@
1
+ var __awaiter =
2
+ (this && this.__awaiter) ||
3
+ function (thisArg, _arguments, P, generator) {
4
+ function adopt(value) {
5
+ return value instanceof P
6
+ ? value
7
+ : new P(function (resolve) {
8
+ resolve(value)
9
+ })
10
+ }
11
+ return new (P || (P = Promise))(function (resolve, reject) {
12
+ function fulfilled(value) {
13
+ try {
14
+ step(generator.next(value))
15
+ } catch (e) {
16
+ reject(e)
17
+ }
18
+ }
19
+ function rejected(value) {
20
+ try {
21
+ step(generator['throw'](value))
22
+ } catch (e) {
23
+ reject(e)
24
+ }
25
+ }
26
+ function step(result) {
27
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected)
28
+ }
29
+ step((generator = generator.apply(thisArg, _arguments || [])).next())
30
+ })
31
+ }
32
+ import {useCallback, useEffect} from 'react'
33
+
34
+ import {query as queryImpl} from './query'
35
+ import {createStateComparer, defaultGetCacheKey, EMPTY_OBJECT, log} from './utilsAndConstants'
36
+
37
+ export const useQuery = (cache, actions, selectors, options) => {
38
+ var _a, _b, _c, _d, _e
39
+ const {
40
+ query: queryKey,
41
+ skipFetch = false,
42
+ params,
43
+ secondsToLive,
44
+ selectorComparer,
45
+ fetchPolicy = (_a = cache.queries[queryKey].fetchPolicy) !== null && _a !== void 0
46
+ ? _a
47
+ : cache.globals.queries.fetchPolicy,
48
+ mergeResults,
49
+ onCompleted,
50
+ onSuccess,
51
+ onError,
52
+ } = options
53
+ const {selectQueryState} = selectors
54
+ const queryInfo = cache.queries[queryKey]
55
+ const logsEnabled = cache.options.logsEnabled
56
+ const getCacheKey = (_b = queryInfo.getCacheKey) !== null && _b !== void 0 ? _b : defaultGetCacheKey
57
+ const comparer =
58
+ selectorComparer === undefined
59
+ ? (_d =
60
+ (_c = queryInfo.selectorComparer) !== null && _c !== void 0
61
+ ? _c
62
+ : cache.globals.queries.selectorComparer) !== null && _d !== void 0
63
+ ? _d
64
+ : defaultStateComparer
65
+ : typeof selectorComparer === 'function'
66
+ ? selectorComparer
67
+ : createStateComparer(selectorComparer)
68
+ const store = cache.storeHooks.useStore()
69
+ const cacheKey = getCacheKey(params)
70
+ const performFetch = useCallback(
71
+ (options) =>
72
+ __awaiter(void 0, void 0, void 0, function* () {
73
+ const paramsPassed = options && 'params' in options
74
+ return yield queryImpl(
75
+ 'useQuery.fetch',
76
+ store,
77
+ cache,
78
+ actions,
79
+ selectors,
80
+ queryKey,
81
+ paramsPassed ? getCacheKey(options.params) : cacheKey,
82
+ paramsPassed ? options.params : params,
83
+ secondsToLive,
84
+ options === null || options === void 0 ? void 0 : options.onlyIfExpired,
85
+ mergeResults,
86
+ onCompleted,
87
+ onSuccess,
88
+ onError
89
+ )
90
+ }),
91
+ [store, queryKey, cacheKey]
92
+ )
93
+ const queryState =
94
+ (_e = cache.storeHooks.useSelector((state) => {
95
+ return selectQueryState(state, queryKey, cacheKey)
96
+ }, comparer)) !== null && _e !== void 0
97
+ ? _e
98
+ : EMPTY_OBJECT
99
+ useEffect(() => {
100
+ if (skipFetch) {
101
+ logsEnabled && log('useQuery.useEffect skip fetch', {skipFetch, queryKey, cacheKey})
102
+ return
103
+ }
104
+ const expired = queryState.expiresAt != null && queryState.expiresAt <= Date.now()
105
+ if (!fetchPolicy(expired, params, queryState, store, selectors)) {
106
+ logsEnabled &&
107
+ log('useQuery.useEffect skip fetch due to fetch policy', {
108
+ queryState,
109
+ expired,
110
+ queryKey,
111
+ cacheKey,
112
+ })
113
+ return
114
+ }
115
+ performFetch()
116
+ }, [cacheKey, skipFetch])
117
+ logsEnabled &&
118
+ log('useQuery', {
119
+ cacheKey,
120
+ options,
121
+ queryState,
122
+ })
123
+ return [queryState, performFetch]
124
+ }
125
+ const defaultStateComparer = createStateComparer(['result', 'loading', 'params', 'error'])
@@ -0,0 +1,168 @@
1
+ export const PACKAGE_SHORT_NAME = 'rrc'
2
+ export const optionalUtils = {
3
+ deepEqual: undefined,
4
+ }
5
+ try {
6
+ optionalUtils.deepEqual = require('fast-deep-equal/es6')
7
+ } catch (_a) {
8
+ console.debug(PACKAGE_SHORT_NAME + ': fast-deep-equal optional dependency was not installed')
9
+ }
10
+ export const IS_DEV = (() => {
11
+ try {
12
+ return __DEV__
13
+ } catch (e) {
14
+ return process.env.NODE_ENV === 'development'
15
+ }
16
+ })()
17
+ export const EMPTY_OBJECT = Object.freeze({})
18
+ export const EMPTY_ARRAY = Object.freeze([])
19
+ export const NOOP = () => {}
20
+ export const defaultGetCacheKey = (params) => {
21
+ switch (typeof params) {
22
+ case 'string':
23
+ case 'symbol':
24
+ return params
25
+ case 'object':
26
+ return JSON.stringify(params)
27
+ default:
28
+ return String(params)
29
+ }
30
+ }
31
+ export const log = (tag, data) => {
32
+ console.debug(`@${PACKAGE_SHORT_NAME} [${tag}]`, data)
33
+ }
34
+ export const FetchPolicy = {
35
+ NoCacheOrExpired: (expired, _params, state) => {
36
+ return expired || state.result === undefined
37
+ },
38
+ Always: () => true,
39
+ }
40
+ export const applyEntityChanges = (entities, changes, options) => {
41
+ var _a, _b, _c, _d
42
+ if (changes.merge && changes.entities) {
43
+ console.warn('react-redux-cache.applyEntityChanges: merge and entities should not be both set')
44
+ }
45
+ const {merge = changes.entities, replace, remove} = changes
46
+ if (!merge && !replace && !remove) {
47
+ return undefined
48
+ }
49
+ const deepEqual = options.deepComparisonEnabled ? optionalUtils.deepEqual : undefined
50
+ let result
51
+ const typenames = new Set([
52
+ ...(changes.entities ? Object.keys(changes.entities) : EMPTY_ARRAY),
53
+ ...(changes.merge ? Object.keys(changes.merge) : EMPTY_ARRAY),
54
+ ...(changes.remove ? Object.keys(changes.remove) : EMPTY_ARRAY),
55
+ ...(changes.replace ? Object.keys(changes.replace) : EMPTY_ARRAY),
56
+ ])
57
+ for (const typename of typenames) {
58
+ const entitiesToMerge = merge === null || merge === void 0 ? void 0 : merge[typename]
59
+ const entitiesToReplace = replace === null || replace === void 0 ? void 0 : replace[typename]
60
+ const entitiesToRemove = remove === null || remove === void 0 ? void 0 : remove[typename]
61
+ if (
62
+ !entitiesToMerge &&
63
+ !entitiesToReplace &&
64
+ !(entitiesToRemove === null || entitiesToRemove === void 0 ? void 0 : entitiesToRemove.length)
65
+ ) {
66
+ continue
67
+ }
68
+ if (options.additionalValidation) {
69
+ const mergeIds = entitiesToMerge && Object.keys(entitiesToMerge)
70
+ const replaceIds = entitiesToReplace && Object.keys(entitiesToReplace)
71
+ const idsSet = new Set(mergeIds)
72
+ replaceIds === null || replaceIds === void 0 ? void 0 : replaceIds.forEach((id) => idsSet.add(id))
73
+ entitiesToRemove === null || entitiesToRemove === void 0
74
+ ? void 0
75
+ : entitiesToRemove.forEach((id) => idsSet.add(String(id)))
76
+ const totalKeysInResponse =
77
+ ((_a = mergeIds === null || mergeIds === void 0 ? void 0 : mergeIds.length) !== null && _a !== void 0
78
+ ? _a
79
+ : 0) +
80
+ ((_b = replaceIds === null || replaceIds === void 0 ? void 0 : replaceIds.length) !== null &&
81
+ _b !== void 0
82
+ ? _b
83
+ : 0) +
84
+ ((_c =
85
+ entitiesToRemove === null || entitiesToRemove === void 0 ? void 0 : entitiesToRemove.length) !==
86
+ null && _c !== void 0
87
+ ? _c
88
+ : 0)
89
+ if (totalKeysInResponse !== 0 && idsSet.size !== totalKeysInResponse) {
90
+ console.warn(
91
+ 'react-redux-cache.applyEntityChanges: merge, replace and remove changes have intersections for: ' +
92
+ typename
93
+ )
94
+ }
95
+ }
96
+ const oldEntities = (_d = entities[typename]) !== null && _d !== void 0 ? _d : EMPTY_OBJECT
97
+ let newEntities
98
+ entitiesToRemove === null || entitiesToRemove === void 0
99
+ ? void 0
100
+ : entitiesToRemove.forEach((id) => {
101
+ if (oldEntities[id]) {
102
+ newEntities !== null && newEntities !== void 0
103
+ ? newEntities
104
+ : (newEntities = Object.assign({}, oldEntities))
105
+ delete newEntities[id]
106
+ }
107
+ })
108
+ if (entitiesToReplace) {
109
+ for (const id in entitiesToReplace) {
110
+ const newEntity = entitiesToReplace[id]
111
+ if (!(deepEqual === null || deepEqual === void 0 ? void 0 : deepEqual(oldEntities[id], newEntity))) {
112
+ newEntities !== null && newEntities !== void 0
113
+ ? newEntities
114
+ : (newEntities = Object.assign({}, oldEntities))
115
+ newEntities[id] = newEntity
116
+ }
117
+ }
118
+ }
119
+ if (entitiesToMerge) {
120
+ for (const id in entitiesToMerge) {
121
+ const oldEntity = oldEntities[id]
122
+ const newEntity = Object.assign(Object.assign({}, oldEntity), entitiesToMerge[id])
123
+ if (!(deepEqual === null || deepEqual === void 0 ? void 0 : deepEqual(oldEntity, newEntity))) {
124
+ newEntities !== null && newEntities !== void 0
125
+ ? newEntities
126
+ : (newEntities = Object.assign({}, oldEntities))
127
+ newEntities[id] = newEntity
128
+ }
129
+ }
130
+ }
131
+ if (!newEntities) {
132
+ continue
133
+ }
134
+ result !== null && result !== void 0 ? result : (result = Object.assign({}, entities))
135
+ result[typename] = newEntities
136
+ }
137
+ options.logsEnabled &&
138
+ log('applyEntityChanges', {
139
+ entities,
140
+ changes,
141
+ options,
142
+ result,
143
+ })
144
+ return result
145
+ }
146
+ export const isEmptyObject = (o) => {
147
+ for (const _ in o) {
148
+ return false
149
+ }
150
+ return true
151
+ }
152
+ export const createStateComparer = (fields) => {
153
+ return (x, y) => {
154
+ if (x === y) {
155
+ return true
156
+ }
157
+ if (x === undefined || y === undefined) {
158
+ return false
159
+ }
160
+ for (let i = 0; i < fields.length; i += 1) {
161
+ const key = fields[i]
162
+ if (x[key] !== y[key]) {
163
+ return false
164
+ }
165
+ }
166
+ return true
167
+ }
168
+ }
@@ -0,0 +1,106 @@
1
+ import type {EntityChanges, Key, MutationState, QueryState, Typenames} from './types'
2
+ import {CacheState} from './types'
3
+
4
+ export type Actions<
5
+ N extends string = string,
6
+ T extends Typenames = Typenames,
7
+ QP = unknown,
8
+ QR = unknown,
9
+ MP = unknown,
10
+ MR = unknown
11
+ > = ReturnType<typeof createActions<N, T, QP, QR, MP, MR>>
12
+ export declare const createActions: <N extends string, T extends Typenames, QP, QR, MP, MR>(
13
+ name: N
14
+ ) => {
15
+ updateQueryStateAndEntities: {
16
+ <K extends keyof (QP | QR)>(
17
+ queryKey: K,
18
+ queryCacheKey: Key,
19
+ state?: Partial<QueryState<T, QP[K], QR[K]>>,
20
+ entityChanges?: EntityChanges<T>
21
+ ): {
22
+ type: `@rrc/${N}/updateQueryStateAndEntities`
23
+ queryKey: K
24
+ queryCacheKey: Key
25
+ state: Partial<QueryState<T, QP[K], QR[K]>> | undefined
26
+ entityChanges: EntityChanges<T> | undefined
27
+ }
28
+ type: `@rrc/${N}/updateQueryStateAndEntities`
29
+ }
30
+ updateMutationStateAndEntities: {
31
+ <K extends keyof (MP | MR)>(
32
+ mutationKey: K,
33
+ state?: Partial<MutationState<T, MP[K], MR[K]>>,
34
+ entityChanges?: EntityChanges<T>
35
+ ): {
36
+ type: `@rrc/${N}/updateMutationStateAndEntities`
37
+ mutationKey: K
38
+ state: Partial<MutationState<T, MP[K], MR[K]>> | undefined
39
+ entityChanges: EntityChanges<T> | undefined
40
+ }
41
+ type: `@rrc/${N}/updateMutationStateAndEntities`
42
+ }
43
+ mergeEntityChanges: {
44
+ (changes: EntityChanges<T>): {
45
+ type: `@rrc/${N}/mergeEntityChanges`
46
+ changes: EntityChanges<T>
47
+ }
48
+ type: `@rrc/${N}/mergeEntityChanges`
49
+ }
50
+ invalidateQuery: {
51
+ <K extends keyof (QP | QR)>(
52
+ queries: {
53
+ /** Query key */
54
+ query: K
55
+ /** Query cache key */
56
+ cacheKey?: Key
57
+ /** Unix timestamp at which query expires. Is set to the query state. @Default Date.now() */
58
+ expiresAt?: number
59
+ }[]
60
+ ): {
61
+ type: `@rrc/${N}/invalidateQuery`
62
+ queries: {
63
+ /** Query key */
64
+ query: K
65
+ /** Query cache key */
66
+ cacheKey?: Key
67
+ /** Unix timestamp at which query expires. Is set to the query state. @Default Date.now() */
68
+ expiresAt?: number
69
+ }[]
70
+ }
71
+ type: `@rrc/${N}/invalidateQuery`
72
+ }
73
+ clearQueryState: {
74
+ <K extends keyof (QP | QR)>(
75
+ queries: {
76
+ /** Query key */
77
+ query: K
78
+ /** Query cache key */
79
+ cacheKey?: Key
80
+ }[]
81
+ ): {
82
+ type: `@rrc/${N}/clearQueryState`
83
+ queries: {
84
+ /** Query key */
85
+ query: K
86
+ /** Query cache key */
87
+ cacheKey?: Key
88
+ }[]
89
+ }
90
+ type: `@rrc/${N}/clearQueryState`
91
+ }
92
+ clearMutationState: {
93
+ <K extends keyof (MP | MR)>(mutationKeys: K[]): {
94
+ type: `@rrc/${N}/clearMutationState`
95
+ mutationKeys: K[]
96
+ }
97
+ type: `@rrc/${N}/clearMutationState`
98
+ }
99
+ clearCache: {
100
+ (stateToKeep?: Partial<CacheState<T, QP, QR, MP, MR>>): {
101
+ type: `@rrc/${N}/clearCache`
102
+ stateToKeep: Partial<CacheState<T, QP, QR, MP, MR>> | undefined
103
+ }
104
+ type: `@rrc/${N}/clearCache`
105
+ }
106
+ }