@oasiz/sdk 1.3.0 → 1.4.1

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/dist/index.js CHANGED
@@ -22,897 +22,6 @@ function triggerHaptic(type) {
22
22
  }
23
23
  }
24
24
 
25
- // src/log-overlay.ts
26
- var CONSOLE_METHODS = [
27
- "debug",
28
- "log",
29
- "info",
30
- "warn",
31
- "error"
32
- ];
33
- var DEFAULT_MAX_ENTRIES = 200;
34
- var DEFAULT_TITLE = "SDK Logs";
35
- var OVERLAY_MARGIN = 12;
36
- var DEFAULT_COLLAPSED_WIDTH = 156;
37
- var DEFAULT_COLLAPSED_HEIGHT = 52;
38
- var DEFAULT_EXPANDED_WIDTH = 565;
39
- var DEFAULT_EXPANDED_HEIGHT = 372;
40
- var DRAG_THRESHOLD_PX = 6;
41
- var MIN_EXPANDED_WIDTH = 160;
42
- var MIN_EXPANDED_HEIGHT = 110;
43
- var RESIZE_HOTSPOT_PX = 28;
44
- var TOP_DRAG_ZONE_PX = 44;
45
- var NOOP_HANDLE = {
46
- clear() {
47
- },
48
- destroy() {
49
- },
50
- hide() {
51
- },
52
- isVisible() {
53
- return false;
54
- },
55
- show() {
56
- }
57
- };
58
- function getBrowserWindow() {
59
- if (typeof window === "undefined") {
60
- return void 0;
61
- }
62
- return window;
63
- }
64
- function getDocument() {
65
- if (typeof document === "undefined") {
66
- return void 0;
67
- }
68
- return document;
69
- }
70
- function clampMaxEntries(value) {
71
- if (!Number.isFinite(value)) {
72
- return DEFAULT_MAX_ENTRIES;
73
- }
74
- return Math.max(10, Math.floor(value));
75
- }
76
- function createConsoleSnapshot() {
77
- const fallback = console.log.bind(console);
78
- return {
79
- debug: typeof console.debug === "function" ? console.debug.bind(console) : fallback,
80
- log: fallback,
81
- info: typeof console.info === "function" ? console.info.bind(console) : fallback,
82
- warn: typeof console.warn === "function" ? console.warn.bind(console) : fallback,
83
- error: typeof console.error === "function" ? console.error.bind(console) : fallback
84
- };
85
- }
86
- function formatTimestamp(timestamp) {
87
- const date = new Date(timestamp);
88
- const hours = String(date.getHours()).padStart(2, "0");
89
- const minutes = String(date.getMinutes()).padStart(2, "0");
90
- const seconds = String(date.getSeconds()).padStart(2, "0");
91
- const milliseconds = String(date.getMilliseconds()).padStart(3, "0");
92
- return "[" + hours + ":" + minutes + ":" + seconds + "." + milliseconds + "]";
93
- }
94
- function safeStringify(value) {
95
- const seen = /* @__PURE__ */ new WeakSet();
96
- try {
97
- return JSON.stringify(
98
- value,
99
- (_key, candidate) => {
100
- if (typeof candidate === "bigint") {
101
- return candidate.toString() + "n";
102
- }
103
- if (typeof candidate === "object" && candidate !== null) {
104
- if (seen.has(candidate)) {
105
- return "[Circular]";
106
- }
107
- seen.add(candidate);
108
- }
109
- return candidate;
110
- },
111
- 2
112
- ) ?? String(value);
113
- } catch {
114
- return String(value);
115
- }
116
- }
117
- function formatArg(value) {
118
- if (typeof value === "string") {
119
- return value;
120
- }
121
- if (value instanceof Error) {
122
- if (value.stack) {
123
- return value.stack;
124
- }
125
- return value.name + ": " + value.message;
126
- }
127
- if (typeof value === "undefined") {
128
- return "undefined";
129
- }
130
- if (typeof value === "function") {
131
- return "[Function " + (value.name || "anonymous") + "]";
132
- }
133
- return safeStringify(value);
134
- }
135
- function formatEntryMessage(args) {
136
- const message = args.map(formatArg).join(" ");
137
- if (message.length <= 4e3) {
138
- return message;
139
- }
140
- return message.slice(0, 3997) + "...";
141
- }
142
- function createEntry(level, args, id) {
143
- return {
144
- id,
145
- level,
146
- message: formatEntryMessage(args),
147
- timestamp: Date.now()
148
- };
149
- }
150
- function createButton(label) {
151
- const button = document.createElement("button");
152
- button.type = "button";
153
- button.textContent = label;
154
- button.style.cssText = [
155
- "appearance:none",
156
- "border:1px solid rgba(255,255,255,0.18)",
157
- "background:rgba(255,255,255,0.06)",
158
- "color:#f8fafc",
159
- "border-radius:999px",
160
- "padding:6px 10px",
161
- "font:600 12px/1.1 ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace",
162
- "cursor:pointer"
163
- ].join(";");
164
- return button;
165
- }
166
- function getLevelAccent(level) {
167
- if (level === "error") {
168
- return {
169
- lineBackground: "rgba(255, 109, 122, 0.08)"
170
- };
171
- }
172
- if (level === "warn") {
173
- return {
174
- lineBackground: "rgba(255, 196, 94, 0.07)"
175
- };
176
- }
177
- if (level === "info") {
178
- return {
179
- lineBackground: "rgba(82, 187, 255, 0.07)"
180
- };
181
- }
182
- if (level === "debug") {
183
- return {
184
- lineBackground: "rgba(166, 137, 255, 0.07)"
185
- };
186
- }
187
- return {
188
- lineBackground: "rgba(117, 235, 191, 0.06)"
189
- };
190
- }
191
- function getViewportSize() {
192
- const browserWindow = getBrowserWindow();
193
- return {
194
- width: Math.max(320, browserWindow?.innerWidth ?? 1280),
195
- height: Math.max(240, browserWindow?.innerHeight ?? 720)
196
- };
197
- }
198
- function clampPanelSize(size) {
199
- const viewport = getViewportSize();
200
- const maxWidth = Math.max(MIN_EXPANDED_WIDTH, viewport.width - OVERLAY_MARGIN * 2);
201
- const maxHeight = Math.max(
202
- MIN_EXPANDED_HEIGHT,
203
- viewport.height - OVERLAY_MARGIN * 2
204
- );
205
- return {
206
- width: Math.min(maxWidth, Math.max(MIN_EXPANDED_WIDTH, size.width)),
207
- height: Math.min(maxHeight, Math.max(MIN_EXPANDED_HEIGHT, size.height))
208
- };
209
- }
210
- function getOverlaySize(state) {
211
- if (state.expanded && state.panelSize) {
212
- return state.panelSize;
213
- }
214
- const rect = state.ui?.root && typeof state.ui.root.getBoundingClientRect === "function" ? state.ui.root.getBoundingClientRect() : null;
215
- if (rect && Number.isFinite(rect.width) && Number.isFinite(rect.height)) {
216
- return {
217
- width: Math.max(1, rect.width),
218
- height: Math.max(1, rect.height)
219
- };
220
- }
221
- return state.expanded ? clampPanelSize({
222
- width: DEFAULT_EXPANDED_WIDTH,
223
- height: DEFAULT_EXPANDED_HEIGHT
224
- }) : { width: DEFAULT_COLLAPSED_WIDTH, height: DEFAULT_COLLAPSED_HEIGHT };
225
- }
226
- function applyPanelSize(state) {
227
- if (!state.ui) {
228
- return;
229
- }
230
- if (!state.expanded) {
231
- state.ui.root.style.width = "auto";
232
- state.ui.panel.style.width = "min(565px, calc(100vw - 24px))";
233
- state.ui.panel.style.height = "auto";
234
- state.ui.entries.style.maxHeight = "min(36vh, 280px)";
235
- return;
236
- }
237
- if (!state.panelSize) {
238
- state.ui.root.style.width = "min(565px, calc(100vw - 24px))";
239
- state.ui.panel.style.width = "min(565px, calc(100vw - 24px))";
240
- state.ui.panel.style.height = "auto";
241
- state.ui.entries.style.maxHeight = "min(36vh, 280px)";
242
- return;
243
- }
244
- const nextSize = clampPanelSize(
245
- state.panelSize
246
- );
247
- state.panelSize = nextSize;
248
- state.ui.root.style.width = nextSize.width + "px";
249
- state.ui.panel.style.width = "100%";
250
- state.ui.panel.style.height = nextSize.height + "px";
251
- state.ui.entries.style.maxHeight = Math.max(72, nextSize.height - 88) + "px";
252
- }
253
- function clampPosition(point, state) {
254
- const viewport = getViewportSize();
255
- const size = getOverlaySize(state);
256
- const maxX = Math.max(OVERLAY_MARGIN, viewport.width - size.width - OVERLAY_MARGIN);
257
- const maxY = Math.max(
258
- OVERLAY_MARGIN,
259
- viewport.height - size.height - OVERLAY_MARGIN
260
- );
261
- return {
262
- x: Math.min(maxX, Math.max(OVERLAY_MARGIN, point.x)),
263
- y: Math.min(maxY, Math.max(OVERLAY_MARGIN, point.y))
264
- };
265
- }
266
- function applyOverlayPosition(state) {
267
- if (!state.ui) {
268
- return;
269
- }
270
- if (!state.position) {
271
- const viewport = getViewportSize();
272
- const size = getOverlaySize(state);
273
- state.position = clampPosition(
274
- {
275
- x: viewport.width - size.width - OVERLAY_MARGIN,
276
- y: viewport.height - size.height - OVERLAY_MARGIN
277
- },
278
- state
279
- );
280
- } else {
281
- state.position = clampPosition(state.position, state);
282
- }
283
- state.ui.root.style.left = state.position.x + "px";
284
- state.ui.root.style.top = state.position.y + "px";
285
- }
286
- function getPointFromMouseEvent(event) {
287
- return { x: event.clientX, y: event.clientY };
288
- }
289
- function getPointFromTouchEvent(event) {
290
- const touch = event.touches[0] ?? event.changedTouches[0];
291
- if (!touch) {
292
- return null;
293
- }
294
- return { x: touch.clientX, y: touch.clientY };
295
- }
296
- function stopDragging(state) {
297
- if (state.isDragging || state.isResizing) {
298
- state.suppressToggleClickUntil = Date.now() + 180;
299
- }
300
- state.isDragging = false;
301
- state.dragStartPoint = null;
302
- state.lastDragPoint = null;
303
- state.removeDragListeners?.();
304
- state.removeDragListeners = null;
305
- if (state.ui) {
306
- state.ui.panel.style.cursor = "default";
307
- state.ui.dragZone.style.cursor = "grab";
308
- state.ui.toggleButton.style.cursor = "grab";
309
- }
310
- }
311
- function stopResizing(state) {
312
- if (state.isResizing) {
313
- state.suppressToggleClickUntil = Date.now() + 180;
314
- }
315
- state.isResizing = false;
316
- state.resizeStartPoint = null;
317
- state.resizeStartSize = null;
318
- state.removeResizeListeners?.();
319
- state.removeResizeListeners = null;
320
- }
321
- function beginDragTracking(state, startPoint) {
322
- const doc = getDocument();
323
- if (!doc) {
324
- return;
325
- }
326
- stopResizing(state);
327
- stopDragging(state);
328
- state.dragMoved = false;
329
- state.dragStartPoint = startPoint;
330
- state.lastDragPoint = startPoint;
331
- const handlePointerMove = (nextPoint) => {
332
- if (!state.dragStartPoint || !state.lastDragPoint || !nextPoint) {
333
- return;
334
- }
335
- if (!state.isDragging) {
336
- const deltaFromStartX = nextPoint.x - state.dragStartPoint.x;
337
- const deltaFromStartY = nextPoint.y - state.dragStartPoint.y;
338
- const distance = Math.sqrt(
339
- deltaFromStartX * deltaFromStartX + deltaFromStartY * deltaFromStartY
340
- );
341
- if (distance < DRAG_THRESHOLD_PX) {
342
- return;
343
- }
344
- state.isDragging = true;
345
- state.dragMoved = true;
346
- if (state.ui) {
347
- state.ui.panel.style.cursor = "grabbing";
348
- state.ui.dragZone.style.cursor = "grabbing";
349
- state.ui.toggleButton.style.cursor = "grabbing";
350
- }
351
- }
352
- const currentPosition = state.position ?? { x: OVERLAY_MARGIN, y: OVERLAY_MARGIN };
353
- state.position = clampPosition(
354
- {
355
- x: currentPosition.x + (nextPoint.x - state.lastDragPoint.x),
356
- y: currentPosition.y + (nextPoint.y - state.lastDragPoint.y)
357
- },
358
- state
359
- );
360
- state.lastDragPoint = nextPoint;
361
- applyOverlayPosition(state);
362
- };
363
- const handleMouseMove = (event) => {
364
- handlePointerMove(getPointFromMouseEvent(event));
365
- };
366
- const handleTouchMove = (event) => {
367
- handlePointerMove(getPointFromTouchEvent(event));
368
- };
369
- const handleMouseUp = () => {
370
- stopDragging(state);
371
- };
372
- const handleTouchEnd = () => {
373
- stopDragging(state);
374
- };
375
- doc.addEventListener("mousemove", handleMouseMove);
376
- doc.addEventListener("mouseup", handleMouseUp);
377
- doc.addEventListener("touchmove", handleTouchMove, { passive: true });
378
- doc.addEventListener("touchend", handleTouchEnd);
379
- doc.addEventListener("touchcancel", handleTouchEnd);
380
- state.removeDragListeners = () => {
381
- doc.removeEventListener("mousemove", handleMouseMove);
382
- doc.removeEventListener("mouseup", handleMouseUp);
383
- doc.removeEventListener("touchmove", handleTouchMove);
384
- doc.removeEventListener("touchend", handleTouchEnd);
385
- doc.removeEventListener("touchcancel", handleTouchEnd);
386
- };
387
- }
388
- function startResizing(state, startPoint) {
389
- const doc = getDocument();
390
- if (!doc) {
391
- return;
392
- }
393
- stopDragging(state);
394
- stopResizing(state);
395
- state.isResizing = true;
396
- state.resizeStartPoint = startPoint;
397
- state.resizeStartSize = state.panelSize ?? clampPanelSize({ width: DEFAULT_EXPANDED_WIDTH, height: DEFAULT_EXPANDED_HEIGHT });
398
- const handleResizeMove = (nextPoint) => {
399
- if (!state.isResizing || !state.resizeStartPoint || !state.resizeStartSize || !nextPoint) {
400
- return;
401
- }
402
- state.panelSize = clampPanelSize({
403
- width: state.resizeStartSize.width + (nextPoint.x - state.resizeStartPoint.x),
404
- height: state.resizeStartSize.height + (nextPoint.y - state.resizeStartPoint.y)
405
- });
406
- applyPanelSize(state);
407
- applyOverlayPosition(state);
408
- };
409
- const handleMouseMove = (event) => {
410
- handleResizeMove(getPointFromMouseEvent(event));
411
- };
412
- const handleTouchMove = (event) => {
413
- handleResizeMove(getPointFromTouchEvent(event));
414
- };
415
- const handleFinish = () => {
416
- stopResizing(state);
417
- };
418
- doc.addEventListener("mousemove", handleMouseMove);
419
- doc.addEventListener("mouseup", handleFinish);
420
- doc.addEventListener("touchmove", handleTouchMove, { passive: true });
421
- doc.addEventListener("touchend", handleFinish);
422
- doc.addEventListener("touchcancel", handleFinish);
423
- state.removeResizeListeners = () => {
424
- doc.removeEventListener("mousemove", handleMouseMove);
425
- doc.removeEventListener("mouseup", handleFinish);
426
- doc.removeEventListener("touchmove", handleTouchMove);
427
- doc.removeEventListener("touchend", handleFinish);
428
- doc.removeEventListener("touchcancel", handleFinish);
429
- };
430
- }
431
- function isInBottomRightResizeZone(element, point) {
432
- const rect = element.getBoundingClientRect();
433
- return point.x >= rect.right - RESIZE_HOTSPOT_PX && point.x <= rect.right && point.y >= rect.bottom - RESIZE_HOTSPOT_PX && point.y <= rect.bottom;
434
- }
435
- function canStartDragFromTarget(target) {
436
- if (!(target instanceof Element)) {
437
- return true;
438
- }
439
- if (target.closest("button") || target.closest("a") || target.closest("input") || target.closest("textarea") || target.closest("select")) {
440
- return false;
441
- }
442
- return true;
443
- }
444
- function isInTopDragZone(element, point, zoneHeight) {
445
- const rect = element.getBoundingClientRect();
446
- return point.x >= rect.left && point.x <= rect.right && point.y >= rect.top && point.y <= rect.top + zoneHeight;
447
- }
448
- function attachDragStartListeners(element, state, options = {}) {
449
- element.addEventListener("mousedown", (event) => {
450
- if (!options.allowInteractiveTarget && !canStartDragFromTarget(event.target)) {
451
- return;
452
- }
453
- const point = getPointFromMouseEvent(event);
454
- if (typeof options.topZoneHeight === "number" && !isInTopDragZone(element, point, options.topZoneHeight)) {
455
- return;
456
- }
457
- beginDragTracking(state, point);
458
- });
459
- element.addEventListener("touchstart", (event) => {
460
- if (!options.allowInteractiveTarget && !canStartDragFromTarget(event.target)) {
461
- return;
462
- }
463
- const point = getPointFromTouchEvent(event);
464
- if (!point) {
465
- return;
466
- }
467
- if (typeof options.topZoneHeight === "number" && !isInTopDragZone(element, point, options.topZoneHeight)) {
468
- return;
469
- }
470
- beginDragTracking(state, point);
471
- });
472
- }
473
- function attachCollapsedToggleListeners(element, state) {
474
- const startToggleInteraction = (startPoint) => {
475
- const doc = getDocument();
476
- if (!doc) {
477
- return;
478
- }
479
- beginDragTracking(state, startPoint);
480
- const finishInteraction = () => {
481
- releaseListeners();
482
- if (state.dragMoved || Date.now() < state.suppressToggleClickUntil) {
483
- return;
484
- }
485
- state.expanded = true;
486
- state.unreadCount = 0;
487
- renderOverlay(state);
488
- };
489
- const releaseListeners = () => {
490
- doc.removeEventListener("mouseup", finishInteraction);
491
- doc.removeEventListener("touchend", finishInteraction);
492
- doc.removeEventListener("touchcancel", finishInteraction);
493
- };
494
- doc.addEventListener("mouseup", finishInteraction);
495
- doc.addEventListener("touchend", finishInteraction);
496
- doc.addEventListener("touchcancel", finishInteraction);
497
- };
498
- element.addEventListener("mousedown", (event) => {
499
- event.preventDefault();
500
- startToggleInteraction(getPointFromMouseEvent(event));
501
- });
502
- element.addEventListener("touchstart", (event) => {
503
- const point = getPointFromTouchEvent(event);
504
- if (!point) {
505
- return;
506
- }
507
- event.preventDefault();
508
- startToggleInteraction(point);
509
- });
510
- }
511
- function attachPanelResizeListeners(element, state) {
512
- element.addEventListener("mousedown", (event) => {
513
- if (!state.expanded || !canStartDragFromTarget(event.target)) {
514
- return;
515
- }
516
- const point = getPointFromMouseEvent(event);
517
- if (!isInBottomRightResizeZone(element, point)) {
518
- return;
519
- }
520
- event.preventDefault();
521
- event.stopPropagation();
522
- startResizing(state, point);
523
- });
524
- element.addEventListener("touchstart", (event) => {
525
- if (!state.expanded || !canStartDragFromTarget(event.target)) {
526
- return;
527
- }
528
- const point = getPointFromTouchEvent(event);
529
- if (!point || !isInBottomRightResizeZone(element, point)) {
530
- return;
531
- }
532
- event.preventDefault();
533
- event.stopPropagation();
534
- startResizing(state, point);
535
- });
536
- }
537
- function createOverlayUi(state) {
538
- const root = document.createElement("div");
539
- root.style.cssText = [
540
- "position:fixed",
541
- "left:12px",
542
- "top:12px",
543
- "z-index:2147483647",
544
- "display:flex",
545
- "flex-direction:column",
546
- "align-items:stretch",
547
- "gap:8px",
548
- "width:min(565px, calc(100vw - 24px))",
549
- "pointer-events:none"
550
- ].join(";");
551
- const toggleButton = createButton("Logs");
552
- toggleButton.style.pointerEvents = "auto";
553
- toggleButton.style.alignSelf = "flex-end";
554
- toggleButton.style.display = "inline-flex";
555
- toggleButton.style.alignItems = "center";
556
- toggleButton.style.justifyContent = "center";
557
- toggleButton.style.minHeight = "40px";
558
- toggleButton.style.minWidth = "76px";
559
- toggleButton.style.padding = "8px 14px";
560
- toggleButton.style.textAlign = "center";
561
- toggleButton.style.border = "1px solid rgba(122, 212, 255, 0.22)";
562
- toggleButton.style.background = "linear-gradient(180deg, rgba(13,31,54,0.98), rgba(8,19,37,0.98))";
563
- toggleButton.style.boxShadow = "0 18px 40px rgba(4,12,24,0.34)";
564
- toggleButton.style.cursor = "grab";
565
- toggleButton.style.touchAction = "none";
566
- const panel = document.createElement("div");
567
- panel.style.cssText = [
568
- "position:relative",
569
- "display:flex",
570
- "flex-direction:column",
571
- "width:min(565px, calc(100vw - 24px))",
572
- "max-height:min(48vh, 372px)",
573
- "border-radius:18px",
574
- "border:1px solid rgba(116,167,255,0.16)",
575
- "background:linear-gradient(180deg, rgba(9,19,37,0.98), rgba(5,12,24,0.98))",
576
- "box-shadow:0 28px 64px rgba(2,8,18,0.46)",
577
- "backdrop-filter:blur(16px)",
578
- "overflow:hidden",
579
- "cursor:default",
580
- "pointer-events:auto"
581
- ].join(";");
582
- const dragZone = document.createElement("div");
583
- dragZone.style.cssText = [
584
- "position:absolute",
585
- "top:0",
586
- "left:0",
587
- "right:0",
588
- "height:" + String(TOP_DRAG_ZONE_PX) + "px",
589
- "z-index:1",
590
- "cursor:grab",
591
- "background:transparent",
592
- "pointer-events:auto"
593
- ].join(";");
594
- const controls = document.createElement("div");
595
- controls.style.cssText = [
596
- "position:absolute",
597
- "top:22px",
598
- "right:22px",
599
- "z-index:2",
600
- "display:flex",
601
- "align-items:center",
602
- "gap:8px",
603
- "pointer-events:auto"
604
- ].join(";");
605
- const clearButton = createButton("Clear");
606
- clearButton.style.background = "rgba(255,255,255,0.1)";
607
- clearButton.style.border = "1px solid rgba(255,255,255,0.16)";
608
- clearButton.style.color = "#eef6ff";
609
- clearButton.style.minHeight = "30px";
610
- clearButton.style.padding = "4px 9px";
611
- clearButton.style.fontSize = "11px";
612
- clearButton.style.backdropFilter = "blur(8px)";
613
- const collapseButton = createButton("Hide");
614
- collapseButton.style.background = "rgba(113, 171, 255, 0.12)";
615
- collapseButton.style.border = "1px solid rgba(113, 171, 255, 0.2)";
616
- collapseButton.style.color = "#d9ebff";
617
- collapseButton.style.minHeight = "30px";
618
- collapseButton.style.padding = "4px 9px";
619
- collapseButton.style.fontSize = "11px";
620
- collapseButton.style.backdropFilter = "blur(8px)";
621
- const body = document.createElement("div");
622
- body.style.cssText = [
623
- "position:relative",
624
- "display:flex",
625
- "flex-direction:column",
626
- "padding:12px",
627
- "background:linear-gradient(180deg, rgba(4,10,20,0.88), rgba(3,8,18,0.98))",
628
- "flex:1 1 auto",
629
- "min-height:0"
630
- ].join(";");
631
- const entries = document.createElement("div");
632
- entries.style.cssText = [
633
- "display:flex",
634
- "flex-direction:column",
635
- "gap:0",
636
- "overflow:auto",
637
- "flex:1 1 auto",
638
- "min-height:96px",
639
- "max-height:min(36vh, 280px)",
640
- "padding:0",
641
- "border:1px solid rgba(115,153,212,0.14)",
642
- "border-radius:12px",
643
- "background:rgba(4,10,20,0.82)"
644
- ].join(";");
645
- const emptyState = document.createElement("div");
646
- emptyState.style.cssText = [
647
- "display:flex",
648
- "align-items:center",
649
- "justify-content:center",
650
- "flex:1 1 auto",
651
- "min-height:96px",
652
- "color:rgba(204,222,250,0.6)",
653
- "font:500 12px/1.5 ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace",
654
- "text-align:center",
655
- "padding:18px"
656
- ].join(";");
657
- emptyState.textContent = "Console output will appear here.";
658
- collapseButton.addEventListener("click", (event) => {
659
- event.stopPropagation();
660
- state.expanded = false;
661
- renderOverlay(state);
662
- });
663
- clearButton.addEventListener("click", (event) => {
664
- event.stopPropagation();
665
- state.entries = [];
666
- state.unreadCount = 0;
667
- renderOverlay(state);
668
- });
669
- controls.appendChild(clearButton);
670
- controls.appendChild(collapseButton);
671
- entries.appendChild(emptyState);
672
- body.appendChild(entries);
673
- body.appendChild(controls);
674
- panel.appendChild(dragZone);
675
- panel.appendChild(body);
676
- attachDragStartListeners(dragZone, state);
677
- attachPanelResizeListeners(panel, state);
678
- attachCollapsedToggleListeners(toggleButton, state);
679
- root.appendChild(panel);
680
- root.appendChild(toggleButton);
681
- return {
682
- body,
683
- clearButton,
684
- collapseButton,
685
- controls,
686
- dragZone,
687
- emptyState,
688
- entries,
689
- panel,
690
- root,
691
- toggleButton
692
- };
693
- }
694
- function renderOverlay(state) {
695
- if (!state.ui) {
696
- return;
697
- }
698
- state.ui.panel.style.display = state.expanded ? "flex" : "none";
699
- state.ui.toggleButton.style.display = state.expanded ? "none" : "inline-flex";
700
- state.ui.toggleButton.textContent = "Logs";
701
- if (state.entries.length === 0) {
702
- state.ui.entries.style.display = "flex";
703
- state.ui.emptyState.style.display = "flex";
704
- state.ui.entries.replaceChildren(state.ui.emptyState);
705
- applyPanelSize(state);
706
- applyOverlayPosition(state);
707
- return;
708
- }
709
- state.ui.entries.style.display = "flex";
710
- state.ui.emptyState.style.display = "none";
711
- const nextChildren = state.entries.map((entry) => {
712
- const accent = getLevelAccent(entry.level);
713
- const row = document.createElement("div");
714
- row.style.cssText = [
715
- "display:flex",
716
- "align-items:flex-start",
717
- "gap:0",
718
- "padding:4px 12px",
719
- "background:" + accent.lineBackground
720
- ].join(";");
721
- const line = document.createElement("div");
722
- line.textContent = formatTimestamp(entry.timestamp) + " " + entry.level.toUpperCase() + " " + entry.message;
723
- line.style.cssText = [
724
- "color:#ecf4ff",
725
- "font:500 12px/1.5 ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace",
726
- "white-space:pre-wrap",
727
- "word-break:break-word",
728
- "flex:1 1 auto"
729
- ].join(";");
730
- row.appendChild(line);
731
- return row;
732
- });
733
- state.ui.entries.replaceChildren(...nextChildren);
734
- state.ui.entries.scrollTop = state.ui.entries.scrollHeight;
735
- applyPanelSize(state);
736
- applyOverlayPosition(state);
737
- }
738
- function mountOverlay(state) {
739
- const doc = getDocument();
740
- if (!doc?.body || state.ui) {
741
- return;
742
- }
743
- state.ui = createOverlayUi(state);
744
- doc.body.appendChild(state.ui.root);
745
- applyPanelSize(state);
746
- applyOverlayPosition(state);
747
- renderOverlay(state);
748
- }
749
- function enqueueEntry(state, level, args) {
750
- state.entries.push(createEntry(level, args, state.nextEntryId));
751
- state.nextEntryId += 1;
752
- if (state.entries.length > state.maxEntries) {
753
- state.entries.splice(0, state.entries.length - state.maxEntries);
754
- }
755
- if (!state.expanded) {
756
- state.unreadCount += 1;
757
- }
758
- renderOverlay(state);
759
- }
760
- function restoreConsole(snapshot) {
761
- for (const method of CONSOLE_METHODS) {
762
- console[method] = snapshot[method];
763
- }
764
- }
765
- function patchConsole(state) {
766
- for (const method of CONSOLE_METHODS) {
767
- const original = state.originalConsole[method];
768
- console[method] = (...args) => {
769
- enqueueEntry(state, method, args);
770
- original(...args);
771
- };
772
- }
773
- }
774
- function cleanupOverlay(browserWindow, state) {
775
- restoreConsole(state.originalConsole);
776
- stopResizing(state);
777
- stopDragging(state);
778
- if (state.domReadyHandler) {
779
- getDocument()?.removeEventListener("DOMContentLoaded", state.domReadyHandler);
780
- state.domReadyHandler = void 0;
781
- }
782
- if (state.resizeHandler && typeof browserWindow.removeEventListener === "function") {
783
- browserWindow.removeEventListener("resize", state.resizeHandler);
784
- state.resizeHandler = void 0;
785
- }
786
- state.ui?.root.remove();
787
- state.ui = null;
788
- delete browserWindow.__oasizLogOverlayController__;
789
- delete browserWindow.__oasizLogOverlayState__;
790
- }
791
- function createController(browserWindow, state) {
792
- return {
793
- retain() {
794
- state.refCount += 1;
795
- this.ensureMounted();
796
- },
797
- ensureMounted() {
798
- const doc = getDocument();
799
- if (!doc) {
800
- return;
801
- }
802
- if (doc.body) {
803
- mountOverlay(state);
804
- applyOverlayPosition(state);
805
- return;
806
- }
807
- if (!state.domReadyHandler) {
808
- state.domReadyHandler = () => {
809
- mountOverlay(state);
810
- state.domReadyHandler = void 0;
811
- };
812
- doc.addEventListener("DOMContentLoaded", state.domReadyHandler, {
813
- once: true
814
- });
815
- }
816
- },
817
- clear() {
818
- state.entries = [];
819
- state.unreadCount = 0;
820
- renderOverlay(state);
821
- },
822
- show() {
823
- state.expanded = true;
824
- state.unreadCount = 0;
825
- renderOverlay(state);
826
- },
827
- hide() {
828
- state.expanded = false;
829
- renderOverlay(state);
830
- },
831
- isVisible() {
832
- return state.expanded;
833
- },
834
- destroy() {
835
- state.refCount = Math.max(0, state.refCount - 1);
836
- if (state.refCount === 0) {
837
- cleanupOverlay(browserWindow, state);
838
- }
839
- }
840
- };
841
- }
842
- function enableLogOverlay(options = {}) {
843
- if (options.enabled === false) {
844
- return NOOP_HANDLE;
845
- }
846
- const browserWindow = getBrowserWindow();
847
- const doc = getDocument();
848
- if (!browserWindow || !doc) {
849
- return NOOP_HANDLE;
850
- }
851
- const existingController = browserWindow.__oasizLogOverlayController__;
852
- const existingState = browserWindow.__oasizLogOverlayState__;
853
- if (existingController && existingState) {
854
- existingController.retain();
855
- if (typeof options.maxEntries === "number") {
856
- existingState.maxEntries = clampMaxEntries(options.maxEntries);
857
- if (existingState.entries.length > existingState.maxEntries) {
858
- existingState.entries.splice(
859
- 0,
860
- existingState.entries.length - existingState.maxEntries
861
- );
862
- }
863
- }
864
- if (typeof options.collapsed === "boolean") {
865
- existingState.expanded = !options.collapsed;
866
- applyPanelSize(existingState);
867
- if (existingState.expanded) {
868
- existingState.unreadCount = 0;
869
- }
870
- }
871
- if (typeof options.title === "string" && options.title.trim().length > 0) {
872
- existingState.title = options.title.trim();
873
- }
874
- existingController.ensureMounted();
875
- renderOverlay(existingState);
876
- return existingController;
877
- }
878
- const state = {
879
- dragMoved: false,
880
- dragStartPoint: null,
881
- entries: [],
882
- expanded: options.collapsed !== true,
883
- isDragging: false,
884
- isResizing: false,
885
- lastDragPoint: null,
886
- maxEntries: clampMaxEntries(options.maxEntries),
887
- nextEntryId: 1,
888
- originalConsole: createConsoleSnapshot(),
889
- panelSize: null,
890
- position: null,
891
- refCount: 1,
892
- removeDragListeners: null,
893
- removeResizeListeners: null,
894
- resizeStartPoint: null,
895
- resizeStartSize: null,
896
- suppressToggleClickUntil: 0,
897
- title: typeof options.title === "string" && options.title.trim().length > 0 ? options.title.trim() : DEFAULT_TITLE,
898
- resizeHandler: void 0,
899
- ui: null,
900
- unreadCount: 0
901
- };
902
- const controller = createController(browserWindow, state);
903
- browserWindow.__oasizLogOverlayState__ = state;
904
- browserWindow.__oasizLogOverlayController__ = controller;
905
- patchConsole(state);
906
- if (typeof browserWindow.addEventListener === "function") {
907
- state.resizeHandler = () => {
908
- applyOverlayPosition(state);
909
- };
910
- browserWindow.addEventListener("resize", state.resizeHandler);
911
- }
912
- controller.ensureMounted();
913
- return controller;
914
- }
915
-
916
25
  // src/multiplayer.ts
