UNPKG

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] [![experimental](http://badges.github.io/stability-badges/dist/ex

197 lines (193 loc) 7.59 kB
import isAbsoluteUrl = require("is-absolute-url"); import { IRemoteFrameControllerDispatchParams } from "../common"; import { IPageFrame, IRequest, IRoute, IRoutePage, NewebGlobalStore } from "./.."; import { createController, disposeController, getController, getControllerData } from "./controllers"; import PageComparator from "./PageComparator"; import PageCreator from "./PageCreator"; import { getSessionContext } from "./sessions"; export async function navigateSeance(store: NewebGlobalStore, seanceId: string, url: string) { const router = await store.getObject("router", seanceId); const request = await store.get("seance-request", seanceId); router.navigate({ request: { ...request, url, }, }); } export async function onNewRoute(store: NewebGlobalStore, seanceId: string, route: IRoute) { if (route.type === "redirect") { const isAbsolute = isAbsoluteUrl(route.url); const socketId = await store.get("seance-socket", seanceId); if (socketId && isAbsolute) { const socket = await store.getObject("socket", socketId); socket.emit("redirect", route.url); return; } await store.dispatch("seance-navigate", { type: "data", dataType: "seance", id: seanceId, }, { seanceId }, route.url); return; } if (route.type === "page") { await loadSeancePage(store, seanceId, route.page); } } export async function createSeance(store: NewebGlobalStore, params: { request: IRequest; sessionId: string }) { const seanceId = params.sessionId + Math.round(Math.random() * 100000).toString(); await store.create("seance", seanceId, { type: "data", dataType: "session", id: params.sessionId, }, { sessionId: params.sessionId, }); await initializeSeance(store, { seanceId, sessionId: params.sessionId, request: params.request, }); return seanceId; } export async function initializeSeance(store: NewebGlobalStore, params: { seanceId: string; sessionId: string; request: IRequest; }) { const app = await store.getObject("app", "default"); const RouterClass = await app.getRouterClass(); const router = new RouterClass({ session: await getSessionContext(store, { type: "data", dataType: "seance", id: params.seanceId, }, params.sessionId), context: await app.getContext(), request: params.request, }); await store.create("seance-request", params.seanceId, { type: "data", dataType: "seance", id: params.seanceId, }, params.request); await store.setObject("router", params.seanceId, { type: "data", dataType: "seance", id: params.seanceId, }, router); router.onNewRoute(await store.action("new-router-route", { type: "object", objectType: "router", id: params.seanceId, }, { seanceId: params.seanceId, })); } export async function loadSeancePage(store: NewebGlobalStore, seanceId: string, routePage: IRoutePage) { if (await store.has("seance-current-page", seanceId)) { await replaceSeancePage(store, seanceId, routePage); } else { await createSeancePage(store, seanceId, routePage); } } async function createSeancePage(store: NewebGlobalStore, seanceId: string, routePage: IRoutePage) { const pageCreator = new PageCreator({ app: await store.getObject("app", "default") }); const page = await pageCreator.createPage(routePage); await Promise.all(page.frames.map(async (frame) => createFrameSeanceController(store, seanceId, frame))); if (routePage.afterLoad) { await routePage.afterLoad(page); } await store.create("seance-current-page", seanceId, { type: "data", dataType: "seance", id: seanceId, }, page); } async function createFrameSeanceController(store: NewebGlobalStore, seanceId: string, frame: IPageFrame) { const seance = await store.get("seance", seanceId); const app = await store.getObject("app", "default"); await createController(store, { frameId: frame.frameId, context: await app.getContext(), frameName: frame.frameName, params: frame.params, navigate: await store.action("seance-navigate", { type: "data", dataType: "seance", id: seanceId, }, { seanceId }), seanceId, sessionId: seance.sessionId, }); const data = await getControllerData(store, frame.frameId); frame.data = data; } async function replaceSeancePage(store: NewebGlobalStore, seanceId: string, routePage: IRoutePage) { const app = await store.getObject("app", "default"); const pageCreator = new PageCreator({ app, }); const page = await pageCreator.createPage(routePage); const comparator = new PageComparator(); const currentPage = await store.get("seance-current-page", seanceId); const info = comparator.getCompareInfo(currentPage, page); // TODO not waiting await Promise.all(info.frameidsForRemoving.map(async (frameId) => disposeController(store, frameId))); await Promise.all(info.newFrames.map(async (frame) => createFrameSeanceController(store, seanceId, frame))); await Promise.all(info.frameForChangeParams.map(async (frame) => { const controller = await getController(store, frame.frameId); await controller.onChangeParams(frame.params); })); if (routePage.afterLoad) { await routePage.afterLoad(info.page); } await store.set("seance-current-page", seanceId, info.page); const socketId = await store.get("seance-socket", seanceId); if (socketId) { if (await store.hasObject("socket", socketId)) { const socket = await store.getObject("socket", socketId); socket.emit("new-page", { page: info.page, }); } } } export async function restoreSeance() { // } export async function connectSeance(store: NewebGlobalStore, { seanceId, socketId }: { seanceId: string; sessionId: string; socketId: string; }) { await store.create("seance-socket", seanceId, { type: "data", dataType: "seance", id: seanceId, }, socketId); const socket = await store.getObject("socket", socketId); const currentPage = await store.get("seance-current-page", seanceId); await Promise.all(currentPage.frames.map(async (frame) => { socket.emit("frame-controller-data", { frameId: frame.frameId, data: await getControllerData(store, frame.frameId), }); })); socket.on("frame-controller-dispatch", (async ( stor: NewebGlobalStore, sockId: string, params: IRemoteFrameControllerDispatchParams, cb: any) => { await stor.dispatch("socket-frame-controller-dispatch", { type: "object", objectType: "socket", id: sockId, }, { socketId: sockId }, params); cb(); }).bind(undefined, store, socketId)); socket.on("navigate", await store.action("socket-navigate", { type: "object", objectType: "socket", id: socketId, }, { seanceId })); }