@cloudsignal/pwa-sdk 1.2.4 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { isValidUUID } from './chunk-IMM7VF4N.js';
2
- export { generateAuthHeaders, generateHMACSignature, isValidUUID, makeAuthenticatedRequest } from './chunk-IMM7VF4N.js';
1
+ import { isValidUUID } from './chunk-IQHSODT4.js';
2
+ export { generateAuthHeaders, generateHMACSignature, isValidUUID, makeAuthenticatedRequest } from './chunk-IQHSODT4.js';
3
3
 
4
4
  /**
5
5
  * CloudSignal PWA SDK v1.0.0
@@ -934,13 +934,13 @@ function createAuthContext(config) {
934
934
  onTokenExpired: config.onTokenExpired
935
935
  };
936
936
  }
937
- if (!config.organizationSecret) {
938
- throw new Error("Either userToken or organizationSecret is required");
937
+ if (!config.organizationPublishableKey) {
938
+ throw new Error("Either userToken or organizationPublishableKey is required");
939
939
  }
940
940
  return {
941
941
  mode: "hmac",
942
942
  organizationId: config.organizationId,
943
- organizationSecret: config.organizationSecret
943
+ organizationPublishableKey: config.organizationPublishableKey
944
944
  };
945
945
  }
946
946
  async function makeAuthenticatedRequestWithContext(authContext, method, url, body, onTokenExpired) {
@@ -960,13 +960,13 @@ async function makeAuthenticatedRequestWithContext(authContext, method, url, bod
960
960
  body
961
961
  );
962
962
  }
963
- const { makeAuthenticatedRequest: makeAuthenticatedRequest4 } = await import('./hmac-LWLR6F7Z.js');
964
- if (!authContext.organizationSecret) {
965
- throw new Error("organizationSecret required for HMAC auth mode");
963
+ const { makeAuthenticatedRequest: makeAuthenticatedRequest4 } = await import('./hmac-WITZIX2O.js');
964
+ if (!authContext.organizationPublishableKey) {
965
+ throw new Error("organizationPublishableKey required for HMAC auth mode");
966
966
  }
967
967
  return makeAuthenticatedRequest4(
968
968
  authContext.organizationId,
969
- authContext.organizationSecret,
969
+ authContext.organizationPublishableKey,
970
970
  method,
971
971
  url,
972
972
  body
@@ -1244,7 +1244,7 @@ var PushNotificationManager = class {
1244
1244
  this.deviceDetector = new DeviceDetector();
1245
1245
  this.authContext = createAuthContext({
1246
1246
  organizationId: options.organizationId,
1247
- organizationSecret: options.organizationSecret,
1247
+ organizationPublishableKey: options.organizationPublishableKey,
1248
1248
  userToken: options.userToken
1249
1249
  });
1250
1250
  this.onRegistered = options.onRegistered;
@@ -1370,6 +1370,64 @@ var PushNotificationManager = class {
1370
1370
  return null;
1371
1371
  }
1372
1372
  }
1373
+ /**
1374
+ * Register a PWA installation without a push subscription.
1375
+ *
1376
+ * Tracks users who installed the PWA (standalone display mode) but
1377
+ * haven't granted notification permission yet. A subsequent
1378
+ * ``registerForPush()`` call upgrades the same row to a full push
1379
+ * registration (matched server-side by browser fingerprint).
1380
+ *
1381
+ * Guarded by a localStorage flag so repeat ``initialize()`` calls in
1382
+ * the same storage session are no-ops.
1383
+ */
1384
+ async registerInstallation() {
1385
+ try {
1386
+ if (isInstallationRegistered(this.organizationId, this.serviceId)) {
1387
+ this.log("Installation already registered, skipping");
1388
+ return null;
1389
+ }
1390
+ const fingerprint = await generateBrowserFingerprint();
1391
+ const deviceInfo = this.deviceDetector.getDeviceInfo();
1392
+ const platformInfo = this.deviceDetector.getPlatformInfo();
1393
+ const installationData = {
1394
+ service_id: this.serviceId,
1395
+ browser_fingerprint: fingerprint || void 0,
1396
+ device_type: deviceInfo.deviceType,
1397
+ device_model: deviceInfo.deviceModel,
1398
+ browser_name: platformInfo.browser,
1399
+ browser_version: platformInfo.browserVersion,
1400
+ os_name: platformInfo.os,
1401
+ os_version: platformInfo.osVersion,
1402
+ user_agent: platformInfo.userAgent,
1403
+ display_mode: "standalone",
1404
+ is_installed: true,
1405
+ timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
1406
+ language: navigator.language || "en-US"
1407
+ };
1408
+ const url = `${this.serviceUrl}/api/v1/registration/install-only`;
1409
+ const response = await makeAuthenticatedRequestWithContext(
1410
+ this.authContext,
1411
+ "POST",
1412
+ url,
1413
+ installationData,
1414
+ this.onTokenExpired
1415
+ );
1416
+ if (!response.ok) {
1417
+ const errorText = await response.text();
1418
+ throw new Error(`Installation registration failed: ${response.status} - ${errorText}`);
1419
+ }
1420
+ const result = await response.json();
1421
+ markInstallationRegistered(this.organizationId, this.serviceId, result.registration_id);
1422
+ this.log(`Installation registered: ${result.registration_id}`);
1423
+ return { registrationId: result.registration_id };
1424
+ } catch (error) {
1425
+ const err = error instanceof Error ? error : new Error(String(error));
1426
+ this.log(`Installation registration failed: ${err.message}`, "error");
1427
+ this.onError?.(err);
1428
+ return null;
1429
+ }
1430
+ }
1373
1431
  /**
1374
1432
  * Unregister from push notifications
1375
1433
  */
