@oasiz/sdk 1.6.1 → 1.7.0
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 +85 -464
- package/dist/index.cjs +231 -1943
- package/dist/index.d.cts +102 -248
- package/dist/index.d.ts +102 -248
- package/dist/index.js +220 -1932
- package/package.json +4 -14
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// src/
|
|
1
|
+
// src/haptics.ts
|
|
2
2
|
function isDevelopment() {
|
|
3
3
|
const nodeEnv = globalThis.process?.env?.NODE_ENV;
|
|
4
4
|
return nodeEnv !== "production";
|
|
@@ -9,1014 +9,72 @@ function getBridgeWindow() {
|
|
|
9
9
|
}
|
|
10
10
|
return window;
|
|
11
11
|
}
|
|
12
|
-
function warnMissingBridge(methodName) {
|
|
13
|
-
if (isDevelopment()) {
|
|
14
|
-
console.warn(
|
|
15
|
-
"[oasiz/sdk] " + methodName + " bridge is unavailable. This is expected in local development."
|
|
16
|
-
);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
async function getPlayerCharacter() {
|
|
20
|
-
const bridge = getBridgeWindow();
|
|
21
|
-
if (typeof bridge?.__oasizGetPlayerCharacter !== "function") {
|
|
22
|
-
warnMissingBridge("getPlayerCharacter");
|
|
23
|
-
return null;
|
|
24
|
-
}
|
|
25
|
-
try {
|
|
26
|
-
const result = await bridge.__oasizGetPlayerCharacter();
|
|
27
|
-
return result ?? null;
|
|
28
|
-
} catch (error) {
|
|
29
|
-
if (isDevelopment()) {
|
|
30
|
-
console.error("[oasiz/sdk] getPlayerCharacter failed:", error);
|
|
31
|
-
}
|
|
32
|
-
return null;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// src/haptics.ts
|
|
37
|
-
function isDevelopment2() {
|
|
38
|
-
const nodeEnv = globalThis.process?.env?.NODE_ENV;
|
|
39
|
-
return nodeEnv !== "production";
|
|
40
|
-
}
|
|
41
|
-
function getBridgeWindow2() {
|
|
42
|
-
if (typeof window === "undefined") {
|
|
43
|
-
return void 0;
|
|
44
|
-
}
|
|
45
|
-
return window;
|
|
46
|
-
}
|
|
47
12
|
function triggerHaptic(type) {
|
|
48
|
-
const bridge =
|
|
13
|
+
const bridge = getBridgeWindow();
|
|
49
14
|
if (typeof bridge?.triggerHaptic === "function") {
|
|
50
15
|
bridge.triggerHaptic(type);
|
|
51
16
|
return;
|
|
52
17
|
}
|
|
53
|
-
if (
|
|
18
|
+
if (isDevelopment()) {
|
|
54
19
|
console.warn(
|
|
55
20
|
"[oasiz/sdk] triggerHaptic bridge is unavailable. This is expected in local development."
|
|
56
21
|
);
|
|
57
22
|
}
|
|
58
23
|
}
|
|
59
24
|
|
|
60
|
-
// src/log-overlay.ts
|
|
61
|
-
var CONSOLE_METHODS = [
|
|
62
|
-
"debug",
|
|
63
|
-
"log",
|
|
64
|
-
"info",
|
|
65
|
-
"warn",
|
|
66
|
-
"error"
|
|
67
|
-
];
|
|
68
|
-
var DEFAULT_MAX_ENTRIES = 200;
|
|
69
|
-
var DEFAULT_TITLE = "SDK Logs";
|
|
70
|
-
var OVERLAY_MARGIN = 12;
|
|
71
|
-
var DEFAULT_COLLAPSED_WIDTH = 156;
|
|
72
|
-
var DEFAULT_COLLAPSED_HEIGHT = 52;
|
|
73
|
-
var DEFAULT_EXPANDED_WIDTH = 565;
|
|
74
|
-
var DEFAULT_EXPANDED_HEIGHT = 372;
|
|
75
|
-
var DRAG_THRESHOLD_PX = 6;
|
|
76
|
-
var MIN_EXPANDED_WIDTH = 160;
|
|
77
|
-
var MIN_EXPANDED_HEIGHT = 110;
|
|
78
|
-
var RESIZE_HOTSPOT_PX = 28;
|
|
79
|
-
var TOP_DRAG_ZONE_PX = 44;
|
|
80
|
-
var NOOP_HANDLE = {
|
|
81
|
-
clear() {
|
|
82
|
-
},
|
|
83
|
-
destroy() {
|
|
84
|
-
},
|
|
85
|
-
hide() {
|
|
86
|
-
},
|
|
87
|
-
isVisible() {
|
|
88
|
-
return false;
|
|
89
|
-
},
|
|
90
|
-
show() {
|
|
91
|
-
}
|
|
92
|
-
};
|
|
93
|
-
function getBrowserWindow() {
|
|
94
|
-
if (typeof window === "undefined") {
|
|
95
|
-
return void 0;
|
|
96
|
-
}
|
|
97
|
-
return window;
|
|
98
|
-
}
|
|
99
|
-
function getDocument() {
|
|
100
|
-
if (typeof document === "undefined") {
|
|
101
|
-
return void 0;
|
|
102
|
-
}
|
|
103
|
-
return document;
|
|
104
|
-
}
|
|
105
|
-
function clampMaxEntries(value) {
|
|
106
|
-
if (!Number.isFinite(value)) {
|
|
107
|
-
return DEFAULT_MAX_ENTRIES;
|
|
108
|
-
}
|
|
109
|
-
return Math.max(10, Math.floor(value));
|
|
110
|
-
}
|
|
111
|
-
function createConsoleSnapshot() {
|
|
112
|
-
const fallback = console.log.bind(console);
|
|
113
|
-
return {
|
|
114
|
-
debug: typeof console.debug === "function" ? console.debug.bind(console) : fallback,
|
|
115
|
-
log: fallback,
|
|
116
|
-
info: typeof console.info === "function" ? console.info.bind(console) : fallback,
|
|
117
|
-
warn: typeof console.warn === "function" ? console.warn.bind(console) : fallback,
|
|
118
|
-
error: typeof console.error === "function" ? console.error.bind(console) : fallback
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
function formatTimestamp(timestamp) {
|
|
122
|
-
const date = new Date(timestamp);
|
|
123
|
-
const hours = String(date.getHours()).padStart(2, "0");
|
|
124
|
-
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
125
|
-
const seconds = String(date.getSeconds()).padStart(2, "0");
|
|
126
|
-
const milliseconds = String(date.getMilliseconds()).padStart(3, "0");
|
|
127
|
-
return "[" + hours + ":" + minutes + ":" + seconds + "." + milliseconds + "]";
|
|
128
|
-
}
|
|
129
|
-
function safeStringify(value) {
|
|
130
|
-
const seen = /* @__PURE__ */ new WeakSet();
|
|
131
|
-
try {
|
|
132
|
-
return JSON.stringify(
|
|
133
|
-
value,
|
|
134
|
-
(_key, candidate) => {
|
|
135
|
-
if (typeof candidate === "bigint") {
|
|
136
|
-
return candidate.toString() + "n";
|
|
137
|
-
}
|
|
138
|
-
if (typeof candidate === "object" && candidate !== null) {
|
|
139
|
-
if (seen.has(candidate)) {
|
|
140
|
-
return "[Circular]";
|
|
141
|
-
}
|
|
142
|
-
seen.add(candidate);
|
|
143
|
-
}
|
|
144
|
-
return candidate;
|
|
145
|
-
},
|
|
146
|
-
2
|
|
147
|
-
) ?? String(value);
|
|
148
|
-
} catch {
|
|
149
|
-
return String(value);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
function formatArg(value) {
|
|
153
|
-
if (typeof value === "string") {
|
|
154
|
-
return value;
|
|
155
|
-
}
|
|
156
|
-
if (value instanceof Error) {
|
|
157
|
-
if (value.stack) {
|
|
158
|
-
return value.stack;
|
|
159
|
-
}
|
|
160
|
-
return value.name + ": " + value.message;
|
|
161
|
-
}
|
|
162
|
-
if (typeof value === "undefined") {
|
|
163
|
-
return "undefined";
|
|
164
|
-
}
|
|
165
|
-
if (typeof value === "function") {
|
|
166
|
-
return "[Function " + (value.name || "anonymous") + "]";
|
|
167
|
-
}
|
|
168
|
-
return safeStringify(value);
|
|
169
|
-
}
|
|
170
|
-
function formatEntryMessage(args) {
|
|
171
|
-
const message = args.map(formatArg).join(" ");
|
|
172
|
-
if (message.length <= 4e3) {
|
|
173
|
-
return message;
|
|
174
|
-
}
|
|
175
|
-
return message.slice(0, 3997) + "...";
|
|
176
|
-
}
|
|
177
|
-
function createEntry(level, args, id) {
|
|
178
|
-
return {
|
|
179
|
-
id,
|
|
180
|
-
level,
|
|
181
|
-
message: formatEntryMessage(args),
|
|
182
|
-
timestamp: Date.now()
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
function createButton(label) {
|
|
186
|
-
const button = document.createElement("button");
|
|
187
|
-
button.type = "button";
|
|
188
|
-
button.textContent = label;
|
|
189
|
-
button.style.cssText = [
|
|
190
|
-
"appearance:none",
|
|
191
|
-
"border:1px solid rgba(255,255,255,0.18)",
|
|
192
|
-
"background:rgba(255,255,255,0.06)",
|
|
193
|
-
"color:#f8fafc",
|
|
194
|
-
"border-radius:999px",
|
|
195
|
-
"padding:6px 10px",
|
|
196
|
-
"font:600 12px/1.1 ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace",
|
|
197
|
-
"cursor:pointer"
|
|
198
|
-
].join(";");
|
|
199
|
-
return button;
|
|
200
|
-
}
|
|
201
|
-
function getLevelAccent(level) {
|
|
202
|
-
if (level === "error") {
|
|
203
|
-
return {
|
|
204
|
-
lineBackground: "rgba(255, 109, 122, 0.08)"
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
if (level === "warn") {
|
|
208
|
-
return {
|
|
209
|
-
lineBackground: "rgba(255, 196, 94, 0.07)"
|
|
210
|
-
};
|
|
211
|
-
}
|
|
212
|
-
if (level === "info") {
|
|
213
|
-
return {
|
|
214
|
-
lineBackground: "rgba(82, 187, 255, 0.07)"
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
if (level === "debug") {
|
|
218
|
-
return {
|
|
219
|
-
lineBackground: "rgba(166, 137, 255, 0.07)"
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
return {
|
|
223
|
-
lineBackground: "rgba(117, 235, 191, 0.06)"
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
function getViewportSize() {
|
|
227
|
-
const browserWindow = getBrowserWindow();
|
|
228
|
-
return {
|
|
229
|
-
width: Math.max(320, browserWindow?.innerWidth ?? 1280),
|
|
230
|
-
height: Math.max(240, browserWindow?.innerHeight ?? 720)
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
function clampPanelSize(size) {
|
|
234
|
-
const viewport = getViewportSize();
|
|
235
|
-
const maxWidth = Math.max(MIN_EXPANDED_WIDTH, viewport.width - OVERLAY_MARGIN * 2);
|
|
236
|
-
const maxHeight = Math.max(
|
|
237
|
-
MIN_EXPANDED_HEIGHT,
|
|
238
|
-
viewport.height - OVERLAY_MARGIN * 2
|
|
239
|
-
);
|
|
240
|
-
return {
|
|
241
|
-
width: Math.min(maxWidth, Math.max(MIN_EXPANDED_WIDTH, size.width)),
|
|
242
|
-
height: Math.min(maxHeight, Math.max(MIN_EXPANDED_HEIGHT, size.height))
|
|
243
|
-
};
|
|
244
|
-
}
|
|
245
|
-
function getOverlaySize(state) {
|
|
246
|
-
if (state.expanded && state.panelSize) {
|
|
247
|
-
return state.panelSize;
|
|
248
|
-
}
|
|
249
|
-
const rect = state.ui?.root && typeof state.ui.root.getBoundingClientRect === "function" ? state.ui.root.getBoundingClientRect() : null;
|
|
250
|
-
if (rect && Number.isFinite(rect.width) && Number.isFinite(rect.height)) {
|
|
251
|
-
return {
|
|
252
|
-
width: Math.max(1, rect.width),
|
|
253
|
-
height: Math.max(1, rect.height)
|
|
254
|
-
};
|
|
255
|
-
}
|
|
256
|
-
return state.expanded ? clampPanelSize({
|
|
257
|
-
width: DEFAULT_EXPANDED_WIDTH,
|
|
258
|
-
height: DEFAULT_EXPANDED_HEIGHT
|
|
259
|
-
}) : { width: DEFAULT_COLLAPSED_WIDTH, height: DEFAULT_COLLAPSED_HEIGHT };
|
|
260
|
-
}
|
|
261
|
-
function applyPanelSize(state) {
|
|
262
|
-
if (!state.ui) {
|
|
263
|
-
return;
|
|
264
|
-
}
|
|
265
|
-
if (!state.expanded) {
|
|
266
|
-
state.ui.root.style.width = "auto";
|
|
267
|
-
state.ui.panel.style.width = "min(565px, calc(100vw - 24px))";
|
|
268
|
-
state.ui.panel.style.height = "auto";
|
|
269
|
-
state.ui.entries.style.maxHeight = "min(36vh, 280px)";
|
|
270
|
-
return;
|
|
271
|
-
}
|
|
272
|
-
if (!state.panelSize) {
|
|
273
|
-
state.ui.root.style.width = "min(565px, calc(100vw - 24px))";
|
|
274
|
-
state.ui.panel.style.width = "min(565px, calc(100vw - 24px))";
|
|
275
|
-
state.ui.panel.style.height = "auto";
|
|
276
|
-
state.ui.entries.style.maxHeight = "min(36vh, 280px)";
|
|
277
|
-
return;
|
|
278
|
-
}
|
|
279
|
-
const nextSize = clampPanelSize(
|
|
280
|
-
state.panelSize
|
|
281
|
-
);
|
|
282
|
-
state.panelSize = nextSize;
|
|
283
|
-
state.ui.root.style.width = nextSize.width + "px";
|
|
284
|
-
state.ui.panel.style.width = "100%";
|
|
285
|
-
state.ui.panel.style.height = nextSize.height + "px";
|
|
286
|
-
state.ui.entries.style.maxHeight = Math.max(72, nextSize.height - 88) + "px";
|
|
287
|
-
}
|
|
288
|
-
function clampPosition(point, state) {
|
|
289
|
-
const viewport = getViewportSize();
|
|
290
|
-
const size = getOverlaySize(state);
|
|
291
|
-
const maxX = Math.max(OVERLAY_MARGIN, viewport.width - size.width - OVERLAY_MARGIN);
|
|
292
|
-
const maxY = Math.max(
|
|
293
|
-
OVERLAY_MARGIN,
|
|
294
|
-
viewport.height - size.height - OVERLAY_MARGIN
|
|
295
|
-
);
|
|
296
|
-
return {
|
|
297
|
-
x: Math.min(maxX, Math.max(OVERLAY_MARGIN, point.x)),
|
|
298
|
-
y: Math.min(maxY, Math.max(OVERLAY_MARGIN, point.y))
|
|
299
|
-
};
|
|
300
|
-
}
|
|
301
|
-
function applyOverlayPosition(state) {
|
|
302
|
-
if (!state.ui) {
|
|
303
|
-
return;
|
|
304
|
-
}
|
|
305
|
-
if (!state.position) {
|
|
306
|
-
const viewport = getViewportSize();
|
|
307
|
-
const size = getOverlaySize(state);
|
|
308
|
-
state.position = clampPosition(
|
|
309
|
-
{
|
|
310
|
-
x: viewport.width - size.width - OVERLAY_MARGIN,
|
|
311
|
-
y: viewport.height - size.height - OVERLAY_MARGIN
|
|
312
|
-
},
|
|
313
|
-
state
|
|
314
|
-
);
|
|
315
|
-
} else {
|
|
316
|
-
state.position = clampPosition(state.position, state);
|
|
317
|
-
}
|
|
318
|
-
state.ui.root.style.left = state.position.x + "px";
|
|
319
|
-
state.ui.root.style.top = state.position.y + "px";
|
|
320
|
-
}
|
|
321
|
-
function getPointFromMouseEvent(event) {
|
|
322
|
-
return { x: event.clientX, y: event.clientY };
|
|
323
|
-
}
|
|
324
|
-
function getPointFromTouchEvent(event) {
|
|
325
|
-
const touch = event.touches[0] ?? event.changedTouches[0];
|
|
326
|
-
if (!touch) {
|
|
327
|
-
return null;
|
|
328
|
-
}
|
|
329
|
-
return { x: touch.clientX, y: touch.clientY };
|
|
330
|
-
}
|
|
331
|
-
function stopDragging(state) {
|
|
332
|
-
if (state.isDragging || state.isResizing) {
|
|
333
|
-
state.suppressToggleClickUntil = Date.now() + 180;
|
|
334
|
-
}
|
|
335
|
-
state.isDragging = false;
|
|
336
|
-
state.dragStartPoint = null;
|
|
337
|
-
state.lastDragPoint = null;
|
|
338
|
-
state.removeDragListeners?.();
|
|
339
|
-
state.removeDragListeners = null;
|
|
340
|
-
if (state.ui) {
|
|
341
|
-
state.ui.panel.style.cursor = "default";
|
|
342
|
-
state.ui.dragZone.style.cursor = "grab";
|
|
343
|
-
state.ui.toggleButton.style.cursor = "grab";
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
function stopResizing(state) {
|
|
347
|
-
if (state.isResizing) {
|
|
348
|
-
state.suppressToggleClickUntil = Date.now() + 180;
|
|
349
|
-
}
|
|
350
|
-
state.isResizing = false;
|
|
351
|
-
state.resizeStartPoint = null;
|
|
352
|
-
state.resizeStartSize = null;
|
|
353
|
-
state.removeResizeListeners?.();
|
|
354
|
-
state.removeResizeListeners = null;
|
|
355
|
-
}
|
|
356
|
-
function beginDragTracking(state, startPoint) {
|
|
357
|
-
const doc = getDocument();
|
|
358
|
-
if (!doc) {
|
|
359
|
-
return;
|
|
360
|
-
}
|
|
361
|
-
stopResizing(state);
|
|
362
|
-
stopDragging(state);
|
|
363
|
-
state.dragMoved = false;
|
|
364
|
-
state.dragStartPoint = startPoint;
|
|
365
|
-
state.lastDragPoint = startPoint;
|
|
366
|
-
const handlePointerMove = (nextPoint) => {
|
|
367
|
-
if (!state.dragStartPoint || !state.lastDragPoint || !nextPoint) {
|
|
368
|
-
return;
|
|
369
|
-
}
|
|
370
|
-
if (!state.isDragging) {
|
|
371
|
-
const deltaFromStartX = nextPoint.x - state.dragStartPoint.x;
|
|
372
|
-
const deltaFromStartY = nextPoint.y - state.dragStartPoint.y;
|
|
373
|
-
const distance = Math.sqrt(
|
|
374
|
-
deltaFromStartX * deltaFromStartX + deltaFromStartY * deltaFromStartY
|
|
375
|
-
);
|
|
376
|
-
if (distance < DRAG_THRESHOLD_PX) {
|
|
377
|
-
return;
|
|
378
|
-
}
|
|
379
|
-
state.isDragging = true;
|
|
380
|
-
state.dragMoved = true;
|
|
381
|
-
if (state.ui) {
|
|
382
|
-
state.ui.panel.style.cursor = "grabbing";
|
|
383
|
-
state.ui.dragZone.style.cursor = "grabbing";
|
|
384
|
-
state.ui.toggleButton.style.cursor = "grabbing";
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
const currentPosition = state.position ?? { x: OVERLAY_MARGIN, y: OVERLAY_MARGIN };
|
|
388
|
-
state.position = clampPosition(
|
|
389
|
-
{
|
|
390
|
-
x: currentPosition.x + (nextPoint.x - state.lastDragPoint.x),
|
|
391
|
-
y: currentPosition.y + (nextPoint.y - state.lastDragPoint.y)
|
|
392
|
-
},
|
|
393
|
-
state
|
|
394
|
-
);
|
|
395
|
-
state.lastDragPoint = nextPoint;
|
|
396
|
-
applyOverlayPosition(state);
|
|
397
|
-
};
|
|
398
|
-
const handleMouseMove = (event) => {
|
|
399
|
-
handlePointerMove(getPointFromMouseEvent(event));
|
|
400
|
-
};
|
|
401
|
-
const handleTouchMove = (event) => {
|
|
402
|
-
handlePointerMove(getPointFromTouchEvent(event));
|
|
403
|
-
};
|
|
404
|
-
const handleMouseUp = () => {
|
|
405
|
-
stopDragging(state);
|
|
406
|
-
};
|
|
407
|
-
const handleTouchEnd = () => {
|
|
408
|
-
stopDragging(state);
|
|
409
|
-
};
|
|
410
|
-
doc.addEventListener("mousemove", handleMouseMove);
|
|
411
|
-
doc.addEventListener("mouseup", handleMouseUp);
|
|
412
|
-
doc.addEventListener("touchmove", handleTouchMove, { passive: true });
|
|
413
|
-
doc.addEventListener("touchend", handleTouchEnd);
|
|
414
|
-
doc.addEventListener("touchcancel", handleTouchEnd);
|
|
415
|
-
state.removeDragListeners = () => {
|
|
416
|
-
doc.removeEventListener("mousemove", handleMouseMove);
|
|
417
|
-
doc.removeEventListener("mouseup", handleMouseUp);
|
|
418
|
-
doc.removeEventListener("touchmove", handleTouchMove);
|
|
419
|
-
doc.removeEventListener("touchend", handleTouchEnd);
|
|
420
|
-
doc.removeEventListener("touchcancel", handleTouchEnd);
|
|
421
|
-
};
|
|
422
|
-
}
|
|
423
|
-
function startResizing(state, startPoint) {
|
|
424
|
-
const doc = getDocument();
|
|
425
|
-
if (!doc) {
|
|
426
|
-
return;
|
|
427
|
-
}
|
|
428
|
-
stopDragging(state);
|
|
429
|
-
stopResizing(state);
|
|
430
|
-
state.isResizing = true;
|
|
431
|
-
state.resizeStartPoint = startPoint;
|
|
432
|
-
state.resizeStartSize = state.panelSize ?? clampPanelSize({ width: DEFAULT_EXPANDED_WIDTH, height: DEFAULT_EXPANDED_HEIGHT });
|
|
433
|
-
const handleResizeMove = (nextPoint) => {
|
|
434
|
-
if (!state.isResizing || !state.resizeStartPoint || !state.resizeStartSize || !nextPoint) {
|
|
435
|
-
return;
|
|
436
|
-
}
|
|
437
|
-
state.panelSize = clampPanelSize({
|
|
438
|
-
width: state.resizeStartSize.width + (nextPoint.x - state.resizeStartPoint.x),
|
|
439
|
-
height: state.resizeStartSize.height + (nextPoint.y - state.resizeStartPoint.y)
|
|
440
|
-
});
|
|
441
|
-
applyPanelSize(state);
|
|
442
|
-
applyOverlayPosition(state);
|
|
443
|
-
};
|
|
444
|
-
const handleMouseMove = (event) => {
|
|
445
|
-
handleResizeMove(getPointFromMouseEvent(event));
|
|
446
|
-
};
|
|
447
|
-
const handleTouchMove = (event) => {
|
|
448
|
-
handleResizeMove(getPointFromTouchEvent(event));
|
|
449
|
-
};
|
|
450
|
-
const handleFinish = () => {
|
|
451
|
-
stopResizing(state);
|
|
452
|
-
};
|
|
453
|
-
doc.addEventListener("mousemove", handleMouseMove);
|
|
454
|
-
doc.addEventListener("mouseup", handleFinish);
|
|
455
|
-
doc.addEventListener("touchmove", handleTouchMove, { passive: true });
|
|
456
|
-
doc.addEventListener("touchend", handleFinish);
|
|
457
|
-
doc.addEventListener("touchcancel", handleFinish);
|
|
458
|
-
state.removeResizeListeners = () => {
|
|
459
|
-
doc.removeEventListener("mousemove", handleMouseMove);
|
|
460
|
-
doc.removeEventListener("mouseup", handleFinish);
|
|
461
|
-
doc.removeEventListener("touchmove", handleTouchMove);
|
|
462
|
-
doc.removeEventListener("touchend", handleFinish);
|
|
463
|
-
doc.removeEventListener("touchcancel", handleFinish);
|
|
464
|
-
};
|
|
465
|
-
}
|
|
466
|
-
function isInBottomRightResizeZone(element, point) {
|
|
467
|
-
const rect = element.getBoundingClientRect();
|
|
468
|
-
return point.x >= rect.right - RESIZE_HOTSPOT_PX && point.x <= rect.right && point.y >= rect.bottom - RESIZE_HOTSPOT_PX && point.y <= rect.bottom;
|
|
469
|
-
}
|
|
470
|
-
function canStartDragFromTarget(target) {
|
|
471
|
-
if (!(target instanceof Element)) {
|
|
472
|
-
return true;
|
|
473
|
-
}
|
|
474
|
-
if (target.closest("button") || target.closest("a") || target.closest("input") || target.closest("textarea") || target.closest("select")) {
|
|
475
|
-
return false;
|
|
476
|
-
}
|
|
477
|
-
return true;
|
|
478
|
-
}
|
|
479
|
-
function isInTopDragZone(element, point, zoneHeight) {
|
|
480
|
-
const rect = element.getBoundingClientRect();
|
|
481
|
-
return point.x >= rect.left && point.x <= rect.right && point.y >= rect.top && point.y <= rect.top + zoneHeight;
|
|
482
|
-
}
|
|
483
|
-
function attachDragStartListeners(element, state, options = {}) {
|
|
484
|
-
element.addEventListener("mousedown", (event) => {
|
|
485
|
-
if (!options.allowInteractiveTarget && !canStartDragFromTarget(event.target)) {
|
|
486
|
-
return;
|
|
487
|
-
}
|
|
488
|
-
const point = getPointFromMouseEvent(event);
|
|
489
|
-
if (typeof options.topZoneHeight === "number" && !isInTopDragZone(element, point, options.topZoneHeight)) {
|
|
490
|
-
return;
|
|
491
|
-
}
|
|
492
|
-
beginDragTracking(state, point);
|
|
493
|
-
});
|
|
494
|
-
element.addEventListener("touchstart", (event) => {
|
|
495
|
-
if (!options.allowInteractiveTarget && !canStartDragFromTarget(event.target)) {
|
|
496
|
-
return;
|
|
497
|
-
}
|
|
498
|
-
const point = getPointFromTouchEvent(event);
|
|
499
|
-
if (!point) {
|
|
500
|
-
return;
|
|
501
|
-
}
|
|
502
|
-
if (typeof options.topZoneHeight === "number" && !isInTopDragZone(element, point, options.topZoneHeight)) {
|
|
503
|
-
return;
|
|
504
|
-
}
|
|
505
|
-
beginDragTracking(state, point);
|
|
506
|
-
});
|
|
507
|
-
}
|
|
508
|
-
function attachCollapsedToggleListeners(element, state) {
|
|
509
|
-
const startToggleInteraction = (startPoint) => {
|
|
510
|
-
const doc = getDocument();
|
|
511
|
-
if (!doc) {
|
|
512
|
-
return;
|
|
513
|
-
}
|
|
514
|
-
beginDragTracking(state, startPoint);
|
|
515
|
-
const finishInteraction = () => {
|
|
516
|
-
releaseListeners();
|
|
517
|
-
if (state.dragMoved || Date.now() < state.suppressToggleClickUntil) {
|
|
518
|
-
return;
|
|
519
|
-
}
|
|
520
|
-
state.expanded = true;
|
|
521
|
-
state.unreadCount = 0;
|
|
522
|
-
renderOverlay(state);
|
|
523
|
-
};
|
|
524
|
-
const releaseListeners = () => {
|
|
525
|
-
doc.removeEventListener("mouseup", finishInteraction);
|
|
526
|
-
doc.removeEventListener("touchend", finishInteraction);
|
|
527
|
-
doc.removeEventListener("touchcancel", finishInteraction);
|
|
528
|
-
};
|
|
529
|
-
doc.addEventListener("mouseup", finishInteraction);
|
|
530
|
-
doc.addEventListener("touchend", finishInteraction);
|
|
531
|
-
doc.addEventListener("touchcancel", finishInteraction);
|
|
532
|
-
};
|
|
533
|
-
element.addEventListener("mousedown", (event) => {
|
|
534
|
-
event.preventDefault();
|
|
535
|
-
startToggleInteraction(getPointFromMouseEvent(event));
|
|
536
|
-
});
|
|
537
|
-
element.addEventListener("touchstart", (event) => {
|
|
538
|
-
const point = getPointFromTouchEvent(event);
|
|
539
|
-
if (!point) {
|
|
540
|
-
return;
|
|
541
|
-
}
|
|
542
|
-
event.preventDefault();
|
|
543
|
-
startToggleInteraction(point);
|
|
544
|
-
});
|
|
545
|
-
}
|
|
546
|
-
function attachPanelResizeListeners(element, state) {
|
|
547
|
-
element.addEventListener("mousedown", (event) => {
|
|
548
|
-
if (!state.expanded || !canStartDragFromTarget(event.target)) {
|
|
549
|
-
return;
|
|
550
|
-
}
|
|
551
|
-
const point = getPointFromMouseEvent(event);
|
|
552
|
-
if (!isInBottomRightResizeZone(element, point)) {
|
|
553
|
-
return;
|
|
554
|
-
}
|
|
555
|
-
event.preventDefault();
|
|
556
|
-
event.stopPropagation();
|
|
557
|
-
startResizing(state, point);
|
|
558
|
-
});
|
|
559
|
-
element.addEventListener("touchstart", (event) => {
|
|
560
|
-
if (!state.expanded || !canStartDragFromTarget(event.target)) {
|
|
561
|
-
return;
|
|
562
|
-
}
|
|
563
|
-
const point = getPointFromTouchEvent(event);
|
|
564
|
-
if (!point || !isInBottomRightResizeZone(element, point)) {
|
|
565
|
-
return;
|
|
566
|
-
}
|
|
567
|
-
event.preventDefault();
|
|
568
|
-
event.stopPropagation();
|
|
569
|
-
startResizing(state, point);
|
|
570
|
-
});
|
|
571
|
-
}
|
|
572
|
-
function createOverlayUi(state) {
|
|
573
|
-
const root = document.createElement("div");
|
|
574
|
-
root.style.cssText = [
|
|
575
|
-
"position:fixed",
|
|
576
|
-
"left:12px",
|
|
577
|
-
"top:12px",
|
|
578
|
-
"z-index:2147483647",
|
|
579
|
-
"display:flex",
|
|
580
|
-
"flex-direction:column",
|
|
581
|
-
"align-items:stretch",
|
|
582
|
-
"gap:8px",
|
|
583
|
-
"width:min(565px, calc(100vw - 24px))",
|
|
584
|
-
"pointer-events:none"
|
|
585
|
-
].join(";");
|
|
586
|
-
const toggleButton = createButton("Logs");
|
|
587
|
-
toggleButton.style.pointerEvents = "auto";
|
|
588
|
-
toggleButton.style.alignSelf = "flex-end";
|
|
589
|
-
toggleButton.style.display = "inline-flex";
|
|
590
|
-
toggleButton.style.alignItems = "center";
|
|
591
|
-
toggleButton.style.justifyContent = "center";
|
|
592
|
-
toggleButton.style.minHeight = "40px";
|
|
593
|
-
toggleButton.style.minWidth = "76px";
|
|
594
|
-
toggleButton.style.padding = "8px 14px";
|
|
595
|
-
toggleButton.style.textAlign = "center";
|
|
596
|
-
toggleButton.style.border = "1px solid rgba(122, 212, 255, 0.22)";
|
|
597
|
-
toggleButton.style.background = "linear-gradient(180deg, rgba(13,31,54,0.98), rgba(8,19,37,0.98))";
|
|
598
|
-
toggleButton.style.boxShadow = "0 18px 40px rgba(4,12,24,0.34)";
|
|
599
|
-
toggleButton.style.cursor = "grab";
|
|
600
|
-
toggleButton.style.touchAction = "none";
|
|
601
|
-
const panel = document.createElement("div");
|
|
602
|
-
panel.style.cssText = [
|
|
603
|
-
"position:relative",
|
|
604
|
-
"display:flex",
|
|
605
|
-
"flex-direction:column",
|
|
606
|
-
"width:min(565px, calc(100vw - 24px))",
|
|
607
|
-
"max-height:min(48vh, 372px)",
|
|
608
|
-
"border-radius:18px",
|
|
609
|
-
"border:1px solid rgba(116,167,255,0.16)",
|
|
610
|
-
"background:linear-gradient(180deg, rgba(9,19,37,0.98), rgba(5,12,24,0.98))",
|
|
611
|
-
"box-shadow:0 28px 64px rgba(2,8,18,0.46)",
|
|
612
|
-
"backdrop-filter:blur(16px)",
|
|
613
|
-
"overflow:hidden",
|
|
614
|
-
"cursor:default",
|
|
615
|
-
"pointer-events:auto"
|
|
616
|
-
].join(";");
|
|
617
|
-
const dragZone = document.createElement("div");
|
|
618
|
-
dragZone.style.cssText = [
|
|
619
|
-
"position:absolute",
|
|
620
|
-
"top:0",
|
|
621
|
-
"left:0",
|
|
622
|
-
"right:0",
|
|
623
|
-
"height:" + String(TOP_DRAG_ZONE_PX) + "px",
|
|
624
|
-
"z-index:1",
|
|
625
|
-
"cursor:grab",
|
|
626
|
-
"background:transparent",
|
|
627
|
-
"pointer-events:auto"
|
|
628
|
-
].join(";");
|
|
629
|
-
const controls = document.createElement("div");
|
|
630
|
-
controls.style.cssText = [
|
|
631
|
-
"position:absolute",
|
|
632
|
-
"top:22px",
|
|
633
|
-
"right:22px",
|
|
634
|
-
"z-index:2",
|
|
635
|
-
"display:flex",
|
|
636
|
-
"align-items:center",
|
|
637
|
-
"gap:8px",
|
|
638
|
-
"pointer-events:auto"
|
|
639
|
-
].join(";");
|
|
640
|
-
const clearButton = createButton("Clear");
|
|
641
|
-
clearButton.style.background = "rgba(255,255,255,0.1)";
|
|
642
|
-
clearButton.style.border = "1px solid rgba(255,255,255,0.16)";
|
|
643
|
-
clearButton.style.color = "#eef6ff";
|
|
644
|
-
clearButton.style.minHeight = "30px";
|
|
645
|
-
clearButton.style.padding = "4px 9px";
|
|
646
|
-
clearButton.style.fontSize = "11px";
|
|
647
|
-
clearButton.style.backdropFilter = "blur(8px)";
|
|
648
|
-
const collapseButton = createButton("Hide");
|
|
649
|
-
collapseButton.style.background = "rgba(113, 171, 255, 0.12)";
|
|
650
|
-
collapseButton.style.border = "1px solid rgba(113, 171, 255, 0.2)";
|
|
651
|
-
collapseButton.style.color = "#d9ebff";
|
|
652
|
-
collapseButton.style.minHeight = "30px";
|
|
653
|
-
collapseButton.style.padding = "4px 9px";
|
|
654
|
-
collapseButton.style.fontSize = "11px";
|
|
655
|
-
collapseButton.style.backdropFilter = "blur(8px)";
|
|
656
|
-
const body = document.createElement("div");
|
|
657
|
-
body.style.cssText = [
|
|
658
|
-
"position:relative",
|
|
659
|
-
"display:flex",
|
|
660
|
-
"flex-direction:column",
|
|
661
|
-
"padding:12px",
|
|
662
|
-
"background:linear-gradient(180deg, rgba(4,10,20,0.88), rgba(3,8,18,0.98))",
|
|
663
|
-
"flex:1 1 auto",
|
|
664
|
-
"min-height:0"
|
|
665
|
-
].join(";");
|
|
666
|
-
const entries = document.createElement("div");
|
|
667
|
-
entries.style.cssText = [
|
|
668
|
-
"display:flex",
|
|
669
|
-
"flex-direction:column",
|
|
670
|
-
"gap:0",
|
|
671
|
-
"overflow:auto",
|
|
672
|
-
"flex:1 1 auto",
|
|
673
|
-
"min-height:96px",
|
|
674
|
-
"max-height:min(36vh, 280px)",
|
|
675
|
-
"padding:0",
|
|
676
|
-
"border:1px solid rgba(115,153,212,0.14)",
|
|
677
|
-
"border-radius:12px",
|
|
678
|
-
"background:rgba(4,10,20,0.82)"
|
|
679
|
-
].join(";");
|
|
680
|
-
const emptyState = document.createElement("div");
|
|
681
|
-
emptyState.style.cssText = [
|
|
682
|
-
"display:flex",
|
|
683
|
-
"align-items:center",
|
|
684
|
-
"justify-content:center",
|
|
685
|
-
"flex:1 1 auto",
|
|
686
|
-
"min-height:96px",
|
|
687
|
-
"color:rgba(204,222,250,0.6)",
|
|
688
|
-
"font:500 12px/1.5 ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace",
|
|
689
|
-
"text-align:center",
|
|
690
|
-
"padding:18px"
|
|
691
|
-
].join(";");
|
|
692
|
-
emptyState.textContent = "Console output will appear here.";
|
|
693
|
-
collapseButton.addEventListener("click", (event) => {
|
|
694
|
-
event.stopPropagation();
|
|
695
|
-
state.expanded = false;
|
|
696
|
-
renderOverlay(state);
|
|
697
|
-
});
|
|
698
|
-
clearButton.addEventListener("click", (event) => {
|
|
699
|
-
event.stopPropagation();
|
|
700
|
-
state.entries = [];
|
|
701
|
-
state.unreadCount = 0;
|
|
702
|
-
renderOverlay(state);
|
|
703
|
-
});
|
|
704
|
-
controls.appendChild(clearButton);
|
|
705
|
-
controls.appendChild(collapseButton);
|
|
706
|
-
entries.appendChild(emptyState);
|
|
707
|
-
body.appendChild(entries);
|
|
708
|
-
body.appendChild(controls);
|
|
709
|
-
panel.appendChild(dragZone);
|
|
710
|
-
panel.appendChild(body);
|
|
711
|
-
attachDragStartListeners(dragZone, state);
|
|
712
|
-
attachPanelResizeListeners(panel, state);
|
|
713
|
-
attachCollapsedToggleListeners(toggleButton, state);
|
|
714
|
-
root.appendChild(panel);
|
|
715
|
-
root.appendChild(toggleButton);
|
|
716
|
-
return {
|
|
717
|
-
body,
|
|
718
|
-
clearButton,
|
|
719
|
-
collapseButton,
|
|
720
|
-
controls,
|
|
721
|
-
dragZone,
|
|
722
|
-
emptyState,
|
|
723
|
-
entries,
|
|
724
|
-
panel,
|
|
725
|
-
root,
|
|
726
|
-
toggleButton
|
|
727
|
-
};
|
|
728
|
-
}
|
|
729
|
-
function renderOverlay(state) {
|
|
730
|
-
if (!state.ui) {
|
|
731
|
-
return;
|
|
732
|
-
}
|
|
733
|
-
state.ui.panel.style.display = state.expanded ? "flex" : "none";
|
|
734
|
-
state.ui.toggleButton.style.display = state.expanded ? "none" : "inline-flex";
|
|
735
|
-
state.ui.toggleButton.textContent = "Logs";
|
|
736
|
-
if (state.entries.length === 0) {
|
|
737
|
-
state.ui.entries.style.display = "flex";
|
|
738
|
-
state.ui.emptyState.style.display = "flex";
|
|
739
|
-
state.ui.entries.replaceChildren(state.ui.emptyState);
|
|
740
|
-
applyPanelSize(state);
|
|
741
|
-
applyOverlayPosition(state);
|
|
742
|
-
return;
|
|
743
|
-
}
|
|
744
|
-
state.ui.entries.style.display = "flex";
|
|
745
|
-
state.ui.emptyState.style.display = "none";
|
|
746
|
-
const nextChildren = state.entries.map((entry) => {
|
|
747
|
-
const accent = getLevelAccent(entry.level);
|
|
748
|
-
const row = document.createElement("div");
|
|
749
|
-
row.style.cssText = [
|
|
750
|
-
"display:flex",
|
|
751
|
-
"align-items:flex-start",
|
|
752
|
-
"gap:0",
|
|
753
|
-
"padding:4px 12px",
|
|
754
|
-
"background:" + accent.lineBackground
|
|
755
|
-
].join(";");
|
|
756
|
-
const line = document.createElement("div");
|
|
757
|
-
line.textContent = formatTimestamp(entry.timestamp) + " " + entry.level.toUpperCase() + " " + entry.message;
|
|
758
|
-
line.style.cssText = [
|
|
759
|
-
"color:#ecf4ff",
|
|
760
|
-
"font:500 12px/1.5 ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace",
|
|
761
|
-
"white-space:pre-wrap",
|
|
762
|
-
"word-break:break-word",
|
|
763
|
-
"flex:1 1 auto"
|
|
764
|
-
].join(";");
|
|
765
|
-
row.appendChild(line);
|
|
766
|
-
return row;
|
|
767
|
-
});
|
|
768
|
-
state.ui.entries.replaceChildren(...nextChildren);
|
|
769
|
-
state.ui.entries.scrollTop = state.ui.entries.scrollHeight;
|
|
770
|
-
applyPanelSize(state);
|
|
771
|
-
applyOverlayPosition(state);
|
|
772
|
-
}
|
|
773
|
-
function mountOverlay(state) {
|
|
774
|
-
const doc = getDocument();
|
|
775
|
-
if (!doc?.body || state.ui) {
|
|
776
|
-
return;
|
|
777
|
-
}
|
|
778
|
-
state.ui = createOverlayUi(state);
|
|
779
|
-
doc.body.appendChild(state.ui.root);
|
|
780
|
-
applyPanelSize(state);
|
|
781
|
-
applyOverlayPosition(state);
|
|
782
|
-
renderOverlay(state);
|
|
783
|
-
}
|
|
784
|
-
function enqueueEntry(state, level, args) {
|
|
785
|
-
state.entries.push(createEntry(level, args, state.nextEntryId));
|
|
786
|
-
state.nextEntryId += 1;
|
|
787
|
-
if (state.entries.length > state.maxEntries) {
|
|
788
|
-
state.entries.splice(0, state.entries.length - state.maxEntries);
|
|
789
|
-
}
|
|
790
|
-
if (!state.expanded) {
|
|
791
|
-
state.unreadCount += 1;
|
|
792
|
-
}
|
|
793
|
-
renderOverlay(state);
|
|
794
|
-
}
|
|
795
|
-
function restoreConsole(snapshot) {
|
|
796
|
-
for (const method of CONSOLE_METHODS) {
|
|
797
|
-
console[method] = snapshot[method];
|
|
798
|
-
}
|
|
799
|
-
}
|
|
800
|
-
function patchConsole(state) {
|
|
801
|
-
for (const method of CONSOLE_METHODS) {
|
|
802
|
-
const original = state.originalConsole[method];
|
|
803
|
-
console[method] = (...args) => {
|
|
804
|
-
enqueueEntry(state, method, args);
|
|
805
|
-
original(...args);
|
|
806
|
-
};
|
|
807
|
-
}
|
|
808
|
-
}
|
|
809
|
-
function cleanupOverlay(browserWindow, state) {
|
|
810
|
-
restoreConsole(state.originalConsole);
|
|
811
|
-
stopResizing(state);
|
|
812
|
-
stopDragging(state);
|
|
813
|
-
if (state.domReadyHandler) {
|
|
814
|
-
getDocument()?.removeEventListener("DOMContentLoaded", state.domReadyHandler);
|
|
815
|
-
state.domReadyHandler = void 0;
|
|
816
|
-
}
|
|
817
|
-
if (state.resizeHandler && typeof browserWindow.removeEventListener === "function") {
|
|
818
|
-
browserWindow.removeEventListener("resize", state.resizeHandler);
|
|
819
|
-
state.resizeHandler = void 0;
|
|
820
|
-
}
|
|
821
|
-
state.ui?.root.remove();
|
|
822
|
-
state.ui = null;
|
|
823
|
-
delete browserWindow.__oasizLogOverlayController__;
|
|
824
|
-
delete browserWindow.__oasizLogOverlayState__;
|
|
825
|
-
}
|
|
826
|
-
function createController(browserWindow, state) {
|
|
827
|
-
return {
|
|
828
|
-
retain() {
|
|
829
|
-
state.refCount += 1;
|
|
830
|
-
this.ensureMounted();
|
|
831
|
-
},
|
|
832
|
-
ensureMounted() {
|
|
833
|
-
const doc = getDocument();
|
|
834
|
-
if (!doc) {
|
|
835
|
-
return;
|
|
836
|
-
}
|
|
837
|
-
if (doc.body) {
|
|
838
|
-
mountOverlay(state);
|
|
839
|
-
applyOverlayPosition(state);
|
|
840
|
-
return;
|
|
841
|
-
}
|
|
842
|
-
if (!state.domReadyHandler) {
|
|
843
|
-
state.domReadyHandler = () => {
|
|
844
|
-
mountOverlay(state);
|
|
845
|
-
state.domReadyHandler = void 0;
|
|
846
|
-
};
|
|
847
|
-
doc.addEventListener("DOMContentLoaded", state.domReadyHandler, {
|
|
848
|
-
once: true
|
|
849
|
-
});
|
|
850
|
-
}
|
|
851
|
-
},
|
|
852
|
-
clear() {
|
|
853
|
-
state.entries = [];
|
|
854
|
-
state.unreadCount = 0;
|
|
855
|
-
renderOverlay(state);
|
|
856
|
-
},
|
|
857
|
-
show() {
|
|
858
|
-
state.expanded = true;
|
|
859
|
-
state.unreadCount = 0;
|
|
860
|
-
renderOverlay(state);
|
|
861
|
-
},
|
|
862
|
-
hide() {
|
|
863
|
-
state.expanded = false;
|
|
864
|
-
renderOverlay(state);
|
|
865
|
-
},
|
|
866
|
-
isVisible() {
|
|
867
|
-
return state.expanded;
|
|
868
|
-
},
|
|
869
|
-
destroy() {
|
|
870
|
-
state.refCount = Math.max(0, state.refCount - 1);
|
|
871
|
-
if (state.refCount === 0) {
|
|
872
|
-
cleanupOverlay(browserWindow, state);
|
|
873
|
-
}
|
|
874
|
-
}
|
|
875
|
-
};
|
|
876
|
-
}
|
|
877
|
-
function enableLogOverlay(options = {}) {
|
|
878
|
-
if (options.enabled === false) {
|
|
879
|
-
return NOOP_HANDLE;
|
|
880
|
-
}
|
|
881
|
-
const browserWindow = getBrowserWindow();
|
|
882
|
-
const doc = getDocument();
|
|
883
|
-
if (!browserWindow || !doc) {
|
|
884
|
-
return NOOP_HANDLE;
|
|
885
|
-
}
|
|
886
|
-
const existingController = browserWindow.__oasizLogOverlayController__;
|
|
887
|
-
const existingState = browserWindow.__oasizLogOverlayState__;
|
|
888
|
-
if (existingController && existingState) {
|
|
889
|
-
existingController.retain();
|
|
890
|
-
if (typeof options.maxEntries === "number") {
|
|
891
|
-
existingState.maxEntries = clampMaxEntries(options.maxEntries);
|
|
892
|
-
if (existingState.entries.length > existingState.maxEntries) {
|
|
893
|
-
existingState.entries.splice(
|
|
894
|
-
0,
|
|
895
|
-
existingState.entries.length - existingState.maxEntries
|
|
896
|
-
);
|
|
897
|
-
}
|
|
898
|
-
}
|
|
899
|
-
if (typeof options.collapsed === "boolean") {
|
|
900
|
-
existingState.expanded = !options.collapsed;
|
|
901
|
-
applyPanelSize(existingState);
|
|
902
|
-
if (existingState.expanded) {
|
|
903
|
-
existingState.unreadCount = 0;
|
|
904
|
-
}
|
|
905
|
-
}
|
|
906
|
-
if (typeof options.title === "string" && options.title.trim().length > 0) {
|
|
907
|
-
existingState.title = options.title.trim();
|
|
908
|
-
}
|
|
909
|
-
existingController.ensureMounted();
|
|
910
|
-
renderOverlay(existingState);
|
|
911
|
-
return existingController;
|
|
912
|
-
}
|
|
913
|
-
const state = {
|
|
914
|
-
dragMoved: false,
|
|
915
|
-
dragStartPoint: null,
|
|
916
|
-
entries: [],
|
|
917
|
-
expanded: options.collapsed !== true,
|
|
918
|
-
isDragging: false,
|
|
919
|
-
isResizing: false,
|
|
920
|
-
lastDragPoint: null,
|
|
921
|
-
maxEntries: clampMaxEntries(options.maxEntries),
|
|
922
|
-
nextEntryId: 1,
|
|
923
|
-
originalConsole: createConsoleSnapshot(),
|
|
924
|
-
panelSize: null,
|
|
925
|
-
position: null,
|
|
926
|
-
refCount: 1,
|
|
927
|
-
removeDragListeners: null,
|
|
928
|
-
removeResizeListeners: null,
|
|
929
|
-
resizeStartPoint: null,
|
|
930
|
-
resizeStartSize: null,
|
|
931
|
-
suppressToggleClickUntil: 0,
|
|
932
|
-
title: typeof options.title === "string" && options.title.trim().length > 0 ? options.title.trim() : DEFAULT_TITLE,
|
|
933
|
-
resizeHandler: void 0,
|
|
934
|
-
ui: null,
|
|
935
|
-
unreadCount: 0
|
|
936
|
-
};
|
|
937
|
-
const controller = createController(browserWindow, state);
|
|
938
|
-
browserWindow.__oasizLogOverlayState__ = state;
|
|
939
|
-
browserWindow.__oasizLogOverlayController__ = controller;
|
|
940
|
-
patchConsole(state);
|
|
941
|
-
if (typeof browserWindow.addEventListener === "function") {
|
|
942
|
-
state.resizeHandler = () => {
|
|
943
|
-
applyOverlayPosition(state);
|
|
944
|
-
};
|
|
945
|
-
browserWindow.addEventListener("resize", state.resizeHandler);
|
|
946
|
-
}
|
|
947
|
-
controller.ensureMounted();
|
|
948
|
-
return controller;
|
|
949
|
-
}
|
|
950
|
-
|
|
951
25
|
// src/multiplayer.ts
|
|
952
|
-
function
|
|
26
|
+
function isDevelopment2() {
|
|
953
27
|
const nodeEnv = globalThis.process?.env?.NODE_ENV;
|
|
954
28
|
return nodeEnv !== "production";
|
|
955
29
|
}
|
|
956
|
-
function
|
|
30
|
+
function getBridgeWindow2() {
|
|
957
31
|
if (typeof window === "undefined") {
|
|
958
32
|
return void 0;
|
|
959
33
|
}
|
|
960
34
|
return window;
|
|
961
35
|
}
|
|
962
|
-
function shareRoomCode(roomCode
|
|
963
|
-
const bridge =
|
|
36
|
+
function shareRoomCode(roomCode) {
|
|
37
|
+
const bridge = getBridgeWindow2();
|
|
964
38
|
if (typeof bridge?.shareRoomCode === "function") {
|
|
965
|
-
bridge.shareRoomCode(roomCode
|
|
39
|
+
bridge.shareRoomCode(roomCode);
|
|
966
40
|
return;
|
|
967
41
|
}
|
|
968
|
-
if (
|
|
42
|
+
if (isDevelopment2()) {
|
|
969
43
|
console.warn(
|
|
970
44
|
"[oasiz/sdk] shareRoomCode bridge is unavailable. This is expected in local development."
|
|
971
45
|
);
|
|
972
46
|
}
|
|
973
47
|
}
|
|
974
|
-
function openInviteModal() {
|
|
975
|
-
const bridge = getBridgeWindow3();
|
|
976
|
-
if (typeof bridge?.openInviteModal === "function") {
|
|
977
|
-
bridge.openInviteModal();
|
|
978
|
-
return;
|
|
979
|
-
}
|
|
980
|
-
if (isDevelopment3()) {
|
|
981
|
-
console.warn(
|
|
982
|
-
"[oasiz/sdk] openInviteModal bridge is unavailable. This is expected in local development."
|
|
983
|
-
);
|
|
984
|
-
}
|
|
985
|
-
}
|
|
986
48
|
function getGameId() {
|
|
987
|
-
const bridge =
|
|
49
|
+
const bridge = getBridgeWindow2();
|
|
988
50
|
return bridge?.__GAME_ID__;
|
|
989
51
|
}
|
|
990
52
|
function getRoomCode() {
|
|
991
|
-
const bridge =
|
|
53
|
+
const bridge = getBridgeWindow2();
|
|
992
54
|
return bridge?.__ROOM_CODE__;
|
|
993
55
|
}
|
|
994
|
-
function getPlayerId() {
|
|
995
|
-
const bridge = getBridgeWindow3();
|
|
996
|
-
return bridge?.__PLAYER_ID__;
|
|
997
|
-
}
|
|
998
56
|
function getPlayerName() {
|
|
999
|
-
const bridge =
|
|
57
|
+
const bridge = getBridgeWindow2();
|
|
1000
58
|
return bridge?.__PLAYER_NAME__;
|
|
1001
59
|
}
|
|
1002
60
|
function getPlayerAvatar() {
|
|
1003
|
-
const bridge =
|
|
61
|
+
const bridge = getBridgeWindow2();
|
|
1004
62
|
return bridge?.__PLAYER_AVATAR__;
|
|
1005
63
|
}
|
|
1006
64
|
|
|
1007
65
|
// src/score.ts
|
|
1008
|
-
function
|
|
66
|
+
function isDevelopment3() {
|
|
1009
67
|
const nodeEnv = globalThis.process?.env?.NODE_ENV;
|
|
1010
68
|
return nodeEnv !== "production";
|
|
1011
69
|
}
|
|
1012
|
-
function
|
|
1013
|
-
if (
|
|
70
|
+
function warnMissingBridge(methodName) {
|
|
71
|
+
if (isDevelopment3()) {
|
|
1014
72
|
console.warn(
|
|
1015
73
|
"[oasiz/sdk] " + methodName + " bridge is unavailable. This is expected in local development."
|
|
1016
74
|
);
|
|
1017
75
|
}
|
|
1018
76
|
}
|
|
1019
|
-
function
|
|
77
|
+
function getBridgeWindow3() {
|
|
1020
78
|
if (typeof window === "undefined") {
|
|
1021
79
|
return void 0;
|
|
1022
80
|
}
|
|
@@ -1024,92 +82,41 @@ function getBridgeWindow4() {
|
|
|
1024
82
|
}
|
|
1025
83
|
function submitScore(score) {
|
|
1026
84
|
if (!Number.isFinite(score)) {
|
|
1027
|
-
if (
|
|
85
|
+
if (isDevelopment3()) {
|
|
1028
86
|
console.warn("[oasiz/sdk] submitScore expected a finite number:", score);
|
|
1029
87
|
}
|
|
1030
88
|
return;
|
|
1031
89
|
}
|
|
1032
|
-
const bridge =
|
|
90
|
+
const bridge = getBridgeWindow3();
|
|
1033
91
|
const normalizedScore = Math.max(0, Math.floor(score));
|
|
1034
92
|
if (typeof bridge?.submitScore === "function") {
|
|
1035
93
|
bridge.submitScore(normalizedScore);
|
|
1036
94
|
return;
|
|
1037
95
|
}
|
|
1038
|
-
|
|
96
|
+
warnMissingBridge("submitScore");
|
|
1039
97
|
}
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
}
|
|
1046
|
-
function getBridgeWindow5() {
|
|
1047
|
-
if (typeof window === "undefined") {
|
|
1048
|
-
return void 0;
|
|
1049
|
-
}
|
|
1050
|
-
return window;
|
|
1051
|
-
}
|
|
1052
|
-
function warnMissingBridge3(methodName) {
|
|
1053
|
-
if (isDevelopment5()) {
|
|
1054
|
-
console.warn(
|
|
1055
|
-
"[oasiz/sdk] " + methodName + " bridge is unavailable. This is expected in local development."
|
|
1056
|
-
);
|
|
1057
|
-
}
|
|
1058
|
-
}
|
|
1059
|
-
async function editScore(payload, methodName) {
|
|
1060
|
-
const bridge = getBridgeWindow5();
|
|
1061
|
-
if (typeof bridge?.__oasizEditScore !== "function") {
|
|
1062
|
-
warnMissingBridge3(methodName);
|
|
1063
|
-
return null;
|
|
1064
|
-
}
|
|
1065
|
-
try {
|
|
1066
|
-
const result = await bridge.__oasizEditScore(payload);
|
|
1067
|
-
return result ?? null;
|
|
1068
|
-
} catch (error) {
|
|
1069
|
-
if (isDevelopment5()) {
|
|
1070
|
-
console.error("[oasiz/sdk] " + methodName + " failed:", error);
|
|
1071
|
-
}
|
|
1072
|
-
return null;
|
|
1073
|
-
}
|
|
1074
|
-
}
|
|
1075
|
-
async function addScore(delta) {
|
|
1076
|
-
if (!Number.isInteger(delta)) {
|
|
1077
|
-
if (isDevelopment5()) {
|
|
1078
|
-
console.warn("[oasiz/sdk] addScore expected an integer:", delta);
|
|
1079
|
-
}
|
|
1080
|
-
return null;
|
|
1081
|
-
}
|
|
1082
|
-
if (delta === 0) {
|
|
1083
|
-
return null;
|
|
1084
|
-
}
|
|
1085
|
-
return editScore({ delta }, "addScore");
|
|
1086
|
-
}
|
|
1087
|
-
async function setScore(score) {
|
|
1088
|
-
if (!Number.isInteger(score) || score < 0) {
|
|
1089
|
-
if (isDevelopment5()) {
|
|
1090
|
-
console.warn(
|
|
1091
|
-
"[oasiz/sdk] setScore expected a non-negative integer:",
|
|
1092
|
-
score
|
|
1093
|
-
);
|
|
1094
|
-
}
|
|
1095
|
-
return null;
|
|
98
|
+
function emitScoreConfig(config) {
|
|
99
|
+
const bridge = getBridgeWindow3();
|
|
100
|
+
if (typeof bridge?.emitScoreConfig === "function") {
|
|
101
|
+
bridge.emitScoreConfig(config);
|
|
102
|
+
return;
|
|
1096
103
|
}
|
|
1097
|
-
|
|
104
|
+
warnMissingBridge("emitScoreConfig");
|
|
1098
105
|
}
|
|
1099
106
|
|
|
1100
107
|
// src/share.ts
|
|
1101
|
-
function
|
|
108
|
+
function isDevelopment4() {
|
|
1102
109
|
const nodeEnv = globalThis.process?.env?.NODE_ENV;
|
|
1103
110
|
return nodeEnv !== "production";
|
|
1104
111
|
}
|
|
1105
|
-
function
|
|
112
|
+
function getBridgeWindow4() {
|
|
1106
113
|
if (typeof window === "undefined") {
|
|
1107
114
|
return void 0;
|
|
1108
115
|
}
|
|
1109
116
|
return window;
|
|
1110
117
|
}
|
|
1111
|
-
function
|
|
1112
|
-
if (
|
|
118
|
+
function warnMissingBridge2(methodName) {
|
|
119
|
+
if (isDevelopment4()) {
|
|
1113
120
|
console.warn(
|
|
1114
121
|
"[oasiz/sdk] " + methodName + " share bridge is unavailable. This is expected in local development."
|
|
1115
122
|
);
|
|
@@ -1140,458 +147,131 @@ function validateRequest(options) {
|
|
|
1140
147
|
}
|
|
1141
148
|
}
|
|
1142
149
|
if (hasImage && !isValidImageReference(options.image)) {
|
|
1143
|
-
throw new Error(
|
|
1144
|
-
"Share image must be an http(s) URL or a data:image/... base64 string."
|
|
1145
|
-
);
|
|
1146
|
-
}
|
|
1147
|
-
return {
|
|
1148
|
-
...hasText ? { text } : {},
|
|
1149
|
-
...hasScore ? { score: options.score } : {},
|
|
1150
|
-
...hasImage ? { image: options.image } : {}
|
|
1151
|
-
};
|
|
1152
|
-
}
|
|
1153
|
-
async function share(options) {
|
|
1154
|
-
const request = validateRequest(options);
|
|
1155
|
-
const bridge = getBridgeWindow6();
|
|
1156
|
-
if (typeof bridge?.__oasizShareRequest !== "function") {
|
|
1157
|
-
warnMissingBridge4("__oasizShareRequest");
|
|
1158
|
-
throw new Error("Share bridge unavailable");
|
|
1159
|
-
}
|
|
1160
|
-
await bridge.__oasizShareRequest(request);
|
|
1161
|
-
}
|
|
1162
|
-
|
|
1163
|
-
// src/state.ts
|
|
1164
|
-
function isDevelopment7() {
|
|
1165
|
-
const nodeEnv = globalThis.process?.env?.NODE_ENV;
|
|
1166
|
-
return nodeEnv !== "production";
|
|
1167
|
-
}
|
|
1168
|
-
function getBridgeWindow7() {
|
|
1169
|
-
if (typeof window === "undefined") {
|
|
1170
|
-
return void 0;
|
|
1171
|
-
}
|
|
1172
|
-
return window;
|
|
1173
|
-
}
|
|
1174
|
-
function isPlainObject(value) {
|
|
1175
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1176
|
-
return false;
|
|
1177
|
-
}
|
|
1178
|
-
const proto = Object.getPrototypeOf(value);
|
|
1179
|
-
return proto === Object.prototype || proto === null;
|
|
1180
|
-
}
|
|
1181
|
-
function warnMissingBridge5(methodName) {
|
|
1182
|
-
if (isDevelopment7()) {
|
|
1183
|
-
console.warn(
|
|
1184
|
-
"[oasiz/sdk] " + methodName + " bridge is unavailable. This is expected in local development."
|
|
1185
|
-
);
|
|
1186
|
-
}
|
|
1187
|
-
}
|
|
1188
|
-
function loadGameState() {
|
|
1189
|
-
const bridge = getBridgeWindow7();
|
|
1190
|
-
if (typeof bridge?.loadGameState !== "function") {
|
|
1191
|
-
warnMissingBridge5("loadGameState");
|
|
1192
|
-
return {};
|
|
1193
|
-
}
|
|
1194
|
-
const state = bridge.loadGameState();
|
|
1195
|
-
if (!isPlainObject(state)) {
|
|
1196
|
-
if (isDevelopment7()) {
|
|
1197
|
-
console.warn(
|
|
1198
|
-
"[oasiz/sdk] loadGameState returned invalid data. Falling back to empty object."
|
|
1199
|
-
);
|
|
1200
|
-
}
|
|
1201
|
-
return {};
|
|
1202
|
-
}
|
|
1203
|
-
return state;
|
|
1204
|
-
}
|
|
1205
|
-
function saveGameState(state) {
|
|
1206
|
-
if (!isPlainObject(state)) {
|
|
1207
|
-
if (isDevelopment7()) {
|
|
1208
|
-
console.warn("[oasiz/sdk] saveGameState expected a plain object:", state);
|
|
1209
|
-
}
|
|
1210
|
-
return;
|
|
1211
|
-
}
|
|
1212
|
-
const bridge = getBridgeWindow7();
|
|
1213
|
-
if (typeof bridge?.saveGameState === "function") {
|
|
1214
|
-
bridge.saveGameState(state);
|
|
1215
|
-
return;
|
|
1216
|
-
}
|
|
1217
|
-
warnMissingBridge5("saveGameState");
|
|
1218
|
-
}
|
|
1219
|
-
function flushGameState() {
|
|
1220
|
-
const bridge = getBridgeWindow7();
|
|
1221
|
-
if (typeof bridge?.flushGameState === "function") {
|
|
1222
|
-
bridge.flushGameState();
|
|
1223
|
-
return;
|
|
1224
|
-
}
|
|
1225
|
-
warnMissingBridge5("flushGameState");
|
|
1226
|
-
}
|
|
1227
|
-
|
|
1228
|
-
// src/lifecycle.ts
|
|
1229
|
-
function isDevelopment8() {
|
|
1230
|
-
const nodeEnv = globalThis.process?.env?.NODE_ENV;
|
|
1231
|
-
return nodeEnv !== "production";
|
|
1232
|
-
}
|
|
1233
|
-
function addLifecycleListener(eventName, callback) {
|
|
1234
|
-
if (typeof window === "undefined") {
|
|
1235
|
-
if (isDevelopment8()) {
|
|
1236
|
-
console.warn(
|
|
1237
|
-
"[oasiz/sdk] " + eventName + " listener registered without a browser window. This is expected in local development."
|
|
1238
|
-
);
|
|
1239
|
-
}
|
|
1240
|
-
return () => {
|
|
1241
|
-
};
|
|
1242
|
-
}
|
|
1243
|
-
const handler = () => callback();
|
|
1244
|
-
window.addEventListener(eventName, handler);
|
|
1245
|
-
return () => window.removeEventListener(eventName, handler);
|
|
1246
|
-
}
|
|
1247
|
-
function onPause(callback) {
|
|
1248
|
-
return addLifecycleListener("oasiz:pause", callback);
|
|
1249
|
-
}
|
|
1250
|
-
function onResume(callback) {
|
|
1251
|
-
return addLifecycleListener("oasiz:resume", callback);
|
|
1252
|
-
}
|
|
1253
|
-
|
|
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
|
-
}
|
|
1270
|
-
function isDevelopment9() {
|
|
1271
|
-
const nodeEnv = globalThis.process?.env?.NODE_ENV;
|
|
1272
|
-
return nodeEnv !== "production";
|
|
1273
|
-
}
|
|
1274
|
-
function getBridgeWindow8() {
|
|
1275
|
-
if (typeof window === "undefined") {
|
|
1276
|
-
return void 0;
|
|
1277
|
-
}
|
|
1278
|
-
return window;
|
|
1279
|
-
}
|
|
1280
|
-
function warnMissingBridge6(methodName) {
|
|
1281
|
-
if (isDevelopment9()) {
|
|
1282
|
-
console.warn(
|
|
1283
|
-
"[oasiz/sdk] " + methodName + " bridge is unavailable. This is expected in local development."
|
|
1284
|
-
);
|
|
1285
|
-
}
|
|
1286
|
-
}
|
|
1287
|
-
function isRecord(value) {
|
|
1288
|
-
return typeof value === "object" && value !== null;
|
|
1289
|
-
}
|
|
1290
|
-
function toFiniteNumber(value) {
|
|
1291
|
-
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
1292
|
-
if (typeof value !== "string") {
|
|
1293
|
-
return void 0;
|
|
1294
|
-
}
|
|
1295
|
-
const parsed = Number.parseFloat(value.trim());
|
|
1296
|
-
if (!Number.isFinite(parsed)) {
|
|
1297
|
-
return void 0;
|
|
1298
|
-
}
|
|
1299
|
-
return parsed;
|
|
1300
|
-
}
|
|
1301
|
-
return value;
|
|
1302
|
-
}
|
|
1303
|
-
function clampInsetPixels(value) {
|
|
1304
|
-
const numeric = toFiniteNumber(value);
|
|
1305
|
-
if (typeof numeric === "undefined") {
|
|
1306
|
-
return void 0;
|
|
1307
|
-
}
|
|
1308
|
-
return Math.max(0, numeric);
|
|
1309
|
-
}
|
|
1310
|
-
function normalizeInsetPercent(value) {
|
|
1311
|
-
const numeric = toFiniteNumber(value);
|
|
1312
|
-
if (typeof numeric === "undefined") {
|
|
1313
|
-
return void 0;
|
|
1314
|
-
}
|
|
1315
|
-
return Math.min(100, Math.max(0, numeric));
|
|
1316
|
-
}
|
|
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;
|
|
1321
|
-
}
|
|
1322
|
-
const innerSize = axis === "vertical" ? bridge.innerHeight : bridge.innerWidth;
|
|
1323
|
-
if (typeof innerSize === "number" && Number.isFinite(innerSize) && innerSize > 0) {
|
|
1324
|
-
return innerSize;
|
|
1325
|
-
}
|
|
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;
|
|
1329
|
-
}
|
|
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;
|
|
1333
|
-
}
|
|
1334
|
-
return 0;
|
|
1335
|
-
}
|
|
1336
|
-
function readCssSafeAreaValue(bridge, cssValue) {
|
|
1337
|
-
const doc = bridge.document;
|
|
1338
|
-
const root = doc?.body ?? doc?.documentElement;
|
|
1339
|
-
if (!doc || !root || typeof doc.createElement !== "function" || typeof root.appendChild !== "function" || typeof bridge.getComputedStyle !== "function") {
|
|
1340
|
-
return 0;
|
|
1341
|
-
}
|
|
1342
|
-
const probe = doc.createElement("div");
|
|
1343
|
-
probe.style.position = "fixed";
|
|
1344
|
-
probe.style.top = "0";
|
|
1345
|
-
probe.style.left = "0";
|
|
1346
|
-
probe.style.width = "0";
|
|
1347
|
-
probe.style.height = "0";
|
|
1348
|
-
probe.style.visibility = "hidden";
|
|
1349
|
-
probe.style.pointerEvents = "none";
|
|
1350
|
-
probe.style.paddingTop = cssValue;
|
|
1351
|
-
root.appendChild(probe);
|
|
1352
|
-
try {
|
|
1353
|
-
return clampInsetPixels(bridge.getComputedStyle(probe).paddingTop) ?? 0;
|
|
1354
|
-
} finally {
|
|
1355
|
-
if (typeof probe.remove === "function") {
|
|
1356
|
-
probe.remove();
|
|
1357
|
-
} else {
|
|
1358
|
-
probe.parentNode?.removeChild(probe);
|
|
1359
|
-
}
|
|
1360
|
-
}
|
|
1361
|
-
}
|
|
1362
|
-
function readCssSafeAreaPixels(bridge, side) {
|
|
1363
|
-
const envPixels = readCssSafeAreaValue(
|
|
1364
|
-
bridge,
|
|
1365
|
-
"env(safe-area-inset-" + side + ")"
|
|
1366
|
-
);
|
|
1367
|
-
if (envPixels > 0) {
|
|
1368
|
-
return envPixels;
|
|
1369
|
-
}
|
|
1370
|
-
return readCssSafeAreaValue(
|
|
1371
|
-
bridge,
|
|
1372
|
-
"constant(safe-area-inset-" + side + ")"
|
|
1373
|
-
);
|
|
1374
|
-
}
|
|
1375
|
-
function getDevicePixelRatio(bridge) {
|
|
1376
|
-
const dpr = bridge.devicePixelRatio;
|
|
1377
|
-
if (typeof dpr !== "number" || !Number.isFinite(dpr) || dpr <= 0) {
|
|
1378
|
-
return 1;
|
|
1379
|
-
}
|
|
1380
|
-
return dpr;
|
|
1381
|
-
}
|
|
1382
|
-
function roughlyEqualPixels(a, b) {
|
|
1383
|
-
return Math.abs(a - b) <= 2;
|
|
1384
|
-
}
|
|
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);
|
|
1391
|
-
if (pixels <= 0) {
|
|
1392
|
-
return cssEnvPixels;
|
|
1393
|
-
}
|
|
1394
|
-
const dpr = getDevicePixelRatio(bridge);
|
|
1395
|
-
if (cssEnvPixels > 0 && dpr > 1 && roughlyEqualPixels(pixels / dpr, cssEnvPixels)) {
|
|
1396
|
-
return cssEnvPixels;
|
|
1397
|
-
}
|
|
1398
|
-
return pixels;
|
|
1399
|
-
}
|
|
1400
|
-
function pixelsToPercentOfViewport(pixels, bridge, side) {
|
|
1401
|
-
const size = getViewportSize2(bridge, SIDE_TO_AXIS[side]);
|
|
1402
|
-
if (size <= 0) {
|
|
1403
|
-
return 0;
|
|
150
|
+
throw new Error(
|
|
151
|
+
"Share image must be an http(s) URL or a data:image/... base64 string."
|
|
152
|
+
);
|
|
1404
153
|
}
|
|
1405
|
-
return
|
|
154
|
+
return {
|
|
155
|
+
...hasText ? { text } : {},
|
|
156
|
+
...hasScore ? { score: options.score } : {},
|
|
157
|
+
...hasImage ? { image: options.image } : {}
|
|
158
|
+
};
|
|
1406
159
|
}
|
|
1407
|
-
function
|
|
1408
|
-
const
|
|
1409
|
-
|
|
1410
|
-
|
|
160
|
+
async function share(options) {
|
|
161
|
+
const request = validateRequest(options);
|
|
162
|
+
const bridge = getBridgeWindow4();
|
|
163
|
+
if (typeof bridge?.__oasizShareRequest !== "function") {
|
|
164
|
+
warnMissingBridge2("__oasizShareRequest");
|
|
165
|
+
throw new Error("Share bridge unavailable");
|
|
1411
166
|
}
|
|
1412
|
-
|
|
1413
|
-
}
|
|
1414
|
-
function cssSafeAreaPercent(bridge, side) {
|
|
1415
|
-
return pixelsToPercentOfViewport(readCssSafeAreaPixels(bridge, side), bridge, side);
|
|
167
|
+
await bridge.__oasizShareRequest(request);
|
|
1416
168
|
}
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
return percent > 0 ? percent : cssSafeAreaPercent(bridge, side);
|
|
169
|
+
|
|
170
|
+
// src/state.ts
|
|
171
|
+
function isDevelopment5() {
|
|
172
|
+
const nodeEnv = globalThis.process?.env?.NODE_ENV;
|
|
173
|
+
return nodeEnv !== "production";
|
|
1423
174
|
}
|
|
1424
|
-
function
|
|
1425
|
-
|
|
1426
|
-
if (typeof numeric === "undefined") {
|
|
175
|
+
function getBridgeWindow5() {
|
|
176
|
+
if (typeof window === "undefined") {
|
|
1427
177
|
return void 0;
|
|
1428
178
|
}
|
|
1429
|
-
return
|
|
179
|
+
return window;
|
|
1430
180
|
}
|
|
1431
|
-
function
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
return "Top";
|
|
1435
|
-
case "right":
|
|
1436
|
-
return "Right";
|
|
1437
|
-
case "bottom":
|
|
1438
|
-
return "Bottom";
|
|
1439
|
-
case "left":
|
|
1440
|
-
return "Left";
|
|
181
|
+
function isPlainObject(value) {
|
|
182
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
183
|
+
return false;
|
|
1441
184
|
}
|
|
185
|
+
const proto = Object.getPrototypeOf(value);
|
|
186
|
+
return proto === Object.prototype || proto === null;
|
|
1442
187
|
}
|
|
1443
|
-
function
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
try {
|
|
1449
|
-
return fn.call(bridge);
|
|
1450
|
-
} catch (error) {
|
|
1451
|
-
console.error("[oasiz/sdk] " + String(name) + " failed:", error);
|
|
1452
|
-
return void 0;
|
|
188
|
+
function warnMissingBridge3(methodName) {
|
|
189
|
+
if (isDevelopment5()) {
|
|
190
|
+
console.warn(
|
|
191
|
+
"[oasiz/sdk] " + methodName + " bridge is unavailable. This is expected in local development."
|
|
192
|
+
);
|
|
1453
193
|
}
|
|
1454
194
|
}
|
|
1455
|
-
function
|
|
1456
|
-
|
|
1457
|
-
|
|
195
|
+
function loadGameState() {
|
|
196
|
+
const bridge = getBridgeWindow5();
|
|
197
|
+
if (typeof bridge?.loadGameState !== "function") {
|
|
198
|
+
warnMissingBridge3("loadGameState");
|
|
199
|
+
return {};
|
|
1458
200
|
}
|
|
1459
|
-
|
|
1460
|
-
|
|
201
|
+
const state = bridge.loadGameState();
|
|
202
|
+
if (!isPlainObject(state)) {
|
|
203
|
+
if (isDevelopment5()) {
|
|
204
|
+
console.warn(
|
|
205
|
+
"[oasiz/sdk] loadGameState returned invalid data. Falling back to empty object."
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
return {};
|
|
1461
209
|
}
|
|
1462
|
-
return
|
|
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
|
-
);
|
|
210
|
+
return state;
|
|
1494
211
|
}
|
|
1495
|
-
function
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
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
|
-
};
|
|
212
|
+
function saveGameState(state) {
|
|
213
|
+
if (!isPlainObject(state)) {
|
|
214
|
+
if (isDevelopment5()) {
|
|
215
|
+
console.warn("[oasiz/sdk] saveGameState expected a plain object:", state);
|
|
216
|
+
}
|
|
217
|
+
return;
|
|
1511
218
|
}
|
|
1512
|
-
const
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
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
|
-
};
|
|
219
|
+
const bridge = getBridgeWindow5();
|
|
220
|
+
if (typeof bridge?.saveGameState === "function") {
|
|
221
|
+
bridge.saveGameState(state);
|
|
222
|
+
return;
|
|
1525
223
|
}
|
|
1526
|
-
|
|
1527
|
-
return {
|
|
1528
|
-
pixels: cssPixels,
|
|
1529
|
-
percent: pixelsToPercentOfViewport(cssPixels, bridge, side)
|
|
1530
|
-
};
|
|
224
|
+
warnMissingBridge3("saveGameState");
|
|
1531
225
|
}
|
|
1532
|
-
function
|
|
1533
|
-
const bridge =
|
|
1534
|
-
if (
|
|
1535
|
-
|
|
1536
|
-
|
|
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;
|
|
226
|
+
function flushGameState() {
|
|
227
|
+
const bridge = getBridgeWindow5();
|
|
228
|
+
if (typeof bridge?.flushGameState === "function") {
|
|
229
|
+
bridge.flushGameState();
|
|
230
|
+
return;
|
|
1547
231
|
}
|
|
1548
|
-
|
|
232
|
+
warnMissingBridge3("flushGameState");
|
|
1549
233
|
}
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
const top = getViewportInsets().percent.top;
|
|
1556
|
-
if (top <= 0) {
|
|
1557
|
-
warnMissingBridge6("getSafeAreaTop");
|
|
1558
|
-
}
|
|
1559
|
-
return top;
|
|
234
|
+
|
|
235
|
+
// src/lifecycle.ts
|
|
236
|
+
function isDevelopment6() {
|
|
237
|
+
const nodeEnv = globalThis.process?.env?.NODE_ENV;
|
|
238
|
+
return nodeEnv !== "production";
|
|
1560
239
|
}
|
|
1561
|
-
function
|
|
1562
|
-
if (typeof
|
|
1563
|
-
if (
|
|
240
|
+
function addLifecycleListener(eventName, callback) {
|
|
241
|
+
if (typeof window === "undefined") {
|
|
242
|
+
if (isDevelopment6()) {
|
|
1564
243
|
console.warn(
|
|
1565
|
-
"[oasiz/sdk]
|
|
1566
|
-
visible
|
|
244
|
+
"[oasiz/sdk] " + eventName + " listener registered without a browser window. This is expected in local development."
|
|
1567
245
|
);
|
|
1568
246
|
}
|
|
1569
|
-
return
|
|
1570
|
-
|
|
1571
|
-
const bridge = getBridgeWindow8();
|
|
1572
|
-
if (typeof bridge?.__oasizSetLeaderboardVisible === "function") {
|
|
1573
|
-
bridge.__oasizSetLeaderboardVisible(visible);
|
|
1574
|
-
return;
|
|
247
|
+
return () => {
|
|
248
|
+
};
|
|
1575
249
|
}
|
|
1576
|
-
|
|
250
|
+
const handler = () => callback();
|
|
251
|
+
window.addEventListener(eventName, handler);
|
|
252
|
+
return () => window.removeEventListener(eventName, handler);
|
|
253
|
+
}
|
|
254
|
+
function onPause(callback) {
|
|
255
|
+
return addLifecycleListener("oasiz:pause", callback);
|
|
256
|
+
}
|
|
257
|
+
function onResume(callback) {
|
|
258
|
+
return addLifecycleListener("oasiz:resume", callback);
|
|
1577
259
|
}
|
|
1578
260
|
|
|
1579
261
|
// src/navigation.ts
|
|
1580
|
-
var BACK_BUTTON_TEST_STATE_KEY = "__oasizBackButtonTest";
|
|
1581
262
|
var activeBackListeners = 0;
|
|
1582
|
-
|
|
1583
|
-
function isDevelopment10() {
|
|
263
|
+
function isDevelopment7() {
|
|
1584
264
|
const nodeEnv = globalThis.process?.env?.NODE_ENV;
|
|
1585
265
|
return nodeEnv !== "production";
|
|
1586
266
|
}
|
|
1587
|
-
function
|
|
267
|
+
function getBridgeWindow6() {
|
|
1588
268
|
if (typeof window === "undefined") {
|
|
1589
269
|
return void 0;
|
|
1590
270
|
}
|
|
1591
271
|
return window;
|
|
1592
272
|
}
|
|
1593
|
-
function
|
|
1594
|
-
if (
|
|
273
|
+
function warnMissingBridge4(methodName) {
|
|
274
|
+
if (isDevelopment7()) {
|
|
1595
275
|
console.warn(
|
|
1596
276
|
"[oasiz/sdk] " + methodName + " bridge is unavailable. This is expected in local development."
|
|
1597
277
|
);
|
|
@@ -1605,19 +285,9 @@ function normalizeNavigationError(error) {
|
|
|
1605
285
|
typeof error === "string" ? error : "Back button callback failed."
|
|
1606
286
|
);
|
|
1607
287
|
}
|
|
1608
|
-
function isRecord2(value) {
|
|
1609
|
-
return typeof value === "object" && value !== null;
|
|
1610
|
-
}
|
|
1611
|
-
function dispatchNavigationEvent(eventName) {
|
|
1612
|
-
const bridge = getBridgeWindow9();
|
|
1613
|
-
if (!bridge || typeof bridge.dispatchEvent !== "function") {
|
|
1614
|
-
return;
|
|
1615
|
-
}
|
|
1616
|
-
bridge.dispatchEvent(new Event(eventName));
|
|
1617
|
-
}
|
|
1618
288
|
function addNavigationListener(eventName, callback) {
|
|
1619
289
|
if (typeof window === "undefined") {
|
|
1620
|
-
if (
|
|
290
|
+
if (isDevelopment7()) {
|
|
1621
291
|
console.warn(
|
|
1622
292
|
"[oasiz/sdk] " + eventName + " listener registered without a browser window. This is expected in local development."
|
|
1623
293
|
);
|
|
@@ -1629,151 +299,6 @@ function addNavigationListener(eventName, callback) {
|
|
|
1629
299
|
window.addEventListener(eventName, handler);
|
|
1630
300
|
return () => window.removeEventListener(eventName, handler);
|
|
1631
301
|
}
|
|
1632
|
-
function enableBackButtonTesting(options = {}) {
|
|
1633
|
-
activeBackButtonTestingHandle?.destroy();
|
|
1634
|
-
const bridge = getBridgeWindow9();
|
|
1635
|
-
if (!bridge) {
|
|
1636
|
-
if (isDevelopment10()) {
|
|
1637
|
-
console.warn(
|
|
1638
|
-
"[oasiz/sdk] enableBackButtonTesting requires a browser window."
|
|
1639
|
-
);
|
|
1640
|
-
}
|
|
1641
|
-
return {
|
|
1642
|
-
destroy: () => {
|
|
1643
|
-
},
|
|
1644
|
-
isBackOverrideActive: () => false,
|
|
1645
|
-
triggerBack: () => {
|
|
1646
|
-
},
|
|
1647
|
-
triggerLeave: () => {
|
|
1648
|
-
}
|
|
1649
|
-
};
|
|
1650
|
-
}
|
|
1651
|
-
const bridgeWindow = bridge;
|
|
1652
|
-
const keyboard = options.keyboard ?? true;
|
|
1653
|
-
const browserHistory = options.browserHistory ?? true;
|
|
1654
|
-
const log = options.log === true;
|
|
1655
|
-
const previousSetBackOverride = bridgeWindow.__oasizSetBackOverride;
|
|
1656
|
-
const previousLeaveGame = bridgeWindow.__oasizLeaveGame;
|
|
1657
|
-
let destroyed = false;
|
|
1658
|
-
let backOverrideActive = false;
|
|
1659
|
-
let historyTrapArmed = false;
|
|
1660
|
-
function maybeLog(message) {
|
|
1661
|
-
if (log) {
|
|
1662
|
-
console.info("[oasiz/sdk] " + message);
|
|
1663
|
-
}
|
|
1664
|
-
}
|
|
1665
|
-
function canUseHistoryTrap() {
|
|
1666
|
-
return browserHistory && typeof bridgeWindow.history?.pushState === "function" && typeof bridgeWindow.history?.replaceState === "function" && typeof bridgeWindow.location?.href === "string";
|
|
1667
|
-
}
|
|
1668
|
-
function ensureHistoryTrap() {
|
|
1669
|
-
if (!backOverrideActive || historyTrapArmed || !canUseHistoryTrap()) {
|
|
1670
|
-
return;
|
|
1671
|
-
}
|
|
1672
|
-
try {
|
|
1673
|
-
const currentState = isRecord2(bridgeWindow.history.state) ? bridgeWindow.history.state : {};
|
|
1674
|
-
bridgeWindow.history.replaceState(
|
|
1675
|
-
{ ...currentState, [BACK_BUTTON_TEST_STATE_KEY]: "base" },
|
|
1676
|
-
"",
|
|
1677
|
-
bridgeWindow.location.href
|
|
1678
|
-
);
|
|
1679
|
-
bridgeWindow.history.pushState(
|
|
1680
|
-
{ [BACK_BUTTON_TEST_STATE_KEY]: "trap" },
|
|
1681
|
-
"",
|
|
1682
|
-
bridgeWindow.location.href
|
|
1683
|
-
);
|
|
1684
|
-
historyTrapArmed = true;
|
|
1685
|
-
maybeLog("Local browser Back testing is armed.");
|
|
1686
|
-
} catch (error) {
|
|
1687
|
-
historyTrapArmed = false;
|
|
1688
|
-
if (log) {
|
|
1689
|
-
console.warn("[oasiz/sdk] Failed to arm browser Back testing:", error);
|
|
1690
|
-
}
|
|
1691
|
-
}
|
|
1692
|
-
}
|
|
1693
|
-
function triggerBack() {
|
|
1694
|
-
dispatchNavigationEvent("oasiz:back");
|
|
1695
|
-
}
|
|
1696
|
-
function triggerLeave() {
|
|
1697
|
-
dispatchNavigationEvent("oasiz:leave");
|
|
1698
|
-
}
|
|
1699
|
-
function setBackOverride(active) {
|
|
1700
|
-
backOverrideActive = active;
|
|
1701
|
-
if (active) {
|
|
1702
|
-
ensureHistoryTrap();
|
|
1703
|
-
}
|
|
1704
|
-
if (typeof previousSetBackOverride === "function") {
|
|
1705
|
-
previousSetBackOverride(active);
|
|
1706
|
-
}
|
|
1707
|
-
maybeLog("Back override " + (active ? "enabled" : "disabled") + ".");
|
|
1708
|
-
}
|
|
1709
|
-
function stopBackEvent(event) {
|
|
1710
|
-
event.preventDefault();
|
|
1711
|
-
event.stopPropagation();
|
|
1712
|
-
event.stopImmediatePropagation?.();
|
|
1713
|
-
}
|
|
1714
|
-
const handleKeyDown = (event) => {
|
|
1715
|
-
if (!backOverrideActive || event.key !== "Escape") {
|
|
1716
|
-
return;
|
|
1717
|
-
}
|
|
1718
|
-
stopBackEvent(event);
|
|
1719
|
-
triggerBack();
|
|
1720
|
-
};
|
|
1721
|
-
const handlePopState = (event) => {
|
|
1722
|
-
if (!backOverrideActive) {
|
|
1723
|
-
historyTrapArmed = false;
|
|
1724
|
-
return;
|
|
1725
|
-
}
|
|
1726
|
-
stopBackEvent(event);
|
|
1727
|
-
triggerBack();
|
|
1728
|
-
historyTrapArmed = false;
|
|
1729
|
-
ensureHistoryTrap();
|
|
1730
|
-
};
|
|
1731
|
-
const testLeaveGame = () => {
|
|
1732
|
-
triggerLeave();
|
|
1733
|
-
if (typeof previousLeaveGame === "function") {
|
|
1734
|
-
previousLeaveGame();
|
|
1735
|
-
}
|
|
1736
|
-
};
|
|
1737
|
-
bridgeWindow.__oasizSetBackOverride = setBackOverride;
|
|
1738
|
-
bridgeWindow.__oasizLeaveGame = testLeaveGame;
|
|
1739
|
-
if (keyboard) {
|
|
1740
|
-
bridgeWindow.addEventListener("keydown", handleKeyDown);
|
|
1741
|
-
}
|
|
1742
|
-
if (browserHistory) {
|
|
1743
|
-
bridgeWindow.addEventListener("popstate", handlePopState);
|
|
1744
|
-
}
|
|
1745
|
-
if (activeBackListeners > 0) {
|
|
1746
|
-
setBackOverride(true);
|
|
1747
|
-
}
|
|
1748
|
-
maybeLog("Back button testing bridge installed.");
|
|
1749
|
-
const handle = {
|
|
1750
|
-
destroy: () => {
|
|
1751
|
-
if (destroyed) return;
|
|
1752
|
-
destroyed = true;
|
|
1753
|
-
if (keyboard) {
|
|
1754
|
-
bridgeWindow.removeEventListener("keydown", handleKeyDown);
|
|
1755
|
-
}
|
|
1756
|
-
if (browserHistory) {
|
|
1757
|
-
bridgeWindow.removeEventListener("popstate", handlePopState);
|
|
1758
|
-
}
|
|
1759
|
-
if (bridgeWindow.__oasizSetBackOverride === setBackOverride) {
|
|
1760
|
-
bridgeWindow.__oasizSetBackOverride = previousSetBackOverride;
|
|
1761
|
-
}
|
|
1762
|
-
if (bridgeWindow.__oasizLeaveGame === testLeaveGame) {
|
|
1763
|
-
bridgeWindow.__oasizLeaveGame = previousLeaveGame;
|
|
1764
|
-
}
|
|
1765
|
-
if (activeBackButtonTestingHandle === handle) {
|
|
1766
|
-
activeBackButtonTestingHandle = void 0;
|
|
1767
|
-
}
|
|
1768
|
-
maybeLog("Back button testing bridge removed.");
|
|
1769
|
-
},
|
|
1770
|
-
isBackOverrideActive: () => backOverrideActive,
|
|
1771
|
-
triggerBack,
|
|
1772
|
-
triggerLeave
|
|
1773
|
-
};
|
|
1774
|
-
activeBackButtonTestingHandle = handle;
|
|
1775
|
-
return handle;
|
|
1776
|
-
}
|
|
1777
302
|
function onBackButton(callback) {
|
|
1778
303
|
const off = addNavigationListener("oasiz:back", () => {
|
|
1779
304
|
try {
|
|
@@ -1783,24 +308,24 @@ function onBackButton(callback) {
|
|
|
1783
308
|
throw normalizeNavigationError(error);
|
|
1784
309
|
}
|
|
1785
310
|
});
|
|
1786
|
-
const bridge =
|
|
311
|
+
const bridge = getBridgeWindow6();
|
|
1787
312
|
activeBackListeners += 1;
|
|
1788
313
|
if (activeBackListeners === 1) {
|
|
1789
314
|
if (typeof bridge?.__oasizSetBackOverride === "function") {
|
|
1790
315
|
bridge.__oasizSetBackOverride(true);
|
|
1791
316
|
} else {
|
|
1792
|
-
|
|
317
|
+
warnMissingBridge4("__oasizSetBackOverride");
|
|
1793
318
|
}
|
|
1794
319
|
}
|
|
1795
320
|
return () => {
|
|
1796
321
|
off();
|
|
1797
322
|
activeBackListeners = Math.max(0, activeBackListeners - 1);
|
|
1798
323
|
if (activeBackListeners === 0) {
|
|
1799
|
-
const currentBridge =
|
|
324
|
+
const currentBridge = getBridgeWindow6();
|
|
1800
325
|
if (typeof currentBridge?.__oasizSetBackOverride === "function") {
|
|
1801
326
|
currentBridge.__oasizSetBackOverride(false);
|
|
1802
327
|
} else {
|
|
1803
|
-
|
|
328
|
+
warnMissingBridge4("__oasizSetBackOverride");
|
|
1804
329
|
}
|
|
1805
330
|
}
|
|
1806
331
|
};
|
|
@@ -1809,413 +334,176 @@ function onLeaveGame(callback) {
|
|
|
1809
334
|
return addNavigationListener("oasiz:leave", callback);
|
|
1810
335
|
}
|
|
1811
336
|
function leaveGame() {
|
|
1812
|
-
const bridge =
|
|
337
|
+
const bridge = getBridgeWindow6();
|
|
1813
338
|
if (typeof bridge?.__oasizLeaveGame === "function") {
|
|
1814
339
|
bridge.__oasizLeaveGame();
|
|
1815
340
|
return;
|
|
1816
341
|
}
|
|
1817
|
-
|
|
342
|
+
warnMissingBridge4("__oasizLeaveGame");
|
|
1818
343
|
}
|
|
1819
344
|
|
|
1820
|
-
// src/
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
}
|
|
1825
|
-
|
|
1826
|
-
minimal: 24,
|
|
1827
|
-
low: 30,
|
|
1828
|
-
medium: 45,
|
|
1829
|
-
high: 60
|
|
1830
|
-
};
|
|
1831
|
-
var cachedEstimatedGraphicsPerformance;
|
|
1832
|
-
function getBridgeWindow10() {
|
|
345
|
+
// src/store.ts
|
|
346
|
+
function isDevelopment8() {
|
|
347
|
+
const nodeEnv = globalThis.process?.env?.NODE_ENV;
|
|
348
|
+
return nodeEnv !== "production";
|
|
349
|
+
}
|
|
350
|
+
function getBridgeWindow7() {
|
|
1833
351
|
if (typeof window === "undefined") {
|
|
1834
352
|
return void 0;
|
|
1835
353
|
}
|
|
1836
354
|
return window;
|
|
1837
355
|
}
|
|
1838
|
-
function
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
return value;
|
|
1844
|
-
}
|
|
1845
|
-
if (typeof value === "string") {
|
|
1846
|
-
const parsed = Number.parseFloat(value.trim());
|
|
1847
|
-
if (Number.isFinite(parsed)) {
|
|
1848
|
-
return parsed;
|
|
1849
|
-
}
|
|
356
|
+
function warnMissingBridge5(methodName) {
|
|
357
|
+
if (isDevelopment8()) {
|
|
358
|
+
console.warn(
|
|
359
|
+
"[oasiz/sdk] " + methodName + " store bridge is unavailable. This is expected in local development."
|
|
360
|
+
);
|
|
1850
361
|
}
|
|
1851
|
-
return void 0;
|
|
1852
|
-
}
|
|
1853
|
-
function clampScore(value) {
|
|
1854
|
-
return Math.min(100, Math.max(0, Math.round(value)));
|
|
1855
|
-
}
|
|
1856
|
-
function clampFps(value) {
|
|
1857
|
-
return Math.min(240, Math.max(1, Math.round(value)));
|
|
1858
|
-
}
|
|
1859
|
-
function tierFromScore(score) {
|
|
1860
|
-
if (score < 25) return "minimal";
|
|
1861
|
-
if (score < 40) return "low";
|
|
1862
|
-
if (score < 70) return "medium";
|
|
1863
|
-
return "high";
|
|
1864
|
-
}
|
|
1865
|
-
function tierFromFps(fps) {
|
|
1866
|
-
if (fps < 30) return "minimal";
|
|
1867
|
-
if (fps < 45) return "low";
|
|
1868
|
-
if (fps < 58) return "medium";
|
|
1869
|
-
return "high";
|
|
1870
|
-
}
|
|
1871
|
-
function fpsFromScore(score) {
|
|
1872
|
-
return TIER_DEFAULT_FPS[tierFromScore(score)];
|
|
1873
362
|
}
|
|
1874
|
-
function
|
|
1875
|
-
|
|
1876
|
-
|
|
363
|
+
async function requestStoreBridge(action, payload) {
|
|
364
|
+
const bridge = getBridgeWindow7();
|
|
365
|
+
if (typeof bridge?.__oasizStoreBridgeRequest !== "function") {
|
|
366
|
+
warnMissingBridge5(action);
|
|
367
|
+
throw new Error("Store bridge unavailable");
|
|
1877
368
|
}
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
if (normalized === "low") return "low";
|
|
1883
|
-
return void 0;
|
|
369
|
+
return await bridge.__oasizStoreBridgeRequest({
|
|
370
|
+
action,
|
|
371
|
+
payload
|
|
372
|
+
});
|
|
1884
373
|
}
|
|
1885
|
-
function
|
|
1886
|
-
return
|
|
374
|
+
async function getFreshState() {
|
|
375
|
+
return await requestStoreBridge("getStoreState");
|
|
1887
376
|
}
|
|
1888
|
-
function
|
|
1889
|
-
if (typeof
|
|
1890
|
-
return
|
|
1891
|
-
|
|
1892
|
-
if (typeof value === "number" || typeof value === "string") {
|
|
1893
|
-
const numeric = toFiniteNumber2(value);
|
|
1894
|
-
if (typeof numeric !== "undefined") {
|
|
1895
|
-
const fps2 = clampFps(numeric);
|
|
1896
|
-
return { fps: fps2, tier: tierFromFps(fps2) };
|
|
1897
|
-
}
|
|
1898
|
-
const tier2 = normalizeTier(value);
|
|
1899
|
-
if (tier2) {
|
|
1900
|
-
return { fps: TIER_DEFAULT_FPS[tier2], tier: tier2 };
|
|
1901
|
-
}
|
|
1902
|
-
return void 0;
|
|
1903
|
-
}
|
|
1904
|
-
if (!isRecord3(value)) {
|
|
1905
|
-
return void 0;
|
|
1906
|
-
}
|
|
1907
|
-
const fpsCandidate = firstDefined2(
|
|
1908
|
-
value.fps,
|
|
1909
|
-
value.targetFps,
|
|
1910
|
-
value.frameRate,
|
|
1911
|
-
value.framesPerSecond
|
|
1912
|
-
);
|
|
1913
|
-
const legacyScoreCandidate = firstDefined2(
|
|
1914
|
-
value.score,
|
|
1915
|
-
value.metric,
|
|
1916
|
-
value.value,
|
|
1917
|
-
value.performance,
|
|
1918
|
-
value.performanceScore,
|
|
1919
|
-
value.graphicsScore
|
|
1920
|
-
);
|
|
1921
|
-
const tierCandidate = firstDefined2(
|
|
1922
|
-
value.tier,
|
|
1923
|
-
value.graphicsTier,
|
|
1924
|
-
value.performanceTier,
|
|
1925
|
-
value.qualityTier,
|
|
1926
|
-
value.recommendedTier
|
|
1927
|
-
);
|
|
1928
|
-
const tier = normalizeTier(tierCandidate);
|
|
1929
|
-
const fpsNumeric = toFiniteNumber2(fpsCandidate);
|
|
1930
|
-
const scoreNumeric = toFiniteNumber2(legacyScoreCandidate);
|
|
1931
|
-
if (typeof fpsNumeric === "undefined" && typeof scoreNumeric === "undefined" && !tier) {
|
|
1932
|
-
return void 0;
|
|
377
|
+
function subscribeToStoreEvent(eventName, callback) {
|
|
378
|
+
if (typeof window === "undefined") {
|
|
379
|
+
return () => {
|
|
380
|
+
};
|
|
1933
381
|
}
|
|
1934
|
-
const
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
382
|
+
const handler = (event) => {
|
|
383
|
+
const customEvent = event;
|
|
384
|
+
callback(customEvent.detail);
|
|
385
|
+
};
|
|
386
|
+
window.addEventListener(eventName, handler);
|
|
387
|
+
return () => {
|
|
388
|
+
window.removeEventListener(eventName, handler);
|
|
1940
389
|
};
|
|
1941
390
|
}
|
|
1942
|
-
function
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
}
|
|
1947
|
-
try {
|
|
1948
|
-
return fn.call(bridge);
|
|
1949
|
-
} catch (error) {
|
|
1950
|
-
console.error("[oasiz/sdk] " + String(name) + " failed:", error);
|
|
1951
|
-
return void 0;
|
|
1952
|
-
}
|
|
1953
|
-
}
|
|
1954
|
-
function readHostGraphicsPerformance(bridge) {
|
|
1955
|
-
const candidates = [
|
|
1956
|
-
callBridgeMetric(bridge, "getGraphicsPerformance"),
|
|
1957
|
-
callBridgeMetric(bridge, "getGraphicsPerformanceMetric"),
|
|
1958
|
-
callBridgeMetric(bridge, "getPerformanceMetric"),
|
|
1959
|
-
bridge.__OASIZ_GRAPHICS_PERFORMANCE__,
|
|
1960
|
-
bridge.__OASIZ_PERFORMANCE_METRIC__
|
|
1961
|
-
];
|
|
1962
|
-
for (const candidate of candidates) {
|
|
1963
|
-
const metric = normalizeMetric(candidate);
|
|
1964
|
-
if (metric) {
|
|
1965
|
-
return metric;
|
|
1966
|
-
}
|
|
1967
|
-
}
|
|
1968
|
-
return void 0;
|
|
1969
|
-
}
|
|
1970
|
-
function getDevicePixelRatio2(bridge) {
|
|
1971
|
-
const dpr = bridge.devicePixelRatio;
|
|
1972
|
-
return typeof dpr === "number" && Number.isFinite(dpr) && dpr > 0 ? dpr : 1;
|
|
1973
|
-
}
|
|
1974
|
-
function getNavigatorValue(bridge) {
|
|
1975
|
-
return bridge.navigator;
|
|
1976
|
-
}
|
|
1977
|
-
function parseIosMajorVersion(userAgent) {
|
|
1978
|
-
const match = /\bOS (\d+)_/i.exec(userAgent);
|
|
1979
|
-
if (!match) {
|
|
1980
|
-
return void 0;
|
|
1981
|
-
}
|
|
1982
|
-
const parsed = Number.parseInt(match[1] ?? "", 10);
|
|
1983
|
-
return Number.isFinite(parsed) ? parsed : void 0;
|
|
1984
|
-
}
|
|
1985
|
-
function isAppleMobileDevice(bridge) {
|
|
1986
|
-
const userAgent = bridge.navigator?.userAgent ?? "";
|
|
1987
|
-
return /iP(hone|ad|od)/i.test(userAgent) || /Macintosh/i.test(userAgent) && (bridge.navigator?.maxTouchPoints ?? 0) > 1;
|
|
1988
|
-
}
|
|
1989
|
-
function getLongestScreenEdge(bridge) {
|
|
1990
|
-
const screenWidth = bridge.screen?.width;
|
|
1991
|
-
const screenHeight = bridge.screen?.height;
|
|
1992
|
-
const innerWidth = bridge.innerWidth;
|
|
1993
|
-
const innerHeight = bridge.innerHeight;
|
|
1994
|
-
return Math.max(
|
|
1995
|
-
typeof screenWidth === "number" ? screenWidth : 0,
|
|
1996
|
-
typeof screenHeight === "number" ? screenHeight : 0,
|
|
1997
|
-
typeof innerWidth === "number" ? innerWidth : 0,
|
|
1998
|
-
typeof innerHeight === "number" ? innerHeight : 0
|
|
1999
|
-
);
|
|
391
|
+
async function syncProducts(products, expectedVersion) {
|
|
392
|
+
return await requestStoreBridge("syncProducts", {
|
|
393
|
+
expectedVersion: expectedVersion ?? null,
|
|
394
|
+
products
|
|
395
|
+
});
|
|
2000
396
|
}
|
|
2001
|
-
function
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
} catch {
|
|
2005
|
-
return false;
|
|
2006
|
-
}
|
|
397
|
+
async function getProducts() {
|
|
398
|
+
const state = await getFreshState();
|
|
399
|
+
return state.products;
|
|
2007
400
|
}
|
|
2008
|
-
function
|
|
2009
|
-
const
|
|
2010
|
-
|
|
2011
|
-
return { webglVersion: 0 };
|
|
2012
|
-
}
|
|
2013
|
-
const gl2 = canvas.getContext("webgl2");
|
|
2014
|
-
const gl = gl2 ?? canvas.getContext("webgl") ?? canvas.getContext("experimental-webgl");
|
|
2015
|
-
if (!gl) {
|
|
2016
|
-
return { webglVersion: 0 };
|
|
2017
|
-
}
|
|
2018
|
-
const context = gl;
|
|
2019
|
-
let maxTextureSize;
|
|
2020
|
-
let renderer;
|
|
2021
|
-
try {
|
|
2022
|
-
const value = context.getParameter(context.MAX_TEXTURE_SIZE);
|
|
2023
|
-
if (typeof value === "number" && Number.isFinite(value)) {
|
|
2024
|
-
maxTextureSize = value;
|
|
2025
|
-
}
|
|
2026
|
-
} catch {
|
|
2027
|
-
}
|
|
2028
|
-
try {
|
|
2029
|
-
const debugInfo = context.getExtension("WEBGL_debug_renderer_info");
|
|
2030
|
-
const rendererParam = debugInfo?.UNMASKED_RENDERER_WEBGL ?? context.RENDERER;
|
|
2031
|
-
const value = context.getParameter(rendererParam);
|
|
2032
|
-
if (typeof value === "string") {
|
|
2033
|
-
renderer = value;
|
|
2034
|
-
}
|
|
2035
|
-
} catch {
|
|
2036
|
-
}
|
|
2037
|
-
return {
|
|
2038
|
-
maxTextureSize,
|
|
2039
|
-
renderer,
|
|
2040
|
-
webglVersion: gl2 ? 2 : 1
|
|
2041
|
-
};
|
|
401
|
+
async function getEntitlements() {
|
|
402
|
+
const state = await getFreshState();
|
|
403
|
+
return state.entitlements;
|
|
2042
404
|
}
|
|
2043
|
-
function
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
}
|
|
2047
|
-
if (memory <= 1) return score - 18;
|
|
2048
|
-
if (memory <= 2) return score - 10;
|
|
2049
|
-
if (memory >= 8) return score + 16;
|
|
2050
|
-
if (memory >= 6) return score + 10;
|
|
2051
|
-
return score;
|
|
405
|
+
async function hasEntitlement(productId) {
|
|
406
|
+
const state = await getFreshState();
|
|
407
|
+
return state.entitlements.find((item) => item.productId === productId)?.owned === true;
|
|
2052
408
|
}
|
|
2053
|
-
function
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
}
|
|
2057
|
-
if (cores <= 2) return score - 12;
|
|
2058
|
-
if (cores <= 4) return score;
|
|
2059
|
-
if (cores >= 8) return score + 12;
|
|
2060
|
-
return score + 8;
|
|
409
|
+
async function getQuantity(productId) {
|
|
410
|
+
const state = await getFreshState();
|
|
411
|
+
return state.entitlements.find((item) => item.productId === productId)?.quantity ?? 0;
|
|
2061
412
|
}
|
|
2062
|
-
function
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
}
|
|
2067
|
-
next += 6;
|
|
2068
|
-
} else {
|
|
2069
|
-
next -= 25;
|
|
2070
|
-
}
|
|
2071
|
-
if (typeof info.maxTextureSize === "number") {
|
|
2072
|
-
if (info.maxTextureSize >= 8192) next += 10;
|
|
2073
|
-
else if (info.maxTextureSize >= 4096) next += 3;
|
|
2074
|
-
else next -= 8;
|
|
2075
|
-
}
|
|
2076
|
-
const renderer = info.renderer?.toLowerCase() ?? "";
|
|
2077
|
-
if (/swiftshader|llvmpipe|software/.test(renderer)) {
|
|
2078
|
-
next = Math.min(next, 35);
|
|
2079
|
-
} else if (/\bm[1-9]\b|apple gpu|a1[6-9]|rtx|radeon|adreno 7|adreno 8/.test(renderer)) {
|
|
2080
|
-
next += 8;
|
|
2081
|
-
}
|
|
2082
|
-
return next;
|
|
413
|
+
async function purchase(productId, quantity = 1) {
|
|
414
|
+
return await requestStoreBridge("purchaseProduct", {
|
|
415
|
+
productId,
|
|
416
|
+
quantity
|
|
417
|
+
});
|
|
2083
418
|
}
|
|
2084
|
-
function
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
const width = bridge.screen?.width ?? bridge.innerWidth ?? 0;
|
|
2090
|
-
const height = bridge.screen?.height ?? bridge.innerHeight ?? 0;
|
|
2091
|
-
const physicalPixels = width * height * dpr * dpr;
|
|
2092
|
-
if (physicalPixels > 4e6) {
|
|
2093
|
-
return score - 5;
|
|
2094
|
-
}
|
|
2095
|
-
return score;
|
|
419
|
+
async function consume(productId, quantity = 1) {
|
|
420
|
+
return await requestStoreBridge("consumeProduct", {
|
|
421
|
+
productId,
|
|
422
|
+
quantity
|
|
423
|
+
});
|
|
2096
424
|
}
|
|
2097
|
-
function
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
}
|
|
2101
|
-
const userAgent = bridge.navigator?.userAgent ?? "";
|
|
2102
|
-
const iosMajorVersion = parseIosMajorVersion(userAgent);
|
|
2103
|
-
const highDensityDisplay = getDevicePixelRatio2(bridge) >= 3;
|
|
2104
|
-
const longestScreenEdge = getLongestScreenEdge(bridge);
|
|
2105
|
-
if (typeof iosMajorVersion === "number" && iosMajorVersion < 15) {
|
|
2106
|
-
return Math.min(score, 35);
|
|
2107
|
-
}
|
|
2108
|
-
if (highDensityDisplay && longestScreenEdge >= 430 && (typeof iosMajorVersion === "undefined" || iosMajorVersion >= 17)) {
|
|
2109
|
-
return Math.max(score, 78);
|
|
2110
|
-
}
|
|
2111
|
-
if (highDensityDisplay && longestScreenEdge >= 414 && (typeof iosMajorVersion === "undefined" || iosMajorVersion >= 16)) {
|
|
2112
|
-
return Math.max(score, 62);
|
|
2113
|
-
}
|
|
2114
|
-
return Math.min(score, 48);
|
|
425
|
+
async function getJemBalance() {
|
|
426
|
+
const state = await getFreshState();
|
|
427
|
+
return state.jemBalance;
|
|
2115
428
|
}
|
|
2116
|
-
function
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
score = applyCoreScore(score, navigatorValue?.hardwareConcurrency);
|
|
2121
|
-
score = applyWebGlScore(score, getWebGlInfo(bridge));
|
|
2122
|
-
score = applyMobileCostScore(score, bridge);
|
|
2123
|
-
score = applyAppleMobileRules(score, bridge);
|
|
2124
|
-
const normalizedScore = clampScore(score);
|
|
2125
|
-
return {
|
|
2126
|
-
fps: fpsFromScore(normalizedScore),
|
|
2127
|
-
tier: tierFromScore(normalizedScore)
|
|
2128
|
-
};
|
|
429
|
+
function onEntitlementsChanged(callback) {
|
|
430
|
+
return subscribeToStoreEvent("oasiz:entitlements-changed", (state) => {
|
|
431
|
+
callback(state.entitlements);
|
|
432
|
+
});
|
|
2129
433
|
}
|
|
2130
|
-
function
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
}
|
|
2135
|
-
const hostMetric = readHostGraphicsPerformance(bridge);
|
|
2136
|
-
if (hostMetric) {
|
|
2137
|
-
return hostMetric;
|
|
2138
|
-
}
|
|
2139
|
-
cachedEstimatedGraphicsPerformance ??= estimateGraphicsPerformance(bridge);
|
|
2140
|
-
return { ...cachedEstimatedGraphicsPerformance };
|
|
434
|
+
function onJemBalanceChanged(callback) {
|
|
435
|
+
return subscribeToStoreEvent("oasiz:jem-balance-changed", (state) => {
|
|
436
|
+
callback(state.jemBalance);
|
|
437
|
+
});
|
|
2141
438
|
}
|
|
2142
439
|
|
|
2143
440
|
// src/index.ts
|
|
2144
441
|
var oasiz = {
|
|
2145
442
|
submitScore,
|
|
2146
|
-
|
|
2147
|
-
setScore,
|
|
2148
|
-
getPlayerCharacter,
|
|
443
|
+
emitScoreConfig,
|
|
2149
444
|
share,
|
|
2150
445
|
triggerHaptic,
|
|
2151
|
-
enableLogOverlay,
|
|
2152
446
|
loadGameState,
|
|
2153
447
|
saveGameState,
|
|
2154
448
|
flushGameState,
|
|
2155
449
|
shareRoomCode,
|
|
2156
|
-
openInviteModal,
|
|
2157
450
|
onPause,
|
|
2158
451
|
onResume,
|
|
2159
|
-
getSafeAreaTop,
|
|
2160
|
-
getViewportInsets,
|
|
2161
|
-
setLeaderboardVisible,
|
|
2162
|
-
getGraphicsPerformance,
|
|
2163
|
-
enableBackButtonTesting,
|
|
2164
452
|
onBackButton,
|
|
2165
453
|
onLeaveGame,
|
|
2166
454
|
leaveGame,
|
|
455
|
+
store: {
|
|
456
|
+
syncProducts,
|
|
457
|
+
getProducts,
|
|
458
|
+
getEntitlements,
|
|
459
|
+
hasEntitlement,
|
|
460
|
+
getQuantity,
|
|
461
|
+
purchase,
|
|
462
|
+
consume,
|
|
463
|
+
getJemBalance,
|
|
464
|
+
onEntitlementsChanged,
|
|
465
|
+
onJemBalanceChanged
|
|
466
|
+
},
|
|
2167
467
|
get gameId() {
|
|
2168
468
|
return getGameId();
|
|
2169
469
|
},
|
|
2170
470
|
get roomCode() {
|
|
2171
471
|
return getRoomCode();
|
|
2172
472
|
},
|
|
2173
|
-
get playerId() {
|
|
2174
|
-
return getPlayerId();
|
|
2175
|
-
},
|
|
2176
473
|
get playerName() {
|
|
2177
474
|
return getPlayerName();
|
|
2178
475
|
},
|
|
2179
476
|
get playerAvatar() {
|
|
2180
477
|
return getPlayerAvatar();
|
|
2181
|
-
},
|
|
2182
|
-
get safeAreaTop() {
|
|
2183
|
-
return getSafeAreaTop();
|
|
2184
|
-
},
|
|
2185
|
-
get viewportInsets() {
|
|
2186
|
-
return getViewportInsets();
|
|
2187
|
-
},
|
|
2188
|
-
get graphicsPerformance() {
|
|
2189
|
-
return getGraphicsPerformance();
|
|
2190
478
|
}
|
|
2191
479
|
};
|
|
2192
480
|
export {
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
enableLogOverlay,
|
|
481
|
+
consume,
|
|
482
|
+
emitScoreConfig,
|
|
2196
483
|
flushGameState,
|
|
484
|
+
getEntitlements,
|
|
2197
485
|
getGameId,
|
|
2198
|
-
|
|
486
|
+
getJemBalance,
|
|
2199
487
|
getPlayerAvatar,
|
|
2200
|
-
getPlayerCharacter,
|
|
2201
|
-
getPlayerId,
|
|
2202
488
|
getPlayerName,
|
|
489
|
+
getProducts,
|
|
490
|
+
getQuantity,
|
|
2203
491
|
getRoomCode,
|
|
2204
|
-
|
|
2205
|
-
getViewportInsets,
|
|
492
|
+
hasEntitlement,
|
|
2206
493
|
leaveGame,
|
|
2207
494
|
loadGameState,
|
|
2208
495
|
oasiz,
|
|
2209
496
|
onBackButton,
|
|
497
|
+
onEntitlementsChanged,
|
|
498
|
+
onJemBalanceChanged,
|
|
2210
499
|
onLeaveGame,
|
|
2211
500
|
onPause,
|
|
2212
501
|
onResume,
|
|
2213
|
-
|
|
502
|
+
purchase,
|
|
2214
503
|
saveGameState,
|
|
2215
|
-
setLeaderboardVisible,
|
|
2216
|
-
setScore,
|
|
2217
504
|
share,
|
|
2218
505
|
shareRoomCode,
|
|
2219
506
|
submitScore,
|
|
507
|
+
syncProducts,
|
|
2220
508
|
triggerHaptic
|
|
2221
509
|
};
|