about summary refs log tree commit diff
path: root/assets/src
diff options
context:
space:
mode:
authorMelonai <einebeere@gmail.com>2021-05-31 01:47:38 +0200
committerMelonai <einebeere@gmail.com>2021-05-31 01:47:38 +0200
commit8f1f90c3e7d836a23f1cd09617c2a0fcfac3f3f4 (patch)
tree7359e054d13a054a661c1584dae20d0698fc4c84 /assets/src
parente0cabfea7c7b442acd3636e7495958b87e253176 (diff)
downloadrook-8f1f90c3e7d836a23f1cd09617c2a0fcfac3f3f4.tar.zst
rook-8f1f90c3e7d836a23f1cd09617c2a0fcfac3f3f4.zip
Socket connection with managed state
Diffstat (limited to 'assets/src')
-rw-r--r--assets/src/components/IncomingRequests.svelte17
-rw-r--r--assets/src/components/Request.svelte10
-rw-r--r--assets/src/network/channel/connection.ts69
-rw-r--r--assets/src/network/channel/request.ts14
-rw-r--r--assets/src/network/channel/share.ts17
-rw-r--r--assets/src/network/channel/socket.ts59
-rw-r--r--assets/src/network/socket.ts44
7 files changed, 170 insertions, 60 deletions
diff --git a/assets/src/components/IncomingRequests.svelte b/assets/src/components/IncomingRequests.svelte
index 1db50af..bf08ffe 100644
--- a/assets/src/components/IncomingRequests.svelte
+++ b/assets/src/components/IncomingRequests.svelte
@@ -1,18 +1,17 @@
 <script lang="ts">
-    import { getToken, joinShareChannel } from "../network/socket";
+    import { getOwnToken, start, Type } from "../network/channel/connection";
+
     import requests from "../stores/requests";
 
-    const startConnection = async () => {
-        const token = await getToken();
-        joinShareChannel(token);
-        return token;
-    };
+    const startPromise = start(Type.SHARE);
+
+    // TODO: Switch to store-based state updates.
 </script>
 
