@@ -1,9 +1,10 @@
1−import { useState, useEffect, useCallback } from 'react';
2−import { Nothing } from 'folktale/maybe';
1+import { useState, useCallback, useMemo } from 'react';
2+import { Just, Nothing } from 'folktale/maybe';
33import * as ob from 'urbit-ob';
44
5+import { getVaneName, getVaneNumber } from 'lib/hosting';
56import SolarisClient from 'lib/SolarisClient';
6−import { usePointCursor } from 'store/pointCursor';
7+// import { usePointCursor } from 'store/pointCursor';
78import useKeyfileGenerator from 'lib/useKeyfileGenerator';
89const STATE = {
910 // container states
@@ -11,32 +12,26 @@ const STATE = {
1112 MISSING: 'MISSING',
1213 RUNNING: 'RUNNING',
1314 PENDING: 'PENDING',
14− // api states
15− QUERYING: 'QUERYING',
16− BOOTING: 'BOOTING',
17− CONNECTING: 'CONNECTING',
18− // connection states
19− CONNECTED: 'CONNECTED',
2015};
2116
22−const mockFetch = status => ({
23− ok: true,
24−
25− json: () => Promise.resolve({ status }),
26−});
27−
2817function useHostingStore(url) {
2918 const client = new SolarisClient(url);
3019
31− const { pointCursor } = usePointCursor();
20+ // const { pointCursor } = usePointCursor();
21+ //
22+ const pointCursor = Just(ob.patp2dec('~wicdev-wisryt'));
23+
24+ const [bootProgress, setBootProgress] = useState(0);
25+ const [bootMessage, setBootMessage] = useState('Assembling Urbit');
26+ const [startTime] = useState(Date.now());
3227
33− const [state, _setState] = useState(STATE.UNKNOWN);
34− const setState = useCallback(
28+ const [status, _setStatus] = useState(STATE.UNKNOWN);
29+ const setStatus = useCallback(
3530 s => {
3631 console.log(s);
37− _setState(s);
32+ _setStatus(s);
3833 },
39− [_setState]
34+ [_setStatus]
4035 );
4136
4237 const [sysEvents, setSysEvents] = useState([]);
@@ -48,65 +43,25 @@ function useHostingStore(url) {
4843 error => {
4944 _setError(error);
5045 if (error) {
51− setState(STATE.UNKNOWN);
46+ setStatus(STATE.UNKNOWN);
5247 console.error(error);
5348 }
5449 },
55− [_setError, setState]
50+ [_setError, setStatus]
5651 );
5752
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;
53+ const unknown = status === STATE.UNKNOWN;
54+ const missing = status === STATE.MISSING;
55+ const running = status === STATE.RUNNING;
56+ const pending = status === STATE.PENDING;
57+
58+ let syncStatus;
6659
6760 const resetEvents = useCallback(() => {
6861 setSysEvents([]);
6962 setNewEvents([]);
7063 setRunEvents([]);
71− }, []);
72−
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);
80−
81− resetEvents();
82−
83− setState(STATE.QUERYING);
84−
85− const response = await client.getShipsByPatp(patp);
86−
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();
93−
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]);
106−
107− // useEffect(() => {
108− // syncStatus();
109− // }, [pointCursor, syncStatus]);
64+ }, [setSysEvents, setNewEvents, setRunEvents]);
11065
11166 const getEvents = useCallback(() => {
11267 try {
@@ -118,29 +73,53 @@ function useHostingStore(url) {
11873
11974 resetEvents();
12075
121− setState(STATE.CONNECTING);
122−
12376 const url = client.getShipsByPatpUrl(patp) + '/events';
12477 const source = new EventSource(url);
12578
126− source.onopen = () => setState(STATE.CONNECTED);
127− // source.onerror = () => setState(STATE.UNKNOWN);
79+ // source.onerror = () => setStatus(STATE.UNKNOWN);
12880 // source.onmessage = console.log;
12981
13082 source.addEventListener('sys', event => {
131− console.log(event);
132− setSysEvents(previous => [...previous, JSON.parse(event.data)]);
83+ // console.log(event);
84+ const sysEvent = JSON.parse(event.data);
85+ const time = new Date(sysEvent.object.firstTimestamp).getTime();
86+ if (time > startTime) {
87+ console.log(sysEvent);
88+ setSysEvents(previous => [...previous, sysEvent]);
89+ }
13390 });
13491
13592 source.addEventListener('new', event => {
136− console.log(event);
93+ // console.log(event);
94+ const elapsed = (Date.now() - startTime) / 1000;
13795 if (event.data !== '') {
13896 setNewEvents(previous => [...previous, event.data]);
13997 }
98+ if (event.data === '1-b') {
99+ setBootMessage('Compiling Hoon');
100+ setBootProgress(0.2);
101+ console.log(`${elapsed}: compiling Hoon`);
102+ } else if (event.data === '1-c') {
103+ setBootProgress(0.25);
104+ } else if (event.data === '%arvo-assembly') {
105+ setBootMessage('Compiling Urbit OS');
106+ setBootProgress(0.3);
107+ } else if (event.data.startsWith('[%vane %')) {
108+ const vane = getVaneName(event.data.slice(8, 9));
109+ setBootMessage(`Compiling vane: ${vane}`);
110+ setBootProgress(0.3 + 0.05 * getVaneNumber(event.data.slice(8, 9)));
111+ } else if (event.data === 'pier: boot complete') {
112+ setBootMessage('Ship starting');
113+ setBootProgress(0.85);
114+ }
140115 });
141116
142117 source.addEventListener('run', event => {
143− console.log(event);
118+ if (event.data === 'goad: recompiling all apps') {
119+ setBootProgress(1.0);
120+ setBootMessage('Ship Launched');
121+ syncStatus();
122+ }
144123 if (event.data !== '') {
145124 setRunEvents(previous => [...previous, event.data]);
146125 }
@@ -148,7 +127,54 @@ function useHostingStore(url) {
148127 } catch (error) {
149128 setError(error);
150129 }
151− }, [setError, resetEvents, client, pointCursor, setState]);
130+ }, [
131+ setError,
132+ resetEvents,
133+ client,
134+ pointCursor,
135+ setBootMessage,
136+ startTime,
137+ syncStatus,
138+ ]);
139+
140+ syncStatus = useCallback(async () => {
141+ try {
142+ if (Nothing.hasInstance(pointCursor)) {
143+ return;
144+ }
145+ const patp = ob.patp(pointCursor.value);
146+ setError(undefined);
147+
148+ resetEvents();
149+
150+ const response = await client.getShipsByPatp(patp);
151+
152+ if (response.status === 404) {
153+ setStatus(STATE.MISSING);
154+ } else if (!response.ok) {
155+ setError(response.statusText);
156+ } else {
157+ const ship = await response.json();
158+
159+ if (ship.status === 'Pending') {
160+ setStatus(STATE.PENDING);
161+ getEvents();
162+ } else if (ship.status === 'Running') {
163+ setStatus(STATE.RUNNING);
164+ } else {
165+ setError(ship);
166+ }
167+ }
168+ } catch (error) {
169+ setError(error);
170+ }
171+ }, [client, getEvents, pointCursor, resetEvents, setError, setStatus]);
172+
173+ const hostedShipUrl = useMemo(
174+ () =>
175+ `http://${ob.patp(pointCursor.getOrElse('')).slice(1)}.liam.tlon.network`,
176+ [pointCursor]
177+ );
152178
153179 const create = useCallback(
154180 async keyfile => {
@@ -156,10 +182,15 @@ function useHostingStore(url) {
156182 if (Nothing.hasInstance(pointCursor)) {
157183 return;
158184 }
159− const patp = ob.patp(pointCursor.value);
185+ keyfile =
186+ '0wnE.Z56pm.i2HLZ.6Pf1R.tAVZH.65R~C.Zgy6y.caI5Z.bZ2vV.09M5A.QP5-p.29UfR.35h2U.2k8-D.QP~~p.6bL62.~x3Em.t9h0x.0y01N.w80c1';
187+ const patp = ob.patp(pointCursor.value).slice(1);
160188 setError(undefined);
161189
162− setState(STATE.BOOTING);
190+ const start = Date.now();
191+ console.log(start);
192+ setStatus(STATE.PENDING);
193+ setBootProgress(0.1);
163194
164195 const response = await client.postShips({
165196 patp,
@@ -177,7 +208,7 @@ function useHostingStore(url) {
177208 setError(error);
178209 }
179210 },
180− [pointCursor, setError, setState, client, getEvents]
211+ [pointCursor, setError, setStatus, client, getEvents]
181212 );
182213
183214 return {
@@ -186,10 +217,7 @@ function useHostingStore(url) {
186217 missing,
187218 running,
188219 pending,
189− querying,
190− booting,
191− connecting,
192− connected,
220+ url: hostedShipUrl,
193221
194222 sysEvents,
195223 newEvents,
@@ -199,8 +227,11 @@ function useHostingStore(url) {
199227 getEvents,
200228 create,
201229
230+ bootProgress,
231+ bootMessage,
232+
202233 // debugging
203− state,
234+ status,
204235 };
205236}
206237