All files / webview-app/src/hooks usePostMessage.ts

75% Statements 15/20
50% Branches 2/4
71.42% Functions 5/7
73.68% Lines 14/19

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76                            1x   1x       1x 1x                           4x   4x   3x 3x 3x                 4x   3x         4x             4x       4x              
import { useCallback, useMemo } from "react";
 
import type {
  OutgoingExtensionMessage,
  StateChangedMessage,
  ToolbarCommand,
  ToolbarCommandMessage,
} from "@/types/messages";
 
interface VsCodeApi {
  postMessage: (message: unknown) => void;
}
 
function getVsCodeApi(): VsCodeApi | null {
  const maybeAcquire = (globalThis as typeof globalThis & { acquireVsCodeApi?: () => VsCodeApi })
    .acquireVsCodeApi;
  Iif (!maybeAcquire) {
    return null;
  }
 
  try {
    return maybeAcquire();
  } catch {
    return null;
  }
}
 
export interface UsePostMessageResult {
  postMessage: (message: OutgoingExtensionMessage) => void;
  postStateChanged: (message: StateChangedMessage["state"]) => void;
  postToolbarCommand: (command: ToolbarCommandMessage["command"]) => void;
  postPreviewCode: () => void;
}
 
export function usePostMessage(): UsePostMessageResult {
  const vscode = useMemo(() => getVsCodeApi(), []);
 
  const postMessage = useCallback(
    (message: OutgoingExtensionMessage) => {
      Eif (vscode) {
        vscode.postMessage(message);
        return;
      }
 
      // Useful fallback during browser development outside VS Code webview.
      console.debug("[webview-app] postMessage fallback", message);
    },
    [vscode],
  );
 
  const postStateChanged = useCallback(
    (state: StateChangedMessage["state"]) => {
      postMessage({ type: "stateChanged", state });
    },
    [postMessage],
  );
 
  const postToolbarCommand = useCallback(
    (command: ToolbarCommand) => {
      postMessage({ type: "toolbarCommand", command });
    },
    [postMessage],
  );
 
  const postPreviewCode = useCallback(() => {
    postToolbarCommand("previewCode");
  }, [postToolbarCommand]);
 
  return {
    postMessage,
    postStateChanged,
    postToolbarCommand,
    postPreviewCode,
  };
}