UNPKG

3.15 kBJavaScriptView Raw
1import { error, doneInvoke } from './actions.js';
2import { toActorRef } from './Actor.js';
3import { toObserver } from './utils.js';
4
5/**
6 * Returns an actor behavior from a reducer and its initial state.
7 *
8 * @param transition The pure reducer that returns the next state given the current state and event.
9 * @param initialState The initial state of the reducer.
10 * @returns An actor behavior
11 */
12
13function fromReducer(transition, initialState) {
14 return {
15 transition: transition,
16 initialState: initialState
17 };
18}
19function fromPromise(promiseFn) {
20 var initialState = {
21 error: undefined,
22 data: undefined,
23 status: 'pending'
24 };
25 return {
26 transition: function (state, event, _a) {
27 var parent = _a.parent,
28 id = _a.id,
29 observers = _a.observers;
30
31 switch (event.type) {
32 case 'fulfill':
33 parent === null || parent === void 0 ? void 0 : parent.send(doneInvoke(id, event.data));
34 return {
35 error: undefined,
36 data: event.data,
37 status: 'fulfilled'
38 };
39
40 case 'reject':
41 parent === null || parent === void 0 ? void 0 : parent.send(error(id, event.error));
42 observers.forEach(function (observer) {
43 observer.error(event.error);
44 });
45 return {
46 error: event.error,
47 data: undefined,
48 status: 'rejected'
49 };
50
51 default:
52 return state;
53 }
54 },
55 initialState: initialState,
56 start: function (_a) {
57 var self = _a.self;
58 promiseFn().then(function (data) {
59 self.send({
60 type: 'fulfill',
61 data: data
62 });
63 }, function (reason) {
64 self.send({
65 type: 'reject',
66 error: reason
67 });
68 });
69 return initialState;
70 }
71 };
72}
73function spawnBehavior(behavior, options) {
74 if (options === void 0) {
75 options = {};
76 }
77
78 var state = behavior.initialState;
79 var observers = new Set();
80 var mailbox = [];
81 var flushing = false;
82
83 var flush = function () {
84 if (flushing) {
85 return;
86 }
87
88 flushing = true;
89
90 while (mailbox.length > 0) {
91 var event_1 = mailbox.shift();
92 state = behavior.transition(state, event_1, actorCtx);
93 observers.forEach(function (observer) {
94 return observer.next(state);
95 });
96 }
97
98 flushing = false;
99 };
100
101 var actor = toActorRef({
102 id: options.id,
103 send: function (event) {
104 mailbox.push(event);
105 flush();
106 },
107 getSnapshot: function () {
108 return state;
109 },
110 subscribe: function (next, handleError, complete) {
111 var observer = toObserver(next, handleError, complete);
112 observers.add(observer);
113 observer.next(state);
114 return {
115 unsubscribe: function () {
116 observers.delete(observer);
117 }
118 };
119 }
120 });
121 var actorCtx = {
122 parent: options.parent,
123 self: actor,
124 id: options.id || 'anonymous',
125 observers: observers
126 };
127 state = behavior.start ? behavior.start(actorCtx) : state;
128 return actor;
129}
130
131export { fromPromise, fromReducer, spawnBehavior };