@oasiz/sdk 1.5.5 → 1.5.6

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 CHANGED
@@ -196,11 +196,32 @@ private onGameOver(): void {
196
196
 
197
197
  ### Layout
198
198
 
199
- Use the runtime safe-area value instead of hardcoded top offsets. The SDK returns the top inset as **a percentage of the active viewport height (0–100)**. If the host exposes CSS pixels via `window.getSafeAreaTop()` or `window.__OASIZ_SAFE_AREA_TOP__`, the SDK converts using `window.visualViewport.height` when available, then `window.innerHeight`, then document height. The host may instead set **`window.getSafeAreaTopPercent()`** or **`window.__OASIZ_SAFE_AREA_TOP_PERCENT__`** (0–100) and that value is used directly. When no host bridge is available, the SDK falls back to CSS `env(safe-area-inset-top)` / `constant(safe-area-inset-top)`.
199
+ Use runtime viewport insets instead of direct CSS `env(safe-area-inset-*)` reads or hardcoded offsets. The SDK resolves host-provided Oasiz values first, then browser CSS `env(safe-area-inset-*)`, then legacy `constant(safe-area-inset-*)`, and finally `0`.
200
+
201
+ The top inset preserves the existing Oasiz game-safe top behavior: host chrome, invite UI, and leaderboard clearance can contribute to it. Left, right, and bottom are device safe-area insets today and may include future host UI obstructions.
202
+
203
+ #### `oasiz.getViewportInsets(): ViewportInsets`
204
+
205
+ Returns effective viewport insets in both CSS pixels and normalized percentages:
206
+
207
+ ```ts
208
+ const insets = oasiz.getViewportInsets();
209
+ hud.style.paddingTop = `${insets.pixels.top}px`;
210
+ hud.style.paddingRight = `${insets.pixels.right}px`;
211
+ hud.style.paddingBottom = `${insets.pixels.bottom}px`;
212
+ hud.style.paddingLeft = `${insets.pixels.left}px`;
213
+ ```
214
+
215
+ Percentages use the matching active viewport axis:
216
+
217
+ - `top` / `bottom` are percentages of viewport height
218
+ - `left` / `right` are percentages of viewport width
219
+
220
+ Hosts may expose pixels via `window.getViewportInsets()` or `window.__OASIZ_VIEWPORT_INSETS__`, for example `{ top, right, bottom, left }` or `{ pixels: { top, right, bottom, left } }`. Hosts may expose percentages via `window.getViewportInsetsPercent()`, `window.__OASIZ_VIEWPORT_INSETS_PERCENT__`, or a `percent` object. Per-side globals such as `window.__OASIZ_SAFE_AREA_BOTTOM__` are also supported.
200
221
 
201
222
  #### `oasiz.getSafeAreaTop(): number`
202
223
 
203
- Returns the top inset as a percentage of viewport height (0–100). To get pixels in JavaScript, multiply by `window.visualViewport?.height || 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`.
224
+ Legacy alias for `oasiz.getViewportInsets().percent.top`. Returns the top inset as a percentage of viewport height (0–100). To get pixels in JavaScript, prefer `oasiz.getViewportInsets().pixels.top`. In CSS, the percent value matches **`vh`** units (for example `12.5vh` for 12.5% of the viewport height). Unsupported hosts return `0`.
204
225
 
205
226
  ```ts
206
227
  const safeTopPct = oasiz.getSafeAreaTop();
@@ -211,6 +232,10 @@ document.documentElement.style.setProperty("--safe-top", `${safeTopPct}vh`);
211
232
 
212
233
  Getter alias for `getSafeAreaTop()`.
213
234
 
235
+ #### `oasiz.viewportInsets`
236
+
237
+ Getter alias for `getViewportInsets()`.
238
+
214
239
  Recommended CSS pattern:
215
240
 
216
241
  ```css
@@ -397,6 +422,7 @@ import {
397
422
  openInviteModal,
398
423
  enableLogOverlay,
399
424
  getSafeAreaTop,
425
+ getViewportInsets,
400
426
  setLeaderboardVisible,
401
427
  onPause,
402
428
  onResume,
@@ -501,7 +527,8 @@ public class GameManager : MonoBehaviour
501
527
  | `oasiz.loadGameState()` | `OasizSDK.LoadGameState()` → `Dictionary<string, object>` |
502
528
  | `oasiz.saveGameState(obj)` | `OasizSDK.SaveGameState(Dictionary<string, object>)` |
503
529
  | `oasiz.flushGameState()` | `OasizSDK.FlushGameState()` |
504
- | `oasiz.getSafeAreaTop()` / `safeAreaTop` | `OasizSDK.GetSafeAreaTop()` / `OasizSDK.SafeAreaTop` (`float`, 0–100, % of viewport height) |
530
+ | `oasiz.getViewportInsets()` / `viewportInsets` | `OasizSDK.GetViewportInsets()` (`ViewportInsets`, each side 0–100, % of matching viewport axis) |
531
+ | `oasiz.getSafeAreaTop()` / `safeAreaTop` | `OasizSDK.GetSafeAreaTop()` / `OasizSDK.SafeAreaTop` (`float`, 0–100, % of viewport height; legacy alias for top viewport inset) |
505
532
  | `oasiz.setLeaderboardVisible(v)` | `OasizSDK.SetLeaderboardVisible(bool)` |
506
533
  | `oasiz.onPause` / `onResume` | `OasizSDK.OnPause` / `OnResume` static events |
507
534
  | `oasiz.onBackButton` | `OasizSDK.OnBackButton` or `SubscribeBackButton(Action)` (reference-counts `__oasizSetBackOverride`) |
package/dist/index.cjs CHANGED
@@ -30,6 +30,7 @@ __export(index_exports, {
30
30
  getPlayerName: () => getPlayerName,
31
31
  getRoomCode: () => getRoomCode,
32
32
  getSafeAreaTop: () => getSafeAreaTop,
33
+ getViewportInsets: () => getViewportInsets,
33
34
  leaveGame: () => leaveGame,
34
35
  loadGameState: () => loadGameState,
35
36
  oasiz: () => oasiz,
@@ -1302,6 +1303,21 @@ function onResume(callback) {
1302
1303
  }
1303
1304
 
1304
1305
  // src/layout.ts
1306
+ var INSET_SIDES = ["top", "right", "bottom", "left"];
1307
+ var SIDE_TO_AXIS = {
1308
+ top: "vertical",
1309
+ right: "horizontal",
1310
+ bottom: "vertical",
1311
+ left: "horizontal"
1312
+ };
1313
+ function createInsetEdges(value) {
1314
+ return {
1315
+ top: value,
1316
+ right: value,
1317
+ bottom: value,
1318
+ left: value
1319
+ };
1320
+ }
1305
1321
  function isDevelopment9() {
1306
1322
  const nodeEnv = globalThis.process?.env?.NODE_ENV;
1307
1323
  return nodeEnv !== "production";
@@ -1319,6 +1335,9 @@ function warnMissingBridge6(methodName) {
1319
1335
  );
1320
1336
  }
1321
1337
  }
1338
+ function isRecord(value) {
1339
+ return typeof value === "object" && value !== null;
1340
+ }
1322
1341
  function toFiniteNumber(value) {
1323
1342
  if (typeof value !== "number" || !Number.isFinite(value)) {
1324
1343
  if (typeof value !== "string") {
@@ -1332,36 +1351,36 @@ function toFiniteNumber(value) {
1332
1351
  }
1333
1352
  return value;
1334
1353
  }
1335
- function clampSafeAreaTopPixels(value) {
1354
+ function clampInsetPixels(value) {
1336
1355
  const numeric = toFiniteNumber(value);
1337
1356
  if (typeof numeric === "undefined") {
1338
- return 0;
1357
+ return void 0;
1339
1358
  }
1340
1359
  return Math.max(0, numeric);
1341
1360
  }
1342
- function normalizeSafeAreaTopPercent(value) {
1361
+ function normalizeInsetPercent(value) {
1343
1362
  const numeric = toFiniteNumber(value);
1344
1363
  if (typeof numeric === "undefined") {
1345
1364
  return void 0;
1346
1365
  }
1347
1366
  return Math.min(100, Math.max(0, numeric));
1348
1367
  }
1349
- function getViewportHeight(bridge) {
1350
- const visualViewportHeight = bridge.visualViewport?.height;
1351
- if (typeof visualViewportHeight === "number" && Number.isFinite(visualViewportHeight) && visualViewportHeight > 0) {
1352
- return visualViewportHeight;
1368
+ function getViewportSize2(bridge, axis) {
1369
+ const visualViewportSize = axis === "vertical" ? bridge.visualViewport?.height : bridge.visualViewport?.width;
1370
+ if (typeof visualViewportSize === "number" && Number.isFinite(visualViewportSize) && visualViewportSize > 0) {
1371
+ return visualViewportSize;
1353
1372
  }
1354
- const innerHeight = bridge.innerHeight;
1355
- if (typeof innerHeight === "number" && Number.isFinite(innerHeight) && innerHeight > 0) {
1356
- return innerHeight;
1373
+ const innerSize = axis === "vertical" ? bridge.innerHeight : bridge.innerWidth;
1374
+ if (typeof innerSize === "number" && Number.isFinite(innerSize) && innerSize > 0) {
1375
+ return innerSize;
1357
1376
  }
1358
- const documentHeight = bridge.document?.documentElement?.clientHeight;
1359
- if (typeof documentHeight === "number" && Number.isFinite(documentHeight) && documentHeight > 0) {
1360
- return documentHeight;
1377
+ const documentSize = axis === "vertical" ? bridge.document?.documentElement?.clientHeight : bridge.document?.documentElement?.clientWidth;
1378
+ if (typeof documentSize === "number" && Number.isFinite(documentSize) && documentSize > 0) {
1379
+ return documentSize;
1361
1380
  }
1362
- const bodyHeight = bridge.document?.body?.clientHeight;
1363
- if (typeof bodyHeight === "number" && Number.isFinite(bodyHeight) && bodyHeight > 0) {
1364
- return bodyHeight;
1381
+ const bodySize = axis === "vertical" ? bridge.document?.body?.clientHeight : bridge.document?.body?.clientWidth;
1382
+ if (typeof bodySize === "number" && Number.isFinite(bodySize) && bodySize > 0) {
1383
+ return bodySize;
1365
1384
  }
1366
1385
  return 0;
1367
1386
  }
@@ -1382,7 +1401,7 @@ function readCssSafeAreaValue(bridge, cssValue) {
1382
1401
  probe.style.paddingTop = cssValue;
1383
1402
  root.appendChild(probe);
1384
1403
  try {
1385
- return clampSafeAreaTopPixels(bridge.getComputedStyle(probe).paddingTop);
1404
+ return clampInsetPixels(bridge.getComputedStyle(probe).paddingTop) ?? 0;
1386
1405
  } finally {
1387
1406
  if (typeof probe.remove === "function") {
1388
1407
  probe.remove();
@@ -1391,12 +1410,18 @@ function readCssSafeAreaValue(bridge, cssValue) {
1391
1410
  }
1392
1411
  }
1393
1412
  }
1394
- function readCssSafeAreaTopPixels(bridge) {
1395
- const envPixels = readCssSafeAreaValue(bridge, "env(safe-area-inset-top)");
1413
+ function readCssSafeAreaPixels(bridge, side) {
1414
+ const envPixels = readCssSafeAreaValue(
1415
+ bridge,
1416
+ "env(safe-area-inset-" + side + ")"
1417
+ );
1396
1418
  if (envPixels > 0) {
1397
1419
  return envPixels;
1398
1420
  }
1399
- return readCssSafeAreaValue(bridge, "constant(safe-area-inset-top)");
1421
+ return readCssSafeAreaValue(
1422
+ bridge,
1423
+ "constant(safe-area-inset-" + side + ")"
1424
+ );
1400
1425
  }
1401
1426
  function getDevicePixelRatio(bridge) {
1402
1427
  const dpr = bridge.devicePixelRatio;
@@ -1408,9 +1433,12 @@ function getDevicePixelRatio(bridge) {
1408
1433
  function roughlyEqualPixels(a, b) {
1409
1434
  return Math.abs(a - b) <= 2;
1410
1435
  }
1411
- function normalizeSafeAreaTopPixels(value, bridge) {
1412
- const pixels = clampSafeAreaTopPixels(value);
1413
- const cssEnvPixels = readCssSafeAreaTopPixels(bridge);
1436
+ function normalizeInsetPixels(value, bridge, side) {
1437
+ const pixels = clampInsetPixels(value);
1438
+ if (typeof pixels === "undefined") {
1439
+ return void 0;
1440
+ }
1441
+ const cssEnvPixels = readCssSafeAreaPixels(bridge, side);
1414
1442
  if (pixels <= 0) {
1415
1443
  return cssEnvPixels;
1416
1444
  }
@@ -1420,65 +1448,166 @@ function normalizeSafeAreaTopPixels(value, bridge) {
1420
1448
  }
1421
1449
  return pixels;
1422
1450
  }
1423
- function pixelsTopToPercentOfViewport(pixels, bridge) {
1424
- const h = getViewportHeight(bridge);
1425
- if (h <= 0) {
1451
+ function pixelsToPercentOfViewport(pixels, bridge, side) {
1452
+ const size = getViewportSize2(bridge, SIDE_TO_AXIS[side]);
1453
+ if (size <= 0) {
1454
+ return 0;
1455
+ }
1456
+ return normalizeInsetPercent(pixels / size * 100) ?? 0;
1457
+ }
1458
+ function percentToPixelsOfViewport(percent, bridge, side) {
1459
+ const size = getViewportSize2(bridge, SIDE_TO_AXIS[side]);
1460
+ if (size <= 0) {
1426
1461
  return 0;
1427
1462
  }
1428
- return normalizeSafeAreaTopPercent(pixels / h * 100) ?? 0;
1463
+ return percent / 100 * size;
1429
1464
  }
1430
- function cssSafeAreaTopPercent(bridge) {
1431
- return pixelsTopToPercentOfViewport(readCssSafeAreaTopPixels(bridge), bridge);
1465
+ function cssSafeAreaPercent(bridge, side) {
1466
+ return pixelsToPercentOfViewport(readCssSafeAreaPixels(bridge, side), bridge, side);
1432
1467
  }
1433
- function resolvePercentValue(value, bridge) {
1434
- const percent = normalizeSafeAreaTopPercent(value);
1468
+ function resolvePercentValue(value, bridge, side) {
1469
+ const percent = normalizeInsetPercent(value);
1435
1470
  if (typeof percent === "undefined") {
1436
1471
  return void 0;
1437
1472
  }
1438
- return percent > 0 ? percent : cssSafeAreaTopPercent(bridge);
1473
+ return percent > 0 ? percent : cssSafeAreaPercent(bridge, side);
1439
1474
  }
1440
- function resolvePixelValue(value, bridge) {
1475
+ function resolvePixelValue(value, bridge, side) {
1441
1476
  const numeric = toFiniteNumber(value);
1442
1477
  if (typeof numeric === "undefined") {
1443
1478
  return void 0;
1444
1479
  }
1445
- return pixelsTopToPercentOfViewport(normalizeSafeAreaTopPixels(numeric, bridge), bridge);
1480
+ return normalizeInsetPixels(numeric, bridge, side);
1446
1481
  }
1447
- function getSafeAreaTop() {
1448
- const bridge = getBridgeWindow8();
1449
- if (!bridge) {
1450
- return 0;
1482
+ function sideSuffix(side) {
1483
+ switch (side) {
1484
+ case "top":
1485
+ return "Top";
1486
+ case "right":
1487
+ return "Right";
1488
+ case "bottom":
1489
+ return "Bottom";
1490
+ case "left":
1491
+ return "Left";
1451
1492
  }
1452
- if (typeof bridge.getSafeAreaTopPercent === "function") {
1453
- const percent = resolvePercentValue(bridge.getSafeAreaTopPercent(), bridge);
1454
- if (typeof percent !== "undefined") {
1455
- return percent;
1456
- }
1493
+ }
1494
+ function callBridgeFunction(bridge, name) {
1495
+ const fn = bridge[name];
1496
+ if (typeof fn !== "function") {
1497
+ return void 0;
1457
1498
  }
1458
- if (typeof bridge.__OASIZ_SAFE_AREA_TOP_PERCENT__ !== "undefined") {
1459
- const percent = resolvePercentValue(bridge.__OASIZ_SAFE_AREA_TOP_PERCENT__, bridge);
1460
- if (typeof percent !== "undefined") {
1461
- return percent;
1462
- }
1499
+ try {
1500
+ return fn.call(bridge);
1501
+ } catch (error) {
1502
+ console.error("[oasiz/sdk] " + String(name) + " failed:", error);
1503
+ return void 0;
1463
1504
  }
1464
- if (typeof bridge.getSafeAreaTop === "function") {
1465
- const percent = resolvePixelValue(bridge.getSafeAreaTop(), bridge);
1466
- if (typeof percent !== "undefined") {
1467
- return percent;
1468
- }
1505
+ }
1506
+ function readInsetObjectValue(value, side, group) {
1507
+ if (!isRecord(value)) {
1508
+ return void 0;
1469
1509
  }
1470
- if (typeof bridge.__OASIZ_SAFE_AREA_TOP__ !== "undefined") {
1471
- const percent = resolvePixelValue(bridge.__OASIZ_SAFE_AREA_TOP__, bridge);
1472
- if (typeof percent !== "undefined") {
1473
- return percent;
1474
- }
1510
+ if (group) {
1511
+ return isRecord(value[group]) ? value[group][side] : void 0;
1475
1512
  }
1476
- const cssPercent = cssSafeAreaTopPercent(bridge);
1477
- if (cssPercent > 0) {
1478
- return cssPercent;
1513
+ return value[side];
1514
+ }
1515
+ function firstDefined(...values) {
1516
+ return values.find((value) => typeof value !== "undefined");
1517
+ }
1518
+ function readHostInsetSources(bridge) {
1519
+ return {
1520
+ globalPixels: bridge.__OASIZ_VIEWPORT_INSETS__,
1521
+ globalPercent: bridge.__OASIZ_VIEWPORT_INSETS_PERCENT__,
1522
+ methodPixels: callBridgeFunction(bridge, "getViewportInsets"),
1523
+ methodPercent: callBridgeFunction(bridge, "getViewportInsetsPercent")
1524
+ };
1525
+ }
1526
+ function readIndividualPercentValue(bridge, side) {
1527
+ const suffix = sideSuffix(side);
1528
+ return firstDefined(
1529
+ callBridgeFunction(
1530
+ bridge,
1531
+ "getSafeArea" + suffix + "Percent"
1532
+ ),
1533
+ bridge["__OASIZ_SAFE_AREA_" + side.toUpperCase() + "_PERCENT__"]
1534
+ );
1535
+ }
1536
+ function readIndividualPixelValue(bridge, side) {
1537
+ const suffix = sideSuffix(side);
1538
+ return firstDefined(
1539
+ callBridgeFunction(
1540
+ bridge,
1541
+ "getSafeArea" + suffix
1542
+ ),
1543
+ bridge["__OASIZ_SAFE_AREA_" + side.toUpperCase() + "__"]
1544
+ );
1545
+ }
1546
+ function resolveInsetSide(bridge, sources, side) {
1547
+ const percentCandidate = firstDefined(
1548
+ readInsetObjectValue(sources.methodPercent, side, "percent"),
1549
+ readInsetObjectValue(sources.methodPercent, side),
1550
+ readInsetObjectValue(sources.globalPercent, side, "percent"),
1551
+ readInsetObjectValue(sources.globalPercent, side),
1552
+ readInsetObjectValue(sources.methodPixels, side, "percent"),
1553
+ readInsetObjectValue(sources.globalPixels, side, "percent"),
1554
+ readIndividualPercentValue(bridge, side)
1555
+ );
1556
+ const percent = resolvePercentValue(percentCandidate, bridge, side);
1557
+ if (typeof percent !== "undefined") {
1558
+ return {
1559
+ pixels: percentToPixelsOfViewport(percent, bridge, side),
1560
+ percent
1561
+ };
1479
1562
  }
1480
- warnMissingBridge6("getSafeAreaTop");
1481
- return 0;
1563
+ const pixelCandidate = firstDefined(
1564
+ readInsetObjectValue(sources.methodPixels, side, "pixels"),
1565
+ readInsetObjectValue(sources.methodPixels, side),
1566
+ readInsetObjectValue(sources.globalPixels, side, "pixels"),
1567
+ readInsetObjectValue(sources.globalPixels, side),
1568
+ readIndividualPixelValue(bridge, side)
1569
+ );
1570
+ const pixels = resolvePixelValue(pixelCandidate, bridge, side);
1571
+ if (typeof pixels !== "undefined") {
1572
+ return {
1573
+ pixels,
1574
+ percent: pixelsToPercentOfViewport(pixels, bridge, side)
1575
+ };
1576
+ }
1577
+ const cssPixels = readCssSafeAreaPixels(bridge, side);
1578
+ return {
1579
+ pixels: cssPixels,
1580
+ percent: pixelsToPercentOfViewport(cssPixels, bridge, side)
1581
+ };
1582
+ }
1583
+ function getViewportInsets() {
1584
+ const bridge = getBridgeWindow8();
1585
+ if (!bridge) {
1586
+ return {
1587
+ pixels: createInsetEdges(0),
1588
+ percent: createInsetEdges(0)
1589
+ };
1590
+ }
1591
+ const sources = readHostInsetSources(bridge);
1592
+ const pixels = createInsetEdges(0);
1593
+ const percent = createInsetEdges(0);
1594
+ for (const side of INSET_SIDES) {
1595
+ const resolved = resolveInsetSide(bridge, sources, side);
1596
+ pixels[side] = resolved.pixels;
1597
+ percent[side] = resolved.percent;
1598
+ }
1599
+ return { pixels, percent };
1600
+ }
1601
+ function getSafeAreaTop() {
1602
+ const bridge = getBridgeWindow8();
1603
+ if (!bridge) {
1604
+ return 0;
1605
+ }
1606
+ const top = getViewportInsets().percent.top;
1607
+ if (top <= 0) {
1608
+ warnMissingBridge6("getSafeAreaTop");
1609
+ }
1610
+ return top;
1482
1611
  }
1483
1612
  function setLeaderboardVisible(visible) {
1484
1613
  if (typeof visible !== "boolean") {
@@ -1599,6 +1728,7 @@ var oasiz = {
1599
1728
  onPause,
1600
1729
  onResume,
1601
1730
  getSafeAreaTop,
1731
+ getViewportInsets,
1602
1732
  setLeaderboardVisible,
1603
1733
  onBackButton,
1604
1734
  onLeaveGame,
@@ -1620,6 +1750,9 @@ var oasiz = {
1620
1750
  },
1621
1751
  get safeAreaTop() {
1622
1752
  return getSafeAreaTop();
1753
+ },
1754
+ get viewportInsets() {
1755
+ return getViewportInsets();
1623
1756
  }
1624
1757
  };
1625
1758
  // Annotate the CommonJS export names for ESM import in node:
@@ -1634,6 +1767,7 @@ var oasiz = {
1634
1767
  getPlayerName,
1635
1768
  getRoomCode,
1636
1769
  getSafeAreaTop,
1770
+ getViewportInsets,
1637
1771
  leaveGame,
1638
1772
  loadGameState,
1639
1773
  oasiz,
package/dist/index.d.cts CHANGED
@@ -1,3 +1,28 @@
1
+ type ViewportInsetSide = "top" | "right" | "bottom" | "left";
2
+ interface ViewportInsetEdges {
3
+ top: number;
4
+ right: number;
5
+ bottom: number;
6
+ left: number;
7
+ }
8
+ interface ViewportInsets {
9
+ pixels: ViewportInsetEdges;
10
+ percent: ViewportInsetEdges;
11
+ }
12
+ /**
13
+ * Effective viewport insets that game UI should avoid.
14
+ *
15
+ * `top` preserves the existing Oasiz game-safe top behavior: host chrome and
16
+ * invite/leaderboard clearance can contribute to it. Other sides are device
17
+ * safe-area insets today, and can include future host UI obstructions.
18
+ */
19
+ declare function getViewportInsets(): ViewportInsets;
20
+ /**
21
+ * Legacy alias for the top entry of `getViewportInsets().percent`.
22
+ */
23
+ declare function getSafeAreaTop(): number;
24
+ declare function setLeaderboardVisible(visible: boolean): void;
25
+
1
26
  type HapticType = "light" | "medium" | "heavy" | "success" | "error";
2
27
  type LogOverlayLevel = "debug" | "log" | "info" | "warn" | "error";
3
28
  interface LogOverlayEntry {
@@ -196,15 +221,6 @@ type Unsubscribe = () => void;
196
221
  declare function onPause(callback: () => void): Unsubscribe;
197
222
  declare function onResume(callback: () => void): Unsubscribe;
198
223
 
199
- /**
200
- * Top safe-area inset as a percentage of the viewport height (0–100).
201
- * The host may expose CSS pixels via `getSafeAreaTop` / `__OASIZ_SAFE_AREA_TOP__`
202
- * (converted using `window.innerHeight`), or percentages via
203
- * `getSafeAreaTopPercent` / `__OASIZ_SAFE_AREA_TOP_PERCENT__`.
204
- */
205
- declare function getSafeAreaTop(): number;
206
- declare function setLeaderboardVisible(visible: boolean): void;
207
-
208
224
  declare function onBackButton(callback: () => void): Unsubscribe;
209
225
  declare function onLeaveGame(callback: () => void): Unsubscribe;
210
226
  declare function leaveGame(): void;
@@ -225,6 +241,7 @@ declare const oasiz: {
225
241
  onPause: typeof onPause;
226
242
  onResume: typeof onResume;
227
243
  getSafeAreaTop: typeof getSafeAreaTop;
244
+ getViewportInsets: typeof getViewportInsets;
228
245
  setLeaderboardVisible: typeof setLeaderboardVisible;
229
246
  onBackButton: typeof onBackButton;
230
247
  onLeaveGame: typeof onLeaveGame;
@@ -235,6 +252,7 @@ declare const oasiz: {
235
252
  readonly playerName: string | undefined;
236
253
  readonly playerAvatar: string | undefined;
237
254
  readonly safeAreaTop: number;
255
+ readonly viewportInsets: ViewportInsets;
238
256
  };
239
257
 
240
- export { type FacingFrameMap, type GameState, type HapticType, type LogOverlayEntry, type LogOverlayHandle, type LogOverlayLevel, type LogOverlayOptions, type PlayerCharacter, type ScoreEditResult, type ShareRequest, type ShareRoomCodeOptions, type TextureAtlas, type TextureAtlasAnimation, type TextureAtlasFrame, type Unsubscribe, addScore, enableLogOverlay, flushGameState, getGameId, getPlayerAvatar, getPlayerCharacter, getPlayerId, getPlayerName, getRoomCode, getSafeAreaTop, leaveGame, loadGameState, oasiz, onBackButton, onLeaveGame, onPause, onResume, openInviteModal, saveGameState, setLeaderboardVisible, setScore, share, shareRoomCode, submitScore, triggerHaptic };
258
+ export { type FacingFrameMap, type GameState, type HapticType, type LogOverlayEntry, type LogOverlayHandle, type LogOverlayLevel, type LogOverlayOptions, type PlayerCharacter, type ScoreEditResult, type ShareRequest, type ShareRoomCodeOptions, type TextureAtlas, type TextureAtlasAnimation, type TextureAtlasFrame, type Unsubscribe, type ViewportInsetEdges, type ViewportInsetSide, type ViewportInsets, addScore, enableLogOverlay, flushGameState, getGameId, getPlayerAvatar, getPlayerCharacter, getPlayerId, getPlayerName, getRoomCode, getSafeAreaTop, getViewportInsets, leaveGame, loadGameState, oasiz, onBackButton, onLeaveGame, onPause, onResume, openInviteModal, saveGameState, setLeaderboardVisible, setScore, share, shareRoomCode, submitScore, triggerHaptic };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,28 @@
1
+ type ViewportInsetSide = "top" | "right" | "bottom" | "left";
2
+ interface ViewportInsetEdges {
3
+ top: number;
4
+ right: number;
5
+ bottom: number;
6
+ left: number;
7
+ }
8
+ interface ViewportInsets {
9
+ pixels: ViewportInsetEdges;
10
+ percent: ViewportInsetEdges;
11
+ }
12
+ /**
13
+ * Effective viewport insets that game UI should avoid.
14
+ *
15
+ * `top` preserves the existing Oasiz game-safe top behavior: host chrome and
16
+ * invite/leaderboard clearance can contribute to it. Other sides are device
17
+ * safe-area insets today, and can include future host UI obstructions.
18
+ */
19
+ declare function getViewportInsets(): ViewportInsets;
20
+ /**
21
+ * Legacy alias for the top entry of `getViewportInsets().percent`.
22
+ */
23
+ declare function getSafeAreaTop(): number;
24
+ declare function setLeaderboardVisible(visible: boolean): void;
25
+
1
26
  type HapticType = "light" | "medium" | "heavy" | "success" | "error";
2
27
  type LogOverlayLevel = "debug" | "log" | "info" | "warn" | "error";
3
28
  interface LogOverlayEntry {
@@ -196,15 +221,6 @@ type Unsubscribe = () => void;
196
221
  declare function onPause(callback: () => void): Unsubscribe;
197
222
  declare function onResume(callback: () => void): Unsubscribe;
198
223
 
199
- /**
200
- * Top safe-area inset as a percentage of the viewport height (0–100).
201
- * The host may expose CSS pixels via `getSafeAreaTop` / `__OASIZ_SAFE_AREA_TOP__`
202
- * (converted using `window.innerHeight`), or percentages via
203
- * `getSafeAreaTopPercent` / `__OASIZ_SAFE_AREA_TOP_PERCENT__`.
204
- */
205
- declare function getSafeAreaTop(): number;
206
- declare function setLeaderboardVisible(visible: boolean): void;
207
-
208
224
  declare function onBackButton(callback: () => void): Unsubscribe;
209
225
  declare function onLeaveGame(callback: () => void): Unsubscribe;
210
226
  declare function leaveGame(): void;
@@ -225,6 +241,7 @@ declare const oasiz: {
225
241
  onPause: typeof onPause;
226
242
  onResume: typeof onResume;
227
243
  getSafeAreaTop: typeof getSafeAreaTop;
244
+ getViewportInsets: typeof getViewportInsets;
228
245
  setLeaderboardVisible: typeof setLeaderboardVisible;
229
246
  onBackButton: typeof onBackButton;
230
247
  onLeaveGame: typeof onLeaveGame;
@@ -235,6 +252,7 @@ declare const oasiz: {
235
252
  readonly playerName: string | undefined;
236
253
  readonly playerAvatar: string | undefined;
237
254
  readonly safeAreaTop: number;
255
+ readonly viewportInsets: ViewportInsets;
238
256
  };
239
257
 
240
- export { type FacingFrameMap, type GameState, type HapticType, type LogOverlayEntry, type LogOverlayHandle, type LogOverlayLevel, type LogOverlayOptions, type PlayerCharacter, type ScoreEditResult, type ShareRequest, type ShareRoomCodeOptions, type TextureAtlas, type TextureAtlasAnimation, type TextureAtlasFrame, type Unsubscribe, addScore, enableLogOverlay, flushGameState, getGameId, getPlayerAvatar, getPlayerCharacter, getPlayerId, getPlayerName, getRoomCode, getSafeAreaTop, leaveGame, loadGameState, oasiz, onBackButton, onLeaveGame, onPause, onResume, openInviteModal, saveGameState, setLeaderboardVisible, setScore, share, shareRoomCode, submitScore, triggerHaptic };
258
+ export { type FacingFrameMap, type GameState, type HapticType, type LogOverlayEntry, type LogOverlayHandle, type LogOverlayLevel, type LogOverlayOptions, type PlayerCharacter, type ScoreEditResult, type ShareRequest, type ShareRoomCodeOptions, type TextureAtlas, type TextureAtlasAnimation, type TextureAtlasFrame, type Unsubscribe, type ViewportInsetEdges, type ViewportInsetSide, type ViewportInsets, addScore, enableLogOverlay, flushGameState, getGameId, getPlayerAvatar, getPlayerCharacter, getPlayerId, getPlayerName, getRoomCode, getSafeAreaTop, getViewportInsets, leaveGame, loadGameState, oasiz, onBackButton, onLeaveGame, onPause, onResume, openInviteModal, saveGameState, setLeaderboardVisible, setScore, share, shareRoomCode, submitScore, triggerHaptic };
package/dist/index.js CHANGED
@@ -1252,6 +1252,21 @@ function onResume(callback) {
1252
1252
  }
1253
1253
 
1254
1254
  // src/layout.ts
1255
+ var INSET_SIDES = ["top", "right", "bottom", "left"];
1256
+ var SIDE_TO_AXIS = {
1257
+ top: "vertical",
1258
+ right: "horizontal",
1259
+ bottom: "vertical",
1260
+ left: "horizontal"
1261
+ };
1262
+ function createInsetEdges(value) {
1263
+ return {
1264
+ top: value,
1265
+ right: value,
1266
+ bottom: value,
1267
+ left: value
1268
+ };
1269
+ }
1255
1270
  function isDevelopment9() {
1256
1271
  const nodeEnv = globalThis.process?.env?.NODE_ENV;
1257
1272
  return nodeEnv !== "production";
@@ -1269,6 +1284,9 @@ function warnMissingBridge6(methodName) {
1269
1284
  );
1270
1285
  }
1271
1286
  }
1287
+ function isRecord(value) {
1288
+ return typeof value === "object" && value !== null;
1289
+ }
1272
1290
  function toFiniteNumber(value) {
1273
1291
  if (typeof value !== "number" || !Number.isFinite(value)) {
1274
1292
  if (typeof value !== "string") {
@@ -1282,36 +1300,36 @@ function toFiniteNumber(value) {
1282
1300
  }
1283
1301
  return value;
1284
1302
  }
1285
- function clampSafeAreaTopPixels(value) {
1303
+ function clampInsetPixels(value) {
1286
1304
  const numeric = toFiniteNumber(value);
1287
1305
  if (typeof numeric === "undefined") {
1288
- return 0;
1306
+ return void 0;
1289
1307
  }
1290
1308
  return Math.max(0, numeric);
1291
1309
  }
1292
- function normalizeSafeAreaTopPercent(value) {
1310
+ function normalizeInsetPercent(value) {
1293
1311
  const numeric = toFiniteNumber(value);
1294
1312
  if (typeof numeric === "undefined") {
1295
1313
  return void 0;
1296
1314
  }
1297
1315
  return Math.min(100, Math.max(0, numeric));
1298
1316
  }
1299
- function getViewportHeight(bridge) {
1300
- const visualViewportHeight = bridge.visualViewport?.height;
1301
- if (typeof visualViewportHeight === "number" && Number.isFinite(visualViewportHeight) && visualViewportHeight > 0) {
1302
- return visualViewportHeight;
1317
+ function getViewportSize2(bridge, axis) {
1318
+ const visualViewportSize = axis === "vertical" ? bridge.visualViewport?.height : bridge.visualViewport?.width;
1319
+ if (typeof visualViewportSize === "number" && Number.isFinite(visualViewportSize) && visualViewportSize > 0) {
1320
+ return visualViewportSize;
1303
1321
  }
1304
- const innerHeight = bridge.innerHeight;
1305
- if (typeof innerHeight === "number" && Number.isFinite(innerHeight) && innerHeight > 0) {
1306
- return innerHeight;
1322
+ const innerSize = axis === "vertical" ? bridge.innerHeight : bridge.innerWidth;
1323
+ if (typeof innerSize === "number" && Number.isFinite(innerSize) && innerSize > 0) {
1324
+ return innerSize;
1307
1325
  }
1308
- const documentHeight = bridge.document?.documentElement?.clientHeight;
1309
- if (typeof documentHeight === "number" && Number.isFinite(documentHeight) && documentHeight > 0) {
1310
- return documentHeight;
1326
+ const documentSize = axis === "vertical" ? bridge.document?.documentElement?.clientHeight : bridge.document?.documentElement?.clientWidth;
1327
+ if (typeof documentSize === "number" && Number.isFinite(documentSize) && documentSize > 0) {
1328
+ return documentSize;
1311
1329
  }
1312
- const bodyHeight = bridge.document?.body?.clientHeight;
1313
- if (typeof bodyHeight === "number" && Number.isFinite(bodyHeight) && bodyHeight > 0) {
1314
- return bodyHeight;
1330
+ const bodySize = axis === "vertical" ? bridge.document?.body?.clientHeight : bridge.document?.body?.clientWidth;
1331
+ if (typeof bodySize === "number" && Number.isFinite(bodySize) && bodySize > 0) {
1332
+ return bodySize;
1315
1333
  }
1316
1334
  return 0;
1317
1335
  }
@@ -1332,7 +1350,7 @@ function readCssSafeAreaValue(bridge, cssValue) {
1332
1350
  probe.style.paddingTop = cssValue;
1333
1351
  root.appendChild(probe);
1334
1352
  try {
1335
- return clampSafeAreaTopPixels(bridge.getComputedStyle(probe).paddingTop);
1353
+ return clampInsetPixels(bridge.getComputedStyle(probe).paddingTop) ?? 0;
1336
1354
  } finally {
1337
1355
  if (typeof probe.remove === "function") {
1338
1356
  probe.remove();
@@ -1341,12 +1359,18 @@ function readCssSafeAreaValue(bridge, cssValue) {
1341
1359
  }
1342
1360
  }
1343
1361
  }
1344
- function readCssSafeAreaTopPixels(bridge) {
1345
- const envPixels = readCssSafeAreaValue(bridge, "env(safe-area-inset-top)");
1362
+ function readCssSafeAreaPixels(bridge, side) {
1363
+ const envPixels = readCssSafeAreaValue(
1364
+ bridge,
1365
+ "env(safe-area-inset-" + side + ")"
1366
+ );
1346
1367
  if (envPixels > 0) {
1347
1368
  return envPixels;
1348
1369
  }
1349
- return readCssSafeAreaValue(bridge, "constant(safe-area-inset-top)");
1370
+ return readCssSafeAreaValue(
1371
+ bridge,
1372
+ "constant(safe-area-inset-" + side + ")"
1373
+ );
1350
1374
  }
1351
1375
  function getDevicePixelRatio(bridge) {
1352
1376
  const dpr = bridge.devicePixelRatio;
@@ -1358,9 +1382,12 @@ function getDevicePixelRatio(bridge) {
1358
1382
  function roughlyEqualPixels(a, b) {
1359
1383
  return Math.abs(a - b) <= 2;
1360
1384
  }
1361
- function normalizeSafeAreaTopPixels(value, bridge) {
1362
- const pixels = clampSafeAreaTopPixels(value);
1363
- const cssEnvPixels = readCssSafeAreaTopPixels(bridge);
1385
+ function normalizeInsetPixels(value, bridge, side) {
1386
+ const pixels = clampInsetPixels(value);
1387
+ if (typeof pixels === "undefined") {
1388
+ return void 0;
1389
+ }
1390
+ const cssEnvPixels = readCssSafeAreaPixels(bridge, side);
1364
1391
  if (pixels <= 0) {
1365
1392
  return cssEnvPixels;
1366
1393
  }
@@ -1370,65 +1397,166 @@ function normalizeSafeAreaTopPixels(value, bridge) {
1370
1397
  }
1371
1398
  return pixels;
1372
1399
  }
1373
- function pixelsTopToPercentOfViewport(pixels, bridge) {
1374
- const h = getViewportHeight(bridge);
1375
- if (h <= 0) {
1400
+ function pixelsToPercentOfViewport(pixels, bridge, side) {
1401
+ const size = getViewportSize2(bridge, SIDE_TO_AXIS[side]);
1402
+ if (size <= 0) {
1403
+ return 0;
1404
+ }
1405
+ return normalizeInsetPercent(pixels / size * 100) ?? 0;
1406
+ }
1407
+ function percentToPixelsOfViewport(percent, bridge, side) {
1408
+ const size = getViewportSize2(bridge, SIDE_TO_AXIS[side]);
1409
+ if (size <= 0) {
1376
1410
  return 0;
1377
1411
  }
1378
- return normalizeSafeAreaTopPercent(pixels / h * 100) ?? 0;
1412
+ return percent / 100 * size;
1379
1413
  }
1380
- function cssSafeAreaTopPercent(bridge) {
1381
- return pixelsTopToPercentOfViewport(readCssSafeAreaTopPixels(bridge), bridge);
1414
+ function cssSafeAreaPercent(bridge, side) {
1415
+ return pixelsToPercentOfViewport(readCssSafeAreaPixels(bridge, side), bridge, side);
1382
1416
  }
1383
- function resolvePercentValue(value, bridge) {
1384
- const percent = normalizeSafeAreaTopPercent(value);
1417
+ function resolvePercentValue(value, bridge, side) {
1418
+ const percent = normalizeInsetPercent(value);
1385
1419
  if (typeof percent === "undefined") {
1386
1420
  return void 0;
1387
1421
  }
1388
- return percent > 0 ? percent : cssSafeAreaTopPercent(bridge);
1422
+ return percent > 0 ? percent : cssSafeAreaPercent(bridge, side);
1389
1423
  }
1390
- function resolvePixelValue(value, bridge) {
1424
+ function resolvePixelValue(value, bridge, side) {
1391
1425
  const numeric = toFiniteNumber(value);
1392
1426
  if (typeof numeric === "undefined") {
1393
1427
  return void 0;
1394
1428
  }
1395
- return pixelsTopToPercentOfViewport(normalizeSafeAreaTopPixels(numeric, bridge), bridge);
1429
+ return normalizeInsetPixels(numeric, bridge, side);
1396
1430
  }
1397
- function getSafeAreaTop() {
1398
- const bridge = getBridgeWindow8();
1399
- if (!bridge) {
1400
- return 0;
1431
+ function sideSuffix(side) {
1432
+ switch (side) {
1433
+ case "top":
1434
+ return "Top";
1435
+ case "right":
1436
+ return "Right";
1437
+ case "bottom":
1438
+ return "Bottom";
1439
+ case "left":
1440
+ return "Left";
1401
1441
  }
1402
- if (typeof bridge.getSafeAreaTopPercent === "function") {
1403
- const percent = resolvePercentValue(bridge.getSafeAreaTopPercent(), bridge);
1404
- if (typeof percent !== "undefined") {
1405
- return percent;
1406
- }
1442
+ }
1443
+ function callBridgeFunction(bridge, name) {
1444
+ const fn = bridge[name];
1445
+ if (typeof fn !== "function") {
1446
+ return void 0;
1407
1447
  }
1408
- if (typeof bridge.__OASIZ_SAFE_AREA_TOP_PERCENT__ !== "undefined") {
1409
- const percent = resolvePercentValue(bridge.__OASIZ_SAFE_AREA_TOP_PERCENT__, bridge);
1410
- if (typeof percent !== "undefined") {
1411
- return percent;
1412
- }
1448
+ try {
1449
+ return fn.call(bridge);
1450
+ } catch (error) {
1451
+ console.error("[oasiz/sdk] " + String(name) + " failed:", error);
1452
+ return void 0;
1413
1453
  }
1414
- if (typeof bridge.getSafeAreaTop === "function") {
1415
- const percent = resolvePixelValue(bridge.getSafeAreaTop(), bridge);
1416
- if (typeof percent !== "undefined") {
1417
- return percent;
1418
- }
1454
+ }
1455
+ function readInsetObjectValue(value, side, group) {
1456
+ if (!isRecord(value)) {
1457
+ return void 0;
1419
1458
  }
1420
- if (typeof bridge.__OASIZ_SAFE_AREA_TOP__ !== "undefined") {
1421
- const percent = resolvePixelValue(bridge.__OASIZ_SAFE_AREA_TOP__, bridge);
1422
- if (typeof percent !== "undefined") {
1423
- return percent;
1424
- }
1459
+ if (group) {
1460
+ return isRecord(value[group]) ? value[group][side] : void 0;
1425
1461
  }
1426
- const cssPercent = cssSafeAreaTopPercent(bridge);
1427
- if (cssPercent > 0) {
1428
- return cssPercent;
1462
+ return value[side];
1463
+ }
1464
+ function firstDefined(...values) {
1465
+ return values.find((value) => typeof value !== "undefined");
1466
+ }
1467
+ function readHostInsetSources(bridge) {
1468
+ return {
1469
+ globalPixels: bridge.__OASIZ_VIEWPORT_INSETS__,
1470
+ globalPercent: bridge.__OASIZ_VIEWPORT_INSETS_PERCENT__,
1471
+ methodPixels: callBridgeFunction(bridge, "getViewportInsets"),
1472
+ methodPercent: callBridgeFunction(bridge, "getViewportInsetsPercent")
1473
+ };
1474
+ }
1475
+ function readIndividualPercentValue(bridge, side) {
1476
+ const suffix = sideSuffix(side);
1477
+ return firstDefined(
1478
+ callBridgeFunction(
1479
+ bridge,
1480
+ "getSafeArea" + suffix + "Percent"
1481
+ ),
1482
+ bridge["__OASIZ_SAFE_AREA_" + side.toUpperCase() + "_PERCENT__"]
1483
+ );
1484
+ }
1485
+ function readIndividualPixelValue(bridge, side) {
1486
+ const suffix = sideSuffix(side);
1487
+ return firstDefined(
1488
+ callBridgeFunction(
1489
+ bridge,
1490
+ "getSafeArea" + suffix
1491
+ ),
1492
+ bridge["__OASIZ_SAFE_AREA_" + side.toUpperCase() + "__"]
1493
+ );
1494
+ }
1495
+ function resolveInsetSide(bridge, sources, side) {
1496
+ const percentCandidate = firstDefined(
1497
+ readInsetObjectValue(sources.methodPercent, side, "percent"),
1498
+ readInsetObjectValue(sources.methodPercent, side),
1499
+ readInsetObjectValue(sources.globalPercent, side, "percent"),
1500
+ readInsetObjectValue(sources.globalPercent, side),
1501
+ readInsetObjectValue(sources.methodPixels, side, "percent"),
1502
+ readInsetObjectValue(sources.globalPixels, side, "percent"),
1503
+ readIndividualPercentValue(bridge, side)
1504
+ );
1505
+ const percent = resolvePercentValue(percentCandidate, bridge, side);
1506
+ if (typeof percent !== "undefined") {
1507
+ return {
1508
+ pixels: percentToPixelsOfViewport(percent, bridge, side),
1509
+ percent
1510
+ };
1429
1511
  }
1430
- warnMissingBridge6("getSafeAreaTop");
1431
- return 0;
1512
+ const pixelCandidate = firstDefined(
1513
+ readInsetObjectValue(sources.methodPixels, side, "pixels"),
1514
+ readInsetObjectValue(sources.methodPixels, side),
1515
+ readInsetObjectValue(sources.globalPixels, side, "pixels"),
1516
+ readInsetObjectValue(sources.globalPixels, side),
1517
+ readIndividualPixelValue(bridge, side)
1518
+ );
1519
+ const pixels = resolvePixelValue(pixelCandidate, bridge, side);
1520
+ if (typeof pixels !== "undefined") {
1521
+ return {
1522
+ pixels,
1523
+ percent: pixelsToPercentOfViewport(pixels, bridge, side)
1524
+ };
1525
+ }
1526
+ const cssPixels = readCssSafeAreaPixels(bridge, side);
1527
+ return {
1528
+ pixels: cssPixels,
1529
+ percent: pixelsToPercentOfViewport(cssPixels, bridge, side)
1530
+ };
1531
+ }
1532
+ function getViewportInsets() {
1533
+ const bridge = getBridgeWindow8();
1534
+ if (!bridge) {
1535
+ return {
1536
+ pixels: createInsetEdges(0),
1537
+ percent: createInsetEdges(0)
1538
+ };
1539
+ }
1540
+ const sources = readHostInsetSources(bridge);
1541
+ const pixels = createInsetEdges(0);
1542
+ const percent = createInsetEdges(0);
1543
+ for (const side of INSET_SIDES) {
1544
+ const resolved = resolveInsetSide(bridge, sources, side);
1545
+ pixels[side] = resolved.pixels;
1546
+ percent[side] = resolved.percent;
1547
+ }
1548
+ return { pixels, percent };
1549
+ }
1550
+ function getSafeAreaTop() {
1551
+ const bridge = getBridgeWindow8();
1552
+ if (!bridge) {
1553
+ return 0;
1554
+ }
1555
+ const top = getViewportInsets().percent.top;
1556
+ if (top <= 0) {
1557
+ warnMissingBridge6("getSafeAreaTop");
1558
+ }
1559
+ return top;
1432
1560
  }
1433
1561
  function setLeaderboardVisible(visible) {
1434
1562
  if (typeof visible !== "boolean") {
@@ -1549,6 +1677,7 @@ var oasiz = {
1549
1677
  onPause,
1550
1678
  onResume,
1551
1679
  getSafeAreaTop,
1680
+ getViewportInsets,
1552
1681
  setLeaderboardVisible,
1553
1682
  onBackButton,
1554
1683
  onLeaveGame,
@@ -1570,6 +1699,9 @@ var oasiz = {
1570
1699
  },
1571
1700
  get safeAreaTop() {
1572
1701
  return getSafeAreaTop();
1702
+ },
1703
+ get viewportInsets() {
1704
+ return getViewportInsets();
1573
1705
  }
1574
1706
  };
1575
1707
  export {
@@ -1583,6 +1715,7 @@ export {
1583
1715
  getPlayerName,
1584
1716
  getRoomCode,
1585
1717
  getSafeAreaTop,
1718
+ getViewportInsets,
1586
1719
  leaveGame,
1587
1720
  loadGameState,
1588
1721
  oasiz,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oasiz/sdk",
3
- "version": "1.5.5",
3
+ "version": "1.5.6",
4
4
  "description": "Typed SDK for Oasiz game platform bridge APIs.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",