ciorent 0.6.1 → 0.8.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
@@ -111,74 +111,48 @@ const task = async (id: number) => {
111
111
  for (let i = 1; i <= 5; i++) task(i);
112
112
  ```
113
113
 
114
- ### Fibers
115
- Virtual threads with more controlled execution.
114
+ ### Signal
115
+ A module to interrupt executions of functions.
116
116
  ```ts
117
- import { fiber, sleep } from 'ciorent';
117
+ import { signal, sleep } from 'ciorent';
118
118
 
119
119
  const logTime = (label: string) =>
120
120
  console.log(`${label}: ${Math.floor(performance.now())}ms`);
121
121
 
122
- const f1 = fiber.fn(function* () {
122
+ const f1 = async (sig: signal.Signal) => {
123
123
  // Wait for a promise
124
- console.log('Fiber 1 waiting: 1s');
125
- yield sleep(1000);
124
+ console.log('Task 1 waiting: 1s');
125
+ await sleep(1000);
126
126
 
127
- // Wait for a promise and return its result
128
- const res = yield* fiber.unwrap(Promise.resolve(1));
129
- console.log('Fiber 1 recieved:', res);
127
+ // Interruption point
128
+ if (signal.aborted(sig)) return;
130
129
 
131
- return Math.random();
132
- });
130
+ const res = Math.random();
131
+ console.log('Task 1 result:', res);
133
132
 
134
- {
135
- // Start the fiber process on next event loop cycle
136
- const main = fiber.spawn(function* (proc) {
137
- // Start f1, wait for the process to complete and get the result
138
- console.log('Fiber 2: joins fiber 1');
139
- const res = yield* fiber.join(fiber.spawn(f1));
140
- console.log('Fiber 2 recieved:', res);
141
-
142
- // Start f1 and make its lifetime depends on current fiber
143
- console.log('Fiber 2: spawns fiber 1');
144
- const childProc = fiber.spawn(f1);
145
- fiber.mount(childProc, proc);
146
- });
147
-
148
- console.log('Fiber 2 started:', fiber.running(main));
149
-
150
- // Wait for the fiber process to finish
151
- await fiber.complete(main);
152
-
153
- // Check finish status
154
- console.log('Fiber 2 completed:', fiber.completed(main));
155
- }
133
+ return res;
134
+ };
156
135
 
157
136
  {
158
137
  console.log('------------------------');
159
138
 
160
- const main = fiber.spawn(f1);
161
- console.log('Fiber 1 started:', fiber.running(main));
139
+ logTime('Task 1 started');
140
+ const sig = signal.init();
141
+ const promise = f1(sig);
162
142
 
163
- // Interrupt a fiber
164
- fiber.interrupt(main);
143
+ // Interrupt the signal
144
+ signal.abort(sig);
165
145
 
166
- // Execution will be stopped on the last yield
167
- await fiber.complete(main);
168
-
169
- console.log('Fiber 1 interrupted:', fiber.interrupted(main));
146
+ // Execution will be stopped on the last interruption point
147
+ await promise;
170
148
  }
171
149
 
172
150
  {
173
151
  console.log('------------------------');
174
152
 
175
- const main = fiber.spawn(f1);
176
- logTime('Fiber 1 started');
177
-
178
- // Wait for a time period then interrupt the fiber
179
- fiber.timeout(main, 500);
180
- await fiber.complete(main);
153
+ logTime('Task 1 started');
181
154
 
182
- logTime('Fiber 1 interrupted');
155
+ // Interrupt the function after 500ms
156
+ await f1(signal.timeout(500));
183
157
  }
184
158
  ```
package/index.d.ts CHANGED
@@ -29,7 +29,7 @@ export declare const timeout: <T>(promise: Promise<T>, ms: number) => Promise<T
29
29
  * @param ms - Sleep duration in milliseconds
30
30
  */
31
31
  export declare const sleepSync: (ms: number) => void;
32
- export * as fiber from "./fiber.js";
32
+ export * as signal from "./signal.js";
33
33
  export * as latch from "./latch.js";
34
34
  export * as rateLimit from "./rate-limit.js";
35
35
  export * as semaphore from "./semaphore.js";
package/index.js CHANGED
@@ -1 +1 @@
1
- export let nextTick=Promise.resolve();export let sleep=globalThis.Bun?.sleep??globalThis.process?.getBuiltinModule?.(`timers/promises`).setTimeout??(e=>new Promise(r=>{setTimeout(r,e)}));export let timeout=(e,i)=>Promise.race([e,sleep(i)]);let sharedBuf=new Int32Array(new SharedArrayBuffer(4));export let sleepSync=globalThis.Bun?.sleepSync??(e=>{Atomics.wait(sharedBuf,0,0,e)});export*as fiber from"./fiber.js";export*as latch from"./latch.js";export*as rateLimit from"./rate-limit.js";export*as semaphore from"./semaphore.js";
1
+ export let nextTick=Promise.resolve();export let sleep=globalThis.Bun?.sleep??globalThis.process?.getBuiltinModule?.(`timers/promises`).setTimeout??(e=>new Promise(r=>{setTimeout(r,e)}));export let timeout=(e,i)=>Promise.race([e,sleep(i)]);let sharedBuf=new Int32Array(new SharedArrayBuffer(4));export let sleepSync=globalThis.Bun?.sleepSync??(e=>{Atomics.wait(sharedBuf,0,0,e)});export*as signal from"./signal.js";export*as latch from"./latch.js";export*as rateLimit from"./rate-limit.js";export*as semaphore from"./semaphore.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ciorent",
3
- "version": "0.6.1",
3
+ "version": "0.8.0",
4
4
  "description": "A lightweight, low-overhead concurrency library",
5
5
  "repository": {
6
6
  "type": "git",
package/semaphore.js CHANGED
@@ -1 +1 @@
1
- export let init=e=>{let t=[,];let n=[t,t,e=>{n[0]=n[0][0]=[,e]},e];return n};export let acquire=async e=>{e[3]--;if(e[3]<0)return new Promise(e[2])};export let release=e=>{if(e[3]<0)(e[1]=e[1][0])[1]();e[3]++};
1
+ export let init=e=>{let t=[,];let n=[t,t,e=>{n[0]=n[0][0]=[,e]},e];return n};export let acquire=async e=>{if(--e[3]<0)return new Promise(e[2])};export let release=e=>{if(e[3]++<0)(e[1]=e[1][0])[1]()};
package/signal.d.ts ADDED
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Describe a signal
3
+ */
4
+ export type Signal = [interrupted: boolean, ...parents: Signal[]];
5
+ /**
6
+ * Create a signal
7
+ */
8
+ export declare const init: () => Signal;
9
+ /**
10
+ * Create a signal that aborts when any of the input signals abort
11
+ * @param sigs
12
+ */
13
+ export declare const any: (...sigs: Signal[]) => Signal;
14
+ /**
15
+ * Check whether the signal has been aborted
16
+ * @param t
17
+ */
18
+ export declare const aborted: (t: Signal) => boolean;
19
+ /**
20
+ * Abort a signal
21
+ * @param t
22
+ */
23
+ export declare const abort: (t: Signal) => void;
24
+ /**
25
+ * Abort a signal after a duration
26
+ * @param t
27
+ */
28
+ export declare const abortAfter: (ms: number, t: Signal) => Promise<void>;
29
+ /**
30
+ * Create a signal that aborts after ms
31
+ * @param ms
32
+ */
33
+ export declare const timeout: (ms: number) => Signal;
package/signal.js ADDED
@@ -0,0 +1 @@
1
+ import{sleep}from".";export let init=()=>[false];export let any=(...e)=>{let a=[false];for(let o=0;o<e.length;o++)e[o].push(a);return a};export let aborted=e=>e[0];export let abort=e=>{if(!e[0]){e[0]=true;if(e.length>1)for(let a=1;a<e.length;a++)abort(e[a])}};export let abortAfter=async(a,o)=>{await sleep(a);abort(o)};export let timeout=e=>{let a=[false];abortAfter(e,a);return a};
package/fiber.d.ts DELETED
@@ -1,70 +0,0 @@
1
- /**
2
- * Describe a fiber process
3
- */
4
- export type Process<TReturn = unknown> = [proc: Promise<TReturn | undefined>, status: 1 | 2 | 3, children: Process[]];
5
- /**
6
- * Describe a fiber runtime
7
- */
8
- export type Runtime = <
9
- const TReturn,
10
- const Args extends any[]
11
- >(gen: (proc: Process<TReturn>, ...args: Args) => Generator<any, TReturn>, ...args: Args) => Process<TReturn>;
12
- /**
13
- * Check whether the fiber is running
14
- */
15
- export declare const running: (t: Process) => boolean;
16
- /**
17
- * Check whether the fiber has completed
18
- */
19
- export declare const completed: (t: Process) => boolean;
20
- /**
21
- * Check whether the fiber has been interrupted
22
- */
23
- export declare const interrupted: (t: Process) => boolean;
24
- /**
25
- * Create a fiber function
26
- * @param f
27
- */
28
- export declare const fn: <const Fn extends (thread: Process, ...args: any[]) => Generator>(f: Fn) => Fn;
29
- /**
30
- * A basic fiber runtime
31
- * @param g
32
- */
33
- export declare const spawn: Runtime;
34
- /**
35
- * Interrupt the execution of a fiber
36
- * @param t
37
- */
38
- export declare const interrupt: (t: Process) => void;
39
- /**
40
- * Timeout a fiber
41
- * @param t
42
- * @param ms
43
- */
44
- export declare const timeout: (t: Process, ms: number) => Promise<void>;
45
- /**
46
- * Wait for a fiber and retrieve its result
47
- * @param t
48
- */
49
- export declare function join<T extends Process>(t: T): Generator<Awaited<T[0]>, Awaited<T[0]>>;
50
- /**
51
- * Wait for a fiber to finish and retrieve its result
52
- * @param t
53
- */
54
- export declare const complete: <T extends Process>(t: T) => T[0];
55
- /**
56
- * Mount child fiber lifetime to parent lifetime
57
- * @param child
58
- * @param parent
59
- */
60
- export declare const mount: (child: Process, parent: Process) => void;
61
- /**
62
- * Control the fiber with an abort signal
63
- * @param t
64
- * @param signal
65
- */
66
- export declare const control: (t: Process, signal: AbortSignal) => void;
67
- /**
68
- * Unwrap a promise result
69
- */
70
- export declare function unwrap<T extends Promise<any>>(t: T): Generator<Awaited<T>, Awaited<T>>;
package/fiber.js DELETED
@@ -1 +0,0 @@
1
- import{nextTick,sleep}from"./index.js";export let running=e=>e[1]===1;export let completed=e=>e[1]===2;export let interrupted=e=>e[1]===3;let invoke=async(f,p)=>{await nextTick;try{let e=f.next();while(!e.done){let m=await e.value;if(p[1]===3)return;e=f.next(m)}p[1]=2;return e.value}finally{if(p[1]!==2)p[1]=3;p[2].forEach(interrupt)}};export let fn=e=>e;export let spawn=(e,...f)=>{let p=[,1,[]];p[0]=invoke(e(p,...f),p);return p};export let interrupt=e=>{if(e[1]!==2)e[1]=3};export let timeout=async(e,p)=>{await sleep(p);interrupt(e)};export function*join(e){return yield e[0]}export let complete=e=>e[0];export let mount=(e,f)=>{f[2].push(e)};export let control=(e,f)=>{f.addEventListener(`abort`,()=>{interrupt(e)})};export function*unwrap(e){return yield e}