ciorent 0.12.2 → 1.0.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.
package/index.d.ts CHANGED
@@ -39,6 +39,6 @@ export declare const sleep: (ms: number) => Promise<void>;
39
39
  */
40
40
  export declare const sleepSync: (ms: number) => void;
41
41
  export * as mutex from "./mutex.js";
42
- export * as rateLimit from "./rate-limit.js";
42
+ export * as limit from "./rate-limit.js";
43
43
  export * as semaphore from "./semaphore.js";
44
44
  export * as signal from "./signal.js";
package/index.js CHANGED
@@ -1 +1 @@
1
- export let nextTick=Promise.resolve();export let state=async p=>{let res=2;p.then(()=>{res=1},()=>{res=0;return p});await nextTick;return res};export let isThenable=p=>p!==null&&typeof p===`object`&&!Array.isArray(p)&&typeof p.then===`function`;export let timeout=(p,ms)=>new Promise((res,rej)=>{p.then(res,e=>{rej(e);return p});setTimeout(res,ms)});export let sleep=globalThis.Bun?.sleep??globalThis.process?.getBuiltinModule?.(`timers/promises`).setTimeout??(ms=>new Promise(res=>{setTimeout(res,ms)}));let sharedBuf=new Int32Array(new SharedArrayBuffer(4));export let sleepSync=globalThis.Bun?.sleepSync??(ms=>{Atomics.wait(sharedBuf,0,0,ms)});export*as mutex from"./mutex.js";export*as rateLimit from"./rate-limit.js";export*as semaphore from"./semaphore.js";export*as signal from"./signal.js";
1
+ import{loadResolve,loadResolvers,promiseResolver}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`;let resolvePromise=async(resolve,reject,p)=>{try{resolve(await p)}catch(e){reject(e)}};export let timeout=(p,ms)=>{let promise=new Promise(loadResolvers);setTimeout(promiseResolver[0],ms);resolvePromise(promiseResolver[0],promiseResolver[1],p);return promise};export let sleep=globalThis.Bun?.sleep??globalThis.process?.getBuiltinModule?.(`timers/promises`).setTimeout??(ms=>{let promise=new Promise(loadResolve);setTimeout(promiseResolver[0],ms);return promise});let sharedBuf=new Int32Array(new SharedArrayBuffer(4));export let sleepSync=globalThis.Bun?.sleepSync??(ms=>{Atomics.wait(sharedBuf,0,0,ms)});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";
package/mutex.d.ts CHANGED
@@ -1,12 +1,17 @@
1
+ import { type Extend } from "./utils.js";
1
2
  /**
2
- * Describe a mutex
3
+ * Describe a mutex.
3
4
  */
4
- export type Mutex = () => Promise<() => void>;
5
+ export type Mutex = [Promise<void>];
5
6
  /**
6
7
  * Create a mutex.
7
8
  */
8
9
  export declare const init: () => Mutex;
9
10
  /**
10
- * Equivalent to `semaphore.permits(fn, 1)` but way faster.
11
+ * Acquire a mutex.
11
12
  */
12
- export declare const permits: <const T extends (...args: any[]) => Promise<any>>(fn: T) => T;
13
+ export declare const acquire: (mu: Extend<Mutex>) => Promise<() => void>;
14
+ /**
15
+ * Automatically acquire and run a task.
16
+ */
17
+ export declare const run: <const T extends (...args: any[]) => Promise<any>>(mu: Extend<Mutex>, fn: T, ...args: Parameters<T>) => ReturnType<T>;
package/mutex.js CHANGED
@@ -1 +1 @@
1
- import{nextTick}from"./index.js";export let init=()=>{let lock=nextTick;let resolve;let callback=res=>{resolve=res};return async()=>{let currentLock=lock;lock=new Promise(callback);let release=resolve;await currentLock;return release}};let chainLock=async(lock,fn,...args)=>{try{await lock}catch{}return fn(...args)};export let permits=fn=>{let lock=nextTick;return(...args)=>lock=chainLock(lock,fn,...args)};
1
+ import{nextTick}from"./index.js";import{chainLock,loadResolve,promiseResolver}from"./utils.js";export let init=()=>[nextTick];export let acquire=async mu=>{let currentLock=mu[0];mu[0]=new Promise(loadResolve);let release=promiseResolver[0];await currentLock;return release};export let run=(mu,fn,...args)=>mu[0]=chainLock(mu[0],fn,...args);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ciorent",
3
- "version": "0.12.2",
3
+ "version": "1.0.0",
4
4
  "description": "A lightweight, low-overhead concurrency library",
5
5
  "homepage": "https://re-utils.pages.dev/concurrency",
6
6
  "repository": {
@@ -11,11 +11,11 @@
11
11
  "license": "MIT",
12
12
  "type": "module",
13
13
  "exports": {
14
- ".": "./index.js",
14
+ "./utils": "./utils.js",
15
15
  "./rate-limit": "./rate-limit.js",
16
+ "./mutex": "./mutex.js",
16
17
  "./signal": "./signal.js",
17
- "./semaphore": "./semaphore.js",
18
- "./types": "./types.js",
19
- "./mutex": "./mutex.js"
18
+ ".": "./index.js",
19
+ "./semaphore": "./semaphore.js"
20
20
  }
21
21
  }
package/rate-limit.d.ts CHANGED
@@ -7,16 +7,16 @@ export type Limiter = (limit: number, ms: number) => () => boolean;
7
7
  * @param limit
8
8
  * @param ms
9
9
  */
10
- export declare const fixed: Limiter;
10
+ export declare const fixedWindow: Limiter;
11
11
  /**
12
12
  * Sliding window strategy
13
13
  * @param limit
14
14
  * @param ms
15
15
  */
16
- export declare const sliding: Limiter;
16
+ export declare const slidingWindow: Limiter;
17
17
  /**
18
18
  * Token bucket strategy
19
19
  * @param limit
20
20
  * @param ms
21
21
  */
22
- export declare const bucket: Limiter;
22
+ export declare const tokenBucket: Limiter;
package/rate-limit.js CHANGED
@@ -1 +1 @@
1
- export let fixed=(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 sliding=(limit,ms)=>{let cur=limit;let unlock=()=>{cur++};return()=>{if(cur===0)return false;cur--;setTimeout(unlock,ms);return true}};export let bucket=(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}};
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}};
package/semaphore.d.ts CHANGED
@@ -1,35 +1,39 @@
1
- import type { Extend } from "./types.js";
2
- /**
3
- * Describe a singly linked list node
4
- */
5
- export type QueueNode = [next: QueueNode | null, value: () => void];
6
- /**
7
- * Describe a semaphore
8
- */
9
- export type Semaphore = [head: QueueNode, tail: QueueNode, remain: number, register: (cb: () => void) => void];
10
- /**
11
- * Create a semaphore that allows n accesses
12
- */
13
- export declare const init: (n: number) => Semaphore;
14
- /**
15
- * Wait until the semaphore allows access
16
- */
17
- export declare const acquire: (s: Extend<Semaphore>) => Promise<void> | void;
18
- /**
19
- * Signal to the semaphore to release access
20
- */
21
- export declare const release: (s: Extend<Semaphore>) => void;
22
- /**
23
- * Control concurrency of a task with a semaphore
24
- */
25
- export declare const control: <T extends (...args: any[]) => Promise<any>>(task: T, s: Extend<Semaphore>) => T;
26
- /**
27
- * Set maximum concurrency for a task (fast path)
28
- */
29
- export declare const permits: <T extends (...args: any[]) => Promise<any>>(task: T, perms: number) => T;
30
- /**
31
- * Queue a task
32
- * @param s
33
- * @param task
34
- */
35
- export declare const queue: <R>(s: Extend<Semaphore>, task: () => Promise<R>) => Promise<R>;
1
+ import { type Extend } from "./utils.js";
2
+ type QueueItem = () => void;
3
+ type Queue = [(QueueItem | null)[], len: number, head: number, tail: number];
4
+ /**
5
+ * Check whether the semaphore queue is full.
6
+ */
7
+ export declare const full: (qu: Extend<Queue>) => boolean;
8
+ export type Semaphore = [...Queue, remain: number];
9
+ /**
10
+ * Create a semaphore.
11
+ *
12
+ * @example
13
+ * // maximum of 10 concurrent tasks and 200 waiting tasks.
14
+ * const sem = semaphore.init(10, 200);
15
+ */
16
+ export declare const init: (permits: number, capacity: number) => Semaphore;
17
+ /**
18
+ * Acquire a permit.
19
+ *
20
+ * @example
21
+ *
22
+ * if (semaphore.full(sem)) {
23
+ * // Internal queue is full
24
+ * }
25
+ *
26
+ * await semaphore.acquire(sem);
27
+ *
28
+ * // Do something and then release the permit.
29
+ * semaphore.release(sem);
30
+ */
31
+ export declare const acquire: (sem: Extend<Semaphore>) => Promise<void> | void;
32
+ /**
33
+ * Release a permit.
34
+ *
35
+ * @example
36
+ * semaphore.release(sem);
37
+ */
38
+ export declare const release: (sem: Extend<Semaphore>) => void;
39
+ export {};
package/semaphore.js CHANGED
@@ -1 +1 @@
1
- export let init=n=>{let r=[null,null];let s=[r,r,n,f=>{s[0]=s[0][0]=[null,f]}];return s};export let acquire=s=>{if(--s[2]<0)return new Promise(s[3])};export let release=s=>{if(s[2]++<0)(s[1]=s[1][0])[1]()};export let control=(task,s)=>async(...args)=>{if(--s[2]<0)await new Promise(s[3]);try{return await task(...args)}finally{release(s)}};export let permits=(task,perms)=>control(task,init(perms));export let queue=async(s,task)=>{try{return await(--s[2]<0?new Promise(s[3]).then(task):task())}finally{release(s)}};
1
+ import{loadResolve,promiseResolver}from"./utils.js";let push=(qu,item)=>{let tail=qu[3];qu[3]=tail+1===qu[1]?0:tail+1;qu[0][tail]=item};export let full=qu=>qu[2]===qu[3]&&qu[0][qu[2]]!==null;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){let promise=new Promise(loadResolve);push(sem,promiseResolver[0]);return promise}};export let release=sem=>{sem[4]++<0&&pop(sem)()};
package/signal.d.ts CHANGED
@@ -10,7 +10,11 @@ export declare const init: () => Signal;
10
10
  * Create a signal that aborts when any of the input signals abort
11
11
  * @param sigs
12
12
  */
13
- export declare const any: (...sigs: Signal[]) => Signal;
13
+ export declare const any: (signals: Signal[]) => Signal;
14
+ /**
15
+ * Create a signal that when interrupted will interrupt a group of other signals
16
+ */
17
+ export declare const group: (signals: Signal[]) => Signal;
14
18
  /**
15
19
  * Check whether the signal has been aborted
16
20
  * @param t
package/signal.js CHANGED
@@ -1 +1 @@
1
- export let init=()=>[false];export let any=(...sigs)=>{let sig=[false];for(let i=0;i<sigs.length;i++)sigs[i].push(sig);return sig};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};
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};
package/utils.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ export type Extend<T extends any[]> = [...T, ...any[]];
2
+ export declare const promiseResolver: [resolve: (res?: any) => void, reject: (reason?: any) => void];
3
+ export declare const loadResolvers: (res: (value?: any) => void, rej: (reason?: any) => void) => void;
4
+ export declare const loadResolve: (res: (value?: any) => void) => void;
5
+ /**
6
+ * Unswallow promise error.
7
+ */
8
+ export declare const unswallow: (p: Promise<any>) => Promise<any>;
9
+ export declare const chainLock: (lock: Promise<void>, fn: any, ...args: any[]) => Promise<any>;
package/utils.js ADDED
@@ -0,0 +1 @@
1
+ export let promiseResolver=[null,null];export let loadResolvers=(res,rej)=>{promiseResolver[0]=res;promiseResolver[1]=rej};export let loadResolve=res=>{promiseResolver[0]=res};export let unswallow=async p=>p;export let chainLock=async(lock,fn,...args)=>{try{await lock}catch{unswallow(lock)}return fn(...args)};
package/types.d.ts DELETED
@@ -1 +0,0 @@
1
- export type Extend<T extends any[]> = [...T, ...any[]];
package/types.js DELETED
@@ -1 +0,0 @@
1
- export{};