ctx-core 2.2.2 → 2.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.
@@ -1,4 +1,4 @@
1
- import { isPromise } from '../isPromise/index.js'
1
+ import { isPromiseLike } from '../isPromiseLike/index.js'
2
2
  /**
3
3
  * Returns an async function, that, as long as it continues to be invoked, will not
4
4
  * be triggered. The function will be called after it stops being called for
@@ -35,7 +35,7 @@ export function debounce(func, wait, immediate) {
35
35
  async function invoke() {
36
36
  try {
37
37
  const in_rv = func.apply(apply_this, arg_a)
38
- resolve(isPromise(in_rv) ? await in_rv : in_rv)
38
+ resolve(isPromiseLike(in_rv) ? await in_rv : in_rv)
39
39
  } catch (e) {
40
40
  reject(e)
41
41
  }
package/all/index.d.ts CHANGED
@@ -188,7 +188,8 @@ export * from './isNumber/index.js'
188
188
  export * from './isNumber_andor/index.js'
189
189
  export * from './isNumber_or/index.js'
190
190
  export * from './isObject/index.js'
191
- export * from './isPromise/index.js'
191
+ export * from './isPrimitive/index.js'
192
+ export * from './isPromiseLike/index.js'
192
193
  export * from './item_r_idx/index.js'
193
194
  export * from './key_compare/index.js'
194
195
  export * from './key_r/index.js'
@@ -222,6 +223,7 @@ export * from './matrix__validate_length/index.js'
222
223
  export * from './maybe/index.js'
223
224
  export * from './mean/index.js'
224
225
  export * from './median/index.js'
226
+ export * from './memo/index.js'
225
227
  export * from './merge/index.js'
226
228
  export * from './minute/index.js'
227
229
  export * from './minute/index.js'
@@ -291,6 +293,7 @@ export * from './prev_idx/index.js'
291
293
  export * from './promise/index.js'
292
294
  export * from './promise_o/index.js'
293
295
  export * from './promise_timeout/index.js'
296
+ export * from './prototype/index.js'
294
297
  export * from './prototype_mixin/index.js'
295
298
  export * from './push/index.js'
296
299
  export * from './quantile/index.js'
package/all/index.js CHANGED
@@ -188,7 +188,8 @@ export * from './isNumber/index.js'
188
188
  export * from './isNumber_andor/index.js'
189
189
  export * from './isNumber_or/index.js'
190
190
  export * from './isObject/index.js'
191
- export * from './isPromise/index.js'
191
+ export * from './isPrimitive/index.js'
192
+ export * from './isPromiseLike/index.js'
192
193
  export * from './item_r_idx/index.js'
193
194
  export * from './key_compare/index.js'
194
195
  export * from './key_r/index.js'
@@ -222,6 +223,7 @@ export * from './matrix__validate_length/index.js'
222
223
  export * from './maybe/index.js'
223
224
  export * from './mean/index.js'
224
225
  export * from './median/index.js'
226
+ export * from './memo/index.js'
225
227
  export * from './merge/index.js'
226
228
  export * from './minute/index.js'
227
229
  export * from './minute/index.js'
@@ -291,6 +293,7 @@ export * from './prev_idx/index.js'
291
293
  export * from './promise/index.js'
292
294
  export * from './promise_o/index.js'
293
295
  export * from './promise_timeout/index.js'
296
+ export * from './prototype/index.js'
294
297
  export * from './prototype_mixin/index.js'
295
298
  export * from './push/index.js'
296
299
  export * from './quantile/index.js'
@@ -13,7 +13,7 @@ export function intersection_set_(member_a_nowrap_a_nowrap) {
13
13
  const rest_a_nowrap = rest_a_nowrap_a[i]
14
14
  const rest_a = wrap_a_(rest_a_nowrap)
15
15
  const current_set = new Set(rest_a)
16
- member_set.forEach((member)=>{
16
+ member_set.forEach(member=>{
17
17
  if (!current_set.has(member)) member_set.delete(member)
18
18
  })
19
19
  }
@@ -0,0 +1 @@
1
+ export declare function isPrimitive(v:unknown):boolean
@@ -0,0 +1,6 @@
1
+ export function isPrimitive(val) {
2
+ return (
3
+ val === null
4
+ || (typeof val !== 'object' && typeof val !== 'function')
5
+ )
6
+ }
@@ -0,0 +1,17 @@
1
+ import { test } from 'uvu'
2
+ import { equal } from 'uvu/assert'
3
+ import { isPrimitive } from './index.js'
4
+ test('isPrimitive', ()=>{
5
+ equal(isPrimitive(1), true)
6
+ equal(isPrimitive('foo'), true)
7
+ equal(isPrimitive(null), true)
8
+ equal(isPrimitive(undefined), true)
9
+ equal(isPrimitive(true), true)
10
+ equal(isPrimitive(false), true)
11
+ equal(isPrimitive(Symbol('foo')), true)
12
+ equal(isPrimitive({}), false)
13
+ equal(isPrimitive([]), false)
14
+ equal(isPrimitive(()=>1), false)
15
+ equal(isPrimitive(new Date), false)
16
+ })
17
+ test.run()
@@ -0,0 +1,4 @@
1
+ export declare function isPromiseLike(val:any):boolean
2
+ export {
3
+ isPromiseLike as isPromise,
4
+ }
@@ -2,6 +2,9 @@
2
2
  * @param {unknown}val
3
3
  * @returns {boolean}
4
4
  */
