pepka 0.12.3 → 0.13.0-b10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/safe.ts CHANGED
@@ -1,11 +1,12 @@
1
- import { __, curry } from './curry'
2
- import { isNum, nul, isUndef, undef, isNull, isArray, isFunc, isStr, isObj } from './utils'
1
+ import { __, curry, curry2, curry3 } from './curry'
2
+ import { isNum, isUndef, undef, isNull, isArray, isFunc, isStr, isObj, inf } from './utils'
3
3
  import { qmergeDeep, qreduce, qappend, qmapKeys, qmergeDeepX, qmergeDeepAdd } from './quick'
4
4
  import { AnyFunc, Cond, AnyObject, Reducer } from './types'
5
5
  import { type } from './common'
6
+ import { F as FT } from 'ts-toolbelt'
6
7
  // over, lensProp
7
8
 
8
- export const equals = curry((a: any, b: any) => {
9
+ export const equals = curry2((a: any, b: any) => {
9
10
  const typea = type(a)
10
11
  if(typea===type(b) && (typea==='Object' || typea=='Array')) {
11
12
  if(isNull(a) || isNull(b)) {
@@ -36,31 +37,33 @@ export const ifElse = curry(
36
37
  s: any
37
38
  ) => cond(s) ? pipeYes(s) : pipeNo(s)
38
39
  )
39
- export const when = curry(
40
+ export const when = curry3(
40
41
  (
41
42
  cond: (s: any) => boolean,
42
43
  pipe: (s: any) => any,
43
44
  s: any
44
45
  ) => ifElse(cond, pipe, identity, s)
45
46
  )
47
+ type Composed<TIn, TOut> = (x: TIn) => TOut
46
48
  export const compose = (
47
- (...fns: Function[]) =>
48
- (s: any = __) => {
49
+ <TIn = any, TOut = any>(...fns: AnyFunc[]): Composed<TIn, TOut> =>
50
+ (s: TIn = Symbol() as any) => {
49
51
  for(let i = length(fns)-1; i>-1; i--) {
50
52
  s = s===__ ? fns[i]() : fns[i](s)
51
53
  }
52
- return s
54
+ return s as any as TOut
53
55
  }
54
- )// as F.Compose
56
+ )
55
57
 
56
- export const bind = curry(
58
+ export const bind = curry2<AnyFunc>(
57
59
  (fn: AnyFunc, context: any) => fn.bind(context)
58
60
  )
59
- export const nth = curry(
60
- (i: number, data: any[]) => data[i]
61
- )
62
- export const includes = curry(
63
- (s: any, ss: any[]) => {
61
+
62
+ const _nth = <T=any>(i: number, data: T[] | string) => data[i]
63
+ export const nth = curry2(_nth)
64
+
65
+ export const includes = curry2(
66
+ <T>(s: T, ss: T[]) => {
64
67
  if(isStr(ss)) {
65
68
  return ss.includes(s)
66
69
  } else {
@@ -73,14 +76,14 @@ export const includes = curry(
73
76
  }
74
77
  }
75
78
  )
76
- export const slice = curry(
77
- (from: number, to: number|null, o: any[] | string) =>
78
- o.slice(from, (isNum(to)?to:Infinity) as number)
79
+ export const slice = curry3(
80
+ (from: number, to: number, o: any[] | string) =>
81
+ o.slice(from, (isNum(to)?to:inf) as number)
79
82
  )
80
83
  export const head = nth(0)
81
- export const tail = slice(1, nul)
82
- export const add = curry((n: number, m: number) => n+m)
83
- export const subtract = curry((n: number, m: number) => m-n)
84
+ export const tail = slice(1, inf) // typeshit.
85
+ export const add = curry2((n: number, m: number) => n+m)
86
+ export const subtract = curry2((n: number, m: number) => m-n)
84
87
  export const flip = (fn: Function) => curry((b: any, a: any) => fn(a, b))
85
88
  export const isNil = (s: any) => isNull(s) || isUndef(s)
86
89
  export const length = (s: any[] | string) => s.length
@@ -96,10 +99,10 @@ export const complement = (fn: AnyFunc) => (...args: any) => {
96
99
  export const keys = (o: AnyObject | any[]) => Object.keys(o)
97
100
  export const values = (o: AnyObject | any[]) => Object.values(o)
98
101
  export const toPairs = (o: AnyObject | any[]) => Object.entries(o)
99
- export const test = curry((re: RegExp, s: string) => re.test(s))
100
- export const tap = curry((fn: Function, s: any) => { fn(s); return s })
101
- export const append = curry((s: any, xs: any[]) => [...xs, s])
102
- export const split = curry((s: string, xs: string) => xs.split(s))
102
+ export const test = curry2((re: RegExp, s: string) => re.test(s))
103
+ export const tap = curry2((fn: Function, s: any) => { fn(s); return s })
104
+ export const append = curry2((s: any, xs: any[]) => [...xs, s])
105
+ export const split = curry2((s: string, xs: string) => xs.split(s))
103
106
  export const T = always<true>(true) as (...args: any[]) => true
104
107
  export const F = always<false>(false) as (...args: any[]) => false
105
108
  export const sizeof = (s: any[] | string | AnyObject) => {
@@ -109,17 +112,17 @@ export const sizeof = (s: any[] | string | AnyObject) => {
109
112
  return len
110
113
  } else return length(s as any[])
111
114
  }
112
- export const range = curry((from: number, to: number) =>
115
+ export const range = curry2((from: number, to: number) =>
113
116
  genBy(add(from), to-from)
114
117
  )
115
118
  export const uniq = (xs: any[]) => qreduce(
116
- (accum: any[], x: any) =>
119
+ <T>(accum: any, x: T) =>
117
120
  includes(x, accum) ? accum : qappend(x, accum),
118
121
  [], xs)
119
- export const intersection = curry(
122
+ export const intersection = curry2(
120
123
  (xs1: any[], xs2: any[]) => xs1.filter(flip(includes)(xs2))
121
124
  )
122
- export const genBy = curry(
125
+ export const genBy = curry2(
123
126
  (
124
127
  generator: (i: number) => any,
125
128
  length: number
@@ -137,40 +140,25 @@ export const once = <Func extends AnyFunc>(fn: Func) => {
137
140
  }
138
141
  }
139
142
  export const reverse = (xs: any[]) => compose(
140
- (ln: number) => reduce(
141
- (nxs: any[], _: any, i: number) => qappend(xs[ln-i], nxs),
143
+ <T>(ln: number) => reduce<any>(
144
+ (nxs: T[], _: any, i: number) => qappend(xs[ln-i], nxs),
142
145
  [], xs
143
146
  ),
144
147
  add(-1),
145
148
  length
146
149
  )(xs)
147
- export const gt = curry(
148
- (a: number, b: number) => a>b
149
- )
150
- export const lt = curry(
151
- (a: number, b: number) => a<b
152
- )
153
- export const gte = curry(
154
- (a: number, b: number) => b>=a
155
- )
156
- export const lte = curry(
157
- (a: number, b: number) => b<=a
158
- )
159
- // : <U=any>(sortFn: (v: U)=>-1|1, xs: U[]) => U[]
160
- export const sort = curry((sortFn: any, xs: any[]) => xs.sort(sortFn))
161
- export const find = curry(
162
- (fn: Cond, s: any[]) => s.find(fn)
163
- )
164
- export const findIndex = curry(
165
- (fn: Cond, s: any[]) => s.findIndex(fn)
166
- )
167
- export const indexOf = curry(
168
- (x: any, xs: any[]) => findIndex(equals(x), xs)
169
- )
150
+ export const gt = curry2( (a: number, b: number) => a>b )
151
+ export const lt = curry2( (a: number, b: number) => a<b )
152
+ export const gte = curry2( (a: number, b: number) => b>=a )
153
+ export const lte = curry2( (a: number, b: number) => b<=a )
154
+ export const sort = curry2((sortFn: any, xs: any[]) => xs.sort(sortFn))
155
+ export const find = curry2((fn: Cond, s: any[]) => s.find(fn))
156
+ export const findIndex = curry2((fn: Cond, s: any[]) => s.findIndex(fn))
157
+ export const indexOf = curry2((x: any, xs: any[]) => findIndex(equals(x), xs))
170
158
  export const explore = (caption: string, level = 'log') => tap(
171
159
  (v: any) => console[level](caption, v)
172
160
  )
173
- export const cond = curry(
161
+ export const cond = curry2(
174
162
  (pairs: [Cond, Function][], s: any) => {
175
163
  for(const [cond, fn] of pairs) {
176
164
  if(cond(s)) {
@@ -179,42 +167,40 @@ export const cond = curry(
179
167
  }
180
168
  }
181
169
  )
182
- export const assoc = curry(
170
+ export const assoc = curry3(
183
171
  (prop: string, v: any, obj: AnyObject) => ({
184
172
  ...obj,
185
173
  [prop]: v
186
174
  })
187
175
  )
188
- export const assocPath = curry(
176
+ export const assocPath = curry3(
189
177
  (_path: string[], v: any, o: AnyObject) => compose(
190
178
  (first: string) => assoc(
191
179
  first,
192
180
  length(_path)<2
193
181
  ? v
194
- : assocPath(slice(1, null, _path), v, isObj(o[first]) ? o[first] : {}),
182
+ : assocPath(slice(1, inf, _path), v, isObj(o[first]) ? o[first] : {}),
195
183
  o
196
184
  ),
197
185
  head
198
186
  )(_path)
199
187
  )
200
- export const all = curry((pred: Cond, xs: any[]) => xs.every(pred))
201
- export const any = curry((pred: Cond, xs: any[]) => xs.some(pred))
202
- export const allPass = curry(
188
+ export const all = curry2((pred: Cond, xs: any[]) => xs.every(pred))
189
+ export const any = curry2((pred: Cond, xs: any[]) => xs.some(pred))
190
+ export const allPass = curry2(
203
191
  (preds: Cond[], x: any) => preds.every((pred) => pred(x))
204
192
  )
205
- export const anyPass = curry(
193
+ export const anyPass = curry2(
206
194
  (preds: Cond[], x: any) => preds.some((pred) => pred(x))
207
195
  )
208
- export const prop = curry(
209
- (key: string, o: AnyObject) => o[key]
210
- )
211
- export const propEq = curry(
196
+ export const prop = curry2( (key: string, o: AnyObject) => o[key] )
197
+ export const propEq = curry3(
212
198
  (key: string, value: any, o: AnyObject) => equals(o[key], value)
213
199
  )
214
- export const propsEq = curry(
200
+ export const propsEq = curry3(
215
201
  (key: string, o1: any, o2: AnyObject) => equals(o1[key], o2[key])
216
202
  )
217
- export const pathOr = curry(
203
+ export const pathOr = curry3(
218
204
  (_default: any, path: string[], o: any) =>
219
205
  ifElse(length,
220
206
  () => isNil(o)
@@ -222,7 +208,7 @@ export const pathOr = curry(
222
208
  : compose(
223
209
  ifElse(isNil,
224
210
  always(_default),
225
- (o: any) => pathOr(_default, slice(1, nul, path), o)
211
+ (o: any) => pathOr(_default, slice(1, inf, path), o)
226
212
  ),
227
213
  flip(prop)(o),
228
214
  head
@@ -231,20 +217,21 @@ export const pathOr = curry(
231
217
  path)
232
218
  )
233
219
  export const path = pathOr(undef)
234
- export const pathEq = curry(
220
+ export const pathEq = curry3(
235
221
  (_path: string[], value: any, o: AnyObject) => equals(path(_path, o), value)
236
222
  )
237
- export const pathsEq = curry(
223
+ export const pathsEq = curry3(
238
224
  (_path: string[], o1: AnyObject, o2: AnyObject) =>
239
225
  equals(path(_path, o1), path(_path, o2))
240
226
  )
241
227
  const typed_arr_re = /^(.*?)(8|16|32|64)(Clamped)?Array$/
242
- export const clone = (s: any) => {
228
+ export const clone = (s: any, shallow = false) => {
243
229
  const t = type(s)
244
230
  switch(t) {
245
231
  case 'Null': return s
246
- case 'Array': return map(clone, s)
232
+ case 'Array': return shallow ? [...s] : map(clone, s)
247
233
  case 'Object':
234
+ if(shallow) return {...s}
248
235
  const out = {}
249
236
  for(let k in s) {
250
237
  out[k] = clone(s[k])
@@ -254,17 +241,19 @@ export const clone = (s: any) => {
254
241
  case 'Boolean': case 'Symbol':
255
242
  return s
256
243
  default:
257
- return typed_arr_re.test(t) ? map(clone, s) : s
244
+ return typed_arr_re.test(t) ? s.constructor.from(s) : s
258
245
  }
259
246
  }
260
- export const reduce = curry(
247
+ export const cloneShallow = (s: any) => clone(s, true)
248
+
249
+ export const reduce = curry3(
261
250
  (fn: Reducer, accum: any, arr: any[]) =>
262
251
  qreduce(fn, clone(accum), arr)
263
252
  )
264
- export const pickBy = curry(
253
+ export const pickBy = curry2(
265
254
  (cond: Cond, o: AnyObject) => filter(cond, o)
266
255
  )
267
- export const pick = curry(
256
+ export const pick = curry2(
268
257
  (props: string[], o: AnyObject) => {
269
258
  const out = {}
270
259
  for(const p of props) {
@@ -275,31 +264,31 @@ export const pick = curry(
275
264
  return out
276
265
  }
277
266
  )
278
- export const omit = curry(
267
+ export const omit = curry2(
279
268
  (props: string[], o: AnyObject) => filter(
280
269
  (_: any, k: string) => !includes(k, props),
281
270
  o
282
271
  )
283
272
  )
284
- export const fromPairs = (pairs: [string, any][]) => reduce(
273
+ export const fromPairs = (pairs: [string, any][]) => reduce<any>(
285
274
  (o: AnyObject, pair: [string, any]) => assoc(...pair, o),
286
275
  {}, pairs
287
276
  )
288
277
  type Concat = ((a: string, b: string) => string)
289
278
  | ((a: any[], b: any[]) => any[])
290
- export const concat = curry(
279
+ export const concat = curry2(
291
280
  ((a, b) => a.concat(b)) as Concat
292
281
  )
293
- export const join = curry(
282
+ export const join = curry2(
294
283
  (delimeter: string, arr: string[]) => arr.join(delimeter)
295
284
  )
296
- export const map = curry(
285
+ export const map = curry2(
297
286
  (pipe: (s: any) => any, arr: any[]) => arr.map(pipe)
298
287
  )
299
- export const forEach = curry(
288
+ export const forEach = curry2(
300
289
  (pipe: (s: any) => any, arr: any[]) => arr.forEach(pipe)
301
290
  )
302
- export const both = curry(
291
+ export const both = curry3(
303
292
  (cond1: Cond, cond2: Cond, s: any) => cond2(s) && cond1(s)
304
293
  )
305
294
  export const isEmpty = (s: any) => {
@@ -319,14 +308,14 @@ export const empty = (s: any) => {
319
308
  default: return undef
320
309
  }
321
310
  }
322
- export const replace = curry(
311
+ export const replace = curry3(
323
312
  (
324
313
  a: string | RegExp,
325
314
  b: string,
326
315
  where: string
327
316
  ) => where.replace(a, b)
328
317
  )
329
- export const filter = curry(
318
+ export const filter = curry2(
330
319
  (
331
320
  cond: (v: any, k: string | number) => boolean,
332
321
  data: any[] | AnyObject
@@ -343,25 +332,25 @@ export const memoize = (fn: Function) => {
343
332
  let cached = false
344
333
  return () => cached ? cache : (cached = true, cache = fn())
345
334
  }
346
- export const mergeShallow = curry(
335
+ export const mergeShallow = curry2(
347
336
  (o1: AnyObject, o2: AnyObject): AnyObject =>
348
337
  Object.assign({}, o1, o2)
349
338
  )
350
- export const mergeDeep = curry(
339
+ export const mergeDeep = curry2(
351
340
  (a: AnyObject, b: AnyObject) => qmergeDeep(clone(a), clone(b))
352
341
  )
353
- export const mergeDeepX = curry(
342
+ export const mergeDeepX = curry2(
354
343
  (a: AnyObject, b: AnyObject) => qmergeDeepX(clone(a), clone(b))
355
344
  )
356
- export const mergeDeepAdd = curry(
345
+ export const mergeDeepAdd = curry2(
357
346
  (a: AnyObject, b: AnyObject) => qmergeDeepAdd(clone(a), clone(b))
358
347
  )
359
- export const overProp = curry(
348
+ export const overProp = curry3(
360
349
  (prop: string, pipe: AnyFunc, data: any) =>
361
350
  assoc(prop, pipe(data[prop]), data)
362
351
  )
363
352
  /** mapKeys({ a: 'b' }, { a: 44 }) -> { b: 44 } */
364
- export const mapKeys = curry(
353
+ export const mapKeys = curry2(
365
354
  (
366
355
  keyMap: {[oldKey: string]: string},
367
356
  o: AnyObject
@@ -378,14 +367,15 @@ export const forEachSerial = (() => {
378
367
  await pipe(fn, items, ++i)
379
368
  }
380
369
  }
381
- return curry(
370
+ return curry2(
382
371
  (fn: AnyFunc, items: any[]) => pipe(fn, items, 0)
383
372
  )
384
373
  })()
385
374
  /** Promise.all wrapper for functional pipelining. */
386
375
  export const waitAll = (promises: Promise<any>[]) => Promise.all(promises)
376
+ export const waitTap = curry2(async (fn: Function, s: any) => { await fn(s); return s })
387
377
  /** Waits for all promises mapped by the fn. */
388
- export const forEachAsync = curry(
378
+ export const forEachAsync = curry2(
389
379
  (fn: (item: any) => Promise<any>, items: any[]) =>
390
380
  Promise.all(items.map(fn))
391
381
  )
@@ -395,10 +385,9 @@ export const composeAsync = (() => {
395
385
  ~i ? await pipe(fns, await fns[i](data), --i) : data
396
386
  return <T = any>(...fns: AnyFunc[]) =>
397
387
  (data?: any) => pipe(fns, data, fns.length-1) as Promise<T>
398
- })()
388
+ })() as FT.Compose<'async'>
399
389
 
400
390
  // ALIASES
401
-
402
391
  export const mirror = identity
403
392
  export const reflect = identity
404
- export const echo = identity
393
+ export const echo = identity
package/src/types.ts CHANGED
@@ -1,7 +1,14 @@
1
-
2
1
  export type Cond = (...xs: any[]) => boolean
3
2
  export interface AnyObject {
4
3
  [k: string]: any
5
4
  }
6
- export type Reducer = <T>(accum: T, cur: any, index: number) => T
7
- export type AnyFunc = (...args: any[]) => any
5
+ export type AnyArgs = any[]
6
+ export type Curried<
7
+ Args extends AnyArgs = AnyArgs,
8
+ ReturnT = any
9
+ > = (arg: Args[number]) => Curried<Args> | ReturnT
10
+ export type Reducer = <T=any>(accum: T, cur: any, index: number) => T
11
+ export type AnyFunc<
12
+ ReturnT = any,
13
+ Args extends AnyArgs = AnyArgs
14
+ > = (...args: Args) => ReturnT
package/src/uncurry.ts ADDED
@@ -0,0 +1,11 @@
1
+ import { qreduce } from "./quick"
2
+ import { AnyFunc, Curried } from "./types"
3
+
4
+ // TODO: possibly introduce a second argument limiting unfolding.
5
+ export const uncurry = <
6
+ Args extends any[] = any[],
7
+ ReturnT = any
8
+ >(fn: Curried<Args>): AnyFunc =>
9
+ (...args: Args) => qreduce<any>(
10
+ ((fn: Curried<Args>, arg: any) => fn ? fn(arg) : fn), fn, args
11
+ ) as ReturnT
package/src/utils.ts CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  export const undef = undefined
4
4
  export const nul = null
5
+ export const inf = Infinity
5
6
  export const to = (s: any) => typeof s
6
7
  export const isNull = (s: any) => s===nul
7
8
  export const isUndef = (s: any) => s===undef
package/tsconfig.json CHANGED
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "compilerOptions": {
3
+ "moduleResolution": "Node",
3
4
  "lib": [ "esnext", "DOM" ],
4
5
  "strictNullChecks": true,
5
6
  "target": "esnext",
@@ -14,8 +15,5 @@
14
15
  "rootDir": "src",
15
16
  "baseUrl": "."
16
17
  },
17
- "include": [
18
- "src/**/*",
19
- "src/node_modules/ts-toolbelt/out/index.d.ts"
20
- ]
18
+ "include": [ "src/**/*" ]
21
19
  }