@promoboxx/use-filter 1.9.1 → 1.11.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.
@@ -7,4 +7,4 @@ export interface FilterStore {
7
7
  clear(): void;
8
8
  }
9
9
  export declare function setFilterStore(newStore: FilterStore): void;
10
- export declare function getFilterStore(): FilterStore;
10
+ export declare function getFilterStore(optionalStore?: FilterStore): FilterStore;
@@ -1,15 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getFilterStore = exports.setFilterStore = void 0;
4
- var store;
4
+ var globalStore;
5
5
  function setFilterStore(newStore) {
6
- store = newStore;
6
+ globalStore = newStore;
7
7
  }
8
8
  exports.setFilterStore = setFilterStore;
9
- function getFilterStore() {
10
- if (!store) {
9
+ function getFilterStore(optionalStore) {
10
+ var resolvedStore = optionalStore || globalStore;
11
+ if (!resolvedStore) {
11
12
  throw new Error('A store must be set with setFilterStore');
12
13
  }
13
- return store;
14
+ return resolvedStore;
14
15
  }
15
16
  exports.getFilterStore = getFilterStore;
@@ -0,0 +1,2 @@
1
+ import { FilterStore } from './index';
2
+ export declare const createUrlParamStore: () => FilterStore;
@@ -0,0 +1,86 @@
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
+ exports.createUrlParamStore = void 0;
18
+ var qs_1 = __importDefault(require("qs"));
19
+ var createUrlParamStore = function () {
20
+ var urlParamStore = {
21
+ getFilter: function (namespace) {
22
+ var parsed = naivelyParseExistingParams();
23
+ var parsedInfo = parsed["info." + namespace];
24
+ var parsedFilter = parsed["filter." + namespace];
25
+ // useFilter doesn't really support returning a partial FilterInfo, so both
26
+ // need to be present,
27
+ if (parsedInfo && parsedFilter) {
28
+ if (parsedInfo.page != null) {
29
+ parsedInfo.page = Number(parsedInfo.page);
30
+ }
31
+ if (parsedInfo.pageSize != null) {
32
+ parsedInfo.pageSize = Number(parsedInfo.pageSize);
33
+ }
34
+ if (parsedInfo.offset != null) {
35
+ parsedInfo.offset = Number(parsedInfo.offset);
36
+ }
37
+ return __assign(__assign({}, parsedInfo), { filter: parsedFilter });
38
+ }
39
+ },
40
+ saveFilter: function (namespace, filterInfo) {
41
+ var parsed = naivelyParseExistingParams();
42
+ // Setting the params to the equivalent of { [namespace]: filterInfo }
43
+ // takes up more room. The idea is that this ...
44
+ // 'filter.filterName%5BfilterValueKey%5D=filterValueValue'
45
+ // ... is smaller than ...
46
+ // filterName%5Bfilter%5D%5BfilterValueKey%5D=filterValueValue
47
+ // ... by 5 characters per value in a filter. So excuse us for a second ...
48
+ var clonedInfo = __assign({}, filterInfo);
49
+ var clonedFilter = filterInfo.filter;
50
+ delete clonedInfo.filter;
51
+ delete clonedInfo.lastRefreshAt;
52
+ delete clonedInfo.shouldRunImmediately;
53
+ delete clonedInfo.totalResults;
54
+ delete clonedInfo.totalPages;
55
+ delete clonedInfo.nextCursor;
56
+ parsed["filter." + namespace] = clonedFilter;
57
+ parsed["info." + namespace] = clonedInfo;
58
+ replaceQueryParams(qs_1.default.stringify(parsed));
59
+ },
60
+ clear: function () {
61
+ var parsed = naivelyParseExistingParams();
62
+ for (var key in parsed) {
63
+ if (key.startsWith('filter.') || key.startsWith('info.')) {
64
+ delete parsed[key];
65
+ }
66
+ }
67
+ replaceQueryParams(qs_1.default.stringify(parsed));
68
+ },
69
+ getData: function () {
70
+ return undefined;
71
+ },
72
+ saveData: function () { },
73
+ };
74
+ return urlParamStore;
75
+ };
76
+ exports.createUrlParamStore = createUrlParamStore;
77
+ function replaceQueryParams(newParams) {
78
+ var nextUrl = new URL(window.location.toString());
79
+ nextUrl.search = newParams;
80
+ window.history.replaceState(undefined, '', nextUrl.toString());
81
+ }
82
+ function naivelyParseExistingParams() {
83
+ // Don't really want to do any casting, especially not to `any`, but the type
84
+ // of `qs.parse` is so wide we'd have to litter checks all over the place.
85
+ return qs_1.default.parse(window.location.search.substring(1));
86
+ }
@@ -1,3 +1,4 @@
1
+ import { FilterStore } from './store';
1
2
  declare type MaybePromise<T> = T | Promise<T>;
2
3
  interface UseFilterOptions<TFilter, TResult> {
3
4
  /**
@@ -19,6 +20,7 @@ interface UseFilterOptions<TFilter, TResult> {
19
20
  */
20
21
  debounceDuration?: number;
21
22
  onBeforeSaveFilter?: (filterInfo: FilterInfo<TFilter>) => FilterInfo<TFilter>;
23
+ store?: FilterStore;
22
24
  }
23
25
  export interface FilterApi<TFilter, TResult> {
24
26
  /**
package/dist/useFilter.js CHANGED
@@ -32,15 +32,6 @@ var getPageFromOffset_1 = __importDefault(require("./lib/getPageFromOffset"));
32
32
  var shallowEqual_1 = __importDefault(require("./lib/shallowEqual"));
33
33
  var store_1 = require("./store");
34
34
  function useFilter(namespace, options) {
35
- var _a = react_1.useState(function () {
36
- var existing = store_1.getFilterStore().getFilter(namespace);
37
- var initialValue = existing
38
- ? __assign(__assign({}, existing), { shouldRunImmediately: true }) : undefined;
39
- return initialValue;
40
- }), filterInfo = _a[0], setFilterInfoState = _a[1];
41
- var _b = react_1.useState(function () {
42
- return store_1.getFilterStore().getData(namespace);
43
- }), data = _b[0], setData = _b[1];
44
35
  // Having these types of refs helps get around rules of hooks, and they need
45
36
  // to be updated each render.
46
37
  var ctxRefValue = {
@@ -49,11 +40,21 @@ function useFilter(namespace, options) {
49
40
  debounceDuration: options.debounceDuration,
50
41
  defaultFilterInfo: options.defaultFilterInfo,
51
42
  onBeforeSaveFilter: options.onBeforeSaveFilter,
43
+ store: options.store,
52
44
  };
53
45
  var ctxRef = react_1.useRef(ctxRefValue);
54
46
  react_1.useEffect(function () {
55
47
  ctxRef.current = ctxRefValue;
56
48
  });
49
+ var _a = react_1.useState(function () {
50
+ var existing = store_1.getFilterStore(ctxRef.current.store).getFilter(namespace);
51
+ var initialValue = existing
52
+ ? __assign(__assign({}, existing), { shouldRunImmediately: true }) : undefined;
53
+ return initialValue;
54
+ }), filterInfo = _a[0], setFilterInfoState = _a[1];
55
+ var _b = react_1.useState(function () {
56
+ return store_1.getFilterStore(ctxRef.current.store).getData(namespace);
57
+ }), data = _b[0], setData = _b[1];
57
58
  var _c = react_1.useState(!filterInfo), isLoading = _c[0], setIsLoading = _c[1];
58
59
  var doesFilterExist = react_1.useRef(!!filterInfo);
59
60
  var lastRefreshAtRef = react_1.useRef(
@@ -83,7 +84,7 @@ function useFilter(namespace, options) {
83
84
  var makeRequest = function () {
84
85
  lastRefreshAtRef.current = filterInfo.lastRefreshAt;
85
86
  var response = ctxRef.current.onChange(filterInfo, updateReasonRef.current);
86
- store_1.getFilterStore().saveFilter(namespace, ctxRef.current.onBeforeSaveFilter
87
+ store_1.getFilterStore(ctxRef.current.store).saveFilter(namespace, ctxRef.current.onBeforeSaveFilter
87
88
  ? ctxRef.current.onBeforeSaveFilter(filterInfo)
88
89
  : filterInfo);
89
90
  if (!response) {
@@ -132,7 +133,7 @@ function useFilter(namespace, options) {
132
133
  }
133
134
  if (response.data) {
134
135
  setData(response.data);
135
- store_1.getFilterStore().saveData(namespace, response.data);
136
+ store_1.getFilterStore(ctxRef.current.store).saveData(namespace, response.data);
136
137
  }
137
138
  }
138
139
  if (isPromise(response)) {
@@ -1,3 +1,4 @@
1
+ import { FilterStore } from './store';
1
2
  import { UseFilterUpdateReason } from './useFilter';
2
3
  interface UseSimpleFilterOptions<TFilter> {
3
4
  /**
@@ -11,6 +12,7 @@ interface UseSimpleFilterOptions<TFilter> {
11
12
  */
12
13
  debounceDuration?: number;
13
14
  onBeforeSaveFilter?: (filterInfo: SimpleFilterInfo<TFilter>) => SimpleFilterInfo<TFilter>;
15
+ store?: FilterStore;
14
16
  }
15
17
  export interface SimpleFilterApi<TFilter> {
16
18
  /**
@@ -27,13 +27,14 @@ function useSimpleFilter(namespace, options) {
27
27
  debounceDuration: options.debounceDuration,
28
28
  defaultFilterInfo: options.defaultFilterInfo,
29
29
  onBeforeSaveFilter: options.onBeforeSaveFilter,
30
+ store: options.store,
30
31
  };
31
32
  var ctxRef = react_1.useRef(ctxRefValue);
32
33
  react_1.useEffect(function () {
33
34
  ctxRef.current = ctxRefValue;
34
35
  });
35
36
  var _a = react_1.useState(false), isLoading = _a[0], setIsLoading = _a[1];
36
- var _b = react_1.useState(function () { return (__assign(__assign({}, (store_1.getFilterStore().getFilter(namespace) ||
37
+ var _b = react_1.useState(function () { return (__assign(__assign({}, (store_1.getFilterStore(ctxRef.current.store).getFilter(namespace) ||
37
38
  buildDefaultFilterInfo(options.defaultFilterInfo))), { shouldRunImmediately: true })); }), filterInfo = _b[0], setFilterInfoState = _b[1];
38
39
  var _c = react_1.useState(filterInfo), debouncedFilterInfo = _c[0], setDebouncedFilterInfo = _c[1];
39
40
  // Not sure this is needed in simple mode?
@@ -50,7 +51,7 @@ function useSimpleFilter(namespace, options) {
50
51
  var timeout = undefined;
51
52
  function makeRequest() {
52
53
  lastRefreshAtRef.current = filterInfo.lastRefreshAt;
53
- store_1.getFilterStore().saveFilter(ctxRef.current.namespace, (ctxRef.current.onBeforeSaveFilter
54
+ store_1.getFilterStore(ctxRef.current.store).saveFilter(ctxRef.current.namespace, (ctxRef.current.onBeforeSaveFilter
54
55
  ? ctxRef.current.onBeforeSaveFilter(filterInfo)
55
56
  : filterInfo));
56
57
  setDebouncedFilterInfo(filterInfo);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@promoboxx/use-filter",
3
- "version": "1.9.1",
3
+ "version": "1.11.0",
4
4
  "description": "",
5
5
  "main": "dist/useFilter.js",
6
6
  "keywords": [],
@@ -10,6 +10,7 @@
10
10
  "@promoboxx/eslint-config": "^2.3.0",
11
11
  "@testing-library/react": "^12.0.0",
12
12
  "@types/jest": "^26.0.24",
13
+ "@types/qs": "^6.9.7",
13
14
  "@types/react": "^17.0.14",
14
15
  "@types/redux": "^3.6.0",
15
16
  "eslint": "^7.30.0",
@@ -43,7 +44,12 @@
43
44
  "dist/store/index.d.ts",
44
45
  "dist/store/index.js",
45
46
  "dist/store/localStorageStore.js",
47
+ "dist/store/urlParamStore.d.ts",
48
+ "dist/store/urlParamStore.js",
46
49
  "dist/store/memoryStore.js",
47
50
  "dist/store/reduxStore.js"
48
- ]
51
+ ],
52
+ "dependencies": {
53
+ "qs": "^6.11.2"
54
+ }
49
55
  }