5
- export function isPromise(val) {
5
+ export function isPromiseLike(val) {
6
6
  return val ? typeof val.then === 'function' : false
7
7
  }
8
+ export {
9
+ isPromiseLike as isPromise,
10
+ }
@@ -0,0 +1,6 @@
1
+ export declare function memo_<
2
+ ret_T,
3
+ arg_a_T extends Array<unknown>,
4
+ >(fn:(...arg_a:arg_a_T)=>ret_T):((...arg_a:arg_a_T)=>ret_T)&{
5
+ clear():void
6
+ }
@@ -0,0 +1,61 @@
1
+ import { isPrimitive } from '../isPrimitive/index.js'
2
+ import { prototype_ } from '../prototype/index.js'
3
+ let empty_sym, WeakRef_proto
4
+ /**
5
+ * @param {(...arg_a:any[])=>any}fn
6
+ * @returns A memo caching arguments & return values. Arguments that are Objects are cached with a WeakRef.
7
+ * @private
8
+ */
9
+ export function memo_(fn) {
10
+ let m = new Map
11
+ let wm = new WeakMap
12
+ if (!empty_sym) {
13
+ empty_sym = Symbol('E')
14
+ WeakRef_proto = WeakRef.prototype
15
+ }
16
+ let memo = (...arg_a)=>{
17
+ if (!arg_a.length) {
18
+ if (!m.has(empty_sym)) {
19
+ m.set(empty_sym, fn())
20
+ }
21
+ return m.get(empty_sym)
22
+ }
23
+ let arg0 = arg_a[0]
24
+ let map = isPrimitive(arg0) ? m : wm
25
+ /** @type {[unknown[], unknown][]} */
26
+ let cache__arg_a_T_ret__a = map.get(arg0)
27
+ if (!cache__arg_a_T_ret__a) {
28
+ cache__arg_a_T_ret__a = []
29
+ map.set(arg0, cache__arg_a_T_ret__a)
30
+ }
31
+ cache__arg_a_T_ret__a:for (let cache__arg_a_T_ret__a__i = cache__arg_a_T_ret__a.length; cache__arg_a_T_ret__a__i--;) {
32
+ let cache__arg_a_T_ret = cache__arg_a_T_ret__a[cache__arg_a_T_ret__a__i]
33
+ let cache__arg_a = cache__arg_a_T_ret[0]
34
+ let { length } = arg_a
35
+ if (cache__arg_a.length !== length) continue
36
+ for (let arg_a__i = length; arg_a__i--;) {
37
+ let cache__arg_val = cache__arg_a[arg_a__i]
38
+ if (prototype_(cache__arg_val) === WeakRef_proto) {
39
+ cache__arg_val = cache__arg_val.deref()
40
+ if (!cache__arg_val) { // cleanup cache__arg_a when arg is GC
41
+ cache__arg_a_T_ret__a.splice(cache__arg_a_T_ret__a__i, 1)
42
+ continue cache__arg_a_T_ret__a
43
+ }
44
+ }
45
+ let arg_val = arg_a[arg_a__i]
46
+ if (arg_val !== cache__arg_val) break
47
+ if (!arg_a__i) { // arguments match
48
+ return cache__arg_a_T_ret[1]
49
+ }
50
+ }
51
+ }
52
+ let ret = fn(...arg_a)
53
+ cache__arg_a_T_ret__a.push([arg_a.map(arg=>isPrimitive(arg) ? arg : new WeakRef(arg)), ret])
54
+ return ret
55
+ }
56
+ memo.clear = ()=>{
57
+ m.clear()
58
+ wm = new WeakMap
59
+ }
60
+ return memo
61
+ }
@@ -0,0 +1,75 @@
1
+ import { test } from 'uvu'
2
+ import { equal } from 'uvu/assert'
3
+ import { memo_ } from './index.js'
4
+ test('memo_|empty', ()=>{
5
+ let call_count = 0
6
+ let fn = ()=>{
7
+ call_count++
8
+ return 'memo-return'
9
+ }
10
+ let memo = memo_(fn)
11
+ equal(call_count, 0)
12
+ equal(memo(), 'memo-return')
13
+ equal(call_count, 1)
14
+ equal(memo(), 'memo-return')
15
+ equal(call_count, 1)
16
+ })
17
+ test('memo_|primitive arguments', ()=>{
18
+ let call_count = 0
19
+ let fn = (arg0:number, arg1:number)=>{
20
+ call_count++
21
+ return arg0 + arg1
22
+ }
23
+ let memo = memo_(fn)
24
+ equal(call_count, 0)
25
+ equal(memo(1, 2), 3)
26
+ equal(call_count, 1)
27
+ equal(memo(1, 2), 3)
28
+ equal(call_count, 1)
29
+ equal(memo(1, 3), 4)
30
+ equal(call_count, 2)
31
+ memo.clear()
32
+ equal(memo(1, 2), 3)
33
+ equal(call_count, 3)
34
+ })
35
+ test('memo_|primitive|with objects', ()=>{
36
+ let call_count = 0
37
+ let fn = (arg0:number, arg1:object)=>{
38
+ call_count++
39
+ return { ...arg1, arg0 }
40
+ }
41
+ let memo = memo_(fn)
42
+ let arg1 = { arg1: true }
43
+ let arg1_2 = { arg1_2: true }
44
+ equal(call_count, 0)
45
+ equal(memo(1, arg1), { arg1: true, arg0: 1 })
46
+ equal(call_count, 1)
47
+ equal(memo(1, arg1), { arg1: true, arg0: 1 })
48
+ equal(call_count, 1)
49
+ equal(memo(1, arg1_2), { arg1_2: true, arg0: 1 })
50
+ equal(call_count, 2)
51
+ memo.clear()
52
+ equal(memo(1, arg1), { arg1: true, arg0: 1 })
53
+ equal(call_count, 3)
54
+ })
55
+ test('memo_|objects|with primitives', ()=>{
56
+ let call_count = 0
57
+ let fn = (arg0:object, arg1:number)=>{
58
+ call_count++
59
+ return { ...arg0, arg1 }
60
+ }
61
+ let memo = memo_(fn)
62
+ let arg0 = { arg0: true }
63
+ let arg0_2 = { arg0_2: true }
64
+ equal(call_count, 0)
65
+ equal(memo(arg0, 1), { arg0: true, arg1: 1 })
66
+ equal(call_count, 1)
67
+ equal(memo(arg0, 1), { arg0: true, arg1: 1 })
68
+ equal(call_count, 1)
69
+ equal(memo(arg0_2, 1), { arg0_2: true, arg1: 1 })
70
+ equal(call_count, 2)
71
+ memo.clear()
72
+ equal(memo(arg0, 1), { arg0: true, arg1: 1 })
73
+ equal(call_count, 3)
74
+ })
75
+ test.run()
@@ -0,0 +1,2 @@
1
+ import type { nullish } from '../nullish/index.js'
2
+ export declare function prototype_(val:Exclude<any, nullish>):Object
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @param {Object}val
3
+ * @returns {Object}
4
+ * @private
5
+ */
6
+ export function prototype_(val) {
7
+ return Object.getPrototypeOf(val)
8
+ }
@@ -0,0 +1,14 @@
1
+ import { test } from 'uvu'
2
+ import { is, not } from 'uvu/assert'
3
+ import { prototype_ } from './index.js'
4
+ test('prototype_', ()=>{
5
+ is(prototype_({}), Object.prototype)
6
+ is(prototype_(new WeakRef({})), WeakRef.prototype)
7
+ is(prototype_(1), Number.prototype)
8
+ is(prototype_(true), Boolean.prototype)
9
+ is(prototype_(false), Boolean.prototype)
10
+ not.equal(prototype_(new Date), Boolean.prototype)
11
+ not.equal(prototype_({}), Boolean.prototype)
12
+ not.equal(prototype_(1), Boolean.prototype)
13
+ })
14
+ test.run()
@@ -0,0 +1,8 @@
1
+ export declare function rememo_<val_T>(def:()=>val_T):rememo_T<val_T>
2
+ export type rememo_T<val_T> =
3
+ ((rememo:rememo_T<val>)=>val_T)
4
+ &rememo_o_T<val_T>
5
+ export type rememo_o_T<val_T> = {
6
+ val:val_T
7
+ listeners:Set<WeakRef<rememo_T<val_T>>>
8
+ }
@@ -0,0 +1,9 @@
1
+ /** @typedef {import('./index.d.ts').rememo_o_T} */
2
+ /**
3
+ * @param {(rememo:rememo_T<unknown>)=>unknown}fn
4
+ * @returns {rememo_T}
5
+ * @private
6
+ */
7
+ export function rememo_(fn) {
8
+ // let
9
+ }
@@ -36,7 +36,7 @@ export * from '../all/ifelse/index.js'
36
36
  export * from '../all/iife/index.js'
37
37
  export * from '../all/invert/index.js'
38
38
  export * from '../all/isArray/index.js'
39
- export * from '../all/isPromise/index.js'
39
+ export * from '../all/isPromiseLike/index.js'
40
40
  export * from '../all/left_and/index.js'
41
41
  export * from '../all/left_or/index.js'
42
42
  export * from '../all/many_andand/index.js'
@@ -45,6 +45,7 @@ export * from '../all/map_apply/index.js'
45
45
  export * from '../all/map_call/index.js'
46
46
  export * from '../all/map_fn/index.js'
47
47
  export * from '../all/maybe/index.js'
48
+ export * from '../all/memo/index.js'
48
49
  export * from '../all/neq/index.js'
49
50
  export * from '../all/neql/index.js'
50
51
  export * from '../all/nf/index.js'
package/function/index.js CHANGED
@@ -36,7 +36,7 @@ export * from '../all/ifelse/index.js'
36
36
  export * from '../all/iife/index.js'
37
37
  export * from '../all/invert/index.js'
38
38
  export * from '../all/isArray/index.js'
39
- export * from '../all/isPromise/index.js'
39
+ export * from '../all/isPromiseLike/index.js'
40
40
  export * from '../all/left_and/index.js'
41
41
  export * from '../all/left_or/index.js'
42
42
  export * from '../all/many_andand/index.js'
@@ -45,6 +45,7 @@ export * from '../all/map_apply/index.js'
45
45
  export * from '../all/map_call/index.js'
46
46
  export * from '../all/map_fn/index.js'
47
47
  export * from '../all/maybe/index.js'
48
+ export * from '../all/memo/index.js'
48
49
  export * from '../all/neq/index.js'
49
50
  export * from '../all/neql/index.js'
50
51
  export * from '../all/nf/index.js'
package/object/index.d.ts CHANGED
@@ -40,6 +40,7 @@ export * from '../all/or_null/index.js'
40
40
  export * from '../all/pick/index.js'
41
41
  export * from '../all/pick_keys/index.js'
42
42
  export * from '../all/pick_val_a/index.js'
43
+ export * from '../all/prototype/index.js'
43
44
  export * from '../all/rc_be/index.js'
44
45
  export * from '../all/rc_be_/index.js'
45
46
  export * from '../all/toString/index.js'
package/object/index.js CHANGED
@@ -39,6 +39,7 @@ export * from '../all/or_null/index.js'
39
39
  export * from '../all/pick/index.js'
40
40
  export * from '../all/pick_keys/index.js'
41
41
  export * from '../all/pick_val_a/index.js'
42
+ export * from '../all/prototype/index.js'
42
43
  export * from '../all/rc_be/index.js'
43
44
  export * from '../all/rc_be_/index.js'
44
45
  export * from '../all/toString/index.js'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ctx-core",
3
- "version": "2.2.2",
3
+ "version": "2.3.0",
4
4
  "description": "ctx-core core library",
5
5
  "keywords": [
6
6
  "ctx-core",
@@ -53,6 +53,7 @@
53
53
  "queue",
54
54
  "random",
55
55
  "regex",
56
+ "rememo",
56
57
  "set",
57
58
  "sleep",
58
59
  "string",
@@ -104,6 +105,7 @@
104
105
  },
105
106
  "devDependencies": {
106
107
  "@arethetypeswrong/cli": "^0.13.1",
108
+ "@types/node": "^20.9.0",
107
109
  "@types/sinon": "^17.0.1",
108
110
  "c8": "^8.0.1",
109
111
  "check-dts": "^0.7.2",
@@ -0,0 +1 @@
1
+ export * from '../all/rememo/index.js'
@@ -0,0 +1 @@
1
+ export * from '../all/rememo/index.js'
package/tsconfig.json CHANGED
@@ -5,7 +5,10 @@
5
5
  "moduleResolution": "nodenext",
6
6
  "target": "ESNext",
7
7
  "strict": true,
8
- "skipLibCheck": true
9
- },
10
- "exclude": ["node_modules"]
8
+ "skipLibCheck": true,
9
+ "lib": ["ESNext"],
10
+ "types": [
11
+ "node"
12
+ ]
13
+ }
11
14
  }
@@ -1 +0,0 @@
1
- export declare function isPromise(obj:any):boolean