ciorent 0.1.5 → 0.2.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/README.md CHANGED
@@ -7,6 +7,35 @@ A lightweight, low-overhead concurrency library.
7
7
  - Fully type-safe.
8
8
 
9
9
  ## Examples
10
+ ### Semaphore
11
+ Semaphore is a concurrency primitive used to control access to a common resource by multiple processes.
12
+
13
+ ```ts
14
+ import * as semaphore from 'ciorent/semaphore';
15
+ import * as co from 'ciorent';
16
+
17
+ // Only allow 2 task to run concurrently
18
+ const sem = semaphore.init(2);
19
+
20
+ const task = async (id: number) => {
21
+ // Acquire the semaphore or wait for the semaphore to be available
22
+ await semaphore.pause(sem);
23
+
24
+ console.log('Task', id, 'started');
25
+
26
+ // Let the main thread schedules other tasks
27
+ for (let i = 1; i <= 5; i++) await co.pause;
28
+
29
+ console.log('Task', id, 'end');
30
+
31
+ // Release the semaphore
32
+ semaphore.signal(sem);
33
+ }
34
+
35
+ // Try to run 5 tasks concurrently
36
+ co.spawn(5, task);
37
+ ```
38
+
10
39
  ### Fibers
11
40
  Virtual threads with more controlled execution.
12
41
 
