@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.
- package/README.md +121 -25
- package/dist/index.public.js +2009 -2044
- 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
|
-
|
|
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
|
-
|
|
88
|
-
|
|
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
|
-
- `
|
|
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
|
-
|
|
143
|
+
Alongside the default `GamiSDK`, the package exposes these named exports:
|
|
139
144
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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
|
-
|
|
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 {
|
|
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
|
-
|
|
153
|
-
|
|
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)
|
|
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
|
-
##
|
|
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
|
-
##
|
|
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
|
-
##
|
|
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
|
-
##
|
|
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.
|