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

@rogue-paradise/platform-sdk

v0.1.0

Published

遊戲與 RogueParadise 平台之間的唯一執行期契約。遊戲端只依賴本套件,不直接接觸平台實作或瀏覽器儲存 API。

Readme

@rogue-paradise/platform-sdk

遊戲與 RogueParadise 平台之間的唯一執行期契約。遊戲端只依賴本套件,不直接接觸平台實作或瀏覽器儲存 API。

遊戲端 API

const sdk = await connect({ gameSlug: 'example-game' })

await sdk.storage.set('save', { floor: 3 })
const save = await sdk.storage.get<{ floor: number }>('save')
await sdk.progress.report({ type: 'run_completed', data: { floor: 9 } })
await sdk.exit()
  • iframe 內執行:modeembedded,請求透過版本化 postMessage 契約送到平台。
  • 獨立執行:modestandalone,Storage 自動改用 rogue-paradise:<gameSlug>:<key> 命名空間。
  • iframe 存在但平台握手失敗時會拋錯,不會靜默降級。否則同一局可能同時存在平台與 standalone 兩份互不相通的存檔。

postMessage 契約

所有訊息使用 channel: "rogue-paradise:v1"

遊戲送出的 request:

{
  channel: 'rogue-paradise:v1',
  kind: 'request',
  id: 'request-1',
  gameSlug: 'example-game',
  method: 'handshake',
  payload: { protocolVersion: 1 },
}

平台成功回應:

{
  channel: 'rogue-paradise:v1',
  kind: 'response',
  replyTo: 'request-1',
  ok: true,
  value: undefined,
}

平台錯誤回應:

{
  channel: 'rogue-paradise:v1',
  kind: 'response',
  replyTo: 'request-1',
  ok: false,
  error: '可供人類診斷的錯誤訊息',
}

支援的方法:

| method | request payload | success value | |---|---|---| | handshake | { protocolVersion: 1 } | 無 | | storage.get | { key } | { found, value? } | | storage.set | { key, value } | 無 | | storage.remove | { key } | 無 | | progress.report | { type, data? } | 無 | | exit | 無 | 無 |

SDK 只接受來自 window.parent 的回應。若呼叫端提供 targetOrigin,還會拒絕其他 origin;平台正式部署時不得使用萬用字元。

反向驗證紀錄

2026-07-28 刻意把 standalone 儲存 prefix 從 rogue-paradise:<gameSlug>: 破壞成 rogue-paradise:,再執行:

pnpm vitest run packages/platform-sdk/test/contract.test.ts \
  -t "standalone 模式使用以遊戲 slug 隔離的儲存空間"

測試如預期失敗,實際診斷為:

expected { floor: 8 } to deeply equal { floor: 3 }
Test Files  1 failed (1)
Tests  1 failed | 8 skipped (9)

還原命名空間後,完整契約測試重新通過。