web_lib

Common web application libraries
git clone https://radroots.dev/git/web_lib.git
Log | Files | Refs | LICENSE

meshnet.ts (3014B)


      1 import { ble_message_text } from "./messages.js";
      2 import type { BleMessage } from "./types.js";
      3 
      4 export type BleMeshnetProfile = {
      5     display_name: string;
      6     device_label: string;
      7 };
      8 
      9 export type BleMeshnetPacketProfile = {
     10     type: "meshnet.profile.v1";
     11     profile: BleMeshnetProfile;
     12     timestamp_ms: number;
     13 };
     14 
     15 export type BleMeshnetPacketChat = {
     16     type: "meshnet.chat.v1";
     17     message_id: string;
     18     profile: BleMeshnetProfile;
     19     text: string;
     20     timestamp_ms: number;
     21 };
     22 
     23 export type BleMeshnetPacket = BleMeshnetPacketProfile | BleMeshnetPacketChat;
     24 
     25 const is_record = (value: unknown): value is Record<string, unknown> =>
     26     typeof value === "object" && value !== null && !Array.isArray(value);
     27 
     28 const is_string = (value: unknown): value is string => typeof value === "string";
     29 
     30 const is_number = (value: unknown): value is number =>
     31     typeof value === "number" && Number.isFinite(value);
     32 
     33 const is_profile = (value: unknown): value is BleMeshnetProfile => {
     34     if (!is_record(value)) return false;
     35     return is_string(value.display_name) && is_string(value.device_label);
     36 };
     37 
     38 const is_packet_profile = (value: unknown): value is BleMeshnetPacketProfile => {
     39     if (!is_record(value)) return false;
     40     if (value.type !== "meshnet.profile.v1") return false;
     41     if (!is_profile(value.profile)) return false;
     42     if (!is_number(value.timestamp_ms)) return false;
     43     return true;
     44 };
     45 
     46 const is_packet_chat = (value: unknown): value is BleMeshnetPacketChat => {
     47     if (!is_record(value)) return false;
     48     if (value.type !== "meshnet.chat.v1") return false;
     49     if (!is_string(value.message_id)) return false;
     50     if (!is_profile(value.profile)) return false;
     51     if (!is_string(value.text)) return false;
     52     if (!is_number(value.timestamp_ms)) return false;
     53     return true;
     54 };
     55 
     56 export const ble_meshnet_packet_profile = (
     57     profile: BleMeshnetProfile,
     58     timestamp_ms: number,
     59 ): BleMeshnetPacketProfile => {
     60     return {
     61         type: "meshnet.profile.v1",
     62         profile,
     63         timestamp_ms,
     64     };
     65 };
     66 
     67 export const ble_meshnet_packet_chat = (
     68     profile: BleMeshnetProfile,
     69     text: string,
     70     message_id: string,
     71     timestamp_ms: number,
     72 ): BleMeshnetPacketChat => {
     73     return {
     74         type: "meshnet.chat.v1",
     75         message_id,
     76         profile,
     77         text,
     78         timestamp_ms,
     79     };
     80 };
     81 
     82 export const ble_meshnet_message_from_packet = (
     83     packet: BleMeshnetPacket,
     84 ): string => {
     85     return JSON.stringify(packet);
     86 };
     87 
     88 export const ble_meshnet_packet_from_text = (
     89     text: string,
     90 ): BleMeshnetPacket | undefined => {
     91     let parsed: unknown;
     92     try {
     93         parsed = JSON.parse(text);
     94     } catch {
     95         return;
     96     }
     97     if (is_packet_profile(parsed)) return parsed;
     98     if (is_packet_chat(parsed)) return parsed;
     99 };
    100 
    101 export const ble_meshnet_packet_from_message = (
    102     message: BleMessage,
    103 ): BleMeshnetPacket | undefined => {
    104     const text = ble_message_text(message.bytes);
    105     if (!text) return;
    106     return ble_meshnet_packet_from_text(text);
    107 };