ciorent 1.0.5 → 1.0.7

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/deferred.d.ts ADDED
@@ -0,0 +1,22 @@
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 ADDED
@@ -0,0 +1 @@
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/index.d.ts ADDED
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Continue the execution on next event loop cycle.
3
+ *
4
+ * You can `await` this **occasionally** in an expensive synchronous operation to avoid
5
+ * blocking the main thread and let other asynchronous task to run.
6
+ */
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
+ export * as deferred from "./deferred.js";
42
+ export * as mutex from "./mutex.js";
43
+ export * as limit from "./rate-limit.js";
44
+ export * as semaphore from "./semaphore.js";
45
+ export * as signal from "./signal.js";
46
+ export * as iters from "./iterators.js";
package/index.js ADDED
@@ -0,0 +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)});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";export*as iters from"./iterators.js";
package/iterators.d.ts ADDED
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Describe an async iterator created by `race()`
3
+ */
4
+ export interface RaceIterator<T> extends AsyncIterator<T> {
5
+ _: Promise<T>[];
6
+ }
7
+ /**
8
+ * Race promises and return them in order
9
+ */
10
+ export declare const race: <T>(promises: Promise<T>[]) => RaceIterator<T>;
11
+ /**
12
+ * Describe an async iterator created by `map()`
13
+ */
14
+ export interface MapIterator<
15
+ I,
16
+ O
17
+ > extends AsyncIterator<O> {
18
+ _: AsyncIterator<I>;
19
+ f: (value: I) => Promise<Awaited<O>>;
20
+ }
21
+ export declare const map: <
22
+ I,
23
+ O
24
+ >(iterator: AsyncIterator<I>, mapFn: MapIterator<I, O>["f"]) => MapIterator<I, O>;
25
+ /**
26
+ * Describe an async iterator created by `filter()`
27
+ */
28
+ export interface FilterIterator<T> extends AsyncIterator<T> {
29
+ _: AsyncIterator<T>;
30
+ f: (value: T) => Promise<boolean> | boolean;
31
+ }
32
+ export declare const filter: <T>(iterator: AsyncIterator<T>, filterFn: FilterIterator<T>["f"]) => FilterIterator<T>;
33
+ export declare const find: <T>(iterator: AsyncIterator<T>, findFn: (value: T) => Promise<boolean> | boolean) => Promise<T | undefined>;
package/iterators.js ADDED
@@ -0,0 +1 @@
1
+ import{loadedResolve,loadResolve}from"./utils.ts";let iteratorDoneResult={done:true,value:undefined};let promiseIteratorDoneResult=Promise.resolve(iteratorDoneResult);let toIteratorResult=value=>({done:false,value});let resolveNext=async(p,resolvers)=>{try{let res=await p;resolvers.pop()(res)}catch{resolvers.pop()(p)}};function raceNext(){return this._.pop()?.then(toIteratorResult)??promiseIteratorDoneResult}export let race=promises=>{let last=promises.length-1;let waitingPromises=new Array(last+1);for(let i=0,resolvers=new Array(last+1);i<=last;i++){waitingPromises[last-i]=new Promise(loadResolve);resolvers[last-i]=loadedResolve;resolveNext(promises[i],resolvers)}return{next:raceNext,_:waitingPromises}};async function mapNext(){let p=await this._.next();if(p.done)return iteratorDoneResult;let res=this.f(p.value);return toIteratorResult(res instanceof Promise?await res:res)}export let map=(iterator,mapFn)=>({next:mapNext,_:iterator,f:mapFn});async function filterNext(){let p=await this._.next();while(!p.done){let res=this.f(p.value);if(res instanceof Promise?await res:res)return p;p=await this._.next()}return iteratorDoneResult}export let filter=(iterator,filterFn)=>({next:filterNext,_:iterator,f:filterFn});export let find=async(iterator,findFn)=>{let p=await iterator.next();while(!p.done){let res=findFn(p.value);if(res instanceof Promise?await res:res)return p.value;p=await iterator.next()}};
package/mutex.d.ts ADDED
@@ -0,0 +1,17 @@
1
+ import { type Extend } from "./utils.js";
2
+ /**
3
+ * Describe a mutex.
4
+ */
5
+ export type Mutex = [Promise<void>];
6
+ /**
7
+ * Create a mutex.
8
+ */
9
+ export declare const init: () => Mutex;
10
+ /**
11
+ * Acquire a mutex.
12
+ */
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 ADDED
@@ -0,0 +1 @@
1
+ import{nextTick}from"./index.js";import{loadedResolve,loadResolve}from"./utils.js";export let init=()=>[nextTick];export let acquire=async mu=>{let currentLock=mu[0];mu[0]=new Promise(loadResolve);let release=loadedResolve;await currentLock;return release};let chainLock=async(lock,fn,...args)=>{try{await lock}finally{return fn(...args)}};export let run=(mu,fn,...args)=>mu[0]=chainLock(mu[0],fn,...args);
package/package.json CHANGED
@@ -1,38 +1 @@
1
- {
2
- "name": "ciorent",
3
- "version": "1.0.5",
4
- "description": "A lightweight, low-overhead concurrency library",
5
- "homepage": "https://re-utils.pages.dev/concurrency",
6
- "repository": {
7
- "type": "git",
8
- "url": "git+https://github.com/re-utils/ciorent.git"
9
- },
10
- "keywords": [
11
- "low-overhead",
12
- "lightweight",
13
- "concurrency",
14
- "cross-runtime"
15
- ],
16
- "license": "MIT",
17
- "type": "module",
18
- "scripts": {
19
- "task": "bun scripts/task.ts",
20
- "fmt": "biome format .",
21
- "lint": "biome check",
22
- "build:test": "bun task build && bun test",
23
- "build:publish": "bun task build && bun task report-size && bun task publish"
24
- },
25
- "devDependencies": {
26
- "@biomejs/biome": "^2.1.3",
27
- "@types/bun": "^1.2.19",
28
- "mitata": "^1.0.34",
29
- "oxc-minify": "^0.64.0",
30
- "oxc-transform": "^0.65.0",
31
- "typescript": "^5.9.2",
32
- "jiti": "^2.5.1",
33
- "ciorent": "./lib"
34
- },
35
- "trustedDependencies": [
36
- "@biomejs/biome"
37
- ]
38
- }
1
+ {"name":"ciorent","version":"1.0.7","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":{"./iterators":"./iterators.js",".":"./index.js","./utils":"./utils.js","./semaphore":"./semaphore.js","./rate-limit":"./rate-limit.js","./deferred":"./deferred.js","./mutex":"./mutex.js","./signal":"./signal.js"}}
@@ -0,0 +1,22 @@
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 ADDED
@@ -0,0 +1 @@
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 ADDED
@@ -0,0 +1,46 @@
1
+ import { type Extend } from "./utils.js";
2
+ type QueueItem = () => void;
3
+ type Queue = [(QueueItem | null)[], len: number, head: number, tail: number];
4
+ export type Semaphore = [...Queue, remain: number];
5
+ /**
6
+ * Check whether the semaphore queue is full.
7
+ */
8
+ export declare const full: (qu: Extend<Semaphore>) => boolean;
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
+ /**
40
+ * @param task Task to limit
41
+ * @param sem Target semaphore
42
+ * @throws {Error} when `sem` internal queue is full
43
+ * @returns The limited function
44
+ */
45
+ export declare const limit: <Fn extends (...args: any[]) => Promise<any>>(task: Fn, sem: Extend<Semaphore>) => Fn;
46
+ export {};
package/semaphore.js ADDED
@@ -0,0 +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 full=qu=>qu[0].length+qu[4]<=0;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,loadedResolve);return promise}};export let release=sem=>{sem[4]++<0&&pop(sem)()};export let limit=(task,sem)=>async(...args)=>{if(full(sem))throw new Error(`Semaphore internal queue is full`);if(--sem[4]<0){let promise=new Promise(loadResolve);push(sem,loadedResolve);await promise}try{return await task(...args)}finally{release(sem)}};
package/signal.d.ts ADDED
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Describe a signal.
3
+ */
4
+ export type Signal = [interrupted: boolean, ...parents: Signal[]];
5
+ /**
6
+ * Create a signal.
7
+ */
8
+ export declare const init: () => Signal;
9
+ /**
10
+ * Create a signal that aborts when any of the input signals abort.
11
+ * @param sigs
12
+ */
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;
18
+ /**
19
+ * Check whether the signal has been aborted.
20
+ * @param t
21
+ */
22
+ export declare const aborted: (t: Signal) => boolean;
23
+ /**
24
+ * Abort a signal.
25
+ * @param t
26
+ */
27
+ export declare const abort: (t: Signal) => void;
28
+ /**
29
+ * Abort a signal after a duration.
30
+ * @param t
31
+ */
32
+ export declare const abortAfter: (ms: number, t: Signal) => void;
33
+ /**
34
+ * Create a signal that aborts after ms.
35
+ * @param ms
36
+ */
37
+ export declare const timeout: (ms: number) => Signal;
38
+ /**
39
+ * Attach a signal to a `DisposableStack` or `AsyncDisposableStack`
40
+ */
41
+ export declare const adopt: (t: Signal, stack: DisposableStack | AsyncDisposableStack) => void;
package/signal.js ADDED
@@ -0,0 +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)};
package/utils.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ export type Extend<T extends any[]> = [...T, ...any[]];
2
+ export declare let loadedResolve: (res?: any) => void;
3
+ export declare let loadedReject: (reason?: any) => void;
4
+ export declare const loadResolvers: (res: (value?: any) => void, rej: (reason?: any) => void) => void;
5
+ export declare const loadResolve: (res: (value?: any) => void) => void;
package/utils.js ADDED
@@ -0,0 +1 @@
1
+ export let loadedResolve;export let loadedReject;export let loadResolvers=(res,rej)=>{loadedResolve=res;loadedReject=rej};export let loadResolve=res=>{loadedResolve=res};
@@ -1,29 +0,0 @@
1
- import { bench, do_not_optimize, run, summary } from 'mitata';
2
-
3
- // Example benchmark
4
- summary(() => {
5
- bench('Await', function* () {
6
- yield {
7
- [0]() {
8
- return Promise.resolve(1);
9
- },
10
- async bench(data: any) {
11
- do_not_optimize(await data);
12
- },
13
- };
14
- });
15
-
16
- bench('Await non-promise', function* () {
17
- yield {
18
- [0]() {
19
- return 1;
20
- },
21
- async bench(data: any) {
22
- do_not_optimize(await data);
23
- },
24
- };
25
- });
26
- });
27
-
28
- // Start the benchmark
29
- run();
package/bench/bun.lock DELETED
@@ -1,38 +0,0 @@
1
- {
2
- "lockfileVersion": 1,
3
- "configVersion": 0,
4
- "workspaces": {
5
- "": {
6
- "dependencies": {
7
- "@types/mutexify": "^1.2.4",
8
- "async-mutex": "^0.5.0",
9
- "async-sema": "^3.1.1",
10
- "bottleneck": "^2.19.5",
11
- "limit-concur": "^4.0.0",
12
- "mutexify": "^1.4.0",
13
- "p-limit": "^6.2.0",
14
- },
15
- },
16
- },
17
- "packages": {
18
- "@types/mutexify": ["@types/mutexify@1.2.4", "", {}, "sha512-mKNLg7IdppIDCNXiC1hNkNhdEdYnd5ErNnoNgEOERwU3DwD/S1/TBseob0Uq/QXWADBz7OWaWUoHa6IEUtrOEQ=="],
19
-
20
- "async-mutex": ["async-mutex@0.5.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA=="],
21
-
22
- "async-sema": ["async-sema@3.1.1", "", {}, "sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg=="],
23
-
24
- "bottleneck": ["bottleneck@2.19.5", "", {}, "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="],
25
-
26
- "limit-concur": ["limit-concur@4.0.0", "", {}, "sha512-BXUCP52gLz8JA8/cRKkXswOV6FnA2gl8hL8DbgQuo8XA9NKcwU3Oq/Cg1JyAZ+gyNmFEZXI+ZYLes0BrZkl+7g=="],
27
-
28
- "mutexify": ["mutexify@1.4.0", "", { "dependencies": { "queue-tick": "^1.0.0" } }, "sha512-pbYSsOrSB/AKN5h/WzzLRMFgZhClWccf2XIB4RSMC8JbquiB0e0/SH5AIfdQMdyHmYtv4seU7yV/TvAwPLJ1Yg=="],
29
-
30
- "p-limit": ["p-limit@6.2.0", "", { "dependencies": { "yocto-queue": "^1.1.1" } }, "sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA=="],
31
-
32
- "queue-tick": ["queue-tick@1.0.1", "", {}, "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag=="],
33
-
34
- "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
35
-
36
- "yocto-queue": ["yocto-queue@1.2.1", "", {}, "sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg=="],
37
- }
38
- }
@@ -1,11 +0,0 @@
1
- {
2
- "type": "module",
3
- "dependencies": {
4
- "@types/mutexify": "^1.2.4",
5
- "async-mutex": "^0.5.0",
6
- "async-sema": "^3.1.1",
7
- "limit-concur": "^4.0.0",
8
- "mutexify": "^1.4.0",
9
- "p-limit": "^6.2.0"
10
- }
11
- }
@@ -1,42 +0,0 @@
1
- import { bench, do_not_optimize, run, summary } from 'mitata';
2
-
3
- // Example benchmark
4
- summary(() => {
5
- bench('Fill with null', function* () {
6
- const DAT = new Array(6).fill(null);
7
-
8
- yield {
9
- [0]() {
10
- return [...DAT];
11
- },
12
- [1]() {
13
- return Promise.resolve(15);
14
- },
15
- async bench(data: any[], p: any) {
16
- data[0] = p;
17
- do_not_optimize(await Promise.all(data));
18
- },
19
- };
20
- });
21
-
22
- bench('Fill with resolved promises', function* () {
23
- const resolvedPromise = Promise.resolve();
24
- const DAT = new Array(6).fill(resolvedPromise);
25
-
26
- yield {
27
- [0]() {
28
- return [...DAT];
29
- },
30
- [1]() {
31
- return Promise.resolve(15);
32
- },
33
- async bench(data: any[], p: any) {
34
- data[0] = p;
35
- do_not_optimize(await Promise.all(data));
36
- },
37
- };
38
- });
39
- });
40
-
41
- // Start the benchmark
42
- run();
@@ -1,101 +0,0 @@
1
- import { semaphore, mutex } from 'ciorent';
2
- import limitConcur from 'limit-concur';
3
- import { limitFunction } from 'p-limit';
4
- import { Mutex, Semaphore } from 'async-mutex';
5
- import mutexify from 'mutexify/promise.js';
6
- import { Sema } from 'async-sema';
7
-
8
- import { bench, do_not_optimize, run, summary } from 'mitata';
9
-
10
-
11
- const task = async () => {
12
- await 0;
13
- do_not_optimize(Math.random());
14
- };
15
-
16
- const setup = (label: string, limited: () => Promise<any>) => {
17
- bench(label, Function('f', `return async () => { await Promise.all([${
18
- 'f(),'.repeat(200)
19
- }]); }`)(limited)).gc('inner');
20
- };
21
-
22
- const setupSemaphoreCases = (permit: number) => {
23
- setup(`permit ${permit} - limit-concur`, limitConcur(permit, task));
24
- setup(`permit ${permit} - p-limit`, limitFunction(task, { concurrency: permit }));
25
-
26
- {
27
- const sem = semaphore.init(permit, 200 - permit);
28
- setup(`permit ${permit} - ciorent (semaphore)`, async () => {
29
- await semaphore.acquire(sem);
30
- try {
31
- await task();
32
- } finally {
33
- semaphore.release(sem);
34
- }
35
- });
36
- }
37
-
38
- {
39
- const sem = new Semaphore(permit);
40
- setup(`permit ${permit} - async-mutex (semaphore)`, () => sem.runExclusive(task));
41
- }
42
-
43
- {
44
- const sem = new Sema(permit);
45
- setup(`permit ${permit} - async-sema`, async () => {
46
- await sem.acquire();
47
- try {
48
- return await task();
49
- } finally {
50
- sem.release();
51
- }
52
- });
53
- }
54
-
55
- {
56
- const sem = new Sema(permit, {
57
- capacity: 200 - permit
58
- });
59
- setup(`permit ${permit} - async-sema (pre-allocated)`, async () => {
60
- await sem.acquire();
61
- try {
62
- return await task();
63
- } finally {
64
- sem.release();
65
- }
66
- });
67
- }
68
- }
69
-
70
- summary(() => {
71
- setupSemaphoreCases(1);
72
-
73
- {
74
- const mu = mutex.init();
75
- setup('permit 1 - ciorent (mutex)', () => mutex.run(mu, task));
76
- }
77
-
78
- {
79
- const mu = new Mutex();
80
- setup('permit 1 - async-mutex (mutex)', () => mu.runExclusive(task));
81
- }
82
-
83
- {
84
- const acquire = mutexify();
85
- setup('permit 1 - mutexify', async () => {
86
- const release = await acquire();
87
- try {
88
- return await task();
89
- } finally {
90
- release();
91
- }
92
- })
93
- }
94
- });
95
-
96
- for (let permit = 2; permit < 128; permit <<= 1)
97
- summary(() => {
98
- setupSemaphoreCases(permit);
99
- });
100
-
101
- run();
@@ -1,69 +0,0 @@
1
- import { bench, do_not_optimize, type k_state, run, summary } from 'mitata';
2
-
3
- // Example benchmark
4
- summary(() => {
5
- bench('Clone 2 arrays - Concat', function* (state: k_state) {
6
- const DAT = new Array(state.get('len')).fill(0).map(Math.random);
7
- const DAT2 = new Array(state.get('len')).map(Math.random);
8
-
9
- yield {
10
- [0]() {
11
- return DAT;
12
- },
13
- [1]() {
14
- return DAT2;
15
- },
16
- bench(data: any[], data1: any[]) {
17
- do_not_optimize(data.concat(data1));
18
- },
19
- };
20
- }).range('len', 2 ** 3, 2 ** 12);
21
-
22
- bench('Clone 2 arrays - Spread', function* (state: k_state) {
23
- const DAT = new Array(state.get('len')).fill(0).map(Math.random);
24
- const DAT2 = new Array(state.get('len')).map(Math.random);
25
-
26
- yield {
27
- [0]() {
28
- return DAT;
29
- },
30
- [1]() {
31
- return DAT2;
32
- },
33
- bench(data: any[], data1: any[]) {
34
- do_not_optimize([...data, ...data1]);
35
- },
36
- };
37
- }).range('len', 2 ** 3, 2 ** 12);
38
- });
39
-
40
- summary(() => {
41
- bench('Clone 1 array - Concat', function* (state: k_state) {
42
- const DAT = new Array(state.get('len')).fill(0).map(Math.random);
43
-
44
- yield {
45
- [0]() {
46
- return DAT;
47
- },
48
- bench(data: any[]) {
49
- do_not_optimize(data.concat([]));
50
- },
51
- };
52
- }).range('len', 2 ** 3, 2 ** 12);
53
-
54
- bench('Clone 1 array - Spread', function* (state: k_state) {
55
- const DAT = new Array(state.get('len')).fill(0).map(Math.random);
56
-
57
- yield {
58
- [0]() {
59
- return DAT;
60
- },
61
- bench(data: any[]) {
62
- do_not_optimize([...data]);
63
- },
64
- };
65
- }).range('len', 2 ** 3, 2 ** 12);
66
- });
67
-
68
- // Start the benchmark
69
- run();
@@ -1,3 +0,0 @@
1
- {
2
- "extends": "../scripts/tsconfig.json"
3
- }
package/biome.json DELETED
@@ -1,62 +0,0 @@
1
- {
2
- "$schema": "https://biomejs.dev/schemas/2.1.3/schema.json",
3
- "vcs": {
4
- "enabled": false
5
- },
6
- "files": {
7
- "experimentalScannerIgnores": ["node_modules"],
8
- "includes": [
9
- "**/*.{js,ts,jsx,tsx,json,astro,svelte,vue}",
10
- "!{lib,bench}/**/*"
11
- ]
12
- },
13
- "javascript": {
14
- "formatter": {
15
- "quoteStyle": "single",
16
- "arrowParentheses": "always",
17
- "semicolons": "always"
18
- }
19
- },
20
- "formatter": {
21
- "enabled": true,
22
- "indentStyle": "space",
23
- "indentWidth": 2,
24
- "bracketSpacing": true
25
- },
26
- "linter": {
27
- "enabled": true,
28
- "rules": {
29
- "style": {
30
- "noEnum": "error",
31
- "noCommonJs": "error",
32
- "useConsistentArrayType": "error",
33
- "noNamespace": "error",
34
- "noImplicitBoolean": "warn",
35
- "noUselessElse": "error",
36
- "useCollapsedElseIf": "error",
37
- "useConst": "error",
38
- "useNodejsImportProtocol": "error",
39
- "useImportType": "error",
40
- "useExponentiationOperator": "info"
41
- },
42
- "complexity": {
43
- "noForEach": "info",
44
- "noUselessCatch": "info",
45
- "useArrowFunction": "warn"
46
- },
47
- "nursery": {
48
- "noShadow": "warn",
49
- "noGlobalDirnameFilename": "error",
50
- "useIndexOf": "warn",
51
- "noImportCycles": "error"
52
- },
53
- "correctness": {
54
- "useYield": "warn",
55
- "noUnusedImports": "warn",
56
- "useImportExtensions": "error",
57
- "useIsNan": "warn"
58
- },
59
- "recommended": false
60
- }
61
- }
62
- }