@amplifyup/sdk 0.1.0 → 0.1.2

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/README.md CHANGED
@@ -4,7 +4,28 @@ AmplifyUp Tracking SDK - CDP-agnostic event tracking library.
4
4
 
5
5
  ## Overview
6
6
 
7
- This SDK provides event tracking that sends events directly to AWS API Gateway. All URLs are hardcoded in the SDK - no configuration needed except `trackingId`.
7
+ This SDK provides event tracking and personalization against AmplifyUp backends.
8
+ Configure a `trackingId`, and optionally a `target` for which environment to use.
9
+
10
+ ## Environment targets
11
+
12
+ Two environments — `local` and `production`. Legacy `dev` maps to `local`.
13
+
14
+ | Target | Layouts / config (Neon) | Events + personalize |
15
+ |--------|-------------------------|----------------------|
16
+ | `local` | `NEXT_PUBLIC_ORCHESTRATOR_URL` (e.g. `http://localhost:5001`) | `https://api-dev.amplifyup.ai` (AWS development) |
17
+ | `production` | `https://amplifyup.ai` | `https://api.amplifyup.ai` |
18
+
19
+ ```bash
20
+ # Demo on http://localhost:5000 — pages from local Neon, events to AWS-dev
21
+ NEXT_PUBLIC_ORCHESTRATOR_URL=http://localhost:5001
22
+ NEXT_PUBLIC_AMPLIFYUP_TARGET=local
23
+
24
+ # Optional: override AWS API base used by local (default api-dev)
25
+ # NEXT_PUBLIC_AMPLIFYUP_API_URL=https://api-dev.amplifyup.ai
26
+ ```
27
+
28
+ Check active URLs in the browser: `AmplifyUp.getStatus()`
8
29
 
9
30
  ## Installation
10
31
 
@@ -19,10 +40,9 @@ npm install @amplifyup/sdk
19
40
  ```typescript
20
41
  import { init } from '@amplifyup/sdk';
21
42
 
22
- // Initialize the SDK (URLs are hardcoded)
23
43
  await init({
24
44
  trackingId: 'your-tracking-id',
25
- debug: true, // Optional, enables debug logging
45
+ debug: true,
26
46
  });
27
47
  ```
28
48
 
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
- import { P as PageConfig } from './types-B9nHG2Cl.mjs';
3
+ import { P as PageConfig } from './types-Xv9P55Dj.mjs';
4
4
 