-{#await startConnection()}
+{#await startPromise}
     <h3>Fetching token...</h3>
-{:then token}
-    <h3>Your token is <b>{token}</b>.</h3>
+{:then}
+    <h3>Your token is <b>{getOwnToken()}</b>.</h3>
 
     {#each $requests as request}
         <p>{JSON.stringify(request)}</p>
diff --git a/assets/src/components/Request.svelte b/assets/src/components/Request.svelte
index 134c4d5..0c0b111 100644
--- a/assets/src/components/Request.svelte
+++ b/assets/src/components/Request.svelte
@@ -1,13 +1,9 @@
 <script lang="ts">
-    import { getToken, joinRequestChannel } from "../network/socket";
-    import getShareToken from "../utils/getShareToken";
+    import { start, Type } from "../network/channel/connection";
 
-    const startConnection = async () => {
-        const token = await getToken();
-        joinRequestChannel(token, getShareToken());
-    };
+    // TODO: Switch to store-based state updates.
 
-    startConnection();
+    start(Type.REQUEST);
 </script>
 
 <main>
diff --git a/assets/src/network/channel/connection.ts b/assets/src/network/channel/connection.ts
new file mode 100644
index 0000000..52d85d1
--- /dev/null
+++ b/assets/src/network/channel/connection.ts
@@ -0,0 +1,69 @@
+import { Channel, Push, Socket } from "phoenix";
+import { startRequest } from "./request";
+import { startShare } from "./share";
+import { connectSocket, fetchToken } from "./socket";
+
+export enum Type {
+    NONE,
+    REQUEST,
+    SHARE,
+}
+
+enum ConnectionState {
+    CONNECTING_SOCKET,
+    FETCHING_TOKEN,
+    CONNECTING_CHANNEL,
+
+    CONNECTED,
+}
+
+export type Connection = {
+    socket: Socket;
+    channel: Channel | null;
+    token: string | null;
+    state: ConnectionState;
+    type: Type;
+};
+
+const connection: Connection = {
+    socket: new Socket("/socket", {}),
+    channel: null,
+    token: null,
+    state: ConnectionState.CONNECTING_SOCKET,
+    type: Type.NONE,
+};
+
+export async function start(type: Type.REQUEST | Type.SHARE) {
+    connection.type = type;
+
+    await connectSocket(connection.socket);
+
+    updateState(ConnectionState.FETCHING_TOKEN);
+    connection.token = await fetchToken(connection.socket);
+
+    updateState(ConnectionState.CONNECTING_CHANNEL);
+    type === Type.SHARE
+        ? await startShare(connection)
+        : await startRequest(connection);
+}
+
+export function send(event: string, data: any): Push {
+    if (connection.state !== ConnectionState.CONNECTED) {
+        throw new Error("There is no connection yet.");
+    }
+
+    return connection.channel.push(event, data);
+}
+
+export function getOwnToken(): string {
+    if (connection.state <= ConnectionState.FETCHING_TOKEN) {
+        throw new Error("There is no token yet.");
+    }
+
+    return connection.token;
+}
+
+function updateState(state: ConnectionState) {
+    // TODO: Notify state listeners
+    connection.state = state;
+}
diff --git a/assets/src/network/channel/request.ts b/assets/src/network/channel/request.ts
new file mode 100644
index 0000000..801eee1
--- /dev/null
+++ b/assets/src/network/channel/request.ts
@@ -0,0 +1,14 @@
+import getShareToken from "../../utils/getShareToken";
+import type { Connection } from "./connection";
+import { joinRequestChannel } from "./socket";
+
+export async function startRequest(connection: Connection) {
+    const requestChannel = await joinRequestChannel(
+        connection.socket,
+        connection.token,
+        getShareToken()
+    );
+    connection.channel = requestChannel;
+
+    // TODO: Handle incoming messages from the request channel
+}
diff --git a/assets/src/network/channel/share.ts b/assets/src/network/channel/share.ts
new file mode 100644
index 0000000..10a34fa
--- /dev/null
+++ b/assets/src/network/channel/share.ts
@@ -0,0 +1,17 @@
+import requests from "../../stores/requests";
+import type { Connection } from "./connection";
+import { joinShareChannel } from "./socket";
+
+export async function startShare(connection: Connection) {
+    const shareChannel = await joinShareChannel(
+        connection.socket,
+        connection.token
+    );
+    connection.channel = shareChannel;
+
+    shareChannel.on("new_request", onNewRequest);
+}
+
+function onNewRequest(data) {
+    requests.addRequest(data);
+}
diff --git a/assets/src/network/channel/socket.ts b/assets/src/network/channel/socket.ts
new file mode 100644
index 0000000..7d14842
--- /dev/null
+++ b/assets/src/network/channel/socket.ts
@@ -0,0 +1,59 @@
+import type { Channel, Socket } from "phoenix";
+
+export function connectSocket(socket: Socket): Promise<void> {
+    return new Promise((resolve, _reject) => {
+        socket.connect();
+        socket.onOpen(() => {
+            resolve();
+        });
+    });
+}
+
+export function fetchToken(socket: Socket): Promise<string> {
+    let tokenChannel = socket.channel("token", {});
+    return new Promise((resolve, reject) => {
+        tokenChannel
+            .join()
+            .receive("ok", () => {
+                tokenChannel
+                    .push("get_token", {}, 5000)
+                    .receive("ok", ({ token }) => resolve(token))
+                    .receive("error", err => reject(err))
+                    .receive("timeout", err => reject(err));
+            })
+            .receive("error", err => reject(err));
+    });
+}
+
+export function joinShareChannel(
+    socket: Socket,
+    token: string
+): Promise<Channel> {
+    return joinChannel(socket, `share:${token}`);
+}
+
+export function joinRequestChannel(
+    socket: Socket,
+    request_token: string,
+    share_token: string
+): Promise<Channel> {
+    return joinChannel(socket, `request:${request_token}`, {
+        share: share_token,
+    });
+}
+
+function joinChannel(
+    socket: Socket,
+    topic: string,
+    opts?: object
+): Promise<Channel> {
+    let channel = socket.channel(topic, opts);
+
+    return new Promise((resolve, reject) => {
+        channel
+            .join()
+            .receive("ok", () => resolve(channel))
+            .receive("error", err => reject(err))
+            .receive("timeout", err => reject(err));
+    });
+}
diff --git a/assets/src/network/socket.ts b/assets/src/network/socket.ts
deleted file mode 100644
index 87f5b7c..0000000
--- a/assets/src/network/socket.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import { Socket } from "phoenix";
-import requests from "../stores/requests";
-
-let socket = new Socket("/socket", {});
-socket.connect();
-
-export const getToken: () => Promise<string> = () => {
-    let tokenChannel = socket.channel("token", {});
-    return new Promise((resolve, reject) => {
-        tokenChannel
-            .join()
-            .receive("ok", () => {
-                tokenChannel
-                    .push("get_token", {}, 5000)
-                    .receive("ok", ({ token }) => resolve(token))
-                    .receive("error", err => reject(err))
-                    .receive("timeout", err => reject(err));
-            })
-            .receive("error", err => reject(err));
-    });
-};
-
-export const joinShareChannel = token => {
-    let shareChannel = socket.channel(`share:${token}`);
-
-    shareChannel.on("new_request", requests.addRequest);
-
-    shareChannel
-        .join()
-        .receive("error", err =>
-            console.log("Failed joining share channel: " + JSON.stringify(err))
-        );
-};
-
-export const joinRequestChannel = (token, share) => {
-    let requestChannel = socket.channel(`request:${token}`, { share });
-
-    requestChannel
-        .join()
-        .receive("ok", () => console.log("Connected to request!"))
-        .receive("error", err =>
-            console.log("Failed joining request channel:" + JSON.stringify(err))
-        );
-};