spotny-sdk 1.0.29 → 1.0.31

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/SpotnySdk.podspec CHANGED
@@ -16,12 +16,12 @@ Pod::Spec.new do |s|
16
16
  s.source_files = "ios/**/*.{h,m,mm,swift,cpp}"
17
17
  s.private_header_files = "ios/**/*.h"
18
18
 
19
- # KontaktSDK and Half are pre-built and bundled — no SPM or manual setup needed.
20
- # CBORCoding is statically compiled inside KontaktSDK.xcframeworkdo NOT add it separately.
21
- # Adding CBORCoding.xcframework causes duplicate ObjC class registration, crashing on iOS 16
22
- # in map_images_nolock and triggering hard crashes with memory-heavy frameworks (e.g. ViroKit/AR).
19
+ # All three frameworks are pre-built and bundled — no SPM or manual setup needed.
20
+ # CBORCoding is pure Swift (no ObjC classes) safe to include alongside KontaktSDK.xcframework.
21
+ # KontaktSDK.swiftinterface requires CBORCoding as a visible module at compile time.
23
22
  s.vendored_frameworks = [
24
23
  "ios/Frameworks/KontaktSDK.xcframework",
24
+ "ios/Frameworks/CBORCoding.xcframework",
25
25
  "ios/Frameworks/Half.xcframework"
26
26
  ]
27
27
 
@@ -67,4 +67,7 @@ dependencies {
67
67
 
68
68
  // AltBeacon — iBeacon scanning for Android
69
69
  implementation "org.altbeacon:android-beacon-library:2.20.5"
70
+
71
+ // Encrypted storage — mirrors iOS Keychain security level
72
+ implementation "androidx.security:security-crypto:1.0.0"
70
73
  }
@@ -7,6 +7,8 @@ import android.os.Build
7
7
  import android.os.RemoteException
8
8
  import android.util.Log
9
9
  import androidx.core.app.NotificationCompat
10
+ import androidx.security.crypto.EncryptedSharedPreferences
11
+ import androidx.security.crypto.MasterKey
10
12
  import com.facebook.react.bridge.*
11
13
  import com.facebook.react.modules.core.DeviceEventManagerModule
12
14
  import org.altbeacon.beacon.*
@@ -16,6 +18,7 @@ import java.net.URL
16
18
  import java.text.SimpleDateFormat
17
19
  import java.util.*
18
20
  import java.util.concurrent.Executors
21
+ import java.util.concurrent.locks.ReentrantLock
19
22
  import kotlin.math.abs
20
23
 
21
24
  // ── Kontakt.io iBeacon layout ─────────────────────────────────────────────────
@@ -44,11 +47,15 @@ class SpotnySdkModule(private val reactContext: ReactApplicationContext) :
44
47
  private var identifierId: String? = null
45
48
 
46
49
  // ── Configuration ─────────────────────────────────────────────────────────
47
- // backendURL and apiBasePath are fixed not overridable by consumers.
48
- private val backendURL = "https://api.spotny.app"
50
+ // backendURL is owner-only overridable via superDebugConfig in initialize().
51
+ private var backendURL = "https://api.spotny.app"
49
52
  private val apiBasePath = "/api/app/sdk"
53
+ /** When true, full API response bodies are logged (mirrors iOS debugMode). */
54
+ private var debugMode = false
50
55
  private var maxDetectionDistance = 8.0 // metres
51
- /** Multiplier applied to raw BLE distance. Default 0.5 matches Kontakt.io -12 dBm beacons. */
56
+ /** Multiplier applied to raw BLE distance. Default 0.5 AltBeacon's distance estimator
57
+ * tends to overestimate for low-power Kontakt.io beacons (-12 dBm), halving corrects it.
58
+ * iOS uses 1.0 because CLBeacon.accuracy is pre-calibrated via measuredPower. */
52
59
  private var distanceCorrectionFactor = 0.5
53
60
  /** API key identifying the SDK consumer (e.g. "nike"). Set during initialize(). */
54
61
  private var apiKey: String? = null
@@ -59,6 +66,13 @@ class SpotnySdkModule(private val reactContext: ReactApplicationContext) :
59
66
  /** Original SDK token — persisted so JWT can be refreshed without calling initialize() again. */
60
67
  private var sdkCredential: String? = null
61
68
 
