mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-01-10 00:47:45 +08:00
4334e8a58e
Co-authored-by: José Valim <jose.valim@dashbit.co>
95 lines
2.2 KiB
JavaScript
95 lines
2.2 KiB
JavaScript
import { Socket } from "phoenix";
|
|
|
|
const csrfToken = document
|
|
.querySelector("meta[name='csrf-token']")
|
|
.getAttribute("content");
|
|
|
|
const socket = new Socket(window.LIVEBOOK_BASE_URL_PATH + "/socket", {
|
|
params: { _csrf_token: csrfToken },
|
|
});
|
|
|
|
let channel = null;
|
|
|
|
/**
|
|
* Returns channel used for all JS views in the current session.
|
|
*/
|
|
export function getChannel(sessionToken) {
|
|
if (!channel) {
|
|
socket.connect();
|
|
channel = socket.channel("js_view", { session_token: sessionToken });
|
|
channel.join();
|
|
}
|
|
|
|
return channel;
|
|
}
|
|
|
|
/**
|
|
* Leaves the JS views channel tied to the current session.
|
|
*/
|
|
export function leaveChannel() {
|
|
if (channel) {
|
|
channel.leave();
|
|
channel = null;
|
|
socket.disconnect();
|
|
}
|
|
}
|
|
|
|
// Encoding/decoding of channel payloads
|
|
|
|
export function transportEncode(meta, payload) {
|
|
if (
|
|
Array.isArray(payload) &&
|
|
payload[1] &&
|
|
payload[1].constructor === ArrayBuffer
|
|
) {
|
|
const [info, buffer] = payload;
|
|
return encode([meta, info], buffer);
|
|
} else {
|
|
return { root: [meta, payload] };
|
|
}
|
|
}
|
|
|
|
export function transportDecode(raw) {
|
|
if (raw.constructor === ArrayBuffer) {
|
|
const [[meta, info], buffer] = decode(raw);
|
|
return [meta, [info, buffer]];
|
|
} else {
|
|
const {
|
|
root: [meta, payload],
|
|
} = raw;
|
|
return [meta, payload];
|
|
}
|
|
}
|
|
|
|
const HEADER_LENGTH = 4;
|
|
|
|
function encode(meta, buffer) {
|
|
const encoder = new TextEncoder();
|
|
const metaArray = encoder.encode(JSON.stringify(meta));
|
|
|
|
const raw = new ArrayBuffer(
|
|
HEADER_LENGTH + metaArray.byteLength + buffer.byteLength
|
|
);
|
|
const view = new DataView(raw);
|
|
|
|
view.setUint32(0, metaArray.byteLength);
|
|
new Uint8Array(raw, HEADER_LENGTH, metaArray.byteLength).set(metaArray);
|
|
new Uint8Array(raw, HEADER_LENGTH + metaArray.byteLength).set(
|
|
new Uint8Array(buffer)
|
|
);
|
|
|
|
return raw;
|
|
}
|
|
|
|
function decode(raw) {
|
|
const view = new DataView(raw);
|
|
const metaArrayLength = view.getUint32(0);
|
|
|
|
const metaArray = new Uint8Array(raw, HEADER_LENGTH, metaArrayLength);
|
|
const buffer = raw.slice(HEADER_LENGTH + metaArrayLength);
|
|
|
|
const decoder = new TextDecoder();
|
|
const meta = JSON.parse(decoder.decode(metaArray));
|
|
|
|
return [meta, buffer];
|
|
}
|