on ee5bed0 help sign in
bridge/src/store/lib/useHostingStore.js
207 lines 4.9 kB history raw
1import { useState, useEffect, useCallback } from 'react';
2import { Nothing } from 'folktale/maybe';
3import * as ob from 'urbit-ob';
5import SolarisClient from 'lib/SolarisClient';
6import { usePointCursor } from 'store/pointCursor';
7import useKeyfileGenerator from 'lib/useKeyfileGenerator';
8const STATE = {
9 // container states
10 UNKNOWN: 'UNKNOWN',
11 MISSING: 'MISSING',
12 RUNNING: 'RUNNING',
13 PENDING: 'PENDING',
14 // api states
15 QUERYING: 'QUERYING',
16 BOOTING: 'BOOTING',
17 CONNECTING: 'CONNECTING',
18 // connection states
19 CONNECTED: 'CONNECTED',
20};
22const mockFetch = status => ({
23 ok: true,
25 json: () => Promise.resolve({ status }),
26});
28function useHostingStore(url) {
29 const client = new SolarisClient(url);
31 const { pointCursor } = usePointCursor();
33 const [state, _setState] = useState(STATE.UNKNOWN);
34 const setState = useCallback(
35 s => {
36 console.log(s);
37 _setState(s);
38 },
39 [_setState]
40 );
42 const [sysEvents, setSysEvents] = useState([]);
43 const [newEvents, setNewEvents] = useState([]);
44 const [runEvents, setRunEvents] = useState([]);
46 const [error, _setError] = useState();
47 const setError = useCallback(
48 error => {
49 _setError(error);
50 if (error) {
51 setState(STATE.UNKNOWN);
52 console.error(error);
53 }
54 },
55 [_setError, setState]
56 );
58 const unknown = state === STATE.UNKNOWN;
59 const missing = state === STATE.MISSING;
60 const running = state === STATE.RUNNING;
61 const pending = state === STATE.PENDING;
62 const querying = state === STATE.QUERYING;
63 const booting = state === STATE.BOOTING;
64 const connecting = state === STATE.CONNECTING;
65 const connected = state === STATE.CONNECTED;
67 const resetEvents = useCallback(() => {
68 setSysEvents([]);
69 setNewEvents([]);
70 setRunEvents([]);
71 }, []);
73 const syncStatus = useCallback(async () => {
74 try {
75 if (Nothing.hasInstance(pointCursor)) {
76 return;
77 }
78 const patp = ob.patp(pointCursor.value);
79 setError(undefined);
81 resetEvents();
83 setState(STATE.QUERYING);
85 const response = await client.getShipsByPatp(patp);
87 if (response.status === 404) {
88 setState(STATE.MISSING);
89 } else if (!response.ok) {
90 setError(response.statusText);
91 } else {
92 const ship = await response.json();
94 if (ship.status === 'Pending') {
95 setState(STATE.PENDING);
96 } else if (ship.status === 'Running') {
97 setState(STATE.RUNNING);
98 } else {
99 setError(ship);
100 }
101 }
102 } catch (error) {
103 setError(error);
104 }
105 }, [client, pointCursor, resetEvents, setError, setState]);
107 // useEffect(() => {
108 // syncStatus();
109 // }, [pointCursor, syncStatus]);
111 const getEvents = useCallback(() => {
112 try {
113 if (Nothing.hasInstance(pointCursor)) {
114 return;
115 }
116 const patp = ob.patp(pointCursor.value);
117 setError(undefined);
119 resetEvents();
121 setState(STATE.CONNECTING);
123 const url = client.getShipsByPatpUrl(patp) + '/events';
124 const source = new EventSource(url);
126 source.onopen = () => setState(STATE.CONNECTED);
127 // source.onerror = () => setState(STATE.UNKNOWN);
128 // source.onmessage = console.log;
130 source.addEventListener('sys', event => {
131 console.log(event);
132 setSysEvents(previous => [...previous, JSON.parse(event.data)]);
133 });
135 source.addEventListener('new', event => {
136 console.log(event);
137 if (event.data !== '') {
138 setNewEvents(previous => [...previous, event.data]);
139 }
140 });
142 source.addEventListener('run', event => {
143 console.log(event);
144 if (event.data !== '') {
145 setRunEvents(previous => [...previous, event.data]);
146 }
147 });
148 } catch (error) {
149 setError(error);
150 }
151 }, [setError, resetEvents, client, pointCursor, setState]);
153 const create = useCallback(
154 async keyfile => {
155 try {
156 if (Nothing.hasInstance(pointCursor)) {
157 return;
158 }
159 const patp = ob.patp(pointCursor.value);
160 setError(undefined);
162 setState(STATE.BOOTING);
164 const response = await client.postShips({
165 patp,
166 key: keyfile,
167 debug: true,
168 fake: false,
169 });
171 if (!response.ok) {
172 setError(response.statusText);
173 } else {
174 getEvents();
175 }
176 } catch (error) {
177 setError(error);
178 }
179 },
180 [pointCursor, setError, setState, client, getEvents]
181 );
183 return {
184 error,
185 unknown,
186 missing,
187 running,
188 pending,
189 querying,
190 booting,
191 connecting,
192 connected,
194 sysEvents,
195 newEvents,
196 runEvents,
198 syncStatus,
199 getEvents,
200 create,
202 // debugging
203 state,
204 };
207export default useHostingStore;