npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@team-monolith/post-message-manager

v1.1.1

Published

`window.postMessage` API를 사용한 크로스 윈도우 통신을 쉽게 관리할 수 있는 TypeScript 라이브러리입니다.

Readme

Post Message Manager

window.postMessage API를 사용한 크로스 윈도우 통신을 쉽게 관리할 수 있는 TypeScript 라이브러리입니다.

특징

  • 🔄 양방향 통신: send 메서드로 메시지를 보내고 응답을 Promise로 받을 수 있습니다
  • 📢 단방향 통신: notify 메서드로 응답이 필요 없는 메시지를 전송할 수 있습니다
  • 🔒 Origin 검증: 메시지 수신 시 origin 검증을 통해 보안을 강화할 수 있습니다
  • ⏱️ 타임아웃 처리: 응답이 오지 않을 때 자동으로 타임아웃 처리합니다
  • 📝 TypeScript 지원: 완전한 타입 정의를 제공합니다

설치

npm install @team-monolith/post-message-manager

사용법

기본 설정

import PostMessageManager from "@team-monolith/post-message-manager";

// 인스턴스 생성 (기본 타임아웃: 3000ms)
const manager = new PostMessageManager();

// 또는 커스텀 타임아웃 설정
const manager = new PostMessageManager(5000); // 5초

메시지 핸들러 등록하기

다른 윈도우로부터 메시지를 받을 때 실행할 콜백을 등록합니다.

// 기본 등록
manager.register({
  messageType: "getUserInfo",
  callback: (payload) => {
    console.log("받은 데이터:", payload);
    return { name: "John", age: 30 };
  },
});

// origin 검증과 함께 등록
manager.register({
  messageType: "sensitiveData",
  callback: (payload) => {
    return { secret: "data" };
  },
  origin: "https://trusted-domain.com", // 특정 origin만 허용
});

// 함수형 origin 검증
manager.register({
  messageType: "flexibleCheck",
  callback: (payload) => {
    return { data: "response" };
  },
  origin: (origin) => {
    // 여러 도메인 허용
    return origin.endsWith(".mycompany.com");
  },
});

// 비동기 콜백
manager.register({
  messageType: "fetchData",
  callback: async (payload) => {
    const data = await fetch("/api/data");
    return data.json();
  },
});

메시지 보내고 응답 받기 (양방향)

send 메서드는 메시지를 보내고 응답을 Promise로 반환합니다.

try {
  const response = await manager.send({
    messageType: "getUserInfo",
    payload: { userId: 123 },
    target: iframe.contentWindow, // 메시지를 받을 window 객체
    targetOrigin: "https://example.com", // 타겟 origin
    timeoutMs: 5000, // 선택적: 이 요청만의 타임아웃 설정
  });

  console.log("응답:", response);
} catch (error) {
  console.error("에러:", error); // 타임아웃 또는 기타 에러
}

메시지 보내기만 하기 (단방향)

응답이 필요 없는 경우 notify를 사용합니다.

manager.notify({
  messageType: "logEvent",
  payload: { event: "button_clicked", timestamp: Date.now() },
  target: window.opener,
  targetOrigin: "https://example.com",
});

핸들러 제거

manager.unregister("getUserInfo");

실전 예제

부모 윈도우와 iframe 간 통신

부모 윈도우 (parent.html)

import PostMessageManager from "@team-monolith/post-message-manager";

const manager = new PostMessageManager();

// iframe에서 보내는 메시지 핸들러 등록
manager.register({
  messageType: "requestUserData",
  callback: async (payload) => {
    const userData = await fetchUserData(payload.userId);
    return userData;
  },
  origin: "https://child-iframe.com",
});

// iframe으로 메시지 보내기
const iframe = document.getElementById("myIframe") as HTMLIFrameElement;

iframe.onload = async () => {
  try {
    const response = await manager.send({
      messageType: "initialize",
      payload: { theme: "dark", lang: "ko" },
      target: iframe.contentWindow!,
      targetOrigin: "https://child-iframe.com",
    });
    console.log("iframe 초기화 완료:", response);
  } catch (error) {
    console.error("초기화 실패:", error);
  }
};

iframe (child.html)

import PostMessageManager from "@team-monolith/post-message-manager";

const manager = new PostMessageManager();

// 부모로부터 초기화 메시지 받기
manager.register({
  messageType: "initialize",
  callback: (payload) => {
    applyTheme(payload.theme);
    setLanguage(payload.lang);
    return { status: "initialized" };
  },
  origin: "https://parent-site.com",
});

// 부모에게 사용자 데이터 요청
async function loadUserData(userId: number) {
  try {
    const userData = await manager.send({
      messageType: "requestUserData",
      payload: { userId },
      target: window.parent,
      targetOrigin: "https://parent-site.com",
    });
    return userData;
  } catch (error) {
    console.error("사용자 데이터 로드 실패:", error);
  }
}

API 레퍼런스

constructor(timeoutMs?: number)

  • timeoutMs: 기본 타임아웃 시간 (밀리초). 기본값: 3000ms

register(args: RegisterProps): void

메시지 핸들러를 등록합니다.

interface RegisterProps {
  messageType: string;
  callback: (payload: any) => Promise<any> | any;
  origin?: string | ((origin: string) => boolean);
}

unregister(messageType: string): void

등록된 메시지 핸들러를 제거합니다.

send<T>(args: SendProps): Promise<T>

메시지를 보내고 응답을 기다립니다.

interface SendProps {
  messageType: string;
  payload: any;
  target: Window;
  targetOrigin: string;
  timeoutMs?: number; // 선택적: 이 요청만의 타임아웃
}

notify(args: NotifyProps): void

응답을 기다리지 않고 메시지를 보냅니다.

type NotifyProps = Omit<SendProps, "timeoutMs">;

주의사항

Origin 검증의 중요성

보안을 위해 반드시 origin 옵션을 사용하여 신뢰할 수 있는 출처의 메시지만 처리하세요.

// ❌ 나쁜 예: origin 검증 없음
manager.register({
  messageType: "sensitiveData",
  callback: (payload) => {
    return { creditCard: "1234-5678" };
  },
});

// ✅ 좋은 예: origin 검증 있음
manager.register({
  messageType: "sensitiveData",
  callback: (payload) => {
    return { creditCard: "1234-5678" };
  },
  origin: "https://trusted-site.com",
});

타임아웃 처리

응답이 늦어질 수 있는 경우 타임아웃을 조정하세요.

// 긴 작업의 경우 타임아웃을 늘림
const response = await manager.send({
  messageType: "heavyComputation",
  payload: data,
  target: worker,
  targetOrigin: "*",
  timeoutMs: 30000, // 30초
});

메모리 누수 방지

컴포넌트나 윈도우가 언마운트될 때는 핸들러를 제거하세요.

// React 예제
useEffect(() => {
  manager.register({
    messageType: "update",
    callback: handleUpdate,
  });

  return () => {
    manager.unregister("update");
  };
}, []);

빌드

# 빌드 (전체)
npm run build

# NPM용 빌드
npm run build:npm

# 브라우저용 빌드 (IIFE), dist/post-message-manager.js 생성
npm run build:browser