on 0eeff2c help sign in
astrolabe/ui/src/lib/apps.ts
177 lines 4.6 kB history raw
1import _get from 'lodash/get';
2import { compose } from 'lodash/fp';
3import type { Apps } from 'types/store';
4import store from 'stores/store';
5import { sleep } from 'lib/utils';
6import { api } from 'lib/api';
7import { normalizeId } from 'lib/id';
9export function getProvidedApps(patp: string): Promise<any> {
10 return api.scry<any>({ app: 'treaty', path: `/treaties/${patp}` });
13// Unused, use subscription
14export function getKnownApps(): Promise<any> {
15 return api.scry<any>({ app: 'treaty', path: `/allies` }).then(processAllies);
18export function getApp(ship: string, desk: string): Promise<any> {
19 return getAppByPath(`${normalizeId(ship)}/${desk}`);
22// @param path - ship/desk e.g. ~mister-dister-dozzod-dozzod/webterm
23export async function getAppByPath(path: string, retry: number = 2): Promise<any> {
24 try {
25 return await api.scry<any>({ app: 'treaty', path: `/treaty/${path}` });
26 } catch (e) {
27 if (retry > 0) {
28 console.log(`Got error when fetching app: ${path}.\nTrying at most ${retry} more time(s)`);
29 await sleep(750);
30 return getAppByPath(path, retry - 1);
31 } else {
32 throw e;
33 }
34 }
37export function getInstalledApps(): Promise<any> {
38 return api.scry<any>({ app: 'docket', path: `/charges` });
41export async function sendAllyUpdate(cmd: string, ship: string) {
42 let result = await api.poke({
43 app: 'treaty',
44 mark: 'ally-update-0',
45 json: { [cmd]: normalizeId(ship) },
46 });
47 return result;
50export function addAlly(patp: string) {
51 return sendAllyUpdate('add', patp);
54export function delAlly(patp: string) {
55 return sendAllyUpdate('del', patp);
58export async function addAllies(ships: string[]) {
59 let results = await Promise.allSettled(ships.map((ship: string) => {
60 return addAlly(normalizeId(ship));
61 }));
62 results = results.filter(r => r.status === 'fulfilled').map((r) => {
63 return (r as PromiseFulfilledResult<any>).value;
64 });
65 return results;
68export async function delAllies(ships: string[], retry: number = 0) {
69 let results = await Promise.allSettled(ships.map((ship: string) => {
70 return delAlly(normalizeId(ship));
71 }));
72 results = results.filter(r => r.status === 'fulfilled').map((r) => {
73 return (r as PromiseFulfilledResult<any>).value;
74 });
75 return results;
78export function processAllies(rawPals: any): Apps {
79 let allies = rawPals.ini;
80 let paths = Object.values(allies).flat() as string[];
81 let set = new Set(paths);
82 return {
83 allies,
84 set,
85 };
88export type AllyUpdate = AllyUpdateIni | AllyUpdateAdd | AllyUpdateDel | AllyUpdateNew;
90export interface AllyUpdateIni {
91 ini: {
92 [ship: string]: string[];
93 }
96export interface AllyUpdateNew {
97 new: {
98 ship: string;
99 alliance: string[];
100 }
103export interface AllyUpdateAdd {
104 add: string;
107export interface AllyUpdateDel {
108 del: string;
111export function handleAllyUpdateIni(json: AllyUpdate, apps: Apps): Apps {
112 const data = _get(json, 'ini', false);
113 if (data) {
114 apps = processAllies(json)
115 }
116 return apps;
117};
119export function handleAllyUpdateNew(json: AllyUpdate, apps: Apps): Apps {
120 const data = _get(json, 'new', false);
121 if (data) {
122 apps = processAllies({
123 ini: {
124 ...apps.allies,
125 [data.ship]: data.alliance,
126 }
127 });
128 }
129 return apps;
130};
132export function handleAllyUpdateAdd(json: AllyUpdate, apps: Apps): Apps {
133 const data = _get(json, 'add', false);
134 if (data) {
135 apps = processAllies({
136 ini: {
137 ...apps.allies,
138 [data]: [],
139 }
140 });
141 }
142 return apps;
143};
145export function handleAllyUpdateDel(json: AllyUpdate, apps: Apps): Apps {
146 const data = _get(json, 'del', false);
147 if (data && (data in apps.allies)) {
148 delete apps.allies[data];
149 apps = processAllies({
150 ini: apps.allies,
151 });
152 }
153 return apps;
154};
156export function handleAllyUpdateEvent(updateApps) {
157 return (allyUpdate: AllyUpdate) => {
158 console.log(`received ally-update: ${Object.keys(allyUpdate)}`);
159 const reducers = [handleAllyUpdateIni, handleAllyUpdateNew, handleAllyUpdateAdd, handleAllyUpdateDel];
160 const reducer = compose(reducers.map(r => sta => r(allyUpdate, sta)));
161 updateApps(reducer);
162 };
165export function subscribeToApps(e: (data: any) => void): Promise<any> {
166 return api.subscribe({
167 app: 'treaty',
168 path: '/allies',
169 event: handleAllyUpdateEvent(e),
170 err: () => {
171 console.error(`Subscription to treaty/all just got "err"`);
172 },
173 quit: () => {
174 console.error(`Subscription to treaty/all just got "quit"`);
175 }
176 })