react-magic-search-params 0.1.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.
@@ -0,0 +1,503 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var reactRouterDom = require('react-router-dom');
6
+ var react = require('react');
7
+
8
+ function _arrayLikeToArray(r, a) {
9
+ (null == a || a > r.length) && (a = r.length);
10
+ for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
11
+ return n;
12
+ }
13
+ function _createForOfIteratorHelperLoose(r, e) {
14
+ var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
15
+ if (t) return (t = t.call(r)).next.bind(t);
16
+ if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) {
17
+ t && (r = t);
18
+ var o = 0;
19
+ return function () {
20
+ return o >= r.length ? {
21
+ done: !0
22
+ } : {
23
+ done: !1,
24
+ value: r[o++]
25
+ };
26
+ };
27
+ }
28
+ throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
29
+ }
30
+ function _extends() {
31
+ return _extends = Object.assign ? Object.assign.bind() : function (n) {
32
+ for (var e = 1; e < arguments.length; e++) {
33
+ var t = arguments[e];
34
+ for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
35
+ }
36
+ return n;
37
+ }, _extends.apply(null, arguments);
38
+ }
39
+ function _unsupportedIterableToArray(r, a) {
40
+ if (r) {
41
+ if ("string" == typeof r) return _arrayLikeToArray(r, a);
42
+ var t = {}.toString.call(r).slice(8, -1);
43
+ return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
44
+ }
45
+ }
46
+
47
+ /**
48
+ Generic hook to handle search parameters in the URL
49
+ @param mandatory - Mandatory parameters (e.g., page=1, page_size=10, etc.)
50
+ @param optional - Optional parameters (e.g., order, search, etc.)
51
+ @param defaultParams - Default parameters sent in the URL on initialization
52
+ @param forceParams - Parameters forced into the URL regardless of user input
53
+ @param omitParamsByValues - Parameters omitted if they have specific values
54
+ */
55
+ var useMagicSearchParams = function useMagicSearchParams(_ref) {
56
+ var _ref$mandatory = _ref.mandatory,
57
+ mandatory = _ref$mandatory === void 0 ? {} : _ref$mandatory,
58
+ _ref$optional = _ref.optional,
59
+ optional = _ref$optional === void 0 ? {} : _ref$optional,
60
+ _ref$defaultParams = _ref.defaultParams,
61
+ defaultParams = _ref$defaultParams === void 0 ? {} : _ref$defaultParams,
62
+ _ref$arraySerializati = _ref.arraySerialization,
63
+ arraySerialization = _ref$arraySerializati === void 0 ? 'csv' : _ref$arraySerializati,
64
+ _ref$forceParams = _ref.forceParams,
65
+ forceParams = _ref$forceParams === void 0 ? {} : _ref$forceParams,
66
+ _ref$omitParamsByValu = _ref.omitParamsByValues,
67
+ omitParamsByValues = _ref$omitParamsByValu === void 0 ? [] : _ref$omitParamsByValu;
68
+ var _useSearchParams = reactRouterDom.useSearchParams(),
69
+ searchParams = _useSearchParams[0],
70
+ setSearchParams = _useSearchParams[1];
71
+ // Ref to store subscriptions: { paramName: [callback1, callback2, ...] }
72
+ var subscriptionsRef = react.useRef({});
73
+ var previousParamsRef = react.useRef({});
74
+ var TOTAL_PARAMS_PAGE = react.useMemo(function () {
75
+ return _extends({}, mandatory, optional);
76
+ }, [mandatory, optional]);
77
+ var PARAM_ORDER = react.useMemo(function () {
78
+ return Array.from(Object.keys(TOTAL_PARAMS_PAGE));
79
+ }, [TOTAL_PARAMS_PAGE]);
80
+ // we get the keys that are arrays according to TOTAL_PARAMS_PAGE since these require special treatment in the URL due to serialization mode
81
+ var ARRAY_KEYS = react.useMemo(function () {
82
+ return Object.keys(TOTAL_PARAMS_PAGE).filter(function (key) {
83
+ return Array.isArray(TOTAL_PARAMS_PAGE[key]);
84
+ });
85
+ }, [TOTAL_PARAMS_PAGE]);
86
+ var appendArrayValues = function appendArrayValues(finallyParams, newParams) {
87
+ // Note: We cannot modify the object of the final parameters directly, as immutability must be maintained
88
+ var updatedParams = _extends({}, finallyParams);
89
+ if (ARRAY_KEYS.length === 0) return updatedParams;
90
+ ARRAY_KEYS.forEach(function (key) {
91
+ // We use the current values directly from searchParams (source of truth)
92
+ // This avoids depending on finallyParams in which the arrays have been omitted
93
+ var currentValues = [];
94
+ switch (arraySerialization) {
95
+ case 'csv':
96
+ {
97
+ var raw = searchParams.get(key) || '';
98
+ // For csv we expect "value1,value2,..." (no prefix)
99
+ currentValues = raw.split(',').map(function (v) {
100
+ return v.trim();
101
+ }).filter(Boolean);
102
+ break;
103
+ }
104
+ case 'repeat':
105
+ {
106
+ // Here we get all ocurrences of key
107
+ var urlParams = searchParams.getAll(key);
108
+ currentValues = urlParams.length > 0 ? urlParams : [];
109
+ console.log({
110
+ REPEAT: currentValues
111
+ });
112
+ break;
113
+ }
114
+ case 'brackets':
115
+ {
116
+ // Build URLSearchParams from current parameters (to ensure no serialized values are taken previously)
117
+ var _urlParams = searchParams.getAll(key + "[]");
118
+ currentValues = _urlParams.length > 0 ? _urlParams : [];
119
+ console.log({
120
+ BRACKETS: _urlParams
121
+ });
122
+ break;
123
+ }
124
+ default:
125
+ {
126
+ var _searchParams$get;
127
+ // Mode by default works as csv
128
+ var _raw = (_searchParams$get = searchParams.get(key)) != null ? _searchParams$get : '';
129
+ currentValues = _raw.split(',').map(function (v) {
130
+ return v.trim();
131
+ }).filter(Boolean);
132
+ }
133
+ break;
134
+ }
135
+ // Update array values with new ones
136
+ if (newParams[key] !== undefined) {
137
+ var incoming = newParams[key];
138
+ var combined = [];
139
+ if (typeof incoming === 'string') {
140
+ // If it is a string, it is toggled (add/remove)
141
+ combined = currentValues.includes(incoming) ? currentValues.filter(function (v) {
142
+ return v !== incoming;
143
+ }) : [].concat(currentValues, [incoming]);
144
+ console.log({
145
+ currentValues: currentValues
146
+ });
147
+ console.log({
148
+ incoming: incoming
149
+ });
150
+ console.log({
151
+ CONBINED_STRING: combined
152
+ });
153
+ } else if (Array.isArray(incoming)) {
154
+ // if an array is passed, repeated values are merged into a single value
155
+ // Note: Set is used to remove duplicates
156
+ combined = Array.from(new Set([].concat(incoming)));
157
+ console.log({
158
+ incoming: incoming
159
+ });
160
+ console.log({
161
+ combined: combined
162
+ });
163
+ } else {
164
+ combined = currentValues;
165
+ }
166
+ updatedParams[key] = combined;
167
+ }
168
+ });
169
+ console.log({
170
+ updatedParams: updatedParams
171
+ });
172
+ return updatedParams;
173
+ };
174
+ var transformParamsToURLSearch = function transformParamsToURLSearch(params) {
175
+ console.log({
176
+ PARAMS_RECIBIDOS_TRANSFORM: params
177
+ });
178
+ var newParam = new URLSearchParams();
179
+ var paramsKeys = Object.keys(params);
180
+ for (var _i = 0, _paramsKeys = paramsKeys; _i < _paramsKeys.length; _i++) {
181
+ var key = _paramsKeys[_i];
182
+ if (Array.isArray(TOTAL_PARAMS_PAGE[key])) {
183
+ var arrayValue = params[key];
184
+ console.log({
185
+ arrayValue: arrayValue
186
+ });
187
+ switch (arraySerialization) {
188
+ case 'csv':
189
+ {
190
+ var csvValue = arrayValue.join(',');
191
+ // set ensure that the previous value is replaced
192
+ newParam.set(key, csvValue);
193
+ break;
194
+ }
195
+ case 'repeat':
196
+ {
197
+ for (var _iterator = _createForOfIteratorHelperLoose(arrayValue), _step; !(_step = _iterator()).done;) {
198
+ var item = _step.value;
199
+ console.log({
200
+ item: item
201
+ });
202
+ // add new value to the key, instead of replacing it
203
+ newParam.append(key, item);
204
+ }
205
+ break;
206
+ }
207
+ case 'brackets':
208
+ {
209
+ for (var _iterator2 = _createForOfIteratorHelperLoose(arrayValue), _step2; !(_step2 = _iterator2()).done;) {
210
+ var _item = _step2.value;
211
+ newParam.append(key + "[]", _item);
212
+ }
213
+ break;
214
+ }
215
+ default:
216
+ {
217
+ var _csvValue = arrayValue.join(',');
218
+ newParam.set(key, _csvValue);
219
+ }
220
+ }
221
+ } else {
222
+ newParam.set(key, params[key]);
223
+ }
224
+ }
225
+ console.log({
226
+ FINAL: newParam.toString()
227
+ });
228
+ return newParam;
229
+ };
230
+ // @ts-ignore
231
+ var hasForcedParamsValues = function hasForcedParamsValues(_ref2) {
232
+ var paramsForced = _ref2.paramsForced,
233
+ compareParams = _ref2.compareParams;
234
+ // Iterates over the forced parameters and verifies that they exist in the URL and match their values
235
+ // Ej: { page: 1, page_size: 10 } === { page: 1, page_size: 10 } => true
236
+ var allParamsMatch = Object.entries(paramsForced).every(function (_ref3) {
237
+ var key = _ref3[0],
238
+ value = _ref3[1];
239
+ return compareParams[key] === value;
240
+ });
241
+ return allParamsMatch;
242
+ };
243
+ react.useEffect(function () {
244
+ var keysDefaultParams = Object.keys(defaultParams);
245
+ var keysForceParams = Object.keys(forceParams);
246
+ if (keysDefaultParams.length === 0 && keysForceParams.length === 0) return;
247
+ function handleStartingParams() {
248
+ var defaultParamsString = transformParamsToURLSearch(defaultParams).toString();
249
+ var paramsUrl = getParams();
250
+ var paramsUrlString = transformParamsToURLSearch(paramsUrl).toString();
251
+ var forceParamsString = transformParamsToURLSearch(forceParams).toString();
252
+ console.log({
253
+ defaultParamsString: defaultParamsString
254
+ });
255
+ var isForcedParams = hasForcedParamsValues({
256
+ paramsForced: forceParams,
257
+ compareParams: paramsUrl
258
+ });
259
+ if (!isForcedParams) {
260
+ // In this case, the forced parameters take precedence over the default parameters and the parameters of the current URL (which could have been modified by the user, e.g., page_size=1000)
261
+ updateParams({
262
+ newParams: _extends({}, defaultParams, forceParams)
263
+ });
264
+ return;
265
+ }
266
+ // In this way it will be validated that the forced parameters keys and values are in the current URL
267
+ var isIncludesForcedParams = hasForcedParamsValues({
268
+ paramsForced: forceParamsString,
269
+ compareParams: defaultParams
270
+ });
271
+ if (keysDefaultParams.length > 0 && isIncludesForcedParams) {
272
+ if (defaultParamsString === paramsUrlString) return; // this means that the URL already has the default parameters
273
+ updateParams({
274
+ newParams: defaultParams
275
+ });
276
+ }
277
+ }
278
+ handleStartingParams();
279
+ // eslint-disable-next-line react-hooks/exhaustive-deps
280
+ }, []);
281
+ /**
282
+ * Convert a string value to its original type (number, boolean, array) according to TOTAL_PARAMS_PAGE
283
+ * @param value - Chain obtained from the URL
284
+ * @param key - Key of the parameter
285
+ */
286
+ var convertOriginalType = function convertOriginalType(value, key) {
287
+ // Given that the parameters of a URL are recieved as strings, they are converted to their original type
288
+ if (typeof TOTAL_PARAMS_PAGE[key] === 'number') {
289
+ return parseInt(value);
290
+ } else if (typeof TOTAL_PARAMS_PAGE[key] === 'boolean') {
291
+ return value === 'true';
292
+ } else if (Array.isArray(TOTAL_PARAMS_PAGE[key])) {
293
+ // The result will be a valid array represented in the URL ej: tags=tag1,tag2,tag3 to ['tag1', 'tag2', 'tag3'], useful to combine the values of the arrays with the new ones
294
+ if (arraySerialization === 'csv') {
295
+ return searchParams.getAll(key).join('').split(',');
296
+ } else if (arraySerialization === 'repeat') {
297
+ console.log({
298
+ SEARCH_PARAMS: searchParams.getAll(key)
299
+ });
300
+ return searchParams.getAll(key);
301
+ } else if (arraySerialization === 'brackets') {
302
+ return searchParams.getAll(key + "[]");
303
+ }
304
+ }
305
+ // Note: dates are not converted as it is better to handle them directly in the component that receives them, using a library like < date-fns >
306
+ return value;
307
+ };
308
+ /**
309
+ * Gets the current parameters from the URL and converts them to their original type if desired
310
+ * @param convert - If true, converts from string to the inferred type (number, boolean, ...)
311
+ */
312
+ var getStringUrl = function getStringUrl(key, paramsUrl) {
313
+ var isKeyArray = Array.isArray(TOTAL_PARAMS_PAGE[key]);
314
+ if (isKeyArray) {
315
+ var _transformParamsToURL3;
316
+ if (arraySerialization === 'brackets') {
317
+ var _transformParamsToURL;
318
+ var arrayUrl = searchParams.getAll(key + "[]");
319
+ var encodedQueryArray = transformParamsToURLSearch((_transformParamsToURL = {}, _transformParamsToURL[key] = arrayUrl, _transformParamsToURL)).toString();
320
+ // in this way the array of the URL is decoded to its original form ej: tags[]=tag1&tags[]=tag2&tags[]=tag3
321
+ var unencodeQuery = decodeURIComponent(encodedQueryArray);
322
+ return unencodeQuery;
323
+ } else if (arraySerialization === 'csv') {
324
+ var _transformParamsToURL2;
325
+ var _arrayValue = searchParams.getAll(key);
326
+ var _encodedQueryArray = transformParamsToURLSearch((_transformParamsToURL2 = {}, _transformParamsToURL2[key] = _arrayValue, _transformParamsToURL2)).toString();
327
+ var _unencodeQuery = decodeURIComponent(_encodedQueryArray);
328
+ return _unencodeQuery;
329
+ }
330
+ var arrayValue = searchParams.getAll(key);
331
+ var stringResult = transformParamsToURLSearch((_transformParamsToURL3 = {}, _transformParamsToURL3[key] = arrayValue, _transformParamsToURL3)).toString();
332
+ return stringResult;
333
+ } else {
334
+ return paramsUrl[key];
335
+ }
336
+ };
337
+ var getParamsObj = function getParamsObj(searchParams) {
338
+ var paramsObj = {};
339
+ // @ts-ignore
340
+ for (var _iterator3 = _createForOfIteratorHelperLoose(searchParams.entries()), _step3; !(_step3 = _iterator3()).done;) {
341
+ var _step3$value = _step3.value,
342
+ key = _step3$value[0],
343
+ value = _step3$value[1];
344
+ if (key.endsWith('[]')) {
345
+ var bareKey = key.replace('[]', '');
346
+ if (paramsObj[bareKey]) {
347
+ paramsObj[bareKey].push(value);
348
+ } else {
349
+ paramsObj[bareKey] = [value];
350
+ }
351
+ } else {
352
+ // If the key already exists, it is a repeated parameter
353
+ if (paramsObj[key]) {
354
+ if (Array.isArray(paramsObj[key])) {
355
+ paramsObj[key].push(value);
356
+ } else {
357
+ paramsObj[key] = [paramsObj[key], value];
358
+ }
359
+ } else {
360
+ paramsObj[key] = value;
361
+ }
362
+ }
363
+ }
364
+ return paramsObj;
365
+ };
366
+ // Optimization: While the parameters are not updated, the current parameters of the URL are not recalculated
367
+ var CURRENT_PARAMS_URL = react.useMemo(function () {
368
+ return arraySerialization === 'brackets' ? getParamsObj(searchParams) : Object.fromEntries(searchParams.entries());
369
+ }, [searchParams, arraySerialization]);
370
+ var getParams = function getParams(_temp) {
371
+ var _ref4 = _temp === void 0 ? {} : _temp,
372
+ _ref4$convert = _ref4.convert,
373
+ convert = _ref4$convert === void 0 ? true : _ref4$convert;
374
+ // All the paramteres are extracted from the URL and converted into an object
375
+ var params = Object.keys(CURRENT_PARAMS_URL).reduce(function (acc, key) {
376
+ if (Object.prototype.hasOwnProperty.call(TOTAL_PARAMS_PAGE, key)) {
377
+ var realKey = arraySerialization === 'brackets' ? key.replace('[]', '') : key;
378
+ // @ts-ignore
379
+ acc[realKey] = convert === true ? convertOriginalType(CURRENT_PARAMS_URL[key], key) : getStringUrl(key, CURRENT_PARAMS_URL);
380
+ }
381
+ return acc;
382
+ }, {});
383
+ return params;
384
+ };
385
+ var getParam = function getParam(key, options) {
386
+ var keyStr = String(key);
387
+ // @ts-ignore
388
+ var value = (options == null ? void 0 : options.convert) === true ? convertOriginalType(searchParams.get(keyStr), keyStr) : getStringUrl(keyStr, CURRENT_PARAMS_URL);
389
+ return value;
390
+ };
391
+ var calculateOmittedParameters = function calculateOmittedParameters(newParams, keepParams) {
392
+ // Calculate the ommited parameters, that is, the parameters that have not been sent in the request
393
+ var params = getParams();
394
+ // hasOw
395
+ // Note: it will be necessary to omit the parameters that are arrays because the idea is not to replace them but to add or remove some values
396
+ var newParamsWithoutArray = Object.entries(newParams).filter(function (_ref5) {
397
+ var key = _ref5[0];
398
+ return !Array.isArray(TOTAL_PARAMS_PAGE[key]);
399
+ });
400
+ var result = Object.assign(_extends({}, params, Object.fromEntries(newParamsWithoutArray), forceParams));
401
+ var paramsFiltered = Object.keys(result).reduce(function (acc, key) {
402
+ // for default no parameters are omitted unless specified in the keepParams object
403
+ if (Object.prototype.hasOwnProperty.call(keepParams, key) && keepParams[key] === false) {
404
+ return acc;
405
+ // Note: They array of parameters omitted by values (e.g., ['all', 'default']) are omitted since they are usually a default value that is not desired to be sent
406
+ } else if (!!result[key] !== false && !omitParamsByValues.includes(result[key])) {
407
+ // @ts-ignore
408
+ acc[key] = result[key];
409
+ }
410
+ return acc;
411
+ }, {});
412
+ return _extends({}, mandatory, paramsFiltered);
413
+ };
414
+ // @ts-ignore
415
+ var sortParameters = function sortParameters(paramsFiltered) {
416
+ // sort the parameters according to the structure so that it persists with each change in the URL, eg: localhost:3000/?page=1&page_size=10
417
+ // Note: this visibly improves the user experience
418
+ var orderedParams = PARAM_ORDER.reduce(function (acc, key) {
419
+ if (Object.prototype.hasOwnProperty.call(paramsFiltered, key)) {
420
+ // @ts-ignore
421
+ acc[key] = paramsFiltered[key];
422
+ }
423
+ return acc;
424
+ }, {});
425
+ return orderedParams;
426
+ };
427
+ var mandatoryParameters = function mandatoryParameters() {
428
+ // Note: in case there are arrays in the URL, they are converted to their original form ej: tags=['tag1', 'tag2'] otherwise the parameters are extracted without converting to optimize performance
429
+ var isNecessaryConvert = ARRAY_KEYS.length > 0 ? true : false;
430
+ var totalParametros = getParams({
431
+ convert: isNecessaryConvert
432
+ });
433
+ var paramsUrlFound = Object.keys(totalParametros).reduce(function (acc, key) {
434
+ if (Object.prototype.hasOwnProperty.call(mandatory, key)) {
435
+ // @ts-ignore
436
+ acc[key] = totalParametros[key];
437
+ }
438
+ return acc;
439
+ }, {});
440
+ return paramsUrlFound;
441
+ };
442
+ var clearParams = function clearParams(_temp2) {
443
+ var _ref6 = _temp2 === void 0 ? {} : _temp2,
444
+ _ref6$keepMandatoryPa = _ref6.keepMandatoryParams,
445
+ keepMandatoryParams = _ref6$keepMandatoryPa === void 0 ? true : _ref6$keepMandatoryPa;
446
+ // for default, the mandatory parameters are not cleared since the current pagination would be lost
447
+ var paramsTransformed = transformParamsToURLSearch(_extends({}, mandatory, keepMandatoryParams && _extends({}, mandatoryParameters()), forceParams));
448
+ setSearchParams(paramsTransformed);
449
+ };
450
+ var updateParams = function updateParams(_temp3) {
451
+ var _ref7 = _temp3 === void 0 ? {} : _temp3,
452
+ _ref7$newParams = _ref7.newParams,
453
+ newParams = _ref7$newParams === void 0 ? {} : _ref7$newParams,
454
+ _ref7$keepParams = _ref7.keepParams,
455
+ keepParams = _ref7$keepParams === void 0 ? {} : _ref7$keepParams;
456
+ if (Object.keys(newParams).length === 0 && Object.keys(keepParams).length === 0) {
457
+ clearParams();
458
+ return;
459
+ }
460
+ // @ts-ignore
461
+ var finallyParamters = calculateOmittedParameters(newParams, keepParams);
462
+ var convertedArrayValues = appendArrayValues(finallyParamters, newParams);
463
+ var paramsSorted = sortParameters(convertedArrayValues);
464
+ setSearchParams(transformParamsToURLSearch(paramsSorted));
465
+ };
466
+ // only for the keys of the parameters to subscribe to changes in the URL to trigger the callback
467
+ var onChange = react.useCallback(function (paramName, callbacks) {
468
+ var paramNameStr = String(paramName);
469
+ // replace the previous callbacks with the new ones so as not to accumulate callbacks
470
+ subscriptionsRef.current[paramNameStr] = callbacks;
471
+ }, []);
472
+ // each time searchParams changes, we notify the subscribers
473
+ react.useEffect(function () {
474
+ for (var _i2 = 0, _Object$entries = Object.entries(subscriptionsRef.current); _i2 < _Object$entries.length; _i2++) {
475
+ var _CURRENT_PARAMS_URL$k, _previousParamsRef$cu;
476
+ var _Object$entries$_i = _Object$entries[_i2],
477
+ key = _Object$entries$_i[0],
478
+ value = _Object$entries$_i[1];
479
+ var newValue = (_CURRENT_PARAMS_URL$k = CURRENT_PARAMS_URL[key]) != null ? _CURRENT_PARAMS_URL$k : null;
480
+ var oldValue = (_previousParamsRef$cu = previousParamsRef.current[key]) != null ? _previousParamsRef$cu : null;
481
+ if (newValue !== oldValue) {
482
+ for (var _iterator4 = _createForOfIteratorHelperLoose(value), _step4; !(_step4 = _iterator4()).done;) {
483
+ var callback = _step4.value;
484
+ console.log(value);
485
+ callback();
486
+ }
487
+ }
488
+ // once the callback is executed, the previous value is updated to ensure that the next time the value changes, the callback is executed
489
+ previousParamsRef.current[key] = newValue;
490
+ }
491
+ }, [CURRENT_PARAMS_URL]);
492
+ return {
493
+ searchParams: searchParams,
494
+ updateParams: updateParams,
495
+ clearParams: clearParams,
496
+ getParams: getParams,
497
+ getParam: getParam,
498
+ onChange: onChange
499
+ };
500
+ };
501
+
502
+ exports.useMagicSearchParams = useMagicSearchParams;
503
+ //# sourceMappingURL=react-magic-search-params.cjs.development.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react-magic-search-params.cjs.development.js","sources":["../src/useMagicSearchParams.ts"],"sourcesContent":["import { useSearchParams } from 'react-router-dom'\r\nimport { useMemo, useEffect, useRef, useCallback } from 'react'\r\n\r\n\r\n// Custom hook with advanced techniques to handle search parameters for any pagination\r\n\r\ntype CommonParams = {\r\n page?: number\r\n page_size?: number\r\n}\r\n/*\r\nMaps all properties of M (mandatory) as required\r\nand all properties of O (optional) as optional. \r\n*/\r\ntype MergeParams<M, O> = {\r\n [K in keyof M]: M[K]\r\n} & {\r\n [K in keyof O]?: O[K]\r\n}\r\n/**\r\n * Interface for the configuration object that the hook receives \r\n */\r\ninterface UseMagicSearchParamsOptions<\r\n M extends Record<string, unknown>,\r\n O extends Record<string, unknown>\r\n> {\r\n mandatory: M \r\n optional?: O\r\n defaultParams?: Partial<MergeParams<M, O>>\r\n forceParams?: Partial<MergeParams<M, O>> // transform all to partial to avoid errors\r\n arraySerialization?: 'csv' | 'repeat' | 'brackets' // technical to serialize arrays in the URL\r\n omitParamsByValues?: Array<'all' | 'default' | 'unknown' | 'none' | 'void '> \r\n}\r\n\r\n/** \r\nGeneric hook to handle search parameters in the URL\r\n@param mandatory - Mandatory parameters (e.g., page=1, page_size=10, etc.)\r\n@param optional - Optional parameters (e.g., order, search, etc.)\r\n@param defaultParams - Default parameters sent in the URL on initialization\r\n@param forceParams - Parameters forced into the URL regardless of user input\r\n@param omitParamsByValues - Parameters omitted if they have specific values \r\n*/\r\nexport const useMagicSearchParams = <\r\n M extends Record<string, unknown> & CommonParams,\r\n O extends Record<string, unknown>,\r\n>({\r\n mandatory = {} as M,\r\n optional = {} as O,\r\n defaultParams = {} as Partial<MergeParams<M, O>>,\r\n arraySerialization = 'csv',\r\n forceParams = {} as {} as Partial<MergeParams<M, O>>,\r\n omitParamsByValues = [] as Array<'all' | 'default' | 'unknown' | 'none' | 'void '>\r\n}: UseMagicSearchParamsOptions<M, O>)=> {\r\n\r\n\r\n const [searchParams, setSearchParams] = useSearchParams() \r\n // Ref to store subscriptions: { paramName: [callback1, callback2, ...] }\r\n const subscriptionsRef = useRef<Record<string, Array<() => unknown>>>({}); \r\n const previousParamsRef = useRef<Record<string, unknown>>({})\r\n\r\n const TOTAL_PARAMS_PAGE: MergeParams<M, O> = useMemo(() => {\r\n return { ...mandatory, ...optional };\r\n }, [mandatory, optional]);\r\n\r\n const PARAM_ORDER = useMemo(() => {\r\n return Array.from(Object.keys(TOTAL_PARAMS_PAGE))\r\n }, [TOTAL_PARAMS_PAGE])\r\n\r\n // we get the keys that are arrays according to TOTAL_PARAMS_PAGE since these require special treatment in the URL due to serialization mode\r\n const ARRAY_KEYS = useMemo(() => {\r\n return Object.keys(TOTAL_PARAMS_PAGE).filter(\r\n (key) => Array.isArray(TOTAL_PARAMS_PAGE[key])\r\n );\r\n }, [TOTAL_PARAMS_PAGE])\r\n\r\n const appendArrayValues = (\r\n finallyParams: Record<string, unknown>,\r\n newParams: Record<string, string | string[] | unknown>\r\n ): Record<string, unknown> => {\r\n \r\n // Note: We cannot modify the object of the final parameters directly, as immutability must be maintained\r\n const updatedParams = { ...finallyParams };\r\n \r\n\r\n if (ARRAY_KEYS.length === 0) return updatedParams;\r\n \r\n ARRAY_KEYS.forEach((key) => {\r\n // We use the current values directly from searchParams (source of truth)\r\n // This avoids depending on finallyParams in which the arrays have been omitted\r\n let currentValues = []; \r\n switch (arraySerialization) {\r\n case 'csv': {\r\n const raw = searchParams.get(key) || '';\r\n // For csv we expect \"value1,value2,...\" (no prefix)\r\n currentValues = raw.split(',')\r\n .map((v) => v.trim())\r\n .filter(Boolean) as Array<string>\r\n break;\r\n }\r\n case 'repeat': {\r\n // Here we get all ocurrences of key\r\n const urlParams = searchParams.getAll(key) as Array<string>\r\n currentValues = urlParams.length > 0 ? urlParams : []\r\n \r\n console.log({REPEAT: currentValues})\r\n break;\r\n }\r\n case 'brackets': {\r\n // Build URLSearchParams from current parameters (to ensure no serialized values are taken previously)\r\n const urlParams = searchParams.getAll(`${key}[]`) as Array<string>\r\n currentValues = urlParams.length > 0 ? urlParams : []\r\n console.log({BRACKETS: urlParams})\r\n \r\n \r\n break;\r\n }\r\n default: {\r\n // Mode by default works as csv\r\n const raw = searchParams.get(key) ?? '';\r\n currentValues = raw.split(',')\r\n .map((v) => v.trim())\r\n .filter(Boolean);\r\n }\r\n break; \r\n }\r\n // Update array values with new ones\r\n \r\n if (newParams[key] !== undefined) {\r\n const incoming = newParams[key];\r\n let combined: string[] = []\r\n if (typeof incoming === 'string') {\r\n // If it is a string, it is toggled (add/remove)\r\n combined = currentValues.includes(incoming)\r\n ? currentValues.filter((v) => v !== incoming)\r\n : [...currentValues, incoming];\r\n console.log({currentValues})\r\n console.log({incoming})\r\n console.log({CONBINED_STRING: combined})\r\n } else if (Array.isArray(incoming)) {\r\n // if an array is passed, repeated values are merged into a single value\r\n // Note: Set is used to remove duplicates\r\n combined = Array.from(new Set([ ...incoming]));\r\n console.log({incoming})\r\n console.log({combined})\r\n } else {\r\n \r\n combined = currentValues;\r\n }\r\n\r\n updatedParams[key] = combined\r\n\r\n }\r\n });\r\n console.log({updatedParams})\r\n return updatedParams\r\n };\r\n\r\n const transformParamsToURLSearch = (params: Record<string, unknown>): URLSearchParams => {\r\n console.log({PARAMS_RECIBIDOS_TRANSFORM: params})\r\n\r\n const newParam: URLSearchParams = new URLSearchParams()\r\n\r\n const paramsKeys = Object.keys(params)\r\n\r\n for (const key of paramsKeys) {\r\n if (Array.isArray(TOTAL_PARAMS_PAGE[key])) {\r\n const arrayValue = params[key] as unknown[]\r\n console.log({arrayValue})\r\n switch (arraySerialization) {\r\n case 'csv': {\r\n const csvValue = arrayValue.join(',')\r\n // set ensure that the previous value is replaced\r\n newParam.set(key, csvValue)\r\n break\r\n } case 'repeat': {\r\n \r\n for (const item of arrayValue) {\r\n console.log({item})\r\n // add new value to the key, instead of replacing it\r\n newParam.append(key, item as string)\r\n \r\n }\r\n break\r\n } case 'brackets': {\r\n for (const item of arrayValue) {\r\n newParam.append(`${key}[]`, item as string)\r\n }\r\n break\r\n } default: {\r\n const csvValue = arrayValue.join(',')\r\n newParam.set(key, csvValue)\r\n }\r\n }\r\n } else {\r\n newParam.set(key, params[key] as string)\r\n }\r\n }\r\n console.log({FINAL: newParam.toString()})\r\n return newParam\r\n }\r\n // @ts-ignore\r\n const hasForcedParamsValues = ({ paramsForced, compareParams }) => {\r\n\r\n // Iterates over the forced parameters and verifies that they exist in the URL and match their values\r\n // Ej: { page: 1, page_size: 10 } === { page: 1, page_size: 10 } => true\r\n const allParamsMatch = Object.entries(paramsForced).every(\r\n ([key, value]) => compareParams[key] === value\r\n );\r\n\r\n return allParamsMatch;\r\n };\r\n \r\n useEffect(() => {\r\n\r\n const keysDefaultParams: string[] = Object.keys(defaultParams)\r\n const keysForceParams: string[] = Object.keys(forceParams)\r\n if(keysDefaultParams.length === 0 && keysForceParams.length === 0) return\r\n \r\n\r\n function handleStartingParams() {\r\n\r\n const defaultParamsString = transformParamsToURLSearch(defaultParams).toString()\r\n const paramsUrl = getParams()\r\n const paramsUrlString = transformParamsToURLSearch(paramsUrl).toString()\r\n const forceParamsString = transformParamsToURLSearch(forceParams).toString()\r\n\r\n console.log({defaultParamsString})\r\n\r\n const isForcedParams: boolean = hasForcedParamsValues({ paramsForced: forceParams, compareParams: paramsUrl })\r\n\r\n if (!isForcedParams) {\r\n\r\n // In this case, the forced parameters take precedence over the default parameters and the parameters of the current URL (which could have been modified by the user, e.g., page_size=1000)\r\n\r\n updateParams({ newParams: {\r\n ...defaultParams,\r\n ...forceParams\r\n }})\r\n return\r\n }\r\n // In this way it will be validated that the forced parameters keys and values are in the current URL\r\n const isIncludesForcedParams = hasForcedParamsValues({ paramsForced: forceParamsString, compareParams: defaultParams })\r\n\r\n if (keysDefaultParams.length > 0 && isIncludesForcedParams) {\r\n if (defaultParamsString === paramsUrlString) return // this means that the URL already has the default parameters\r\n updateParams({ newParams: defaultParams })\r\n }\r\n\r\n }\r\n handleStartingParams()\r\n\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n /**\r\n * Convert a string value to its original type (number, boolean, array) according to TOTAL_PARAMS_PAGE\r\n * @param value - Chain obtained from the URL\r\n * @param key - Key of the parameter\r\n */\r\n const convertOriginalType = (value: string, key: string) => {\r\n // Given that the parameters of a URL are recieved as strings, they are converted to their original type\r\n if (typeof TOTAL_PARAMS_PAGE[key] === 'number') {\r\n return parseInt(value)\r\n } else if (typeof TOTAL_PARAMS_PAGE[key] === 'boolean') {\r\n return value === 'true'\r\n } else if (Array.isArray(TOTAL_PARAMS_PAGE[key])) {\r\n // The result will be a valid array represented in the URL ej: tags=tag1,tag2,tag3 to ['tag1', 'tag2', 'tag3'], useful to combine the values of the arrays with the new ones\r\n \r\n if (arraySerialization === 'csv') {\r\n return searchParams.getAll(key).join('').split(',')\r\n } else if (arraySerialization === 'repeat') {\r\n \r\n console.log({SEARCH_PARAMS: searchParams.getAll(key)})\r\n return searchParams.getAll(key)\r\n } else if (arraySerialization === 'brackets') {\r\n return searchParams.getAll(`${key}[]`)\r\n }\r\n \r\n \r\n }\r\n // Note: dates are not converted as it is better to handle them directly in the component that receives them, using a library like < date-fns >\r\n return value\r\n }\r\n \r\n /**\r\n * Gets the current parameters from the URL and converts them to their original type if desired\r\n * @param convert - If true, converts from string to the inferred type (number, boolean, ...)\r\n */\r\n const getStringUrl = (key: string, paramsUrl: Record<string, unknown>) => {\r\n const isKeyArray = Array.isArray(TOTAL_PARAMS_PAGE[key])\r\n if (isKeyArray) {\r\n\r\n if (arraySerialization === 'brackets') {\r\n\r\n const arrayUrl = searchParams.getAll(`${key}[]`)\r\n const encodedQueryArray = transformParamsToURLSearch({ [key]: arrayUrl }).toString()\r\n // in this way the array of the URL is decoded to its original form ej: tags[]=tag1&tags[]=tag2&tags[]=tag3\r\n const unencodeQuery = decodeURIComponent(encodedQueryArray)\r\n return unencodeQuery\r\n } else if (arraySerialization === 'csv') {\r\n const arrayValue = searchParams.getAll(key)\r\n const encodedQueryArray = transformParamsToURLSearch({ [key]: arrayValue }).toString()\r\n const unencodeQuery = decodeURIComponent(encodedQueryArray)\r\n return unencodeQuery\r\n }\r\n const arrayValue = searchParams.getAll(key)\r\n const stringResult = transformParamsToURLSearch({ [key]: arrayValue }).toString()\r\n return stringResult\r\n } else {\r\n \r\n return paramsUrl[key] as string\r\n }\r\n }\r\n const getParamsObj = (searchParams: URLSearchParams): Record<string, string | string[]> => {\r\n const paramsObj: Record<string, string | string[]> = {};\r\n // @ts-ignore\r\n for (const [key, value] of searchParams.entries()) {\r\n if (key.endsWith('[]')) {\r\n const bareKey = key.replace('[]', '');\r\n if (paramsObj[bareKey]) {\r\n (paramsObj[bareKey] as string[]).push(value);\r\n } else {\r\n paramsObj[bareKey] = [value];\r\n }\r\n } else {\r\n // If the key already exists, it is a repeated parameter\r\n if (paramsObj[key]) {\r\n if (Array.isArray(paramsObj[key])) {\r\n (paramsObj[key] as string[]).push(value);\r\n } else {\r\n paramsObj[key] = [paramsObj[key] as string, value];\r\n }\r\n } else {\r\n paramsObj[key] = value;\r\n }\r\n }\r\n }\r\n return paramsObj;\r\n }\r\n // Optimization: While the parameters are not updated, the current parameters of the URL are not recalculated\r\n const CURRENT_PARAMS_URL: Record<string, unknown> = useMemo(() => {\r\n\r\n return arraySerialization === 'brackets' ? getParamsObj(searchParams) : Object.fromEntries(searchParams.entries())\r\n }, [searchParams, arraySerialization])\r\n\r\n const getParams = ({ convert = true } = {}): MergeParams<M, O> => {\r\n // All the paramteres are extracted from the URL and converted into an object\r\n\r\n const params = Object.keys(CURRENT_PARAMS_URL).reduce((acc, key) => {\r\n if (Object.prototype.hasOwnProperty.call(TOTAL_PARAMS_PAGE, key)) {\r\n const realKey = arraySerialization === 'brackets' ? key.replace('[]', '') : key\r\n // @ts-ignore\r\n acc[realKey] = convert === true\r\n ? convertOriginalType(CURRENT_PARAMS_URL[key] as string, key)\r\n : getStringUrl(key, CURRENT_PARAMS_URL)\r\n }\r\n return acc\r\n }, {})\r\n \r\n return params as MergeParams<M, O>\r\n }\r\n type keys = keyof MergeParams<M, O>\r\n // Note: in this way the return of the getParam function is typed dynamically, thus having autocomplete in the IDE (eg: value.split(','))\r\n type TagReturn<T extends boolean> = T extends true ? string[] : string;\r\n const getParam = <T extends boolean>(key: keys, options?: { convert: T }): TagReturn<T> => {\r\n\r\n const keyStr = String(key)\r\n // @ts-ignore\r\n const value = options?.convert === true ? convertOriginalType(searchParams.get(keyStr), keyStr) : getStringUrl(keyStr, CURRENT_PARAMS_URL)\r\n return value as TagReturn<T> \r\n }\r\n \r\n type OptionalParamsFiltered = Partial<O>\r\n\r\n const calculateOmittedParameters = (newParams: Record<string, unknown | unknown[]>, keepParams: Record<string, boolean>) => {\r\n // Calculate the ommited parameters, that is, the parameters that have not been sent in the request\r\n const params = getParams()\r\n // hasOw\r\n // Note: it will be necessary to omit the parameters that are arrays because the idea is not to replace them but to add or remove some values\r\n const newParamsWithoutArray = Object.entries(newParams).filter(([key,]) => !Array.isArray(TOTAL_PARAMS_PAGE[key]))\r\n const result = Object.assign({\r\n ...params,\r\n ...Object.fromEntries(newParamsWithoutArray),\r\n ...forceParams // the forced parameters will always be sent and will maintain their value\r\n })\r\n const paramsFiltered: OptionalParamsFiltered = Object.keys(result).reduce((acc, key) => {\r\n // for default no parameters are omitted unless specified in the keepParams object\r\n if (Object.prototype.hasOwnProperty.call(keepParams, key) && keepParams[key] === false) {\r\n return acc\r\n // Note: They array of parameters omitted by values (e.g., ['all', 'default']) are omitted since they are usually a default value that is not desired to be sent\r\n } else if (!!result[key] !== false && !omitParamsByValues.includes(result[key])) {\r\n // @ts-ignore\r\n acc[key] = result[key]\r\n }\r\n\r\n return acc\r\n }, {})\r\n\r\n return {\r\n ...mandatory,\r\n ...paramsFiltered\r\n } \r\n }\r\n // @ts-ignore\r\n const sortParameters = (paramsFiltered) => {\r\n // sort the parameters according to the structure so that it persists with each change in the URL, eg: localhost:3000/?page=1&page_size=10\r\n // Note: this visibly improves the user experience\r\n const orderedParams = PARAM_ORDER.reduce((acc, key) => {\r\n if (Object.prototype.hasOwnProperty.call(paramsFiltered, key)) {\r\n // @ts-ignore\r\n acc[key] = paramsFiltered[key]\r\n }\r\n\r\n return acc\r\n }, {})\r\n return orderedParams\r\n }\r\n\r\n const mandatoryParameters = () => {\r\n // Note: in case there are arrays in the URL, they are converted to their original form ej: tags=['tag1', 'tag2'] otherwise the parameters are extracted without converting to optimize performance\r\n const isNecessaryConvert: boolean = ARRAY_KEYS.length > 0 ? true : false\r\n const totalParametros: Record<string, unknown> = getParams({ convert: isNecessaryConvert })\r\n\r\n const paramsUrlFound: Record<string, boolean> = Object.keys(totalParametros).reduce(\r\n (acc, key) => {\r\n if (Object.prototype.hasOwnProperty.call(mandatory, key)) {\r\n // @ts-ignore\r\n acc[key] = totalParametros[key]\r\n }\r\n return acc\r\n },\r\n {}\r\n )\r\n\r\n return paramsUrlFound\r\n }\r\n\r\n const clearParams = ({ keepMandatoryParams = true } = {}): void => {\r\n // for default, the mandatory parameters are not cleared since the current pagination would be lost\r\n const paramsTransformed = transformParamsToURLSearch(\r\n {\r\n ...mandatory,\r\n \r\n ...(keepMandatoryParams && {\r\n ...mandatoryParameters()\r\n }),\r\n ...forceParams \r\n }\r\n )\r\n setSearchParams(paramsTransformed) \r\n }\r\n\r\n // transforms the keys to boolean to know which parameters to keep\r\n type KeepParamsTransformedValuesBoolean = Partial<Record<keyof typeof TOTAL_PARAMS_PAGE, boolean>>\r\n type NewParams = Partial<typeof TOTAL_PARAMS_PAGE> \r\n type KeepParams = KeepParamsTransformedValuesBoolean\r\n const updateParams = ({ newParams = {} as NewParams, keepParams = {} as KeepParams } = {}) => {\r\n\r\n if (\r\n Object.keys(newParams).length === 0 &&\r\n Object.keys(keepParams).length === 0\r\n ) {\r\n clearParams()\r\n return\r\n }\r\n // @ts-ignore\r\n const finallyParamters = calculateOmittedParameters(newParams, keepParams)\r\n\r\n const convertedArrayValues = appendArrayValues(finallyParamters, newParams)\r\n\r\n const paramsSorted = sortParameters(convertedArrayValues)\r\n\r\n setSearchParams(transformParamsToURLSearch(paramsSorted))\r\n\r\n }\r\n\r\n // only for the keys of the parameters to subscribe to changes in the URL to trigger the callback\r\n const onChange = useCallback( (paramName: keys, callbacks: Array<() => void>) => {\r\n const paramNameStr = String(paramName)\r\n // replace the previous callbacks with the new ones so as not to accumulate callbacks\r\n subscriptionsRef.current[paramNameStr] = callbacks;\r\n }, [])\r\n \r\n // each time searchParams changes, we notify the subscribers\r\n useEffect(() => {\r\n\r\n for (const [key, value] of Object.entries(subscriptionsRef.current)) {\r\n\r\n const newValue = CURRENT_PARAMS_URL[key] ?? null \r\n const oldValue = previousParamsRef.current[key] ?? null\r\n if (newValue !== oldValue) {\r\n \r\n for (const callback of value) {\r\n console.log(value)\r\n\r\n callback()\r\n\r\n }\r\n }\r\n // once the callback is executed, the previous value is updated to ensure that the next time the value changes, the callback is executed\r\n previousParamsRef.current[key] = newValue\r\n }\r\n\r\n \r\n }, [CURRENT_PARAMS_URL])\r\n return {\r\n searchParams,\r\n updateParams,\r\n clearParams,\r\n getParams,\r\n getParam,\r\n onChange\r\n }\r\n}\r\n"],"names":["useMagicSearchParams","_ref","mandatory","_ref$mandatory","_ref$optional","optional","_ref$defaultParams","defaultParams","_ref$arraySerializati","arraySerialization","_ref$forceParams","forceParams","_ref$omitParamsByValu","omitParamsByValues","_useSearchParams","useSearchParams","searchParams","setSearchParams","subscriptionsRef","useRef","previousParamsRef","TOTAL_PARAMS_PAGE","useMemo","_extends","PARAM_ORDER","Array","from","Object","keys","ARRAY_KEYS","filter","key","isArray","appendArrayValues","finallyParams","newParams","updatedParams","length","forEach","currentValues","raw","get","split","map","v","trim","Boolean","urlParams","getAll","console","log","REPEAT","BRACKETS","_searchParams$get","undefined","incoming","combined","includes","concat","CONBINED_STRING","Set","transformParamsToURLSearch","params","PARAMS_RECIBIDOS_TRANSFORM","newParam","URLSearchParams","paramsKeys","_i","_paramsKeys","arrayValue","csvValue","join","set","_iterator","_createForOfIteratorHelperLoose","_step","done","item","value","append","_iterator2","_step2","FINAL","toString","hasForcedParamsValues","_ref2","paramsForced","compareParams","allParamsMatch","entries","every","_ref3","useEffect","keysDefaultParams","keysForceParams","handleStartingParams","defaultParamsString","paramsUrl","getParams","paramsUrlString","forceParamsString","isForcedParams","updateParams","isIncludesForcedParams","convertOriginalType","parseInt","SEARCH_PARAMS","getStringUrl","isKeyArray","_transformParamsToURL3","_transformParamsToURL","arrayUrl","encodedQueryArray","unencodeQuery","decodeURIComponent","_transformParamsToURL2","stringResult","getParamsObj","paramsObj","_iterator3","_step3","_step3$value","endsWith","bareKey","replace","push","CURRENT_PARAMS_URL","fromEntries","_temp","_ref4$convert","_ref4","convert","reduce","acc","prototype","hasOwnProperty","call","realKey","getParam","options","keyStr","String","calculateOmittedParameters","keepParams","newParamsWithoutArray","_ref5","result","assign","paramsFiltered","sortParameters","orderedParams","mandatoryParameters","isNecessaryConvert","totalParametros","paramsUrlFound","clearParams","_temp2","_ref6$keepMandatoryPa","_ref6","keepMandatoryParams","paramsTransformed","_temp3","_ref7$newParams","_ref7","_ref7$keepParams","finallyParamters","convertedArrayValues","paramsSorted","onChange","useCallback","paramName","callbacks","paramNameStr","current","_i2","_Object$entries","_CURRENT_PARAMS_URL$k","_previousParamsRef$cu","_Object$entries$_i","newValue","oldValue","_iterator4","_step4","callback"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var r=require("react-router-dom"),e=require("react");function t(r,e){(null==e||e>r.length)&&(e=r.length);for(var t=0,n=Array(e);t<e;t++)n[t]=r[t];return n}function n(r,e){var n="undefined"!=typeof Symbol&&r[Symbol.iterator]||r["@@iterator"];if(n)return(n=n.call(r)).next.bind(n);if(Array.isArray(r)||(n=function(r,e){if(r){if("string"==typeof r)return t(r,e);var n={}.toString.call(r).slice(8,-1);return"Object"===n&&r.constructor&&(n=r.constructor.name),"Map"===n||"Set"===n?Array.from(r):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?t(r,e):void 0}}(r))||e&&r&&"number"==typeof r.length){n&&(r=n);var a=0;return function(){return a>=r.length?{done:!0}:{done:!1,value:r[a++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function a(){return(a=Object.assign?Object.assign.bind():function(r){for(var e=1;e<arguments.length;e++){var t=arguments[e];for(var n in t)({}).hasOwnProperty.call(t,n)&&(r[n]=t[n])}return r}).apply(null,arguments)}exports.useMagicSearchParams=function(t){var o=t.mandatory,c=void 0===o?{}:o,i=t.optional,l=void 0===i?{}:i,s=t.defaultParams,u=void 0===s?{}:s,f=t.arraySerialization,v=void 0===f?"csv":f,g=t.forceParams,m=void 0===g?{}:g,d=t.omitParamsByValues,y=void 0===d?[]:d,p=r.useSearchParams(),b=p[0],A=p[1],h=e.useRef({}),O=e.useRef({}),P=e.useMemo((function(){return a({},c,l)}),[c,l]),j=e.useMemo((function(){return Array.from(Object.keys(P))}),[P]),S=e.useMemo((function(){return Object.keys(P).filter((function(r){return Array.isArray(P[r])}))}),[P]),k=function(r){console.log({PARAMS_RECIBIDOS_TRANSFORM:r});for(var e=new URLSearchParams,t=0,a=Object.keys(r);t<a.length;t++){var o=a[t];if(Array.isArray(P[o])){var c=r[o];switch(console.log({arrayValue:c}),v){case"csv":var i=c.join(",");e.set(o,i);break;case"repeat":for(var l,s=n(c);!(l=s()).done;){var u=l.value;console.log({item:u}),e.append(o,u)}break;case"brackets":for(var f,g=n(c);!(f=g()).done;)e.append(o+"[]",f.value);break;default:var m=c.join(",");e.set(o,m)}}else e.set(o,r[o])}return console.log({FINAL:e.toString()}),e},w=function(r){var e=r.compareParams;return Object.entries(r.paramsForced).every((function(r){return e[r[0]]===r[1]}))};e.useEffect((function(){var r=Object.keys(u),e=Object.keys(m);0===r.length&&0===e.length||function(){var e=k(u).toString(),t=M(),n=k(t).toString(),o=k(m).toString();if(console.log({defaultParamsString:e}),w({paramsForced:m,compareParams:t})){var c=w({paramsForced:o,compareParams:u});if(r.length>0&&c){if(e===n)return;B({newParams:u})}}else B({newParams:a({},u,m)})}()}),[]);var R=function(r,e){if("number"==typeof P[e])return parseInt(r);if("boolean"==typeof P[e])return"true"===r;if(Array.isArray(P[e])){if("csv"===v)return b.getAll(e).join("").split(",");if("repeat"===v)return console.log({SEARCH_PARAMS:b.getAll(e)}),b.getAll(e);if("brackets"===v)return b.getAll(e+"[]")}return r},E=function(r,e){if(Array.isArray(P[r])){var t;if("brackets"===v){var n,a=b.getAll(r+"[]"),o=k((n={},n[r]=a,n)).toString();return decodeURIComponent(o)}if("csv"===v){var c,i=b.getAll(r),l=k((c={},c[r]=i,c)).toString();return decodeURIComponent(l)}var s=b.getAll(r);return k((t={},t[r]=s,t)).toString()}return e[r]},I=e.useMemo((function(){return"brackets"===v?function(r){for(var e,t={},a=n(r.entries());!(e=a()).done;){var o=e.value,c=o[0],i=o[1];if(c.endsWith("[]")){var l=c.replace("[]","");t[l]?t[l].push(i):t[l]=[i]}else t[c]?Array.isArray(t[c])?t[c].push(i):t[c]=[t[c],i]:t[c]=i}return t}(b):Object.fromEntries(b.entries())}),[b,v]),M=function(r){var e=(void 0===r?{}:r).convert,t=void 0===e||e;return Object.keys(I).reduce((function(r,e){return Object.prototype.hasOwnProperty.call(P,e)&&(r["brackets"===v?e.replace("[]",""):e]=!0===t?R(I[e],e):E(e,I)),r}),{})},C=function(r){var e,t=(void 0===r?{}:r).keepMandatoryParams,n=k(a({},c,(void 0===t||t)&&a({},(e=M({convert:S.length>0}),Object.keys(e).reduce((function(r,t){return Object.prototype.hasOwnProperty.call(c,t)&&(r[t]=e[t]),r}),{}))),m));A(n)},B=function(r){var e=void 0===r?{}:r,t=e.newParams,n=void 0===t?{}:t,o=e.keepParams,i=void 0===o?{}:o;if(0!==Object.keys(n).length||0!==Object.keys(i).length){var l,s=function(r,e){var t=a({},r);return 0===S.length||(S.forEach((function(r){var n=[];switch(v){case"csv":n=(b.get(r)||"").split(",").map((function(r){return r.trim()})).filter(Boolean);break;case"repeat":var a=b.getAll(r);n=a.length>0?a:[],console.log({REPEAT:n});break;case"brackets":var o=b.getAll(r+"[]");n=o.length>0?o:[],console.log({BRACKETS:o});break;default:var c;n=(null!=(c=b.get(r))?c:"").split(",").map((function(r){return r.trim()})).filter(Boolean)}if(void 0!==e[r]){var i=e[r],l=[];"string"==typeof i?(l=n.includes(i)?n.filter((function(r){return r!==i})):[].concat(n,[i]),console.log({currentValues:n}),console.log({incoming:i}),console.log({CONBINED_STRING:l})):Array.isArray(i)?(l=Array.from(new Set([].concat(i))),console.log({incoming:i}),console.log({combined:l})):l=n,t[r]=l}})),console.log({updatedParams:t})),t}(function(r,e){var t=M(),n=Object.entries(r).filter((function(r){return!Array.isArray(P[r[0]])})),o=Object.assign(a({},t,Object.fromEntries(n),m)),i=Object.keys(o).reduce((function(r,t){return Object.prototype.hasOwnProperty.call(e,t)&&!1===e[t]||0==!!o[t]||y.includes(o[t])||(r[t]=o[t]),r}),{});return a({},c,i)}(n,i),n),u=(l=s,j.reduce((function(r,e){return Object.prototype.hasOwnProperty.call(l,e)&&(r[e]=l[e]),r}),{}));A(k(u))}else C()},_=e.useCallback((function(r,e){var t=String(r);h.current[t]=e}),[]);return e.useEffect((function(){for(var r=0,e=Object.entries(h.current);r<e.length;r++){var t,a,o=e[r],c=o[0],i=o[1],l=null!=(t=I[c])?t:null;if(l!==(null!=(a=O.current[c])?a:null))for(var s,u=n(i);!(s=u()).done;){var f=s.value;console.log(i),f()}O.current[c]=l}}),[I]),{searchParams:b,updateParams:B,clearParams:C,getParams:M,getParam:function(r,e){var t=String(r);return!0===(null==e?void 0:e.convert)?R(b.get(t),t):E(t,I)},onChange:_}};
2
+ //# sourceMappingURL=react-magic-search-params.cjs.production.min.js.map