69
+ // ── JWT refresh coordination ──────────────────────────────────────────────
70
+ // Mirrors iOS jwtRefreshInProgress / jwtRefreshQueue: only one verify request
71
+ // is in-flight at a time; concurrent ioExecutor threads wait on the condition.
72
+ private val jwtRefreshLock = ReentrantLock()
73
+ private val jwtRefreshDone = jwtRefreshLock.newCondition()
74
+ @Volatile private var jwtRefreshInProgress = false
75
+
62
76
  // ── Timing constants ──────────────────────────────────────────────────────
63
77
  private var proximityDistanceThreshold = 0.75
64
78
  private var impressionEventInterval = 10_000L // ms
@@ -107,7 +121,7 @@ class SpotnySdkModule(private val reactContext: ReactApplicationContext) :
107
121
  }
108
122
 
109
123
  private fun resumeStoredSession() {
110
- val prefs = reactContext.getSharedPreferences("SpotnySDK", Context.MODE_PRIVATE)
124
+ val prefs = prefs()
111
125
  if (!prefs.getBoolean("sessionActive", false)) return
112
126
  // Restore persisted JWT + credentials so all API calls work without initialize()
113
127
  sdkToken = prefs.getString("jwt", null)
@@ -126,7 +140,7 @@ class SpotnySdkModule(private val reactContext: ReactApplicationContext) :
126
140
  override fun startScanner(promise: Promise) {
127
141
  if (scanning) { promise.resolve("Already scanning"); return }
128
142
 
129
- val prefs = reactContext.getSharedPreferences("SpotnySDK", Context.MODE_PRIVATE).edit()
143
+ val prefs = prefs().edit()
130
144
  prefs.putBoolean("sessionActive", true)
131
145
  prefs.apply()
132
146
 
@@ -146,7 +160,7 @@ class SpotnySdkModule(private val reactContext: ReactApplicationContext) :
146
160
 
147
161
  cleanupAllState()
148
162
 
149
- val prefs = reactContext.getSharedPreferences("SpotnySDK", Context.MODE_PRIVATE).edit()
163
+ val prefs = prefs().edit()
150
164
  prefs.remove("sessionActive"); prefs.apply()
151
165
 
152
166
  scanning = false
@@ -163,6 +177,13 @@ class SpotnySdkModule(private val reactContext: ReactApplicationContext) :
163
177
  config?.getDouble("distanceCorrectionFactor")
164
178
  .takeIf { config?.hasKey("distanceCorrectionFactor") == true && (it ?: 0.0) > 0 }
165
179
  ?.let { distanceCorrectionFactor = it; Log.d(TAG, "distanceCorrectionFactor = $it") }
180
+ if (config?.hasKey("debug") == true) {
181
+ debugMode = config.getBoolean("debug")
182
+ Log.d(TAG, "debugMode = $debugMode")
183
+ }
184
+ config?.getMap("superDebugConfig")?.getString("backendURL")
185
+ ?.takeIf { it.isNotBlank() }
186
+ ?.let { backendURL = it; Log.w(TAG, "[OWNER DEBUG] backendURL overridden → $it") }
166
187
  val token = config?.getString("token")?.takeIf { it.isNotBlank() }
167
188
  if (token == null) {
168
189
  promise.reject("MISSING_TOKEN", "initialize() requires a token")
@@ -275,7 +296,7 @@ class SpotnySdkModule(private val reactContext: ReactApplicationContext) :
275
296
 
276
297
  // Session heartbeat every 60 s to prevent TTL expiry on a live session
277
298
  if (now - lastSessionHeartbeat >= 60_000L) {
278
- val prefs = reactContext.getSharedPreferences("SpotnySDK", Context.MODE_PRIVATE).edit()
299
+ val prefs = prefs().edit()
279
300
  prefs.putLong("sessionTimestamp", now); prefs.apply()
280
301
  lastSessionHeartbeat = now
281
302
  }
@@ -430,6 +451,26 @@ class SpotnySdkModule(private val reactContext: ReactApplicationContext) :
430
451
 
431
452
  // ── Helpers ───────────────────────────────────────────────────────────────
432
453
 
454
+ /** Returns EncryptedSharedPreferences backed by Android Keystore (AES-256).
455
+ * Falls back to plain SharedPreferences on the rare Keystore initialisation failure. */
456
+ private fun prefs(): android.content.SharedPreferences {
457
+ return try {
458
+ val masterKey = MasterKey.Builder(reactContext)
459
+ .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
460
+ .build()
461
+ EncryptedSharedPreferences.create(
462
+ reactContext,
463
+ "SpotnySDK_secure",
464
+ masterKey,
465
+ EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
466
+ EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
467
+ )
468
+ } catch (e: Exception) {
469
+ Log.w(TAG, "EncryptedSharedPreferences unavailable, using plain prefs: ${e.message}")
470
+ reactContext.getSharedPreferences("SpotnySDK", Context.MODE_PRIVATE)
471
+ }
472
+ }
473
+
433
474
  private fun beaconKey(major: Int, minor: Int) = "${major}_${minor}"
434
475
 
435
476
  private fun proximityLabel(distance: Double) = when {
@@ -440,7 +481,7 @@ class SpotnySdkModule(private val reactContext: ReactApplicationContext) :
440
481
  }
441
482
 
442
483
  private fun getDeviceId(): String {
443
- val prefs = reactContext.getSharedPreferences("SpotnySDK", Context.MODE_PRIVATE)
484
+ val prefs = prefs()
444
485
  return prefs.getString("deviceId", null) ?: run {
445
486
  val id = UUID.randomUUID().toString()
446
487
  prefs.edit().putString("deviceId", id).apply()
@@ -533,7 +574,7 @@ class SpotnySdkModule(private val reactContext: ReactApplicationContext) :
533
574
  }
534
575
 
535
576
  private fun persistJWT() {
536
- val prefs = reactContext.getSharedPreferences("SpotnySDK", Context.MODE_PRIVATE).edit()
577
+ val prefs = prefs().edit()
537
578
  sdkToken?.let { prefs.putString("jwt", it) }
538
579
  sdkCredential?.let { prefs.putString("sdkCredential", it) }
539
580
  apiKey?.let { prefs.putString("sdkApiKey", it) }
@@ -542,8 +583,36 @@ class SpotnySdkModule(private val reactContext: ReactApplicationContext) :
542
583
  prefs.apply()
543
584
  }
544
585
 
545
- /** Synchronous JWT refresh — safe to call from ioExecutor thread. */
586
+ /** Deduplicating JWT refresh — safe to call from any ioExecutor thread.
587
+ * First caller fires the HTTP request; concurrent callers block on the condition
588
+ * and return as soon as the single in-flight request completes (mirrors iOS jwtRefreshQueue). */
546
589
  private fun refreshJWTBlocking(): Boolean {
590
+ jwtRefreshLock.lock()
591
+ try {
592
+ while (jwtRefreshInProgress) {
593
+ jwtRefreshDone.await() // wait for the in-flight refresh to finish
594
+ }
595
+ if (!isTokenExpired()) return true // another thread already refreshed it
596
+ jwtRefreshInProgress = true
597
+ } finally {
598
+ jwtRefreshLock.unlock()
599
+ }
600
+
601
+ val success = doRefreshHTTP()
602
+
603
+ jwtRefreshLock.lock()
604
+ try {
605
+ jwtRefreshInProgress = false
606
+ jwtRefreshDone.signalAll()
607
+ } finally {
608
+ jwtRefreshLock.unlock()
609
+ }
610
+
611
+ return success
612
+ }
613
+
614
+ /** Fires a single synchronous verify POST and updates sdkToken / sdkTokenExpiry on success. */
615
+ private fun doRefreshHTTP(): Boolean {
547
616
  val credential = sdkCredential ?: return false
548
617
  val key = apiKey ?: return false
549
618
  return try {
@@ -554,7 +623,14 @@ class SpotnySdkModule(private val reactContext: ReactApplicationContext) :
554
623
  readTimeout = 10_000
555
624
  doOutput = true
556
625
  }
557
- conn.outputStream.use { it.write(buildJsonString(mapOf("api_token" to credential, "api_key" to key, "identifier_id" to (identifierId ?: ""), "device_id" to getDeviceId())).toByteArray()) }
626
+ conn.outputStream.use {
627
+ it.write(buildJsonString(mapOf(
628
+ "api_token" to credential,
629
+ "api_key" to key,
630
+ "identifier_id" to (identifierId ?: ""),
631
+ "device_id" to getDeviceId()
632
+ )).toByteArray())
633
+ }
558
634
  val status = conn.responseCode
559
635
  val response = try { conn.inputStream.bufferedReader().readText() }
560
636
  catch (_: Exception) { conn.errorStream?.bufferedReader()?.readText() ?: "" }
@@ -605,8 +681,10 @@ class SpotnySdkModule(private val reactContext: ReactApplicationContext) :
605
681
  val response = try { conn.inputStream.bufferedReader().readText() }
606
682
  catch (_: Exception) { conn.errorStream?.bufferedReader()?.readText() ?: "" }
607
683
  conn.disconnect()
684
+ if (debugMode) Log.d(TAG, "[DEBUG] $endpoint → $status: $response")
608
685
  reactContext.runOnUiQueueThread { completion(status, response) }
609
686
  } catch (e: Exception) {
687
+ if (debugMode) Log.d(TAG, "[DEBUG] $endpoint → error: ${e.message}")
610
688
  Log.e(TAG, "POST $endpoint error: ${e.message}")
611
689
  reactContext.runOnUiQueueThread { completion(-1, "") }
612
690
  }
@@ -58,8 +58,9 @@ public class SpotnyBeaconScanner: NSObject {
58
58
  private let apiBasePath: String = "/api/app/sdk"
59
59
  private let kontaktAPIKey: String = "mgrz08TOKNHafeY02cWIs9mxUHbynNQJ"
60
60
  private var maxDetectionDistance: Double = 8.0
61
- /// Multiplier applied to raw RSSI-derived distance to compensate for low TX power.
62
- /// Overridable via configure(). Default 0.5 matches Kontakt.io -12 dBm beacons.
61
+ /// Multiplier applied to raw RSSI-derived distance. Default 1.0 CLBeacon.accuracy
62
+ /// already accounts for TX power via Apple's measuredPower algorithm, so no correction
63
+ /// is needed. Overridable via initialize(distanceCorrectionFactor:).
63
64
  private var distanceCorrectionFactor: Double = 1.0
64
65
  /// API key identifying the SDK consumer (e.g. "nike"). Set during initialize().
65
66
  private var apiKey: String?
@@ -0,0 +1,18 @@
1
+ import { type TurboModule } from 'react-native';
2
+ export interface Spec extends TurboModule {
3
+ startScanner(): Promise<string>;
4
+ stopScanner(): Promise<string>;
5
+ isScanning(): Promise<boolean>;
6
+ initialize(config: Object): Promise<string>;
7
+ requestNotificationPermissions(): Promise<string>;
8
+ getDebugLogs(): Promise<string>;
9
+ clearDebugLogs(): Promise<string>;
10
+ setDebounceInterval(interval: number): Promise<string>;
11
+ clearDebounceCache(): Promise<string>;
12
+ getDebounceStatus(): Promise<Object>;
13
+ addListener(eventName: string): void;
14
+ removeListeners(count: number): void;
15
+ }
16
+ declare const _default: Spec;
17
+ export default _default;
18
+ //# sourceMappingURL=NativeSpotnySdk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NativeSpotnySdk.d.ts","sourceRoot":"","sources":["../../../../../IP_Submission/01_SDK/src/NativeSpotnySdk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAErE,MAAM,WAAW,IAAK,SAAQ,WAAW;IAEvC,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAChC,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/B,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAG/B,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAG5C,8BAA8B,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAGlD,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAChC,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAGlC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACvD,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IACtC,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAGrC,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;;AAED,wBAAmE"}
@@ -0,0 +1,91 @@
1
+ export declare const SpotnyEvents: {
2
+ readonly ON_BEACONS_RANGED: "onBeaconsRanged";
3
+ readonly ON_BEACON_REGION_EVENT: "onBeaconRegionEvent";
4
+ };
5
+ export type BeaconData = {
6
+ uuid: string;
7
+ major: number;
8
+ minor: number;
9
+ /** Estimated distance in metres */
10
+ distance: number;
11
+ rssi: number;
12
+ /** 'immediate' | 'near' | 'far' | 'unknown' */
13
+ proximity: string;
14
+ };
15
+ export type BeaconRangedEvent = {
16
+ beacons: BeaconData[];
17
+ region: string;
18
+ };
19
+ export type BeaconRegionEvent = {
20
+ region: string;
21
+ /** 'enter' | 'exit' | 'determined' */
22
+ event: 'enter' | 'exit' | 'determined';
23
+ state?: 'inside' | 'outside' | 'unknown';
24
+ };
25
+ export type SpotnySdkConfig = {
26
+ /**
27
+ * SDK token issued by Spotny for your app.
28
+ * Sent to the backend during initialize() to obtain a session JWT. Required.
29
+ */
30
+ token: string;
31
+ /**
32
+ * API key identifying your brand or app (e.g. 'nike').
33
+ * Sent to the backend during initialize() alongside the token. Required.
34
+ */
35
+ apiKey: string;
36
+ /**
37
+ * Unique identifier for the authenticated user (e.g. database UUID, hashed email).
38
+ * Embedded in the JWT so all tracking events are tied to this user. Required.
39
+ */
40
+ identifierId: string;
41
+ /** Maximum BLE detection distance in metres (default: 8.0) */
42
+ maxDetectionDistance?: number;
43
+ /**
44
+ * Multiplier applied to raw RSSI-derived distance to compensate for device
45
+ * TX power variance (default: 0.5, tuned for Kontakt.io -12 dBm beacons).
46
+ */
47
+ distanceCorrectionFactor?: number;
48
+ /**
49
+ * When `true`, full API response bodies (status + JSON) are printed to the
50
+ * console for every SDK network call. Useful for diagnosing backend errors.
51
+ * Default: `false`.
52
+ */
53
+ debug?: boolean;
54
+ /** @internal Owner-only: override the backend URL for local API debugging. */
55
+ superDebugConfig?: {
56
+ backendURL: string;
57
+ };
58
+ };
59
+ /** Start beacon scanning. */
60
+ export declare function startScanner(): Promise<string>;
61
+ /** Stop beacon scanning and clean up all state. */
62
+ export declare function stopScanner(): Promise<string>;
63
+ /** Returns `true` if the SDK is currently scanning. */
64
+ export declare function isScanning(): Promise<boolean>;
65
+ /**
66
+ * Initialize the SDK. Must be called **before** any other SDK function.
67
+ */
68
+ export declare function initialize(config: SpotnySdkConfig): Promise<string>;
69
+ /** (iOS) Prompt the user for local-notification permissions. */
70
+ export declare function requestNotificationPermissions(): Promise<string>;
71
+ /** Read the on-device debug log file. */
72
+ export declare function getDebugLogs(): Promise<string>;
73
+ /** Delete the on-device debug log file. */
74
+ export declare function clearDebugLogs(): Promise<string>;
75
+ /** Override the proximity-event debounce interval (seconds). */
76
+ export declare function setDebounceInterval(interval: number): Promise<string>;
77
+ /** Clear the debounce / cooldown cache for all beacons. */
78
+ export declare function clearDebounceCache(): Promise<string>;
79
+ /** Return the current debounce status for all tracked beacons. */
80
+ export declare function getDebounceStatus(): Promise<Object>;
81
+ /**
82
+ * Subscribe to continuous ranging updates.
83
+ * The callback fires roughly every second while beacons are in range.
84
+ */
85
+ export declare function addBeaconsRangedListener(callback: (event: BeaconRangedEvent) => void): import("react-native").EventSubscription;
86
+ /**
87
+ * Subscribe to region enter/exit events.
88
+ * These fire in all app states (foreground, background, terminated on iOS).
89
+ */
90
+ export declare function addBeaconRegionListener(callback: (event: BeaconRegionEvent) => void): import("react-native").EventSubscription;
91
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../IP_Submission/01_SDK/src/index.tsx"],"names":[],"mappings":"AAIA,eAAO,MAAM,YAAY;;;CAGf,CAAC;AAIX,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,YAAY,CAAC;IACvC,KAAK,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;CAC1C,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;OAGG;IACH,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,8EAA8E;IAC9E,gBAAgB,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3C,CAAC;AAOF,6BAA6B;AAC7B,wBAAgB,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAE9C;AAED,mDAAmD;AACnD,wBAAgB,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAE7C;AAED,uDAAuD;AACvD,wBAAgB,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC,CAE7C;AAID;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAEnE;AAID,gEAAgE;AAChE,wBAAgB,8BAA8B,IAAI,OAAO,CAAC,MAAM,CAAC,CAEhE;AAID,yCAAyC;AACzC,wBAAgB,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAE9C;AAED,2CAA2C;AAC3C,wBAAgB,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAEhD;AAID,gEAAgE;AAChE,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAErE;AAED,2DAA2D;AAC3D,wBAAgB,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,CAEpD;AAED,kEAAkE;AAClE,wBAAgB,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC,CAEnD;AAID;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,4CAM7C;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,4CAM7C"}
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../../../../IP_Submission/01_SDK/src/index.test.tsx"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spotny-sdk",
3
- "version": "1.0.29",
3
+ "version": "1.0.31",
4
4
  "description": "Beacon Scanner",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",