ciorent 0.0.17 → 0.0.20
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 +67 -28
- package/fiber.d.ts +85 -0
- package/fiber.js +1 -0
- package/fixed-queue.d.ts +1 -4
- package/index.d.ts +7 -0
- package/index.js +1 -1
- package/latch.d.ts +1 -4
- package/package.json +12 -24
- package/semaphore.d.ts +1 -1
- package/concurrent.d.ts +0 -11
package/README.md
CHANGED
@@ -23,42 +23,38 @@ const task = semaphore.task(
|
|
23
23
|
cio.concurrent(6, task);
|
24
24
|
```
|
25
25
|
|
26
|
-
##
|
27
|
-
|
26
|
+
## Fibers
|
27
|
+
Virtual threads with more controlled execution.
|
28
28
|
|
29
29
|
```ts
|
30
|
-
import * as channel from 'ciorent/channel';
|
31
30
|
import * as cio from 'ciorent';
|
31
|
+
import * as fiber from 'ciorent/fiber';
|
32
32
|
|
33
|
-
const
|
33
|
+
const thread1 = fiber.fn(function* () {
|
34
|
+
console.log('Fiber 1 started');
|
34
35
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
channel.send(c, i);
|
39
|
-
console.log('Sent', i);
|
40
|
-
}
|
36
|
+
// Thread1 will be interrupted by thread2
|
37
|
+
// As thread2 will end first
|
38
|
+
yield cio.sleep(1000);
|
41
39
|
|
42
|
-
|
43
|
-
|
44
|
-
channel.flush(c);
|
45
|
-
};
|
40
|
+
console.log('Fiber 1 done');
|
41
|
+
})
|
46
42
|
|
47
|
-
const
|
48
|
-
|
49
|
-
// Wait until a value is sent
|
50
|
-
const x = await channel.recieve(c);
|
51
|
-
if (x == null) break;
|
43
|
+
const thread2 = fiber.fn(function* (thread) {
|
44
|
+
console.log('Fiber 2 started');
|
52
45
|
|
53
|
-
|
54
|
-
|
55
|
-
}
|
46
|
+
yield;
|
47
|
+
console.log('Fiber 2 resumed');
|
56
48
|
|
57
|
-
|
58
|
-
|
49
|
+
// Start thread 1 and make thread1
|
50
|
+
// lifetime depends on thread2
|
51
|
+
fiber.mount(fiber.start(thread1), thread);
|
59
52
|
|
60
|
-
|
61
|
-
|
53
|
+
console.log('Fiber 2 done');
|
54
|
+
});
|
55
|
+
|
56
|
+
// Start running the thread
|
57
|
+
fiber.start(thread2);
|
62
58
|
```
|
63
59
|
|
64
60
|
## Pubsub
|
@@ -140,6 +136,44 @@ await main();
|
|
140
136
|
await main();
|
141
137
|
```
|
142
138
|
|
139
|
+
## Channel
|
140
|
+
Channel is a synchronization primitive via message passing. A message may be sent over a channel, and another process is able to receive messages sent over a channel it has a reference to.
|
141
|
+
|
142
|
+
```ts
|
143
|
+
import * as channel from 'ciorent/channel';
|
144
|
+
import * as cio from 'ciorent';
|
145
|
+
|
146
|
+
const c = channel.init<number>();
|
147
|
+
|
148
|
+
const run = async () => {
|
149
|
+
for (let i = 0; i < 10; i++) {
|
150
|
+
await cio.sleep(10);
|
151
|
+
channel.send(c, i);
|
152
|
+
console.log('Sent', i);
|
153
|
+
}
|
154
|
+
|
155
|
+
// Resolve all waiting promises with `undefined`
|
156
|
+
// This is a way to tell the reciever to not listen to more data
|
157
|
+
channel.flush(c);
|
158
|
+
};
|
159
|
+
|
160
|
+
const log = async () => {
|
161
|
+
while (true) {
|
162
|
+
// Wait until a value is sent
|
163
|
+
const x = await channel.recieve(c);
|
164
|
+
if (x == null) break;
|
165
|
+
|
166
|
+
console.log('Recieved', x);
|
167
|
+
};
|
168
|
+
}
|
169
|
+
|
170
|
+
run();
|
171
|
+
log();
|
172
|
+
|
173
|
+
// This runs first
|
174
|
+
console.log('Starting...');
|
175
|
+
```
|
176
|
+
|
143
177
|
## Utilities
|
144
178
|
### Pausing
|
145
179
|
Delay the execution of a function for other asynchronous tasks to run.
|
@@ -172,12 +206,17 @@ task2();
|
|
172
206
|
```
|
173
207
|
|
174
208
|
### Sleep
|
175
|
-
|
209
|
+
Cross-runtime synchronous and asynchronous sleep functions.
|
176
210
|
```ts
|
177
|
-
import { sleep } from 'ciorent';
|
211
|
+
import { sleep, sleepSync } from 'ciorent';
|
178
212
|
|
179
213
|
await sleep(500);
|
180
214
|
console.log('Hi');
|
215
|
+
|
216
|
+
// This blocks the current thread
|
217
|
+
// On the browser this only works in workers
|
218
|
+
sleepSync(500);
|
219
|
+
console.log('Hi');
|
181
220
|
```
|
182
221
|
|
183
222
|
### Spawning tasks
|
package/fiber.d.ts
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
/**
|
2
|
+
* @module Fibers
|
3
|
+
*/
|
4
|
+
/**
|
5
|
+
* Check whether the fiber is paused
|
6
|
+
*/
|
7
|
+
export declare const paused: (t: Thread) => boolean;
|
8
|
+
/**
|
9
|
+
* Check whether the fiber is running
|
10
|
+
*/
|
11
|
+
export declare const running: (t: Thread) => boolean;
|
12
|
+
/**
|
13
|
+
* Check whether the fiber is done
|
14
|
+
*/
|
15
|
+
export declare const done: (t: Thread) => boolean;
|
16
|
+
/**
|
17
|
+
* Describe a fiber
|
18
|
+
*/
|
19
|
+
export interface Thread<T = unknown, TReturn = unknown> {
|
20
|
+
/**
|
21
|
+
* The waiting promise
|
22
|
+
*/
|
23
|
+
0: Promise<T | TReturn>;
|
24
|
+
/**
|
25
|
+
* Fiber status
|
26
|
+
*/
|
27
|
+
1: 0 | 1 | 2;
|
28
|
+
/**
|
29
|
+
* Callback to continue running the fiber
|
30
|
+
*/
|
31
|
+
2: null | (() => void);
|
32
|
+
/**
|
33
|
+
* Bounded threads
|
34
|
+
*/
|
35
|
+
3: Thread[];
|
36
|
+
}
|
37
|
+
/**
|
38
|
+
* Describe a fiber runtime
|
39
|
+
*/
|
40
|
+
export type Runtime = <const T, const TReturn, const Args extends any[]>(gen: (thread: Thread<T, TReturn>, ...args: Args) => Generator<T, TReturn>, ...args: Args) => Thread<T, TReturn>;
|
41
|
+
/**
|
42
|
+
* Create a fiber function
|
43
|
+
* @param f
|
44
|
+
*/
|
45
|
+
export declare const fn: <const Fn extends (thread: Thread, ...args: any[]) => Generator>(f: Fn) => Fn;
|
46
|
+
/**
|
47
|
+
* A basic fiber runtime
|
48
|
+
* @param g
|
49
|
+
*/
|
50
|
+
export declare const start: Runtime;
|
51
|
+
/**
|
52
|
+
* Pause the execution of a fiber
|
53
|
+
* @param t
|
54
|
+
*/
|
55
|
+
export declare const pause: (t: Thread) => void;
|
56
|
+
/**
|
57
|
+
* Resume the execution of a fiber
|
58
|
+
* @param t
|
59
|
+
*/
|
60
|
+
export declare const resume: (t: Thread) => void;
|
61
|
+
/**
|
62
|
+
* Stop the execution of a fiber
|
63
|
+
* @param t
|
64
|
+
*/
|
65
|
+
export declare const stop: (t: Thread) => void;
|
66
|
+
/**
|
67
|
+
* Wait for a fiber and retrieve its result
|
68
|
+
* @param t
|
69
|
+
*/
|
70
|
+
export declare function join<T extends Thread>(t: T): Generator<Awaited<T[1]>, Awaited<T[1]>>;
|
71
|
+
/**
|
72
|
+
* Wait for a fiber to finish and retrieve its result
|
73
|
+
* @param t
|
74
|
+
*/
|
75
|
+
export declare const finish: <T extends Thread>(t: T) => T[1];
|
76
|
+
/**
|
77
|
+
* Mount child fiber lifetime to parent lifetime
|
78
|
+
* @param child
|
79
|
+
* @param parent
|
80
|
+
*/
|
81
|
+
export declare const mount: (child: Thread, parent: Thread) => void;
|
82
|
+
/**
|
83
|
+
* Unwrap a promise result
|
84
|
+
*/
|
85
|
+
export declare function unwrap<T extends Promise<any>>(t: T): Generator<Awaited<T>, Awaited<T>>;
|
package/fiber.js
ADDED
@@ -0,0 +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 function*unwrap(t){return yield t}
|
package/fixed-queue.d.ts
CHANGED
@@ -26,10 +26,7 @@ export interface FixedQueue<T extends {}> {
|
|
26
26
|
/**
|
27
27
|
* Describe a queue node (singly linked list node)
|
28
28
|
*/
|
29
|
-
export type QueueNode<T> = [
|
30
|
-
value: T,
|
31
|
-
next: QueueNode<T> | null
|
32
|
-
];
|
29
|
+
export type QueueNode<T> = [value: T, next: QueueNode<T> | null];
|
33
30
|
/**
|
34
31
|
* Create a fixed queue.
|
35
32
|
* @param n - The queue size
|
package/index.d.ts
CHANGED
@@ -14,6 +14,13 @@ export declare const pause: Promise<void>;
|
|
14
14
|
* @param ms - Sleep duration in milliseconds
|
15
15
|
*/
|
16
16
|
export declare const sleep: (ms: number) => Promise<void>;
|
17
|
+
/**
|
18
|
+
* Sleep for a duration synchronously.
|
19
|
+
*
|
20
|
+
* On the browser it only works in workers.
|
21
|
+
* @param ms - Sleep duration in milliseconds
|
22
|
+
*/
|
23
|
+
export declare const sleepSync: (ms: number) => void;
|
17
24
|
/**
|
18
25
|
* Spawn n tasks that runs sequentially
|
19
26
|
* @param n
|
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)}));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)=>{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)};
|
package/latch.d.ts
CHANGED
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "ciorent",
|
3
|
-
"version": "0.0.
|
3
|
+
"version": "0.0.20",
|
4
4
|
"description": "A lightweight, low-overhead concurrency library",
|
5
5
|
"homepage": "https://ciorent.netlify.app",
|
6
6
|
"repository": {
|
@@ -17,27 +17,15 @@
|
|
17
17
|
"type": "module",
|
18
18
|
"main": "./index.js",
|
19
19
|
"types": "./index.d.ts",
|
20
|
-
"
|
21
|
-
"
|
22
|
-
"
|
23
|
-
"
|
24
|
-
"
|
25
|
-
"
|
26
|
-
"
|
27
|
-
|
28
|
-
|
29
|
-
"
|
30
|
-
"@types/bun": "latest",
|
31
|
-
"@types/uglify-js": "latest",
|
32
|
-
"eslint": "latest",
|
33
|
-
"eslint-plugin-jsdoc": "latest",
|
34
|
-
"mitata": "latest",
|
35
|
-
"terser": "^5.39.0",
|
36
|
-
"tsx": "latest",
|
37
|
-
"typedoc": "^0.27.9",
|
38
|
-
"typedoc-material-theme": "^1.3.0",
|
39
|
-
"typedoc-plugin-inline-sources": "^1.2.1",
|
40
|
-
"typescript": "latest",
|
41
|
-
"typescript-eslint": "latest"
|
20
|
+
"exports": {
|
21
|
+
"./fixed-queue": "./fixed-queue.js",
|
22
|
+
"./sliding-queue": "./sliding-queue.js",
|
23
|
+
"./fiber": "./fiber.js",
|
24
|
+
"./channel": "./channel.js",
|
25
|
+
"./dropping-queue": "./dropping-queue.js",
|
26
|
+
"./topic": "./topic.js",
|
27
|
+
".": "./index.js",
|
28
|
+
"./semaphore": "./semaphore.js",
|
29
|
+
"./latch": "./latch.js"
|
42
30
|
}
|
43
|
-
}
|
31
|
+
}
|
package/semaphore.d.ts
CHANGED
@@ -34,7 +34,7 @@ export declare const signal: (s: Semaphore) => void;
|
|
34
34
|
/**
|
35
35
|
* Wrap a task to bind to a custom semaphore later
|
36
36
|
*/
|
37
|
-
export declare const wrap: <Args extends any[], Return extends Promise<any>>(f: (...args: Args) => Return) => (s: Semaphore, ...a: Args) => Return;
|
37
|
+
export declare const wrap: <Args extends any[], Return extends Promise<any>>(f: (...args: Args) => Return) => ((s: Semaphore, ...a: Args) => Return);
|
38
38
|
/**
|
39
39
|
* Create a task that acquire a semaphore and release the access when it's finished
|
40
40
|
*/
|
package/concurrent.d.ts
DELETED