@kizmann/pico-js 1.0.13 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/README.md +27 -7
  2. package/dist/pico-js.browser.js +2 -0
  3. package/dist/pico-js.browser.js.map +1 -0
  4. package/dist/pico-js.esm.js +2 -0
  5. package/dist/pico-js.esm.js.map +1 -0
  6. package/package.json +20 -7
  7. package/src/dom/DomAttribute.js +374 -0
  8. package/src/dom/DomBuilder.js +152 -0
  9. package/src/dom/DomEvent.js +253 -0
  10. package/src/dom/DomFinder.js +669 -0
  11. package/src/dom/DomForm.js +57 -0
  12. package/src/dom/DomGlobal.js +193 -0
  13. package/src/dom/DomInview.js +332 -0
  14. package/src/dom/DomMeta.js +66 -0
  15. package/src/dom/DomObserver.js +57 -0
  16. package/src/dom/DomRectangle.js +657 -0
  17. package/src/format/FormatFile.js +54 -0
  18. package/src/format/FormatOption.js +108 -0
  19. package/src/format/FormatParam.js +107 -0
  20. package/src/format/FormatParser.js +156 -0
  21. package/src/format/FormatUrl.js +75 -0
  22. package/src/index.browser.js +10 -0
  23. package/src/index.esm.js +138 -0
  24. package/src/now/NowDefault.js +533 -0
  25. package/src/now/NowFormat.js +196 -0
  26. package/src/now/NowGrid.js +251 -0
  27. package/src/now/NowHuman.js +118 -0
  28. package/src/now/NowMatch.js +175 -0
  29. package/src/now/NowRange.js +70 -0
  30. package/src/now/NowWalker.js +544 -0
  31. package/src/tool/scope.js +103 -0
  32. package/src/utils/Array.js +986 -0
  33. package/src/utils/Cookie.js +184 -0
  34. package/src/utils/Data.js +200 -0
  35. package/src/utils/Dom.js +208 -0
  36. package/src/utils/Event.js +140 -0
  37. package/src/utils/Format.js +62 -0
  38. package/src/utils/Hash.js +164 -0
  39. package/src/utils/Locale.js +229 -0
  40. package/src/utils/Mixed.js +887 -0
  41. package/src/utils/Now.js +234 -0
  42. package/src/utils/Number.js +238 -0
  43. package/src/utils/Object.js +655 -0
  44. package/src/utils/Route.js +67 -0
  45. package/src/utils/Runner.js +327 -0
  46. package/src/utils/String.js +618 -0
  47. package/src/{library/element.js → wip/Element.js} +90 -16
  48. package/src/{library/map.js → wip/Map.js} +256 -40
  49. package/types/dom/DomAttribute.d.ts +137 -0
  50. package/types/dom/DomBuilder.d.ts +67 -0
  51. package/types/dom/DomEvent.d.ts +103 -0
  52. package/types/dom/DomFinder.d.ts +321 -0
  53. package/types/dom/DomForm.d.ts +21 -0
  54. package/types/dom/DomGlobal.d.ts +79 -0
  55. package/types/dom/DomInview.d.ts +114 -0
  56. package/types/dom/DomMeta.d.ts +29 -0
  57. package/types/dom/DomObserver.d.ts +21 -0
  58. package/types/dom/DomRectangle.d.ts +270 -0
  59. package/types/format/FormatFile.d.ts +18 -0
  60. package/types/format/FormatOption.d.ts +40 -0
  61. package/types/format/FormatParam.d.ts +39 -0
  62. package/types/format/FormatParser.d.ts +46 -0
  63. package/types/format/FormatUrl.d.ts +17 -0
  64. package/types/index.browser.d.ts +1 -0
  65. package/types/index.esm.d.ts +52 -0
  66. package/types/now/NowDefault.d.ts +183 -0
  67. package/types/now/NowFormat.d.ts +70 -0
  68. package/types/now/NowGrid.d.ts +107 -0
  69. package/types/now/NowHuman.d.ts +37 -0
  70. package/types/now/NowMatch.d.ts +108 -0
  71. package/types/now/NowRange.d.ts +21 -0
  72. package/types/now/NowWalker.d.ts +301 -0
  73. package/types/tool/scope.d.ts +24 -0
  74. package/types/utils/Array.d.ts +480 -0
  75. package/types/utils/Cookie.d.ts +60 -0
  76. package/types/utils/Data.d.ts +91 -0
  77. package/types/utils/Dom.d.ts +138 -0
  78. package/types/utils/Event.d.ts +58 -0
  79. package/types/utils/Format.d.ts +37 -0
  80. package/types/utils/Hash.d.ts +81 -0
  81. package/types/utils/Locale.d.ts +115 -0
  82. package/types/utils/Mixed.d.ts +469 -0
  83. package/types/utils/Now.d.ts +125 -0
  84. package/types/utils/Number.d.ts +127 -0
  85. package/types/utils/Object.d.ts +255 -0
  86. package/types/utils/Route.d.ts +37 -0
  87. package/types/utils/Runner.d.ts +139 -0
  88. package/types/utils/String.d.ts +330 -0
  89. package/types/wip/Element.d.ts +119 -0
  90. package/types/wip/Map.d.ts +254 -0
  91. package/dist/.ignore.js +0 -0
  92. package/dist/pico-js.js +0 -2
  93. package/dist/pico-js.js.map +0 -1
  94. package/src/element/default.js +0 -46
  95. package/src/element/example.js +0 -58
  96. package/src/index.js +0 -90
  97. package/src/library/cookie.js +0 -123
  98. package/src/library/data.js +0 -111
  99. package/src/library/event.js +0 -91
  100. package/src/library/locale.js +0 -84
  101. package/src/library/queue.js +0 -64
  102. package/src/library/route.js +0 -28
  103. package/src/utility/any.js +0 -369
  104. package/src/utility/array.js +0 -410
  105. package/src/utility/dom.js +0 -1425
  106. package/src/utility/now.js +0 -544
  107. package/src/utility/number.js +0 -128
  108. package/src/utility/object.js +0 -429
  109. package/src/utility/string.js +0 -328
  110. package/types/index.d.ts +0 -77
  111. package/types/library/cookie.d.ts +0 -10
  112. package/types/library/data.d.ts +0 -15
  113. package/types/library/element.d.ts +0 -22
  114. package/types/library/event.d.ts +0 -13
  115. package/types/library/locale.d.ts +0 -14
  116. package/types/library/map.d.ts +0 -43
  117. package/types/library/queue.d.ts +0 -18
  118. package/types/library/route.d.ts +0 -11
  119. package/types/utility/any.d.ts +0 -35
  120. package/types/utility/array.d.ts +0 -46
  121. package/types/utility/dom.d.ts +0 -101
  122. package/types/utility/now.d.ts +0 -79
  123. package/types/utility/number.d.ts +0 -17
  124. package/types/utility/object.d.ts +0 -29
  125. package/types/utility/string.d.ts +0 -26
