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

@vircle/sdk-core-ts

v1.3.0

Published

Vircle SDK TypeScript Core

Readme

@vircle/sdk-core-ts

Vircle SDK의 핵심 엔진으로, 모든 플랫폼별 SDK 구현의 기반이 되는 TypeScript 코어 라이브러리입니다.

설치

pnpm add @vircle/sdk-core-ts

빠른 시작

import { VircleCore } from '@vircle/sdk-core-ts';

const vircle = new VircleCore({
    apiKey: 'your-api-key',
    environment: 'production',
});

await vircle.initialize();

// 이벤트 추적
await vircle.track('button_clicked', {
    buttonId: 'purchase',
    value: 99.99,
});

// 사용자 식별
await vircle.identify('user-123', {
    email: '[email protected]',
    plan: 'premium',
});

// 크로스 도메인 어트리뷰션용 anonymousId 조회
const anonymousId = vircle.getAnonymousId();
// → "anon_1709500000_abc123xyz"

플러그인과 함께 초기화

config.plugins 배열에 플러그인 인스턴스를 전달하면 initialize() 시 자동 등록됩니다.

import { VircleCore } from '@vircle/sdk-core-ts';
import { createCafe24Plugin } from '@vircle/plugin-cafe24';

const vircle = new VircleCore(
    {
        apiKey: 'your-api-key',
        plugins: [createCafe24Plugin()],
    },
    { enablePlugins: true },
);

await vircle.initialize();
// → Cafe24Plugin이 자동으로 등록 및 초기화됨

설정 옵션

const vircle = new VircleCore(
    {
        apiKey: 'your-api-key',
        environment: 'production',   // 'development' | 'production' (기본값: 'production')

        batch: {
            size: 50,                // 배치당 최대 이벤트 수
            timeout: 5000,           // 배치 대기 시간 (ms)
            maxBytes: 500000,        // 배치 최대 크기 (bytes)
        },
        queue: {
            maxSize: 1000,           // 최대 큐 크기
            strategy: 'fifo',        // 'fifo' | 'lifo' | 'priority'
        },
        retry: {
            maxAttempts: 3,          // 최대 재시도 횟수
            initialDelay: 1000,      // 초기 재시도 지연 (ms)
            maxDelay: 30000,         // 최대 재시도 지연 (ms)
            multiplier: 2,           // 지수 백오프 계수
        },
        autoCollect: {
            device: true,            // 기기 정보
            app: true,               // 앱 정보
            page: true,              // 페이지 정보
            performance: false,      // 성능 메트릭
        },
        plugins: [],                 // 자동 등록할 VirclePlugin 인스턴스 배열
    },
    {
        enableValidation: true,      // 이벤트/설정 검증
        enableAutoContext: true,     // 자동 컨텍스트 수집
        enablePlugins: true,         // 플러그인 시스템
        enableEncryption: true,      // 페이로드 암호화
        storageType: 'indexedDB',    // 'localStorage' | 'indexedDB' | 'memory'
        debug: true,                 // 디버그 로그
    },
);

플러그인 시스템

플러그인 생성

import type { VirclePlugin, PluginContext } from '@vircle/sdk-core-ts';

const myPlugin: VirclePlugin = {
    name: 'my-plugin',
    version: '1.0.0',

    async initialize(config, context: PluginContext) {
        // context.track()으로 SDK 파이프라인을 통해 이벤트 전송
        context.track('plugin_loaded', { pluginName: 'my-plugin' });
    },

    hooks: {
        beforeEventSend: async (event) => {
            event.properties = { ...event.properties, enriched: true };
            return event;
        },
        afterEventSend: async (event) => {
            console.log('Event sent:', event.name);
        },
    },

    async cleanup() {
        console.log('Plugin cleanup');
    },
};

플러그인 등록 방법

// 방법 1: config.plugins로 자동 등록 (권장)
const vircle = new VircleCore({
    apiKey: 'your-api-key',
    plugins: [myPlugin],
}, { enablePlugins: true });

// 방법 2: 초기화 후 수동 등록
await vircle.registerPlugin(myPlugin);

PluginContext API

플러그인의 initialize(config, context) 에서 전달받는 PluginContext가 제공하는 메서드:

| 메서드 | 설명 | |--------|------| | track(eventName, properties?) | VircleCore.track() 파이프라인을 통해 이벤트 전송 | | identify(userId, traits?) | VircleCore.identify() 파이프라인을 통해 사용자 식별 | | emit(event, data?) | 플러그인 간 pub/sub 이벤트 발행 | | on(event, handler) / off(event, handler) | 이벤트 리스너 등록/해제 | | getConfig() | SDK 설정 조회 | | getPlugin(name) | 다른 플러그인 인스턴스 조회 | | logger | debug/info/warn/error 로거 | | storage | get/set/remove 키-값 저장소 |

