Karolis' playground dv-svelte / master src / lib / dvSwitchControl.ts
master

Tree @master (Download .tar.gz)

dvSwitchControl.ts @masterraw · history · blame

import { writable, type Writable } from "svelte/store";
import type { SwitchController } from "./switchControl";



function handleUpdates(baseURL: string, uuid: string, callback: (e: boolean[]) => void): () => void {
    let done = false;
    (async () => {
        while (!done) {
            const t = await (await fetch(`${baseURL}/updates/${uuid}`)).json()

            if (t.junctions) {
                callback((t.junctions as number[]).map(x => x == 1))
            }
        }
    })()
    return () => { done = true }
}

async function setSwitch(baseURL: string, id: number, state: boolean) {
    await fetch(`${baseURL}/junction/${id}/set`, {
        method: "PUT",
        body: JSON.stringify(state)
    })
}

function uuidv4() {
    return [1e7, 1e3, 4e3, 8e3, 1e11].join("-").replace(/[018]/g, c =>
        (c as any ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> (c as any) / 4).toString(16)
    );
}

export interface CancelableSwitchController extends SwitchController {
    done(): void
}


export async function RemoteDispatchSwitchController(baseURL: string): Promise<CancelableSwitchController> {
    const resp = await fetch(`${baseURL}/junction`)

    if (!resp.ok) {
        throw "something's wrong yo";
    }

    const t = await resp.json() as { state: number }[]


    const swtichSet = t.map(x => writable<boolean>(x.state == 1))
    const sessionId = uuidv4()

    let locked = true

    swtichSet.forEach((element, i) => {
        var captured = i
        element.subscribe((v) => {
            if (locked) {
                return
            }
            setSwitch(baseURL, captured, v)
        })
    });


    const kill = handleUpdates(baseURL, sessionId, (e) => {
        locked = true
        swtichSet.forEach((x, idx) => x.set(e[idx]))
        locked = false
    })
    locked = false

    return {
        done: kill,
        set(id: number, state: boolean) {
            swtichSet[id].set(state)
        },
        getStore(id: number): Writable<boolean> {
            return swtichSet[id]
        }
    }
}