ciorent 1.0.8 → 1.0.10

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/index.d.ts CHANGED
@@ -5,62 +5,7 @@
5
5
  * blocking the main thread and let other asynchronous task to run.
6
6
  */
7
7
  export declare const nextTick: Promise<void>;
8
- /**
9
- * Get the state of a promise on next tick:
10
- * - `0`: Input promise rejected
11
- * - `1`: Input promise resolves
12
- * - `2`: Input promise pending
13
- */
14
- export declare const state: (p: Promise<any>) => Promise<0 | 1 | 2>;
15
- /**
16
- * Check whether a value is awaitable.
17
- * @param p
18
- * @returns
19
- */
20
- export declare const isThenable: <T>(p: unknown) => p is PromiseLike<T>;
21
- /**
22
- * Timeout a promise.
23
- * @param p
24
- * @param ms
25
- */
26
- export declare const timeout: <T>(p: Promise<T>, ms: number) => Promise<T | void>;
27
- /**
28
- * Sleep for a duration.
29
- * @param ms - Sleep duration in milliseconds
30
- */
31
- export declare const sleep: (ms: number) => Promise<void>;
32
- /**
33
- * Sleep for a duration synchronously.
34
- *
35
- * This method blocks the current thread.
36
- *
37
- * On the browser it only works in workers.
38
- * @param ms - Sleep duration in milliseconds
39
- */
40
- export declare const sleepSync: (ms: number) => void;
41
- /**
42
- * Async `Array.prototype.map`. Mutates the original array.
43
- *
44
- * @example
45
- * await Promise.all(
46
- * map([task1(), task2(), task3()], (taskResult) => taskResult.debug)
47
- * );
48
- *
49
- * // Map without mutating the original array
50
- * await Promise.all(
51
- * map(taskPromises.slice(), (taskResult) => taskResult.debug)
52
- * );
53
- */
54
- export declare const map: <
55
- T,
56
- R
57
- >(arr: Promise<T>[], mapFn: (value: T) => R | Promise<R>) => Promise<R>[];
58
- /**
59
- * Async `Array.prototype.find`.
60
- */
61
- export declare const find: <T>(arr: Promise<T>[], findFn: (value: T) => boolean | Promise<boolean>) => Promise<T | undefined>;
62
- export * as deferred from "./deferred.js";
63
8
  export * as mutex from "./mutex.js";
64
- export * as limit from "./rate-limit.js";
65
9
  export * as semaphore from "./semaphore.js";
66
10
  export * as signal from "./signal.js";
