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

@seamos/bridge

v0.1.2

Published

Type-safe bridge interface between SeamOS and WebView applications

Readme

@seamos/bridge

React Native 앱과 WebView 간 타입 안전한 양방향 통신 브릿지.

설치

npm install @seamos/bridge

WebView에서 사용하기

import { bridge, BridgeEvent } from '@seamos/bridge/webview';

bridge는 싱글톤입니다.


데이터 접근 (settings / location)

bridge.settingsbridge.location으로 현재 값을 동기적으로 읽을 수 있습니다.

// NativeSettings & { location?: Location } | null
const settings = bridge.settings;
// settings.locale   — 'ko' | 'en' | 'de' | 'ja'
// settings.darkMode — boolean
// settings.fontSize — 'small' | 'medium' | 'large' | 'xlarge' | 'xxlarge' | 'xxxlarge'
// settings.location — Location | undefined

// Location | null
const location = bridge.location;
// location.latitude   — number
// location.longitude  — number
// location.altitude   — number | null | undefined
// location.accuracy   — number | null | undefined
// location.speed      — number | null | undefined
// location.heading    — number | null | undefined
// location.timestamp  — number (Unix ms)

초기값 주입에 대해 Native가 injectedJavaScriptBeforeContentLoadedwindow.__SEAMOS_SETTINGS를 주입한 경우, import 즉시 bridge.settingsbridge.location을 사용할 수 있습니다. 그렇지 않으면 Native가 업데이트를 보낼 때까지 null입니다.


이벤트 구독

bridge.addListener(event, listener)로 Native에서 오는 업데이트를 구독합니다. 반환값은 구독 해제 함수입니다.

Settings 업데이트

const unsubscribe = bridge.addListener(
  BridgeEvent.SETTINGS_UPDATE,
  (settings) => {
    // settings: NativeSettings & { location?: Location }
  },
);

unsubscribe(); // 구독 해제

Location 업데이트

const unsubscribe = bridge.addListener(
  BridgeEvent.LOCATION_UPDATE,
  (location) => {
    // location: Location
  },
);

unsubscribe();

커스텀 메시지 수신

const unsubscribe = bridge.addListener(
  BridgeEvent.custom('someAction'),
  (payload) => {
    // payload: unknown
  },
);

unsubscribe();

에러

bridge.addListener(BridgeEvent.ERROR, (error) => {
  // error.code, error.message
});

| 에러 | code | 발생 조건 | | ------------------------- | ------------------ | -------------------------------------- | | BridgeVersionError | VERSION_MISMATCH | Native와 프로토콜 버전이 맞지 않을 때 | | BridgeNotAvailableError | NOT_AVAILABLE | ReactNativeWebView를 찾을 수 없을 때 |


메서드

bridge.sendCustom(action, payload)

Native로 커스텀 메시지를 전송합니다.

bridge.sendCustom('user:action', { itemId: 42 });

bridge.triggerHaptic(type)

햅틱 피드백을 요청합니다.

// type: 'light' | 'medium' | 'heavy' | 'success' | 'warning' | 'error' | 'selection'
bridge.triggerHaptic('success');

bridge.triggerVibration(options?)

진동을 요청합니다.

bridge.triggerVibration({ duration: 500 });
bridge.triggerVibration({ pattern: [0, 300, 100, 500] });
bridge.triggerVibration({ pattern: [0, 200, 100, 200], repeat: true });

durationpattern은 함께 사용할 수 없습니다.

bridge.cancelVibration()

반복 진동을 취소합니다.

bridge.cancelVibration();

bridge.downloadFile(options)

Native에 파일 다운로드(저장)를 요청합니다. Base64 인코딩된 파일 데이터를 전송합니다.

bridge.downloadFile({
  data: 'dGVzdA==', // Base64 encoded file data
  fileName: 'report.pdf', // 파일명 (확장자 포함)
  mimeType: 'application/pdf', // MIME type
});

파일 다운로드 결과 수신

const unsubscribe = bridge.addListener(
  BridgeEvent.FILE_DOWNLOAD_RESULT,
  (result) => {
    // result.fileName — 요청 시 전달한 파일명
    // result.success  — 저장 성공 여부
    // result.error    — 실패 시 에러 메시지
  },
);

unsubscribe();

License

MIT