@kontextso/sdk-react-native 3.0.7-rc.1 → 3.0.7-rc.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -56,47 +56,10 @@ function handleIframeMessage(handler, opts) {
56
56
 
57
57
  // src/formats/Format.tsx
58
58
  var import_sdk_react = require("@kontextso/sdk-react");
59
- var import_react2 = require("react");
60
- var import_react_native = require("react-native");
61
-
62
- // src/frame-webview.tsx
63
59
  var import_react = require("react");
60
+ var import_react_native = require("react-native");
64
61
  var import_react_native_webview = require("react-native-webview");
65
62
  var import_jsx_runtime = require("react/jsx-runtime");
66
- var FrameWebView = (0, import_react.forwardRef)(
67
- ({ iframeUrl, onMessage, style, onError, onLoad }, forwardedRef) => {
68
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
69
- import_react_native_webview.WebView,
70
- {
71
- ref: forwardedRef,
72
- source: {
73
- uri: iframeUrl
74
- },
75
- onMessage,
76
- style,
77
- allowsInlineMediaPlayback: true,
78
- mediaPlaybackRequiresUserAction: false,
79
- javaScriptEnabled: true,
80
- domStorageEnabled: true,
81
- allowsFullscreenVideo: false,
82
- injectedJavaScript: `
83
- window.addEventListener("message", function(event) {
84
- if (window.ReactNativeWebView && event.data) {
85
- // ReactNativeWebView.postMessage only supports string data
86
- window.ReactNativeWebView.postMessage(JSON.stringify(event.data));
87
- }
88
- }, false);
89
- `,
90
- onError,
91
- onLoad
92
- }
93
- );
94
- }
95
- );
96
- var frame_webview_default = FrameWebView;
97
-
98
- // src/formats/Format.tsx
99
- var import_jsx_runtime2 = require("react/jsx-runtime");
100
63
  var sendMessage = (webViewRef, type, code, data) => {
101
64
  const message = makeIframeMessage(type, {
102
65
  data,
@@ -108,56 +71,24 @@ var sendMessage = (webViewRef, type, code, data) => {
108
71
  }));
109
72
  `);
110
73
  };
111
- var getCachedContent = (context, bidId) => {
112
- if (!bidId) {
74
+ var getUrl = (code, messageId, bidId) => {
75
+ const context = (0, import_react.useContext)(import_sdk_react.AdsContext);
76
+ if (!context || !bidId) {
113
77
  return null;
114
78
  }
115
- return context?.cachedContentRef?.current?.get(bidId) ?? null;
79
+ const adServerUrl = context?.adServerUrl;
80
+ const params = new URLSearchParams({
81
+ code,
82
+ messageId,
83
+ sdk: "sdk-react-native"
84
+ });
85
+ return `${adServerUrl}/api/frame/${bidId}?${params}`;
116
86
  };
117
87
  var Format = ({ code, messageId, wrapper, onEvent, ...otherParams }) => {
118
- const context = (0, import_react2.useContext)(import_sdk_react.AdsContext);
88
+ const context = (0, import_react.useContext)(import_sdk_react.AdsContext);
119
89
  const bid = (0, import_sdk_react.useBid)({ code, messageId });
120
- const [height, setHeight] = (0, import_react2.useState)(0);
121
- const cachedContent = getCachedContent(context, bid?.bidId);
122
- const iframeUrl = (0, import_sdk_react.useIframeUrl)(bid, code, messageId, "sdk-react-native", otherParams.theme, cachedContent);
123
- const modalUrl = iframeUrl.replace("/api/frame/", "/api/modal/");
124
- const [showIframe, setShowIframe] = (0, import_react2.useState)(false);
125
- const [iframeLoaded, setIframeLoaded] = (0, import_react2.useState)(false);
126
- const [modalOpen, setModalOpen] = (0, import_react2.useState)(false);
127
- const [modalShown, setModalShown] = (0, import_react2.useState)(false);
128
- const [modalLoaded, setModalLoaded] = (0, import_react2.useState)(false);
129
- const [containerStyles, setContainerStyles] = (0, import_react2.useState)({});
130
- const [iframeStyles, setIframeStyles] = (0, import_react2.useState)({});
131
- const containerRef = (0, import_react2.useRef)(null);
132
- const webViewRef = (0, import_react2.useRef)(null);
133
- const modalWebViewRef = (0, import_react2.useRef)(null);
134
- const modalInitTimeoutRef = (0, import_react2.useRef)(null);
135
- const isModalInitRef = (0, import_react2.useRef)(false);
136
- const { height: windowHeight, width: windowWidth } = (0, import_react_native.useWindowDimensions)();
137
- const keyboardHeightRef = (0, import_react2.useRef)(0);
138
- const isAdViewVisible = showIframe && iframeLoaded;
139
- const reset = () => {
140
- setHeight(0);
141
- setShowIframe(false);
142
- setContainerStyles({});
143
- setIframeStyles({});
144
- setIframeLoaded(false);
145
- resetModal();
146
- context?.resetAll();
147
- context?.captureError(new Error("Processing iframe error"));
148
- };
149
- const resetModal = () => {
150
- debugModal("Format:resetModal");
151
- if (modalInitTimeoutRef.current) {
152
- debugModal("Format:resetModalTimeout");
153
- clearTimeout(modalInitTimeoutRef.current);
154
- modalInitTimeoutRef.current = null;
155
- }
156
- isModalInitRef.current = false;
157
- setModalOpen(false);
158
- setModalLoaded(false);
159
- setModalShown(false);
160
- };
90
+ const iframeUrl = getUrl(code, messageId, bid?.bidId);
91
+ const webViewRef = (0, import_react.useRef)(null);
161
92
  const debug = (name, data = {}) => {
162
93
  context?.onDebugEventInternal?.(name, {
163
94
  code,
@@ -165,42 +96,30 @@ var Format = ({ code, messageId, wrapper, onEvent, ...otherParams }) => {
165
96
  otherParams,
166
97
  bid,
167
98
  iframeUrl,
168
- iframeLoaded,
169
- showIframe,
170
- height,
171
- containerStyles,
172
- iframeStyles,
173
99
  ...data
174
100
  });
175
101
  };
176
- const debugModal = (name, data = {}) => {
177
- context?.onDebugEventInternal?.(name, {
178
- code,
102
+ debug("Format:updateState", {
103
+ params: {
179
104
  messageId,
180
- otherParams,
181
- bid,
182
- modalUrl,
183
- modalOpen,
184
- modalShown,
185
- modalLoaded,
186
- ...data
187
- });
188
- };
189
- debug("Format:updateState");
105
+ code,
106
+ otherParams
107
+ }
108
+ });
190
109
  const onMessage = (event) => {
191
110
  try {
192
111
  const data = JSON.parse(event.nativeEvent.data);
193
112
  debug("Format:iframeMessage", {
194
113
  message: data,
195
- params: { data }
114
+ params: { data, messageId, code, otherParams }
196
115
  });
197
116
  const messageHandler = handleIframeMessage(
198
117
  (message) => {
199
118
  switch (message.type) {
200
119
  case "init-iframe":
201
- setIframeLoaded(true);
202
120
  debug("Format:iframePostMessage", {
203
121
  params: {
122
+ code,
204
123
  messages: context?.messages,
205
124
  sdk: "sdk-react-native",
206
125
  otherParams,
@@ -214,46 +133,6 @@ var Format = ({ code, messageId, wrapper, onEvent, ...otherParams }) => {
214
133
  messageId
215
134
  });
216
135
  break;
217
- case "error-iframe":
218
- reset();
219
- break;
220
- case "resize-iframe":
221
- setHeight(message.data.height);
222
- break;
223
- case "click-iframe":
224
- if (message.data.url) {
225
- import_react_native.Linking.openURL(`${context?.adServerUrl}${message.data.url}`).catch(
226
- (err) => console.error("error opening url", err)
227
- );
228
- }
229
- context?.onAdClickInternal(message.data);
230
- break;
231
- case "view-iframe":
232
- context?.onAdViewInternal(message.data);
233
- break;
234
- case "ad-done-iframe":
235
- if (bid?.bidId && message.data.cachedContent) {
236
- context?.cachedContentRef?.current?.set(bid.bidId, message.data.cachedContent);
237
- }
238
- break;
239
- case "show-iframe":
240
- setShowIframe(true);
241
- break;
242
- case "hide-iframe":
243
- setShowIframe(false);
244
- break;
245
- case "set-styles-iframe":
246
- setContainerStyles(message.data.containerStyles);
247
- setIframeStyles(message.data.iframeStyles);
248
- break;
249
- case "open-component-iframe":
250
- setModalOpen(true);
251
- modalInitTimeoutRef.current = setTimeout(() => {
252
- if (!isModalInitRef.current) {
253
- resetModal();
254
- }
255
- }, message.data.timeout ?? 5e3);
256
- break;
257
136
  case "event-iframe":
258
137
  onEvent?.(message.data);
259
138
  context?.onAdEventInternal(message.data);
@@ -267,253 +146,144 @@ var Format = ({ code, messageId, wrapper, onEvent, ...otherParams }) => {
267
146
  messageHandler({ data });
268
147
  } catch (e) {
269
148
  debug("Format:iframeMessageError", {
270
- params: { error: e },
271
- error: e
272
- });
273
- console.error("error parsing message from webview", e);
274
- reset();
275
- }
276
- };
277
- const onModalMessage = (event) => {
278
- try {
279
- const data = JSON.parse(event.nativeEvent.data);
280
- debugModal("Format:modalIframeMessage", {
281
- params: { data },
282
- message: data
283
- });
284
- const messageHandler = handleIframeMessage(
285
- (message) => {
286
- switch (message.type) {
287
- case "close-component-iframe":
288
- resetModal();
289
- break;
290
- case "init-component-iframe":
291
- isModalInitRef.current = true;
292
- if (modalInitTimeoutRef.current) {
293
- clearTimeout(modalInitTimeoutRef.current);
294
- modalInitTimeoutRef.current = null;
295
- }
296
- setModalShown(true);
297
- break;
298
- case "error-component-iframe":
299
- case "error-iframe":
300
- resetModal();
301
- context?.captureError(new Error("Processing modal iframe error"));
302
- break;
303
- case "click-iframe":
304
- if (message.data.url) {
305
- import_react_native.Linking.openURL(`${context?.adServerUrl}${message.data.url}`).catch(
306
- (err) => console.error("error opening url", err)
307
- );
308
- }
309
- context?.onAdClickInternal(message.data);
310
- break;
311
- case "event-iframe":
312
- onEvent?.(message.data);
313
- context?.onAdEventInternal(message.data);
314
- break;
315
- }
316
- },
317
- {
318
- code,
319
- component: "modal"
320
- }
321
- );
322
- messageHandler({ data });
323
- } catch (e) {
324
- debugModal("Format:modalIframeMessageError", {
325
- params: { error: e },
149
+ params: { error: e, messageId, code, otherParams },
326
150
  error: e
327
151
  });
328
152
  console.error("error parsing message from webview", e);
329
- resetModal();
330
153
  }
331
154
  };
332
- const paramsString = (0, import_sdk_react.convertParamsToString)(otherParams);
333
- (0, import_react2.useEffect)(() => {
334
- if (!iframeLoaded || !context?.adServerUrl || !bid || !webViewRef.current) {
335
- debug("Format:iframePostMessageNotLoaded", {
336
- params: {
337
- iframeLoaded,
338
- contextAdServerUrl: context?.adServerUrl,
339
- bid
340
- }
341
- });
342
- return;
343
- }
344
- debug("Format:iframePostMessage", {
345
- params: {
346
- otherParams
347
- }
348
- });
349
- sendMessage(webViewRef, "update-iframe", code, {
350
- data: { otherParams },
351
- code
352
- });
353
- }, [paramsString, iframeLoaded, context?.adServerUrl, bid, code]);
354
- const checkIfInViewport = () => {
355
- if (!containerRef.current) {
356
- debug("Format:checkIfInViewportNoContainer");
357
- return;
358
- }
359
- debug("Format:checkIfInViewportMeasure", {
360
- params: {
361
- windowWidth,
362
- windowHeight
363
- }
364
- });
365
- containerRef.current.measureInWindow((containerX, containerY, containerWidth, containerHeight) => {
366
- sendMessage(webViewRef, "update-dimensions-iframe", code, {
367
- windowWidth,
368
- windowHeight,
369
- containerWidth,
370
- containerHeight,
371
- containerX,
372
- containerY,
373
- keyboardHeight: keyboardHeightRef.current
374
- });
375
- debug("Format:checkIfInViewportMeasureSend", {
376
- params: {
377
- windowWidth,
378
- windowHeight,
379
- containerWidth,
380
- containerHeight,
381
- containerX,
382
- containerY,
383
- keyboardHeight: keyboardHeightRef.current
384
- }
385
- });
386
- });
387
- };
388
- (0, import_react2.useEffect)(() => {
389
- if (!isAdViewVisible) {
390
- debug("Format:checkIfInViewportNotVisible");
391
- return;
392
- }
393
- const interval = setInterval(() => {
394
- checkIfInViewport();
395
- }, 250);
396
- return () => {
397
- clearInterval(interval);
398
- debug("Format:checkIfInViewportCleanup");
399
- };
400
- }, [isAdViewVisible]);
401
- (0, import_react2.useEffect)(() => {
402
- const showSubscription = import_react_native.Keyboard.addListener("keyboardDidShow", (e) => {
403
- debug("Format:keyboardDidShow", {
404
- params: {
405
- keyboardHeight: e?.endCoordinates?.height ?? 0
406
- }
407
- });
408
- keyboardHeightRef.current = e?.endCoordinates?.height ?? 0;
409
- });
410
- const hideSubscription = import_react_native.Keyboard.addListener("keyboardDidHide", () => {
411
- debug("Format:keyboardDidHide");
412
- keyboardHeightRef.current = 0;
413
- });
414
- return () => {
415
- showSubscription.remove();
416
- hideSubscription.remove();
417
- keyboardHeightRef.current = 0;
418
- debug("Format:keyboardEffectCleanup");
419
- };
420
- }, []);
421
155
  if (!context || !bid || !iframeUrl) {
422
156
  debug("Format:noContextOrBidOrIframeUrl", {
423
157
  params: {
424
158
  context,
425
159
  bid,
426
- iframeUrl
160
+ iframeUrl,
161
+ messageId,
162
+ code,
163
+ otherParams
427
164
  }
428
165
  });
429
166
  return null;
430
167
  }
431
- const inlineContent = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
432
- frame_webview_default,
168
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
169
+ import_react_native.View,
433
170
  {
434
- ref: webViewRef,
435
- iframeUrl,
436
- onMessage,
437
171
  style: {
438
- height,
172
+ height: 300,
439
173
  width: "100%",
440
174
  backgroundColor: "transparent",
441
- borderWidth: 0,
442
- ...iframeStyles
175
+ borderWidth: 0
443
176
  },
444
- onError: () => {
445
- debug("Format:iframeError");
446
- reset();
447
- },
448
- onLoad: () => {
449
- debug("Format:iframeLoad");
450
- }
451
- }
452
- );
453
- const interstitialContent = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
454
- import_react_native.Modal,
455
- {
456
- visible: modalOpen,
457
- transparent: true,
458
- onRequestClose: resetModal,
459
- animationType: "slide",
460
- statusBarTranslucent: true,
461
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
462
- import_react_native.View,
177
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
178
+ import_react_native_webview.WebView,
463
179
  {
180
+ ref: webViewRef,
181
+ source: {
182
+ uri: iframeUrl
183
+ },
184
+ onMessage,
464
185
  style: {
465
- flex: 1,
466
- // Don't show the modal until the modal page is loaded and sends 'init-component-iframe' message back to SDK
467
- ...modalShown ? { opacity: 1, pointerEvents: "auto" } : { opacity: 0, pointerEvents: "none" }
186
+ height: 300,
187
+ width: "100%",
188
+ backgroundColor: "transparent",
189
+ borderWidth: 0
468
190
  },
469
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
470
- frame_webview_default,
471
- {
472
- ref: modalWebViewRef,
473
- iframeUrl: modalUrl,
474
- onMessage: onModalMessage,
475
- style: {
476
- backgroundColor: "transparent",
477
- height: "100%",
478
- width: "100%",
479
- borderWidth: 0
480
- },
481
- onError: () => {
482
- debug("Format:modalError");
483
- resetModal();
484
- },
485
- onLoad: () => {
486
- debug("Format:modalLoad");
487
- setModalLoaded(true);
488
- }
191
+ allowsInlineMediaPlayback: true,
192
+ mediaPlaybackRequiresUserAction: false,
193
+ javaScriptEnabled: true,
194
+ domStorageEnabled: true,
195
+ allowsFullscreenVideo: false,
196
+ injectedJavaScript: `
197
+ window.addEventListener("message", function(event) {
198
+ if (window.ReactNativeWebView && event.data) {
199
+ // ReactNativeWebView.postMessage only supports string data
200
+ window.ReactNativeWebView.postMessage(JSON.stringify(event.data));
489
201
  }
490
- )
202
+ }, false);
203
+ `,
204
+ onLoadStart: () => {
205
+ debug("Format:iframeLoadStart", {
206
+ params: {
207
+ messageId,
208
+ code,
209
+ otherParams
210
+ }
211
+ });
212
+ },
213
+ onError: () => {
214
+ debug("Format:iframeError", {
215
+ params: {
216
+ messageId,
217
+ code,
218
+ otherParams
219
+ }
220
+ });
221
+ },
222
+ onLoad: () => {
223
+ debug("Format:iframeLoad", {
224
+ params: {
225
+ messageId,
226
+ code,
227
+ otherParams
228
+ }
229
+ });
230
+ },
231
+ onLoadProgress: () => {
232
+ debug("Format:iframeLoadProgress", {
233
+ params: {
234
+ messageId,
235
+ code,
236
+ otherParams
237
+ }
238
+ });
239
+ },
240
+ onHttpError: () => {
241
+ debug("Format:iframeHttpError", {
242
+ params: {
243
+ messageId,
244
+ code,
245
+ otherParams
246
+ }
247
+ });
248
+ },
249
+ onRenderProcessGone: () => {
250
+ debug("Format:iframeRenderProcessGone", {
251
+ params: {
252
+ messageId,
253
+ code,
254
+ otherParams
255
+ }
256
+ });
257
+ },
258
+ onNavigationStateChange: () => {
259
+ debug("Format:iframeNavigationStateChange", {
260
+ params: {
261
+ messageId,
262
+ code,
263
+ otherParams
264
+ }
265
+ });
266
+ },
267
+ onContentProcessDidTerminate: () => {
268
+ debug("Format:iframeContentProcessDidTerminate", {
269
+ params: {
270
+ messageId,
271
+ code,
272
+ otherParams
273
+ }
274
+ });
275
+ }
491
276
  }
492
277
  )
493
278
  }
494
279
  );
495
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
496
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
497
- import_react_native.View,
498
- {
499
- style: isAdViewVisible ? containerStyles : {
500
- height: 0,
501
- overflow: "hidden"
502
- },
503
- ref: containerRef,
504
- children: wrapper ? wrapper(inlineContent) : inlineContent
505
- }
506
- ),
507
- interstitialContent
508
- ] });
509
280
  };
510
- var FormatWithErrorBoundary = (props) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_sdk_react.ErrorBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Format, { ...props }) });
511
- var Format_default = FormatWithErrorBoundary;
281
+ var Format_default = Format;
512
282
 
513
283
  // src/formats/InlineAd.tsx
514
- var import_jsx_runtime3 = require("react/jsx-runtime");
284
+ var import_jsx_runtime2 = require("react/jsx-runtime");
515
285
  var InlineAd = ({ code, messageId, wrapper, ...props }) => {
516
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Format_default, { code, messageId, wrapper, ...props });
286
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Format_default, { code, messageId, wrapper, ...props });
517
287
  };
518
288
  var InlineAd_default = InlineAd;
519
289
 
@@ -524,14 +294,14 @@ var import_react_native3 = require("react-native");
524
294
  var import_react_native_device_info = __toESM(require("react-native-device-info"));
525
295
 
526
296
  // package.json
527
- var version = "3.0.7-rc.1";
297
+ var version = "3.0.7-rc.3";
528
298
 
529
299
  // src/NativeRNKontext.ts
530
300
  var import_react_native2 = require("react-native");
531
301
  var NativeRNKontext_default = import_react_native2.TurboModuleRegistry.getEnforcing("RNKontext");
532
302
 
533
303
  // src/context/AdsProvider.tsx
534
- var import_jsx_runtime4 = require("react/jsx-runtime");
304
+ var import_jsx_runtime3 = require("react/jsx-runtime");
535
305
  ErrorUtils.setGlobalHandler((error, isFatal) => {
536
306
  if (!isFatal) {
537
307
  import_sdk_react2.log.warn(error);
@@ -625,7 +395,7 @@ var getSdk = async () => ({
625
395
  version
626
396
  });
627
397
  var AdsProvider = (props) => {
628
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_sdk_react2.AdsProviderInternal, { ...props, getDevice, getSdk, getApp });
398
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_sdk_react2.AdsProviderInternal, { ...props, getDevice, getSdk, getApp });
629
399
  };
630
400
  // Annotate the CommonJS export names for ESM import in node:
631
401
  0 && (module.exports = {