@namiml/sdk-core 3.4.0-dev.202605180118 → 3.4.0-dev.202605190129

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.cjs CHANGED
@@ -98,7 +98,7 @@ const {
98
98
  // version — stamped by scripts/version.sh
99
99
  NAMI_SDK_VERSION: exports.NAMI_SDK_VERSION = "3.4.0",
100
100
  // full package version including dev suffix — stamped by scripts/version.sh
101
- NAMI_SDK_PACKAGE_VERSION: exports.NAMI_SDK_PACKAGE_VERSION = "3.4.0-dev.202605180118",
101
+ NAMI_SDK_PACKAGE_VERSION: exports.NAMI_SDK_PACKAGE_VERSION = "3.4.0-dev.202605190129",
102
102
  // environments
103
103
  PRODUCTION: exports.PRODUCTION = "production", DEVELOPMENT: exports.DEVELOPMENT = "development",
104
104
  // error messages
@@ -7404,19 +7404,34 @@ const mapAnonymousCampaigns = (campaigns, splitPosition, formFactor) => {
7404
7404
  });
7405
7405
  };
7406
7406
  /**
7407
+ * Returns the combined list of API + initial-config campaigns for the current device's
7408
+ * form factor, deduplicated by (type, value) with API entries winning on collision.
7407
7409
  *
7408
- * @returns A combined list of unique campaigns based on both API and Initial, filtered by form factor.
7409
- * This is used to get all campaigns that are applicable to the current device.
7410
+ * Mirrors NamiCampaignManager.allCampaigns() on Apple (Set keyed on hash(value, type))
7411
+ * and Android (.distinct() with server-first ordering). Keying on (type, value) rather
7412
+ * than rule UUID — ensures the same logical placement does not surface twice when the
7413
+ * server has republished a campaign under a new rule id.
7410
7414
  *
7411
- * Note: Since this function returns a unique list of campaigns, and API campaigns take precedence,
7412
- * there may be times when API campaigns are returned that do not yet have paywalls but initial campaigns would.
7415
+ * Note: this list reflects which placements are available, not whether they are launchable.
7416
+ * An API entry surfaced here may reference a paywall that has not yet been published in the
7417
+ * API response. NamiCampaignManager.launch() handles that case independently via
7418
+ * getPaywallDataFromLabel(), which falls back to the initial-config (campaign, paywall) pair
7419
+ * when the API pair is incomplete — matching the merged-paywall-lookup behavior on
7420
+ * Apple and Android.
7413
7421
  */
7414
7422
  const allCampaigns = () => {
7415
7423
  const apiCampaigns = storageService.getCampaignRules(exports.API_CAMPAIGN_RULES) ?? [];
7416
7424
  const initialCampaigns = storageService.getCampaignRules(exports.INITIAL_CAMPAIGN_RULES) ?? [];
7417
7425
  const formFactor = getDeviceFormFactor();
7418
7426
  const campaigns = compact([...apiCampaigns, ...initialCampaigns]).filter((cRule) => cRule.form_factors?.some((f) => f.form_factor === formFactor));
7419
- return uniqBy(campaigns, "rule");
7427
+ const seen = new Set();
7428
+ return campaigns.filter((c) => {
7429
+ const key = `${c.type ?? ''}::${c.value ?? ''}`;
7430
+ if (seen.has(key))
7431
+ return false;
7432
+ seen.add(key);
7433
+ return true;
7434
+ });
7420
7435
  };
7421
7436
  /**
7422
7437
  * Get campaigns by rule key, filtered by form factor.
package/dist/index.d.ts CHANGED
@@ -2751,12 +2751,20 @@ declare const bestUrlCampaignMatch: (incomingUrl: string, campaigns: NamiCampaig
2751
2751
  declare const selectSegment: (segments: NamiCampaignSegment[], splitPosition: number) => NamiCampaignSegment;
2752
2752
  declare const mapAnonymousCampaigns: (campaigns: NamiAnonymousCampaign[], splitPosition: number, formFactor?: TDevice) => NamiCampaign[];
2753
2753
  /**
2754
+ * Returns the combined list of API + initial-config campaigns for the current device's
2755
+ * form factor, deduplicated by (type, value) with API entries winning on collision.
2754
2756
  *
2755
- * @returns A combined list of unique campaigns based on both API and Initial, filtered by form factor.
2756
- * This is used to get all campaigns that are applicable to the current device.
2757
+ * Mirrors NamiCampaignManager.allCampaigns() on Apple (Set keyed on hash(value, type))
2758
+ * and Android (.distinct() with server-first ordering). Keying on (type, value) rather
2759
+ * than rule UUID — ensures the same logical placement does not surface twice when the
2760
+ * server has republished a campaign under a new rule id.
2757
2761
  *
2758
- * Note: Since this function returns a unique list of campaigns, and API campaigns take precedence,
2759
- * there may be times when API campaigns are returned that do not yet have paywalls but initial campaigns would.
2762
+ * Note: this list reflects which placements are available, not whether they are launchable.
2763
+ * An API entry surfaced here may reference a paywall that has not yet been published in the
2764
+ * API response. NamiCampaignManager.launch() handles that case independently via
2765
+ * getPaywallDataFromLabel(), which falls back to the initial-config (campaign, paywall) pair
2766
+ * when the API pair is incomplete — matching the merged-paywall-lookup behavior on
2767
+ * Apple and Android.
2760
2768
  */