@@ -0,0 +1,655 @@
1
+ import { go, Mix, Arr } from "#src/index.esm.js";
2
+
3
+ export class PicoObject
4
+ {
5
+ /**
6
+ * Normalize key path to array
7
+ *
8
+ * @example Obj.keyoptim("a.b") // => ["a","b"]
9
+ * @example Obj.keyoptim(["a","b"]) // => ["a","b"]
10
+ *
11
+ * @param {any} keys Key path
12
+ * @param {boolean} [flatten] Flatten keys
13
+ * @param {boolean|null} [isstr] Is string flag
14
+ * @returns {Array<any>} Key segments
15
+ */
16
+ static keyoptim(keys, flatten = false, isstr = null)
17
+ {
18
+ if ( isstr === null ) {
19
+ isstr = Mix.isStr(keys);
20
+ }
21
+
22
+ if ( !isstr && flatten ) {
23
+ keys = keys.join('.');
24
+ }
25
+
26
+ return isstr || flatten ? keys.split('.') : keys;
27
+ }
28
+
29
+ /**
30
+ * Check if nested key exists
31
+ *
32
+ * @example Obj.has({a:{b:1}}, "a.b") // => true
33
+ * @example Obj.has({a:{}}, "a.b") // => false
34
+ *
35
+ * @param {any} target Target object
36
+ * @param {any} keys Key path
37
+ * @param {boolean} [flatten] Flatten keys
38
+ * @returns {boolean} True if exists
39
+ */
40
+ static has(target, keys, flatten = false)
41
+ {
42
+ if ( target == null || keys == null ) {
43
+ return false;
44
+ }
45
+
46
+ if ( typeof keys === 'number' ) {
47
+ keys = Mix.str(keys);
48
+ }
49
+
50
+ const isstr = typeof keys === 'string';
51
+
52
+ if ( isstr && target && target[keys] !== undefined ) {
53
+ return target[keys] !== undefined;
54
+ }
55
+
56
+ keys = this.keyoptim(keys, flatten, isstr);
57
+
58
+ let [list, index, length] = [
59
+ keys.pop(), 0, keys.length
60
+ ];
61
+
62
+ if ( length === 0 ) {
63
+ return target[list] !== undefined;
64
+ }
65
+
66
+ while ( target != null && index < length ) {
67
+ target = target[keys[index ++]];
68
+ }
69
+
70
+ if ( target == null ) {
71
+ return false;
72
+ }
73
+
74
+ return target[list] !== undefined;
75
+
76
+ }
77
+
78
+ /**
79
+ * Get nested value or fallback
80
+ *
81
+ * @example Obj.get({a:{b:1}}, "a.b") // => 1
82
+ * @example Obj.get({}, "a.b", null) // => null
83
+ *
84
+ * @param {any} target Target object
85
+ * @param {any} keys Key path
86
+ * @param {any} [fallback] Fallback value
87
+ * @param {boolean} [flatten] Flatten keys
88
+ * @returns {any} Nested value
89
+ */
90
+ static get(target, keys, fallback = null, flatten = false)
91
+ {
92
+ if ( target == null || keys == null ) {
93
+ return fallback;
94
+ }
95
+
96
+ if ( typeof keys === 'number' ) {
97
+ keys = Mix.str(keys);
98
+ }
99
+
100
+ const isstr = typeof keys === 'string';
101
+
102
+ if ( isstr && target && target[keys] !== undefined ) {
103
+ return target[keys];
104
+ }
105
+
106
+ keys = this.keyoptim(keys, flatten, isstr);
107
+
108
+ let index = 0, length = keys.length;
109
+
110
+ if ( length === 0 ) {
111
+ return fallback;
112
+ }
113
+
114
+ while ( target != null && index < length ) {
115
+ target = target[keys[index ++]];
116
+ }
117
+
118
+ if ( target == null ) {
119
+ return fallback;
120
+ }
121
+
122
+ return target;
123
+ }
124
+
125
+ /**
126
+ * Set nested value (mutates)
127
+ *
128
+ * @example Obj.set({}, "a.b", 1) // => object
129
+ * @example Obj.set({}, ["a","b"], 1) // => object
130
+ *
131
+ * @param {any} target Target object
132
+ * @param {any} keys Key path
133
+ * @param {any} value Value to set
134
+ * @param {boolean} [flatten] Flatten keys
135
+ * @returns {any} Mutated target
136
+ */
137
+ static set(target, keys, value, flatten = false)
138
+ {
139
+ if ( keys == null ) {
140
+ return target;
141
+ }
142
+
143
+ if ( typeof keys === 'number' ) {
144
+ keys = Mix.str(keys);
145
+ }
146
+
147
+ const isstr = typeof keys === 'string';
148
+
149
+ if ( isstr && target && target[keys] !== undefined ) {
150
+ return (target[keys] = value, target);
151
+ }
152
+
153
+ keys = this.keyoptim(keys, flatten, isstr);
154
+
155
+ if ( keys.length === 0 ) {
156
+ return target;
157
+ }
158
+
159
+ let nested = target;
160
+
161
+ for ( let mod, src, i = 0; i < keys.length; i++) {
162
+
163
+ mod = src = String(keys[i]);
164
+
165
+ if ( src.indexOf('[]') !== -1 ) {
166
+ mod = src.replace('[]', '');
167
+ }
168
+
169
+ if ( nested[mod] == null ) {
170
+ nested[mod] = mod === src ? {} : [];
171
+ }
172
+
173
+ if ( mod !== src ) {
174
+ Arr.insert(keys, i + 1, nested[mod].length);
175
+ }
176
+
177
+ if ( keys.length - 1 === i ) {
178
+ nested[mod] = value;
179
+ }
180
+
181
+ nested = nested[mod];
182
+ }
183
+
184
+ return target;
185
+ }
186
+
187
+ /**
188
+ * Unset nested value (mutates)
189
+ *
190
+ * @example Obj.unset({a:{b:1}}, "a.b")
191
+ * @example Obj.unset({a:{b:1}}, ["a","b"])
192
+ *
193
+ * @param {any} target Target object
194
+ * @param {any} keys Key path
195
+ * @param {boolean} [flatten] Flatten keys
196
+ * @returns {any} Mutated target
197
+ */
198
+ static unset(target, keys, flatten = false)
199
+ {
200
+ if ( keys == null ) {
201
+ return target;
202
+ }
203
+
204
+ if ( typeof keys === 'number' ) {
205
+ keys = Mix.str(keys);
206
+ }
207
+
208
+ const isstr = typeof keys === 'string';
209
+
210
+ if ( isstr && target && target[keys] !== undefined ) {
211
+ return (delete target[keys], target);
212
+ }
213
+
214
+ keys = this.keyoptim(keys, flatten, isstr);
215
+
216
+ let [list, index, length, nested] = [
217
+ keys.pop(), 0, keys.length, target
218
+ ];
219
+
220
+ if ( length === 0 ) {
221
+ return target;
222
+ }
223
+
224
+ while ( nested != null && index < length ) {
225
+ nested = nested[keys[index ++]];
226
+ }
227
+
228
+ if ( nested == null ) {
229
+ return target;
230
+ }
231
+
232
+ return (delete nested[list], target);
233
+ }
234
+
235
+ /**
236
+ * Check if nested value is empty
237
+ *
238
+ * @example Obj.empty({a:null}, "a") // => true
239
+ * @example Obj.empty({a:1}, "a") // => false
240
+ *
241
+ * @param {any} target Target object
242
+ * @param {any} key Key path
243
+ * @returns {boolean} True if empty
244
+ */
245
+ static empty(target, key)
246
+ {
247
+ return Mix.isEmpty(this.get(target, key));
248
+ }
249
+
250
+ /**
251
+ * Unset multiple keys (mutates)
252
+ *
253
+ * @example Obj.remove({a:1,b:2}, ["a"]) // => object
254
+ *
255
+ * @param {any} target Target object
256
+ * @param {any} keys Keys list
257
+ * @returns {any} Mutated target
258
+ */
259
+ static remove(target, keys)
260
+ {
261
+ if ( ! Mix.isArr(keys) ) {
262
+ return target;
263
+ }
264
+
265
+ for ( let key of keys ) {
266
+ this.unset(target, key);
267
+ }
268
+
269
+ return target;
270
+ }
271
+
272
+ /**
273
+ * Map object values to object
274
+ *
275
+ * @example Obj.each({a:1}, v => v+1) // => {a:2}
276
+ *
277
+ * @param {any} value Source object
278
+ * @param {function} cb Map callback
279
+ * @param {any} [retval] Forced return
280
+ * @returns {any} Mapped object
281
+ */
282
+ static each(value, cb, retval = null)
283
+ {
284
+ let result = {};
285
+
286
+ for ( let key of Mix.keys(value) ) {
287
+ result[key] = cb(value[key], key);
288
+ }
289
+
290
+ if ( retval != null ) {
291
+ return retval;
292
+ }
293
+
294
+ return result;
295
+ }
296
+
297
+ /**
298
+ * Map object values to object
299
+ *
300
+ * @example Obj.map({a:1}, v => v+1) // => {a:2}
301
+ *
302
+ * @param {any} value Source object
303
+ * @param {function} cb Map callback
304
+ * @returns {Record<string, any>} Mapped object
305
+ */
306
+ static map(value, cb)
307
+ {
308
+ let result = {};
309
+
310
+ for ( let key of Mix.keys(value) ) {
311
+ result[key] = cb(value[key], key);
312
+ }
313
+
314
+ return result;
315
+ }
316
+
317
+ /**
318
+ * Get filtered key indexes
319
+ *
320
+ * @example Obj.filterIndex({a:1,b:null}) // => ["a"]
321
+ *
322
+ * @param {any} value Source object
323
+ * @param {any} [filter] Filter spec
324
+ * @returns {Array<any>} Key list
325
+ */
326
+ static filterIndex(value, filter = null)
327
+ {
328
+ return Arr.filterIndex(value, filter);
329
+ }
330
+
331
+ /**
332
+ * Filter object by key filter
333
+ *
334
+ * @example Obj.filter({a:1,b:null}) // => {a:1}
335
+ *
336
+ * @param {any} value Source object
337
+ * @param {any} [filter] Filter spec
338
+ * @returns {Record<string, any>} Filtered object
339
+ */
340
+ static filter(value, filter = null)
341
+ {
342
+ let result = {};
343
+
344
+ for (let key of this.filterIndex(value, filter)) {
345
+ result[key] = value[key];
346
+ }
347
+
348
+ return result;
349
+ }
350
+
351
+ /**
352
+ * Flatten object into dot keys
353
+ *
354
+ * @example Obj.flatten({a:{b:1}}) // => {"a.b":1}
355
+ *
356
+ * @param {any} value Source object
357
+ * @param {string} [prefix] Key prefix
358
+ * @param {Record<string, any>} [result] Result map
359
+ * @returns {Record<string, any>} Flat map
360
+ */
361
+ static flatten(value, prefix = '', result = {})
362
+ {
363
+ if ( typeof value !== 'object' ) {
364
+ return result[prefix] = value;
365
+ }
366
+
367
+ if ( prefix !== '' ) {
368
+ prefix += '.';
369
+ }
370
+
371
+ for ( let key of Mix.keys(value) ) {
372
+ this.flatten(value[key], prefix + key, result);
373
+ }
374
+
375
+ return result;
376
+ }
377
+
378
+ /**
379
+ * Flatten object into form keys
380
+ *
381
+ * @example Obj.flattenForm({a:{b:1}}) // => {"a[b]":1}
382
+ *
383
+ * @param {any} value Source object
384
+ * @param {string} [prefix] Key prefix
385
+ * @param {Record<string, any>} [result] Result map
386
+ * @returns {Record<string, any>} Flat map
387
+ */
388
+ static flattenForm(value, prefix = '', result = {})
389
+ {
390
+ if ( typeof value !== 'object' ) {
391
+ return result[prefix] = value;
392
+ }
393
+
394
+ let fn = (key) => {
395
+ return prefix ? `${prefix}[${key}]` : key;
396
+ };
397
+
398
+ for ( let key of Mix.keys(value) ) {
399
+ this.flattenForm(value[key], fn(key), result);
400
+ }
401
+
402
+ return result;
403
+ }
404
+
405
+ /**
406
+ * Unpack dotted keys into object
407
+ *
408
+ * @example Obj.unpack({"a.b":1}) // => {a:{b:1}}
409
+ *
410
+ * @param {any} value Flat key map
411
+ * @param {Record<string, any>} [result] Result object
412
+ * @returns {Record<string, any>} Unpacked object
413
+ */
414
+ static unpack(value, result = {})
415
+ {
416
+ Arr.each(Mix.keys(value), (key) => {
417
+ this.set(result, key, value[key]);
418
+ });
419
+
420
+ return result;
421
+ }
422
+
423
+ /**
424
+ * Assign objects (Object.assign)
425
+ *
426
+ * @example Obj.assign({}, {a:1}) // => {a:1}
427
+ *
428
+ * @param {...any} args Assign args
429
+ * @returns {any} Assigned object
430
+ */
431
+ static assign(...args)
432
+ {
433
+ return Object.assign(...args);
434
+ }
435
+
436
+ /**
437
+ * Deep clone primitive/array/object
438
+ *
439
+ * @example Obj.clone({a:{b:1}}) // => new object
440
+ *
441
+ * @param {any} value Value to clone
442
+ * @param {any} [merge] Merge values
443
+ * @returns {any} Cloned value
444
+ */
445
+ static clone(value, merge = null)
446
+ {
447
+ if ( Mix.isPrim(value) ) {
448
+ return value;
449
+ }
450
+
451
+ if ( Mix.isArr(value) ) {
452
+ return Arr.clone(value);
453
+ }
454
+
455
+ if ( ! Mix.isObj(value) ) {
456
+ return value;
457
+ }
458
+
459
+ let result = {};
460
+
461
+ for ( let key of Mix.keys(value) ) {
462
+ result[key] = this.clone(value[key]);
463
+ }
464
+
465
+ if ( merge != null ) {
466
+ return this.assign(result, merge);
467
+ }
468
+
469
+ return result;
470
+ }
471
+
472
+ /**
473
+ * Get and remove nested value
474
+ *
475
+ * @example Obj.pluck({a:1}, "a") // => 1
476
+ *
477
+ * @param {any} value Source object
478
+ * @param {any} key Key path
479
+ * @param {any} [fallback] Fallback value
480
+ * @returns {any} Plucked value
481
+ */
482
+ static pluck(value, key, fallback = null)
483
+ {
484
+ let result = this.get(value, key, fallback);
485
+
486
+ this.unset(value, key);
487
+
488
+ return result;
489
+ }
490
+
491
+ /**
492
+ * Pick only given keys
493
+ *
494
+ * @example Obj.only({a:1,b:2}, ["a"]) // => {a:1}
495
+ *
496
+ * @param {any} value Source object
497
+ * @param {Array<any>} keys Allowed keys
498
+ * @param {any} [merge] Merge values
499
+ * @returns {Record<string, any>} Picked object
500
+ */
501
+ static only(value, keys, merge = null)
502
+ {
503
+ let result = {};
504
+
505
+ this.each(value, (val, key) => {
506
+ if ( Arr.has(keys, key) ) result[key] = val;
507
+ });
508
+
509
+ if ( merge == null ) {
510
+ return result;
511
+ }
512
+
513
+ return this.assign(result, merge);
514
+ }
515
+
516
+ /**
517
+ * Pick all keys except given
518
+ *
519
+ * @example Obj.except({a:1,b:2}, ["a"]) // => {b:2}
520
+ *
521
+ * @param {any} value Source object
522
+ * @param {Array<any>} keys Excluded keys
523
+ * @param {any} [merge] Merge values
524
+ * @returns {Record<string, any>} Picked object
525
+ */
526
+ static except(value, keys, merge = null)
527
+ {
528
+ let result = {};
529
+
530
+ this.each(value, (val, key) => {
531
+ if ( ! Arr.has(keys, key) ) result[key] = val;
532
+ });
533
+
534
+ if ( merge == null ) {
535
+ return result;
536
+ }
537
+
538
+ return this.assign(result, merge);
539
+ }
540
+
541
+ /**
542
+ * Check if value includes search
543
+ *
544
+ * @example Obj.includes({a:1}, {a:1}) // => true
545
+ * @example Obj.includes({a:1}, {a:2}) // => false
546
+ *
547
+ * @param {any} value Source value
548
+ * @param {any} search Search spec
549
+ * @returns {boolean} True if includes
550
+ */
551
+ static includes(value, search)
552
+ {
553
+ if ( Mix.isArr(search) ) {
554
+ return Arr.includes(value, search);
555
+ }
556
+
557
+ if ( ! Mix.isObj(search) ) {
558
+ return value === search;
559
+ }
560
+
561
+ let keys = Mix.keys(search);
562
+
563
+ let [result, length] = [
564
+ true, keys.length,
565
+ ];
566
+
567
+ for ( let i = 0; result === true && i < length; i++) {
568
+ result = this.includes(...[
569
+ value[keys[i]], search[keys[i]]
570
+ ]);
571
+ }
572
+
573
+ return result;
574
+ }
575
+
576
+ /**
577
+ * Check if value matches search
578
+ *
579
+ * @example Obj.matches({a:1}, {a:1}) // => true
580
+ * @example Obj.matches({a:1}, {b:1}) // => false
581
+ *
582
+ * @param {any} value Source value
583
+ * @param {any} search Search spec
584
+ * @returns {boolean} True if matches
585
+ */
586
+ static matches(value, search)
587
+ {
588
+ if ( Mix.isArr(search) ) {
589
+ return Arr.matches(value, search);
590
+ }
591
+
592
+ if ( ! Mix.isObj(value) ) {
593
+ return value === search;
594
+ }
595
+
596
+ let keys = Arr.unique([
597
+ ...Mix.keys(search), ...Mix.keys(value)
598
+ ]);
599
+
600
+ let [result, length] = [
601
+ true, keys.length,
602
+ ];
603
+
604
+ for ( let i = 0; result === true && i < length; i++) {
605
+ result &&= this.matches(...[
606
+ value[keys[i]], search[keys[i]]
607
+ ]);
608
+ }
609
+
610
+ return result;
611
+ }
612
+
613
+ }
614
+
615
+ /**
616
+ * @see PicoMixed.vals
617
+ */
618
+ PicoObject.values = (...args) => {
619
+ console.warn('Obj.values() is deprecated, use Mix.vals() instead.');
620
+ return Mix.vals(...args);
621
+ };
622
+
623
+ /**
624
+ * @see PicoArray.find
625
+ */
626
+ PicoObject.find = (...args) => {
627
+ console.warn('Obj.find() is deprecated, use Arr.find() instead.');
628
+ return Arr.find(...args);
629
+ };
630
+
631
+ /**
632
+ * @see PicoArray.findIndex
633
+ */
634
+ PicoObject.findIndex = (...args) => {
635
+ console.warn('Obj.findIndex() is deprecated, use Arr.findIndex() instead.');
636
+ return Arr.findIndex(...args);
637
+ };
638
+
639
+ /**
640
+ * @see PicoArray.sort
641
+ */
642
+ PicoObject.sort = (...args) => {
643
+ console.warn('Obj.sort() is deprecated, use Arr.sort() instead.');
644
+ return Arr.sort(...args);
645
+ };
646
+
647
+ /**
648
+ * @see PicoArray.sortDeep
649
+ */
650
+ PicoObject.sortString = (...args) => {
651
+ console.warn('Obj.sortString() is deprecated, use Arr.sortDeep() instead.');
652
+ return Arr.sortDeep(...args);
653
+ };
654
+
655
+ export default PicoObject
@@ -0,0 +1,67 @@
1
+ import { Arr, For, Locale, Mix, Obj } from "#src/index.esm.js";
2
+
3
+ export class PicoRoute
4
+ {
5
+
6
+ static $routes = {};
7
+
8
+ /**
9
+ * Store route template by key
10
+ *
11
+ * @example Route.set("home", "/") // stores
12
+ *
13
+ * @param {string} key Route key
14
+ * @param {string} value Route template
15
+ * @returns {void} No return value
16
+ */
17
+ static set(key, value)
18
+ {
19
+ this.$routes[key] = value;
20
+ }
21
+
22
+ /**
23
+ * Build route URL from template
24
+ *
25
+ * @example Route.get("home") // => "/"
26
+ * @example Route.get("/u/:id", {id:1}) // => "/u/1"
27
+ *
28
+ * @param {string} key Route key or url
29
+ * @param {any} [values] Token values
30
+ * @param {any} [query] Query params
31
+ * @returns {string} Built url
32
+ */
33
+ static get(key, values = null, query = null)
34
+ {
35
+ let route = key;
36
+
37
+ if ( ! /^https?:\/\//.test(route) ) {
38
+ route = this.$routes[key] || key
39
+ }
40
+
41
+ route = Locale.replace(route, values);
42
+
43
+ if ( ! Mix.isEmpty(query) ) {
44
+ route += '?' + For.castParams(values);
45
+ }
46
+
47
+ return route;
48
+ }
49
+
50
+ /**
51
+ * Navigate to built route URL
52
+ *
53
+ * @example Route.goto("home")
54
+ *
55
+ * @param {string} key Route key or url
56
+ * @param {any} [values] Token values
57
+ * @param {any} [params] Query params
58
+ * @returns {void} No return value
59
+ */
60
+ static goto(key, values = null, params = null)
61
+ {
62
+ window.location.href = this.get(key, values, params);
63
+ }
64
+
65
+ }
66
+
67
+ export default PicoRoute;