@momo-cloud/gami-sdk 0.0.86 → 0.0.95

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +121 -25
  2. package/dist/index.public.js +2009 -2044
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  `@momo-cloud/gami-sdk` is the integration layer between your web game and MoMo host capabilities.
4
4
  It provides:
5
5
 
6
- - Game backend APIs (spin, shake, mission, leaderboard, balance, exchange)
6
+ - Game backend APIs (spin, shake, mission, leaderboard, submit leaderboard score, balance, exchange)
7
7
  - Platform bridge APIs (toast, share, permission, contacts, deep-link, calendar, clipboard, and more)
8
8
  - Runtime utilities (server-time sync, storage helpers, SSE, event bus)
9
9
 
@@ -82,20 +82,25 @@ Then rely on runtime properties:
82
82
  await GamiSDK.startGame();
83
83
  ```
84
84
 
85
- Typical game loop calls:
85
+ > `startGame()` / `endGame()` bracket a **gameplay session**, not a single spin. Call `startGame()` once when entering the game and `endGame()` once when leaving — many `spin()` calls happen in between.
86
86
 
87
- - `getConfig()`
88
- - `getBalance({ balanceId })`
87
+ Typical game loop calls (signatures match `IGameApi`):
88
+
89
+ - `getConfig({ ext? })`
90
+ - `getBalance({ balanceId? })`
89
91
  - `getBalanceConfig()`
90
- - `spin()`
92
+ - `spin({ checkCounter?, giftCate?, isBonus? })`
91
93
  - `shake()`
92
94
  - `getCoinBalance()`
93
- - `getCoinExchangeInfo()`
94
- - `coinExchange({ amount })`
95
+ - `getCoinExchangeInfo({ actionId? })`
96
+ - `coinExchange({ amount, actionId? })`
95
97
  - `getMission({ viewId? })`
96
- - `getLeaderboard({ boardId, group?, limit?, page? })`
98
+ - `postSuccessMission({ eventName, serviceId? })`
99
+ - `getLeaderboard({ type })`
100
+ - `submitLeaderboard({ boardName, score, periodType?, delta? })`
97
101
  - `getHistory({ page, limit })`
98
102
  - `getEvent({ eventId })`
103
+ - `customGameRequest({ path, method, subDomain?, body?, extraHeader?, mockData? })`
99
104
 
100
105
  ### Phase C - Close or Navigate
101
106
 
@@ -133,28 +138,91 @@ GamiSDK.screenTracking({
133
138
  });
134
139
  ```
135
140
 
136
- ## 6) Shared Utilities
141
+ ## 6) Shared Utilities (Named Exports)
137
142
 
138
- Named exports are available for common integration helpers:
143
+ Alongside the default `GamiSDK`, the package exposes these named exports:
139
144
 
140
- - Storage: `saveItem`, `getItem`, `cacheFile`
141
- - Calendar wrapper: `addCalendar`
142
- - Time sync: `setServerTime`, `getServerTime`
143
- - Event bus: `GameEvent`
144
- - SSE support: from `features/sse/*`
145
- - Types: from `features/types/*`
145
+ ```ts
146
+ import GamiSDK, { Storage, Calendar, AudioPlayer, GameEvent, Utils } from '@momo-cloud/gami-sdk';
147
+ ```
146
148
 
147
- Example:
149
+ | Export | What it is |
150
+ | --- | --- |
151
+ | `GamiSDK` (default) | Composed game + platform API object |
152
+ | `Storage` | Persistent key/value + file cache (see §6.1) |
153
+ | `Calendar` | Device calendar helper |
154
+ | `AudioPlayer` | Music / SFX playback (see §6.2) |
155
+ | `GameEvent` | In-app event bus (`eventemitter3`) |
156
+ | `Utils` | Misc helpers (name/phone formatting, etc.) |
157
+ | Types | Domain DTOs (`TSpin`, `TLeaderboard`, `THistory`, …) |
158
+
159
+ > `getServerTime()` / `setServerTime()` live on the `GamiSDK` object, not as standalone named exports — call `GamiSDK.getServerTime()`. It is **synchronous** (returns `number`, ms epoch) — do **not** `await` it. Use it for any countdown, expiry, or campaign window instead of `Date.now()` to avoid client-clock skew.
160
+ >
161
+ > ```ts
162
+ > const now = GamiSDK.getServerTime(); // ✅ synchronous
163
+ > const remaining = campaignEndAt - now; // ❌ never Date.now()
164
+ > ```
165
+
166
+ ### 6.1) Storage
167
+
168
+ **Use `Storage` for all persistence — not `localStorage` / `sessionStorage`.** Browser storage is unreliable inside the MoMo WebView. All keys are automatically namespaced with the current `gameId` (e.g. `wheel_fpt_progress`).
169
+
170
+ ```ts
171
+ import { Storage } from '@momo-cloud/gami-sdk';
172
+
173
+ // Writes are fire-and-forget (synchronous, return void)
174
+ Storage.cacheJson('progress', { level: 3, stars: 15 });
175
+ Storage.cacheValue('lastSeen', Date.now());
176
+
177
+ // Reads are async
178
+ const progress = await Storage.getJson('progress', /* default */ {});
179
+ const lastSeen = await Storage.getValue('lastSeen');
180
+
181
+ // CDN file caching → returns a usable (possibly object) URL
182
+ const localUrl = await Storage.cacheFile('https://cdn.example.com/img/wheel.png');
183
+ ```
184
+
185
+ | Method | Returns | Notes |
186
+ | --- | --- | --- |
187
+ | `cacheJson(key, obj)` | `void` | Persist an object (fire-and-forget) |
188
+ | `cacheValue(key, val)` | `void` | Persist a primitive |
189
+ | `getJson(key, default?)` | `Promise<any>` | Read object; falls back to `default` |
190
+ | `getValue(key, default?)` | `Promise<any>` | Read primitive |
191
+ | `cacheFile(url)` | `Promise<string>` | Cache a remote file, returns local URL |
192
+ | `getInCache(url)` | `string \| undefined` | Synchronous lookup of an already-cached file |
193
+
194
+ ### 6.2) AudioPlayer
148
195
 