@@ -1483,72 +1541,6 @@ var PushNotificationManager = class {
1483
1541
  return null;
1484
1542
  }
1485
1543
  }
1486
- /**
1487
- * Register PWA installation without push subscription.
1488
- * This tracks users who installed the PWA but haven't subscribed to notifications.
1489
- * Called automatically when installation is detected.
1490
- *
1491
- * @returns Installation registration result or null if already registered/failed
1492
- */
1493
- async registerInstallation() {
1494
- try {
1495
- if (isInstallationRegistered(this.organizationId, this.serviceId)) {
1496
- this.log("Installation already registered, skipping");
1497
- return null;
1498
- }
1499
- const fingerprint = await generateBrowserFingerprint();
1500
- const deviceInfo = this.deviceDetector.getDeviceInfo();
1501
- const platformInfo = this.deviceDetector.getPlatformInfo();
1502
- const installationData = {
1503
- service_id: this.serviceId,
1504
- browser_fingerprint: fingerprint || void 0,
1505
- device_type: deviceInfo.deviceType,
1506
- device_model: deviceInfo.deviceModel,
1507
- browser_name: platformInfo.browser,
1508
- browser_version: platformInfo.browserVersion,
1509
- os_name: platformInfo.os,
1510
- os_version: platformInfo.osVersion,
1511
- user_agent: platformInfo.userAgent,
1512
- display_mode: "standalone",
1513
- is_installed: true,
1514
- timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
1515
- language: navigator.language || "en-US"
1516
- };
1517
- const url = `${this.serviceUrl}/api/v1/registration/install-only`;
1518
- const response = await makeAuthenticatedRequestWithContext(
1519
- this.authContext,
1520
- "POST",
1521
- url,
1522
- installationData,
1523
- this.onTokenExpired
1524
- );
1525
- if (!response.ok) {
1526
- const errorText = await response.text();
1527
- throw new Error(`Installation registration failed: ${response.status} - ${errorText}`);
1528
- }
1529
- const result = await response.json();
1530
- markInstallationRegistered(this.organizationId, this.serviceId, result.registration_id);
1531
- this.log(`Installation registered successfully: ${result.registration_id}`);
1532
- return { registrationId: result.registration_id };
1533
- } catch (error) {
1534
- const err = error instanceof Error ? error : new Error(String(error));
1535
- this.log(`Installation registration failed: ${err.message}`, "error");
1536
- this.onError?.(err);
1537
- return null;
1538
- }
1539
- }
1540
- /**
1541
- * Check if installation is already registered
1542
- */
1543
- isInstallationRegistered() {
1544
- return isInstallationRegistered(this.organizationId, this.serviceId);
1545
- }
1546
- /**
1547
- * Get stored installation registration ID
1548
- */
1549
- getInstallationId() {
1550
- return getStorageItem(`install_id_${this.organizationId}_${this.serviceId}`);
1551
- }
1552
1544
  /**
1553
1545
  * Request notification permission
1554
1546
  */
