@oasiz/sdk 1.5.1 → 1.5.3
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 +50 -12
- package/dist/index.cjs +130 -36
- package/dist/index.d.cts +15 -1
- package/dist/index.d.ts +15 -1
- package/dist/index.js +129 -36
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,7 +21,9 @@ Typed SDK for integrating browser games with the Oasiz platform: score, haptics,
|
|
|
21
21
|
npm install @oasiz/sdk
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
The published package includes ESM, CommonJS, and TypeScript declarations.
|
|
25
|
+
|
|
26
|
+
## Quick start
|
|
25
27
|
|
|
26
28
|
```ts
|
|
27
29
|
import { oasiz } from "@oasiz/sdk";
|
|
@@ -36,10 +38,10 @@ oasiz.saveGameState({ level, coins: 42 });
|
|
|
36
38
|
// 3. Trigger haptics on key events
|
|
37
39
|
oasiz.triggerHaptic("medium");
|
|
38
40
|
|
|
39
|
-
// 4. Respect the host's top safe area
|
|
41
|
+
// 4. Respect the host's top safe area (percent of viewport height → CSS vh)
|
|
40
42
|
document.documentElement.style.setProperty(
|
|
41
43
|
"--safe-top",
|
|
42
|
-
`${oasiz.safeAreaTop}
|
|
44
|
+
`${oasiz.safeAreaTop}vh`,
|
|
43
45
|
);
|
|
44
46
|
|
|
45
47
|
// 5. Submit score when the game ends
|
|
@@ -194,15 +196,15 @@ private onGameOver(): void {
|
|
|
194
196
|
|
|
195
197
|
### Layout
|
|
196
198
|
|
|
197
|
-
Use the runtime safe-area value instead of hardcoded top offsets. The
|
|
199
|
+
Use the runtime safe-area value instead of hardcoded top offsets. The SDK returns the top inset as **a percentage of the viewport height (0–100)**. If the host exposes CSS pixels via `window.getSafeAreaTop()` or `window.__OASIZ_SAFE_AREA_TOP__`, the SDK converts using `window.innerHeight`. The host may instead set **`window.getSafeAreaTopPercent()`** or **`window.__OASIZ_SAFE_AREA_TOP_PERCENT__`** (0–100) and that value is used directly.
|
|
198
200
|
|
|
199
201
|
#### `oasiz.getSafeAreaTop(): number`
|
|
200
202
|
|
|
201
|
-
Returns the
|
|
203
|
+
Returns the top inset as a percentage of viewport height (0–100). To get pixels in JavaScript, use `(getSafeAreaTop() / 100) * window.innerHeight`. In CSS, the same value matches **`vh`** units (for example `12.5vh` for 12.5% of the viewport height). Unsupported hosts return `0`.
|
|
202
204
|
|
|
203
205
|
```ts
|
|
204
|
-
const
|
|
205
|
-
document.documentElement.style.setProperty("--safe-top", `${
|
|
206
|
+
const safeTopPct = oasiz.getSafeAreaTop();
|
|
207
|
+
document.documentElement.style.setProperty("--safe-top", `${safeTopPct}vh`);
|
|
206
208
|
```
|
|
207
209
|
|
|
208
210
|
#### `oasiz.safeAreaTop`
|
|
@@ -298,7 +300,18 @@ quitButton.addEventListener("click", () => {
|
|
|
298
300
|
});
|
|
299
301
|
```
|
|
300
302
|
|
|
301
|
-
|
|
303
|
+
### `oasiz.share(options: { text?: string; score?: number; image?: string }): Promise<void>`
|
|
304
|
+
|
|
305
|
+
Ask the host to open the same share flow Oasiz already uses today. Use `text` to customize the share message, `score` to trigger a challenge-style share, and `image` to share an `http(s)` URL or `data:image/...` payload.
|
|
306
|
+
|
|
307
|
+
```ts
|
|
308
|
+
await oasiz.share({
|
|
309
|
+
text: "I made it to level 9!",
|
|
310
|
+
score: 4200,
|
|
311
|
+
});
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### `oasiz.onLeaveGame(callback: () => void): Unsubscribe`
|
|
302
315
|
|
|
303
316
|
Registers a callback fired when the host initiates closing the game (for example, close button, gesture, or host navigation). Use this for lightweight cleanup.
|
|
304
317
|
|
|
@@ -375,6 +388,7 @@ All methods are also available as named exports if you prefer not to use the `oa
|
|
|
375
388
|
```ts
|
|
376
389
|
import {
|
|
377
390
|
submitScore,
|
|
391
|
+
share,
|
|
378
392
|
triggerHaptic,
|
|
379
393
|
loadGameState,
|
|
380
394
|
saveGameState,
|
|
@@ -406,6 +420,7 @@ import type {
|
|
|
406
420
|
LogOverlayHandle,
|
|
407
421
|
LogOverlayLevel,
|
|
408
422
|
LogOverlayOptions,
|
|
423
|
+
ShareRequest,
|
|
409
424
|
ShareRoomCodeOptions,
|
|
410
425
|
Unsubscribe,
|
|
411
426
|
} from "@oasiz/sdk";
|
|
@@ -440,9 +455,10 @@ public class GameManager : MonoBehaviour
|
|
|
440
455
|
OasizSDK.OnPause += OnPause;
|
|
441
456
|
OasizSDK.OnResume += OnResume;
|
|
442
457
|
|
|
443
|
-
// Offset UI for the host's top safe area
|
|
444
|
-
float
|
|
445
|
-
|
|
458
|
+
// Offset UI for the host's top safe area (0–100 percent of Screen.height)
|
|
459
|
+
float safeTopPct = OasizSDK.SafeAreaTop;
|
|
460
|
+
float safeTopPx = safeTopPct / 100f * Screen.height;
|
|
461
|
+
Debug.Log($"Safe area top: {safeTopPx}px ({safeTopPct}% of height)");
|
|
446
462
|
|
|
447
463
|
// Emit score normalization anchors
|
|
448
464
|
OasizSDK.EmitScoreConfig(new ScoreConfig(
|
|
@@ -485,12 +501,13 @@ public class GameManager : MonoBehaviour
|
|
|
485
501
|
| `oasiz.loadGameState()` | `OasizSDK.LoadGameState()` → `Dictionary<string, object>` |
|
|
486
502
|
| `oasiz.saveGameState(obj)` | `OasizSDK.SaveGameState(Dictionary<string, object>)` |
|
|
487
503
|
| `oasiz.flushGameState()` | `OasizSDK.FlushGameState()` |
|
|
488
|
-
| `oasiz.getSafeAreaTop()` / `safeAreaTop` | `OasizSDK.GetSafeAreaTop()` / `OasizSDK.SafeAreaTop` (`float`,
|
|
504
|
+
| `oasiz.getSafeAreaTop()` / `safeAreaTop` | `OasizSDK.GetSafeAreaTop()` / `OasizSDK.SafeAreaTop` (`float`, 0–100, % of viewport height) |
|
|
489
505
|
| `oasiz.setLeaderboardVisible(v)` | `OasizSDK.SetLeaderboardVisible(bool)` |
|
|
490
506
|
| `oasiz.onPause` / `onResume` | `OasizSDK.OnPause` / `OnResume` static events |
|
|
491
507
|
| `oasiz.onBackButton` | `OasizSDK.OnBackButton` or `SubscribeBackButton(Action)` (reference-counts `__oasizSetBackOverride`) |
|
|
492
508
|
| `oasiz.onLeaveGame` | `OasizSDK.OnLeaveGame` |
|
|
493
509
|
| `oasiz.leaveGame()` | `OasizSDK.LeaveGame()` |
|
|
510
|
+
| `oasiz.share(request)` | `OasizSDK.Share(ShareRequest)` |
|
|
494
511
|
| `oasiz.shareRoomCode` | `OasizSDK.ShareRoomCode(string, ShareRoomCodeOptions)` |
|
|
495
512
|
| `oasiz.openInviteModal()` | `OasizSDK.OpenInviteModal()` |
|
|
496
513
|
| `oasiz.gameId` / `roomCode` / ... | `OasizSDK.GameId` / `RoomCode` / `PlayerName` / `PlayerAvatar` |
|
|
@@ -498,6 +515,19 @@ public class GameManager : MonoBehaviour
|
|
|
498
515
|
| `oasiz.enableLogOverlay` | `OasizSDK.EnableLogOverlay(LogOverlayOptions)` (see note below) |
|
|
499
516
|
| -- | `OasizSDK.AppendLogOverlay(level, message, stackTrace)` (see note below) |
|
|
500
517
|
|
|
518
|
+
### Share (Unity)
|
|
519
|
+
|
|
520
|
+
HTML5 **`oasiz.share`** returns a **Promise** you can `await`. Unity **`OasizSDK.Share(ShareRequest)`** returns **`void`**: C# validation throws **`ArgumentException`** with the same rules as TypeScript (at least one of text, score, or image; non-negative integer score; `http(s)` or `data:image/...;base64,...` image). The call forwards JSON to **`window.__oasizShareRequest`**. If the host promise rejects, the **WebGL `.jslib` logs the error** to the browser console.
|
|
521
|
+
|
|
522
|
+
```csharp
|
|
523
|
+
OasizSDK.Share(new ShareRequest
|
|
524
|
+
{
|
|
525
|
+
Text = "Beat this run!",
|
|
526
|
+
Score = 1200,
|
|
527
|
+
Image = "https://example.com/card.png",
|
|
528
|
+
});
|
|
529
|
+
```
|
|
530
|
+
|
|
501
531
|
### Types
|
|
502
532
|
|
|
503
533
|
```csharp
|
|
@@ -508,6 +538,14 @@ public enum HapticType { Light, Medium, Heavy, Success, Error }
|
|
|
508
538
|
public struct ScoreAnchor { public int raw; public int normalized; }
|
|
509
539
|
public struct ScoreConfig { public ScoreAnchor[] anchors; }
|
|
510
540
|
|
|
541
|
+
// Host share sheet (text / score / image URL or data URL)
|
|
542
|
+
public class ShareRequest
|
|
543
|
+
{
|
|
544
|
+
public string Text { get; set; }
|
|
545
|
+
public int? Score { get; set; }
|
|
546
|
+
public string Image { get; set; }
|
|
547
|
+
}
|
|
548
|
+
|
|
511
549
|
// Multiplayer invite options
|
|
512
550
|
public class ShareRoomCodeOptions { public bool InviteOverride { get; set; } }
|
|
513
551
|
|
package/dist/index.cjs
CHANGED
|
@@ -37,6 +37,7 @@ __export(index_exports, {
|
|
|
37
37
|
openInviteModal: () => openInviteModal,
|
|
38
38
|
saveGameState: () => saveGameState,
|
|
39
39
|
setLeaderboardVisible: () => setLeaderboardVisible,
|
|
40
|
+
share: () => share,
|
|
40
41
|
shareRoomCode: () => shareRoomCode,
|
|
41
42
|
submitScore: () => submitScore,
|
|
42
43
|
triggerHaptic: () => triggerHaptic
|
|
@@ -1044,7 +1045,7 @@ function submitScore(score) {
|
|
|
1044
1045
|
warnMissingBridge("submitScore");
|
|
1045
1046
|
}
|
|
1046
1047
|
|
|
1047
|
-
// src/
|
|
1048
|
+
// src/share.ts
|
|
1048
1049
|
function isDevelopment4() {
|
|
1049
1050
|
const nodeEnv = globalThis.process?.env?.NODE_ENV;
|
|
1050
1051
|
return nodeEnv !== "production";
|
|
@@ -1055,6 +1056,69 @@ function getBridgeWindow4() {
|
|
|
1055
1056
|
}
|
|
1056
1057
|
return window;
|
|
1057
1058
|
}
|
|
1059
|
+
function warnMissingBridge2(methodName) {
|
|
1060
|
+
if (isDevelopment4()) {
|
|
1061
|
+
console.warn(
|
|
1062
|
+
"[oasiz/sdk] " + methodName + " share bridge is unavailable. This is expected in local development."
|
|
1063
|
+
);
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
function isValidImageReference(image) {
|
|
1067
|
+
if (/^data:image\/[a-zA-Z0-9.+-]+;base64,/.test(image)) {
|
|
1068
|
+
return true;
|
|
1069
|
+
}
|
|
1070
|
+
try {
|
|
1071
|
+
const parsed = new URL(image);
|
|
1072
|
+
return parsed.protocol === "http:" || parsed.protocol === "https:";
|
|
1073
|
+
} catch {
|
|
1074
|
+
return false;
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
function validateRequest(options) {
|
|
1078
|
+
const text = typeof options.text === "string" ? options.text.trim() : "";
|
|
1079
|
+
const hasText = text.length > 0;
|
|
1080
|
+
const hasScore = options.score !== void 0;
|
|
1081
|
+
const hasImage = typeof options.image === "string" && options.image.length > 0;
|
|
1082
|
+
if (!hasText && !hasScore && !hasImage) {
|
|
1083
|
+
throw new Error("Share request requires text, score, or image.");
|
|
1084
|
+
}
|
|
1085
|
+
if (hasScore) {
|
|
1086
|
+
if (typeof options.score !== "number" || !Number.isInteger(options.score) || options.score < 0) {
|
|
1087
|
+
throw new Error("Share score must be a non-negative integer.");
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
if (hasImage && !isValidImageReference(options.image)) {
|
|
1091
|
+
throw new Error(
|
|
1092
|
+
"Share image must be an http(s) URL or a data:image/... base64 string."
|
|
1093
|
+
);
|
|
1094
|
+
}
|
|
1095
|
+
return {
|
|
1096
|
+
...hasText ? { text } : {},
|
|
1097
|
+
...hasScore ? { score: options.score } : {},
|
|
1098
|
+
...hasImage ? { image: options.image } : {}
|
|
1099
|
+
};
|
|
1100
|
+
}
|
|
1101
|
+
async function share(options) {
|
|
1102
|
+
const request = validateRequest(options);
|
|
1103
|
+
const bridge = getBridgeWindow4();
|
|
1104
|
+
if (typeof bridge?.__oasizShareRequest !== "function") {
|
|
1105
|
+
warnMissingBridge2("__oasizShareRequest");
|
|
1106
|
+
throw new Error("Share bridge unavailable");
|
|
1107
|
+
}
|
|
1108
|
+
await bridge.__oasizShareRequest(request);
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
// src/state.ts
|
|
1112
|
+
function isDevelopment5() {
|
|
1113
|
+
const nodeEnv = globalThis.process?.env?.NODE_ENV;
|
|
1114
|
+
return nodeEnv !== "production";
|
|
1115
|
+
}
|
|
1116
|
+
function getBridgeWindow5() {
|
|
1117
|
+
if (typeof window === "undefined") {
|
|
1118
|
+
return void 0;
|
|
1119
|
+
}
|
|
1120
|
+
return window;
|
|
1121
|
+
}
|
|
1058
1122
|
function isPlainObject(value) {
|
|
1059
1123
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1060
1124
|
return false;
|
|
@@ -1062,22 +1126,22 @@ function isPlainObject(value) {
|
|
|
1062
1126
|
const proto = Object.getPrototypeOf(value);
|
|
1063
1127
|
return proto === Object.prototype || proto === null;
|
|
1064
1128
|
}
|
|
1065
|
-
function
|
|
1066
|
-
if (
|
|
1129
|
+
function warnMissingBridge3(methodName) {
|
|
1130
|
+
if (isDevelopment5()) {
|
|
1067
1131
|
console.warn(
|
|
1068
1132
|
"[oasiz/sdk] " + methodName + " bridge is unavailable. This is expected in local development."
|
|
1069
1133
|
);
|
|
1070
1134
|
}
|
|
1071
1135
|
}
|
|
1072
1136
|
function loadGameState() {
|
|
1073
|
-
const bridge =
|
|
1137
|
+
const bridge = getBridgeWindow5();
|
|
1074
1138
|
if (typeof bridge?.loadGameState !== "function") {
|
|
1075
|
-
|
|
1139
|
+
warnMissingBridge3("loadGameState");
|
|
1076
1140
|
return {};
|
|
1077
1141
|
}
|
|
1078
1142
|
const state = bridge.loadGameState();
|
|
1079
1143
|
if (!isPlainObject(state)) {
|
|
1080
|
-
if (
|
|
1144
|
+
if (isDevelopment5()) {
|
|
1081
1145
|
console.warn(
|
|
1082
1146
|
"[oasiz/sdk] loadGameState returned invalid data. Falling back to empty object."
|
|
1083
1147
|
);
|
|
@@ -1088,35 +1152,35 @@ function loadGameState() {
|
|
|
1088
1152
|
}
|
|
1089
1153
|
function saveGameState(state) {
|
|
1090
1154
|
if (!isPlainObject(state)) {
|
|
1091
|
-
if (
|
|
1155
|
+
if (isDevelopment5()) {
|
|
1092
1156
|
console.warn("[oasiz/sdk] saveGameState expected a plain object:", state);
|
|
1093
1157
|
}
|
|
1094
1158
|
return;
|
|
1095
1159
|
}
|
|
1096
|
-
const bridge =
|
|
1160
|
+
const bridge = getBridgeWindow5();
|
|
1097
1161
|
if (typeof bridge?.saveGameState === "function") {
|
|
1098
1162
|
bridge.saveGameState(state);
|
|
1099
1163
|
return;
|
|
1100
1164
|
}
|
|
1101
|
-
|
|
1165
|
+
warnMissingBridge3("saveGameState");
|
|
1102
1166
|
}
|
|
1103
1167
|
function flushGameState() {
|
|
1104
|
-
const bridge =
|
|
1168
|
+
const bridge = getBridgeWindow5();
|
|
1105
1169
|
if (typeof bridge?.flushGameState === "function") {
|
|
1106
1170
|
bridge.flushGameState();
|
|
1107
1171
|
return;
|
|
1108
1172
|
}
|
|
1109
|
-
|
|
1173
|
+
warnMissingBridge3("flushGameState");
|
|
1110
1174
|
}
|
|
1111
1175
|
|
|
1112
1176
|
// src/lifecycle.ts
|
|
1113
|
-
function
|
|
1177
|
+
function isDevelopment6() {
|
|
1114
1178
|
const nodeEnv = globalThis.process?.env?.NODE_ENV;
|
|
1115
1179
|
return nodeEnv !== "production";
|
|
1116
1180
|
}
|
|
1117
1181
|
function addLifecycleListener(eventName, callback) {
|
|
1118
1182
|
if (typeof window === "undefined") {
|
|
1119
|
-
if (
|
|
1183
|
+
if (isDevelopment6()) {
|
|
1120
1184
|
console.warn(
|
|
1121
1185
|
"[oasiz/sdk] " + eventName + " listener registered without a browser window. This is expected in local development."
|
|
1122
1186
|
);
|
|
@@ -1136,46 +1200,74 @@ function onResume(callback) {
|
|
|
1136
1200
|
}
|
|
1137
1201
|
|
|
1138
1202
|
// src/layout.ts
|
|
1139
|
-
function
|
|
1203
|
+
function isDevelopment7() {
|
|
1140
1204
|
const nodeEnv = globalThis.process?.env?.NODE_ENV;
|
|
1141
1205
|
return nodeEnv !== "production";
|
|
1142
1206
|
}
|
|
1143
|
-
function
|
|
1207
|
+
function getBridgeWindow6() {
|
|
1144
1208
|
if (typeof window === "undefined") {
|
|
1145
1209
|
return void 0;
|
|
1146
1210
|
}
|
|
1147
1211
|
return window;
|
|
1148
1212
|
}
|
|
1149
|
-
function
|
|
1150
|
-
if (
|
|
1213
|
+
function warnMissingBridge4(methodName) {
|
|
1214
|
+
if (isDevelopment7()) {
|
|
1151
1215
|
console.warn(
|
|
1152
1216
|
"[oasiz/sdk] " + methodName + " bridge is unavailable. This is expected in local development."
|
|
1153
1217
|
);
|
|
1154
1218
|
}
|
|
1155
1219
|
}
|
|
1156
|
-
function
|
|
1220
|
+
function normalizeSafeAreaTopPixels(value) {
|
|
1157
1221
|
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
1158
1222
|
return 0;
|
|
1159
1223
|
}
|
|
1160
1224
|
return Math.max(0, value);
|
|
1161
1225
|
}
|
|
1226
|
+
function normalizeSafeAreaTopPercent(value) {
|
|
1227
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
1228
|
+
return 0;
|
|
1229
|
+
}
|
|
1230
|
+
return Math.min(100, Math.max(0, value));
|
|
1231
|
+
}
|
|
1232
|
+
function viewportInnerHeight(bridge) {
|
|
1233
|
+
const h = bridge.innerHeight;
|
|
1234
|
+
if (typeof h !== "number" || !Number.isFinite(h) || h <= 0) {
|
|
1235
|
+
return 0;
|
|
1236
|
+
}
|
|
1237
|
+
return h;
|
|
1238
|
+
}
|
|
1239
|
+
function pixelsTopToPercentOfViewport(pixels, bridge) {
|
|
1240
|
+
const h = viewportInnerHeight(bridge);
|
|
1241
|
+
if (h <= 0) {
|
|
1242
|
+
return 0;
|
|
1243
|
+
}
|
|
1244
|
+
return normalizeSafeAreaTopPercent(pixels / h * 100);
|
|
1245
|
+
}
|
|
1162
1246
|
function getSafeAreaTop() {
|
|
1163
|
-
const bridge =
|
|
1247
|
+
const bridge = getBridgeWindow6();
|
|
1164
1248
|
if (!bridge) {
|
|
1165
1249
|
return 0;
|
|
1166
1250
|
}
|
|
1251
|
+
if (typeof bridge.getSafeAreaTopPercent === "function") {
|
|
1252
|
+
return normalizeSafeAreaTopPercent(bridge.getSafeAreaTopPercent());
|
|
1253
|
+
}
|
|
1254
|
+
if (typeof bridge.__OASIZ_SAFE_AREA_TOP_PERCENT__ !== "undefined") {
|
|
1255
|
+
return normalizeSafeAreaTopPercent(bridge.__OASIZ_SAFE_AREA_TOP_PERCENT__);
|
|
1256
|
+
}
|
|
1167
1257
|
if (typeof bridge.getSafeAreaTop === "function") {
|
|
1168
|
-
|
|
1258
|
+
const px = normalizeSafeAreaTopPixels(bridge.getSafeAreaTop());
|
|
1259
|
+
return pixelsTopToPercentOfViewport(px, bridge);
|
|
1169
1260
|
}
|
|
1170
1261
|
if (typeof bridge.__OASIZ_SAFE_AREA_TOP__ !== "undefined") {
|
|
1171
|
-
|
|
1262
|
+
const px = normalizeSafeAreaTopPixels(bridge.__OASIZ_SAFE_AREA_TOP__);
|
|
1263
|
+
return pixelsTopToPercentOfViewport(px, bridge);
|
|
1172
1264
|
}
|
|
1173
|
-
|
|
1265
|
+
warnMissingBridge4("getSafeAreaTop");
|
|
1174
1266
|
return 0;
|
|
1175
1267
|
}
|
|
1176
1268
|
function setLeaderboardVisible(visible) {
|
|
1177
1269
|
if (typeof visible !== "boolean") {
|
|
1178
|
-
if (
|
|
1270
|
+
if (isDevelopment7()) {
|
|
1179
1271
|
console.warn(
|
|
1180
1272
|
"[oasiz/sdk] setLeaderboardVisible expected a boolean:",
|
|
1181
1273
|
visible
|
|
@@ -1183,28 +1275,28 @@ function setLeaderboardVisible(visible) {
|
|
|
1183
1275
|
}
|
|
1184
1276
|
return;
|
|
1185
1277
|
}
|
|
1186
|
-
const bridge =
|
|
1278
|
+
const bridge = getBridgeWindow6();
|
|
1187
1279
|
if (typeof bridge?.__oasizSetLeaderboardVisible === "function") {
|
|
1188
1280
|
bridge.__oasizSetLeaderboardVisible(visible);
|
|
1189
1281
|
return;
|
|
1190
1282
|
}
|
|
1191
|
-
|
|
1283
|
+
warnMissingBridge4("__oasizSetLeaderboardVisible");
|
|
1192
1284
|
}
|
|
1193
1285
|
|
|
1194
1286
|
// src/navigation.ts
|
|
1195
1287
|
var activeBackListeners = 0;
|
|
1196
|
-
function
|
|
1288
|
+
function isDevelopment8() {
|
|
1197
1289
|
const nodeEnv = globalThis.process?.env?.NODE_ENV;
|
|
1198
1290
|
return nodeEnv !== "production";
|
|
1199
1291
|
}
|
|
1200
|
-
function
|
|
1292
|
+
function getBridgeWindow7() {
|
|
1201
1293
|
if (typeof window === "undefined") {
|
|
1202
1294
|
return void 0;
|
|
1203
1295
|
}
|
|
1204
1296
|
return window;
|
|
1205
1297
|
}
|
|
1206
|
-
function
|
|
1207
|
-
if (
|
|
1298
|
+
function warnMissingBridge5(methodName) {
|
|
1299
|
+
if (isDevelopment8()) {
|
|
1208
1300
|
console.warn(
|
|
1209
1301
|
"[oasiz/sdk] " + methodName + " bridge is unavailable. This is expected in local development."
|
|
1210
1302
|
);
|
|
@@ -1220,7 +1312,7 @@ function normalizeNavigationError(error) {
|
|
|
1220
1312
|
}
|
|
1221
1313
|
function addNavigationListener(eventName, callback) {
|
|
1222
1314
|
if (typeof window === "undefined") {
|
|
1223
|
-
if (
|
|
1315
|
+
if (isDevelopment8()) {
|
|
1224
1316
|
console.warn(
|
|
1225
1317
|
"[oasiz/sdk] " + eventName + " listener registered without a browser window. This is expected in local development."
|
|
1226
1318
|
);
|
|
@@ -1241,24 +1333,24 @@ function onBackButton(callback) {
|
|
|
1241
1333
|
throw normalizeNavigationError(error);
|
|
1242
1334
|
}
|
|
1243
1335
|
});
|
|
1244
|
-
const bridge =
|
|
1336
|
+
const bridge = getBridgeWindow7();
|
|
1245
1337
|
activeBackListeners += 1;
|
|
1246
1338
|
if (activeBackListeners === 1) {
|
|
1247
1339
|
if (typeof bridge?.__oasizSetBackOverride === "function") {
|
|
1248
1340
|
bridge.__oasizSetBackOverride(true);
|
|
1249
1341
|
} else {
|
|
1250
|
-
|
|
1342
|
+
warnMissingBridge5("__oasizSetBackOverride");
|
|
1251
1343
|
}
|
|
1252
1344
|
}
|
|
1253
1345
|
return () => {
|
|
1254
1346
|
off();
|
|
1255
1347
|
activeBackListeners = Math.max(0, activeBackListeners - 1);
|
|
1256
1348
|
if (activeBackListeners === 0) {
|
|
1257
|
-
const currentBridge =
|
|
1349
|
+
const currentBridge = getBridgeWindow7();
|
|
1258
1350
|
if (typeof currentBridge?.__oasizSetBackOverride === "function") {
|
|
1259
1351
|
currentBridge.__oasizSetBackOverride(false);
|
|
1260
1352
|
} else {
|
|
1261
|
-
|
|
1353
|
+
warnMissingBridge5("__oasizSetBackOverride");
|
|
1262
1354
|
}
|
|
1263
1355
|
}
|
|
1264
1356
|
};
|
|
@@ -1267,17 +1359,18 @@ function onLeaveGame(callback) {
|
|
|
1267
1359
|
return addNavigationListener("oasiz:leave", callback);
|
|
1268
1360
|
}
|
|
1269
1361
|
function leaveGame() {
|
|
1270
|
-
const bridge =
|
|
1362
|
+
const bridge = getBridgeWindow7();
|
|
1271
1363
|
if (typeof bridge?.__oasizLeaveGame === "function") {
|
|
1272
1364
|
bridge.__oasizLeaveGame();
|
|
1273
1365
|
return;
|
|
1274
1366
|
}
|
|
1275
|
-
|
|
1367
|
+
warnMissingBridge5("__oasizLeaveGame");
|
|
1276
1368
|
}
|
|
1277
1369
|
|
|
1278
1370
|
// src/index.ts
|
|
1279
1371
|
var oasiz = {
|
|
1280
1372
|
submitScore,
|
|
1373
|
+
share,
|
|
1281
1374
|
triggerHaptic,
|
|
1282
1375
|
enableLogOverlay,
|
|
1283
1376
|
loadGameState,
|
|
@@ -1327,6 +1420,7 @@ var oasiz = {
|
|
|
1327
1420
|
openInviteModal,
|
|
1328
1421
|
saveGameState,
|
|
1329
1422
|
setLeaderboardVisible,
|
|
1423
|
+
share,
|
|
1330
1424
|
shareRoomCode,
|
|
1331
1425
|
submitScore,
|
|
1332
1426
|
triggerHaptic
|
package/dist/index.d.cts
CHANGED
|
@@ -20,6 +20,11 @@ interface LogOverlayHandle {
|
|
|
20
20
|
show: () => void;
|
|
21
21
|
}
|
|
22
22
|
type GameState = Record<string, unknown>;
|
|
23
|
+
interface ShareRequest {
|
|
24
|
+
image?: string;
|
|
25
|
+
score?: number;
|
|
26
|
+
text?: string;
|
|
27
|
+
}
|
|
23
28
|
|
|
24
29
|
declare function triggerHaptic(type: HapticType): void;
|
|
25
30
|
|
|
@@ -47,6 +52,8 @@ declare function getPlayerAvatar(): string | undefined;
|
|
|
47
52
|
|
|
48
53
|
declare function submitScore(score: number): void;
|
|
49
54
|
|
|
55
|
+
declare function share(options: ShareRequest): Promise<void>;
|
|
56
|
+
|
|
50
57
|
declare function loadGameState(): GameState;
|
|
51
58
|
declare function saveGameState(state: GameState): void;
|
|
52
59
|
declare function flushGameState(): void;
|
|
@@ -55,6 +62,12 @@ type Unsubscribe = () => void;
|
|
|
55
62
|
declare function onPause(callback: () => void): Unsubscribe;
|
|
56
63
|
declare function onResume(callback: () => void): Unsubscribe;
|
|
57
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Top safe-area inset as a percentage of the viewport height (0–100).
|
|
67
|
+
* The host may expose CSS pixels via `getSafeAreaTop` / `__OASIZ_SAFE_AREA_TOP__`
|
|
68
|
+
* (converted using `window.innerHeight`), or percentages via
|
|
69
|
+
* `getSafeAreaTopPercent` / `__OASIZ_SAFE_AREA_TOP_PERCENT__`.
|
|
70
|
+
*/
|
|
58
71
|
declare function getSafeAreaTop(): number;
|
|
59
72
|
declare function setLeaderboardVisible(visible: boolean): void;
|
|
60
73
|
|
|
@@ -64,6 +77,7 @@ declare function leaveGame(): void;
|
|
|
64
77
|
|
|
65
78
|
declare const oasiz: {
|
|
66
79
|
submitScore: typeof submitScore;
|
|
80
|
+
share: typeof share;
|
|
67
81
|
triggerHaptic: typeof triggerHaptic;
|
|
68
82
|
enableLogOverlay: typeof enableLogOverlay;
|
|
69
83
|
loadGameState: typeof loadGameState;
|
|
@@ -85,4 +99,4 @@ declare const oasiz: {
|
|
|
85
99
|
readonly safeAreaTop: number;
|
|
86
100
|
};
|
|
87
101
|
|
|
88
|
-
export { type GameState, type HapticType, type LogOverlayEntry, type LogOverlayHandle, type LogOverlayLevel, type LogOverlayOptions, type ShareRoomCodeOptions, type Unsubscribe, enableLogOverlay, flushGameState, getGameId, getPlayerAvatar, getPlayerName, getRoomCode, getSafeAreaTop, leaveGame, loadGameState, oasiz, onBackButton, onLeaveGame, onPause, onResume, openInviteModal, saveGameState, setLeaderboardVisible, shareRoomCode, submitScore, triggerHaptic };
|
|
102
|
+
export { type GameState, type HapticType, type LogOverlayEntry, type LogOverlayHandle, type LogOverlayLevel, type LogOverlayOptions, type ShareRequest, type ShareRoomCodeOptions, type Unsubscribe, enableLogOverlay, flushGameState, getGameId, getPlayerAvatar, getPlayerName, getRoomCode, getSafeAreaTop, leaveGame, loadGameState, oasiz, onBackButton, onLeaveGame, onPause, onResume, openInviteModal, saveGameState, setLeaderboardVisible, share, shareRoomCode, submitScore, triggerHaptic };
|
package/dist/index.d.ts
CHANGED
|
@@ -20,6 +20,11 @@ interface LogOverlayHandle {
|
|
|
20
20
|
show: () => void;
|
|
21
21
|
}
|
|
22
22
|
type GameState = Record<string, unknown>;
|
|
23
|
+
interface ShareRequest {
|
|
24
|
+
image?: string;
|
|
25
|
+
score?: number;
|
|
26
|
+
text?: string;
|
|
27
|
+
}
|
|
23
28
|
|
|
24
29
|
declare function triggerHaptic(type: HapticType): void;
|
|
25
30
|
|
|
@@ -47,6 +52,8 @@ declare function getPlayerAvatar(): string | undefined;
|
|
|
47
52
|
|
|
48
53
|
declare function submitScore(score: number): void;
|
|
49
54
|
|
|
55
|
+
declare function share(options: ShareRequest): Promise<void>;
|
|
56
|
+
|
|
50
57
|
declare function loadGameState(): GameState;
|
|
51
58
|
declare function saveGameState(state: GameState): void;
|
|
52
59
|
declare function flushGameState(): void;
|
|
@@ -55,6 +62,12 @@ type Unsubscribe = () => void;
|
|
|
55
62
|
declare function onPause(callback: () => void): Unsubscribe;
|
|
56
63
|
declare function onResume(callback: () => void): Unsubscribe;
|
|
57
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Top safe-area inset as a percentage of the viewport height (0–100).
|
|
67
|
+
* The host may expose CSS pixels via `getSafeAreaTop` / `__OASIZ_SAFE_AREA_TOP__`
|
|
68
|
+
* (converted using `window.innerHeight`), or percentages via
|
|
69
|
+
* `getSafeAreaTopPercent` / `__OASIZ_SAFE_AREA_TOP_PERCENT__`.
|
|
70
|
+
*/
|
|
58
71
|
declare function getSafeAreaTop(): number;
|
|
59
72
|
declare function setLeaderboardVisible(visible: boolean): void;
|
|
60
73
|
|
|
@@ -64,6 +77,7 @@ declare function leaveGame(): void;
|
|
|
64
77
|
|
|
65
78
|
declare const oasiz: {
|
|
66
79
|
submitScore: typeof submitScore;
|
|
80
|
+
share: typeof share;
|
|
67
81
|
triggerHaptic: typeof triggerHaptic;
|
|
68
82
|
enableLogOverlay: typeof enableLogOverlay;
|
|
69
83
|
loadGameState: typeof loadGameState;
|
|
@@ -85,4 +99,4 @@ declare const oasiz: {
|
|
|
85
99
|
readonly safeAreaTop: number;
|
|
86
100
|
};
|
|
87
101
|
|
|
88
|
-
export { type GameState, type HapticType, type LogOverlayEntry, type LogOverlayHandle, type LogOverlayLevel, type LogOverlayOptions, type ShareRoomCodeOptions, type Unsubscribe, enableLogOverlay, flushGameState, getGameId, getPlayerAvatar, getPlayerName, getRoomCode, getSafeAreaTop, leaveGame, loadGameState, oasiz, onBackButton, onLeaveGame, onPause, onResume, openInviteModal, saveGameState, setLeaderboardVisible, shareRoomCode, submitScore, triggerHaptic };
|
|
102
|
+
export { type GameState, type HapticType, type LogOverlayEntry, type LogOverlayHandle, type LogOverlayLevel, type LogOverlayOptions, type ShareRequest, type ShareRoomCodeOptions, type Unsubscribe, enableLogOverlay, flushGameState, getGameId, getPlayerAvatar, getPlayerName, getRoomCode, getSafeAreaTop, leaveGame, loadGameState, oasiz, onBackButton, onLeaveGame, onPause, onResume, openInviteModal, saveGameState, setLeaderboardVisible, share, shareRoomCode, submitScore, triggerHaptic };
|
package/dist/index.js
CHANGED
|
@@ -999,7 +999,7 @@ function submitScore(score) {
|
|
|
999
999
|
warnMissingBridge("submitScore");
|
|
1000
1000
|
}
|
|
1001
1001
|
|
|
1002
|
-
// src/
|
|
1002
|
+
// src/share.ts
|
|
1003
1003
|
function isDevelopment4() {
|
|
1004
1004
|
const nodeEnv = globalThis.process?.env?.NODE_ENV;
|
|
1005
1005
|
return nodeEnv !== "production";
|
|
@@ -1010,6 +1010,69 @@ function getBridgeWindow4() {
|
|
|
1010
1010
|
}
|
|
1011
1011
|
return window;
|
|
1012
1012
|
}
|
|
1013
|
+
function warnMissingBridge2(methodName) {
|
|
1014
|
+
if (isDevelopment4()) {
|
|
1015
|
+
console.warn(
|
|
1016
|
+
"[oasiz/sdk] " + methodName + " share bridge is unavailable. This is expected in local development."
|
|
1017
|
+
);
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
function isValidImageReference(image) {
|
|
1021
|
+
if (/^data:image\/[a-zA-Z0-9.+-]+;base64,/.test(image)) {
|
|
1022
|
+
return true;
|
|
1023
|
+
}
|
|
1024
|
+
try {
|
|
1025
|
+
const parsed = new URL(image);
|
|
1026
|
+
return parsed.protocol === "http:" || parsed.protocol === "https:";
|
|
1027
|
+
} catch {
|
|
1028
|
+
return false;
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
function validateRequest(options) {
|
|
1032
|
+
const text = typeof options.text === "string" ? options.text.trim() : "";
|
|
1033
|
+
const hasText = text.length > 0;
|
|
1034
|
+
const hasScore = options.score !== void 0;
|
|
1035
|
+
const hasImage = typeof options.image === "string" && options.image.length > 0;
|
|
1036
|
+
if (!hasText && !hasScore && !hasImage) {
|
|
1037
|
+
throw new Error("Share request requires text, score, or image.");
|
|
1038
|
+
}
|
|
1039
|
+
if (hasScore) {
|
|
1040
|
+
if (typeof options.score !== "number" || !Number.isInteger(options.score) || options.score < 0) {
|
|
1041
|
+
throw new Error("Share score must be a non-negative integer.");
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
if (hasImage && !isValidImageReference(options.image)) {
|
|
1045
|
+
throw new Error(
|
|
1046
|
+
"Share image must be an http(s) URL or a data:image/... base64 string."
|
|
1047
|
+
);
|
|
1048
|
+
}
|
|
1049
|
+
return {
|
|
1050
|
+
...hasText ? { text } : {},
|
|
1051
|
+
...hasScore ? { score: options.score } : {},
|
|
1052
|
+
...hasImage ? { image: options.image } : {}
|
|
1053
|
+
};
|
|
1054
|
+
}
|
|
1055
|
+
async function share(options) {
|
|
1056
|
+
const request = validateRequest(options);
|
|
1057
|
+
const bridge = getBridgeWindow4();
|
|
1058
|
+
if (typeof bridge?.__oasizShareRequest !== "function") {
|
|
1059
|
+
warnMissingBridge2("__oasizShareRequest");
|
|
1060
|
+
throw new Error("Share bridge unavailable");
|
|
1061
|
+
}
|
|
1062
|
+
await bridge.__oasizShareRequest(request);
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
// src/state.ts
|
|
1066
|
+
function isDevelopment5() {
|
|
1067
|
+
const nodeEnv = globalThis.process?.env?.NODE_ENV;
|
|
1068
|
+
return nodeEnv !== "production";
|
|
1069
|
+
}
|
|
1070
|
+
function getBridgeWindow5() {
|
|
1071
|
+
if (typeof window === "undefined") {
|
|
1072
|
+
return void 0;
|
|
1073
|
+
}
|
|
1074
|
+
return window;
|
|
1075
|
+
}
|
|
1013
1076
|
function isPlainObject(value) {
|
|
1014
1077
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1015
1078
|
return false;
|
|
@@ -1017,22 +1080,22 @@ function isPlainObject(value) {
|
|
|
1017
1080
|
const proto = Object.getPrototypeOf(value);
|
|
1018
1081
|
return proto === Object.prototype || proto === null;
|
|
1019
1082
|
}
|
|
1020
|
-
function
|
|
1021
|
-
if (
|
|
1083
|
+
function warnMissingBridge3(methodName) {
|
|
1084
|
+
if (isDevelopment5()) {
|
|
1022
1085
|
console.warn(
|
|
1023
1086
|
"[oasiz/sdk] " + methodName + " bridge is unavailable. This is expected in local development."
|
|
1024
1087
|
);
|
|
1025
1088
|
}
|
|
1026
1089
|
}
|
|
1027
1090
|
function loadGameState() {
|
|
1028
|
-
const bridge =
|
|
1091
|
+
const bridge = getBridgeWindow5();
|
|
1029
1092
|
if (typeof bridge?.loadGameState !== "function") {
|
|
1030
|
-
|
|
1093
|
+
warnMissingBridge3("loadGameState");
|
|
1031
1094
|
return {};
|
|
1032
1095
|
}
|
|
1033
1096
|
const state = bridge.loadGameState();
|
|
1034
1097
|
if (!isPlainObject(state)) {
|
|
1035
|
-
if (
|
|
1098
|
+
if (isDevelopment5()) {
|
|
1036
1099
|
console.warn(
|
|
1037
1100
|
"[oasiz/sdk] loadGameState returned invalid data. Falling back to empty object."
|
|
1038
1101
|
);
|
|
@@ -1043,35 +1106,35 @@ function loadGameState() {
|
|
|
1043
1106
|
}
|
|
1044
1107
|
function saveGameState(state) {
|
|
1045
1108
|
if (!isPlainObject(state)) {
|
|
1046
|
-
if (
|
|
1109
|
+
if (isDevelopment5()) {
|
|
1047
1110
|
console.warn("[oasiz/sdk] saveGameState expected a plain object:", state);
|
|
1048
1111
|
}
|
|
1049
1112
|
return;
|
|
1050
1113
|
}
|
|
1051
|
-
const bridge =
|
|
1114
|
+
const bridge = getBridgeWindow5();
|
|
1052
1115
|
if (typeof bridge?.saveGameState === "function") {
|
|
1053
1116
|
bridge.saveGameState(state);
|
|
1054
1117
|
return;
|
|
1055
1118
|
}
|
|
1056
|
-
|
|
1119
|
+
warnMissingBridge3("saveGameState");
|
|
1057
1120
|
}
|
|
1058
1121
|
function flushGameState() {
|
|
1059
|
-
const bridge =
|
|
1122
|
+
const bridge = getBridgeWindow5();
|
|
1060
1123
|
if (typeof bridge?.flushGameState === "function") {
|
|
1061
1124
|
bridge.flushGameState();
|
|
1062
1125
|
return;
|
|
1063
1126
|
}
|
|
1064
|
-
|
|
1127
|
+
warnMissingBridge3("flushGameState");
|
|
1065
1128
|
}
|
|
1066
1129
|
|
|
1067
1130
|
// src/lifecycle.ts
|
|
1068
|
-
function
|
|
1131
|
+
function isDevelopment6() {
|
|
1069
1132
|
const nodeEnv = globalThis.process?.env?.NODE_ENV;
|
|
1070
1133
|
return nodeEnv !== "production";
|
|
1071
1134
|
}
|
|
1072
1135
|
function addLifecycleListener(eventName, callback) {
|
|
1073
1136
|
if (typeof window === "undefined") {
|
|
1074
|
-
if (
|
|
1137
|
+
if (isDevelopment6()) {
|
|
1075
1138
|
console.warn(
|
|
1076
1139
|
"[oasiz/sdk] " + eventName + " listener registered without a browser window. This is expected in local development."
|
|
1077
1140
|
);
|
|
@@ -1091,46 +1154,74 @@ function onResume(callback) {
|
|
|
1091
1154
|
}
|
|
1092
1155
|
|
|
1093
1156
|
// src/layout.ts
|
|
1094
|
-
function
|
|
1157
|
+
function isDevelopment7() {
|
|
1095
1158
|
const nodeEnv = globalThis.process?.env?.NODE_ENV;
|
|
1096
1159
|
return nodeEnv !== "production";
|
|
1097
1160
|
}
|
|
1098
|
-
function
|
|
1161
|
+
function getBridgeWindow6() {
|
|
1099
1162
|
if (typeof window === "undefined") {
|
|
1100
1163
|
return void 0;
|
|
1101
1164
|
}
|
|
1102
1165
|
return window;
|
|
1103
1166
|
}
|
|
1104
|
-
function
|
|
1105
|
-
if (
|
|
1167
|
+
function warnMissingBridge4(methodName) {
|
|
1168
|
+
if (isDevelopment7()) {
|
|
1106
1169
|
console.warn(
|
|
1107
1170
|
"[oasiz/sdk] " + methodName + " bridge is unavailable. This is expected in local development."
|
|
1108
1171
|
);
|
|
1109
1172
|
}
|
|
1110
1173
|
}
|
|
1111
|
-
function
|
|
1174
|
+
function normalizeSafeAreaTopPixels(value) {
|
|
1112
1175
|
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
1113
1176
|
return 0;
|
|
1114
1177
|
}
|
|
1115
1178
|
return Math.max(0, value);
|
|
1116
1179
|
}
|
|
1180
|
+
function normalizeSafeAreaTopPercent(value) {
|
|
1181
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
1182
|
+
return 0;
|
|
1183
|
+
}
|
|
1184
|
+
return Math.min(100, Math.max(0, value));
|
|
1185
|
+
}
|
|
1186
|
+
function viewportInnerHeight(bridge) {
|
|
1187
|
+
const h = bridge.innerHeight;
|
|
1188
|
+
if (typeof h !== "number" || !Number.isFinite(h) || h <= 0) {
|
|
1189
|
+
return 0;
|
|
1190
|
+
}
|
|
1191
|
+
return h;
|
|
1192
|
+
}
|
|
1193
|
+
function pixelsTopToPercentOfViewport(pixels, bridge) {
|
|
1194
|
+
const h = viewportInnerHeight(bridge);
|
|
1195
|
+
if (h <= 0) {
|
|
1196
|
+
return 0;
|
|
1197
|
+
}
|
|
1198
|
+
return normalizeSafeAreaTopPercent(pixels / h * 100);
|
|
1199
|
+
}
|
|
1117
1200
|
function getSafeAreaTop() {
|
|
1118
|
-
const bridge =
|
|
1201
|
+
const bridge = getBridgeWindow6();
|
|
1119
1202
|
if (!bridge) {
|
|
1120
1203
|
return 0;
|
|
1121
1204
|
}
|
|
1205
|
+
if (typeof bridge.getSafeAreaTopPercent === "function") {
|
|
1206
|
+
return normalizeSafeAreaTopPercent(bridge.getSafeAreaTopPercent());
|
|
1207
|
+
}
|
|
1208
|
+
if (typeof bridge.__OASIZ_SAFE_AREA_TOP_PERCENT__ !== "undefined") {
|
|
1209
|
+
return normalizeSafeAreaTopPercent(bridge.__OASIZ_SAFE_AREA_TOP_PERCENT__);
|
|
1210
|
+
}
|
|
1122
1211
|
if (typeof bridge.getSafeAreaTop === "function") {
|
|
1123
|
-
|
|
1212
|
+
const px = normalizeSafeAreaTopPixels(bridge.getSafeAreaTop());
|
|
1213
|
+
return pixelsTopToPercentOfViewport(px, bridge);
|
|
1124
1214
|
}
|
|
1125
1215
|
if (typeof bridge.__OASIZ_SAFE_AREA_TOP__ !== "undefined") {
|
|
1126
|
-
|
|
1216
|
+
const px = normalizeSafeAreaTopPixels(bridge.__OASIZ_SAFE_AREA_TOP__);
|
|
1217
|
+
return pixelsTopToPercentOfViewport(px, bridge);
|
|
1127
1218
|
}
|
|
1128
|
-
|
|
1219
|
+
warnMissingBridge4("getSafeAreaTop");
|
|
1129
1220
|
return 0;
|
|
1130
1221
|
}
|
|
1131
1222
|
function setLeaderboardVisible(visible) {
|
|
1132
1223
|
if (typeof visible !== "boolean") {
|
|
1133
|
-
if (
|
|
1224
|
+
if (isDevelopment7()) {
|
|
1134
1225
|
console.warn(
|
|
1135
1226
|
"[oasiz/sdk] setLeaderboardVisible expected a boolean:",
|
|
1136
1227
|
visible
|
|
@@ -1138,28 +1229,28 @@ function setLeaderboardVisible(visible) {
|
|
|
1138
1229
|
}
|
|
1139
1230
|
return;
|
|
1140
1231
|
}
|
|
1141
|
-
const bridge =
|
|
1232
|
+
const bridge = getBridgeWindow6();
|
|
1142
1233
|
if (typeof bridge?.__oasizSetLeaderboardVisible === "function") {
|
|
1143
1234
|
bridge.__oasizSetLeaderboardVisible(visible);
|
|
1144
1235
|
return;
|
|
1145
1236
|
}
|
|
1146
|
-
|
|
1237
|
+
warnMissingBridge4("__oasizSetLeaderboardVisible");
|
|
1147
1238
|
}
|
|
1148
1239
|
|
|
1149
1240
|
// src/navigation.ts
|
|
1150
1241
|
var activeBackListeners = 0;
|
|
1151
|
-
function
|
|
1242
|
+
function isDevelopment8() {
|
|
1152
1243
|
const nodeEnv = globalThis.process?.env?.NODE_ENV;
|
|
1153
1244
|
return nodeEnv !== "production";
|
|
1154
1245
|
}
|
|
1155
|
-
function
|
|
1246
|
+
function getBridgeWindow7() {
|
|
1156
1247
|
if (typeof window === "undefined") {
|
|
1157
1248
|
return void 0;
|
|
1158
1249
|
}
|
|
1159
1250
|
return window;
|
|
1160
1251
|
}
|
|
1161
|
-
function
|
|
1162
|
-
if (
|
|
1252
|
+
function warnMissingBridge5(methodName) {
|
|
1253
|
+
if (isDevelopment8()) {
|
|
1163
1254
|
console.warn(
|
|
1164
1255
|
"[oasiz/sdk] " + methodName + " bridge is unavailable. This is expected in local development."
|
|
1165
1256
|
);
|
|
@@ -1175,7 +1266,7 @@ function normalizeNavigationError(error) {
|
|
|
1175
1266
|
}
|
|
1176
1267
|
function addNavigationListener(eventName, callback) {
|
|
1177
1268
|
if (typeof window === "undefined") {
|
|
1178
|
-
if (
|
|
1269
|
+
if (isDevelopment8()) {
|
|
1179
1270
|
console.warn(
|
|
1180
1271
|
"[oasiz/sdk] " + eventName + " listener registered without a browser window. This is expected in local development."
|
|
1181
1272
|
);
|
|
@@ -1196,24 +1287,24 @@ function onBackButton(callback) {
|
|
|
1196
1287
|
throw normalizeNavigationError(error);
|
|
1197
1288
|
}
|
|
1198
1289
|
});
|
|
1199
|
-
const bridge =
|
|
1290
|
+
const bridge = getBridgeWindow7();
|
|
1200
1291
|
activeBackListeners += 1;
|
|
1201
1292
|
if (activeBackListeners === 1) {
|
|
1202
1293
|
if (typeof bridge?.__oasizSetBackOverride === "function") {
|
|
1203
1294
|
bridge.__oasizSetBackOverride(true);
|
|
1204
1295
|
} else {
|
|
1205
|
-
|
|
1296
|
+
warnMissingBridge5("__oasizSetBackOverride");
|
|
1206
1297
|
}
|
|
1207
1298
|
}
|
|
1208
1299
|
return () => {
|
|
1209
1300
|
off();
|
|
1210
1301
|
activeBackListeners = Math.max(0, activeBackListeners - 1);
|
|
1211
1302
|
if (activeBackListeners === 0) {
|
|
1212
|
-
const currentBridge =
|
|
1303
|
+
const currentBridge = getBridgeWindow7();
|
|
1213
1304
|
if (typeof currentBridge?.__oasizSetBackOverride === "function") {
|
|
1214
1305
|
currentBridge.__oasizSetBackOverride(false);
|
|
1215
1306
|
} else {
|
|
1216
|
-
|
|
1307
|
+
warnMissingBridge5("__oasizSetBackOverride");
|
|
1217
1308
|
}
|
|
1218
1309
|
}
|
|
1219
1310
|
};
|
|
@@ -1222,17 +1313,18 @@ function onLeaveGame(callback) {
|
|
|
1222
1313
|
return addNavigationListener("oasiz:leave", callback);
|
|
1223
1314
|
}
|
|
1224
1315
|
function leaveGame() {
|
|
1225
|
-
const bridge =
|
|
1316
|
+
const bridge = getBridgeWindow7();
|
|
1226
1317
|
if (typeof bridge?.__oasizLeaveGame === "function") {
|
|
1227
1318
|
bridge.__oasizLeaveGame();
|
|
1228
1319
|
return;
|
|
1229
1320
|
}
|
|
1230
|
-
|
|
1321
|
+
warnMissingBridge5("__oasizLeaveGame");
|
|
1231
1322
|
}
|
|
1232
1323
|
|
|
1233
1324
|
// src/index.ts
|
|
1234
1325
|
var oasiz = {
|
|
1235
1326
|
submitScore,
|
|
1327
|
+
share,
|
|
1236
1328
|
triggerHaptic,
|
|
1237
1329
|
enableLogOverlay,
|
|
1238
1330
|
loadGameState,
|
|
@@ -1281,6 +1373,7 @@ export {
|
|
|
1281
1373
|
openInviteModal,
|
|
1282
1374
|
saveGameState,
|
|
1283
1375
|
setLeaderboardVisible,
|
|
1376
|
+
share,
|
|
1284
1377
|
shareRoomCode,
|
|
1285
1378
|
submitScore,
|
|
1286
1379
|
triggerHaptic
|