@kontextso/sdk-react-native 3.0.5 → 3.0.7-rc.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
@@ -44,10 +44,11 @@ function makeIframeMessage(type, opts) {
44
44
  function handleIframeMessage(handler, opts) {
45
45
  const { origin, code, component } = opts;
46
46
  return (event) => {
47
+ var _a, _b;
47
48
  if (origin && event.origin !== origin) return;
48
- const eventCode = event.data.data?.code;
49
+ const eventCode = (_a = event.data.data) == null ? void 0 : _a.code;
49
50
  if (eventCode && code && eventCode !== code) return;
50
- const eventComponent = event.data.data?.component;
51
+ const eventComponent = (_b = event.data.data) == null ? void 0 : _b.component;
51
52
  if (eventComponent && component && eventComponent !== component) return;
52
53
  handler(event.data);
53
54
  };
@@ -146,7 +147,9 @@ var Format = ({ code, messageId, wrapper, onEvent, ...otherParams }) => {
146
147
  context?.captureError(new Error("Processing iframe error"));
147
148
  };
148
149
  const resetModal = () => {
150
+ debugModal("Format:resetModal");
149
151
  if (modalInitTimeoutRef.current) {
152
+ debugModal("Format:resetModalTimeout");
150
153
  clearTimeout(modalInitTimeoutRef.current);
151
154
  modalInitTimeoutRef.current = null;
152
155
  }
@@ -183,19 +186,27 @@ var Format = ({ code, messageId, wrapper, onEvent, ...otherParams }) => {
183
186
  ...data
184
187
  });
185
188
  };
186
- debug("format-update-state");
189
+ debug("Format:updateState");
187
190
  const onMessage = (event) => {
188
191
  try {
189
192
  const data = JSON.parse(event.nativeEvent.data);
190
- debug("iframe-message", {
191
- message: data
193
+ debug("Format:iframeMessage", {
194
+ message: data,
195
+ params: { data }
192
196
  });
193
197
  const messageHandler = handleIframeMessage(
194
198
  (message) => {
195
199
  switch (message.type) {
196
200
  case "init-iframe":
197
201
  setIframeLoaded(true);
198
- debug("iframe-post-message");
202
+ debug("Format:iframePostMessage", {
203
+ params: {
204
+ messages: context?.messages,
205
+ sdk: "sdk-react-native",
206
+ otherParams,
207
+ messageId
208
+ }
209
+ });
199
210
  sendMessage(webViewRef, "update-iframe", code, {
200
211
  messages: context?.messages,
201
212
  sdk: "sdk-react-native",
@@ -255,7 +266,8 @@ var Format = ({ code, messageId, wrapper, onEvent, ...otherParams }) => {
255
266
  );
256
267
  messageHandler({ data });
257
268
  } catch (e) {
258
- debug("iframe-message-error", {
269
+ debug("Format:iframeMessageError", {
270
+ params: { error: e },
259
271
  error: e
260
272
  });
261
273
  console.error("error parsing message from webview", e);
@@ -265,7 +277,8 @@ var Format = ({ code, messageId, wrapper, onEvent, ...otherParams }) => {
265
277
  const onModalMessage = (event) => {
266
278
  try {
267
279
  const data = JSON.parse(event.nativeEvent.data);
268
- debugModal("modal-iframe-message", {
280
+ debugModal("Format:modalIframeMessage", {
281
+ params: { data },
269
282
  message: data
270
283
  });
271
284
  const messageHandler = handleIframeMessage(
@@ -308,7 +321,8 @@ var Format = ({ code, messageId, wrapper, onEvent, ...otherParams }) => {
308
321
  );
309
322
  messageHandler({ data });
310
323
  } catch (e) {
311
- debugModal("modal-iframe-message-error", {
324
+ debugModal("Format:modalIframeMessageError", {
325
+ params: { error: e },
312
326
  error: e
313
327
  });
314
328
  console.error("error parsing message from webview", e);
@@ -318,16 +332,36 @@ var Format = ({ code, messageId, wrapper, onEvent, ...otherParams }) => {
318
332
  const paramsString = (0, import_sdk_react.convertParamsToString)(otherParams);
319
333
  (0, import_react2.useEffect)(() => {
320
334
  if (!iframeLoaded || !context?.adServerUrl || !bid || !webViewRef.current) {
335
+ debug("Format:iframePostMessageNotLoaded", {
336
+ params: {
337
+ iframeLoaded,
338
+ contextAdServerUrl: context?.adServerUrl,
339
+ bid
340
+ }
341
+ });
321
342
  return;
322
343
  }
323
- debug("iframe-post-message");
344
+ debug("Format:iframePostMessage", {
345
+ params: {
346
+ otherParams
347
+ }
348
+ });
324
349
  sendMessage(webViewRef, "update-iframe", code, {
325
350
  data: { otherParams },
326
351
  code
327
352
  });
328
353
  }, [paramsString, iframeLoaded, context?.adServerUrl, bid, code]);
329
354
  const checkIfInViewport = () => {
330
- if (!containerRef.current) return;
355
+ if (!containerRef.current) {
356
+ debug("Format:checkIfInViewportNoContainer");
357
+ return;
358
+ }
359
+ debug("Format:checkIfInViewportMeasure", {
360
+ params: {
361
+ windowWidth,
362
+ windowHeight
363
+ }
364
+ });
331
365
  containerRef.current.measureInWindow((containerX, containerY, containerWidth, containerHeight) => {
332
366
  sendMessage(webViewRef, "update-dimensions-iframe", code, {
333
367
  windowWidth,
@@ -338,29 +372,60 @@ var Format = ({ code, messageId, wrapper, onEvent, ...otherParams }) => {
338
372
  containerY,
339
373
  keyboardHeight: keyboardHeightRef.current
340
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
+ });
341
386
  });
342
387
  };
343
388
  (0, import_react2.useEffect)(() => {
344
- if (!isAdViewVisible) return;
389
+ if (!isAdViewVisible) {
390
+ debug("Format:checkIfInViewportNotVisible");
391
+ return;
392
+ }
345
393
  const interval = setInterval(() => {
346
394
  checkIfInViewport();
347
395
  }, 250);
348
- return () => clearInterval(interval);
396
+ return () => {
397
+ clearInterval(interval);
398
+ debug("Format:checkIfInViewportCleanup");
399
+ };
349
400
  }, [isAdViewVisible]);
350
401
  (0, import_react2.useEffect)(() => {
351
402
  const showSubscription = import_react_native.Keyboard.addListener("keyboardDidShow", (e) => {
403
+ debug("Format:keyboardDidShow", {
404
+ params: {
405
+ keyboardHeight: e?.endCoordinates?.height ?? 0
406
+ }
407
+ });
352
408
  keyboardHeightRef.current = e?.endCoordinates?.height ?? 0;
353
409
  });
354
410
  const hideSubscription = import_react_native.Keyboard.addListener("keyboardDidHide", () => {
411
+ debug("Format:keyboardDidHide");
355
412
  keyboardHeightRef.current = 0;
356
413
  });
357
414
  return () => {
358
415
  showSubscription.remove();
359
416
  hideSubscription.remove();
360
417
  keyboardHeightRef.current = 0;
418
+ debug("Format:keyboardEffectCleanup");
361
419
  };
362
420
  }, []);
363
421
  if (!context || !bid || !iframeUrl) {
422
+ debug("Format:noContextOrBidOrIframeUrl", {
423
+ params: {
424
+ context,
425
+ bid,
426
+ iframeUrl
427
+ }
428
+ });
364
429
  return null;
365
430
  }
366
431
  const inlineContent = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -377,11 +442,11 @@ var Format = ({ code, messageId, wrapper, onEvent, ...otherParams }) => {
377
442
  ...iframeStyles
378
443
  },
379
444
  onError: () => {
380
- debug("iframe-error");
445
+ debug("Format:iframeError");
381
446
  reset();
382
447
  },
383
448
  onLoad: () => {
384
- debug("iframe-load");
449
+ debug("Format:iframeLoad");
385
450
  }
386
451
  }
387
452
  );
@@ -414,11 +479,11 @@ var Format = ({ code, messageId, wrapper, onEvent, ...otherParams }) => {
414
479
  borderWidth: 0
415
480
  },
416
481
  onError: () => {
417
- debug("modal-error");
482
+ debug("Format:modalError");
418
483
  resetModal();
419
484
  },
420
485
  onLoad: () => {
421
- debug("modal-load");
486
+ debug("Format:modalLoad");
422
487
  setModalLoaded(true);
423
488
  }
424
489
  }
@@ -454,11 +519,12 @@ var InlineAd_default = InlineAd;
454
519
 
455
520
  // src/context/AdsProvider.tsx
456
521
  var import_sdk_react2 = require("@kontextso/sdk-react");
522
+ var import_netinfo = require("@react-native-community/netinfo");
457
523
  var import_react_native3 = require("react-native");
458
524
  var import_react_native_device_info = __toESM(require("react-native-device-info"));
459
525
 
460
526
  // package.json
461
- var version = "3.0.5";
527
+ var version = "3.0.7-rc.1";
462
528
 
463
529
  // src/NativeRNKontext.ts
464
530
  var import_react_native2 = require("react-native");
@@ -479,6 +545,7 @@ var getDevice = async () => {
479
545
  const deviceType = import_react_native_device_info.default.getDeviceType();
480
546
  const soundOn = await NativeRNKontext_default.isSoundOn();
481
547
  const screen = import_react_native3.Dimensions.get("screen");
548
+ const networkInfo = await (0, import_netinfo.fetch)();
482
549
  const mapDeviceTypeToHardwareType = () => {
483
550
  switch (deviceType) {
484
551
  case "Handset":
@@ -508,10 +575,10 @@ var getDevice = async () => {
508
575
  // outputType: Not available without native module
509
576
  },
510
577
  network: {
511
- // carrier: await DeviceInfo.getCarrier(), not supported in react-native-device-info v10.0.0
512
- userAgent: await import_react_native_device_info.default.getUserAgent()
513
- // detail: Requires @react-native-community/netinfo
514
- // type: Requires @react-native-community/netinfo
578
+ carrier: networkInfo.type === import_netinfo.NetInfoStateType.cellular && networkInfo.details.carrier || void 0,
579
+ userAgent: await import_react_native_device_info.default.getUserAgent(),
580
+ type: [import_netinfo.NetInfoStateType.wifi, import_netinfo.NetInfoStateType.cellular, import_netinfo.NetInfoStateType.ethernet].includes(networkInfo.type) ? networkInfo.type : import_netinfo.NetInfoStateType.other,
581
+ detail: networkInfo.type === import_netinfo.NetInfoStateType.cellular && networkInfo.details.cellularGeneration || void 0
515
582
  },
516
583
  os: {
517
584
  name: import_react_native3.Platform.OS,
@@ -537,14 +604,21 @@ var getDevice = async () => {
537
604
  return {};
538
605
  }
539
606
  };
540
- var getApp = async () => ({
541
- bundleId: import_react_native_device_info.default.getBundleId(),
542
- // not supported in react-native-device-info v10.0.0
543
- // firstInstallTime: await DeviceInfo.getFirstInstallTime(),
544
- // lastUpdateTime: await DeviceInfo.getLastUpdateTime(),
545
- // startTime: await DeviceInfo.getStartupTime(),
546
- version: import_react_native_device_info.default.getVersion()
547
- });
607
+ var getApp = async () => {
608
+ try {
609
+ return {
610
+ bundleId: import_react_native_device_info.default.getBundleId(),
611
+ firstInstallTime: await import_react_native_device_info.default.getFirstInstallTime(),
612
+ lastUpdateTime: await import_react_native_device_info.default.getLastUpdateTime(),
613
+ version: import_react_native_device_info.default.getVersion()
614
+ // Not supported in react-native-device-info v10
615
+ // startTime: await DeviceInfo.getStartupTime(),
616
+ };
617
+ } catch (error) {
618
+ console.error(error);
619
+ return {};
620
+ }
621
+ };
548
622
  var getSdk = async () => ({
549
623
  name: "sdk-react-native",
550
624
  platform: import_react_native3.Platform.OS === "ios" ? "ios" : "android",
package/dist/index.mjs CHANGED
@@ -7,10 +7,11 @@ function makeIframeMessage(type, opts) {
7
7
  function handleIframeMessage(handler, opts) {
8
8
  const { origin, code, component } = opts;
9
9
  return (event) => {
10
+ var _a, _b;
10
11
  if (origin && event.origin !== origin) return;
11
- const eventCode = event.data.data?.code;
12
+ const eventCode = (_a = event.data.data) == null ? void 0 : _a.code;
12
13
  if (eventCode && code && eventCode !== code) return;
13
- const eventComponent = event.data.data?.component;
14
+ const eventComponent = (_b = event.data.data) == null ? void 0 : _b.component;
14
15
  if (eventComponent && component && eventComponent !== component) return;
15
16
  handler(event.data);
16
17
  };
@@ -115,7 +116,9 @@ var Format = ({ code, messageId, wrapper, onEvent, ...otherParams }) => {
115
116
  context?.captureError(new Error("Processing iframe error"));
116
117
  };
117
118
  const resetModal = () => {
119
+ debugModal("Format:resetModal");
118
120
  if (modalInitTimeoutRef.current) {
121
+ debugModal("Format:resetModalTimeout");
119
122
  clearTimeout(modalInitTimeoutRef.current);
120
123
  modalInitTimeoutRef.current = null;
121
124
  }
@@ -152,19 +155,27 @@ var Format = ({ code, messageId, wrapper, onEvent, ...otherParams }) => {
152
155
  ...data
153
156
  });
154
157
  };
155
- debug("format-update-state");
158
+ debug("Format:updateState");
156
159
  const onMessage = (event) => {
157
160
  try {
158
161
  const data = JSON.parse(event.nativeEvent.data);
159
- debug("iframe-message", {
160
- message: data
162
+ debug("Format:iframeMessage", {
163
+ message: data,
164
+ params: { data }
161
165
  });
162
166
  const messageHandler = handleIframeMessage(
163
167
  (message) => {
164
168
  switch (message.type) {
165
169
  case "init-iframe":
166
170
  setIframeLoaded(true);
167
- debug("iframe-post-message");
171
+ debug("Format:iframePostMessage", {
172
+ params: {
173
+ messages: context?.messages,
174
+ sdk: "sdk-react-native",
175
+ otherParams,
176
+ messageId
177
+ }
178
+ });
168
179
  sendMessage(webViewRef, "update-iframe", code, {
169
180
  messages: context?.messages,
170
181
  sdk: "sdk-react-native",
@@ -224,7 +235,8 @@ var Format = ({ code, messageId, wrapper, onEvent, ...otherParams }) => {
224
235
  );
225
236
  messageHandler({ data });
226
237
  } catch (e) {
227
- debug("iframe-message-error", {
238
+ debug("Format:iframeMessageError", {
239
+ params: { error: e },
228
240
  error: e
229
241
  });
230
242
  console.error("error parsing message from webview", e);
@@ -234,7 +246,8 @@ var Format = ({ code, messageId, wrapper, onEvent, ...otherParams }) => {
234
246
  const onModalMessage = (event) => {
235
247
  try {
236
248
  const data = JSON.parse(event.nativeEvent.data);
237
- debugModal("modal-iframe-message", {
249
+ debugModal("Format:modalIframeMessage", {
250
+ params: { data },
238
251
  message: data
239
252
  });
240
253
  const messageHandler = handleIframeMessage(
@@ -277,7 +290,8 @@ var Format = ({ code, messageId, wrapper, onEvent, ...otherParams }) => {
277
290
  );
278
291
  messageHandler({ data });
279
292
  } catch (e) {
280
- debugModal("modal-iframe-message-error", {
293
+ debugModal("Format:modalIframeMessageError", {
294
+ params: { error: e },
281
295
  error: e
282
296
  });
283
297
  console.error("error parsing message from webview", e);
@@ -287,16 +301,36 @@ var Format = ({ code, messageId, wrapper, onEvent, ...otherParams }) => {
287
301
  const paramsString = convertParamsToString(otherParams);
288
302
  useEffect(() => {
289
303
  if (!iframeLoaded || !context?.adServerUrl || !bid || !webViewRef.current) {
304
+ debug("Format:iframePostMessageNotLoaded", {
305
+ params: {
306
+ iframeLoaded,
307
+ contextAdServerUrl: context?.adServerUrl,
308
+ bid
309
+ }
310
+ });
290
311
  return;
291
312
  }
292
- debug("iframe-post-message");
313
+ debug("Format:iframePostMessage", {
314
+ params: {
315
+ otherParams
316
+ }
317
+ });
293
318
  sendMessage(webViewRef, "update-iframe", code, {
294
319
  data: { otherParams },
295
320
  code
296
321
  });
297
322
  }, [paramsString, iframeLoaded, context?.adServerUrl, bid, code]);
298
323
  const checkIfInViewport = () => {
299
- if (!containerRef.current) return;
324
+ if (!containerRef.current) {
325
+ debug("Format:checkIfInViewportNoContainer");
326
+ return;
327
+ }
328
+ debug("Format:checkIfInViewportMeasure", {
329
+ params: {
330
+ windowWidth,
331
+ windowHeight
332
+ }
333
+ });
300
334
  containerRef.current.measureInWindow((containerX, containerY, containerWidth, containerHeight) => {
301
335
  sendMessage(webViewRef, "update-dimensions-iframe", code, {
302
336
  windowWidth,
@@ -307,29 +341,60 @@ var Format = ({ code, messageId, wrapper, onEvent, ...otherParams }) => {
307
341
  containerY,
308
342
  keyboardHeight: keyboardHeightRef.current
309
343
  });
344
+ debug("Format:checkIfInViewportMeasureSend", {
345
+ params: {
346
+ windowWidth,
347
+ windowHeight,
348
+ containerWidth,
349
+ containerHeight,
350
+ containerX,
351
+ containerY,
352
+ keyboardHeight: keyboardHeightRef.current
353
+ }
354
+ });
310
355
  });
311
356
  };
312
357
  useEffect(() => {
313
- if (!isAdViewVisible) return;
358
+ if (!isAdViewVisible) {
359
+ debug("Format:checkIfInViewportNotVisible");
360
+ return;
361
+ }
314
362
  const interval = setInterval(() => {
315
363
  checkIfInViewport();
316
364
  }, 250);
317
- return () => clearInterval(interval);
365
+ return () => {
366
+ clearInterval(interval);
367
+ debug("Format:checkIfInViewportCleanup");
368
+ };
318
369
  }, [isAdViewVisible]);
319
370
  useEffect(() => {
320
371
  const showSubscription = Keyboard.addListener("keyboardDidShow", (e) => {
372
+ debug("Format:keyboardDidShow", {
373
+ params: {
374
+ keyboardHeight: e?.endCoordinates?.height ?? 0
375
+ }
376
+ });
321
377
  keyboardHeightRef.current = e?.endCoordinates?.height ?? 0;
322
378
  });
323
379
  const hideSubscription = Keyboard.addListener("keyboardDidHide", () => {
380
+ debug("Format:keyboardDidHide");
324
381
  keyboardHeightRef.current = 0;
325
382
  });
326
383
  return () => {
327
384
  showSubscription.remove();
328
385
  hideSubscription.remove();
329
386
  keyboardHeightRef.current = 0;
387
+ debug("Format:keyboardEffectCleanup");
330
388
  };
331
389
  }, []);
332
390
  if (!context || !bid || !iframeUrl) {
391
+ debug("Format:noContextOrBidOrIframeUrl", {
392
+ params: {
393
+ context,
394
+ bid,
395
+ iframeUrl
396
+ }
397
+ });
333
398
  return null;
334
399
  }
335
400
  const inlineContent = /* @__PURE__ */ jsx2(
@@ -346,11 +411,11 @@ var Format = ({ code, messageId, wrapper, onEvent, ...otherParams }) => {
346
411
  ...iframeStyles
347
412
  },
348
413
  onError: () => {
349
- debug("iframe-error");
414
+ debug("Format:iframeError");
350
415
  reset();
351
416
  },
352
417
  onLoad: () => {
353
- debug("iframe-load");
418
+ debug("Format:iframeLoad");
354
419
  }
355
420
  }
356
421
  );
@@ -383,11 +448,11 @@ var Format = ({ code, messageId, wrapper, onEvent, ...otherParams }) => {
383
448
  borderWidth: 0
384
449
  },
385
450
  onError: () => {
386
- debug("modal-error");
451
+ debug("Format:modalError");
387
452
  resetModal();
388
453
  },
389
454
  onLoad: () => {
390
- debug("modal-load");
455
+ debug("Format:modalLoad");
391
456
  setModalLoaded(true);
392
457
  }
393
458
  }
@@ -422,12 +487,16 @@ var InlineAd = ({ code, messageId, wrapper, ...props }) => {
422
487
  var InlineAd_default = InlineAd;
423
488
 
424
489
  // src/context/AdsProvider.tsx
425
- import { AdsProviderInternal, log } from "@kontextso/sdk-react";
490
+ import {
491
+ AdsProviderInternal,
492
+ log
493
+ } from "@kontextso/sdk-react";
494
+ import { fetch as fetchNetworkInfo, NetInfoStateType } from "@react-native-community/netinfo";
426
495
  import { Appearance, Dimensions, PixelRatio, Platform } from "react-native";
427
496
  import DeviceInfo from "react-native-device-info";
428
497
 
429
498
  // package.json
430
- var version = "3.0.5";
499
+ var version = "3.0.7-rc.1";
431
500
 
432
501
  // src/NativeRNKontext.ts
433
502
  import { TurboModuleRegistry } from "react-native";
@@ -448,6 +517,7 @@ var getDevice = async () => {
448
517
  const deviceType = DeviceInfo.getDeviceType();
449
518
  const soundOn = await NativeRNKontext_default.isSoundOn();
450
519
  const screen = Dimensions.get("screen");
520
+ const networkInfo = await fetchNetworkInfo();
451
521
  const mapDeviceTypeToHardwareType = () => {
452
522
  switch (deviceType) {
453
523
  case "Handset":
@@ -477,10 +547,10 @@ var getDevice = async () => {
477
547
  // outputType: Not available without native module
478
548
  },
479
549
  network: {
480
- // carrier: await DeviceInfo.getCarrier(), not supported in react-native-device-info v10.0.0
481
- userAgent: await DeviceInfo.getUserAgent()
482
- // detail: Requires @react-native-community/netinfo
483
- // type: Requires @react-native-community/netinfo
550
+ carrier: networkInfo.type === NetInfoStateType.cellular && networkInfo.details.carrier || void 0,
551
+ userAgent: await DeviceInfo.getUserAgent(),
552
+ type: [NetInfoStateType.wifi, NetInfoStateType.cellular, NetInfoStateType.ethernet].includes(networkInfo.type) ? networkInfo.type : NetInfoStateType.other,
553
+ detail: networkInfo.type === NetInfoStateType.cellular && networkInfo.details.cellularGeneration || void 0
484
554
  },
485
555
  os: {
486
556
  name: Platform.OS,
@@ -506,14 +576,21 @@ var getDevice = async () => {
506
576
  return {};
507
577
  }
508
578
  };
509
- var getApp = async () => ({
510
- bundleId: DeviceInfo.getBundleId(),
511
- // not supported in react-native-device-info v10.0.0
512
- // firstInstallTime: await DeviceInfo.getFirstInstallTime(),
513
- // lastUpdateTime: await DeviceInfo.getLastUpdateTime(),
514
- // startTime: await DeviceInfo.getStartupTime(),
515
- version: DeviceInfo.getVersion()
516
- });
579
+ var getApp = async () => {
580
+ try {
581
+ return {
582
+ bundleId: DeviceInfo.getBundleId(),
583
+ firstInstallTime: await DeviceInfo.getFirstInstallTime(),
584
+ lastUpdateTime: await DeviceInfo.getLastUpdateTime(),
585
+ version: DeviceInfo.getVersion()
586
+ // Not supported in react-native-device-info v10
587
+ // startTime: await DeviceInfo.getStartupTime(),
588
+ };
589
+ } catch (error) {
590
+ console.error(error);
591
+ return {};
592
+ }
593
+ };
517
594
  var getSdk = async () => ({
518
595
  name: "sdk-react-native",
519
596
  platform: Platform.OS === "ios" ? "ios" : "android",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kontextso/sdk-react-native",
3
- "version": "3.0.5",
3
+ "version": "3.0.7-rc.1",
4
4
  "description": "Kontext SDK for React Native",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -14,13 +14,15 @@
14
14
  "dev": "npm-run-all2 dev:js",
15
15
  "build:js": "tsup",
16
16
  "build": "npm run build:js && cross-env NODE_ENV=development npm run test:run",
17
- "test": "",
18
- "test:run": "",
17
+ "test:run": "vitest --run",
18
+ "test": "vitest --run",
19
+ "test:watch": "vitest --watch",
19
20
  "format": "biome format --write ."
20
21
  },
21
22
  "devDependencies": {
22
- "@kontextso/sdk-common": "^0.2.0",
23
+ "@kontextso/sdk-common": "^1.0.0",
23
24
  "@kontextso/typescript-config": "*",
25
+ "@react-native-community/netinfo": "11.3.1",
24
26
  "@testing-library/dom": "^10.4.0",
25
27
  "@testing-library/jest-dom": "^6.4.6",
26
28
  "@testing-library/react": "^16.0.0",
@@ -37,7 +39,7 @@
37
39
  "react": "^18.3.1",
38
40
  "react-dom": "^18.3.1",
39
41
  "react-native": "^0.80.1",
40
- "react-native-device-info": ">=12.0.0",
42
+ "react-native-device-info": "10.14.0",
41
43
  "react-native-webview": "^13.15.0",
42
44
  "react-test-renderer": "^18.3.1",
43
45
  "tsup": "^8.0.2",
@@ -45,13 +47,14 @@
45
47
  "vitest": "^2.1.2"
46
48
  },
47
49
  "peerDependencies": {
50
+ "@react-native-community/netinfo": "^11.0",
48
51
  "react": ">=18.0.0",
49
52
  "react-native": ">=0.73.0",
50
53
  "react-native-device-info": ">=10.0.0 <15.0.0",
51
54
  "react-native-webview": "^13.10.0"
52
55
  },
53
56
  "dependencies": {
54
- "@kontextso/sdk-react": "^3.0.5"
57
+ "@kontextso/sdk-react": "^3.0.7-rc.1"
55
58
  },
56
59
  "files": [
57
60
  "dist/*",
@@ -0,0 +1,9 @@
1
+ import { describe, expect, test } from 'vitest'
2
+
3
+ describe('utils', () => {
4
+ describe('test', () => {
5
+ test('test', () => {
6
+ expect(1).toBe(1)
7
+ })
8
+ })
9
+ })
@@ -1,5 +1,12 @@
1
- import type { AdsProviderProps, AppConfig, DeviceConfig, SDKConfig } from '@kontextso/sdk-react'
2
- import { AdsProviderInternal, log } from '@kontextso/sdk-react'
1
+ import {
2
+ AdsProviderInternal,
3
+ type AdsProviderProps,
4
+ type AppConfig,
5
+ type DeviceConfig,
6
+ log,
7
+ type SDKConfig,
8
+ } from '@kontextso/sdk-react'
9
+ import { fetch as fetchNetworkInfo, NetInfoStateType } from '@react-native-community/netinfo'
3
10
  import { Appearance, Dimensions, PixelRatio, Platform } from 'react-native'
4
11
  import DeviceInfo, { type DeviceType } from 'react-native-device-info'
5
12
  import { version } from '../../package.json'
@@ -19,6 +26,7 @@ const getDevice = async (): Promise<DeviceConfig> => {
19
26
  const deviceType = DeviceInfo.getDeviceType() as DeviceType
20
27
  const soundOn = await KontextSDK.isSoundOn()
21
28
  const screen = Dimensions.get('screen')
29
+ const networkInfo = await fetchNetworkInfo()
22
30
 
23
31
  const mapDeviceTypeToHardwareType = (): DeviceConfig['hardware']['type'] => {
24
32
  switch (deviceType) {
@@ -50,10 +58,12 @@ const getDevice = async (): Promise<DeviceConfig> => {
50
58
  // outputType: Not available without native module
51
59
  },
52
60
  network: {
53
- // carrier: await DeviceInfo.getCarrier(), not supported in react-native-device-info v10.0.0
61
+ carrier: (networkInfo.type === NetInfoStateType.cellular && networkInfo.details.carrier) || undefined,
54
62
  userAgent: await DeviceInfo.getUserAgent(),
55
- // detail: Requires @react-native-community/netinfo
56
- // type: Requires @react-native-community/netinfo
63
+ type: [NetInfoStateType.wifi, NetInfoStateType.cellular, NetInfoStateType.ethernet].includes(networkInfo.type)
64
+ ? (networkInfo.type as NetInfoStateType.wifi | NetInfoStateType.cellular | NetInfoStateType.ethernet)
65
+ : NetInfoStateType.other,
66
+ detail: (networkInfo.type === NetInfoStateType.cellular && networkInfo.details.cellularGeneration) || undefined,
57
67
  },
58
68
  os: {
59
69
  name: Platform.OS,
@@ -81,16 +91,22 @@ const getDevice = async (): Promise<DeviceConfig> => {
81
91
  }
82
92
  }
83
93
 
84
- const getApp = async (): Promise<AppConfig> => ({
85
- bundleId: DeviceInfo.getBundleId(),
86
-
87
- // not supported in react-native-device-info v10.0.0
88
- // firstInstallTime: await DeviceInfo.getFirstInstallTime(),
89
- // lastUpdateTime: await DeviceInfo.getLastUpdateTime(),
90
- // startTime: await DeviceInfo.getStartupTime(),
91
-
92
- version: DeviceInfo.getVersion(),
93
- })
94
+ const getApp = async (): Promise<AppConfig> => {
95
+ try {
96
+ return {
97
+ bundleId: DeviceInfo.getBundleId(),
98
+ firstInstallTime: await DeviceInfo.getFirstInstallTime(),
99
+ lastUpdateTime: await DeviceInfo.getLastUpdateTime(),
100
+ version: DeviceInfo.getVersion(),
101
+ // Not supported in react-native-device-info v10
102
+ // startTime: await DeviceInfo.getStartupTime(),
103
+ }
104
+ } catch (error) {
105
+ console.error(error)
106
+ // @ts-expect-error
107
+ return {}
108
+ }
109
+ }
94
110
 
95
111
  const getSdk = async (): Promise<SDKConfig> => ({
96
112
  name: 'sdk-react-native',
@@ -89,7 +89,9 @@ const Format = ({ code, messageId, wrapper, onEvent, ...otherParams }: FormatPro
89
89
  }
90
90
 
91
91
  const resetModal = () => {
92
+ debugModal('Format:resetModal')
92
93
  if (modalInitTimeoutRef.current) {
94
+ debugModal('Format:resetModalTimeout')
93
95
  clearTimeout(modalInitTimeoutRef.current)
94
96
  modalInitTimeoutRef.current = null
95
97
  }
@@ -130,14 +132,15 @@ const Format = ({ code, messageId, wrapper, onEvent, ...otherParams }: FormatPro
130
132
  })
131
133
  }
132
134
 
133
- debug('format-update-state')
135
+ debug('Format:updateState')
134
136
 
135
137
  const onMessage = (event: WebViewMessageEvent) => {
136
138
  try {
137
139
  const data = JSON.parse(event.nativeEvent.data) as IframeMessage
138
140
 
139
- debug('iframe-message', {
141
+ debug('Format:iframeMessage', {
140
142
  message: data,
143
+ params: { data }
141
144
  })
142
145
 
143
146
  const messageHandler = handleIframeMessage(
@@ -145,7 +148,14 @@ const Format = ({ code, messageId, wrapper, onEvent, ...otherParams }: FormatPro
145
148
  switch (message.type) {
146
149
  case 'init-iframe':
147
150
  setIframeLoaded(true)
148
- debug('iframe-post-message')
151
+ debug('Format:iframePostMessage', {
152
+ params: {
153
+ messages: context?.messages,
154
+ sdk: 'sdk-react-native',
155
+ otherParams,
156
+ messageId,
157
+ }
158
+ })
149
159
  sendMessage(webViewRef, 'update-iframe', code, {
150
160
  messages: context?.messages,
151
161
  sdk: 'sdk-react-native',
@@ -216,7 +226,8 @@ const Format = ({ code, messageId, wrapper, onEvent, ...otherParams }: FormatPro
216
226
  )
217
227
  messageHandler({ data } as IframeMessageEvent)
218
228
  } catch (e) {
219
- debug('iframe-message-error', {
229
+ debug('Format:iframeMessageError', {
230
+ params: { error: e },
220
231
  error: e,
221
232
  })
222
233
  console.error('error parsing message from webview', e)
@@ -228,7 +239,8 @@ const Format = ({ code, messageId, wrapper, onEvent, ...otherParams }: FormatPro
228
239
  try {
229
240
  const data = JSON.parse(event.nativeEvent.data) as IframeMessage
230
241
 
231
- debugModal('modal-iframe-message', {
242
+ debugModal('Format:modalIframeMessage', {
243
+ params: { data },
232
244
  message: data,
233
245
  })
234
246
 
@@ -279,7 +291,8 @@ const Format = ({ code, messageId, wrapper, onEvent, ...otherParams }: FormatPro
279
291
  )
280
292
  messageHandler({ data } as IframeMessageEvent)
281
293
  } catch (e) {
282
- debugModal('modal-iframe-message-error', {
294
+ debugModal('Format:modalIframeMessageError', {
295
+ params: { error: e },
283
296
  error: e,
284
297
  })
285
298
  console.error('error parsing message from webview', e)
@@ -291,9 +304,20 @@ const Format = ({ code, messageId, wrapper, onEvent, ...otherParams }: FormatPro
291
304
 
292
305
  useEffect(() => {
293
306
  if (!iframeLoaded || !context?.adServerUrl || !bid || !webViewRef.current) {
307
+ debug('Format:iframePostMessageNotLoaded', {
308
+ params: {
309
+ iframeLoaded,
310
+ contextAdServerUrl: context?.adServerUrl,
311
+ bid,
312
+ }
313
+ })
294
314
  return
295
315
  }
296
- debug('iframe-post-message')
316
+ debug('Format:iframePostMessage', {
317
+ params: {
318
+ otherParams
319
+ }
320
+ })
297
321
  sendMessage(webViewRef, 'update-iframe', code, {
298
322
  data: { otherParams },
299
323
  code,
@@ -302,7 +326,17 @@ const Format = ({ code, messageId, wrapper, onEvent, ...otherParams }: FormatPro
302
326
  }, [paramsString, iframeLoaded, context?.adServerUrl, bid, code])
303
327
 
304
328
  const checkIfInViewport = () => {
305
- if (!containerRef.current) return
329
+ if (!containerRef.current) {
330
+ debug('Format:checkIfInViewportNoContainer')
331
+ return
332
+ }
333
+
334
+ debug('Format:checkIfInViewportMeasure', {
335
+ params: {
336
+ windowWidth,
337
+ windowHeight,
338
+ }
339
+ })
306
340
 
307
341
  containerRef.current.measureInWindow((containerX, containerY, containerWidth, containerHeight) => {
308
342
  sendMessage(webViewRef, 'update-dimensions-iframe', code, {
@@ -314,24 +348,47 @@ const Format = ({ code, messageId, wrapper, onEvent, ...otherParams }: FormatPro
314
348
  containerY,
315
349
  keyboardHeight: keyboardHeightRef.current,
316
350
  })
351
+ debug('Format:checkIfInViewportMeasureSend', {
352
+ params: {
353
+ windowWidth,
354
+ windowHeight,
355
+ containerWidth,
356
+ containerHeight,
357
+ containerX,
358
+ containerY,
359
+ keyboardHeight: keyboardHeightRef.current,
360
+ }
361
+ })
317
362
  })
318
363
  }
319
364
 
320
365
  useEffect(() => {
321
- if (!isAdViewVisible) return
366
+ if (!isAdViewVisible) {
367
+ debug('Format:checkIfInViewportNotVisible')
368
+ return
369
+ }
322
370
 
323
371
  const interval = setInterval(() => {
324
372
  checkIfInViewport()
325
373
  }, 250)
326
374
 
327
- return () => clearInterval(interval)
375
+ return () => {
376
+ clearInterval(interval)
377
+ debug('Format:checkIfInViewportCleanup')
378
+ }
328
379
  }, [isAdViewVisible])
329
380
 
330
381
  useEffect(() => {
331
382
  const showSubscription = Keyboard.addListener('keyboardDidShow', (e) => {
383
+ debug('Format:keyboardDidShow', {
384
+ params: {
385
+ keyboardHeight: e?.endCoordinates?.height ?? 0,
386
+ }
387
+ })
332
388
  keyboardHeightRef.current = e?.endCoordinates?.height ?? 0
333
389
  })
334
390
  const hideSubscription = Keyboard.addListener('keyboardDidHide', () => {
391
+ debug('Format:keyboardDidHide')
335
392
  keyboardHeightRef.current = 0
336
393
  })
337
394
 
@@ -339,10 +396,18 @@ const Format = ({ code, messageId, wrapper, onEvent, ...otherParams }: FormatPro
339
396
  showSubscription.remove()
340
397
  hideSubscription.remove()
341
398
  keyboardHeightRef.current = 0
399
+ debug('Format:keyboardEffectCleanup')
342
400
  }
343
401
  }, [])
344
402
 
345
403
  if (!context || !bid || !iframeUrl) {
404
+ debug('Format:noContextOrBidOrIframeUrl', {
405
+ params: {
406
+ context,
407
+ bid,
408
+ iframeUrl,
409
+ }
410
+ })
346
411
  return null
347
412
  }
348
413
 
@@ -359,11 +424,11 @@ const Format = ({ code, messageId, wrapper, onEvent, ...otherParams }: FormatPro
359
424
  ...iframeStyles,
360
425
  }}
361
426
  onError={() => {
362
- debug('iframe-error')
427
+ debug('Format:iframeError')
363
428
  reset()
364
429
  }}
365
430
  onLoad={() => {
366
- debug('iframe-load')
431
+ debug('Format:iframeLoad')
367
432
  }}
368
433
  />
369
434
  )
@@ -394,11 +459,11 @@ const Format = ({ code, messageId, wrapper, onEvent, ...otherParams }: FormatPro
394
459
  borderWidth: 0,
395
460
  }}
396
461
  onError={() => {
397
- debug('modal-error')
462
+ debug('Format:modalError')
398
463
  resetModal()
399
464
  }}
400
465
  onLoad={() => {
401
- debug('modal-load')
466
+ debug('Format:modalLoad')
402
467
  setModalLoaded(true)
403
468
  }}
404
469
  />