2761
2769
  declare const allCampaigns: () => NamiCampaign[];
2762
2770
  declare const getInitialCampaigns: () => NamiCampaign[];
package/dist/index.mjs CHANGED
@@ -96,7 +96,7 @@ const {
96
96
  // version — stamped by scripts/version.sh
97
97
  NAMI_SDK_VERSION = "3.4.0",
98
98
  // full package version including dev suffix — stamped by scripts/version.sh
99
- NAMI_SDK_PACKAGE_VERSION = "3.4.0-dev.202605180118",
99
+ NAMI_SDK_PACKAGE_VERSION = "3.4.0-dev.202605190129",
100
100
  // environments
101
101
  PRODUCTION = "production", DEVELOPMENT = "development",
102
102
  // error messages
@@ -7402,19 +7402,34 @@ const mapAnonymousCampaigns = (campaigns, splitPosition, formFactor) => {
7402
7402
  });
7403
7403
  };
7404
7404
  /**
7405
+ * Returns the combined list of API + initial-config campaigns for the current device's
7406
+ * form factor, deduplicated by (type, value) with API entries winning on collision.
7405
7407
  *
7406
- * @returns A combined list of unique campaigns based on both API and Initial, filtered by form factor.
7407
- * This is used to get all campaigns that are applicable to the current device.
7408
+ * Mirrors NamiCampaignManager.allCampaigns() on Apple (Set keyed on hash(value, type))
7409
+ * and Android (.distinct() with server-first ordering). Keying on (type, value) rather
7410
+ * than rule UUID — ensures the same logical placement does not surface twice when the
7411
+ * server has republished a campaign under a new rule id.
7408
7412
  *
7409
- * Note: Since this function returns a unique list of campaigns, and API campaigns take precedence,
7410
- * there may be times when API campaigns are returned that do not yet have paywalls but initial campaigns would.
7413
+ * Note: this list reflects which placements are available, not whether they are launchable.
7414
+ * An API entry surfaced here may reference a paywall that has not yet been published in the
7415
+ * API response. NamiCampaignManager.launch() handles that case independently via
7416
+ * getPaywallDataFromLabel(), which falls back to the initial-config (campaign, paywall) pair
7417
+ * when the API pair is incomplete — matching the merged-paywall-lookup behavior on
7418
+ * Apple and Android.
7411
7419
  */
7412
7420
  const allCampaigns = () => {
7413
7421
  const apiCampaigns = storageService.getCampaignRules(API_CAMPAIGN_RULES) ?? [];
7414
7422
  const initialCampaigns = storageService.getCampaignRules(INITIAL_CAMPAIGN_RULES) ?? [];
7415
7423
  const formFactor = getDeviceFormFactor();
7416
7424
  const campaigns = compact([...apiCampaigns, ...initialCampaigns]).filter((cRule) => cRule.form_factors?.some((f) => f.form_factor === formFactor));
7417
- return uniqBy(campaigns, "rule");
7425
+ const seen = new Set();
7426
+ return campaigns.filter((c) => {
7427
+ const key = `${c.type ?? ''}::${c.value ?? ''}`;
7428
+ if (seen.has(key))
7429
+ return false;
7430
+ seen.add(key);
7431
+ return true;
7432
+ });
7418
7433
  };
7419
7434
  /**
7420
7435
  * Get campaigns by rule key, filtered by form factor.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@namiml/sdk-core",
3
- "version": "3.4.0-dev.202605180118",
3
+ "version": "3.4.0-dev.202605190129",
4
4
  "description": "Platform-agnostic core for the Nami SDK — business logic, API, types, and state management",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",