11
+ export * as promises from "./promises.js";
package/index.js CHANGED
@@ -1 +1 @@
1
- import{loadedReject,loadedResolve,loadResolve,loadResolvers}from"./utils.js";export let nextTick=Promise.resolve();let getFinishedState=async(s,p)=>{try{await p;s[0]=1}catch(e){s[0]=0;return p}};export let state=async p=>{let res=[2];getFinishedState(res,p);await nextTick;return res[0]};export let isThenable=p=>p!==null&&typeof p===`object`&&!Array.isArray(p)&&typeof p.then===`function`;export let timeout=(p,ms)=>{let promise=new Promise(loadResolvers);setTimeout(loadedResolve,ms);p.then(loadedResolve,loadedReject);return promise};export let sleep=globalThis.Bun?.sleep??globalThis.process?.getBuiltinModule?.(`timers/promises`).setTimeout??(ms=>{let promise=new Promise(loadResolve);setTimeout(loadedResolve,ms);return promise});let sharedBuf=new Int32Array(new SharedArrayBuffer(4));export let sleepSync=globalThis.Bun?.sleepSync??(ms=>{Atomics.wait(sharedBuf,0,0,ms)});let resolveFind=async(resolve,findFn,promise,counter)=>{try{if(await promise.then(findFn))return resolve(promise);counter[0]--;return}catch{if(--counter[0]===0)resolve();return promise}};export let map=(arr,mapFn)=>{for(let i=0;i<arr.length;i++)arr[i]=arr[i].then(mapFn);return arr};export let find=(arr,findFn)=>{let promise=new Promise(loadResolve);let counter=[arr.length];for(let i=0;i<arr.length;i++)resolveFind(loadedResolve,findFn,arr[i],counter);return promise};export*as deferred from"./deferred.js";export*as mutex from"./mutex.js";export*as limit from"./rate-limit.js";export*as semaphore from"./semaphore.js";export*as signal from"./signal.js";
1
+ export let nextTick=Promise.resolve();export*as mutex from"./mutex.js";export*as semaphore from"./semaphore.js";export*as signal from"./signal.js";export*as promises from"./promises.js";
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"ciorent","version":"1.0.8","description":"A lightweight, low-overhead concurrency library","homepage":"https://re-utils.pages.dev/concurrency","repository":{"type":"git","url":"git+https://github.com/re-utils/ciorent.git"},"keywords":["low-overhead","lightweight","concurrency","cross-runtime"],"license":"MIT","type":"module","exports":{"./utils":"./utils.js",".":"./index.js","./rate-limit":"./rate-limit.js","./semaphore":"./semaphore.js","./deferred":"./deferred.js","./signal":"./signal.js","./mutex":"./mutex.js"}}
1
+ {"name":"ciorent","version":"1.0.10","description":"A lightweight, low-overhead concurrency library","homepage":"https://re-utils.pages.dev/concurrency","repository":{"type":"git","url":"git+https://github.com/re-utils/ciorent.git"},"keywords":["low-overhead","lightweight","concurrency","cross-runtime"],"license":"MIT","type":"module","exports":{"./promises":"./promises.js","./utils":"./utils.js","./mutex":"./mutex.js",".":"./index.js","./semaphore":"./semaphore.js","./signal":"./signal.js"}}
package/promises.d.ts ADDED
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Async `Array.prototype.map`. **Mutates** the original array.
3
+ *
4
+ * @example
5
+ * await Promise.all(
6
+ * map([task1(), task2(), task3()], (taskResult) => taskResult.debug)
7
+ * );
8
+ *
9
+ * // Map without mutating the original array
10
+ * await Promise.all(
11
+ * map(taskPromises.slice(), (taskResult) => taskResult.debug)
12
+ * );
13
+ */
14
+ export declare const map: <
15
+ T,
16
+ R
17
+ >(arr: Promise<T>[], fn: (value: T) => R | Promise<R>) => Promise<R>[];
18
+ /**
19
+ * Async `Array.prototype.find`.
20
+ */
21
+ export declare const find: <T>(arr: Promise<T>[], fn: (value: T) => boolean | Promise<boolean>) => Promise<T | undefined>;
22
+ /**
23
+ * Async `Array.prototype.some`.
24
+ */
25
+ export declare const some: <T>(arr: Promise<T>[], fn: (value: T) => boolean | Promise<boolean>) => Promise<boolean>;
26
+ /**
27
+ * Async `Array.prototype.every`.
28
+ */
29
+ export declare const every: <T>(arr: Promise<T>[], fn: (value: T) => boolean | Promise<boolean>) => Promise<boolean>;
package/promises.js ADDED
@@ -0,0 +1 @@
1
+ import{loadedResolve,loadResolve}from"./utils.js";export let map=(arr,fn)=>{for(let i=0;i<arr.length;i++)arr[i]=arr[i].then(fn);return arr};let resolveFind=async(fn,promise,state)=>{try{let result=await promise;let findResult=fn(result);if(findResult instanceof Promise?await findResult:findResult)return state[1](result);if(--state[0]===0)state[1]()}catch{if(--state[0]===0)state[1]();return promise}};export let find=(arr,fn)=>{let promise=new Promise(loadResolve);for(let i=0,state=[arr.length,loadedResolve];i<arr.length;i++)resolveFind(fn,arr[i],state);return promise};let resolveSome=async(fn,promise,state)=>{try{let result=fn(await promise);if(typeof result===`boolean`?result:await result)return state[1](true);if(--state[0]===0)state[1](false)}catch{if(--state[0]===0)state[1](false);return promise}};export let some=(arr,fn)=>{let promise=new Promise(loadResolve);for(let i=0,state=[arr.length,loadedResolve];i<arr.length;i++)resolveSome(fn,arr[i],state);return promise};let resolveEvery=async(fn,promise,state)=>{try{let result=fn(await promise);if(typeof result===`boolean`?!result:!await result)return state[1](false);if(--state[0]===0)state[1](true)}catch{if(--state[0]===0)state[1](true);return promise}};export let every=(arr,fn)=>{let promise=new Promise(loadResolve);for(let i=0,state=[arr.length,loadedResolve];i<arr.length;i++)resolveEvery(fn,arr[i],state);return promise};
package/semaphore.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { type Extend } from "./utils.js";
2
2
  type QueueItem = (value: true) => void;
