@promoboxx/use-filter 1.0.3 → 1.0.4
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 +7 -0
- package/dist/lib/buildDefaultFilterInfo.js +35 -0
- package/dist/lib/getOffsetFromPage.js +6 -0
- package/dist/lib/getPageFromOffset.js +6 -0
- package/dist/lib/shallowEqual.js +23 -0
- package/dist/lib/shallowEqual.test.js +54 -0
- package/dist/store/index.js +15 -0
- package/dist/store/memoryStore.js +15 -0
- package/dist/useFilter.js +184 -0
- package/dist/useFilter.test.js +581 -0
- package/package.json +14 -3
- package/.eslintrc.js +0 -19
- package/.github/workflows/main.yml +0 -32
- package/.vscode/settings.json +0 -3
- package/Makefile +0 -31
- package/jest.config.js +0 -196
- package/prettier.config.js +0 -1
- package/src/lib/buildDefaultFilterInfo.ts +0 -35
- package/src/lib/getOffsetFromPage.ts +0 -5
- package/src/lib/getPageFromOffset.ts +0 -5
- package/src/lib/shallowEqual.test.ts +0 -71
- package/src/lib/shallowEqual.ts +0 -26
- package/src/store/index.ts +0 -21
- package/src/store/memoryStore.ts +0 -19
- package/src/useFilter.test.tsx +0 -449
- package/src/useFilter.ts +0 -280
- package/tsconfig.json +0 -75
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
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.4 (2021-07-16)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* more release prep ([daf06ac](https://github.com/promoboxx/use-filter/commit/daf06acc94668fdc7f0905c120f5541b4b2d16e9))
|
|
11
|
+
|
|
5
12
|
### 1.0.3 (2021-07-16)
|
|
6
13
|
|
|
7
14
|
### 1.0.2 (2021-07-16)
|
|
@@ -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,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,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,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,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,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
|
+
}
|