@affiliateo/web 4.6.0 → 4.6.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.
Files changed (2) hide show
  1. package/dist/provider.js +26 -5
  2. package/package.json +15 -5
package/dist/provider.js CHANGED
@@ -171,6 +171,23 @@ export function getAttribution() {
171
171
  // mount (host has the call sites) but we can shout in dev so the
172
172
  // mistake is visible.
173
173
  let providerMountCount = 0;
174
+ /**
175
+ * True only when we can SEE that this is a production build.
176
+ *
177
+ * Every bundler (webpack, Vite, Next, Rollup) replaces `process.env.NODE_ENV`
178
+ * with a literal before shipping, which is why reading it works for almost
179
+ * everyone. Someone importing the ESM directly has no `process` at all, and
180
+ * touching it there throws a ReferenceError rather than reading undefined.
181
+ *
182
+ * UNKNOWN COUNTS AS NOT-PRODUCTION, deliberately. The only caller is the
183
+ * double-mount warning, and a double mount double-fires every pageview — which
184
+ * corrupts the merchant's own numbers and the affiliate attribution built on
185
+ * them. One stray console line on an unbundled production page is a smaller
186
+ * cost than silently letting that run.
187
+ */
188
+ function isProductionBuild() {
189
+ return typeof process !== 'undefined' && process?.env?.NODE_ENV === 'production';
190
+ }
174
191
  export function AffiliateoProvider({ appId, campaignId, apiUrl, allowedHostnames, allowLocalhost, allowIframe, allowFileProtocol, debug, flushInterval, maxQueueSize, autoCapturePageviews, children, }) {
175
192
  // Normalize autoCapturePageviews. Three shapes:
176
193
  // - undefined / true / object → auto-capture ON (with object overrides)
@@ -209,10 +226,8 @@ export function AffiliateoProvider({ appId, campaignId, apiUrl, allowedHostnames
209
226
  const log = useCallback((msg, data) => {
210
227
  if (!debug)
211
228
  return;
212
- // eslint-disable-next-line no-console
213
229
  if (data !== undefined)
214
230
  console.log('[Affiliateo] ' + msg, data);
215
- // eslint-disable-next-line no-console
216
231
  else
217
232
  console.log('[Affiliateo] ' + msg);
218
233
  }, [debug]);
@@ -443,7 +458,6 @@ export function AffiliateoProvider({ appId, campaignId, apiUrl, allowedHostnames
443
458
  // Neither appId nor the legacy campaignId alias was passed — nothing to
444
459
  // attribute events to, so stay dormant instead of firing junk.
445
460
  if (!appIdRef.current) {
446
- // eslint-disable-next-line no-console
447
461
  console.error('[Affiliateo] Missing appId — pass your app ID to <AffiliateoProvider appId="...">.');
448
462
  return;
449
463
  }
@@ -451,8 +465,7 @@ export function AffiliateoProvider({ appId, campaignId, apiUrl, allowedHostnames
451
465
  // ever mounted in the page lifetime. Dev-only; production swallows
452
466
  // the warning to avoid noise in real merchant consoles.
453
467
  providerMountCount += 1;
454
- if (providerMountCount > 1 && process.env.NODE_ENV !== 'production') {
455
- // eslint-disable-next-line no-console
468
+ if (providerMountCount > 1 && !isProductionBuild()) {
456
469
  console.warn('[Affiliateo] AffiliateoProvider mounted more than once. Mount it exactly once near the root of your app, or pageviews will double-fire.');
457
470
  }
458
471
  // Client-side bot detection. If the current browser context looks
@@ -952,6 +965,14 @@ export function AffiliateoProvider({ appId, campaignId, apiUrl, allowedHostnames
952
965
  queueRef.current = null;
953
966
  providerMountCount = Math.max(0, providerMountCount - 1);
954
967
  };
968
+ // flushInterval, maxQueueSize, allowFileProtocol and the autoCfg.* fields
969
+ // are BOOT configuration, read once when the queue and listeners are
970
+ // constructed. Listing them would tear the whole pipeline down and rebuild
971
+ // it whenever a host app re-renders with a new inline object, and
972
+ // shutdown() drops the in-memory queue — so honoring the rule here would
973
+ // cost real events. A host that needs different settings should remount
974
+ // the provider.
975
+ // eslint-disable-next-line react-hooks/exhaustive-deps
955
976
  }, [apiBase, allowedHostnames, allowLocalhost, allowIframe, log, track, identify, trackPageview, reset, optOut, optIn, flush]);
956
977
  return (_jsx(AffiliateoContext.Provider, { value: state, children: children }));
957
978
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@affiliateo/web",
3
- "version": "4.6.0",
4
- "description": "Affiliateo web SDK — affiliate attribution and tracking for web apps",
3
+ "version": "4.6.1",
4
+ "description": "Affiliateo web SDK \u2014 affiliate attribution and tracking for web apps",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -14,7 +14,7 @@
14
14
  },
15
15
  "scripts": {
16
16
  "build": "tsc",
17
- "prepublishOnly": "npm run build"
17
+ "prepack": "npm run build"
18
18
  },
19
19
  "peerDependencies": {
20
20
  "react": ">=18.0.0"
@@ -28,7 +28,17 @@
28
28
  "@types/react": "^19.0.0",
29
29
  "typescript": "^5.0.0"
30
30
  },
31
- "keywords": ["affiliateo", "affiliate", "attribution", "stripe", "web", "session", "tracking"],
31
+ "keywords": [
32
+ "affiliateo",
33
+ "affiliate",
34
+ "attribution",
35
+ "stripe",
36
+ "web",
37
+ "session",
38
+ "tracking"
39
+ ],
32
40
  "license": "MIT",
33
- "files": ["dist"]
41
+ "files": [
42
+ "dist"
43
+ ]
34
44
  }