3
- type Queue = [(QueueItem | null)[], len: number, head: number, tail: number];
4
- export type Semaphore = [...Queue, remain: number];
3
+ export type Semaphore = [(QueueItem | null)[], len: number, head: number, tail: number, remain: number];
5
4
  /**
6
5
  * Create a semaphore.
7
6
  *
@@ -31,10 +30,15 @@ export declare const acquire: (sem: Extend<Semaphore>) => Promise<true> | boolea
31
30
  */
32
31
  export declare const release: (sem: Extend<Semaphore>) => void;
33
32
  /**
34
- * @param task Task to limit
35
- * @param sem Target semaphore
33
+ * Run a task with concurrency control.
34
+ *
35
+ * @param sem Semaphore to acquire from
36
+ * @param task Task to run
36
37
  * @throws When `sem` internal queue is full
37
38
  * @returns The limited function
38
39
  */
39
- export declare const limit: <Fn extends (...args: any[]) => Promise<any>>(task: Fn, sem: Extend<Semaphore>) => Fn;
40
+ export declare const run: <
41
+ Args extends any[],
42
+ R
43
+ >(sem: Extend<Semaphore>, task: (...args: Args) => Promise<R>, ...args: Args) => Promise<R>;
40
44
  export {};
package/semaphore.js CHANGED
@@ -1 +1 @@
1
- import{loadedResolve,loadResolve}from"./utils.js";let push=(qu,item)=>{let tail=qu[3];qu[3]=tail+1===qu[1]?0:tail+1;qu[0][tail]=item};let pop=qu=>{let head=qu[2];qu[2]=head+1===qu[1]?0:head+1;let val=qu[0][head];qu[0][head]=null;return val};export let init=(permits,capacity)=>[new Array(capacity).fill(null),capacity,0,0,permits];export let acquire=sem=>{if(--sem[4]<0){if(sem[0].length+sem[4]<0){sem[4]++;return false}let promise=new Promise(loadResolve);push(sem,loadedResolve);return promise}return true};export let release=sem=>{sem[4]++<0&&pop(sem)(true)};export let limit=(task,sem)=>async(...args)=>{if(--sem[4]<0){if(sem[0].length+sem[4]<0){sem[4]++;return Promise.reject(new Error(`Semaphore internal queue is full`))}let promise=new Promise(loadResolve);push(sem,loadedResolve);await promise}try{return await task(...args)}finally{release(sem)}};
1
+ import{loadedResolve,loadResolve}from"./utils.js";export let init=(permits,capacity)=>[new Array(capacity).fill(null),capacity,0,0,permits];export let acquire=sem=>{if(--sem[4]<0){if(sem[0].length+sem[4]<0){sem[4]++;return false}let promise=new Promise(loadResolve);let tail=sem[3];sem[3]=tail+1===sem[1]?0:tail+1;sem[0][tail]=loadedResolve;return promise}return true};export let release=sem=>{if(sem[4]++<0){let head=sem[2];sem[2]=head+1===sem[1]?0:head+1;sem[0][head](true);sem[0][head]=null}};export let run=async(sem,task,...args)=>{if(--sem[4]<0){if(sem[0].length+sem[4]<0){sem[4]++;return Promise.reject(new Error(`Semaphore internal queue is full`))}let promise=new Promise(loadResolve);let tail=sem[3];sem[3]=tail+1===sem[1]?0:tail+1;sem[0][tail]=loadedResolve;await promise}try{return await task(...args)}finally{release(sem)}};
package/signal.d.ts CHANGED
@@ -12,9 +12,9 @@ export declare const init: () => Signal;
12
12
  */
13
13
  export declare const any: (signals: Signal[]) => Signal;
14
14
  /**
15
- * Create a signal that when interrupted will interrupt a group of other signals.
15
+ * Create a child signal that aborts when the parent signal aborts.
16
16
  */
17
- export declare const group: (signals: Signal[]) => Signal;
17
+ export declare const fork: (signal: Signal) => Signal;
18
18
  /**
19
19
  * Check whether the signal has been aborted.
20
20
  * @param t
@@ -26,16 +26,11 @@ export declare const aborted: (t: Signal) => boolean;
26
26
  */
27
27
  export declare const abort: (t: Signal) => void;
