@thi.ng/csp 3.2.0 → 3.2.2
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/CHANGELOG.md +10 -1
- package/README.md +10 -9
- package/channel.js +8 -16
- package/mult.js +1 -2
- package/ops.d.ts +20 -6
- package/ops.js +10 -28
- package/package.json +11 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
- **Last updated**: 2024-
|
|
3
|
+
- **Last updated**: 2024-06-21T19:34:38Z
|
|
4
4
|
- **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
|
|
5
5
|
|
|
6
6
|
All notable changes to this project will be documented in this file.
|
|
@@ -9,6 +9,15 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
|
|
|
9
9
|
**Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
|
|
10
10
|
and/or version bumps of transitive dependencies.
|
|
11
11
|
|
|
12
|
+
### [3.2.2](https://github.com/thi-ng/umbrella/tree/@thi.ng/csp@3.2.2) (2024-06-21)
|
|
13
|
+
|
|
14
|
+
#### ♻️ Refactoring
|
|
15
|
+
|
|
16
|
+
- rename various rest args to be more semantically meaningful ([8088a56](https://github.com/thi-ng/umbrella/commit/8088a56))
|
|
17
|
+
- dedupe pipe() logic, deprecate into() ([5979527](https://github.com/thi-ng/umbrella/commit/5979527))
|
|
18
|
+
- update fromAsyncIterable()
|
|
19
|
+
- add docstrings
|
|
20
|
+
|
|
12
21
|
## [3.2.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/csp@3.2.0) (2024-04-28)
|
|
13
22
|
|
|
14
23
|
#### 🚀 Features
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
[](https://mastodon.thi.ng/@toxi)
|
|
8
8
|
|
|
9
9
|
> [!NOTE]
|
|
10
|
-
> This is one of
|
|
10
|
+
> This is one of 193 standalone projects, maintained as part
|
|
11
11
|
> of the [@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo
|
|
12
12
|
> and anti-framework.
|
|
13
13
|
>
|
|
@@ -35,13 +35,14 @@
|
|
|
35
35
|
|
|
36
36
|
Primitives & operators for Communicating Sequential Processes based on async/await and async iterables.
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
38
|
+
> [!IMPORTANT]
|
|
39
|
+
> This package was temporarily deprecated (throughout most of 2023), but
|
|
40
|
+
> meanwhile has been **reanimated in the form of a complete rewrite**, using a
|
|
41
|
+
> new, more simple and more modern approach afforded by contemporary ES language
|
|
42
|
+
> features (and widespread support for them).
|
|
43
|
+
>
|
|
44
|
+
> **This new/current implementation is in most cases NOT compatible with earlier
|
|
45
|
+
> versions**.
|
|
45
46
|
|
|
46
47
|
### What is CSP?
|
|
47
48
|
|
|
@@ -157,7 +158,7 @@ For Node.js REPL:
|
|
|
157
158
|
const csp = await import("@thi.ng/csp");
|
|
158
159
|
```
|
|
159
160
|
|
|
160
|
-
Package sizes (brotli'd, pre-treeshake): ESM: 1.
|
|
161
|
+
Package sizes (brotli'd, pre-treeshake): ESM: 1.80 KB
|
|
161
162
|
|
|
162
163
|
## Dependencies
|
|
163
164
|
|
package/channel.js
CHANGED
|
@@ -23,10 +23,8 @@ class Channel {
|
|
|
23
23
|
let opts;
|
|
24
24
|
switch (args.length) {
|
|
25
25
|
case 1:
|
|
26
|
-
if (isPlainObject(args[0]))
|
|
27
|
-
|
|
28
|
-
else
|
|
29
|
-
buf = args[0];
|
|
26
|
+
if (isPlainObject(args[0])) opts = args[0];
|
|
27
|
+
else buf = args[0];
|
|
30
28
|
break;
|
|
31
29
|
case 2:
|
|
32
30
|
[buf, opts] = args;
|
|
@@ -68,8 +66,7 @@ class Channel {
|
|
|
68
66
|
async *[Symbol.asyncIterator]() {
|
|
69
67
|
while (this.state < STATE_CLOSED) {
|
|
70
68
|
const x = await this.read();
|
|
71
|
-
if (x !== void 0)
|
|
72
|
-
yield x;
|
|
69
|
+
if (x !== void 0) yield x;
|
|
73
70
|
}
|
|
74
71
|
}
|
|
75
72
|
/**
|
|
@@ -100,8 +97,7 @@ class Channel {
|
|
|
100
97
|
resolve(void 0);
|
|
101
98
|
}
|
|
102
99
|
}
|
|
103
|
-
if (this.writes.readable())
|
|
104
|
-
this.deliver();
|
|
100
|
+
if (this.writes.readable()) this.deliver();
|
|
105
101
|
});
|
|
106
102
|
}
|
|
107
103
|
/**
|
|
@@ -208,19 +204,15 @@ class Channel {
|
|
|
208
204
|
* still "closing", not yet fully "closed".
|
|
209
205
|
*/
|
|
210
206
|
close() {
|
|
211
|
-
if (this.state >= STATE_CLOSING)
|
|
212
|
-
return;
|
|
207
|
+
if (this.state >= STATE_CLOSING) return;
|
|
213
208
|
const { reads, writes, races } = this;
|
|
214
209
|
this.state = reads.length || writes.readable() ? STATE_CLOSING : STATE_CLOSED;
|
|
215
|
-
while (reads.length && writes.readable())
|
|
216
|
-
this.deliver();
|
|
210
|
+
while (reads.length && writes.readable()) this.deliver();
|
|
217
211
|
if (!writes.readable()) {
|
|
218
|
-
while (reads.length)
|
|
219
|
-
reads.shift()(void 0);
|
|
212
|
+
while (reads.length) reads.shift()(void 0);
|
|
220
213
|
}
|
|
221
214
|
this.state = writes.readable() ? STATE_CLOSING : STATE_CLOSED;
|
|
222
|
-
while (races.length)
|
|
223
|
-
races.shift()(this);
|
|
215
|
+
while (races.length) races.shift()(this);
|
|
224
216
|
}
|
|
225
217
|
/**
|
|
226
218
|
* Returns true if the channel is principally readable (i.e. not yet
|
package/mult.js
CHANGED
package/ops.d.ts
CHANGED
|
@@ -33,26 +33,40 @@ export declare const consumeWith: <T>(chan: Channel<T>, fn: Fn2<T, Channel<T>, v
|
|
|
33
33
|
export declare const drain: <T>(chan: Channel<T>) => Promise<Awaited<T>[]>;
|
|
34
34
|
/**
|
|
35
35
|
* Takes an async iterable and returns a new CSP {@link Channel}, which receives
|
|
36
|
-
* all values from `src
|
|
37
|
-
* automatically closed once the iterable is exhausted.
|
|
36
|
+
* all values from `src` (via {@link pipe}). If `close` is true (default), the
|
|
37
|
+
* channel will be automatically closed once the iterable is exhausted. Returns
|
|
38
|
+
* the new channel.
|
|
38
39
|
*
|
|
39
40
|
* @param src
|
|
40
41
|
* @param close
|
|
41
42
|
*/
|
|
42
43
|
export declare const fromAsyncIterable: <T>(src: AsyncIterable<T>, close?: boolean) => Channel<T>;
|
|
43
44
|
export declare const merge: <T>(src: Channel<T>[], dest?: Channel<T>, close?: boolean) => Channel<T>;
|
|
45
|
+
/**
|
|
46
|
+
* @deprecated use {@link pipe} instead.
|
|
47
|
+
*/
|
|
44
48
|
export declare const into: <T, DEST extends IWriteable<T> & IClosable>(chan: DEST, src: Iterable<T> | AsyncIterable<T>, close?: boolean) => Promise<void>;
|
|
45
|
-
|
|
49
|
+
/**
|
|
50
|
+
* Receives values from `src` and writes them to `dest` for as long as it's
|
|
51
|
+
* accepting new writes (i.e. isn't closed from elsewhere). If `close` is true
|
|
52
|
+
* (default), the `dest` channel will be automatically closed once the `src` is
|
|
53
|
+
* exhausted. Returns `dest` channel.
|
|
54
|
+
*
|
|
55
|
+
* @param src
|
|
56
|
+
* @param dest
|
|
57
|
+
* @param close
|
|
58
|
+
*/
|
|
59
|
+
export declare const pipe: <T, DEST extends IWriteable<T> & IClosable>(src: AsyncIterable<T>, dest: DEST, close?: boolean) => DEST;
|
|
46
60
|
/**
|
|
47
61
|
* Takes one or more input channels and attempts to read from all of them at
|
|
48
62
|
* once (via {@link Channel.race}, a blocking op). Returns a promise which
|
|
49
63
|
* resolves once one of the inputs becomes available or was closed, selects that
|
|
50
64
|
* channel to read from it and returns tuple of `[value, channel]`.
|
|
51
65
|
*
|
|
52
|
-
* @param input
|
|
53
|
-
* @param
|
|
66
|
+
* @param input - first input
|
|
67
|
+
* @param rest - other inputs
|
|
54
68
|
*/
|
|
55
|
-
export declare const select: <T>(input: Channel<T>, ...
|
|
69
|
+
export declare const select: <T>(input: Channel<T>, ...rest: Channel<T>[]) => Promise<[Maybe<T>, Channel<T>]>;
|
|
56
70
|
/**
|
|
57
71
|
* Returns a new {@link Channel} which will automatically close after `delay`
|
|
58
72
|
* milliseconds.
|
package/ops.js
CHANGED
|
@@ -2,12 +2,10 @@ import { assert } from "@thi.ng/errors/assert";
|
|
|
2
2
|
import { Channel } from "./channel.js";
|
|
3
3
|
const broadcast = async (src, dest, close = true) => {
|
|
4
4
|
for await (let x of src) {
|
|
5
|
-
for (let chan of dest)
|
|
6
|
-
chan.write(x);
|
|
5
|
+
for (let chan of dest) chan.write(x);
|
|
7
6
|
}
|
|
8
7
|
if (close) {
|
|
9
|
-
for (let chan of dest)
|
|
10
|
-
chan.close();
|
|
8
|
+
for (let chan of dest) chan.close();
|
|
11
9
|
}
|
|
12
10
|
};
|
|
13
11
|
const concat = async (dest, chans, close = true) => {
|
|
@@ -21,8 +19,7 @@ const concat = async (dest, chans, close = true) => {
|
|
|
21
19
|
const consume = async (chan, res = [], num = Infinity) => {
|
|
22
20
|
for (let n = 0; !chan.closed() && n < num; n++) {
|
|
23
21
|
const x = await chan.read();
|
|
24
|
-
if (x == void 0)
|
|
25
|
-
break;
|
|
22
|
+
if (x == void 0) break;
|
|
26
23
|
res.push(x);
|
|
27
24
|
}
|
|
28
25
|
return res;
|
|
@@ -30,8 +27,7 @@ const consume = async (chan, res = [], num = Infinity) => {
|
|
|
30
27
|
const consumeWith = async (chan, fn, num = Infinity) => {
|
|
31
28
|
for (let n = 0; !chan.closed() && n < num; n++) {
|
|
32
29
|
const x = await chan.read();
|
|
33
|
-
if (x == void 0)
|
|
34
|
-
break;
|
|
30
|
+
if (x == void 0) break;
|
|
35
31
|
fn(x, chan);
|
|
36
32
|
}
|
|
37
33
|
};
|
|
@@ -42,18 +38,7 @@ const drain = async (chan) => await (async () => {
|
|
|
42
38
|
}
|
|
43
39
|
return Promise.all(ops);
|
|
44
40
|
})();
|
|
45
|
-
const fromAsyncIterable = (src, close = true) =>
|
|
46
|
-
const chan = new Channel();
|
|
47
|
-
(async () => {
|
|
48
|
-
for await (let x of src) {
|
|
49
|
-
await chan.write(x);
|
|
50
|
-
if (!chan.writable())
|
|
51
|
-
break;
|
|
52
|
-
}
|
|
53
|
-
close && chan.close();
|
|
54
|
-
})();
|
|
55
|
-
return chan;
|
|
56
|
-
};
|
|
41
|
+
const fromAsyncIterable = (src, close = true) => pipe(src, new Channel(), close);
|
|
57
42
|
const merge = (src, dest, close = true) => {
|
|
58
43
|
assert(src.length > 0, "no inputs given");
|
|
59
44
|
dest = dest || new Channel();
|
|
@@ -75,8 +60,7 @@ const merge = (src, dest, close = true) => {
|
|
|
75
60
|
};
|
|
76
61
|
const into = async (chan, src, close = false) => {
|
|
77
62
|
for await (let x of src) {
|
|
78
|
-
if (!chan.writable())
|
|
79
|
-
break;
|
|
63
|
+
if (!chan.writable()) break;
|
|
80
64
|
await chan.write(x);
|
|
81
65
|
}
|
|
82
66
|
close && chan.close();
|
|
@@ -85,19 +69,17 @@ const pipe = (src, dest, close = true) => {
|
|
|
85
69
|
(async () => {
|
|
86
70
|
for await (let x of src) {
|
|
87
71
|
await dest.write(x);
|
|
88
|
-
if (!dest.writable())
|
|
89
|
-
break;
|
|
72
|
+
if (!dest.writable()) break;
|
|
90
73
|
}
|
|
91
74
|
close && dest.close();
|
|
92
75
|
})();
|
|
93
76
|
return dest;
|
|
94
77
|
};
|
|
95
|
-
const select = async (input, ...
|
|
96
|
-
const inputs = [input, ...
|
|
78
|
+
const select = async (input, ...rest) => {
|
|
79
|
+
const inputs = [input, ...rest];
|
|
97
80
|
const sel = await Promise.race(inputs.map((x) => x.race()));
|
|
98
81
|
for (let chan of inputs) {
|
|
99
|
-
if (chan !== sel)
|
|
100
|
-
chan.races.shift();
|
|
82
|
+
if (chan !== sel) chan.races.shift();
|
|
101
83
|
}
|
|
102
84
|
if (sel.writes.readable()) {
|
|
103
85
|
const [msg, write] = sel.writes.read();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/csp",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.2",
|
|
4
4
|
"description": "Primitives & operators for Communicating Sequential Processes based on async/await and async iterables",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"type": "git",
|
|
11
11
|
"url": "https://github.com/thi-ng/umbrella.git"
|
|
12
12
|
},
|
|
13
|
-
"homepage": "https://
|
|
13
|
+
"homepage": "https://thi.ng/csp",
|
|
14
14
|
"funding": [
|
|
15
15
|
{
|
|
16
16
|
"type": "github",
|
|
@@ -40,16 +40,16 @@
|
|
|
40
40
|
"tool:tangle": "../../node_modules/.bin/tangle src/**/*.ts"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@thi.ng/api": "^8.11.
|
|
44
|
-
"@thi.ng/buffers": "^0.1.
|
|
45
|
-
"@thi.ng/checks": "^3.6.
|
|
46
|
-
"@thi.ng/errors": "^2.5.
|
|
43
|
+
"@thi.ng/api": "^8.11.3",
|
|
44
|
+
"@thi.ng/buffers": "^0.1.4",
|
|
45
|
+
"@thi.ng/checks": "^3.6.5",
|
|
46
|
+
"@thi.ng/errors": "^2.5.8"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@microsoft/api-extractor": "^7.
|
|
50
|
-
"esbuild": "^0.
|
|
51
|
-
"typedoc": "^0.25.
|
|
52
|
-
"typescript": "^5.
|
|
49
|
+
"@microsoft/api-extractor": "^7.47.0",
|
|
50
|
+
"esbuild": "^0.21.5",
|
|
51
|
+
"typedoc": "^0.25.13",
|
|
52
|
+
"typescript": "^5.5.2"
|
|
53
53
|
},
|
|
54
54
|
"keywords": [
|
|
55
55
|
"async",
|
|
@@ -106,5 +106,5 @@
|
|
|
106
106
|
"status": "beta",
|
|
107
107
|
"year": 2016
|
|
108
108
|
},
|
|
109
|
-
"gitHead": "
|
|
109
|
+
"gitHead": "154c95cf9d6bab32174498ec3b5b5d87e42be7f9\n"
|
|
110
110
|
}
|