on master help sign in
added hosting store
commit66bd0fa818ec7eaa1d63da4bda50aac7e60f83e3 authorLiam Fitzgerald <liam@urizen.co> dateSat 8 Feb 2020, 16:05 (7 years ago) parent7803665
2 files changed+211
src/store/hosting.js+23 src/store/lib/useHostingStore.js+188
src/store/hosting.jsnew file+23
@@ -0,0 +1,23 @@
1+import React, { createContext, useContext, forwardRef } from 'react';
2+
3+import useHostingStore from './lib/useHostingStore';
4+
5+export const HostingContext = createContext(null);
6+
7+export function HostingProvider({ children }) {
8+ const store = useHostingStore('https://localhost:3030');
9+ return (
10+ <HostingContext.Provider value={store}>{children}</HostingContext.Provider>
11+ );
12+}
13+
14+export function useHosting() {
15+ return useContext(HostingContext);
16+}
17+
18+export const withHosting = Component =>
19+ forwardRef((props, ref) => (
20+ <HostingContext.Consumer>
21+ {store => <Component ref={ref} {...store} {...props} />}
22+ </HostingContext.Consumer>
23+ ));
src/store/lib/useHostingStore.jsnew file+188
@@ -0,0 +1,188 @@
1+import { useState, useEffect, useCallback } from 'react';
2+import { Nothing } from 'folktale/maybe';
3+import * as ob from 'urbit-ob';
4+
5+import SolarisClient from 'lib/SolarisClient';
6+import { usePointCursor } from 'store/pointCursor';
7+const STATE = {
8+ // container states
9+ UNKNOWN: 'UNKNOWN',
10+ MISSING: 'MISSING',
11+ RUNNING: 'RUNNING',
12+ PENDING: 'PENDING',
13+ // api states
14+ QUERYING: 'QUERYING',
15+ BOOTING: 'BOOTING',
16+ CONNECTING: 'CONNECTING',
17+ // connection states
18+ CONNECTED: 'CONNECTED',
19+};
20+
21+function useHostingStore(url) {
22+ const client = new SolarisClient(url);
23+
24+ const { pointCursor } = usePointCursor();
25+
26+ const [state, _setState] = useState(STATE.UNKNOWN);
27+ const setState = useCallback(
28+ s => {
29+ console.log(s);
30+ _setState(s);
31+ },
32+ [_setState]
33+ );
34+
35+ const [sysEvents, setSysEvents] = useState([]);
36+ const [newEvents, setNewEvents] = useState([]);
37+ const [runEvents, setRunEvents] = useState([]);
38+
39+ const [error, _setError] = useState();
40+ const setError = useCallback(
41+ error => {
42+ _setError(error);
43+ if (error) {
44+ setState(STATE.UNKNOWN);
45+ console.error(error);
46+ }
47+ },
48+ [_setError, setState]
49+ );
50+
51+ const unknown = state === STATE.UNKNOWN;
52+ const missing = state === STATE.MISSING;
53+ const running = state === STATE.RUNNING;
54+ const pending = state === STATE.PENDING;
55+ const querying = state === STATE.QUERYING;
56+ const booting = state === STATE.BOOTING;
57+ const connecting = state === STATE.CONNECTING;
58+ const connected = state === STATE.CONNECTED;
59+
60+ const resetEvents = useCallback(() => {
61+ setSysEvents([]);
62+ setNewEvents([]);
63+ setRunEvents([]);
64+ }, []);
65+
66+ const syncStatus = useCallback(async () => {
67+ try {
68+ if (Nothing.hasInstance(pointCursor)) {
69+ return;
70+ }
71+ const patp = ob.patp(pointCursor.value);
72+ setError(undefined);
73+
74+ resetEvents();
75+
76+ setState(STATE.QUERYING);
77+
78+ const response = await client.getShipsByPatp(patp);
79+
80+ if (response.status === 404) {
81+ setState(STATE.MISSING);
82+ } else if (!response.ok) {
83+ setError(response.statusText);
84+ } else {
85+ const ship = await response.json();
86+
87+ if (ship.status === 'Pending') {
88+ setState(STATE.PENDING);
89+ } else if (ship.status === 'Running') {
90+ setState(STATE.RUNNING);
91+ } else {
92+ setError(ship);
93+ }
94+ }
95+ } catch (error) {
96+ setError(error);
97+ }
98+ }, [client, pointCursor, resetEvents, setError, setState]);
99+
100+ const getEvents = useCallback(() => {
101+ try {
102+ if (Nothing.hasInstance(pointCursor)) {
103+ return;
104+ }
105+ const patp = ob.patp(pointCursor.value);
106+ setError(undefined);
107+
108+ resetEvents();
109+
110+ setState(STATE.CONNECTING);
111+
112+ const url = client.getShipsByPatpUrl(patp) + '/events';
113+ const source = new EventSource(url);
114+
115+ source.onopen = () => setState(STATE.CONNECTED);
116+ // source.onerror = () => setState(STATE.UNKNOWN);
117+ // source.onmessage = console.log;
118+
119+ source.addEventListener('sys', event => {
120+ setSysEvents(previous => [...previous, JSON.parse(event.data)]);
121+ });
122+
123+ source.addEventListener('new', event => {
124+ if (event.data !== '') {
125+ setNewEvents(previous => [...previous, event.data]);
126+ }
127+ });
128+
129+ source.addEventListener('run', event => {
130+ if (event.data !== '') {
131+ setRunEvents(previous => [...previous, event.data]);
132+ }
133+ });
134+ } catch (error) {
135+ setError(error);
136+ }
137+ }, [setError, resetEvents, client, pointCursor, setState]);
138+
139+ const create = useCallback(async () => {
140+ try {
141+ if (Nothing.hasInstance(pointCursor)) {
142+ return;
143+ }
144+ const patp = ob.patp(pointCursor.value);
145+ setError(undefined);
146+
147+ setState(STATE.BOOTING);
148+
149+ const response = await client.postShips({
150+ patp,
151+ key: '123',
152+ });
153+
154+ if (!response.ok) {
155+ setError(response.statusText);
156+ } else {
157+ getEvents();
158+ }
159+ } catch (error) {
160+ setError(error);
161+ }
162+ }, [pointCursor, setError, setState, client, getEvents]);
163+
164+ return {
165+ error,
166+ unknown,
167+ missing,
168+ running,
169+ pending,
170+ querying,
171+ booting,
172+ connecting,
173+ connected,
174+
175+ sysEvents,
176+ newEvents,
177+ runEvents,
178+
179+ syncStatus,
180+ getEvents,
181+ create,
182+
183+ // debugging
184+ state,
185+ };
186+}
187+
188+export default useHostingStore;