atomic-fns 0.2.2 → 0.3.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 (70) hide show
  1. package/.firebaserc +5 -0
  2. package/README.md +9 -4
  3. package/firebase.json +10 -0
  4. package/package.json +9 -9
  5. package/src/collections/index.d.ts +672 -0
  6. package/src/collections/index.js +1091 -0
  7. package/src/collections/index.ts +1186 -0
  8. package/src/datetime/index.d.ts +6 -0
  9. package/src/datetime/index.js +6 -0
  10. package/src/datetime/index.ts +7 -0
  11. package/src/functools/index.d.ts +107 -0
  12. package/src/functools/index.js +219 -0
  13. package/src/functools/index.ts +255 -0
  14. package/src/globals/index.d.ts +286 -0
  15. package/src/globals/index.js +388 -0
  16. package/src/globals/index.ts +451 -0
  17. package/src/index.d.ts +8 -7
  18. package/src/index.js +8 -7
  19. package/src/index.ts +8 -7
  20. package/src/itertools/index.d.ts +225 -0
  21. package/src/itertools/index.js +449 -0
  22. package/src/itertools/index.ts +471 -0
  23. package/src/math/index.d.ts +97 -0
  24. package/src/math/index.js +92 -0
  25. package/src/math/index.ts +152 -0
  26. package/src/{operators.d.ts → operators/index.d.ts} +11 -9
  27. package/src/operators/index.js +171 -0
  28. package/src/operators/index.ts +175 -0
  29. package/src/random/index.d.ts +42 -0
  30. package/src/random/index.js +65 -0
  31. package/src/random/index.ts +66 -0
  32. package/tests/collections.spec.ts +42 -25
  33. package/tests/globals.spec.ts +56 -60
  34. package/tests/itertools.spec.ts +176 -4
  35. package/tests/math.spec.ts +25 -0
  36. package/tests/operators.spec.ts +1 -26
  37. package/tests/random.spec.ts +46 -0
  38. package/tsconfig.json +12 -4
  39. package/src/collections.d.ts +0 -228
  40. package/src/collections.js +0 -553
  41. package/src/collections.ts +0 -641
  42. package/src/datetime.d.ts +0 -5
  43. package/src/datetime.js +0 -5
  44. package/src/datetime.ts +0 -6
  45. package/src/functools.d.ts +0 -40
  46. package/src/functools.js +0 -78
  47. package/src/functools.ts +0 -93
  48. package/src/globals.d.ts +0 -179
  49. package/src/globals.js +0 -309
  50. package/src/globals.ts +0 -377
  51. package/src/itertools.d.ts +0 -20
  52. package/src/itertools.js +0 -98
  53. package/src/itertools.ts +0 -116
  54. package/src/math.d.ts +0 -16
  55. package/src/math.js +0 -70
  56. package/src/math.ts +0 -77
  57. package/src/objects.d.ts +0 -0
  58. package/src/objects.js +0 -1
  59. package/src/objects.ts +0 -0
  60. package/src/operators.js +0 -109
  61. package/src/operators.ts +0 -130
  62. package/src/random.d.ts +0 -22
  63. package/src/random.js +0 -48
  64. package/src/random.ts +0 -53
  65. package/src/strings.d.ts +0 -0
  66. package/src/strings.js +0 -1
  67. package/src/strings.ts +0 -0
  68. package/src/util.d.ts +0 -0
  69. package/src/util.js +0 -1
  70. package/src/util.ts +0 -0