@@ -65,6 +94,42 @@ const f1 = fiber.fn(function* () {
65
94
  }
66
95
  ```
67
96
 
97
+ ### Pubsub
98
+ A fast, simple publish-subscribe API.
99
+
100
+ ```ts
101
+ import * as topic from 'ciorent/topic';
102
+ import * as co from 'ciorent';
103
+
104
+ const messages = topic.init<number>();
105
+
106
+ // A task that publish messages
107
+ const publisher = async () => {
108
+ for (let i = 0; i < 3; i++) {
109
+ await co.sleep(100);
110
+ topic.publish(messages, i);
111
+ }
112
+
113
+ // Resolve all waiting promises
114
+ // And clear the value queue
115
+ topic.flush(messages);
116
+ }
117
+
118
+ // Spawn 3 tasks that recieve messages
119
+ co.spawn(3, async (id: number) => {
120
+ const sub = topic.subscribe(messages);
121
+
122
+ while (true) {
123
+ // Block until the value is sent
124
+ const x = await topic.recieve(sub);
125
+ if (x == null) break;
126
+ console.log(`Task ${id} recieved: ${x}`);
127
+ }
128
+ });
129
+
130
+ publisher();
131
+ ```
132
+
68
133
  ### Latch
69
134
  Latch is a synchronization primitive that allows one process to wait until another completes an operation before continuing execution.
70
135
 
@@ -130,71 +195,6 @@ run();
130
195
  console.log('Starting...');
131
196
  ```
132
197
 
133
- ### Pubsub
134
- A fast, simple publish-subscribe API.
135
-
136
- ```ts
137
- import * as topic from 'ciorent/topic';
138
- import * as co from 'ciorent';
139
-
140
- const messages = topic.init<number>();
141
-
142
- // A task that publish messages
143
- const publisher = async () => {
144
- for (let i = 0; i < 3; i++) {
145
- await co.sleep(100);
146
- topic.publish(messages, i);
147
- }
148
-
149
- // Resolve all waiting promises
150
- // And clear the value queue
151
- topic.flush(messages);
152
- }
153
-
154
- // Spawn 3 tasks that recieve messages
155
- co.spawn(3, async (id: number) => {
156
- const sub = topic.subscribe(messages);
157
-
158
- while (true) {
159
- // Block until the value is sent
160
- const x = await topic.recieve(sub);
161
- if (x == null) break;
162
- console.log(`Task ${id} recieved: ${x}`);
163
- }
164
- });
165
-
166
- publisher();
167
- ```
168
-
169
- ### Semaphore
170
- Semaphore is a concurrency primitive used to control access to a common resource by multiple processes.
171
-
172
- ```ts
173
- import * as semaphore from 'ciorent/semaphore';
174
- import * as co from 'ciorent';
175
-
176
- // Only allow 2 task to run concurrently
177
- const sem = semaphore.init(2);
178
-
179
- const task = async (id: number) => {
180
- // Acquire the semaphore or wait for the semaphore to be available
181
- await semaphore.pause(sem);
182
-
183
- console.log('Task', id, 'started');
184
-
185
- // Let the main thread schedules other tasks
186
- for (let i = 1; i <= 5; i++) await co.pause;
187
-
188
- console.log('Task', id, 'end');
189
-
190
- // Release the semaphore
191
- semaphore.signal(sem);
192
- }
193
-
194
- // Try to run 5 tasks concurrently
195
- co.spawn(5, task);
196
- ```
197
-
198
198
  ### Utilities
199
199
  #### Pausing
200
200
  Delay the execution of a function for other asynchronous tasks to run.
@@ -286,10 +286,11 @@ Executes a function at a regular interval.
286
286
  import * as co from 'ciorent';
287
287
 
288
288
  // Allow 2 calls in 500ms
289
- const fn = co.throttle((id: number) => {
290
- console.log(id + ': ' + Math.floor(performance.now()) + 'ms');
291
- }, 500, 2);
289
+ const throttle = co.throttle(500, 2);
292
290
 
293
- co.spawn(8, fn);
291
+ co.spawn(8, async (id) => {
292
+ await throttle();
293
+ console.log(id + ': ' + Math.floor(performance.now()) + 'ms');
294
+ });
294
295
  ```
295
296
 
package/index.d.ts CHANGED
@@ -24,7 +24,7 @@ export declare const sleep: (ms: number) => Promise<void>;
24
24
  */
25
25
  export declare const sleepSync: (ms: number) => void;
26
26
  /**
27
- * Spawn n tasks that runs sequentially
27
+ * Spawn n sequential task
28
28
  * @param n
29
29
  * @param task - The function to run
30
30
  */
@@ -47,4 +47,4 @@ export declare const debounce: <const Args extends any[]>(f: (...args: Args) =>
47
47
  * @param ms - The time in milliseconds
48
48
  * @param limit - The call limit in the time period
49
49
  */
50
- export declare const throttle: <const Args extends any[], const R>(f: (...args: Args) => R, ms: number, limit: number) => ((...args: Args) => Promise<Awaited<R>>);
50
+ export declare const throttle: (ms: number, limit: number) => (() => Promise<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,...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=(f,ms,limit)=>{let head=[null];let tail=head;let cur=limit;let scheduled=false;let unlock=()=>{cur=limit;while(cur>0){if(tail===head){scheduled=false;return}cur--;tail=tail[0];tail[1](f(...tail[2]))}setTimeout(unlock,ms)};return(...a)=>{if(cur===0){let r;let p=new Promise((res)=>{r=res});head=head[0]=[null,r,a];return p}if(!scheduled){scheduled=true;setTimeout(unlock,ms)}cur--;return f(...a)}};
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 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;while(cur>0){if(tail===head){scheduled=false;return}cur--;(tail=tail[0])[1]()}setTimeout(unlock,ms)};return()=>{if(cur===0){let r;let p=new Promise((res)=>{r=res});head=head[0]=[null,r];return p}if(!scheduled){scheduled=true;setTimeout(unlock,ms)}cur--;return pause}};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ciorent",
3
- "version": "0.1.5",
3
+ "version": "0.2.0",
4
4
  "description": "A lightweight, low-overhead concurrency library",
5
5
  "homepage": "https://ciorent.netlify.app",
6
6
  "repository": {
@@ -19,13 +19,13 @@
19
19
  "types": "./index.d.ts",
20
20
  "exports": {
21
21
  "./fixed-queue": "./fixed-queue.js",
22
- "./sliding-queue": "./sliding-queue.js",
23
- "./latch": "./latch.js",
24
- "./channel": "./channel.js",
25
22
  "./fiber": "./fiber.js",
23
+ "./sliding-queue": "./sliding-queue.js",
24
+ "./semaphore": "./semaphore.js",
26
25
  "./dropping-queue": "./dropping-queue.js",
26
+ "./channel": "./channel.js",
27
27
  ".": "./index.js",
28
28
  "./topic": "./topic.js",
29
- "./semaphore": "./semaphore.js"
29
+ "./latch": "./latch.js"
30
30
  }
31
31
  }