28
28
  /**
29
- * Abort a signal after a duration.
30
- * @param t
31
- */
32
- export declare const abortAfter: (ms: number, t: Signal) => void;
33
- /**
34
29
  * Create a signal that aborts after ms.
35
30
  * @param ms
36
31
  */
37
32
  export declare const timeout: (ms: number) => Signal;
38
33
  /**
39
- * Attach a signal to a `DisposableStack` or `AsyncDisposableStack`
34
+ * Create and attach a signal to a `DisposableStack` or `AsyncDisposableStack`.
40
35
  */
41
- export declare const adopt: (t: Signal, stack: DisposableStack | AsyncDisposableStack) => void;
36
+ export declare const bind: (stack: DisposableStack | AsyncDisposableStack) => Signal;
package/signal.js CHANGED
@@ -1 +1 @@
1
- export let init=()=>[false];export let any=signals=>{let sig=[false];for(let i=0;i<signals.length;i++)signals[i].push(sig);return sig};let _=[false];export let group=signals=>_.concat(signals);export let aborted=t=>t[0];export let abort=t=>{if(!t[0]){t[0]=true;if(t.length>1)for(let i=1;i<t.length;i++)abort(t[i])}};export let abortAfter=(ms,t)=>{setTimeout(()=>abort(t),ms)};export let timeout=ms=>{let sig=[false];abortAfter(ms,sig);return sig};export let adopt=(t,stack)=>{stack.adopt(t,abort)};
1
+ export let init=()=>[false];export let any=signals=>{let sig=[false];for(let i=0;i<signals.length;i++)signals[i].push(sig);return sig};export let fork=signal=>{let sig=[false];signal.push(sig);return signal};export let aborted=t=>t[0];export let abort=t=>{if(!t[0]){t[0]=true;if(t.length>1)for(let i=1;i<t.length;i++)abort(t[i])}};export let timeout=ms=>{let sig=[false];setTimeout(abort,ms,sig);return sig};export let bind=stack=>{let sig=[false];stack.adopt(sig,abort);return sig};
package/deferred.d.ts DELETED
@@ -1,22 +0,0 @@
1
- export interface Deferred<T> {
2
- get: Promise<T>;
3
- set: T extends undefined ? (value?: T) => void : (value: T) => void;
4
- }
5
- /**
6
- * Create a deferred value.
7
- *
8
- * @example
9
- * const result = deferred.init();
10
- *
11
- * // Set result value, unblock all
12
- * // coroutines waiting for the results
13
- * result.set(10);
14
- *
15
- * // Get result value
16
- * await result.get;
17
- */
18
- export declare const init: <T>() => Deferred<T>;
19
- /**
20
- * Reset a deferred value.
21
- */
22
- export declare const reset: (value: Deferred<any>) => void;
package/deferred.js DELETED
@@ -1 +0,0 @@
1
- import{loadedResolve,loadResolve}from"./utils.js";export let init=()=>({get:new Promise(loadResolve),set:loadedResolve});export let reset=value=>{value.get=new Promise(loadResolve);value.set=loadedResolve};
package/rate-limit.d.ts DELETED
@@ -1,22 +0,0 @@
1
- /**
2
- * Describe a rate limiter.
3
- */
4
- export type Limiter = (limit: number, ms: number) => () => boolean;
5
- /**
6
- * Fixed window strategy.
7
- * @param limit
8
- * @param ms
9
- */
10
- export declare const fixedWindow: Limiter;
11
- /**
12
- * Sliding window strategy.
13
- * @param limit
14
- * @param ms
15
- */
16
- export declare const slidingWindow: Limiter;
17
- /**
18
- * Token bucket strategy.
19
- * @param limit
20
- * @param ms
21
- */
22
- export declare const tokenBucket: Limiter;
package/rate-limit.js DELETED
@@ -1 +0,0 @@
1
- export let fixedWindow=(limit,ms)=>{let cur=limit;let unlock=()=>{cur=limit};return()=>{if(cur===0)return false;if(cur--===limit)setTimeout(unlock,ms);return true}};export let slidingWindow=(limit,ms)=>{let cur=limit;let unlock=()=>{cur++};return()=>{if(cur===0)return false;cur--;setTimeout(unlock,ms);return true}};export let tokenBucket=(limit,ms)=>{let cur=limit;ms/=limit;let unlock=()=>{if(cur++<limit)setTimeout(unlock,ms)};return()=>{if(cur===0)return false;if(cur--===limit)setTimeout(unlock,ms);return true}};