context.track()VircleCore.track()과 동일한 파이프라인(검증 → 훅 → 배치 → 전송)을 거칩니다. context.emit()은 플러그인 간 내부 통신용 pub/sub으로 서버 전송과 무관합니다.

사용 가능한 훅

| 훅 | 설명 | |----|------| | beforeEventSend | 전송 전 이벤트 수정 (이벤트 반환) | | afterEventSend | 전송 성공 후 처리 | | onError | 에러 처리 | | onConfigChange | 설정 변경 반응 | | onUserIdentify | 사용자 식별 반응 | | onSessionStart / onSessionEnd | 세션 시작/종료 |

타입 안전 이벤트

interface PurchaseEvent {
    productId: string;
    price: number;
    currency: string;
}

await vircle.track<PurchaseEvent>('purchase', {
    productId: 'SKU-123',
    price: 99.99,
    currency: 'USD',
});

이벤트 빌더

await vircle
    .createEvent('purchase')
    .properties({ productId: 'SKU-123', price: 99.99 })
    .userId('user-123')
    .context({ campaign: { source: 'google' } })
    .track();

전송 제어

await vircle.flush();           // 대기 중인 이벤트 즉시 전송

const status = vircle.getStatus();
// { isInitialized, sessionId, userId, pluginCount, queueSize }

const anonId = vircle.getAnonymousId();  // 크로스 도메인 어트리뷰션용

await vircle.reset();           // SDK 상태 초기화
await vircle.cleanup();         // 모든 리소스 정리

전역 속성

모든 track()/trackBatch() 호출 시 properties에 자동 병합됩니다.

// 설정 — 이후 모든 이벤트에 partnerIdx가 포함됨
vircle.setGlobalProperties({ partnerIdx: 123 });

// track() properties가 globalProperties보다 우선
await vircle.track('click', { partnerIdx: 456 }); // → partnerIdx: 456

// 초기화
vircle.clearGlobalProperties();

컨텍스트 관리

vircle.setContext({
    experiment: { id: 'exp-123', variant: 'A' },
});

vircle.clearContext();

세션 관리

SDK는 세션을 스토리지에 영속화하여 MPA 페이지 전환 간 세션을 유지합니다.

  • 30분 비활동 타임아웃: 마지막 활동으로부터 30분 경과 시 새 세션 생성
  • 스토리지 기반 복원: 페이지 로드 시 스토리지에서 세션 복원 (MPA 지원)
  • Throttled 저장: track() 호출 시 10초 간격으로 활동 시간 갱신 (스토리지 쓰기 최적화)

페이로드 암호화

하이브리드 암호화(AES-256-GCM + RSA-OAEP)로 이벤트 페이로드를 보호합니다.

const vircle = new VircleCore(
    { apiKey: 'your-api-key' },
    { enableEncryption: true },
);
  • CDN에서 공개키를 자동으로 가져와 암호화
  • 별도 코드 변경 없이 모든 이벤트/identify 데이터 자동 암호화
  • 암호화 실패 시 전송 중단 (안전한 실패)

환경별 엔드포인트

| 환경 | Events API | Config CDN | |------|-----------|------------| | production (기본값) | https://integration.vircle.co.kr/v1/track/events | https://static.vircle.co.kr/sdk/v1/config | | development | https://dev-integration.vircle.co.kr/v1/track/events | https://dstatic.vircle.co.kr/sdk/v1/config |

에러 처리

import { VircleError, ErrorCode } from '@vircle/sdk-core-ts';

try {
    await vircle.track('event');
} catch (error) {
    if (error instanceof VircleError) {
        console.error(error.code, error.message);

        if (error.code === ErrorCode.NETWORK_ERROR) {
            // 네트워크 에러 처리
        }
    }
}

아키텍처

VircleCore (중앙 오케스트레이터)
├── EventService      — 이벤트 생성, 검증, 큐잉
├── TransportService  — 배치 전송, 재시도, 서킷 브레이커
├── StorageService    — 다중 어댑터 (Memory, LocalStorage, IndexedDB)
├── PluginService     — 플러그인 라이프사이클, 훅 실행, PluginContext 제공
├── RemoteConfigService — CDN 기반 동적 설정
└── ContextService    — 디바이스/앱/페이지 컨텍스트 자동 수집

데이터 흐름

track() → EventService (검증/보강) → PluginHooks (beforeEventSend)
       → TransportService (배치/암호화) → HTTP POST

플랫폼 어댑터 패턴

플랫폼별 SDK(Web, React Native)는 VircleCore를 상속하고 어댑터를 주입합니다:

| 어댑터 인터페이스 | Web 구현 | React Native 구현 | |------------------|---------|-------------------| | StorageAdapter | LocalStorage, IndexedDB | AsyncStorage | | ExtendedCryptoAdapter | Web Crypto API | react-native-quick-crypto | | ContextAdapter | WebContextCollector | RNContextAdapter |