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

zuburi-game-platform

v0.2.8

Published

Framework-independent TypeScript SDK for KZTK Game Platform

Readme

zuburi-game-platform

ZUBURI のゲームから ZUBURI Game Platform を利用するための React 非依存 TypeScript SDK です。

Install

pnpm add zuburi-game-platform @supabase/supabase-js

Basic usage

import { createGamePlatformClient } from 'zuburi-game-platform'
import { supabase } from '../lib/supabase'

export const platform = createGamePlatformClient({
  supabase,
  gameId: 'coffee_roaster',
})

SDK は Supabase Client を生成しません。service_role / Secret key / userId は渡しません。

Storage policy

Game Platform は履歴を蓄積せず、現在状態を保持する state-first 構成です。

保持する主な値:

  • ポイント現在残高・累積獲得・累積消費
  • 実績進捗・解除状態
  • ログインボーナス現在状態
  • 各ゲームの必要な集計値

イベント履歴、ポイント増減履歴、開封履歴などは原則保存しません。

詳細: ../../docs/STATE_FIRST_STORAGE_POLICY.md

Client events

ゲームから送信できるイベントは Platform 標準の4種類だけです。

game_started
ゲーム開始。value に開始時の数値を付けてもよい

game_finished
ゲーム終了。value に最終スコアなどを付けてもよい

personal_best_updated
自己ベスト更新。value 必須

item_obtained
アイテム獲得。metadata.itemId 必須、quantity は任意
import { PLATFORM_EVENTS } from 'zuburi-game-platform'

await platform.events.emit({
  type: PLATFORM_EVENTS.GAME_STARTED,
  value: 1,
})

await platform.events.emit({
  type: PLATFORM_EVENTS.GAME_FINISHED,
  sourceId: 'run:123',
  value: 85,
})

await platform.events.emit({
  type: PLATFORM_EVENTS.PERSONAL_BEST_UPDATED,
  value: 120,
})

await platform.events.emit({
  type: PLATFORM_EVENTS.ITEM_OBTAINED,
  metadata: {
    itemId: 'golden-bean',
    quantity: 1,
  },
})

独自 EventMap をゲーム側から追加する API はありません。TypeScript の型を回避して任意文字列を渡しても SDK が送信前に拒否します。

sourceId は Event Definition で必要な場合の識別情報です。イベントはDBへ永続保存されません。

永続イベント行による idempotency 管理を行わないため、SDKは書き込みRPCを自動リトライしません。読み取りRPCのみ一時エラー時に最大1回リトライします。

Points

const account = await platform.points.getAccount()

account.balance
account.lifetimeEarned
account.lifetimeSpent

ポイント履歴取得、points.add()、points.set() はありません。

Score multiplier rewards

Point Reward Rule は管理画面で次の2方式を選べます。

  • fixed: Event 1回につき固定ポイントを加算
  • value_multiplier: Event の value × 倍率 を端数切り捨てして加算

たとえば倍率を 0.1 にして、ゲーム終了時にスコア 1234 を送ると 123pt 加算されます。

const result = await platform.events.emit({
  type: PLATFORM_EVENTS.GAME_FINISHED,
  value: 1234,
})

console.log(result.points.delta) // 123(倍率0.1の場合)

倍率はフロント側で掛けず、Backend が管理画面の設定を参照して計算します。倍率ルールで value がない、または負数の場合は Event を拒否します。

ブラウザから送る value 自体は改変可能です。改変耐性が必要なスコアはゲーム固有RPCで検証して trusted event を使ってください。

Achievements

const achievements = await platform.achievements.list()

進捗・解除判定・報酬付与は Backend が行います。

Login bonus

const status = await platform.loginBonus.getStatus()
const result = await platform.loginBonus.claimAvailable()
await platform.loginBonus.claimProgram('summer_campaign_2026')

受取履歴を毎回追加せず、ユーザー・プログラムごとの現在状態を更新します。

Development write guard

const platform = createGamePlatformClient({
  supabase,
  gameId: 'coffee_roaster',
  writesEnabled: import.meta.env.VITE_DEVELOPMENT_MODE !== 'true',
})

writesEnabled=false の場合、Event送信とLogin Bonus claimは WRITE_DISABLED になります。

Security boundary

SDKは意図的に以下を提供しません。

points.add()
points.set()
points.listTransactions()
achievements.unlock()
achievements.setProgress()
events.emitTrusted()

スコア・勝敗など改変耐性が必要な処理はゲーム固有RPCで検証してください。

Repository development

pnpm install
pnpm check

SDK build は dist を削除してから生成します。

Publishing

main への変更は既存の Release workflow の対象です。

詳細: ../../docs/PUBLISHING.md