neweb
Version:
[![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Dependency Status][daviddm-image]][daviddm-url] [![Coverage percentage][coveralls-image]][coveralls-url] [ • 4.35 kB
text/typescript
import o from "onemitter";
import { IHistoryContext, IPage, ISeanceDumpInfo } from "./..";
import {
IRemoteFrameControllerDataParams,
IRemoteFrameControllerDispatchParams, IRemoteNewPageParams,
} from "./../common";
import ClientApp from "./ClientApp";
import ClientPageMetaManager from "./ClientPageMetaManager";
import ClientPageRenderer from "./ClientPageRenderer";
export interface IClientSeanceConfig {
seanceId: string;
socket: SocketIOClient.Socket;
}
export interface IClientSeanceConfig {
app: ClientApp;
pageRenderer: ClientPageRenderer;
pageMetaManager: ClientPageMetaManager;
}
class ClientSeance {
protected seansStatusEmitter = o();
protected networkStatusEmitter = o<string>();
protected seansId: string;
protected historyContext: IHistoryContext;
constructor(protected config: IClientSeanceConfig) { }
public async initialize(initialInfo: ISeanceDumpInfo) {
this.seansId = initialInfo.seanceId;
this.seansStatusEmitter.emit("initializing");
this.networkStatusEmitter.emit(this.config.socket.connected ? "connected" : "disconnected");
this.historyContext = {
push: (url: string) => {
history.pushState(url, "", url);
this.navigate(url);
},
replace: (url: string) => {
history.replaceState(url, "", url);
this.navigate(url);
},
};
this.config.pageRenderer.setMethods({
dispatch: (params: IRemoteFrameControllerDispatchParams) => this.dispatch(params),
navigate: (url: string) => this.navigate(url),
seansStatusEmitter: this.seansStatusEmitter,
networkStatusEmitter: this.networkStatusEmitter,
historyContext: this.historyContext,
});
if (initialInfo.page) {
await this.loadPage(initialInfo.page);
await this.config.pageRenderer.loadPage(initialInfo.page);
await this.config.pageRenderer.initialize();
}
this.config.socket.on("connect", () => this.networkStatusEmitter.emit("connected"));
this.config.socket.on("connect_error", () => this.networkStatusEmitter.emit("disconnected"));
this.config.socket.on("connect_timeout", () => this.networkStatusEmitter.emit("disconnected"));
this.config.socket.on("error", () => this.networkStatusEmitter.emit("disconnected"));
this.config.socket.on("reconnect", () => this.networkStatusEmitter.emit("connected"));
this.config.socket.on("reconnect_attempt", () => this.networkStatusEmitter.emit("connecting"));
this.config.socket.on("reconnect_error", () => this.networkStatusEmitter.emit("disconnected"));
this.config.socket.on("reconnect_failed", () => this.networkStatusEmitter.emit("disconnected"));
this.config.socket.on("frame-controller-data", (params: IRemoteFrameControllerDataParams) => {
this.config.pageRenderer.emitFrameControllerData(params);
});
this.config.socket.on("new-page", async (params: IRemoteNewPageParams) => {
await this.config.pageRenderer.newPage(params.page);
history.replaceState(params.page.url, params.page.title || "", params.page.url);
this.config.pageMetaManager.update(params.page);
this.seansStatusEmitter.emit("ready");
});
await new Promise((resolve) => {
this.config.socket.emit("initialize", { seanceId: this.config.seanceId }, resolve);
});
history.replaceState(window.location.href, "", window.location.href);
window.onpopstate = (e) => {
this.navigate(e.state);
};
this.seansStatusEmitter.emit("ready");
}
public navigate(url: string) {
this.seansStatusEmitter.emit("navigating");
this.config.socket.emit("navigate", { url });
}
public async dispatch(params: IRemoteFrameControllerDispatchParams) {
await new Promise((resolve) => {
this.config.socket.emit("frame-controller-dispatch", params, resolve);
});
}
protected async loadPage(page: IPage) {
await this.config.app.getPageClass(page);
}
}
export default ClientSeance;