@artstorefronts/arthelper-nav 0.1.0-alpha.6 → 0.1.0-alpha.7

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
@@ -67,8 +67,20 @@ is obviously this app, stop and ask — an id is added by an operator, not by yo
67
67
  Without this, a user who collapsed the bar gets an expanded bar in the first byte and a
68
68
  56px jump after hydration.
69
69
 
70
- 6. **Optionally pass `onAppClick`** to emit your own analytics. The package imports no
71
- analytics library, and one callback covers both the desktop tiles and the mobile dropdown.
70
+ 6. **Pass `onAppClick`** so this app's clicks reach the fleet-wide chart. The package ships
71
+ no analytics SDK — transport, identity and consent stay with you — but it does export the
72
+ event's shape, so use it rather than hand-writing the payload:
73
+
74
+ ```ts
75
+ import { suiteNavClickEvent } from '@artstorefronts/arthelper-nav';
76
+
77
+ onAppClick={(args) => yourTracker.track(...suiteNavClickEvent(args, '<this-app-id>'))}
78
+ ```
79
+
80
+ Hand-writing it is how a satellite ends up sending `app_id` instead of `target_app_id`,
81
+ which does not fail — it silently splits the chart. One callback covers both the desktop
82
+ tiles and the mobile dropdown. If your tracker batches, flush on the way out: a tile is a
83
+ real cross-app `<a href>`, so the document is replaced and a queued batch dies with it.
72
84
 
73
85
  ## `configUrl` — the mistake to avoid
74
86
 
@@ -306,23 +318,37 @@ This is the same derivation both in-monorepo hosts (`client/`, `town-square/`) u
306
318
 
307
319
  ## `onAppClick`: the analytics seam
308
320
 
309
- The package imports no analytics library of any kind. `onAppClick` is the one hook
310
- through which a host wires its own analytics — it fires immediately before navigation,
311
- from **both** the desktop tile row and the mobile dropdown, so one callback covers both
312
- surfaces:
321
+ `onAppClick` fires immediately before navigation, from one shared handler behind both the
322
+ desktop tile row and the mobile dropdown — so it covers both surfaces and cannot
323
+ double-fire.
324
+
325
+ **The package ships no analytics SDK, deliberately.** Bundling one would run a second
326
+ instance alongside yours, racing it on device id and session, and would emit without your
327
+ identity or consent handling — producing clicks that cannot be joined to users. Transport,
328
+ identity and consent are yours.
329
+
330
+ What the package does own is the event's shape, because that is the part that drifts:
313
331
 
314
332
  ```ts
333
+ import { suiteNavClickEvent } from '@artstorefronts/arthelper-nav';
334
+
315
335
  <NavProvider
316
- activeAppId="my-app"
317
336
  configUrl={NAV_CONFIG_URL}
318
- onAppClick={({ app, activeAppId, collapsed }) => {
319
- myAnalytics.track('suite_nav_app_clicked', { targetAppId: app.id, activeAppId, collapsed });
320
- }}
337
+ activeAppId="art-books"
338
+ onAppClick={(args) => amplitude.track(...suiteNavClickEvent(args, 'art_books'))}
321
339
  >
322
340
  ```
323
341
 
324
- Navigation itself happens via a real `<a href>` the browser follows natively —
325
- `onAppClick` never intercepts or prevents it.
342
+ It returns a `[name, properties]` pair, so the two cannot be paired wrongly. Properties are
343
+ `target_app_id` (the app clicked — the dimension click-throughs group on), `source_app`
344
+ (this app, passed in because hosts sharing a product surface share an `activeAppId` and so
345
+ cannot be told apart by it), and `collapsed`.
346
+
347
+ `SUITE_NAV_CLICK_EVENT` is exported too if your tracker needs the name separately.
348
+
349
+ **If your tracker batches, flush on the way out.** A tile is a real cross-app `<a href>`, so
350
+ the document is replaced and a queued batch dies with it — both ArtHelper hosts use their
351
+ tracker's on-exit variant for exactly this reason.
326
352
 
327
353
  ## SSR and the collapsed cookie
328
354
 
