@promoboxx/use-filter 1.0.2 → 1.0.5

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/CHANGELOG.md CHANGED
@@ -2,6 +2,22 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### 1.0.5 (2021-07-16)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * declaration files ([4ce29e4](https://github.com/promoboxx/use-filter/commit/4ce29e43469ad4ade2d222c3b09f38ad8f89ca4c))
11
+
12
+ ### 1.0.4 (2021-07-16)
13
+
14
+
15
+ ### Bug Fixes
16
+
17
+ * more release prep ([daf06ac](https://github.com/promoboxx/use-filter/commit/daf06acc94668fdc7f0905c120f5541b4b2d16e9))
18
+
19
+ ### 1.0.3 (2021-07-16)
20
+
5
21
  ### 1.0.2 (2021-07-16)
6
22
 
7
23
 
@@ -0,0 +1,3 @@
1
+ import { FilterInfo } from '../useFilter';
2
+ declare function buildDefaultFilterInfo<T>(filterInfo?: Partial<FilterInfo<T>>): FilterInfo<T>;
3
+ export default buildDefaultFilterInfo;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ var getOffsetFromPage_1 = __importDefault(require("./getOffsetFromPage"));
18
+ var getPageFromOffset_1 = __importDefault(require("./getPageFromOffset"));
19
+ function buildDefaultFilterInfo(filterInfo) {
20
+ if (filterInfo === void 0) { filterInfo = {}; }
21
+ var merged = __assign({
22
+ // Cast here to work around "'T' could be instantiated with an arbitrary
23
+ // type which could be unrelated to '{}'"
24
+ filter: {}, sort: undefined, pageSize: 20, lastRefreshAt: new Date().getTime(), totalResults: 1, totalPages: 1, offset: 0, page: 1 }, filterInfo);
25
+ // If there's a page but no offset, set the offset.
26
+ if (filterInfo.page != null && filterInfo.offset == null) {
27
+ merged.offset = getOffsetFromPage_1.default(filterInfo.page, merged.pageSize);
28
+ // If there's an offset but no page, set the page.
29
+ }
30
+ else if (filterInfo.page == null && filterInfo.offset != null) {
31
+ merged.page = getPageFromOffset_1.default(filterInfo.offset, merged.pageSize);
32
+ }
33
+ return merged;
34
+ }
35
+ exports.default = buildDefaultFilterInfo;
@@ -0,0 +1,2 @@
1
+ declare function getOffsetFromPage(page: number, pageSize: number): number;
2
+ export default getOffsetFromPage;
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ function getOffsetFromPage(page, pageSize) {
4
+ return pageSize * (page - 1);
5
+ }
6
+ exports.default = getOffsetFromPage;
@@ -0,0 +1,2 @@
1
+ declare function getPageFromOffset(offset: number, pageSize: number): number;
2
+ export default getPageFromOffset;
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ function getPageFromOffset(offset, pageSize) {
4
+ return Math.floor(offset / pageSize) + 1;
5
+ }
6
+ exports.default = getPageFromOffset;
@@ -0,0 +1,2 @@
1
+ declare const shallowEqual: (objA: any, objB: any) => boolean;
2
+ export default shallowEqual;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var shallowEqual = function (objA, objB) {
4
+ if (Object.is(objA, objB)) {
5
+ return true;
6
+ }
7
+ if (typeof objA !== 'object' || !objA || typeof objB !== 'object' || !objB) {
8
+ return false;
9
+ }
10
+ var keysA = Object.keys(objA);
11
+ var keysB = Object.keys(objB);
12
+ if (keysA.length !== keysB.length) {
13
+ return false;
14
+ }
15
+ for (var _i = 0, keysA_1 = keysA; _i < keysA_1.length; _i++) {
16
+ var key = keysA_1[_i];
17
+ if (!Object.is(objA[key], objB[key])) {
18
+ return false;
19
+ }
20
+ }
21
+ return true;
22
+ };
23
+ exports.default = shallowEqual;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ var shallowEqual_1 = __importDefault(require("./shallowEqual"));
7
+ describe('shallowEqual', function () {
8
+ it('should return true if arguments fields are equal', function () {
9
+ expect(shallowEqual_1.default({ a: 1, b: 2, c: undefined }, { a: 1, b: 2, c: undefined })).toBe(true);
10
+ expect(shallowEqual_1.default({ a: 1, b: 2, c: 3 }, { a: 1, b: 2, c: 3 })).toBe(true);
11
+ var o = {};
12
+ expect(shallowEqual_1.default({ a: 1, b: 2, c: o }, { a: 1, b: 2, c: o })).toBe(true);
13
+ var d = function () {
14
+ return 1;
15
+ };
16
+ expect(shallowEqual_1.default({ a: 1, b: 2, c: o, d: d }, { a: 1, b: 2, c: o, d: d })).toBe(true);
17
+ });
18
+ it('should return false if arguments fields are different function identities', function () {
19
+ expect(shallowEqual_1.default({
20
+ a: 1,
21
+ b: 2,
22
+ d: function () {
23
+ return 1;
24
+ },
25
+ }, {
26
+ a: 1,
27
+ b: 2,
28
+ d: function () {
29
+ return 1;
30
+ },
31
+ })).toBe(false);
32
+ });
33
+ it('should return false if first argument has too many keys', function () {
34
+ expect(shallowEqual_1.default({ a: 1, b: 2, c: 3 }, { a: 1, b: 2 })).toBe(false);
35
+ });
36
+ it('should return false if second argument has too many keys', function () {
37
+ expect(shallowEqual_1.default({ a: 1, b: 2 }, { a: 1, b: 2, c: 3 })).toBe(false);
38
+ });
39
+ it('should return false if arguments have different keys', function () {
40
+ expect(shallowEqual_1.default({ a: 1, b: 2, c: undefined }, { a: 1, bb: 2, c: undefined })).toBe(false);
41
+ });
42
+ it('should compare two NaN values', function () {
43
+ expect(shallowEqual_1.default(NaN, NaN)).toBe(true);
44
+ });
45
+ it('should compare empty objects, with false', function () {
46
+ expect(shallowEqual_1.default({}, false)).toBe(false);
47
+ expect(shallowEqual_1.default(false, {})).toBe(false);
48
+ expect(shallowEqual_1.default([], false)).toBe(false);
49
+ expect(shallowEqual_1.default(false, [])).toBe(false);
50
+ });
51
+ it('should compare two zero values', function () {
52
+ expect(shallowEqual_1.default(0, 0)).toBe(true);
53
+ });
54
+ });
@@ -0,0 +1,8 @@
1
+ import { FilterInfo } from '../useFilter';
2
+ export interface FilterStore {
3
+ getFilter(namespace: string): FilterInfo<any> | null | undefined;
4
+ saveFilter(namespace: string, filter: FilterInfo<any>): void;
5
+ clear(): void;
6
+ }
7
+ export declare function setFilterStore(newStore: FilterStore): void;
8
+ export declare function getFilterStore(): FilterStore;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getFilterStore = exports.setFilterStore = void 0;
4
+ var store;
5
+ function setFilterStore(newStore) {
6
+ store = newStore;
7
+ }
8
+ exports.setFilterStore = setFilterStore;
9
+ function getFilterStore() {
10
+ if (!store) {
11
+ throw new Error('A store must be set with setFilterStore');
12
+ }
13
+ return store;
14
+ }
15
+ exports.getFilterStore = getFilterStore;
@@ -0,0 +1,3 @@
1
+ import { FilterStore } from '.';
2
+ declare const memoryStore: FilterStore;
3
+ export default memoryStore;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var filters = {};
4
+ var memoryStore = {
5
+ getFilter: function (namespace) {
6
+ return filters[namespace];
7
+ },
8
+ saveFilter: function (namespace, filter) {
9
+ filters[namespace] = filter;
10
+ },
11
+ clear: function () {
12
+ filters = {};
13
+ },
14
+ };
15
+ exports.default = memoryStore;
@@ -0,0 +1,37 @@
1
+ declare type MaybePromise<T> = T | Promise<T>;
2
+ interface UseFilterOptions<TFilter, TResult> {
3
+ defaultFilterInfo?: Partial<FilterInfo<TFilter>>;
4
+ shouldForceRunOnMount?: boolean;
5
+ onChange: (filterInfo: FilterInfo<TFilter>) => MaybePromise<UseFilterOnChangeResult<TFilter, TResult>>;
6
+ debounceDuration?: number;
7
+ }
8
+ declare function useFilter<T>(namespace: string, options: UseFilterOptions<T, any>): {
9
+ isLoading: boolean;
10
+ doesFilterExist: boolean;
11
+ filterInfo: FilterInfo<T>;
12
+ updateFilter(filter: T): void;
13
+ resetFilter(): void;
14
+ setOffset(offset: number | string): void;
15
+ setPage(page: number | string): void;
16
+ setSort(sort: string | undefined): void;
17
+ forceRefresh(): void;
18
+ };
19
+ export default useFilter;
20
+ export interface FilterInfo<TFilter> {
21
+ filter: TFilter;
22
+ offset: number;
23
+ page: number;
24
+ sort?: string;
25
+ pageSize: number;
26
+ lastRefreshAt: number;
27
+ totalResults: number;
28
+ totalPages: number;
29
+ }
30
+ declare type UseFilterOnChangeResult<TFilter, TResult> = void | {
31
+ filterInfo?: Partial<Omit<FilterInfo<TFilter>, 'totalResults' | 'offset' | 'pageSize'> & {
32
+ totalResults: string | number;
33
+ offset: string | number;
34
+ pageSize: string | number;
35
+ }>;
36
+ data?: TResult;
37
+ };
@@ -0,0 +1,184 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __rest = (this && this.__rest) || function (s, e) {
14
+ var t = {};
15
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
16
+ t[p] = s[p];
17
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
18
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
19
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
20
+ t[p[i]] = s[p[i]];
21
+ }
22
+ return t;
23
+ };
24
+ var __importDefault = (this && this.__importDefault) || function (mod) {
25
+ return (mod && mod.__esModule) ? mod : { "default": mod };
26
+ };
27
+ Object.defineProperty(exports, "__esModule", { value: true });
28
+ var react_1 = require("react");
29
+ var buildDefaultFilterInfo_1 = __importDefault(require("./lib/buildDefaultFilterInfo"));
30
+ var getOffsetFromPage_1 = __importDefault(require("./lib/getOffsetFromPage"));
31
+ var getPageFromOffset_1 = __importDefault(require("./lib/getPageFromOffset"));
32
+ var shallowEqual_1 = __importDefault(require("./lib/shallowEqual"));
33
+ var store_1 = require("./store");
34
+ function useFilter(namespace, options) {
35
+ var _a = react_1.useState(function () { return store_1.getFilterStore().getFilter(namespace); }), filterInfo = _a[0], setFilterInfoState = _a[1];
36
+ var setFilterInfo = react_1.useCallback(function (filterInfo, skipFetch) {
37
+ if (skipFetch === void 0) { skipFetch = false; }
38
+ setFilterInfoState(function (previousFilterInfo) {
39
+ var lastRefreshAt;
40
+ if (skipFetch) {
41
+ lastRefreshAt = previousFilterInfo === null || previousFilterInfo === void 0 ? void 0 : previousFilterInfo.lastRefreshAt;
42
+ }
43
+ else {
44
+ lastRefreshAt = new Date().getTime();
45
+ }
46
+ if (!lastRefreshAt) {
47
+ throw new Error();
48
+ }
49
+ return __assign(__assign({}, filterInfo), { lastRefreshAt: lastRefreshAt });
50
+ });
51
+ }, []);
52
+ var ctxRef = react_1.useRef({
53
+ namespace: namespace,
54
+ onChange: options.onChange,
55
+ debounceDuration: options.debounceDuration,
56
+ defaultFilterInfo: options.defaultFilterInfo,
57
+ });
58
+ var _b = react_1.useState(!filterInfo), isLoading = _b[0], setIsLoading = _b[1];
59
+ var doesFilterExist = react_1.useRef(!!filterInfo);
60
+ var lastRefreshAtRef = react_1.useRef(
61
+ // if shouldForceRunOnMount is set, always use -1
62
+ // otherwise, try grabbing lastRefreshAt
63
+ // then, just use -1 cause there's no other option
64
+ options.shouldForceRunOnMount
65
+ ? -1
66
+ : filterInfo
67
+ ? filterInfo.lastRefreshAt
68
+ : -1);
69
+ // Call onChange when data changes.
70
+ react_1.useEffect(function () {
71
+ setIsLoading(true);
72
+ // If there is no existing filter info, set it to the defaults and return.
73
+ // This same effect will trigger next go.
74
+ if (!filterInfo) {
75
+ setFilterInfo(buildDefaultFilterInfo_1.default(ctxRef.current.defaultFilterInfo));
76
+ return;
77
+ }
78
+ // If the lastRefreshAt hasn't changed, don't make a request.
79
+ if (lastRefreshAtRef.current === filterInfo.lastRefreshAt) {
80
+ setIsLoading(false);
81
+ return;
82
+ }
83
+ var timeout = setTimeout(function () {
84
+ lastRefreshAtRef.current = filterInfo.lastRefreshAt;
85
+ var response = ctxRef.current.onChange(filterInfo);
86
+ store_1.getFilterStore().saveFilter(namespace, filterInfo);
87
+ if (!response) {
88
+ setIsLoading(false);
89
+ return;
90
+ }
91
+ function handleResponse(response) {
92
+ if (!filterInfo) {
93
+ return;
94
+ }
95
+ if (!response) {
96
+ return;
97
+ }
98
+ if (response.filterInfo) {
99
+ var extra = {};
100
+ var _a = response.filterInfo, page = _a.page, offset = _a.offset, totalResults = _a.totalResults, pageSize = _a.pageSize, filterInfoFromResponse = __rest(_a, ["page", "offset", "totalResults", "pageSize"]);
101
+ var pageSizeNumber = Number(pageSize || filterInfo.pageSize);
102
+ if (page != null && offset == null) {
103
+ extra.offset = getOffsetFromPage_1.default(page, pageSizeNumber);
104
+ extra.page = page;
105
+ // If there's an offset but no page, set the page.
106
+ }
107
+ else if (page == null && offset != null) {
108
+ var offsetNumber = Number(offset);
109
+ extra.offset = offsetNumber;
110
+ extra.page = getPageFromOffset_1.default(offsetNumber, pageSizeNumber);
111
+ }
112
+ if (totalResults) {
113
+ extra.totalResults = Number(totalResults);
114
+ extra.totalPages = Math.ceil(extra.totalResults / pageSizeNumber);
115
+ }
116
+ // TODO Don't do anther request here????
117
+ setFilterInfo(__assign(__assign(__assign({}, filterInfo), filterInfoFromResponse), extra), true);
118
+ }
119
+ }
120
+ if (isPromise(response)) {
121
+ response.then(handleResponse).finally(function () { return setIsLoading(false); });
122
+ }
123
+ else {
124
+ handleResponse(response);
125
+ setIsLoading(false);
126
+ }
127
+ }, ctxRef.current.debounceDuration != null
128
+ ? ctxRef.current.debounceDuration
129
+ : 500);
130
+ return function () {
131
+ if (timeout) {
132
+ clearTimeout(timeout);
133
+ }
134
+ };
135
+ }, [filterInfo, setFilterInfo, namespace]);
136
+ return {
137
+ isLoading: isLoading,
138
+ doesFilterExist: doesFilterExist.current,
139
+ filterInfo: filterInfo || buildDefaultFilterInfo_1.default(options.defaultFilterInfo),
140
+ updateFilter: function (filter) {
141
+ if (!filterInfo) {
142
+ throw new Error();
143
+ }
144
+ var nextFilter = __assign(__assign({}, filterInfo.filter), filter);
145
+ if (shallowEqual_1.default(filterInfo.filter, nextFilter)) {
146
+ return;
147
+ }
148
+ setFilterInfo(__assign(__assign({}, filterInfo), { offset: 0, page: 1, totalResults: 1, totalPages: 1, filter: nextFilter }));
149
+ },
150
+ resetFilter: function () {
151
+ setFilterInfo(buildDefaultFilterInfo_1.default(options.defaultFilterInfo));
152
+ },
153
+ setOffset: function (offset) {
154
+ if (!filterInfo) {
155
+ throw new Error();
156
+ }
157
+ var offsetNumber = Number(offset);
158
+ setFilterInfo(__assign(__assign({}, filterInfo), { offset: offsetNumber, page: getPageFromOffset_1.default(offsetNumber, filterInfo.pageSize) }));
159
+ },
160
+ setPage: function (page) {
161
+ if (!filterInfo) {
162
+ throw new Error();
163
+ }
164
+ var pageNumber = Number(page);
165
+ setFilterInfo(__assign(__assign({}, filterInfo), { offset: getOffsetFromPage_1.default(pageNumber, filterInfo.pageSize), page: pageNumber }));
166
+ },
167
+ setSort: function (sort) {
168
+ if (!filterInfo) {
169
+ throw new Error();
170
+ }
171
+ setFilterInfo(__assign(__assign({}, filterInfo), { sort: sort }));
172
+ },
173
+ forceRefresh: function () {
174
+ if (!filterInfo) {
175
+ throw new Error();
176
+ }
177
+ setFilterInfo(__assign(__assign({}, filterInfo), { lastRefreshAt: new Date().getTime() }));
178
+ },
179
+ };
180
+ }
181
+ exports.default = useFilter;
182
+ function isPromise(t) {
183
+ return !!(t === null || t === void 0 ? void 0 : t.then);
184
+ }
@@ -0,0 +1 @@
1
+ export {};