5
5
  interface AmplifyRendererProps {
6
6
  /**
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
- import { P as PageConfig } from './types-B9nHG2Cl.js';
3
+ import { P as PageConfig } from './types-Xv9P55Dj.js';
4
4
 
5
5
  interface AmplifyRendererProps {
6
6
  /**
@@ -1,3 +1,4 @@
1
+ 'use client';
1
2
  'use strict';
2
3
 
3
4
  var react = require('react');
@@ -178,6 +179,16 @@ var AWSAdapter = class {
178
179
  // src/storage.ts
179
180
  var INSTANCE_ID_KEY = "amplifyup_instance_id";
180
181
  var USER_ID_KEY = "amplifyup_user_id";
182
+ function generateGuid() {
183
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
184
+ return crypto.randomUUID();
185
+ }
186
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
187
+ const r = Math.random() * 16 | 0;
188
+ const v = c === "x" ? r : r & 3 | 8;
189
+ return v.toString(16);
190
+ });
191
+ }
181
192
  function getInstanceId() {
182
193
  if (typeof window === "undefined") {
183
194
  return "";
@@ -186,7 +197,7 @@ function getInstanceId() {
186
197
  if (stored) {
187
198
  return stored;
188
199
  }
189
- const instanceId = `anon_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
200
+ const instanceId = `browser_${generateGuid()}`;
190
201
  localStorage.setItem(INSTANCE_ID_KEY, instanceId);
191
202
  return instanceId;
192
203
  }
@@ -210,9 +221,69 @@ function clearIds() {
210
221
  localStorage.removeItem(USER_ID_KEY);
211
222
  }
212
223
 
224
+ // src/targets.ts
225
+ var AWS_DEV_API = "https://api-dev.amplifyup.ai";
226
+ var AWS_PROD_API = "https://api.amplifyup.ai";
227
+ var PROD_ORCHESTRATOR = "https://amplifyup.ai";
228
+ function isAmplifyUpTarget(value) {
229
+ return value === "local" || value === "dev" || value === "production";
230
+ }
231
+ function normalizeAmplifyUpTarget(value) {
232
+ return value === "dev" ? "local" : value;
233
+ }
234
+ function resolveAmplifyUpTarget(options) {
235
+ if (options?.configTarget && isAmplifyUpTarget(options.configTarget)) {
236
+ return normalizeAmplifyUpTarget(options.configTarget);
237
+ }
238
+ if (options?.configDev === true) {
239
+ return "local";
240
+ }
241
+ const envTarget = typeof process !== "undefined" ? process.env.NEXT_PUBLIC_AMPLIFYUP_TARGET : void 0;
242
+ if (isAmplifyUpTarget(envTarget)) {
243
+ return normalizeAmplifyUpTarget(envTarget);
244
+ }
245
+ if (typeof window !== "undefined") {
246
+ const host = window.location.hostname;
247
+ if (host === "localhost" || host === "127.0.0.1") {
248
+ return "local";
249
+ }
250
+ }
251
+ return "production";
252
+ }
253
+ function localOrchestratorUrl() {
254
+ const fromEnv = typeof process !== "undefined" ? process.env.NEXT_PUBLIC_ORCHESTRATOR_URL : void 0;
255
+ return (fromEnv || "http://localhost:5001").replace(/\/$/, "");
256
+ }
257
+ function localAwsApiUrl() {
258
+ const fromEnv = typeof process !== "undefined" ? process.env.NEXT_PUBLIC_AMPLIFYUP_API_URL : void 0;
259
+ return (fromEnv || AWS_DEV_API).replace(/\/$/, "");
260
+ }
261
+ function resolveAmplifyUpUrls(target) {
262
+ if (target === "local") {
263
+ const orchestratorUrl2 = localOrchestratorUrl();
264
+ const apiGatewayUrl = localAwsApiUrl();
265
+ return {
266
+ target: "local",
267
+ // Layouts / site config / composer APIs → local orchestrator + Neon
268
+ orchestratorUrl: orchestratorUrl2,
269
+ // Events + personalize → AWS development stack
270
+ apiGatewayUrl,
271
+ decisionApiUrl: `${apiGatewayUrl}/v1/personalize`
272
+ };
273
+ }
274
+ const resolvedApi = typeof process !== "undefined" && process.env.NEXT_PUBLIC_AMPLIFYUP_API_URL?.replace(/\/$/, "") || AWS_PROD_API;
275
+ const orchestratorFromEnv = typeof process !== "undefined" ? process.env.NEXT_PUBLIC_ORCHESTRATOR_URL : void 0;
276
+ const isLocalOrchestrator = !!orchestratorFromEnv && (orchestratorFromEnv.includes("localhost") || orchestratorFromEnv.includes("127.0.0.1"));
277
+ const orchestratorUrl = isLocalOrchestrator || !orchestratorFromEnv ? PROD_ORCHESTRATOR : orchestratorFromEnv.replace(/\/$/, "");
278
+ return {
279
+ target: "production",
280
+ apiGatewayUrl: resolvedApi,
281
+ orchestratorUrl,
282
+ decisionApiUrl: `${resolvedApi}/v1/personalize`
283
+ };
284
+ }
285
+
213
286
  // src/index.ts
214
- var PROD_API_URL = "https://api.amplifyup.ai" ;
215
- var PROD_ORCHESTRATOR_URL = "https://amplifyup.ai" ;
216
287
  var AmplifyUpSDK = class {
217
288
  constructor(adapter) {
218
289
  this.config = null;
@@ -220,7 +291,12 @@ var AmplifyUpSDK = class {
220
291
  this.apiGatewayUrl = "";
221
292
  this.orchestratorUrl = "";
222
293
  this.decisionApiUrl = "";
294
+ this.target = "local";
223
295
  this.initialized = false;
296
+ /** Prevents overlapping init() from React Strict Mode double-mount */
297
+ this.initPromise = null;
298
+ /** Ensures auto page() on init fires once per page load */
299
+ this.initialPageSent = false;
224
300
  this.highlightingEnabled = false;
225
301
  this.componentRegistry = [];
226
302
  this.messageListener = null;
@@ -303,46 +379,41 @@ var AmplifyUpSDK = class {
303
379
  }
304
380
  return false;
305
381
  }