@@ -0,0 +1,42 @@
1
+ import type { NavAppClickArgs } from './types.js';
2
+ /**
3
+ * The one spelling of the suite bar's click event.
4
+ *
5
+ * The package deliberately ships no analytics SDK. Bundling one would run a second
6
+ * instance alongside the host's — racing it on device id and session — and would emit
7
+ * without the host's identity or consent handling, producing clicks that cannot be joined
8
+ * to users. Transport, identity and consent stay with the host; only the event's shape
9
+ * lives here.
10
+ *
11
+ * What that leaves is a drift risk, and it is the whole reason this helper exists: a
12
+ * satellite that hand-writes `app_id` instead of `target_app_id`, or renames the event,
13
+ * silently splits the fleet-wide chart rather than failing. Name and properties travel
14
+ * together as one value so the two cannot be paired wrongly.
15
+ */
16
+ declare const SUITE_NAV_CLICK_EVENT = "suite_nav_app_clicked";
17
+ type SuiteNavClickProperties<TSource extends string> = {
18
+ /** Catalog id of the app that was clicked — the dimension click-throughs group on. */
19
+ target_app_id: string;
20
+ /**
21
+ * Which host emitted the click. Passed in rather than read off `activeAppId`, because
22
+ * hosts that are one product surface share an id — ArtHelper's client and town-square
23
+ * both declare `home`, so `activeAppId` cannot tell them apart.
24
+ */
25
+ source_app: TSource;
26
+ /** Whether the bar was collapsed at click time. */
27
+ collapsed: boolean;
28
+ };
29
+ /**
30
+ * Builds the event as a `[name, properties]` pair, ready to spread into a tracker:
31
+ *
32
+ * ```ts
33
+ * onAppClick={(args) => amplitude.track(...suiteNavClickEvent(args, 'art_books'))}
34
+ * ```
35
+ *
36
+ * `TSource` is generic so the literal survives: a host whose tracker types `source_app` as
37
+ * a union of known apps still typechecks, which a widened `string` would not.
38
+ */
39
+ declare function suiteNavClickEvent<TSource extends string>(args: NavAppClickArgs, sourceApp: TSource): [typeof SUITE_NAV_CLICK_EVENT, SuiteNavClickProperties<TSource>];
40
+ export { SUITE_NAV_CLICK_EVENT, suiteNavClickEvent };
41
+ export type { SuiteNavClickProperties };
42
+ //# sourceMappingURL=analytics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../src/analytics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;;;;;;;;;;;;GAaG;AACH,QAAA,MAAM,qBAAqB,0BAA0B,CAAC;AAKtD,KAAK,uBAAuB,CAAC,OAAO,SAAS,MAAM,IAAI;IACrD,sFAAsF;IACtF,aAAa,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,UAAU,EAAE,OAAO,CAAC;IACpB,mDAAmD;IACnD,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF;;;;;;;;;GASG;AACH,iBAAS,kBAAkB,CAAC,OAAO,SAAS,MAAM,EAChD,IAAI,EAAE,eAAe,EACrB,SAAS,EAAE,OAAO,GACjB,CAAC,OAAO,qBAAqB,EAAE,uBAAuB,CAAC,OAAO,CAAC,CAAC,CAElE;AAED,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,CAAC;AACrD,YAAY,EAAE,uBAAuB,EAAE,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * The one spelling of the suite bar's click event.
3
+ *
4
+ * The package deliberately ships no analytics SDK. Bundling one would run a second
5
+ * instance alongside the host's — racing it on device id and session — and would emit
6
+ * without the host's identity or consent handling, producing clicks that cannot be joined
7
+ * to users. Transport, identity and consent stay with the host; only the event's shape
8
+ * lives here.
9
+ *
10
+ * What that leaves is a drift risk, and it is the whole reason this helper exists: a
11
+ * satellite that hand-writes `app_id` instead of `target_app_id`, or renames the event,
12
+ * silently splits the fleet-wide chart rather than failing. Name and properties travel
13
+ * together as one value so the two cannot be paired wrongly.
14
+ */
15
+ const SUITE_NAV_CLICK_EVENT = 'suite_nav_app_clicked';
16
+ /**
17
+ * Builds the event as a `[name, properties]` pair, ready to spread into a tracker:
18
+ *
19
+ * ```ts
20
+ * onAppClick={(args) => amplitude.track(...suiteNavClickEvent(args, 'art_books'))}
21
+ * ```
22
+ *
23
+ * `TSource` is generic so the literal survives: a host whose tracker types `source_app` as
24
+ * a union of known apps still typechecks, which a widened `string` would not.
25
+ */
26
+ function suiteNavClickEvent(args, sourceApp) {
27
+ return [SUITE_NAV_CLICK_EVENT, { target_app_id: args.app.id, source_app: sourceApp, collapsed: args.collapsed }];
28
+ }
29
+ export { SUITE_NAV_CLICK_EVENT, suiteNavClickEvent };
30
+ //# sourceMappingURL=analytics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.js","sourceRoot":"","sources":["../src/analytics.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AACH,MAAM,qBAAqB,GAAG,uBAAuB,CAAC;AAkBtD;;;;;;;;;GASG;AACH,SAAS,kBAAkB,CACzB,IAAqB,EACrB,SAAkB;IAElB,OAAO,CAAC,qBAAqB,EAAE,EAAE,aAAa,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;AACnH,CAAC;AAED,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export { SUITE_NAV_CLICK_EVENT, suiteNavClickEvent } from './analytics.js';
1
2
  export { useNav } from './context.js';
2
3
  export { COLLAPSED_COOKIE } from './cookie.js';
3
4
  export { FALLBACK_CONFIG } from './fallback.js';
@@ -5,6 +6,7 @@ export { NavBar } from './nav-bar.js';
5
6
  export { NavTrigger } from './nav-trigger.js';
6
7
  export { NavProvider } from './provider.js';
7
8
  export { resolveApps } from './resolve.js';
9
+ export type { SuiteNavClickProperties } from './analytics.js';
8
10
  export type { NavContextValue } from './context.js';
9
11
  export type { NavBarProps } from './nav-bar.js';
10
12
  export type { NavTriggerProps } from './nav-trigger.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,YAAY,EAAE,MAAM,EAAE,eAAe,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAC3E,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,YAAY,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAC9D,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,YAAY,EAAE,MAAM,EAAE,eAAe,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ export { SUITE_NAV_CLICK_EVENT, suiteNavClickEvent } from './analytics.js';
1
2
  export { useNav } from './context.js';
2
3
  export { COLLAPSED_COOKIE } from './cookie.js';
3
4
  export { FALLBACK_CONFIG } from './fallback.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAC3E,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@artstorefronts/arthelper-nav",
3
- "version": "0.1.0-alpha.6",
3
+ "version": "0.1.0-alpha.7",
4
4
  "description": "The ArtHelper suite navigation bar — a config-driven, cross-origin app switcher.",
5
5
  "license": "ISC",
6
6
  "type": "module",