Skip to content

Commit

Permalink
additional cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
floodfx committed Jan 26, 2022
1 parent fb74a5f commit 1f2e53c
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 218 deletions.
14 changes: 1 addition & 13 deletions src/examples/autocomplete/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import { BaseLiveViewComponent, LiveViewExternalEventListener, LiveViewInternalE
import { sendInternalMessage } from "../../server/socket/message_router";
import { WebSocket } from "ws";
import { searchByCity, searchByZip, Store } from "../live-search/data";
import { listCities, suggest } from "./data";

import { suggest } from "./data";

export interface AutocompleteContext {
zip: string;
Expand Down Expand Up @@ -150,17 +149,6 @@ export class AutocompleteLiveViewComponent extends BaseLiveViewComponent<Autocom
}
}

// handleEvent(event: "suggest-city", params: {zip: string}, socket: PhxSocket) {
// console.log("event:", event, params, socket);
// const { zip } = params;
// // wait a second to send the message
// setTimeout(() => {
// sendInternalMessage(socket, this, {type: "run_zip_search", zip });
// }, 1000);

// return { data: { zip, city: "", stores:[], matches:[], loading: true } };
// }

handleInfo(event: { type: "run_zip_search", zip: string } | { type: "run_city_search", city: string }, socket: LiveViewSocket<AutocompleteContext>) {

let stores: Store[] = [];
Expand Down
4 changes: 0 additions & 4 deletions src/examples/servers/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ export interface ServersContext {
selectedServer: Server
}

const idToWs = new Map<string, WebSocket>();

export class ServersLiveViewComponent extends BaseLiveViewComponent<ServersContext, { id: string }> {


Expand All @@ -23,15 +21,13 @@ export class ServersLiveViewComponent extends BaseLiveViewComponent<ServersConte
}

handleParams(params: { id: string; }, url: string, socket: LiveViewSocket<ServersContext>): ServersContext {
console.log("params", params);
const servers = listServers();
const selectedServer = servers.find(server => server.id === params.id) || servers[0];
return { servers, selectedServer };
}

render(context: ServersContext): LiveViewTemplate {
const { servers, selectedServer } = context;
console.log("rendering servers", servers, selectedServer);
return html`
<h1>Servers</h1>
<div id="servers">
Expand Down
4 changes: 1 addition & 3 deletions src/server/live_view_server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ export class LiveViewServer {

private _router: LiveViewRouter = {};

private _topicToPath: { [key: string]: string } = {};

constructor(options: Partial<LiveViewServerOptions>) {
this.port = options.port ?? this.port;
this.rootView = options.rootView ?? this.rootView;
Expand Down Expand Up @@ -69,7 +67,7 @@ export class LiveViewServer {
const connectionId = nanoid();
// handle ws messages
socket.on('message', message => {
onMessage(socket, message, this._topicToPath, this._router, connectionId, this.signingSecret);
onMessage(socket, message, this._router, connectionId, this.signingSecret);
});
});

Expand Down
211 changes: 13 additions & 198 deletions src/server/socket/message_router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,63 +7,47 @@ import { LiveViewComponentManager } from './component_manager';
import { LiveViewSocket } from '..';

const topicComponentManager: { [key: string]: LiveViewComponentManager } = {};
const heartbeatRouter: { [key: string]: LiveViewComponentManager } = {};

export function onMessage(ws: WebSocket, message: WebSocket.RawData, topicToPath: { [key: string]: string }, router: LiveViewRouter, connectionId: string, signingSecret: string) {
console.log("connectionId", connectionId);

// get raw message to string
const stringMsg = message.toString();
// console.log("message", stringMsg);
export function onMessage(ws: WebSocket, message: WebSocket.RawData, router: LiveViewRouter, connectionId: string, signingSecret: string) {

// parse string to JSON
const rawPhxMessage: PhxIncomingMessage<unknown> = JSON.parse(stringMsg);
// console.log("rawPhxMessage", rawPhxMessage);
const rawPhxMessage: PhxIncomingMessage<unknown> = JSON.parse(message.toString());

// rawPhxMessage must be an array with 5 elements
if (typeof rawPhxMessage === 'object' && Array.isArray(rawPhxMessage) && rawPhxMessage.length === 5) {
const [joinRef, messageRef, topic, event, payload] = rawPhxMessage;
// lookup component manager for this topic
const componentManager = topicComponentManager[topic];

switch (event) {
case "phx_join":
// assume componentManager is not defined since join creates a new component manager
onPhxJoin(ws, rawPhxMessage as PhxJoinIncoming, topicToPath, router, signingSecret);
onPhxJoin(ws, rawPhxMessage as PhxJoinIncoming, router, signingSecret, connectionId);
break;
case "heartbeat":
// heartbeat comes in as a "phoenix" topic so lookup via connectionId
let componentManager = heartbeatRouter[connectionId];
if (componentManager) {
componentManager.onHeartbeat(ws, rawPhxMessage as PhxHeartbeatIncoming);
} else {
console.log("expected component manager for topic", topic);
}
// onHeartbeat(ws, rawPhxMessage as PhxHeartbeatIncoming);
break;
case "event":
// map based on event type
const { type } = payload as PhxClickPayload | PhxFormPayload
// lookup component manager for this topic
componentManager = topicComponentManager[topic];
if (componentManager) {
componentManager.onEvent(ws, rawPhxMessage as PhxIncomingMessage<PhxClickPayload | PhxFormPayload>);
} else {
console.log("expected component manager for topic", topic);
}

// switch (type) {
// case "click":
// onPhxClickEvent(ws, rawPhxMessage as PhxClickEvent, topicToPath, router);
// break;
// case "form":
// onPhxFormEvent(ws, rawPhxMessage as PhxFormEvent, topicToPath, router);
// break;
// default:
// console.error("unhandeded event type", type);
// }
break;
case "live_patch":
componentManager = topicComponentManager[topic];
if (componentManager) {
componentManager.onLivePatch(ws, rawPhxMessage as PhxLivePatchIncoming);
} else {
console.log("expected component manager for topic", topic);
}
// onPhxLivePatch(ws, rawPhxMessage as PhxLivePatchIncoming, topicToPath, router);
break;
default:
console.error("unhandeded protocol event", event);
Expand All @@ -76,7 +60,7 @@ export function onMessage(ws: WebSocket, message: WebSocket.RawData, topicToPath
}


export function onPhxJoin(ws: WebSocket, message: PhxJoinIncoming, topicToPath: { [key: string]: string }, router: LiveViewRouter, signingSecret: string) {
export function onPhxJoin(ws: WebSocket, message: PhxJoinIncoming, router: LiveViewRouter, signingSecret: string, connectionId: string) {

// use url to route join request to component
const [joinRef, messageRef, topic, event, payload] = message;
Expand All @@ -89,176 +73,12 @@ export function onPhxJoin(ws: WebSocket, message: PhxJoinIncoming, topicToPath:
}

const componentManager = new LiveViewComponentManager(component, signingSecret);
componentManager.handleJoin(ws, message);
topicComponentManager[topic] = componentManager;
heartbeatRouter[connectionId] = componentManager;
componentManager.handleJoin(ws, message);


// // // update topicToPath
// topicToPath[topic] = url.pathname;

// // extract params, session and socket from payload
// const { params: payloadParams, session: payloadSession, static: payloadStatic } = payload;
// console.log("payloadParams", payloadParams, payloadSession, payloadStatic);

// // TODO - use session from cookie
// // const session = jwt.verify(payloadSession, signingSecret) as any;

// const phxSocket: PhxSocket = {
// id: topic,
// connected: true, // websocket is connected
// ws, // the websocket
// }
// // pass in phx_join payload params, session, and socket
// let ctx = component.mount(payloadParams, {}, phxSocket);

// // attempt to call handleParams if it exists
// if ((component as any).handleParams) {
// // @ts-ignore - searchParams returns an entries but types are wrong
// const urlParams = Object.fromEntries(url.searchParams);
// // @ts-ignore
// const hpCtx = component.handleParams(urlParams, urlString, { id: topic });
// // merge contexts
// if (Object.keys(hpCtx.data).length > 0) {
// ctx = { ...ctx, ...hpCtx };
// }
// }

// // now render this component
// const view = component.render(ctx);

// // send full view parts (statics & dynaimcs back)
// const replyPayload = {
// response: {
// rendered: view.partsTree()
// },
// status: "ok"
// }

// sendPhxReply(ws, newPhxReply(message, replyPayload));
}



// export function onPhxLivePatch(ws: WebSocket, message: PhxLivePatchIncoming, topicToPath: { [key: string]: string }, router: LiveViewRouter) {

// const [joinRef, messageRef, topic, event, payload] = message;

// // route using topic to lookup path
// const path = topicToPath[topic];
// const component = router[path];
// if (!component) {
// console.error("no mapping found topic", topic);
// return;
// }

// // check if component has event handler
// // this type of message goes to handleParams
// if (!(component as any).handleParams) {
// console.warn("no event handler for component", component);
// return;
// }

// const { url: urlString } = payload;
// const url = new URL(urlString);

// // @ts-ignore - searchParams returns an entries but types are wrong
// const params = Object.fromEntries(url.searchParams);
// // TODO update types to have optional handleEvent???
// // alternatively have a abstract class defining empty handleParams?
// // @ts-ignore
// const ctx = component.handleParams(params, urlString, { id: topic });

// const view = component.render(ctx);

// const replyPayload = {
// response: {
// diff: {
// ...view.partsTree(false)
// }
// },
// status: "ok"
// }

// sendPhxReply(ws, newPhxReply(message, replyPayload));
// }

// export function onPhxFormEvent(ws: WebSocket, message: PhxFormEvent, topicToPath: { [key: string]: string }, router: LiveViewRouter) {

// const [joinRef, messageRef, topic, event, payload] = message;

// // route using topic to lookup path
// const path = topicToPath[topic];
// const component = router[path];
// if (!component) {
// console.error("no mapping found topic", topic);
// return;
// }

// // check if component has event handler
// if (!(component as any).handleEvent) {
// console.warn("no event handler for component", component);
// return;
// }

// const { type, event: payloadEvent, value } = payload;
// const params = new URLSearchParams(value);
// // TODO update types to have optional handleEvent???
// // @ts-ignore
// const ctx = component.handleEvent(payloadEvent, Object.fromEntries(params), { id: topic });

// const view = component.render(ctx);

// const replyPayload = {
// response: {
// diff: {
// ...view.partsTree(false)
// }
// },
// status: "ok"
// }

// sendPhxReply(ws, newPhxReply(message, replyPayload));
// }

// export function onPhxClickEvent(ws: WebSocket, message: PhxClickEvent, topicToPath: { [key: string]: string }, router: LiveViewRouter) {

// const [joinRef, messageRef, topic, event, payload] = message;

// // route using topic to lookup path
// const path = topicToPath[topic];
// const component = router[path];
// if (!component) {
// console.error("no mapping found topic", topic);
// return;
// }

// // check if component has event handler
// if (!(component as any).handleEvent) {
// console.warn("no event handler for component", component);
// return;
// }

// const { type, event: payloadEvent, value } = payload;
// // TODO update types to have optional handleEvent???
// // @ts-ignore
// const ctx = component.handleEvent(payloadEvent, value, { id: topic });

// const view = component.render(ctx);

// const replyPayload = {
// response: {
// diff: {
// ...view.partsTree(false)
// }
// },
// status: "ok"
// }

// sendPhxReply(ws, newPhxReply(message, replyPayload));
// }



export function sendInternalMessage(socket: LiveViewSocket<unknown>, component: LiveViewComponent<any, any>, event: any, payload?: any) {

// check if component has event handler
Expand All @@ -283,11 +103,6 @@ export function sendInternalMessage(socket: LiveViewSocket<unknown>, component:
sendPhxReply(socket.ws!, reply);
}

// export function onHeartbeat(ws: WebSocket, message: PhxHeartbeatIncoming) {
// // TODO keep track of last heartbeat and disconnect if no heartbeat for a while?
// sendPhxReply(ws, newHeartbeatReply(message));
// }


function sendPhxReply(ws: WebSocket, reply: PhxOutgoingMessage<any>) {
ws.send(JSON.stringify(reply), { binary: false }, (err: any) => {
Expand Down

0 comments on commit 1f2e53c

Please sign in to comment.