@@ -1,553 +0,0 @@
1
- /**
2
- * Collections
3
- * @module
4
- */
5
- import {
6
- call,
7
- get,
8
- isArray,
9
- isArrayLike,
10
- isBool,
11
- isEmpty,
12
- isFunc,
13
- isNull,
14
- isNumber,
15
- isObject,
16
- isString,
17
- keys,
18
- NotImplementedError,
19
- set
20
- } from './globals.js'
21
- import { comp, eq, id } from './operators.js'
22
- /**
23
- * A Collection is an iterable container type.
24
- * This is an abstract base class for user-defined collection types.
25
- *
26
- *
27
- * @abstract
28
- * @class Collection
29
- * @implements {Container}
30
- */
31
- export class Collection {
32
- /**
33
- * Returns an iterator for the container items
34
- * @return {Iterator}
35
- */
36
- [Symbol.iterator]() {
37
- return this
38
- }
39
-
40
- /**
41
- * Implements the iterator protocol and returns the next item in the iterable.
42
- */
43
- next() {}
44
- /**
45
- * Adds a new item to the container.
46
- * @param item
47
- */
48
- add(item) {}
49
- /**
50
- * Checks if item is present in the container.
51
- * @param item
52
- */
53
- contains(item) {
54
- return false
55
- }
56
-
57
- /**
58
- * Returns the total number of elements in the container.
59
- */
60
- size() {
61
- throw new NotImplementedError()
62
- }
63
-
64
- /**
65
- * Remove the first item from the container where `item == x`
66
- * @raises ValueError when x is not found
67
- */
68
- remove(x) {}
69
- /**
70
- * Retrieve and remove the item at index `i`.
71
- * @returns the item or undefined if not found.
72
- */
73
- pop(i) {}
74
- /**
75
- * Remove all items from the container
76
- */
77
- clear() {}
78
- }
79
- /**
80
- * A sequence is an iterable type with efficient index-based access.
81
- *
82
- *
83
- * @abstract
84
- * @class Sequence
85
- * @extends {Collection}
86
- * @template T
87
- */
88
- export class Sequence extends Collection {
89
- /**
90
- * Return the item at the given key or index
91
- * @param {*} key
92
- * @memberof Sequence
93
- */
94
- get(key) {
95
- throw new NotImplementedError()
96
- }
97
-
98
- /**
99
- * Set a new value at the given key or index
100
- *
101
- * @param {*} key
102
- * @param {T} val
103
- * @memberof Sequence
104
- */
105
- set(key, val) {
106
- throw new NotImplementedError()
107
- }
108
-
109
- /**
110
- * Deletes the given key or index, and its value.
111
- * Raises ValueError if not key is found.
112
- *
113
- * @param {*} key
114
- * @memberof Sequence
115
- */
116
- delete(key) {
117
- throw new NotImplementedError()
118
- }
119
-
120
- /**
121
- * Adds a new item to the end of the sequence.
122
- *
123
- * @param {T} x
124
- * @memberof Sequence
125
- */
126
- append(x) {}
127
- /**
128
- * Append all the items to the sequence.
129
- *
130
- * @param {Iterable<T>} iter
131
- * @memberof Sequence
132
- */
133
- extend(iter) {}
134
- /**
135
- * Return the index of x in the sequence, or undefined if not found.
136
- *
137
- * @param {T} item
138
- * @return {(number | undefined)}
139
- * @memberof Sequence
140
- */
141
- indexOf(item) {
142
- throw new NotImplementedError()
143
- }
144
-
145
- size() {
146
- return 0
147
- }
148
-
149
- reversed() {
150
- throw new NotImplementedError()
151
- }
152
- }
153
- /**
154
- * Returns a new immutable Set object with elements from `iterable`. Its contents cannot be altered after it's created.
155
- *
156
- *
157
- * @class FrozenSet
158
- * @extends {Set<T>}
159
- * @template T
160
- */
161
- export class FrozenSet extends Set {
162
- constructor(iterable) {
163
- super(iterable)
164
- return this.freeze()
165
- }
166
-
167
- add() {
168
- throw TypeError('FrozenSet cannot be modified.')
169
- return this; // eslint-disable-line
170
- }
171
-
172
- delete() {
173
- throw TypeError('FrozenSet cannot be modified.')
174
- return false; // eslint-disable-line
175
- }
176
-
177
- clear() {
178
- throw TypeError('FrozenSet cannot be modified.')
179
- return this; // eslint-disable-line
180
- }
181
-
182
- freeze() {
183
- return Object.freeze(this)
184
- }
185
- }
186
- export const compact = (...arr) => arr.filter((x) => !isEmpty(x))
187
- /**
188
- * Creates a function that can be used to create named tuple-like objects.
189
- * @example
190
- * ```
191
- * let Point = namedtuple('x', 'y', 'z')
192
- * let userObj = User(0, 0, 0)
193
- * // -> {x: 0, y: 0, z: 0}
194
- * ```
195
- *
196
- *
197
- * @param {...string[]} fields
198
- * @return
199
- */
200
- export function namedtuple(...fields) {
201
- return (...args) => fields.reduce((prev, f, i) => set(prev, f, args[i], false, true), {})
202
- }
203
- export function filter(arr, fn = isNull) {
204
- if (Array.isArray(arr)) {
205
- // @ts-expect-error function is not compatible?
206
- if (typeof fn === 'function') return arr.filter(fn)
207
- if (typeof fn === 'string') return arr.filter((x) => get(x, fn))
208
- if (isObject(fn)) return arr.filter(matches(fn))
209
- }
210
- }
211
- export function find(arr, fn) {
212
- if (Array.isArray(arr)) {
213
- if (typeof fn === 'function') return arr.find(fn)
214
- if (typeof fn === 'string') return arr.find((x) => x?.[fn])
215
- if (isObject(fn)) return arr.find(matches(fn))
216
- }
217
- }
218
- export function findRight(arr, fn) {
219
- if (Array.isArray(arr)) {
220
- for (let i = arr.length - 1; i >= 0; i--) {
221
- const x = arr[i]
222
- if (typeof fn === 'function') {
223
- if (fn(x)) return x
224
- } else if (typeof fn === 'string') {
225
- if (x?.[fn]) return x
226
- } else if (isObject(fn)) {
227
- if (matches(fn)(x)) return x
228
- }
229
- }
230
- }
231
- }
232
- export const matches = (o) => (x) => {
233
- if (!o || !x) return false
234
- for (const key in o) {
235
- if (!eq(x[key], o[key])) return false
236
- }
237
- return true
238
- }
239
- export function forEach(arr, fn) {
240
- if (Array.isArray(arr)) return arr.forEach(fn)
241
- if (isObject(arr)) {
242
- return Object.keys(arr).forEach((key) => fn(get(arr, key), key, arr))
243
- }
244
- }
245
- export function flatten(arr, depth = 1) {
246
- if (!depth) return arr
247
- if (Array.isArray(arr)) return flattenArray(arr, depth, [])
248
- if (isObject(arr)) return flattenObj(arr)
249
- return arr
250
- }
251
- export function flattenArray(arr, depth = 1, result = []) {
252
- for (const value of arr) {
253
- if (depth && Array.isArray(value)) {
254
- flattenArray(value, typeof depth === 'number' ? depth - 1 : depth, result)
255
- } else {
256
- result.push(value)
257
- }
258
- }
259
- return result
260
- }
261
- export function flattenObj(o, prefix = '', result = {}, keepNull = false) {
262
- if (isString(o) || isNumber(o) || isBool(o) || (keepNull && isNull(o))) {
263
- result[prefix] = o
264
- return result
265
- }
266
- if (isArray(o) || isObject(o)) {
267
- for (const i in o) {
268
- let pref = prefix
269
- if (isArray(o)) {
270
- pref = pref + `[${i}]`
271
- } else {
272
- if (isEmpty(prefix)) {
273
- pref = i
274
- } else {
275
- pref = prefix + '.' + i
276
- }
277
- }
278
- flattenObj(o[i], pref, result, keepNull)
279
- }
280
- return result
281
- }
282
- return result
283
- }
284
- export const map = (arr, fn) => {
285
- if (Array.isArray(arr)) {
286
- return arr.map((x, i) => {
287
- if (typeof fn === 'string') return x[fn]
288
- return fn(x, i, arr)
289
- })
290
- }
291
- if (isObject(arr)) {
292
- return Object.keys(arr).map((key) => {
293
- if (typeof fn === 'string') return get(arr[key], fn)
294
- return fn(arr[key], key, arr)
295
- })
296
- }
297
- }
298
- export function pick(obj, paths) {
299
- if (obj == null) {
300
- return {}
301
- }
302
- const result = {}
303
- if (Array.isArray(paths)) {
304
- for (const key of paths) {
305
- result[key] = obj[key]
306
- }
307
- return result
308
- } else if (typeof paths === 'function') {
309
- for (const key in obj) {
310
- const value = obj[key]
311
- if (paths(value, key)) result[key] = value
312
- }
313
- }
314
- return result
315
- }
316
- export function omit(obj, paths) {
317
- const result = {}
318
- for (const key in obj) {
319
- const value = obj[key]
320
- if (Array.isArray(paths) && !paths.includes(key)) {
321
- result[key] = value
322
- } else if (typeof paths === 'function' && !paths(value, key)) {
323
- result[key] = value
324
- }
325
- }
326
- return result
327
- }
328
- export function contains(arr, y) {
329
- const op = call(arr, 'contains', y)
330
- if (op != null) return op
331
- return indexOf(arr, y) >= 0
332
- }
333
- export function indexOf(obj, x, start = 0) {
334
- if (obj == null) return
335
- const op = call(obj, 'indexOf', x, start)
336
- if (op != null) return op
337
- const length = obj.length
338
- if (length && start < 0) {
339
- start = Math.max(start + length, 0)
340
- }
341
- if (!length || start >= length) return -1
342
- for (; start < length; start++) {
343
- if (eq(x, obj[start])) return start
344
- }
345
- return -1
346
- }
347
- export function lastIndexOf(obj, x, start) {
348
- if (obj == null) return
349
- const op = call(obj, 'lastIndexOf', x, start)
350
- if (op != null) return op
351
- const length = obj.length
352
- if (start == null) start = length - 1
353
- if (!length || start < 0) return -1
354
- for (; start >= 0; start--) {
355
- if (eq(x, obj[start])) return start
356
- }
357
- return -1
358
- }
359
- /**
360
- * Creates a clone of the given `obj`. If `deep` is `true` it will clone it recursively.
361
- *
362
- *
363
- * @param {*} obj
364
- * @param {boolean} [deep=false]
365
- * @return The clone value
366
- */
367
- export function clone(obj, deep = false) {
368
- if (ArrayBuffer.isView(obj)) {
369
- return cloneTypedArray(obj, deep)
370
- }
371
- if (isArray(obj) || isArrayLike(obj)) {
372
- return cloneArray(obj, deep)
373
- }
374
- if (isObject(obj)) {
375
- if (isFunc(obj.clone)) {
376
- return obj.clone()
377
- }
378
- const copy = {}
379
- for (const key of keys(obj)) {
380
- if (deep) {
381
- copy[key] = clone(obj[key], deep)
382
- } else {
383
- copy[key] = obj[key]
384
- }
385
- }
386
- return copy
387
- }
388
- return obj
389
- }
390
- export function cloneArray(arr, deep = false) {
391
- if (!deep) return Array.from(arr)
392
- return arr.map((item) => clone(item, deep))
393
- }
394
- export function cloneArrayBuffer(arrayBuffer) {
395
- const result = new arrayBuffer.constructor(arrayBuffer.byteLength)
396
- new Uint8Array(result).set(new Uint8Array(arrayBuffer))
397
- return result
398
- }
399
- export function cloneTypedArray(typedArray, isDeep) {
400
- const buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer
401
- return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length)
402
- }
403
- export function uniq(arr, fn = id) {
404
- const keys = new Set()
405
- for (const x of arr) {
406
- if (typeof fn === 'function') {
407
- keys.add(fn(x))
408
- } else {
409
- keys.add(get(x, fn))
410
- }
411
- }
412
- return Array.from(keys.values())
413
- }
414
- export function sortedUniq(arr, fn = id) {
415
- const lst = uniq(arr, fn)
416
- lst.sort(comp)
417
- return lst
418
- }
419
- function baseMergeDeep(obj, source, key, stack) {
420
- const objValue = obj[key]
421
- const srcValue = source[key]
422
- const stacked = stack.get(srcValue)
423
- if (stacked && (objValue !== stacked || !(key in obj))) {
424
- obj[key] = stacked
425
- return
426
- }
427
- let newValue
428
- let isCommon = newValue === undefined
429
- const isArray = Array.isArray(srcValue)
430
- const isTyped = ArrayBuffer.isView(srcValue)
431
- if (isArray || isTyped) {
432
- if (Array.isArray(objValue)) {
433
- newValue = objValue
434
- } else if (isArrayLike(objValue)) {
435
- newValue = Array.from(objValue)
436
- } else if (isTyped) {
437
- isCommon = false
438
- newValue = cloneTypedArray(srcValue, true)
439
- } else {
440
- newValue = []
441
- }
442
- } else if (isObject(srcValue)) {
443
- newValue = objValue
444
- if (!isObject(objValue)) {
445
- newValue = srcValue
446
- }
447
- } else {
448
- isCommon = false
449
- }
450
- if (isCommon) {
451
- stack.set(srcValue, newValue)
452
- baseMerge(newValue, srcValue, stack)
453
- stack.delete(srcValue)
454
- }
455
- obj[key] = newValue
456
- }
457
- function baseMerge(obj, source, stack) {
458
- if (obj === source) return obj
459
- for (const key in source) {
460
- const srcValue = source[key]
461
- const objValue = obj[key]
462
- if (typeof srcValue === 'object' && srcValue !== null) {
463
- baseMergeDeep(obj, source, key, stack || new WeakMap())
464
- } else {
465
- if (objValue !== srcValue) {
466
- obj[key] = srcValue
467
- }
468
- }
469
- }
470
- }
471
- /**
472
- * Recursively merges own and inherited enumerable string keyed properties of source objects into the destination object. Source properties that resolve to `undefined` are skipped if a destination value exists. Array and plain object properties are merged recursively. Other objects and value types are overridden by assignment. Source objects are applied from left to right. Subsequent sources overwrite property assignments of previous sources.
473
- *
474
- * Note: this method mutates `obj`
475
- *
476
- *
477
- * @param {Object} obj
478
- * @param {...Object} sources
479
- * @return {Object} The destination object.
480
- */
481
- export function merge(obj, ...sources) {
482
- for (const source of sources) {
483
- baseMerge(obj, source)
484
- }
485
- return obj
486
- }
487
- export function* difference(...args) {
488
- const sets = args.map((arr) => new Set(arr))
489
- const setA = sets[0]
490
- for (let i = 1; i < sets.length; i++) {
491
- for (const x of sets[i].values()) {
492
- if (!setA.delete(x)) setA.add(x)
493
- }
494
- }
495
- for (const x of setA.values()) {
496
- yield x
497
- }
498
- }
499
- export function* intersection(...args) {
500
- const sets = args.map((arr) => new Set(arr))
501
- // build a counter map to find items in all
502
- const results = new Map()
503
- const total = sets.length
504
- for (let i = 0; i < total; i++) {
505
- for (const x of sets[i].values()) {
506
- const count = results.get(x) || 0
507
- results.set(x, count + 1)
508
- }
509
- }
510
- for (const [key, value] of results.entries()) {
511
- if (value === total) yield key
512
- }
513
- }
514
- export function* union(...args) {
515
- const results = new Set()
516
- for (const arr of args) {
517
- for (const item of arr) {
518
- results.add(item)
519
- }
520
- }
521
- for (const item of results.values()) {
522
- yield item
523
- }
524
- }
525
- /**
526
- * Creates an object composed of keys generated from the results of running each element of `arr` thru `func`. The order of grouped values is determined by the order they occur in `arr`. The corresponding value of each key is an array of elements responsible for generating the key.
527
- *
528
- *
529
- * @param {(any[] | Object)} arr The collection to iterate over.
530
- * @param {(Iteratee | PropertyKey)} [func=id] The iteratee to transform keys.
531
- * @return {Object} Returns the composed aggregate object.
532
- */
533
- export function groupBy(arr, func = id) {
534
- const results = {}
535
- if (Array.isArray(arr)) {
536
- for (let i = 0; i < arr.length; i++) {
537
- const item = arr[i]
538
- const groupKey = typeof func === 'function' ? func(item, i) : get(item, func)
539
- const values = results[groupKey] || []
540
- values.push(item)
541
- results[groupKey] = values
542
- }
543
- } else {
544
- for (const k in arr) {
545
- const item = arr[k]
546
- const groupKey = typeof func === 'function' ? func(item, k) : get(item, func)
547
- const values = results[groupKey]
548
- values.push(item)
549
- results[groupKey] = values
550
- }
551
- }
552
- return results
553
- }