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 +31 -24
- package/channel.d.ts +3 -3
- package/channel.js +1 -1
- package/defer.d.ts +4 -4
- package/index.js +1 -1
- package/lock.d.ts +0 -5
- package/lock.js +1 -1
- package/package.json +8 -9
- package/semaphore.d.ts +2 -2
- package/semaphore.js +1 -1
- package/latch.d.ts +0 -20
- package/latch.js +0 -1
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
|
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('
|
98
|
+
console.log('Task 1 result:', x);
|
95
99
|
};
|
96
100
|
|
97
101
|
// Short async task
|
98
|
-
const task2 = async () => {
|
99
|
-
|
100
|
-
|
101
|
-
|
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
|
-
|
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
|
-
###
|
175
|
-
|
179
|
+
### Defer
|
180
|
+
Wait for a value to be resolved.
|
176
181
|
|
177
182
|
```ts
|
178
|
-
import * as
|
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
|
187
|
+
const deferredUrl = defer.init<string>();
|
181
188
|
|
182
189
|
const task = async () => {
|
183
|
-
// Blocks until the
|
184
|
-
await
|
190
|
+
// Blocks until the defer is resolved
|
191
|
+
const url = await defer.wait(deferredUrl);
|
185
192
|
|
186
|
-
|
187
|
-
|
188
|
-
|
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
|
-
|
194
|
-
|
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
|
-
|
13
|
+
3: QueueNode<T>;
|
14
14
|
/**
|
15
15
|
* The tail of the value queue
|
16
16
|
*/
|
17
|
-
|
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
|
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{
|
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
|
-
|
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
|
-
*
|
16
|
+
* Wait until a deferred is resolved
|
17
17
|
*/
|
18
18
|
export declare const wait: <T>(d: Defer<T>) => Promise<T>;
|
19
19
|
/**
|
20
|
-
*
|
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)
|
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
|
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.
|
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
|
-
"./
|
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
|
-
"
|
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<
|
8
|
+
export interface Semaphore extends Lock<void> {
|
9
9
|
/**
|
10
10
|
* Current remaining process allowed
|
11
11
|
*/
|
12
|
-
|
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{
|
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]()};
|