@@ -1642,7 +1634,7 @@ var HeartbeatManager = class {
1642
1634
  this.onTokenExpired = options.onTokenExpired;
1643
1635
  this.authContext = createAuthContext({
1644
1636
  organizationId: options.organizationId,
1645
- organizationSecret: options.organizationSecret,
1637
+ organizationPublishableKey: options.organizationPublishableKey,
1646
1638
  userToken: options.userToken
1647
1639
  });
1648
1640
  this.config = {
@@ -3079,7 +3071,7 @@ var IOSInstallBanner = class {
3079
3071
 
3080
3072
  // src/CloudSignalPWA.ts
3081
3073
  var DEFAULT_SERVICE_URL = "https://pwa.cloudsignal.app";
3082
- var SDK_VERSION = "1.2.3";
3074
+ var SDK_VERSION = "1.2.0";
3083
3075
  var CloudSignalPWA = class {
3084
3076
  constructor(config) {
3085
3077
  this.initialized = false;
@@ -3093,12 +3085,12 @@ var CloudSignalPWA = class {
3093
3085
  this.config = config;
3094
3086
  this.serviceUrl = config.serviceUrl || DEFAULT_SERVICE_URL;
3095
3087
  this.debug = config.debug ?? false;
3096
- if (!config.organizationSecret && !config.userToken) {
3097
- throw new Error("Either organizationSecret or userToken must be provided");
3088
+ if (!config.organizationPublishableKey && !config.userToken) {
3089
+ throw new Error("Either organizationPublishableKey or userToken must be provided");
3098
3090
  }
3099
3091
  this.authContext = createAuthContext({
3100
3092
  organizationId: config.organizationId,
3101
- organizationSecret: config.organizationSecret,
3093
+ organizationPublishableKey: config.organizationPublishableKey,
3102
3094
  userToken: config.userToken
3103
3095
  });
3104
3096
  this.deviceDetector = new DeviceDetector();
@@ -3119,7 +3111,7 @@ var CloudSignalPWA = class {
3119
3111
  this.pushNotificationManager = new PushNotificationManager({
3120
3112
  serviceUrl: this.serviceUrl,
3121
3113
  organizationId: config.organizationId,
3122
- organizationSecret: config.organizationSecret,
3114
+ organizationPublishableKey: config.organizationPublishableKey,
3123
3115
  userToken: config.userToken,
3124
3116
  onTokenExpired: config.onTokenExpired,
3125
3117
  serviceId: config.serviceId,
@@ -3138,7 +3130,7 @@ var CloudSignalPWA = class {
3138
3130
  this.heartbeatManager = new HeartbeatManager({
3139
3131
  serviceUrl: this.serviceUrl,
3140
3132
  organizationId: config.organizationId,
3141
- organizationSecret: config.organizationSecret,
3133
+ organizationPublishableKey: config.organizationPublishableKey,
3142
3134
  userToken: config.userToken,
3143
3135
  onTokenExpired: config.onTokenExpired,
3144
3136
  config: config.heartbeat,
@@ -3227,10 +3219,9 @@ var CloudSignalPWA = class {
3227
3219
  }
3228
3220
  const installState = this.installationManager.getState();
3229
3221
  if (installState.isInstalled) {
3230
- this.log("PWA installation detected, registering...");
3222
+ this.log("PWA installation detected, registering\u2026");
3231
3223
  const installResult = await this.pushNotificationManager.registerInstallation();
3232
3224
  if (installResult) {
3233
- this.log(`Installation registered: ${installResult.registrationId}`);
3234
3225
  this.emit("install:registered", { registrationId: installResult.registrationId });
3235
3226
  }
3236
3227
  }