@thi.ng/fibers 1.0.3 → 1.0.5
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 +1 -1
- package/README.md +11 -10
- package/csp.d.ts +1 -1
- package/csp.js +2 -4
- package/fiber.js +13 -26
- package/ops.d.ts +1 -1
- package/ops.js +11 -22
- package/package.json +16 -16
package/CHANGELOG.md
CHANGED
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
|
>
|
|
@@ -423,15 +423,16 @@ Several projects in this repo's
|
|
|
423
423
|
[/examples](https://github.com/thi-ng/umbrella/tree/develop/examples)
|
|
424
424
|
directory are using this package:
|
|
425
425
|
|
|
426
|
-
| Screenshot
|
|
427
|
-
|
|
428
|
-
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/ascii-raymarch.jpg" width="240"/>
|
|
429
|
-
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/fiber-basics.png" width="240"/>
|
|
430
|
-
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/
|
|
431
|
-
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/
|
|
432
|
-
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/
|
|
433
|
-
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/
|
|
434
|
-
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/
|
|
426
|
+
| Screenshot | Description | Live demo | Source |
|
|
427
|
+
|:-------------------------------------------------------------------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------|:--------------------------------------------------------|:-------------------------------------------------------------------------------------|
|
|
428
|
+
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/ascii-raymarch.jpg" width="240"/> | ASCII art raymarching with thi.ng/shader-ast & thi.ng/text-canvas | [Demo](https://demo.thi.ng/umbrella/ascii-raymarch/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/ascii-raymarch) |
|
|
429
|
+
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/fiber-basics.png" width="240"/> | Fiber-based cooperative multitasking basics | [Demo](https://demo.thi.ng/umbrella/fiber-basics/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/fiber-basics) |
|
|
430
|
+
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/geom-unique-edges.png" width="240"/> | Iterating the unique edges of a tessellation | [Demo](https://demo.thi.ng/umbrella/geom-unique-edges/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/geom-unique-edges) |
|
|
431
|
+
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/ifs-fractal.jpg" width="240"/> | Barnsley fern IFS fractal renderer | [Demo](https://demo.thi.ng/umbrella/ifs-fractal/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/ifs-fractal) |
|
|
432
|
+
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/mastodon-feed.jpg" width="240"/> | Mastodon API feed reader with support for different media types, fullscreen media modal, HTML rewriting | [Demo](https://demo.thi.ng/umbrella/mastodon-feed/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/mastodon-feed) |
|
|
433
|
+
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/poly-subdiv.jpg" width="240"/> | Animated, iterative polygon subdivisions & visualization | [Demo](https://demo.thi.ng/umbrella/poly-subdiv/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/poly-subdiv) |
|
|
434
|
+
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/related-images.jpg" width="240"/> | Responsive image gallery with tag-based Jaccard similarity ranking | [Demo](https://demo.thi.ng/umbrella/related-images/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/related-images) |
|
|
435
|
+
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/render-audio.png" width="240"/> | Generative audio synth offline renderer and WAV file export | [Demo](https://demo.thi.ng/umbrella/render-audio/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/render-audio) |
|
|
435
436
|
|
|
436
437
|
## API
|
|
437
438
|
|
package/csp.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ import { Fiber } from "./fiber.js";
|
|
|
9
9
|
declare const STATE_OPEN = 0;
|
|
10
10
|
declare const STATE_CLOSING = 1;
|
|
11
11
|
declare const STATE_CLOSED = 2;
|
|
12
|
-
type CSPState = typeof STATE_OPEN | typeof STATE_CLOSING | typeof STATE_CLOSED;
|
|
12
|
+
export type CSPState = typeof STATE_OPEN | typeof STATE_CLOSING | typeof STATE_CLOSED;
|
|
13
13
|
/**
|
|
14
14
|
* Fiber-based CSP channel implementation, supporting any
|
|
15
15
|
* [IReadWriteBuffer](https://docs.thi.ng/umbrella/buffers/interfaces/IReadWriteBuffer.html)
|
package/csp.js
CHANGED
|
@@ -84,13 +84,11 @@ class Channel {
|
|
|
84
84
|
close(wait = true) {
|
|
85
85
|
const chan = this;
|
|
86
86
|
return fiber(function* (ctx) {
|
|
87
|
-
if (chan.state >= STATE_CLOSING)
|
|
88
|
-
return;
|
|
87
|
+
if (chan.state >= STATE_CLOSING) return;
|
|
89
88
|
if (wait) {
|
|
90
89
|
ctx.logger?.debug("waiting to close...");
|
|
91
90
|
chan.state = STATE_CLOSING;
|
|
92
|
-
while (chan.buffer.readable())
|
|
93
|
-
yield;
|
|
91
|
+
while (chan.buffer.readable()) yield;
|
|
94
92
|
}
|
|
95
93
|
chan.state = STATE_CLOSED;
|
|
96
94
|
chan.buffer.clear();
|
package/fiber.js
CHANGED
|
@@ -5,8 +5,7 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
5
5
|
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
6
6
|
if (decorator = decorators[i])
|
|
7
7
|
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
-
if (kind && result)
|
|
9
|
-
__defProp(target, key, result);
|
|
8
|
+
if (kind && result) __defProp(target, key, result);
|
|
10
9
|
return result;
|
|
11
10
|
};
|
|
12
11
|
import { INotifyMixin } from "@thi.ng/api/mixins/inotify";
|
|
@@ -64,8 +63,7 @@ let Fiber = class {
|
|
|
64
63
|
} else {
|
|
65
64
|
this.idgen = DEFAULT_ID_GEN;
|
|
66
65
|
}
|
|
67
|
-
if (this.idgen)
|
|
68
|
-
this.id = this.idgen.next();
|
|
66
|
+
if (this.idgen) this.id = this.idgen.next();
|
|
69
67
|
this.gen = isFunction(gen) ? gen(this) : gen;
|
|
70
68
|
}
|
|
71
69
|
/**
|
|
@@ -73,8 +71,7 @@ let Fiber = class {
|
|
|
73
71
|
* Then return this fiber's value.
|
|
74
72
|
*/
|
|
75
73
|
*[Symbol.iterator]() {
|
|
76
|
-
while (this.state <= STATE_ACTIVE && this.next() <= STATE_ACTIVE)
|
|
77
|
-
yield;
|
|
74
|
+
while (this.state <= STATE_ACTIVE && this.next() <= STATE_ACTIVE) yield;
|
|
78
75
|
return this.value;
|
|
79
76
|
}
|
|
80
77
|
/**
|
|
@@ -178,8 +175,7 @@ let Fiber = class {
|
|
|
178
175
|
* @param opts
|
|
179
176
|
*/
|
|
180
177
|
fork(body, opts) {
|
|
181
|
-
if (!this.isActive())
|
|
182
|
-
illegalState(`fiber (id: ${this.id}) not active`);
|
|
178
|
+
if (!this.isActive()) illegalState(`fiber (id: ${this.id}) not active`);
|
|
183
179
|
let $fiber;
|
|
184
180
|
if (body instanceof Fiber) {
|
|
185
181
|
if (body.parent)
|
|
@@ -218,8 +214,7 @@ let Fiber = class {
|
|
|
218
214
|
*/
|
|
219
215
|
*join() {
|
|
220
216
|
this.logger?.debug("waiting for children...");
|
|
221
|
-
while (this.children.length)
|
|
222
|
-
yield;
|
|
217
|
+
while (this.children.length) yield;
|
|
223
218
|
}
|
|
224
219
|
/**
|
|
225
220
|
* Processes a single iteration of this fiber and any of its children. Does
|
|
@@ -246,16 +241,14 @@ let Fiber = class {
|
|
|
246
241
|
if (child.state > STATE_ACTIVE || child.next() > STATE_ACTIVE) {
|
|
247
242
|
children.splice(i, 1);
|
|
248
243
|
n--;
|
|
249
|
-
} else
|
|
250
|
-
i++;
|
|
244
|
+
} else i++;
|
|
251
245
|
}
|
|
252
246
|
} else if (this.autoTerminate) {
|
|
253
247
|
this.cancel();
|
|
254
248
|
break;
|
|
255
249
|
}
|
|
256
250
|
const res = this.gen ? this.gen.next(this) : NO_RESULT;
|
|
257
|
-
if (res.done)
|
|
258
|
-
this.done(res.value);
|
|
251
|
+
if (res.done) this.done(res.value);
|
|
259
252
|
} catch (e) {
|
|
260
253
|
this.catch(e);
|
|
261
254
|
}
|
|
@@ -283,11 +276,9 @@ let Fiber = class {
|
|
|
283
276
|
* Function is a no-op if the fiber is not active anymore.
|
|
284
277
|
*/
|
|
285
278
|
cancel() {
|
|
286
|
-
if (!this.isActive())
|
|
287
|
-
return;
|
|
279
|
+
if (!this.isActive()) return;
|
|
288
280
|
this.logger?.debug("cancel", this.id);
|
|
289
|
-
for (let child of this.children)
|
|
290
|
-
child.cancel();
|
|
281
|
+
for (let child of this.children) child.cancel();
|
|
291
282
|
this.deinit();
|
|
292
283
|
this.state = STATE_CANCELED;
|
|
293
284
|
this.idgen?.free(this.id);
|
|
@@ -304,12 +295,10 @@ let Fiber = class {
|
|
|
304
295
|
* @param value
|
|
305
296
|
*/
|
|
306
297
|
done(value) {
|
|
307
|
-
if (!this.isActive())
|
|
308
|
-
return;
|
|
298
|
+
if (!this.isActive()) return;
|
|
309
299
|
this.logger?.debug("done", this.id, value);
|
|
310
300
|
this.value = value;
|
|
311
|
-
for (let child of this.children)
|
|
312
|
-
child.done();
|
|
301
|
+
for (let child of this.children) child.done();
|
|
313
302
|
this.deinit();
|
|
314
303
|
this.state = STATE_DONE;
|
|
315
304
|
this.idgen?.free(this.id);
|
|
@@ -328,11 +317,9 @@ let Fiber = class {
|
|
|
328
317
|
* @param err
|
|
329
318
|
*/
|
|
330
319
|
catch(err) {
|
|
331
|
-
if (this.state >= STATE_ERROR || this.user?.catch?.(this, err))
|
|
332
|
-
return;
|
|
320
|
+
if (this.state >= STATE_ERROR || this.user?.catch?.(this, err)) return;
|
|
333
321
|
this.logger ? this.logger.severe(`error ${this.id}:`, err) : console.warn(`error ${this.id}:`, err);
|
|
334
|
-
for (let child of this.children)
|
|
335
|
-
child.cancel();
|
|
322
|
+
for (let child of this.children) child.cancel();
|
|
336
323
|
this.state = STATE_ERROR;
|
|
337
324
|
this.error = err;
|
|
338
325
|
this.deinit();
|
package/ops.d.ts
CHANGED
|
@@ -97,7 +97,7 @@ export declare const timeSlice: (body: MaybeFiber, maxTime: number, opts?: Parti
|
|
|
97
97
|
* @example
|
|
98
98
|
* ```ts
|
|
99
99
|
* import { timeSliceIterable } from "@thi.ng/fibers";
|
|
100
|
-
* import { range } from "@
|
|
100
|
+
* import { range } from "@thi.ng/transducers";
|
|
101
101
|
*
|
|
102
102
|
* // consume & batch process iterable in 16ms time slices
|
|
103
103
|
* timeSliceIterable(
|
package/ops.js
CHANGED
|
@@ -10,23 +10,18 @@ import { Fiber, fiber } from "./fiber.js";
|
|
|
10
10
|
const wait = (delay) => delay !== void 0 ? untilPromise(
|
|
11
11
|
new Promise((resolve) => setTimeout(resolve, delay))
|
|
12
12
|
) : fiber(function* () {
|
|
13
|
-
while (true)
|
|
14
|
-
yield;
|
|
13
|
+
while (true) yield;
|
|
15
14
|
});
|
|
16
15
|
function* waitFrames(delay) {
|
|
17
|
-
while (delay-- > 0)
|
|
18
|
-
yield;
|
|
16
|
+
while (delay-- > 0) yield;
|
|
19
17
|
}
|
|
20
18
|
const sequence = (fibers, opts) => fiber(function* (ctx) {
|
|
21
19
|
for (let fiber2 of fibers) {
|
|
22
20
|
const $fiber = ctx.fork(fiber2);
|
|
23
|
-
while ($fiber.isActive())
|
|
24
|
-
|
|
25
|
-
if ($fiber.state === STATE_ERROR)
|
|
26
|
-
throw $fiber.error;
|
|
21
|
+
while ($fiber.isActive()) yield;
|
|
22
|
+
if ($fiber.state === STATE_ERROR) throw $fiber.error;
|
|
27
23
|
ctx.value = $fiber.value;
|
|
28
|
-
if ($fiber.state > STATE_DONE || ctx.state > STATE_ACTIVE)
|
|
29
|
-
break;
|
|
24
|
+
if ($fiber.state > STATE_DONE || ctx.state > STATE_ACTIVE) break;
|
|
30
25
|
}
|
|
31
26
|
return ctx.value;
|
|
32
27
|
}, opts);
|
|
@@ -34,8 +29,7 @@ const first = (fibers, opts) => fiber(function* (ctx) {
|
|
|
34
29
|
const $fibers = [...fibers].map((f) => ctx.fork(f));
|
|
35
30
|
while (true) {
|
|
36
31
|
for (let f of $fibers) {
|
|
37
|
-
if (!f.isActive())
|
|
38
|
-
return f;
|
|
32
|
+
if (!f.isActive()) return f;
|
|
39
33
|
}
|
|
40
34
|
yield;
|
|
41
35
|
}
|
|
@@ -74,12 +68,10 @@ const timeSliceIterable = (src, consume, maxTime, opts) => fiber(function* () {
|
|
|
74
68
|
}
|
|
75
69
|
}, opts);
|
|
76
70
|
function* until(pred) {
|
|
77
|
-
while (!pred())
|
|
78
|
-
yield;
|
|
71
|
+
while (!pred()) yield;
|
|
79
72
|
}
|
|
80
73
|
function* untilState(state, pred) {
|
|
81
|
-
while (!pred(state))
|
|
82
|
-
yield;
|
|
74
|
+
while (!pred(state)) yield;
|
|
83
75
|
}
|
|
84
76
|
const untilPromise = (promise, opts) => fiber(function* (ctx) {
|
|
85
77
|
let error;
|
|
@@ -88,8 +80,7 @@ const untilPromise = (promise, opts) => fiber(function* (ctx) {
|
|
|
88
80
|
(e) => error = e
|
|
89
81
|
);
|
|
90
82
|
while (true) {
|
|
91
|
-
if (error)
|
|
92
|
-
throw error;
|
|
83
|
+
if (error) throw error;
|
|
93
84
|
yield;
|
|
94
85
|
}
|
|
95
86
|
}, opts);
|
|
@@ -114,8 +105,7 @@ class Shuffle extends Fiber {
|
|
|
114
105
|
this.forkAll(...fibers);
|
|
115
106
|
}
|
|
116
107
|
next() {
|
|
117
|
-
if (!this.isActive())
|
|
118
|
-
return this.state;
|
|
108
|
+
if (!this.isActive()) return this.state;
|
|
119
109
|
$shuffle(this.children, this.children.length, this.rnd);
|
|
120
110
|
return super.next();
|
|
121
111
|
}
|
|
@@ -129,8 +119,7 @@ const asPromise = (task, opts) => new Promise((resolve, reject) => {
|
|
|
129
119
|
ctx.state < STATE_ERROR && resolve(ctx.deref());
|
|
130
120
|
},
|
|
131
121
|
catch: (ctx, e) => {
|
|
132
|
-
if (opts?.catch && opts.catch(ctx, e))
|
|
133
|
-
return true;
|
|
122
|
+
if (opts?.catch && opts.catch(ctx, e)) return true;
|
|
134
123
|
reject(e);
|
|
135
124
|
return false;
|
|
136
125
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/fibers",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "Process hierarchies & operators for cooperative multitasking",
|
|
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/fibers",
|
|
14
14
|
"funding": [
|
|
15
15
|
{
|
|
16
16
|
"type": "github",
|
|
@@ -36,21 +36,21 @@
|
|
|
36
36
|
"tool:tangle": "../../node_modules/.bin/tangle src/**/*.ts"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@thi.ng/api": "^8.11.
|
|
40
|
-
"@thi.ng/arrays": "^2.9.
|
|
41
|
-
"@thi.ng/bench": "^3.5.
|
|
42
|
-
"@thi.ng/buffers": "^0.1.
|
|
43
|
-
"@thi.ng/checks": "^3.6.
|
|
44
|
-
"@thi.ng/errors": "^2.5.
|
|
45
|
-
"@thi.ng/idgen": "^2.2.
|
|
46
|
-
"@thi.ng/logger": "^3.0.
|
|
47
|
-
"@thi.ng/random": "^3.
|
|
39
|
+
"@thi.ng/api": "^8.11.3",
|
|
40
|
+
"@thi.ng/arrays": "^2.9.7",
|
|
41
|
+
"@thi.ng/bench": "^3.5.7",
|
|
42
|
+
"@thi.ng/buffers": "^0.1.4",
|
|
43
|
+
"@thi.ng/checks": "^3.6.5",
|
|
44
|
+
"@thi.ng/errors": "^2.5.8",
|
|
45
|
+
"@thi.ng/idgen": "^2.2.42",
|
|
46
|
+
"@thi.ng/logger": "^3.0.13",
|
|
47
|
+
"@thi.ng/random": "^3.8.1"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@microsoft/api-extractor": "^7.
|
|
51
|
-
"esbuild": "^0.
|
|
52
|
-
"typedoc": "^0.25.
|
|
53
|
-
"typescript": "^5.
|
|
50
|
+
"@microsoft/api-extractor": "^7.47.0",
|
|
51
|
+
"esbuild": "^0.21.5",
|
|
52
|
+
"typedoc": "^0.25.13",
|
|
53
|
+
"typescript": "^5.5.2"
|
|
54
54
|
},
|
|
55
55
|
"keywords": [
|
|
56
56
|
"blocking",
|
|
@@ -113,5 +113,5 @@
|
|
|
113
113
|
"status": "alpha",
|
|
114
114
|
"year": 2023
|
|
115
115
|
},
|
|
116
|
-
"gitHead": "
|
|
116
|
+
"gitHead": "154c95cf9d6bab32174498ec3b5b5d87e42be7f9\n"
|
|
117
117
|
}
|