ciorent 0.0.4 → 0.0.6
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 +28 -1
- package/channel.d.ts +1 -2
- package/latch.d.ts +4 -4
- package/package.json +9 -4
- package/queue/index.d.ts +8 -0
- package/semaphore.d.ts +38 -0
- package/semaphore.js +1 -0
package/README.md
CHANGED
@@ -77,7 +77,7 @@ console.log('Starting...');
|
|
77
77
|
```
|
78
78
|
|
79
79
|
## Latch
|
80
|
-
|
80
|
+
A latch is a synchronization tool that allows one or more threads to wait until a specific condition is met.
|
81
81
|
|
82
82
|
```ts
|
83
83
|
import * as latch from 'ciorent/latch';
|
@@ -151,3 +151,30 @@ const main = async () => {
|
|
151
151
|
// Run fetch after 500ms
|
152
152
|
await main();
|
153
153
|
```
|
154
|
+
|
155
|
+
## Semaphore
|
156
|
+
A semaphore is a synchronization tool to control access to shared resources.
|
157
|
+
|
158
|
+
It's essentially a counter that regulates how many threads or processes can access a particular resource or section of code.
|
159
|
+
|
160
|
+
```ts
|
161
|
+
import * as semaphore from 'ciorent/semaphore';
|
162
|
+
import * as cio from 'ciorent';
|
163
|
+
|
164
|
+
// Only allow 2 of these tasks to run concurrently
|
165
|
+
const task = semaphore.task(
|
166
|
+
semaphore.init(2),
|
167
|
+
async (task: number) => {
|
168
|
+
for (let i = 1; i <= 5; i++) {
|
169
|
+
await cio.pause;
|
170
|
+
console.log('Task', task, 'iteration', i);
|
171
|
+
}
|
172
|
+
|
173
|
+
await cio.sleep(500);
|
174
|
+
console.log('Task', task, 'end');
|
175
|
+
}
|
176
|
+
);
|
177
|
+
|
178
|
+
// Try to run 5 tasks concurrently
|
179
|
+
for (let i = 1; i <= 5; i++) task(i);
|
180
|
+
```
|
package/channel.d.ts
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
* @module
|
3
3
|
* Channels
|
4
4
|
*/
|
5
|
-
type QueueNode
|
5
|
+
import type { QueueNode } from './queue';
|
6
6
|
/**
|
7
7
|
* Describe a channel
|
8
8
|
*/
|
@@ -58,4 +58,3 @@ export declare const close: <T>(c: Channel<T>) => void;
|
|
58
58
|
* @param c
|
59
59
|
*/
|
60
60
|
export declare const active: (c: Channel<any>) => boolean;
|
61
|
-
export {};
|
package/latch.d.ts
CHANGED
package/package.json
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
{
|
2
2
|
"name": "ciorent",
|
3
|
-
"version": "0.0.
|
4
|
-
"description": "A concurrency library",
|
3
|
+
"version": "0.0.6",
|
4
|
+
"description": "A low-overhead, lightweight concurrency library",
|
5
|
+
"homepage": "https://ciorent.netlify.app",
|
6
|
+
"repository": {
|
7
|
+
"type": "github",
|
8
|
+
"url": "https://github.com/re-utils/ciorent"
|
9
|
+
},
|
5
10
|
"keywords": [],
|
6
11
|
"license": "MIT",
|
7
12
|
"type": "module",
|
@@ -9,8 +14,8 @@
|
|
9
14
|
"types": "./index.d.ts",
|
10
15
|
"scripts": {
|
11
16
|
"task": "bun scripts/task.ts",
|
12
|
-
"build:test": "bun task build && bun test",
|
13
|
-
"build:publish": "bun
|
17
|
+
"build:test": "bun docs && bun task build && bun test",
|
18
|
+
"build:publish": "bun build:test && bun task report-size && bun task publish",
|
14
19
|
"lint": "eslint ./src",
|
15
20
|
"lint:fix": "eslint ./src --fix",
|
16
21
|
"docs": "typedoc ./src/** --entryPointStrategy Expand --plugin typedoc-material-theme --skipErrorChecking"
|
package/queue/index.d.ts
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
/**
|
2
|
+
* @private
|
2
3
|
* @module
|
3
4
|
* Queue utilities
|
4
5
|
*/
|
@@ -23,6 +24,13 @@ export interface FixedQueue<T extends {}> {
|
|
23
24
|
*/
|
24
25
|
3: number;
|
25
26
|
}
|
27
|
+
/**
|
28
|
+
* Describe a queue node (singly linked list node)
|
29
|
+
*/
|
30
|
+
export type QueueNode<T> = [
|
31
|
+
value: T,
|
32
|
+
next: QueueNode<T> | null
|
33
|
+
];
|
26
34
|
/**
|
27
35
|
* Create a fixed queue.
|
28
36
|
* @param n - The queue size
|
package/semaphore.d.ts
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
/**
|
2
|
+
* @module
|
3
|
+
* Semaphores
|
4
|
+
*/
|
5
|
+
import type { QueueNode } from './queue';
|
6
|
+
/**
|
7
|
+
* Describe a semaphore
|
8
|
+
*/
|
9
|
+
export interface Semaphore {
|
10
|
+
/**
|
11
|
+
* Current remaining process allowed
|
12
|
+
*/
|
13
|
+
0: number;
|
14
|
+
/**
|
15
|
+
* The head of the Promise resolve queue
|
16
|
+
*/
|
17
|
+
1: QueueNode<() => void>;
|
18
|
+
/**
|
19
|
+
* The tail of the Promise resolve queue
|
20
|
+
*/
|
21
|
+
2: QueueNode<() => void>;
|
22
|
+
}
|
23
|
+
/**
|
24
|
+
* Create a semaphore that allows n accesses
|
25
|
+
*/
|
26
|
+
export declare const init: (n: number) => Semaphore;
|
27
|
+
/**
|
28
|
+
* Wait until the semaphore allows access
|
29
|
+
*/
|
30
|
+
export declare const pause: (s: Semaphore) => Promise<void>;
|
31
|
+
/**
|
32
|
+
* Signal to the semaphore to release access
|
33
|
+
*/
|
34
|
+
export declare const signal: (s: Semaphore) => void;
|
35
|
+
/**
|
36
|
+
* Create a task that acquire a semaphore and release the access later
|
37
|
+
*/
|
38
|
+
export declare const task: <F extends (...args: any[]) => Promise<any>>(s: Semaphore, f: F) => F;
|
package/semaphore.js
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
import{pause as resolvedPromise}from".";export let init=(n)=>{let root=[null,null];return[n,root,root]};export let pause=(s)=>{if(s[0]===0){let r;let p=new Promise((res)=>{r=res});s[1]=s[1][1]=[r,null];return p}s[0]--;return resolvedPromise};export let signal=(s)=>{if(s[1]===s[2])s[0]++;else(s[2]=s[2][1])[0]()};export let task=(s,f)=>async(...a)=>{await pause(s);let r=await f(...a);signal(s);return r};
|