ciorent 0.3.2 → 0.3.4

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
@@ -79,31 +79,36 @@ Continue the execution on next tick, allowing other asynchronous tasks to run.
79
79
  ```ts
80
80
  import * as co from 'ciorent';
81
81
 
82
+ const logTime = (label: string) => console.log(label + ':', Math.floor(performance.now()) + 'ms');
83
+
82
84
  // Expensive sync task
83
85
  const task1 = async () => {
84
86
  let x = 0;
85
87
 
86
- // Yield control back to the runtime, allowing it to
87
- // schedule other tasks
88
- await co.nextTick;
89
-
90
88
  // Simulate heavy operation
91
- for (let i = 0; i < (Math.random() + 15) * 1e6; i++)
89
+ for (let i = 0, l = (Math.random() + 15) * 1e6; i < l; i++) {
90
+ // Yield control back occasionally to the runtime, allowing
91
+ // it to schedule other tasks
92
+ if (i % 1e5 === 0)
93
+ await co.nextTick;
94
+
92
95
  x += Math.random() * 32 + i * Math.round(Math.random() * 16);
96
+ }
93
97
 
94
- console.log('Finish task 1:', x);
98
+ console.log('Task 1 result:', x);
95
99
  };
96
100
 
97
101
  // Short async task
98
- const task2 = async () => {
99
- console.log('Start fetching...');
100
- const txt = await fetch('http://example.com');
101
- console.log('Fetch status', txt.status);
102
+ const task2 = async (id: number) => {
103
+ logTime('Task 2.' + id + ' start fetching');
104
+ await fetch('http://localhost:3000').catch(() => {});
105
+ logTime('Task 2.' + id + ' done fetching');
102
106
  };
103
107
 
104
- // Task 2 will not get blocked by task 1
105
108
  task1();
106
- task2();
109
+
110
+ // Task 2 will not get blocked by task 1
111
+ co.spawn(5, task2);
107
112
  ```
108
113
 
109
114
  ### Pubsub