306
- /**
307
- * Get production URLs
308
- *
309
- * URLs are baked in at build time via tsup.config.ts
310
- *
311
- * API Gateway endpoints:
312
- * - /v1/track - Event tracking (ingestion)
313
- * - /v1/page - Page view tracking (ingestion)
314
- * - /v1/personalize - Decision engine (personalization)
315
- */
316
- getProductionUrls() {
317
- return {
318
- apiGatewayUrl: PROD_API_URL,
319
- orchestratorUrl: PROD_ORCHESTRATOR_URL,
320
- decisionApiUrl: `${PROD_API_URL}/v1/personalize`
321
- };
322
- }
323
382
  /**
324
383
  * Initialize the SDK
325
- * Automatically reads env vars and sets up tracking
384
+ * Resolves local | dev | production targets for ingestion + personalization URLs.
326
385
  */
327
386
  async init(config) {
387
+ if (this.initialized && this.adapter?.isInitialized()) {
388
+ return;
389
+ }
390
+ if (this.initPromise) {
391
+ return this.initPromise;
392
+ }
393
+ this.initPromise = this.performInit(config);
394
+ try {
395
+ await this.initPromise;
396
+ } finally {
397
+ this.initPromise = null;
398
+ }
399
+ }
400
+ async performInit(config) {
328
401
  if (!this.adapter) {
329
402
  this.adapter = new AWSAdapter();
330
403
  }
331
- const isLocalhost = typeof window !== "undefined" && (window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1");
332
- if (isLocalhost || config.dev === true) {
333
- this.apiGatewayUrl = "http://localhost:5001/api";
334
- this.orchestratorUrl = "http://localhost:5001";
335
- this.decisionApiUrl = "http://localhost:5001/api/v1/personalize";
336
- } else {
337
- const urls = this.getProductionUrls();
338
- this.apiGatewayUrl = urls.apiGatewayUrl;
339
- this.orchestratorUrl = urls.orchestratorUrl;
340
- this.decisionApiUrl = urls.decisionApiUrl;
341
- }
404
+ this.target = resolveAmplifyUpTarget({
405
+ configTarget: config.target,
406
+ configDev: config.dev
407
+ });
408
+ const urls = resolveAmplifyUpUrls(this.target);
409
+ this.apiGatewayUrl = urls.apiGatewayUrl;
410
+ this.orchestratorUrl = urls.orchestratorUrl;
411
+ this.decisionApiUrl = urls.decisionApiUrl;
342
412
  this.config = {
343
413
  trackingId: config.trackingId,
344
414
  debug: config.debug ?? true,
345
415
  // Enable debug by default
416
+ target: this.target,
346
417
  dev: config.dev
347
418
  };
348
419
  try {
@@ -359,6 +430,7 @@ var AmplifyUpSDK = class {
359
430
  getInstanceId: () => this.getInstanceId(),
360
431
  getUserId: () => this.getUserId(),
361
432
  getTrackingId: () => this.getTrackingId(),
433
+ getTarget: () => this.getTarget(),
362
434
  getDiagnostics: () => this.getDiagnostics(),
363
435
  getStatus: () => {
364
436
  console.log(this.getStatus());
@@ -379,7 +451,7 @@ var AmplifyUpSDK = class {
379
451
  };
380
452
  if (this.config?.debug) {
381
453
  console.log("AmplifyUp SDK: Diagnostic methods available on window.AmplifyUp");
382
- console.log("Try: AmplifyUp.getStatus() or AmplifyUp.verifyAWSConnection()");
454
+ console.log("Try: AmplifyUp.getStatus() or AmplifyUp.testTracking()");
383
455
  }
384
456
  }
385
457
  this.clearTrackingIntervals();
@@ -391,11 +463,20 @@ var AmplifyUpSDK = class {
391
463
  if (this.isPreviewMode()) {
392
464
  return;
393
465
  }
394
- const url = window.location.pathname;
395
- this.page(url);
466
+ if (!this.initialPageSent) {
467
+ this.initialPageSent = true;
468
+ const url = window.location.pathname;
469
+ this.page(url);
470
+ }
396
471
  }
397
472
  if (this.config?.debug && this.initialized) {
398
- console.log("AmplifyUp SDK: Initialized successfully", { trackingId: config.trackingId });
473
+ console.log("AmplifyUp SDK: Initialized successfully", {
474
+ trackingId: config.trackingId,
475
+ target: this.target,
476
+ apiGatewayUrl: this.apiGatewayUrl,
477
+ orchestratorUrl: this.orchestratorUrl,
478
+ decisionApiUrl: this.decisionApiUrl || "(orchestrator fallback)"
479
+ });
399
480
  }
400
481
  } catch (error) {
401
482
  console.error("AmplifyUp SDK: Initialization failed", error);
@@ -596,6 +677,7 @@ var AmplifyUpSDK = class {
596
677
  instanceId,
597
678
  userId,
598
679
  trackingId: this.config?.trackingId,
680
+ target: this.target,
599
681
  config: {
600
682
  apiGatewayUrl: this.apiGatewayUrl,
601
683
  decisionApiUrl: this.decisionApiUrl,
@@ -604,6 +686,9 @@ var AmplifyUpSDK = class {
604
686
  }
605
687
  };
606
688
  }
689
+ getTarget() {
690
+ return this.target;
691
+ }
607
692
  /**
608
693
  * Test tracking by sending a test event
609
694
  */
@@ -661,6 +746,7 @@ var AmplifyUpSDK = class {
661
746
  AmplifyUp SDK Status:
662
747
  \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
663
748
  Initialized: ${diag.initialized ? "\u2705 Yes" : "\u274C No"}
749
+ Target: ${diag.target}
664
750
  Instance ID: ${diag.instanceId}
665
751
  User ID: ${diag.userId || "Not identified"}
666
752
  Tracking ID: ${diag.trackingId || "Not set"}
@@ -672,11 +758,11 @@ Config:
672
758
  API Gateway: ${this.apiGatewayUrl || "Not set (required)"}
673
759
  Decision API: ${this.decisionApiUrl || "Not set (using Orchestrator fallback)"}
674
760
  Orchestrator: ${this.orchestratorUrl || "Not set"}
675
- Debug: ${diag.config.debug ? "Enabled" : "Disabled"}
676
761
 
677
762
  Available Console Commands:
678
763
  AmplifyUp.getStatus() - Show this status
679
764
  AmplifyUp.getDiagnostics() - Get full diagnostic object
765
+ AmplifyUp.getTarget() - Current environment target
680
766
  AmplifyUp.getInstanceId() - Get instance ID (browser/session ID)
681
767
  AmplifyUp.getUserId() - Get user ID if identified
682
768
  AmplifyUp.testTracking() - Send a test event