@adstage/web-sdk 3.0.10 โ†’ 3.0.11

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adstage/web-sdk",
3
- "version": "3.0.10",
3
+ "version": "3.0.11",
4
4
  "description": "AdStage Web SDK - Production-ready marketing platform SDK with React Provider support for seamless integration",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs.js",
@@ -78,9 +78,41 @@ export class AdStage {
78
78
  console.log('๐Ÿ“Š Tracking parameters captured:', trackingParams);
79
79
  }
80
80
 
81
- // ๏ฟฝ ์„œ๋ฒ„์— Attribution ์ž๋™ ๋“ฑ๋ก (ํด๋ฆญ ID๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ)
82
- if (trackingParams && TrackingParamsModule.hasClickId()) {
83
- setTimeout(async () => {
81
+ // ๐Ÿ”Ž ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ๋‹จ๊ณ„์—์„œ ์ „๋‹ฌ๋œ attributionId(attribution_id) ์šฐ์„  ์‚ฌ์šฉ
82
+ const aidFromUrl = (() => {
83
+ try {
84
+ const search = new URLSearchParams(window.location.search);
85
+ const hash = new URLSearchParams((window.location.hash || '').replace(/^#/, ''));
86
+ return search.get('attribution_id') || hash.get('attribution_id');
87
+ } catch {
88
+ return null;
89
+ }
90
+ })();
91
+
92
+ if (aidFromUrl) {
93
+ try {
94
+ localStorage.setItem('adstage_attribution_id', aidFromUrl);
95
+ if (config.debug) {
96
+ console.log('๐Ÿ”— Using attributionId from URL (attribution_id):', aidFromUrl);
97
+ }
98
+ } catch (_) {
99
+ // no-op: storage might be unavailable in some contexts
100
+ }
101
+ }
102
+
103
+ // ๐ŸŽฏ Click ์ด๋ฒคํŠธ ์ž๋™ ์ „์†ก (์ƒˆ๋กœ์šด ํด๋ฆญ ID ๋ฐœ๊ฒฌ ์‹œ)
104
+ const shouldSend = TrackingParamsModule.shouldSendClickEvent();
105
+ if (config.debug) {
106
+ console.log('๐Ÿ” Should send click event:', shouldSend);
107
+ if (!shouldSend) {
108
+ console.log('โญ๏ธ Skipping click event (duplicate or no click ID)');
109
+ }
110
+ }
111
+
112
+ // ๏ฟฝ ์„œ๋ฒ„์— Attribution ์ž๋™ ๋“ฑ๋ก (ํด๋ฆญ ID๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ, ๋‹จ URL๋กœ ์ด๋ฏธ ์ „๋‹ฌ๋œ ๊ฒฝ์šฐ๋Š” ์ƒ๋žต)
113
+ if (!aidFromUrl && trackingParams && TrackingParamsModule.hasClickId()) {
114
+ // Attribution ๋“ฑ๋ก์„ Promise๋กœ ์ฒ˜๋ฆฌ
115
+ const attributionPromise = (async () => {
84
116
  try {
85
117
  // Device ID ์ƒ์„ฑ (๋ธŒ๋ผ์šฐ์ € fingerprint ๋˜๋Š” ๋žœ๋ค)
86
118
  const deviceId = instance.generateDeviceId();
@@ -95,29 +127,62 @@ export class AdStage {
95
127
  expiresAt: attribution.expiresAt,
96
128
  });
97
129
  }
130
+
131
+ return attribution;
98
132
  } catch (err) {
99
133
  console.error('โŒ Failed to register attribution:', err);
134
+ return null;
100
135
  }
101
- }, 100);
102
- }
103
-
104
- // ๏ฟฝ๐ŸŽฏ Click ์ด๋ฒคํŠธ ์ž๋™ ์ „์†ก (์ƒˆ๋กœ์šด ํด๋ฆญ ID ๋ฐœ๊ฒฌ ์‹œ)
105
- const shouldSend = TrackingParamsModule.shouldSendClickEvent();
106
- if (config.debug) {
107
- console.log('๐Ÿ” Should send click event:', shouldSend);
108
- if (!shouldSend) {
109
- console.log('โญ๏ธ Skipping click event (duplicate or no click ID)');
136
+ })();
137
+
138
+ // Click ์ด๋ฒคํŠธ๋Š” Attribution ๋“ฑ๋ก์ด ์™„๋ฃŒ๋œ ํ›„์—๋งŒ ์ „์†ก
139
+ if (shouldSend) {
140
+ attributionPromise.then((attribution) => {
141
+ try {
142
+ const trackingParams = TrackingParamsModule.get();
143
+ const attributionObj = TrackingParamsModule.toAttributionObject();
144
+
145
+ if (config.debug) {
146
+ console.log('๐ŸŽฏ Sending click event after attribution registration', {
147
+ attributionId: attribution?.attributionId,
148
+ hasAttribution: !!attribution,
149
+ });
150
+ }
151
+
152
+ // Click ์ด๋ฒคํŠธ ์ „์†ก (์ถ”์  ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” EventsModule์—์„œ ์ž๋™ ์ฃผ์ž…)
153
+ instance.events
154
+ .track('click', {
155
+ _autoGenerated: true,
156
+ _source: 'tracking_params',
157
+ _timestamp: new Date().toISOString(),
158
+ _platform: 'web',
159
+ })
160
+ .then(() => {
161
+ TrackingParamsModule.markClickEventSent();
162
+
163
+ if (config.debug) {
164
+ console.log('โœ… Auto-tracked click event with tracking params:', {
165
+ attribution: attributionObj,
166
+ trackingParams,
167
+ });
168
+ }
169
+ })
170
+ .catch((err) => {
171
+ console.error('โŒ Failed to auto-track click event:', err);
172
+ });
173
+ } catch (err) {
174
+ console.error('โŒ Error in click event auto-tracking:', err);
175
+ }
176
+ });
110
177
  }
111
- }
112
-
113
- if (shouldSend) {
114
- // EventsModule ์ดˆ๊ธฐํ™” ์™„๋ฃŒ ๋Œ€๊ธฐ
178
+ } else if (shouldSend) {
179
+ // Attribution ๋“ฑ๋ก์ด ํ•„์š”์—†๋Š” ๊ฒฝ์šฐ (aidFromUrl์ด ์žˆ๊ฑฐ๋‚˜ ํด๋ฆญ ID๊ฐ€ ์—†์Œ)
180
+ // ๊ธฐ์กด ๋ฐฉ์‹๋Œ€๋กœ Click ์ด๋ฒคํŠธ๋งŒ ์ „์†ก
115
181
  setTimeout(() => {
116
182
  try {
117
183
  const trackingParams = TrackingParamsModule.get();
118
184
  const attribution = TrackingParamsModule.toAttributionObject();
119
185
 
120
- // Click ์ด๋ฒคํŠธ ์ „์†ก (์ถ”์  ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” EventsModule์—์„œ ์ž๋™ ์ฃผ์ž…)
121
186
  instance.events
122
187
  .track('click', {
123
188
  _autoGenerated: true,
@@ -141,7 +206,7 @@ export class AdStage {
141
206
  } catch (err) {
142
207
  console.error('โŒ Error in click event auto-tracking:', err);
143
208
  }
144
- }, 200); // Attribution ๋“ฑ๋ก ํ›„ ์‹คํ–‰
209
+ }, 100);
145
210
  }
146
211
  }
147
212
 
@@ -251,9 +251,10 @@ export class EventsModule implements BaseModule {
251
251
  console.log('โœ… Attribution registered:', response);
252
252
  }
253
253
 
254
- // Attribution ID๋ฅผ sessionStorage์— ์ €์žฅ
254
+ // Attribution ID๋ฅผ localStorage + sessionStorage์— ์ €์žฅ (์„ธ์…˜ ์ข…๋ฃŒ ํ›„์—๋„ ์œ ์ง€)
255
255
  if (response.attributionId) {
256
- sessionStorage.setItem('adstage_attribution_id', response.attributionId);
256
+ try { localStorage.setItem('adstage_attribution_id', response.attributionId); } catch (_) {}
257
+ try { sessionStorage.setItem('adstage_attribution_id', response.attributionId); } catch (_) {}
257
258
  }
258
259
 
259
260
  return response;
@@ -265,13 +266,23 @@ export class EventsModule implements BaseModule {
265
266
 
266
267
  /**
267
268
  * ์ €์žฅ๋œ Attribution ID ๋ฐ˜ํ™˜
269
+ * ์šฐ์„ ์ˆœ์œ„: sessionStorage (ํ˜„์žฌ ์„ธ์…˜) > localStorage (์˜์† ์ €์žฅ)
268
270
  */
269
271
  getAttributionId(): string | null {
270
- if (typeof window === 'undefined' || !window.sessionStorage) {
272
+ if (typeof window === 'undefined') {
271
273
  return null;
272
274
  }
273
275
 
274
- return sessionStorage.getItem('adstage_attribution_id');
276
+ try {
277
+ const fromSession = sessionStorage.getItem('adstage_attribution_id');
278
+ if (fromSession) return fromSession;
279
+ } catch (_) {}
280
+
281
+ try {
282
+ return localStorage.getItem('adstage_attribution_id');
283
+ } catch (_) {}
284
+
285
+ return null;
275
286
  }
276
287
 
277
288
  /**
@@ -140,11 +140,11 @@ export class TrackingParamsModule {
140
140
  }
141
141
 
142
142
  /**
143
- * ์ถ”์  ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ sessionStorage์— ์ €์žฅ
144
- * (SPA ํŽ˜์ด์ง€ ์ „ํ™˜ ์‹œ์—๋„ ์œ ์ง€)
143
+ * ์ถ”์  ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ sessionStorage + localStorage์— ์ €์žฅ
144
+ * (SPA ํŽ˜์ด์ง€ ์ „ํ™˜ + ๋ธŒ๋ผ์šฐ์ € ์žฌ์‹œ์ž‘ ์‹œ์—๋„ ์œ ์ง€)
145
145
  */
146
146
  public static store(params: TrackingParams): void {
147
- if (typeof window === 'undefined' || !window.sessionStorage) {
147
+ if (typeof window === 'undefined') {
148
148
  return;
149
149
  }
150
150
 
@@ -152,8 +152,10 @@ export class TrackingParamsModule {
152
152
  // ๊ธฐ์กด ํŒŒ๋ผ๋ฏธํ„ฐ์™€ ๋ณ‘ํ•ฉ (์ƒˆ ํŒŒ๋ผ๋ฏธํ„ฐ ์šฐ์„ )
153
153
  const existing = TrackingParamsModule.get();
154
154
  const merged = { ...existing, ...params };
155
+ const json = JSON.stringify(merged);
155
156
 
156
- sessionStorage.setItem(TrackingParamsModule.STORAGE_KEY, JSON.stringify(merged));
157
+ try { sessionStorage.setItem(TrackingParamsModule.STORAGE_KEY, json); } catch (_) {}
158
+ try { localStorage.setItem(TrackingParamsModule.STORAGE_KEY, json); } catch (_) {}
157
159
  } catch (error) {
158
160
  console.warn('Failed to store tracking params:', error);
159
161
  }
@@ -161,21 +163,23 @@ export class TrackingParamsModule {
161
163
 
162
164
  /**
163
165
  * ์ €์žฅ๋œ ์ถ”์  ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฐ˜ํ™˜
166
+ * ์šฐ์„ ์ˆœ์œ„: sessionStorage (ํ˜„์žฌ ์„ธ์…˜) > localStorage (์˜์† ์ €์žฅ)
164
167
  * EventsModule์—์„œ track() ํ˜ธ์ถœ ์‹œ ์‚ฌ์šฉ๋จ
165
168
  */
166
169
  public static get(): TrackingParams | null {
167
- if (typeof window === 'undefined' || !window.sessionStorage) {
170
+ if (typeof window === 'undefined') {
168
171
  return null;
169
172
  }
170
173
 
171
174
  try {
172
- const stored = sessionStorage.getItem(TrackingParamsModule.STORAGE_KEY);
173
- if (stored) {
174
- return JSON.parse(stored) as TrackingParams;
175
- }
176
- } catch (error) {
177
- console.warn('Failed to retrieve tracking params:', error);
178
- }
175
+ const fromSession = sessionStorage?.getItem(TrackingParamsModule.STORAGE_KEY);
176
+ if (fromSession) return JSON.parse(fromSession) as TrackingParams;
177
+ } catch (_) {}
178
+
179
+ try {
180
+ const fromLocal = localStorage?.getItem(TrackingParamsModule.STORAGE_KEY);
181
+ if (fromLocal) return JSON.parse(fromLocal) as TrackingParams;
182
+ } catch (_) {}
179
183
 
180
184
  return null;
181
185
  }
@@ -184,15 +188,12 @@ export class TrackingParamsModule {
184
188
  * ์ €์žฅ๋œ ์ถ”์  ํŒŒ๋ผ๋ฏธํ„ฐ ์‚ญ์ œ
185
189
  */
186
190
  public static clear(): void {
187
- if (typeof window === 'undefined' || !window.sessionStorage) {
191
+ if (typeof window === 'undefined') {
188
192
  return;
189
193
  }
190
194
 
191
- try {
192
- sessionStorage.removeItem(TrackingParamsModule.STORAGE_KEY);
193
- } catch (error) {
194
- console.warn('Failed to clear tracking params:', error);
195
- }
195
+ try { sessionStorage?.removeItem(TrackingParamsModule.STORAGE_KEY); } catch (_) {}
196
+ try { localStorage?.removeItem(TrackingParamsModule.STORAGE_KEY); } catch (_) {}
196
197
  }
197
198
 
198
199
  /**