UNPKG

2.33 kBJavaScriptView Raw
1import { A as ARRAY_EMPTY } from './chunk/constants.js';
2import { p as promise, i as isFunction } from './chunk/utils.js';
3import { useState, useEffect, useMemo } from './core.js';
4
5const promiseIgnore = promise(() => {});
6
7const CONTINUE = Symbol();
8
9function delay(ms) {
10 return promise(resolve => setTimeout(() => resolve(CONTINUE), ms));
11}
12
13function 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
34function 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
58function 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
80export { CONTINUE, delay, useStateGenerator };
81//# sourceMappingURL=use-state-generator.js.map