ctx-core 5.8.0 → 5.10.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.
@@ -6,7 +6,7 @@ import { be_ } from '../be_/index.js'
6
6
  import { lock_memosig_ } from '../rmemo/index.js'
7
7
  /**
8
8
  * @param {Be<sig_T>|be__val__new_T<unknown>}be_OR_val__new
9
- * @param {rmemo_subscriber_T[]|[...rmemo_subscriber_T[], be_config_T]}subscriber_a_THEN_config
9
+ * @param {memo_subscriber_T[]|[...memo_subscriber_T[], be_config_T]}subscriber_a_THEN_config
10
10
  * @returns {be_lock_memosig_triple_T}
11
11
  * @private
12
12
  */
@@ -5,7 +5,7 @@ import { be_ } from '../be_/index.js'
5
5
  import { memo_ } from '../rmemo/index.js'
6
6
  /**
7
7
  * @param {Be|be__val__new_T<unknown>}be_OR_val__new
8
- * @param {rmemo_subscriber_T[]|[...rmemo_subscriber_T[], be_config_T]}subscriber_a_THEN_config
8
+ * @param {memo_subscriber_T[]|[...memo_subscriber_T[], be_config_T]}subscriber_a_THEN_config
9
9
  * @returns {be_memo_pair_T}
10
10
  * @private
11
11
  */
@@ -5,7 +5,7 @@ import { be_ } from '../be_/index.js'
5
5
  import { sig_ } from '../rmemo/index.js'
6
6
  /**
7
7
  * @param {Be<sig_T>|be__val__new_T<unknown>}be_OR_val__new
8
- * @param {rmemo_subscriber_T[]|[...rmemo_subscriber_T[], be_config_T]}subscriber_a_THEN_config
8
+ * @param {memo_subscriber_T[]|[...memo_subscriber_T[], be_config_T]}subscriber_a_THEN_config
9
9
  * @returns {be_sig_triple_T}
10
10
  * @private
11
11
  */
@@ -0,0 +1,8 @@
1
+ export declare class Cancel<R = unknown> extends Error {
2
+ constructor(config?:Cancel_config_T<R>)
3
+ returns:R
4
+ }
5
+ export type Cancel_config_T<R = unknown> = {
6
+ message?:string
7
+ returns?:R
8
+ }
@@ -0,0 +1,6 @@
1
+ export class Cancel extends Error {
2
+ constructor(config) {
3
+ super(config?.message ?? 'Cancel')
4
+ this.returns = config?.returns
5
+ }
6
+ }
@@ -0,0 +1,9 @@
1
+ import { test } from 'uvu'
2
+ import { equal } from 'uvu/assert'
3
+ import { Cancel } from './index.js'
4
+ test('Cancel', ()=>{
5
+ equal(new Cancel().message, 'Cancel')
6
+ equal(new Cancel({ message: 'custom message' }).message, 'custom message')
7
+ equal(new Cancel({ returns: 1 }).returns, 1)
8
+ })
9
+ test.run()
@@ -1,3 +1,4 @@
1
+ import type { waitfor_Promise } from '../waitfor/index.js'
1
2
  export declare function file_exists_(path:string):Promise<boolean|undefined>
