@drawbridgesolutions/js-sdk
    Preparing search index...

    @drawbridgesolutions/js-sdk

    drawbridge-sdk

    JavaScript SDK for connecting screen clients to a Drawbridge server.

    Drawbridge manages interactive experiences made up of named screens (display panels). Each screen connects to the Drawbridge server over a persistent WebSocket. The server sends commands to change what a screen is displaying; screens report state back (puzzle results, scores, answers) by setting variables.

    The SDK handles connection lifecycle automatically: it reconnects after transient network interruptions and buffers outgoing messages while the link is down.

    The fastest way to start a custom screen is the create-screen CLI. It scaffolds a Vite project, installs this SDK, and wires up a DrawbridgeConnection for you:

    npm create @drawbridgesolutions/screen@latest
    # or: pnpm create @drawbridgesolutions/screen
    # or: yarn create @drawbridgesolutions/screen

    The CLI prompts for a package manager, screen name, and template (React, TypeScript, or JavaScript), then generates a ready-to-run project with the connection already set up. If you'd rather wire things up manually, follow the installation and quick start below.

    npm install @drawbridgesolutions/js-sdk
    
    import { DrawbridgeConnection } from "@drawbridgesolutions/js-sdk";

    const connection = new DrawbridgeConnection({
    screen_name: "lobby-display",
    });

    connection.onScreenChange((screen) => {
    console.log("Active screen:", screen);
    });

    Opens a WebSocket to the Drawbridge server for the named screen. The connection is established immediately and will auto-reconnect if dropped.

    • screen_name — unique identifier for this screen, must exactly match the name configured in the Drawbridge project and playbook settings.

    Registers a function to call whenever the server sends a screen-change command. Only one callback is active at a time — calling this again replaces the previous one.

    The callback receives the new screen identifier as a string (e.g. "0", "1", "intro"), as defined in the Drawbridge project configuration. It also fires on reconnect if the server re-sends the current state.

    connection.onScreenChange((screen) => {
    switch (screen) {
    case "idle":
    showIdleVideo();
    break;
    case "intro":
    showIntroVideo();
    break;
    case "puzzle":
    showPuzzleScreen();
    break;
    default:
    showIdleVideo();
    }
    });

    The identifier of the most recently received screen, or null if no screen-change command has arrived yet. Updated synchronously on each incoming event — safe to read at any time.

    if (connection.getCurrentScreen === "puzzle-active") {
    enableInputControls();
    }

    Registers a function to call whenever the server sends a timer update. Only one callback is active at a time — calling this again replaces the previous one.

    The callback receives the number of seconds left in the game as a number.

    connection.onTimerChange((secondsRemaining) => {
    const minutes = Math.floor(secondsRemaining / 60);
    const seconds = secondsRemaining % 60;
    clock.textContent = `${minutes}:${seconds.toString().padStart(2, "0")}`;

    if (secondsRemaining <= 10) {
    document.body.classList.add("time-critical");
    }
    });

    The number of seconds left in the game as of the most recent timer update, or null if no timer command has arrived yet. Updated synchronously on each incoming event — safe to read at any time.

    if (connection.getCurrentTimer !== null && connection.getCurrentTimer <= 0) {
    endExperience();
    }

    Registers a function to call whenever the server pauses or resumes the game. Only one callback is active at a time — calling this again replaces the previous one.

    The callback receives a boolean: true when the game is paused and false when it resumes.

    connection.onGamePause((paused) => {
    const video = document.getElementById("clip") as HTMLVideoElement;
    if (paused) {
    video.pause();
    } else {
    video.play();
    }
    });

    Whether the game is currently paused as of the most recent paused update, or null if no paused command has arrived yet. Updated synchronously on each incoming event — safe to read at any time.

    if (connection.getIsPaused) {
    return;
    }

    true when the WebSocket readyState is OPEN. false during the initial connect, a reconnect pause, or after close() is called. Messages sent while disconnected are buffered and delivered once the link is restored.

    setInterval(() => {
    statusDot.className = connection.isConnected ? "dot-green" : "dot-red";
    }, 1000);

    Sends a variable update to the server. Variables are the primary way a screen reports state — signalling a completed puzzle, submitting an answer, reporting a score. The server can use these values to trigger transitions, unlock other screens, or drive game logic.

    • variableName — must match the variable name in the Drawbridge playbook settings exactly (case-sensitive).
    • valuestring, number, or boolean.
    // Signal puzzle completion
    connection.setVariable("VAULT_PUZZLE", "DONE");

    // Reset after a failed attempt
    connection.setVariable("VAULT_PUZZLE", "-");

    // Send a numeric score
    connection.setVariable("PLAYER_SCORE", 4200);

    // Validate a code entry
    function checkCode(entered: string) {
    connection.setVariable(
    "KEYPAD_CODE",
    entered === "7734" ? "CORRECT" : "WRONG",
    );
    }

    Subscribes to events on the connection's internal EventTarget. Follows the standard EventTarget.addEventListener interface. Useful for fanning out events to multiple listeners without replacing the primary onScreenChange callback.

    connection.addEventListener(
    "screenReady",
    () => {
    initializeAnimations();
    },
    { once: true },
    );

    Removes a listener previously registered via addEventListener. The type, listener, and options arguments must match those used when the listener was added.

    function onConnected() {
    console.log("Connected");
    }

    connection.addEventListener("connected", onConnected);
    // Later:
    connection.removeEventListener("connected", onConnected);

    Permanently closes the WebSocket and disables auto-reconnect. No further messages will be sent or received. Call this when the screen unmounts or the page is about to unload.

    window.addEventListener("beforeunload", () => connection.close());

    // React
    useEffect(() => {
    return () => connection.close();
    }, []);