1 | import { A as ARRAY_EMPTY } from './chunk/constants.js';
|
2 | import { p as promise, i as isFunction } from './chunk/utils.js';
|
3 | import { useState, useEffect, useMemo } from './core.js';
|
4 |
|
5 | const promiseIgnore = promise(() => {});
|
6 |
|
7 | const CONTINUE = Symbol();
|
8 |
|
9 | function delay(ms) {
|
10 | return promise(resolve => setTimeout(() => resolve(CONTINUE), ms));
|
11 | }
|
12 |
|
13 | function useStateGenerator(stream, initialState, vars = ARRAY_EMPTY) {
|
14 | let [{ ref }, setValue] = useState(() => ({
|
15 | ref: createState(initialState)
|
16 | }));
|
17 |
|
18 | useEffect(() => ref.cancel, []);
|
19 |
|
20 | ref.stream = stream;
|
21 |
|
22 | return [
|
23 | ref.state,
|
24 | useMemo(
|
25 | () =>
|
26 | ref.send(() => {
|
27 | setValue({ ref });
|
28 | }),
|
29 | vars
|
30 | )
|
31 | ];
|
32 | }
|
33 |
|
34 | function consumer(value, process, id, subscribe) {
|
35 | return Promise.resolve(value).then(value => {
|
36 | if (isFunction(value)) {
|
37 | return consumer(value(process.state), process, id, subscribe);
|
38 | }
|
39 |
|
40 | if (typeof value == "object" && isFunction(value.next)) {
|
41 | return promise(resolve => {
|
42 | function scan(generator) {
|
43 | Promise.resolve(
|
44 | generator.next(process.state)
|
45 | ).then(({ value, done }) =>
|
46 | consumer(value, process, id, subscribe).then(() =>
|
47 | done ? resolve(process.state) : scan(generator)
|
48 | )
|
49 | );
|
50 | }
|
51 | scan(value);
|
52 | });
|
53 | }
|
54 | return process.next(value, subscribe, id);
|
55 | });
|
56 | }
|
57 |
|
58 | function createState(state) {
|
59 | let currentID = 0;
|
60 | let process = { state, next, cancel, send };
|
61 |
|
62 | function next(value, subscribe, id) {
|
63 | if (id != currentID) return promiseIgnore;
|
64 | if (value != CONTINUE) {
|
65 | process.state = value;
|
66 | subscribe && subscribe(value);
|
67 | }
|
68 | return process.state;
|
69 | }
|
70 | function cancel() {
|
71 | currentID++;
|
72 | }
|
73 | function send(subscribe) {
|
74 | return consumer(process.stream, process, ++currentID, subscribe);
|
75 | }
|
76 |
|
77 | return process;
|
78 | }
|
79 |
|
80 | export { CONTINUE, delay, useStateGenerator };
|
81 |
|