2023-10-27 10:01:59 +00:00
|
|
|
import {
|
|
|
|
Coordinator,
|
2023-10-27 11:00:53 +00:00
|
|
|
type Exchange,
|
|
|
|
type Garage,
|
|
|
|
type Origin,
|
|
|
|
type PublicOrder,
|
|
|
|
type Robot,
|
|
|
|
type Settings,
|
2023-10-27 10:01:59 +00:00
|
|
|
defaultExchange,
|
|
|
|
} from '.';
|
|
|
|
import defaultFederation from '../../static/federation.json';
|
2023-10-27 11:00:53 +00:00
|
|
|
import { type CurrentOrder } from '../contexts/FederationContext';
|
2023-10-27 10:01:59 +00:00
|
|
|
import { updateExchangeInfo } from './Exchange.model';
|
|
|
|
|
|
|
|
type FederationHooks = 'onCoordinatorUpdate' | 'onFederationReady';
|
|
|
|
|
|
|
|
export class Federation {
|
|
|
|
constructor() {
|
|
|
|
this.coordinators = Object.entries(defaultFederation).reduce(
|
|
|
|
(acc: Record<string, Coordinator>, [key, value]: [string, any]) => {
|
|
|
|
acc[key] = new Coordinator(value);
|
|
|
|
return acc;
|
|
|
|
},
|
|
|
|
{},
|
|
|
|
);
|
|
|
|
this.exchange = {
|
|
|
|
...defaultExchange,
|
|
|
|
totalCoordinators: Object.keys(this.coordinators).length,
|
|
|
|
};
|
|
|
|
this.book = [];
|
|
|
|
this.hooks = {
|
|
|
|
onCoordinatorUpdate: [],
|
|
|
|
onFederationReady: [],
|
|
|
|
};
|
|
|
|
this.loading = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public coordinators: Record<string, Coordinator>;
|
|
|
|
public exchange: Exchange;
|
|
|
|
public book: PublicOrder[];
|
|
|
|
public loading: boolean;
|
|
|
|
|
2023-10-27 11:00:53 +00:00
|
|
|
public hooks: Record<FederationHooks, Array<() => void>>;
|
2023-10-27 10:01:59 +00:00
|
|
|
|
|
|
|
// Hooks
|
|
|
|
registerHook = (hookName: FederationHooks, fn: () => void): void => {
|
|
|
|
this.hooks[hookName].push(fn);
|
|
|
|
};
|
|
|
|
|
|
|
|
triggerHook = (hookName: FederationHooks): void => {
|
2023-10-27 11:00:53 +00:00
|
|
|
this.hooks[hookName]?.forEach((fn) => {
|
|
|
|
fn();
|
|
|
|
});
|
2023-10-27 10:01:59 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
onCoordinatorSaved = (shortAlias: string) => {
|
|
|
|
this.book = [...this.book, ...this.getCoordinator(shortAlias).book];
|
|
|
|
this.loading = false;
|
|
|
|
this.triggerHook('onCoordinatorUpdate');
|
|
|
|
if (Object.values(this.coordinators).every((coor) => coor.isUpdated())) {
|
|
|
|
this.updateExchange();
|
|
|
|
this.triggerHook('onFederationReady');
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Setup
|
|
|
|
start = (origin: Origin, settings: Settings, hostUrl: string): void => {
|
|
|
|
const onCoordinatorStarted = (shortAlias: string) => {
|
|
|
|
this.exchange.onlineCoordinators = this.exchange.onlineCoordinators + 1;
|
|
|
|
this.onCoordinatorSaved(shortAlias);
|
|
|
|
};
|
|
|
|
this.loading = true;
|
2023-10-27 11:00:53 +00:00
|
|
|
Object.values(this.coordinators).forEach(async (coor) => {
|
|
|
|
await coor.start(origin, settings, hostUrl, onCoordinatorStarted);
|
|
|
|
});
|
2023-10-27 10:01:59 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
update = (): void => {
|
|
|
|
this.loading = false;
|
2023-10-27 11:00:53 +00:00
|
|
|
Object.values(this.coordinators).forEach(async (coor) => {
|
|
|
|
await coor.update(() => {
|
2023-10-27 10:01:59 +00:00
|
|
|
this.onCoordinatorSaved(coor.shortAlias);
|
2023-10-27 11:00:53 +00:00
|
|
|
});
|
|
|
|
});
|
2023-10-27 10:01:59 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
updateExchange = () => {
|
|
|
|
this.exchange.info = updateExchangeInfo(this);
|
|
|
|
};
|
|
|
|
|
|
|
|
// Fetchs
|
|
|
|
fetchRobot = async (garage: Garage, slot: number): Promise<void> => {
|
|
|
|
Object.values(this.coordinators).forEach((coor) => {
|
|
|
|
coor.fecthRobot(garage, slot);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
fetchOrder = async (currentOrder: CurrentOrder, robot: Robot): Promise<CurrentOrder | null> => {
|
|
|
|
if (currentOrder.shortAlias !== null) {
|
|
|
|
const coordinator = this.coordinators[currentOrder.shortAlias];
|
|
|
|
if (coordinator && currentOrder.id !== null) {
|
|
|
|
const newOrber = await coordinator.fetchOrder(currentOrder.id, robot);
|
|
|
|
|
|
|
|
return {
|
|
|
|
...currentOrder,
|
|
|
|
order: newOrber,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return currentOrder;
|
|
|
|
};
|
|
|
|
|
2023-10-27 11:00:53 +00:00
|
|
|
// Coordinators
|
2023-10-27 10:01:59 +00:00
|
|
|
getCoordinator = (shortAlias: string): Coordinator => {
|
|
|
|
return this.coordinators[shortAlias];
|
|
|
|
};
|
|
|
|
|
2023-10-27 10:40:42 +00:00
|
|
|
disableCoordinator = (shortAlias: string) => {
|
2023-10-27 10:01:59 +00:00
|
|
|
this.coordinators[shortAlias].disable();
|
2023-11-01 12:18:00 +00:00
|
|
|
this.triggerHook('onCoordinatorUpdate');
|
2023-10-27 10:01:59 +00:00
|
|
|
};
|
|
|
|
|
2023-10-27 10:40:42 +00:00
|
|
|
enableCoordinator = (shortAlias: string) => {
|
2023-11-01 12:18:00 +00:00
|
|
|
this.coordinators[shortAlias].enable(() => {
|
|
|
|
this.triggerHook('onCoordinatorUpdate');
|
|
|
|
});
|
2023-10-27 10:01:59 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
export default Federation;
|