917
26
  function isDevelopment2() {
918
27
  const nodeEnv = globalThis.process?.env?.NODE_ENV;
@@ -924,10 +33,10 @@ function getBridgeWindow2() {
924
33
  }
925
34
  return window;
926
35
  }
927
- function shareRoomCode(roomCode, options) {
36
+ function shareRoomCode(roomCode) {
928
37
  const bridge = getBridgeWindow2();
929
38
  if (typeof bridge?.shareRoomCode === "function") {
930
- bridge.shareRoomCode(roomCode, options);
39
+ bridge.shareRoomCode(roomCode);
931
40
  return;
932
41
  }
933
42
  if (isDevelopment2()) {
@@ -936,18 +45,6 @@ function shareRoomCode(roomCode, options) {
936
45
  );
937
46
  }
938
47
  }
939
- function openInviteModal() {
940
- const bridge = getBridgeWindow2();
941
- if (typeof bridge?.openInviteModal === "function") {
942
- bridge.openInviteModal();
943
- return;
944
- }
945
- if (isDevelopment2()) {
946
- console.warn(
947
- "[oasiz/sdk] openInviteModal bridge is unavailable. This is expected in local development."
948
- );
949
- }
950
- }
951
48
  function getGameId() {
952
49
  const bridge = getBridgeWindow2();
953
50
  return bridge?.__GAME_ID__;
@@ -1007,7 +104,7 @@ function emitScoreConfig(config) {
1007
104
  warnMissingBridge("emitScoreConfig");
1008
105
  }
1009
106
 
1010
- // src/state.ts
107
+ // src/share.ts
1011
108
  function isDevelopment4() {
1012
109
  const nodeEnv = globalThis.process?.env?.NODE_ENV;
1013
110
  return nodeEnv !== "production";
@@ -1018,6 +115,69 @@ function getBridgeWindow4() {
1018
115
  }
1019
116
  return window;
1020
117
  }
118
+ function warnMissingBridge2(methodName) {
119
+ if (isDevelopment4()) {
120
+ console.warn(
121
+ "[oasiz/sdk] " + methodName + " share bridge is unavailable. This is expected in local development."
122
+ );
123
+ }
124
+ }
125
+ function isValidImageReference(image) {
126
+ if (/^data:image\/[a-zA-Z0-9.+-]+;base64,/.test(image)) {
127
+ return true;
128
+ }
129
+ try {
130
+ const parsed = new URL(image);
131
+ return parsed.protocol === "http:" || parsed.protocol === "https:";
132
+ } catch {
133
+ return false;
134
+ }
135
+ }
136
+ function validateRequest(options) {
137
+ const text = typeof options.text === "string" ? options.text.trim() : "";
138
+ const hasText = text.length > 0;
139
+ const hasScore = options.score !== void 0;
140
+ const hasImage = typeof options.image === "string" && options.image.length > 0;
141
+ if (!hasText && !hasScore && !hasImage) {
142
+ throw new Error("Share request requires text, score, or image.");
143
+ }
144
+ if (hasScore) {
145
+ if (typeof options.score !== "number" || !Number.isInteger(options.score) || options.score < 0) {
146
+ throw new Error("Share score must be a non-negative integer.");
147
+ }
148
+ }
149
+ if (hasImage && !isValidImageReference(options.image)) {
150
+ throw new Error(
151
+ "Share image must be an http(s) URL or a data:image/... base64 string."
152
+ );
153
+ }
154
+ return {
155
+ ...hasText ? { text } : {},
156
+ ...hasScore ? { score: options.score } : {},
157
+ ...hasImage ? { image: options.image } : {}
158
+ };
159
+ }
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");
166
+ }
167
+ await bridge.__oasizShareRequest(request);
168
+ }
169
+
170
+ // src/state.ts
171
+ function isDevelopment5() {
172
+ const nodeEnv = globalThis.process?.env?.NODE_ENV;
173
+ return nodeEnv !== "production";
174
+ }
175
+ function getBridgeWindow5() {
176
+ if (typeof window === "undefined") {
177
+ return void 0;
178
+ }
179
+ return window;
180
+ }
1021
181
  function isPlainObject(value) {
1022
182
  if (!value || typeof value !== "object" || Array.isArray(value)) {
1023
183
  return false;
@@ -1025,22 +185,22 @@ function isPlainObject(value) {
1025
185
  const proto = Object.getPrototypeOf(value);
1026
186
  return proto === Object.prototype || proto === null;
1027
187
  }
1028
- function warnMissingBridge2(methodName) {
1029
- if (isDevelopment4()) {
188
+ function warnMissingBridge3(methodName) {
189
+ if (isDevelopment5()) {
1030
190
  console.warn(
1031
191
  "[oasiz/sdk] " + methodName + " bridge is unavailable. This is expected in local development."
1032
192
  );
1033
193
  }
1034
194
  }
1035
195
  function loadGameState() {
1036
- const bridge = getBridgeWindow4();
196
+ const bridge = getBridgeWindow5();
1037
197
  if (typeof bridge?.loadGameState !== "function") {
1038
- warnMissingBridge2("loadGameState");
198
+ warnMissingBridge3("loadGameState");
1039
199
  return {};
1040
200
  }
1041
201
  const state = bridge.loadGameState();
1042
202
  if (!isPlainObject(state)) {
1043
- if (isDevelopment4()) {
203
+ if (isDevelopment5()) {
1044
204
  console.warn(
1045
205
  "[oasiz/sdk] loadGameState returned invalid data. Falling back to empty object."
1046
206
  );
@@ -1051,35 +211,35 @@ function loadGameState() {
1051
211
  }
1052
212
  function saveGameState(state) {
1053
213
  if (!isPlainObject(state)) {
1054
- if (isDevelopment4()) {
214
+ if (isDevelopment5()) {
1055
215
  console.warn("[oasiz/sdk] saveGameState expected a plain object:", state);
1056
216
  }
1057
217
  return;
1058
218
  }
1059
- const bridge = getBridgeWindow4();
219
+ const bridge = getBridgeWindow5();
1060
220
  if (typeof bridge?.saveGameState === "function") {
1061
221
  bridge.saveGameState(state);
1062
222
  return;
1063
223
  }
1064
- warnMissingBridge2("saveGameState");
224
+ warnMissingBridge3("saveGameState");
1065
225
  }
1066
226
  function flushGameState() {
1067
- const bridge = getBridgeWindow4();
227
+ const bridge = getBridgeWindow5();
1068
228
  if (typeof bridge?.flushGameState === "function") {
1069
229
  bridge.flushGameState();
1070
230
  return;
1071
231
  }
1072
- warnMissingBridge2("flushGameState");
232
+ warnMissingBridge3("flushGameState");
1073
233
  }
1074
234
 
1075
235
  // src/lifecycle.ts
1076
- function isDevelopment5() {
236
+ function isDevelopment6() {
1077
237
  const nodeEnv = globalThis.process?.env?.NODE_ENV;
1078
238
  return nodeEnv !== "production";
1079
239
  }
1080
240
  function addLifecycleListener(eventName, callback) {
1081
241
  if (typeof window === "undefined") {
1082
- if (isDevelopment5()) {
242
+ if (isDevelopment6()) {
1083
243
  console.warn(
1084
244
  "[oasiz/sdk] " + eventName + " listener registered without a browser window. This is expected in local development."
1085
245
  );
@@ -1100,26 +260,34 @@ function onResume(callback) {
1100
260
 
1101
261
  // src/navigation.ts
1102
262
  var activeBackListeners = 0;
1103
- function isDevelopment6() {
263
+ function isDevelopment7() {
1104
264
  const nodeEnv = globalThis.process?.env?.NODE_ENV;
1105
265
  return nodeEnv !== "production";
1106
266
  }
1107
- function getBridgeWindow5() {
267
+ function getBridgeWindow6() {
1108
268
  if (typeof window === "undefined") {
1109
269
  return void 0;
1110
270
  }
1111
271
  return window;
1112
272
  }
1113
- function warnMissingBridge3(methodName) {
1114
- if (isDevelopment6()) {
273
+ function warnMissingBridge4(methodName) {
274
+ if (isDevelopment7()) {
1115
275
  console.warn(
1116
276
  "[oasiz/sdk] " + methodName + " bridge is unavailable. This is expected in local development."
1117
277
  );
1118
278
  }
1119
279
  }
280
+ function normalizeNavigationError(error) {
281
+ if (error instanceof Error) {
282
+ return error;
283
+ }
284
+ return new Error(
285
+ typeof error === "string" ? error : "Back button callback failed."
286
+ );
287
+ }
1120
288
  function addNavigationListener(eventName, callback) {
1121
289
  if (typeof window === "undefined") {
1122
- if (isDevelopment6()) {
290
+ if (isDevelopment7()) {
1123
291
  console.warn(
1124
292
  "[oasiz/sdk] " + eventName + " listener registered without a browser window. This is expected in local development."
1125
293
  );
@@ -1132,25 +300,32 @@ function addNavigationListener(eventName, callback) {
1132
300
  return () => window.removeEventListener(eventName, handler);
1133
301
  }
1134
302
  function onBackButton(callback) {
1135
- const off = addNavigationListener("oasiz:back", callback);
1136
- const bridge = getBridgeWindow5();
303
+ const off = addNavigationListener("oasiz:back", () => {
304
+ try {
305
+ callback();
306
+ } catch (error) {
307
+ leaveGame();
308
+ throw normalizeNavigationError(error);
309
+ }
310
+ });
311
+ const bridge = getBridgeWindow6();
1137
312
  activeBackListeners += 1;
1138
313
  if (activeBackListeners === 1) {
1139
314
  if (typeof bridge?.__oasizSetBackOverride === "function") {
1140
315
  bridge.__oasizSetBackOverride(true);
1141
316
  } else {
1142
- warnMissingBridge3("__oasizSetBackOverride");
317
+ warnMissingBridge4("__oasizSetBackOverride");
1143
318
  }
1144
319
  }
1145
320
  return () => {
1146
321
  off();
1147
322
  activeBackListeners = Math.max(0, activeBackListeners - 1);
1148
323
  if (activeBackListeners === 0) {
1149
- const currentBridge = getBridgeWindow5();
324
+ const currentBridge = getBridgeWindow6();
1150
325
  if (typeof currentBridge?.__oasizSetBackOverride === "function") {
1151
326
  currentBridge.__oasizSetBackOverride(false);
1152
327
  } else {
1153
- warnMissingBridge3("__oasizSetBackOverride");
328
+ warnMissingBridge4("__oasizSetBackOverride");
1154
329
  }
1155
330
  }
1156
331
  };
@@ -1159,30 +334,136 @@ function onLeaveGame(callback) {
1159
334
  return addNavigationListener("oasiz:leave", callback);
1160
335
  }
1161
336
  function leaveGame() {
1162
- const bridge = getBridgeWindow5();
337
+ const bridge = getBridgeWindow6();
1163
338
  if (typeof bridge?.__oasizLeaveGame === "function") {
1164
339
  bridge.__oasizLeaveGame();
1165
340
  return;
1166
341
  }
1167
- warnMissingBridge3("__oasizLeaveGame");
342
+ warnMissingBridge4("__oasizLeaveGame");
343
+ }
344
+
345
+ // src/store.ts
346
+ function isDevelopment8() {
347
+ const nodeEnv = globalThis.process?.env?.NODE_ENV;
348
+ return nodeEnv !== "production";
349
+ }
350
+ function getBridgeWindow7() {
351
+ if (typeof window === "undefined") {
352
+ return void 0;
353
+ }
354
+ return window;
355
+ }
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
+ );
361
+ }
362
+ }
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");
368
+ }
369
+ return await bridge.__oasizStoreBridgeRequest({
370
+ action,
371
+ payload
372
+ });
373
+ }
374
+ async function getFreshState() {
375
+ return await requestStoreBridge("getStoreState");
376
+ }
377
+ function subscribeToStoreEvent(eventName, callback) {
378
+ if (typeof window === "undefined") {
379
+ return () => {
380
+ };
381
+ }
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);
389
+ };
390
+ }
391
+ async function syncProducts(products, expectedVersion) {
392
+ return await requestStoreBridge("syncProducts", {
393
+ expectedVersion: expectedVersion ?? null,
394
+ products
395
+ });
396
+ }
397
+ async function getProducts() {
398
+ const state = await getFreshState();
399
+ return state.products;
400
+ }
401
+ async function getEntitlements() {
402
+ const state = await getFreshState();
403
+ return state.entitlements;
404
+ }
405
+ async function hasEntitlement(productId) {
406
+ const state = await getFreshState();
407
+ return state.entitlements.find((item) => item.productId === productId)?.owned === true;
408
+ }
409
+ async function getQuantity(productId) {
410
+ const state = await getFreshState();
411
+ return state.entitlements.find((item) => item.productId === productId)?.quantity ?? 0;
412
+ }
413
+ async function purchase(productId, quantity = 1) {
414
+ return await requestStoreBridge("purchaseProduct", {
415
+ productId,
416
+ quantity
417
+ });
418
+ }
419
+ async function consume(productId, quantity = 1) {
420
+ return await requestStoreBridge("consumeProduct", {
421
+ productId,
422
+ quantity
423
+ });
424
+ }
425
+ async function getJemBalance() {
426
+ const state = await getFreshState();
427
+ return state.jemBalance;
428
+ }
429
+ function onEntitlementsChanged(callback) {
430
+ return subscribeToStoreEvent("oasiz:entitlements-changed", (state) => {
431
+ callback(state.entitlements);
432
+ });
433
+ }
434
+ function onJemBalanceChanged(callback) {
435
+ return subscribeToStoreEvent("oasiz:jem-balance-changed", (state) => {
436
+ callback(state.jemBalance);
437
+ });
1168
438
  }
1169
439
 
1170
440
  // src/index.ts
1171
441
  var oasiz = {
1172
442
  submitScore,
1173
443
  emitScoreConfig,
444
+ share,
1174
445
  triggerHaptic,
1175
- enableLogOverlay,
1176
446
  loadGameState,
1177
447
  saveGameState,
1178
448
  flushGameState,
1179
449
  shareRoomCode,
1180
- openInviteModal,
1181
450
  onPause,
1182
451
  onResume,
1183
452
  onBackButton,
1184
453
  onLeaveGame,
1185
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
+ },
1186
467
  get gameId() {
1187
468
  return getGameId();
1188
469
  },
@@ -1197,23 +478,32 @@ var oasiz = {
1197
478
  }
1198
479
  };
1199
480
  export {
481
+ consume,
1200
482
  emitScoreConfig,
1201
- enableLogOverlay,
1202
483
  flushGameState,
484
+ getEntitlements,
1203
485
  getGameId,
486
+ getJemBalance,
1204
487
  getPlayerAvatar,
1205
488
  getPlayerName,
489
+ getProducts,
490
+ getQuantity,
1206
491
  getRoomCode,
492
+ hasEntitlement,
1207
493
  leaveGame,
1208
494
  loadGameState,
1209
495
  oasiz,
1210
496
  onBackButton,
497
+ onEntitlementsChanged,
498
+ onJemBalanceChanged,
1211
499
  onLeaveGame,
1212
500
  onPause,
1213
501
  onResume,
1214
- openInviteModal,
502
+ purchase,
1215
503
  saveGameState,
504
+ share,
1216
505
  shareRoomCode,
1217
506
  submitScore,
507
+ syncProducts,
1218
508
  triggerHaptic
1219
509
  };