ciorent 0.0.21 → 0.0.23

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/README.md CHANGED
@@ -6,9 +6,7 @@ Semaphore is a concurrency primitive used to control access to a common resource
6
6
  import * as semaphore from 'ciorent/semaphore';
7
7
  import * as cio from 'ciorent';
8
8
 
9
- // Only allow 2 of these tasks to run concurrently
10
- const task = semaphore.task(
11
- semaphore.init(2),
9
+ const task = semaphore.wrap(
12
10
  async (task: number) => {
13
11
  for (let i = 1; i <= 5; i++) {
14
12
  console.log('Task', task, 'iteration', i);
@@ -19,8 +17,11 @@ const task = semaphore.task(
19
17
  }
20
18
  );
21
19
 
20
+ // Only allow 2 task to run concurrently
21
+ const sem = semaphore.init(2);
22
+
22
23
  // Try to run 6 tasks concurrently
23
- cio.concurrent(6, task);
24
+ cio.concurrent(6, (sem, id) => task(sem, id), sem);
24
25
  ```
25
26
 
26
27
  ## Fibers
@@ -48,13 +49,13 @@ const thread2 = fiber.fn(function* (thread) {
48
49
 
49
50
  // Start thread 1 and make thread1
50
51
  // lifetime depends on thread2
51
- fiber.mount(fiber.start(thread1), thread);
52
+ fiber.mount(fiber.spawn(thread1), thread);
52
53
 
53
54
  console.log('Fiber 2 done');
54
55
  });
55
56
 
56
57
  // Start running the thread
57
- fiber.start(thread2);
58
+ fiber.spawn(thread2);
58
59
  ```
59
60
 
60
61
  ## Latch
@@ -183,20 +184,23 @@ import * as cio from 'ciorent';
183
184
  // Expensive sync task
184
185
  const task1 = async () => {
185
186
  let x = 0;
186
- for (let i = 0; i < (Math.random() + 15) * 1e7; i++) {
187
- // Frequent pausing
188
- if (i % 2e6 === 0)
189
- await cio.pause;
190
187
 
188
+ // Pause to let task2 to run
189
+ await cio.pause;
190
+
191
+ for (let i = 0; i < (Math.random() + 15) * 1e6; i++)
191
192
  x += Math.random() * 32 + i * Math.round(Math.random() * 16);
192
- }
193
+
193
194
  console.log('Finish task 1:', x);
194
195
  };
195
196
 
196
197
  // Short async task
197
198
  const task2 = async () => {
198
199
  console.log('Fetch start', performance.now().toFixed(2) + 'ms');
200
+
201
+ // This will pause task2 to let task1 to continue running
199
202
  const txt = await fetch('http://example.com');
203
+
200
204
  console.log('Fetch status', txt.status);
201
205
  };
202
206
 
@@ -238,3 +242,17 @@ console.log('Running 5 tasks concurrently:');
238
242
  cio.concurrent(5, task);
239
243
  ```
240
244
 
245
+ ### Debounce
246
+ Dropping tasks for a period of time
247
+ ```ts
248
+ import * as cio from 'ciorent';
249
+
250
+ const fn = cio.debounce((id: number) => {
251
+ console.log('ID:', id);
252
+ }, 500);
253
+
254
+ fn(1); // fn(1) gets skipped
255
+ cio.sleepSync(100);
256
+ fn(2); // fn(2) gets executed
257
+ ```
258
+
package/fiber.d.ts CHANGED
@@ -47,7 +47,7 @@ export declare const fn: <const Fn extends (thread: Thread, ...args: any[]) => G
47
47
  * A basic fiber runtime
48
48
  * @param g
49
49
  */
50
- export declare const start: Runtime;
50
+ export declare const spawn: Runtime;
51
51
  /**
52
52
  * Pause the execution of a fiber
53
53
  * @param t
package/fiber.js CHANGED
@@ -1 +1 @@
1
- export let paused=(t)=>t[1]===0;export let running=(t)=>t[1]===1;export let done=(t)=>t[1]===2;let invoke=async(g,thread)=>{let t=g.next();while(!t.done){let v=await t.value;if(thread[1]===0){let r;let p=new Promise((res)=>{r=res});thread[2]=r;await p}if(thread[1]===2){thread[3].forEach(stop);return v}t=g.next(v)}thread[1]=2;thread[3].forEach(stop);return t.value};export let fn=(f)=>f;export let start=(f,...args)=>{let thread=[null,1,null,[]];thread[0]=invoke(f(thread,...args),thread);return thread};export let pause=(t)=>{if(t[1]===1)t[1]=0};export let resume=(t)=>{if(t[1]===0){t[1]=1;t[2]?.()}};export let stop=(t)=>{if(t[1]===0){t[1]=2;t[2]()}else t[1]=2};export function*join(t){return yield t[1]}export let finish=(t)=>t[1];export let mount=(child,parent)=>{parent[3].push(child)};export let control=(t,signal)=>{signal.addEventListener("abort",()=>{stop(t)})};export function*unwrap(t){return yield t}
1
+ export let paused=(t)=>t[1]===0;export let running=(t)=>t[1]===1;export let done=(t)=>t[1]===2;let invoke=async(g,thread)=>{let t=g.next();while(!t.done){let v=await t.value;if(thread[1]===0){let r;let p=new Promise((res)=>{r=res});thread[2]=r;await p}if(thread[1]===2){thread[3].forEach(stop);return v}t=g.next(v)}thread[1]=2;thread[3].forEach(stop);return t.value};export let fn=(f)=>f;export let spawn=(f,...args)=>{let thread=[null,1,null,[]];thread[0]=invoke(f(thread,...args),thread);return thread};export let pause=(t)=>{if(t[1]===1)t[1]=0};export let resume=(t)=>{if(t[1]===0){t[1]=1;t[2]?.()}};export let stop=(t)=>{if(t[1]===0){t[1]=2;t[2]?.()}else t[1]=2};export function*join(t){return yield t[1]}export let finish=(t)=>t[1];export let mount=(child,parent)=>{parent[3].push(child)};export let control=(t,signal)=>{signal.addEventListener("abort",()=>{stop(t)})};export function*unwrap(t){return yield t}
package/index.d.ts CHANGED
@@ -26,10 +26,16 @@ export declare const sleepSync: (ms: number) => void;
26
26
  * @param n
27
27
  * @param task - The function to run
28
28
  */
29
- export declare const sequential: (n: number, task: (id: number) => Promise<any>) => Promise<void>;
29
+ export declare const sequential: <const T extends any[]>(n: number, task: (...args: [...T, id: number]) => Promise<any>, ...args: T) => Promise<void>;
30
30
  /**
31
31
  * Spawn n tasks that runs concurrently
32
32
  * @param n
33
33
  * @param task - The function to run
34
34
  */
35
- export declare const concurrent: (n: number, task: (id: number) => Promise<any>) => Promise<any>;
35
+ export declare const concurrent: <const T extends any[], const R>(n: number, task: (...args: [...T, id: number]) => Promise<R>, ...args: T) => Promise<R[]>;
36
+ /**
37
+ * Drop sync function calls for a specific period
38
+ * @param f - The target function to debounce
39
+ * @param ms - The time period in milliseconds
40
+ */
41
+ export declare const debounce: <const Args extends any[]>(f: (...args: Args) => any, ms: number) => ((...args: Args) => void);
package/index.js CHANGED
@@ -1 +1 @@
1
- export let pause=Promise.resolve();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 let sequential=async(n,task)=>{for(let i=0;i<n;i++)await task(i)};export let concurrent=(n,task)=>{let arr=new Array(n);for(let i=0;i<n;i++)arr[i]=task(i);return Promise.all(arr)};
1
+ export let pause=Promise.resolve();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 let sequential=async(n,task,...args)=>{for(let i=0;i<n;i++)await task(...args,i)};export let concurrent=(n,task,...args)=>{let arr=new Array(n);for(let i=0;i<n;i++)arr[i]=task(...args,i);return Promise.all(arr)};export let debounce=(f,ms)=>{let args;let unlocked=true;let unlock=()=>{unlocked=true};let call=()=>Promise.try(f,...args).finally(unlock);return(...a)=>{args=a;if(unlocked){unlocked=false;setTimeout(call,ms)}}};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ciorent",
3
- "version": "0.0.21",
3
+ "version": "0.0.23",
4
4
  "description": "A lightweight, low-overhead concurrency library",
5
5
  "homepage": "https://ciorent.netlify.app",
6
6
  "repository": {
@@ -18,14 +18,14 @@
18
18
  "main": "./index.js",
19
19
  "types": "./index.d.ts",
20
20
  "exports": {
21
+ "./fixed-queue": "./fixed-queue.js",
21
22
  "./sliding-queue": "./sliding-queue.js",
23
+ "./fiber": "./fiber.js",
22
24
  "./channel": "./channel.js",
23
- "./semaphore": "./semaphore.js",
25
+ "./dropping-queue": "./dropping-queue.js",
24
26
  "./topic": "./topic.js",
27
+ "./semaphore": "./semaphore.js",
25
28
  ".": "./index.js",
26
- "./dropping-queue": "./dropping-queue.js",
27
- "./fiber": "./fiber.js",
28
- "./fixed-queue": "./fixed-queue.js",
29
29
  "./latch": "./latch.js"
30
30
  }
31
31
  }
package/semaphore.d.ts CHANGED
@@ -35,7 +35,3 @@ export declare const signal: (s: Semaphore) => void;
35
35
  * Wrap a task to bind to a custom semaphore later
36
36
  */
37
37
  export declare const wrap: <Args extends any[], Return extends Promise<any>>(f: (...args: Args) => Return) => ((s: Semaphore, ...a: Args) => Return);
38
- /**
39
- * Create a task that acquire a semaphore and release the access when it's finished
40
- */
41
- export declare const task: <F extends (...args: any[]) => Promise<any>>(s: Semaphore, f: F) => F;
package/semaphore.js CHANGED
@@ -1 +1 @@
1
- import{pause as resolvedPromise}from"./index.js";export let init=(n)=>{let root=[null,null];return[n,root,root]};export let pause=(s)=>{s[0]--;if(s[0]<0){let r;let p=new Promise((res)=>{r=res});s[1]=s[1][1]=[r,null];return p}return resolvedPromise};export let signal=(s)=>{if(s[0]<0)(s[2]=s[2][1])[0]();s[0]++};export let wrap=(f)=>async(s,...a)=>{s[0]--;if(s[0]<0){let r;let p=new Promise((res)=>{r=res});s[1]=s[1][1]=[r,null];await p}try{return await f(...a)}finally{signal(s)}};export let task=(s,f)=>{f=wrap(f);return(...a)=>f(s,...a)};
1
+ import{pause as resolvedPromise}from"./index.js";export let init=(n)=>{let root=[null,null];return[n,root,root]};export let pause=(s)=>{s[0]--;if(s[0]<0){let r;let p=new Promise((res)=>{r=res});s[1]=s[1][1]=[r,null];return p}return resolvedPromise};export let signal=(s)=>{if(s[0]<0)(s[2]=s[2][1])[0]();s[0]++};export let wrap=(f)=>async(s,...a)=>{s[0]--;if(s[0]<0){let r;let p=new Promise((res)=>{r=res});s[1]=s[1][1]=[r,null];await p}try{return await f(...a)}finally{signal(s)}};
@@ -11,6 +11,6 @@ export { init } from './fixed-queue.js';
11
11
  export declare const push: <T extends {}>(q: FixedQueue<T>, item: T) => void;
12
12
  /**
13
13
  * Pop an item from the queue
14
- * @param q - The queue to pull from
14
+ * @param q - The queue to pop from
15
15
  */
16
16
  export declare const pop: <T extends {}>(q: FixedQueue<T>) => T | undefined;