@@ -171,27 +176,29 @@ const task = async (id: number) => {
171
176
  co.spawn(5, task);
172
177
  ```
173
178
 
174
- ### Latch
175
- Latch is a synchronization primitive that allows one process to wait until another completes an operation before continuing execution.
179
+ ### Defer
180
+ Wait for a value to be resolved.
176
181
 
177
182
  ```ts
178
- import * as latch from 'ciorent/latch';
183
+ import * as defer from 'ciorent/defer';
184
+
185
+ const logTime = (label: string) => console.log(label + ':', Math.floor(performance.now()) + 'ms');
179
186
 
180
- const startFetch = latch.init();
187
+ const deferredUrl = defer.init<string>();
181
188
 
182
189
  const task = async () => {
183
- // Blocks until the latch is open
184
- await latch.wait(startFetch);
190
+ // Blocks until the defer is resolved
191
+ const url = await defer.wait(deferredUrl);
185
192
 
186
- console.log('Start fetching...');
187
- const res = await fetch('http://example.com');
188
- console.log('Fetch status:', res.status);
193
+ logTime('Start fetching');
194
+ await fetch(url).catch(() => {});
195
+ logTime('Done fetching');
189
196
  }
190
197
 
191
198
  const prepare = () => {
192
- // This always run first
193
- console.log('Run before fetch:', performance.now().toFixed(2));
194
- latch.open(startFetch);
199
+ // This always run first as task is waiting
200
+ logTime('Run before fetch');
201
+ defer.resolve(deferredUrl, 'http://localhost:3000');
195
202
  }
196
203
 
197
204
  task();
package/channel.d.ts CHANGED
@@ -10,11 +10,11 @@ export interface Channel<T = any> extends Lock<T> {
10
10
  /**
11
11
  * The head of the value queue
12
12
  */
13
- 2: QueueNode<T>;
13
+ 3: QueueNode<T>;
14
14
  /**
15
15
  * The tail of the value queue
16
16
  */
17
- 3: QueueNode<T>;
17
+ 4: QueueNode<T>;
18
18
  }
19
19
  /**
20
20
  * Create a channel
@@ -32,7 +32,7 @@ export declare const send: <T>(c: Channel<T>, t: T) => void;
32
32
  */
33
33
  export declare const recieve: <T>(c: Channel<T>) => Promise<T | undefined>;
34
34
  /**
35
- * Recieve a message from a channel, return null if no message is currently in queue
35
+ * Recieve a message from a channel, return undefined if no message is currently in queue
36
36
  * @param c
37
37
  */
38
38
  export declare const poll: <T>(c: Channel<T>) => T | undefined;
package/channel.js CHANGED
@@ -1 +1 @@
1
- import{acquire as lockAcquire,release as lockRelease,released as lockReleased}from"./lock.js";export let init=()=>{let resolveQu=[null];let qu=[null];return[resolveQu,resolveQu,qu,qu]};export let send=(c,t)=>{if(lockReleased(c))c[2]=c[2][0]=[null,t];else lockRelease(c,t)};export let recieve=(c)=>c[3][0]!==null?Promise.resolve((c[3]=c[3][0])[1]):lockAcquire(c);export let poll=(c)=>c[3][0]!==null?(c[3]=c[3][0])[1]:undefined;export{flush}from"./lock.js";
1
+ import{release as lockRelease,released as lockReleased}from"./lock.js";export let init=()=>{let resolveQu=[null];let qu=[null];let chan=[resolveQu,resolveQu,(res)=>{chan[0]=chan[0][0]=[null,res]},qu,qu];return chan};export let send=(c,t)=>{if(lockReleased(c))c[3]=c[3][0]=[null,t];else lockRelease(c,t)};export let recieve=(c)=>c[4][0]!==null?Promise.resolve((c[4]=c[4][0])[1]):new Promise(c[2]);export let poll=(c)=>c[4][0]!==null?(c[4]=c[4][0])[1]:undefined;export{flush}from"./lock.js";
package/defer.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  * Describe a defer
6
6
  */
7
7
  export type Defer<T = any> = [
8
- pause: Promise<T>,
8
+ wait: Promise<T>,
9
9
  open: (value: T | PromiseLike<T>) => void
10
10
  ];
11
11
  /**
@@ -13,10 +13,10 @@ export type Defer<T = any> = [
13
13
  */
14
14
  export declare const init: <T>() => Defer<T>;
15
15
  /**
16
- * Pause until a deferred is resolved
16
+ * Wait until a deferred is resolved
17
17
  */
18
18
  export declare const wait: <T>(d: Defer<T>) => Promise<T>;
19
19
  /**
20
- * Open a latch
20
+ * Resolve the defer
21
21
  */
22
- export declare const resolve: <T>(d: Defer<T>, p: T | PromiseLike<T>) => void;
22
+ export declare const resolve: (<T extends {}>(d: Defer<T>, p: T | PromiseLike<T>) => void) & ((d: Defer<void>) => void);
package/index.js CHANGED
@@ -1 +1 @@
1
- export let nextTick=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 spawn=(n,task,...args)=>{let arr=new Array(n);for(let i=0;i<n;i++)arr[i]=task(...args,i);return arr};export let debounce=(f,ms)=>{let id;return(...a)=>{clearTimeout(id);id=setTimeout(f,ms,...a)}};export let throttle=(ms,limit)=>{let head=[null];let tail=head;let cur=limit;let scheduled=false;let unlock=()=>{cur=limit;if(tail===head){scheduled=false;return}do{cur--;(tail=tail[0])[1]()}while(cur>0&&tail!==head);setTimeout(unlock,ms)};return()=>{if(cur===0){return new Promise((res)=>{head=head[0]=[null,res]})}if(!scheduled){scheduled=true;setTimeout(unlock,ms)}cur--;return nextTick}};
1
+ export let nextTick=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 spawn=(n,task,...args)=>{let arr=new Array(n);for(let i=0;i<n;i++)arr[i]=task(...args,i);return arr};export let debounce=(f,ms)=>{let id;return(...a)=>{clearTimeout(id);id=setTimeout(f,ms,...a)}};export let throttle=(ms,limit)=>{let head=[null];let tail=head;let promiseCb=(res)=>{head=head[0]=[null,res]};let cur=limit;let scheduled=false;let unlock=()=>{cur=limit;if(tail===head){scheduled=false;return}do{cur--;(tail=tail[0])[1]()}while(cur>0&&tail!==head);setTimeout(unlock,ms)};return()=>{if(cur===0)return new Promise(promiseCb);if(!scheduled){scheduled=true;setTimeout(unlock,ms)}cur--;return nextTick}};
package/lock.d.ts CHANGED
@@ -15,11 +15,6 @@ export interface Lock<T = any> {
15
15
  */
16
16
  1: QueueNode<(value?: T) => void>;
17
17
  }
18
- /**
19
- * Acquire an item
20
- * @param lock
21
- */
22
- export declare const acquire: <T>(lock: Lock<T>) => Promise<T | undefined>;
23
18
  /**
24
19
  * Release an item
25
20
  * @param lock
package/lock.js CHANGED
@@ -1 +1 @@
1
- export let acquire=(lock)=>new Promise((res)=>{lock[0]=lock[0][0]=[null,res]});export let release=(lock,value)=>{(lock[1]=lock[1][0])[1](value)};export let released=(lock)=>lock[1][0]===null;export let flush=(lock)=>{while(lock[1][0]!==null)(lock[1]=lock[1][0])[1]()};
1
+ export let release=(lock,value)=>{(lock[1]=lock[1][0])[1](value)};export let released=(lock)=>lock[1][0]===null;export let flush=(lock)=>{while(lock[1][0]!==null)(lock[1]=lock[1][0])[1]()};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ciorent",
3
- "version": "0.3.2",
3
+ "version": "0.3.4",
4
4
  "description": "A lightweight, low-overhead concurrency library",
5
5
  "homepage": "https://ciorent.netlify.app",
6
6
  "repository": {
@@ -18,16 +18,15 @@
18
18
  "main": "./index.js",
19
19
  "types": "./index.d.ts",
20
20
  "exports": {
21
- "./queue": "./queue.js",
22
- "./topic": "./topic.js",
21
+ "./defer": "./defer.js",
23
22
  "./sliding-queue": "./sliding-queue.js",
23
+ "./topic": "./topic.js",
24
+ ".": "./index.js",
24
25
  "./lock": "./lock.js",
25
- "./latch": "./latch.js",
26
- "./defer": "./defer.js",
27
- "./semaphore": "./semaphore.js",
28
- "./dropping-queue": "./dropping-queue.js",
29
26
  "./channel": "./channel.js",
30
- ".": "./index.js",
31
- "./fiber": "./fiber.js"
27
+ "./dropping-queue": "./dropping-queue.js",
28
+ "./fiber": "./fiber.js",
29
+ "./queue": "./queue.js",
30
+ "./semaphore": "./semaphore.js"
32
31
  }
33
32
  }
package/semaphore.d.ts CHANGED
@@ -5,11 +5,11 @@ import { type Lock } from './lock.js';
5
5
  /**
6
6
  * Describe a semaphore
7
7
  */
8
- export interface Semaphore extends Lock<undefined> {
8
+ export interface Semaphore extends Lock<void> {
9
9
  /**
10
10
  * Current remaining process allowed
11
11
  */
12
- 2: number;
12
+ 3: number;
13
13
  }
14
14
  /**
15
15
  * Create a semaphore that allows n accesses
package/semaphore.js CHANGED
@@ -1 +1 @@
1
- import{nextTick as resolvedPromise}from"./index.js";import{acquire as lockAcquire,release as lockRelease}from"./lock.js";export let init=(n)=>{let root=[null];return[root,root,n]};export let acquire=(s)=>{s[2]--;return s[2]>=0?resolvedPromise:lockAcquire(s)};export let release=(s)=>{if(s[2]<0)lockRelease(s);s[2]++};export let bind=(f,s)=>async(...a)=>{s[2]--;if(s[2]<0)await acquire(s);try{return await f(...a)}finally{if(s[2]<0)release(s);s[2]++}};
1
+ import{nextTick as resolvedPromise}from"./index.js";import{release as lockRelease}from"./lock.js";export let init=(n)=>{let root=[null];let sem=[root,root,(res)=>{sem[0]=sem[0][0]=[null,res]},n];return sem};export let acquire=(s)=>{s[3]--;return s[3]>=0?resolvedPromise:new Promise(s[2])};export let release=(s)=>{if(s[3]<0)lockRelease(s);s[3]++};export let bind=(f,s)=>async(...a)=>{s[3]--;if(s[3]<0)await new Promise(s[2]);try{return await f(...a)}finally{if(s[3]<0)release(s);s[3]++}};
package/latch.d.ts DELETED
@@ -1,20 +0,0 @@
1
- /**
2
- * @module Latches
3
- */
4
- import { type Defer } from './defer.js';
5
- /**
6
- * Describe a latch
7
- */
8
- export type Latch = Defer<void>;
9
- /**
10
- * Create a latch
11
- */
12
- export declare const init: () => Latch;
13
- /**
14
- * Wait until a latch is opened
15
- */
16
- export declare const wait: (d: Latch) => Promise<void>;
17
- /**
18
- * Open a latch
19
- */
20
- export declare const open: (latch: Latch) => void;
package/latch.js DELETED
@@ -1 +0,0 @@
1
- import{init as deferInit,wait as deferWait}from"./defer.js";export let init=deferInit;export let wait=deferWait;export let open=(latch)=>{latch[1]()};