149
196
  ```ts
150
- import { saveItem, getItem, GameEvent } from '@momo-cloud/gami-sdk';
197
+ import { AudioPlayer } from '@momo-cloud/gami-sdk';
198
+
199
+ // If sound names are short keys (e.g. 'bg', 'btn-click'), set a base URL first.
200
+ // Skip this if every name you pass is already a full https URL.
201
+ AudioPlayer.init({ baseURL: 'https://cdn.example.com/sounds/' });
151
202
 
152
- await saveItem('progress', { level: 3, stars: 15 });
153
- const progress = await getItem('progress');
203
+ AudioPlayer.play('btn-click'); // one-shot SFX
204
+ AudioPlayer.play('btn-click', { volume: 0.5 }); // with options
205
+ AudioPlayer.playMusic('bg', { loop: true, volume: 1 }); // looping background music
206
+
207
+ AudioPlayer.pause(); // pause all (no arg) — call synchronously on app blur
208
+ AudioPlayer.resume(); // resume all — on app focus, wrap in setTimeout(…, 1000) on iOS WebView
209
+ AudioPlayer.stop('bg');
210
+ AudioPlayer.enable = false; // mute everything (respect user setting)
211
+ AudioPlayer.musicVolume = 0.3; // 0..1
212
+ ```
213
+
214
+ > `playMusic`'s second argument is an **options object** (`{ loop, volume, onComplete }`) — not a boolean. `init` takes `{ baseURL }` (capital `URL`).
215
+
216
+ ### 6.3) Event bus
217
+
218
+ ```ts
219
+ import { GameEvent } from '@momo-cloud/gami-sdk';
154
220
 
155
221
  GameEvent.on('GAME_ON_BACK', () => {
156
222
  // route back to your home screen
157
223
  });
224
+ GameEvent.emit('GAME_ON_BACK');
225
+ GameEvent.off('GAME_ON_BACK', handler);
158
226
  ```
159
227
 
160
228
  ## 7) Error Handling Pattern
@@ -174,7 +242,35 @@ if (res?.response_info?.error_code !== 0) {
174
242
  }
175
243
  ```
176
244
 
177
- ## 8) Browser vs Host Runtime
245
+ ## 8) Leaderboard APIs
246
+
247
+ ### Read leaderboard
248
+
249
+ ```ts
250
+ const lb = await GamiSDK.getLeaderboard({ type: 'win' });
251
+ ```
252
+
253
+ - `type` — the leaderboard identifier (e.g. `'win'`).
254
+
255
+ ### Submit a score
256
+
257
+ ```ts
258
+ await GamiSDK.submitLeaderboard({
259
+ boardName: 'win',
260
+ score: 1,
261
+ periodType: 'WEEKLY', // default – omit if weekly
262
+ delta: 1, // optional; defaults to score value
263
+ });
264
+ ```
265
+
266
+ - `boardName` — leaderboard identifier (e.g. `'win'`).
267
+ - `score` — the score value to record.
268
+ - `periodType` — leaderboard period bucket; defaults to `'WEEKLY'`.
269
+ - `delta` — incremental change amount; omit to use the same value as `score`.
270
+
271
+ `gameId` and `userId` are injected automatically from the SDK session — do not pass them manually.
272
+
273
+ ## 9) Browser vs Host Runtime
178
274
 
179
275
  - In MoMo host: full platform bridge behavior is available.
180
276
  - In browser/dev mode: host-only behavior may be mocked, no-op, or limited.
@@ -184,7 +280,7 @@ Integration recommendation:
184
280
  - Keep game domain flow independent from host-only APIs.
185
281
  - Wrap optional host actions with graceful fallback in browser.
186
282
 
187
- ## 9) Build and Publish Modes
283
+ ## 10) Build and Publish Modes
188
284
 
189
285
  This repository supports two build modes:
190
286
 
@@ -206,7 +302,7 @@ npm run publish:npm
206
302
  npm run publish:all
207
303
  ```
208
304
 
209
- ## 10) Integration Checklist
305
+ ## 11) Integration Checklist
210
306
 
211
307
  Before releasing a game integration:
212
308
 
@@ -218,7 +314,7 @@ Before releasing a game integration:
218
314
  - Local cache keys use SDK helpers to avoid collisions
219
315
  - Permissions flow validated for calendar/contacts/image capture
220
316
 
221
- ## 11) Minimal End-to-End Example
317
+ ## 12) Minimal End-to-End Example
222
318
 
223
319
  ```ts
224
320
  import GamiSDK from '@momo-cloud/gami-sdk';
@@ -244,7 +340,7 @@ export async function run() {
244
340
  }
245
341
  ```
246
342
 
247
- ## 12) Notes for Architects
343
+ ## 13) Notes for Architects
248
344
 
249
345
  - Keep `GamiSDK` behind your own `sdkService` adapter in app code.
250
346
  - Separate domain logic from host bridge calls for easier testability.