2
3
  export {
3
4
  file_exists_ as path__exists_
@@ -5,5 +6,5 @@ export {
5
6
  export declare function file_exists__waitfor(
6
7
  path:string,
7
8
  timeout?:number,
8
- period?:number
9
- ):Promise<void>
9
+ period?:number|((promise:waitfor_Promise<boolean>)=>Promise<number>)
10
+ ):waitfor_Promise<boolean>
@@ -19,9 +19,16 @@ export {
19
19
  /**
20
20
  * @param {string}path
21
21
  * @param {number}[timeout]
22
- * @param {number}[period]
23
- * @returns {Promise<void>}
22
+ * @param {number|((promise:waitfor_Promise<boolean>)=>Promise<number>)}[period]
23
+ * @returns {Promise<boolean>}
24
24
  */
25
- export function file_exists__waitfor(path, timeout = 5000, period = 0) {
26
- return waitfor(()=>file_exists_(path), timeout, period)
25
+ export function file_exists__waitfor(
26
+ path,
27
+ timeout,
28
+ period
29
+ ) {
30
+ return waitfor(()=>
31
+ file_exists_(path),
32
+ timeout ?? 5000,
33
+ period ?? 0)
27
34
  }
@@ -3,18 +3,35 @@ import { unlink, writeFile } from 'fs/promises'
3
3
  import { test } from 'uvu'
4
4
  import { equal } from 'uvu/assert'
5
5
  import { tempfile_path_ } from '../tempfile_path/index.js'
6
+ import { waitfor_Promise } from '../waitfor/index.js'
6
7
  import { file_exists_, file_exists__waitfor } from './index.js'
7
8
  test('file_exists_ + file_exists__waitfor|server', async ()=>{
8
9
  const tempfile_path = await tempfile_path_()
9
10
  equal(await file_exists_(tempfile_path), false)
10
11
  await writeFile(tempfile_path, 'test content')
11
12
  try {
12
- await file_exists__waitfor(tempfile_path)
13
+ equal(await file_exists__waitfor(tempfile_path), true)
13
14
  equal(await file_exists_(tempfile_path), true)
14
15
  } finally {
15
16
  await unlink(tempfile_path)
16
17
  }
17
18
  })
19
+ test('file_exists__waitfor|server|cancel', async ()=>{
20
+ const tempfile_path = await tempfile_path_()
21
+ equal(await file_exists_(tempfile_path), false)
22
+ const promise= file_exists__waitfor(tempfile_path)
23
+ let rv:boolean|undefined = undefined
24
+ promise.then(_rv=>rv = _rv)
25
+ equal(rv, undefined)
26
+ equal(await promise.cancel(), false)
27
+ equal(await promise, false)
28
+ rv = undefined
29
+ const arg_promise= file_exists__waitfor(tempfile_path)
30
+ promise.then(_rv=>rv = _rv)
31
+ equal(rv, undefined)
32
+ equal(await arg_promise.cancel(true), true)
33
+ equal(await arg_promise, true)
34
+ })
18
35
  test('file_exists_ + file_exists__waitfor|browser', async ()=>{
19
36
  const { file_exists_, file_exists__waitfor } = await esmock('./index.js', {}, {
20
37
  '../process_release_name/index.js': {
package/all/index.d.ts CHANGED
@@ -70,6 +70,7 @@ export * from './call/index.js'
70
70
  export * from './call_assign/index.js'
71
71
  export * from './call_fn_a/index.js'
72
72
  export * from './call_or_fn/index.js'
73
+ export * from './cancel/index.js'
73
74
  export * from './chain/index.js'
74
75
  export * from './chunk_aa/index.js'
75
76
  export * from './circular_idx/index.js'
package/all/index.js CHANGED
@@ -70,6 +70,7 @@ export * from './call/index.js'
70
70
  export * from './call_assign/index.js'
71
71
  export * from './call_fn_a/index.js'
72
72
  export * from './call_or_fn/index.js'
73
+ export * from './cancel/index.js'
73
74
  export * from './chain/index.js'
74
75
  export * from './chunk_aa/index.js'
75
76
  export * from './circular_idx/index.js'
@@ -1,2 +1,11 @@
1
- export declare type promise_resolve_T<T> = (value:T|PromiseLike<T>)=>void
2
- export declare type promise_reject_T = (reason?:any)=>void
1
+ export type promise_resolve_T<T> = (value:T|PromiseLike<T>)=>void
2
+ export type promise_reject_T = (reason?:unknown)=>void
3
+ export type cancel_Promise<
4
+ V,
5
+ cancel_fn_T extends (
6
+ |(()=>Promise<V>)
7
+ |((val:V)=>Promise<V>)
8
+ )
9
+ > =
10
+ &Promise<V>
11
+ &{ cancel:cancel_fn_T }
@@ -1 +1 @@
1
- export {}
1
+ export {}
@@ -1,5 +1,6 @@
1
+ import type { cancel_Promise } from '../promise/index.js'
1
2
  export declare function promise_timeout<O>(
2
3
  promise:(()=>Promise<O>)|Promise<O>,
3
4
  ms:number,
4
5
  error?:Error
5
- ):Promise<O>&{ cancel:(val:O)=>void }
6
+ ):cancel_Promise<O, (val?:O)=>Promise<O>>
@@ -2,7 +2,7 @@
2
2
  * @param {(()=>Promise<unknown>)|Promise<unknown>}promise
3
3
  * @param {number}ms
4
4
  * @param {Error}[error]
5
- * @returns {Promise<unknown>}
5
+ * @returns {cancel_Promise}
6
6
  */
7
7
  export function promise_timeout(
8
8
  promise,
@@ -16,6 +16,7 @@ export function promise_timeout(
16
16
  })
17
17
  let cancel_promise__resolve
18
18
  let cancel_promise = new Promise(resolve=>cancel_promise__resolve = resolve)
19
+ /** @type {cancel_Promise} */
19
20
  let ret_promise = Promise.race([
20
21
  typeof promise === 'function' ? promise() : promise,
21
22
  timeout,
@@ -19,21 +19,25 @@ export declare function on(rmemo:rmemo_T<unknown>):void
19
19
  export declare function off(rmemo:rmemo_T<unknown>):void
20
20
  export declare function rmemo__subscribe(rmemo:rmemo_T<unknown>, listener:()=>unknown):()=>void
21
21
  export type rmemo_T<val_T> = memo_T<val_T>|sig_T<val_T>|lock_memosig_T<val_T>
22
+ export type circular_rmemo_T = circular_memo_T|circular_sig_T|circular_lock_memosig_T
22
23
  export type memo_T<val_T> = (()=>val_T)&{
23
24
  readonly _:val_T
24
25
  readonly val:val_T
25
26
  r?:WeakRef<()=>val_T>
26
27
  memor:WeakRef<()=>val_T>[]
27
28
  }
29
+ export interface circular_memo_T extends memo_T<circular_memo_T> {}
28
30
  export type sig_T<val_T> = (()=>val_T)&{
29
31
  _:val_T
30
32
  readonly val:val_T
31
33
  r?:WeakRef<()=>val_T>
32
34
  memor:WeakRef<()=>val_T>[]
33
35
  }
36
+ export interface circular_sig_T extends sig_T<circular_sig_T> {}
34
37
  export type lock_memosig_T<val_T> = sig_T<val_T>&{
35
38
  lock?:0|1
36
39
  }
40
+ export interface circular_lock_memosig_T extends lock_memosig_T<circular_lock_memosig_T> {}
37
41
  export type rmemo_val_T<sig_T> = sig_T extends { ():infer val_T }
38
42
  ? val_T
39
43
  : unknown
@@ -1,3 +1,4 @@
1
+ import { cancel_Promise } from '../promise/index.js'
1
2
  import type { memo_T, rmemo_T, rmemo_val_T } from '../rmemo/index.js'
2
3
  export declare function rmemo__wait<
3
4
  _rmemo_T extends rmemo_T<unknown> = rmemo_T<unknown>
@@ -6,8 +7,12 @@ export declare function rmemo__wait<
6
7
  condition_fn:(val:rmemo_val_T<_rmemo_T>)=>unknown,
7
8
  timeout?:number,
8
9
  error?:Error
9
- ):Promise<rmemo_val_T<_rmemo_T>>&{
10
+ ):rmemo__wait_ret_T<rmemo_val_T<_rmemo_T>>
11
+ export type rmemo__wait_ret_T<R> =
12
+ cancel_Promise<
13
+ R,
14
+ (val?:R)=>Promise<R>
15
+ >&{
10
16
  // prevent early usGC
11
17
  m:memo_T<unknown>
12
- cancel:(val:rmemo_val_T<_rmemo_T>)=>void
13
18
  }
@@ -7,7 +7,7 @@ import { memo_ } from '../rmemo/index.js'
7
7
  * @param {(val:unknown)=>unknown}condition_fn
8
8
  * @param {number}[timeout]
9
9
  * @param {Error}[error]
10
- * @returns {Promise<*>|Promise<unknown>}
10
+ * @returns {cancel_Promise&{ m:memo_T<unknown> }}
11
11
  */
12
12
  export function rmemo__wait(
13
13
  rmemo,
@@ -24,6 +24,7 @@ export function rmemo__wait(
24
24
  })
25
25
  memo()
26
26
  })
27
+ /** @type {cancel_Promise&{ m:memo_T<unknown> }} */
27
28
  let promise =
28
29
  promise_timeout(
29
30
  _subscribe_wait,
@@ -1 +1,3 @@
1
- export declare function sleep(ms:number):Promise<number|NodeJS.Timeout>
1
+ export declare function sleep(
2
+ ms:number
3
+ ):Promise<number>
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * @param {number}ms
3
- * @returns {Promise<number|NodeJS.Timeout>}
3
+ * @returns {Promise<number>}
4
4
  */
5
5
  export function sleep(ms) {
6
- return new Promise((resolve)=>setTimeout(resolve, ms))
6
+ return new Promise(resolve=>
7
+ setTimeout(resolve, ms))
7
8
  }
@@ -1,5 +1,14 @@
1
+ import type { cancel_Promise } from '../promise/index.js'
1
2
  export declare function waitfor<V>(
2
3
  fn:()=>Promise<V>|V,
3
4
  timeout:number,
4
- period?:number
5
- ):Promise<V>&{ cancel:()=>Promise<V> }
5
+ period?:number|((promise:waitfor_Promise<V>)=>Promise<number>)
6
+ ):waitfor_Promise<V>
7
+ export declare function cancel__period_<V>(
8
+ ms:number,
9
+ should_cancel_:()=>boolean
10
+ ):(
11
+ promise:waitfor_Promise<V>
12
+ )=>Promise<number>
13
+ export type waitfor_Promise<V> =
14
+ cancel_Promise<V, (val?:V)=>Promise<V>>
@@ -1,31 +1,61 @@
1
+ import { Cancel } from '../cancel/index.js'
1
2
  import { promise_timeout } from '../promise_timeout/index.js'
2
3
  import { sleep } from '../sleep/index.js'
3
4
  /**
4
5
  * @param {()=>Promise<unknown>}fn
5
- * @param {unknown}timeout
6
- * @param {unknown}[period]
7
- * @returns {Promise<void>}
6
+ * @param {number}timeout
7
+ * @param {number|(()=>Promise<unknown>)}[period]
8
+ * @returns {Promise<unknown>}
8
9
  */
9
- export function waitfor(fn, timeout, period = 0) {
10
- let cancel
10
+ export function waitfor(
11
+ fn,
12
+ timeout,
13
+ period
14
+ ) {
15
+ let rv
16
+ let cancel_arg_a
11
17
  let promise = new Promise((resolve, reject)=>
12
18
  promise_timeout(async ()=>{
13
- let rv
14
- for (; !cancel;) {
15
- rv = await fn()
16
- if (rv) return rv
17
- await sleep(period)
19
+ for (; !cancel_arg_a;) {
20
+ let _rv = await fn()
21
+ rv = cancel_arg_a?.length ? cancel_arg_a[0] : _rv
22
+ if (rv || cancel_arg_a) return rv
23
+ if (typeof period === 'function') {
24
+ await period(promise)
25
+ } else {
26
+ await sleep(period ?? 0)
27
+ }
18
28
  }
19
29
  return rv
20
30
  }, timeout)
21
31
  .then(resolve)
22
32
  .catch(err=>{
23
- cancel = 1
33
+ cancel_arg_a = []
24
34
  reject(err)
25
35
  }))
26
- promise.cancel = ()=>{
27
- cancel = 1
36
+ promise.cancel = (...arg_a)=>{
37
+ cancel_arg_a = arg_a
28
38
  return promise
29
39
  }
30
40
  return promise
31
41
  }
42
+ /**
43
+ * @param {number}ms
44
+ * @param {()=>boolean}should_cancel_
45
+ * @param {Cancel_config_T}[Cancel_config]
46
+ * @returns {(promise:Promise<unknown>&{cancel():unknown})=>Promise<number>}
47
+ * @private
48
+ */
49
+ export function cancel__period_(
50
+ ms,
51
+ should_cancel_,
52
+ Cancel_config
53
+ ) {
54
+ return promise=>{
55
+ if (should_cancel_()) {
56
+ promise.cancel()
57
+ throw new Cancel(Cancel_config)
58
+ }
59
+ return sleep(ms)
60
+ }
61
+ }
@@ -1,5 +1,6 @@
1
1
  import { test } from 'uvu'
2
2
  import { equal } from 'uvu/assert'
3
+ import { sleep } from '../sleep/index.js'
3
4
  import { waitfor } from './index.js'
4
5
  test('waitfor|success', async ()=>{
5
6
  let count = 0
@@ -45,5 +46,65 @@ test('waitfor|cancel', async ()=>{
45
46
  equal(count, 1)
46
47
  equal(await promise, false)
47
48
  equal(count, 1)
49
+ count = 0
50
+ const undefinable_promise = waitfor<boolean|undefined>(()=>{
51
+ count++
52
+ return false
53
+ }, 10)
54
+ equal(count, 1)
55
+ equal(await undefinable_promise.cancel(undefined), undefined)
56
+ equal(count, 1)
57
+ equal(await undefinable_promise, undefined)
58
+ equal(count, 1)
59
+ })
60
+ test('waitfor|period|number', async ()=>{
61
+ let count = 0
62
+ let ret = false
63
+ const promise = waitfor(()=>{
64
+ count++
65
+ return ret
66
+ }, 10, 2)
67
+ try {
68
+ equal(count, 1)
69
+ await sleep(2)
70
+ await sleep(0)
71
+ equal(count, 2)
72
+ await sleep(2)
73
+ equal(count, 3)
74
+ ret = true
75
+ equal(await promise, true)
76
+ equal(count, 4)
77
+ } finally {
78
+ await promise.cancel()
79
+ }
80
+ })
81
+ test('waitfor|period|async function', async ()=>{
82
+ let count = 0
83
+ let ret = false
84
+ const period_arg_aa:Promise<boolean>[][] = []
85
+ const promise = waitfor(()=>{
86
+ count++
87
+ return ret
88
+ }, 10, (...arg_a)=>{
89
+ period_arg_aa.push(arg_a)
90
+ return sleep(2)
91
+ })
92
+ try {
93
+ equal(count, 1)
94
+ await sleep(0)
95
+ equal(period_arg_aa, [[promise]])
96
+ await sleep(2)
97
+ equal(count, 2)
98
+ equal(period_arg_aa, [[promise], [promise]])
99
+ await sleep(2)
100
+ equal(count, 3)
101
+ equal(period_arg_aa, [[promise], [promise], [promise]])
102
+ ret = true
103
+ equal(await promise, true)
104
+ equal(count, 4)
105
+ equal(period_arg_aa, [[promise], [promise], [promise]])
106
+ } finally {
107
+ await promise.cancel()
108
+ }
48
109
  })
49
110
  test.run()
@@ -17,6 +17,7 @@ export * from '../all/bind_map_call/index.js'
17
17
  export * from '../all/call/index.js'
18
18
  export * from '../all/call_fn_a/index.js'
19
19
  export * from '../all/call_or_fn/index.js'
20
+ export * from '../all/cancel/index.js'
20
21
  export * from '../all/compose/index.js'
21
22
  export * from '../all/concat/index.js'
22
23
  export * from '../all/debounce/index.js'
package/function/index.js CHANGED
@@ -17,6 +17,7 @@ export * from '../all/bind_map_call/index.js'
17
17
  export * from '../all/call/index.js'
18
18
  export * from '../all/call_fn_a/index.js'
19
19
  export * from '../all/call_or_fn/index.js'
20
+ export * from '../all/cancel/index.js'
20
21
  export * from '../all/compose/index.js'
21
22
  export * from '../all/concat/index.js'
22
23
  export * from '../all/debounce/index.js'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ctx-core",
3
- "version": "5.8.0",
3
+ "version": "5.10.0",
4
4
  "description": "ctx-core core library",
5
5
  "keywords": [
6
6
  "ctx-core",