@sharadtech/infralytiqs-sdk 1.0.1 → 1.0.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/clients/publicis/ps/README.md +105 -5
- package/clients/publicis/ps/package.json +1 -1
- package/clients/publicis/ps/src/index.js +2473 -70
- package/dist/infralytiqs.js +99 -2
- package/dist/infralytiqs.min.js +2 -2
- package/package.json +1 -1
- package/src/index.ts +31 -0
- package/src/token.ts +79 -0
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# Infralytiqs Client Bootstrap — Publicis Sapient (`ps`)
|
|
2
2
|
|
|
3
|
-
Client-specific Infralytiqs bootstrap for the
|
|
4
|
-
|
|
3
|
+
Client-specific Infralytiqs bootstrap for the Publicis Sapient family of
|
|
4
|
+
Asset Share Commons (ASC) sites — currently
|
|
5
|
+
**https://psassets.publicissapient.com** and **https://ps-dev.adobedam.com**.
|
|
5
6
|
|
|
6
7
|
This project ships a single minified JavaScript file (`dist/infralytiqs-bootstrap.min.js`)
|
|
7
8
|
that is deployed to CloudFront and embedded in the host page **after** the
|
|
@@ -16,6 +17,8 @@ Host page <head>
|
|
|
16
17
|
|
|
17
18
|
## Tracked events
|
|
18
19
|
|
|
20
|
+
### Login page (anonymous)
|
|
21
|
+
|
|
19
22
|
| Event | Trigger | Notes |
|
|
20
23
|
| ------------------ | ------------------------------------------------ | --- |
|
|
21
24
|
| `login_page_view` | Anonymous user lands on the login page | Fired in addition to the SDK's auto `page_view` so the Reports login funnel can segment login-page traffic before identify(). |
|
|
@@ -23,9 +26,65 @@ Host page <head>
|
|
|
23
26
|
| `sso_click` | Click on **Login with Lion Login** SSO button | Sends `method: lion_login`, `sso_provider: lion`. |
|
|
24
27
|
| `terms_click` | Click on **Terms and Conditions** link | Sends the link `href` and visible text. |
|
|
25
28
|
|
|
29
|
+
### Asset Share Commons (`search_context = "asc"`, authenticated)
|
|
30
|
+
|
|
31
|
+
The user is resolved via `/libs/granite/security/currentuser.json` on every
|
|
32
|
+
page (cached in `localStorage`) and identified to the SDK so every event
|
|
33
|
+
below carries `user_id` in addition to the SDK's `anonymous_id` / `session_id`.
|
|
34
|
+
|
|
35
|
+
| Event | Trigger | Dimensions |
|
|
36
|
+
| ------------------- | ----------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
37
|
+
| `search_executed` | Any page load whose URL carries `?fulltext=…` | `search_term`, `semantic_search`, `fuzzy_search`, `filters_json` (JSON array of `{group, name, property, operation, values[]}` — `name` is the right-rail section heading like `"ASSET TYPE"`, resolved by cross-referencing the URL property against the rail's `cmp-predicate` blocks), `filters_dom_json` (belt-and-braces JSON of `{name, values[]}` produced by sweeping the rail for checked inputs — catches DOM-only state the URL didn't carry), `orderby`, `order_dir`, `layout`, `search_context="asc"`, `page_url`, `page_referrer`, `search_stats_ready` (`"true"` when the search-statistics widget had populated before we fired). Metrics: `filter_count`, `filter_dom_count`, `result_offset`, `result_limit`, **`search_time_ms`** (server-reported search latency read from the right-rail statistics widget), **`result_total`** (total asset count), **`result_pages`** (total page count, when the widget exposes one), **`result_displayed`** (assets shown on the current results page). The bootstrap briefly observes the statistics container with a `MutationObserver` so the timing reflects the search that just executed, not a stale value left over from the previous in-page navigation; if the widget never populates within 3 s the event still fires with `search_stats_ready=false`. The raw label→value tuples (first 240 chars of JSON) are also emitted as `search_stats_raw_json` so any future label change in ASC can be diagnosed from ClickHouse without re-instrumenting the page. |
|
|
38
|
+
| `asset_preview` | Any page load matching `/details/<type>.html/<assetPath>` | `asset_path` (`/content/dam/…`), `asset_type` (`image`, `video`, `document`, `3d`, …), `asset_name`, `asset_extension`, `page_url`, `page_referrer`. |
|
|
39
|
+
| `asset_download` | Network `POST` to ASC `…/actions/download/.../download.download-asset-renditions.zip` | `asset_path` (from form body `path`), `rendition_name` (from `renditionName`), `download_endpoint`, `page_url`. **Intercepts `fetch` and `XMLHttpRequest`** so it fires whether the user used the card menu, the detail-page button, or a rendition picker. |
|
|
40
|
+
| `asset_add_to_cart` | Click on a per-tile / per-card Add-to-Cart button. Detected primarily by `data-asset-share-id="add-to-cart"` (the ASC convention), with `[data-il-cart-add]` / `[data-cmp-cart-action="add"]` and a visible-text `/add to cart/i` regex as fallbacks. The icon-only variant is detected via data-attrs alone (no text required). | `asset_path` — read from `data-asset-share-asset` directly when the button is the ASC variant, or walked up the DOM via `data-asset-path` / `data-asset` / `data-foundation-collection-item-id` / nearest `<a href="/details/…">`. `page_url`. |
|
|
41
|
+
| `asset_share` | Click on an asset-level Share button (`data-asset-share-id="share-asset"`, `[data-il-share]`, `[data-cmp-share-action]`, or visible-text `/share/i`). Explicitly excludes the cart-level Share Cart button so a click on it cannot fall through. | `asset_path`, `page_url`. |
|
|
42
|
+
| `cart_open` | Click anywhere inside the header cart icon link (`a.item > i.cart.icon`, `[data-asset-share-id="cart"]`). | `page_url`. Subtype: `cart_action`. |
|
|
43
|
+
| `cart_share_initiated` | Click on the cart-modal "Share Cart" button (`data-asset-share-id="share-all"`). Funnel-only intent — the actual share happens when the user fills the share modal and submits. | `cart_asset_paths_json` (JSON array of `/content/dam/...` paths scraped from the cart modal). Metric: `cart_item_count`. Subtype: `cart_action`. |
|
|
44
|
+
| `cart_share` | Submit of the share-modal form (`form.cmp-modal-share` / `form[class*="cmp-modal-share"]`). Fires the moment the user submits, BEFORE jQuery validation may cancel — so the funnel captures every share attempt. | `share_emails` (comma-joined, deduped, lowercase-key dedupe, 480-char cap), `share_is_public` (`"true"` / `"false"` — taken from the "Share Publicly" checkbox OR inferred from non-empty dates), `share_start_date`, `share_end_date` (`yyyy-mm-dd`, only set when `share_is_public="true"`), `cart_asset_paths_json` (carried over from the cart snapshot captured at button-click time so it survives the cart modal closing). Metrics: `share_emails_count`, `share_date_range_days` (`end - start`, clamped to ≥ 0), `cart_item_count`. Subtype: `cart_action`. |
|
|
45
|
+
| `cart_download` | Click on the cart-modal "Download Cart" button (`data-asset-share-id="download-all"`). The user's confirmed intent to start the cart-download pipeline — the actual binaries arrive asynchronously and emit `asset_download` events when the user clicks the per-row download anchors in the downloads modal. | Same shape as `cart_share`: `cart_asset_paths_json`, `cart_item_count`. Subtype: `cart_action`. |
|
|
46
|
+
| `downloads_open` | Click anywhere inside the header download icon link (`a.item > i.download.icon`, `[data-asset-share-id="downloads"]`). | `page_url`. Subtype: `cart_action`. |
|
|
47
|
+
| `asset_download` | (a) Network `POST` to ASC `…/actions/download/.../download.download-asset-renditions.zip` — `download_method="ajax"`. (b) Click on a per-artifact download anchor in the downloads modal (`a[href*="downloadbinaries.json"]`) — `download_method="binary_link_click"`, with `download_source="downloads_modal"`. | (a) `asset_path` (form body `path`), `rendition_name` (form body `renditionName`), `download_endpoint`, `page_url`. (b) `download_id` and `artifact_id` (parsed off the anchor's query string), `download_endpoint` (URL minus query), `download_source`, `download_method`, `page_url`. |
|
|
48
|
+
| `download_removed` | Click on the per-row "remove from downloads" button (`data-asset-share-id="remove-from-downloads"`). | `download_id` (from `data-asset-share-download-id`), `page_url`. Subtype: `cart_action`. |
|
|
49
|
+
|
|
50
|
+
### Asset Explorer (`search_context = "asset_explorer"`, authenticated)
|
|
51
|
+
|
|
52
|
+
`/asset-explorer.html#/content/dam/...` is the React SPA front-end. Search,
|
|
53
|
+
folder browsing, and the Search Options modal live entirely in client-side
|
|
54
|
+
state, so the bootstrap routes off DOM events rather than URL parsing.
|
|
55
|
+
|
|
56
|
+
| Event | Trigger | Dimensions |
|
|
57
|
+
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
58
|
+
| `search_executed` | Any of: Enter inside the search input, native form submit, Search Options modal close, right-rail filter click, debounced live-typing pause (800 ms). Overlapping triggers on the same user action collapse into one event via `(term, semantic, fuzzy, folder, filters)` dedup. | `search_term`, `semantic_search` / `fuzzy_search` (read from the toggles in the open Search Options modal — falls back through native checkbox → `aria-checked` → `data-state` → class-name heuristic; emits `""` when the row isn't currently rendered), `folder_path` (the `#/content/dam/...` hash), `filters_dom_json` (JSON of `{name, values[]}` blocks scraped from the right-rail facet panel via native-checkbox / ARIA / data-state / class-name heuristics — grouped under the section heading the chip lives under), `search_context="asset_explorer"`, `search_trigger` (which hook fired: `enter` / `submit` / `options_close` / `filter_click` / `input_debounced`), `page_url`, `page_referrer`. Metrics: `filter_dom_count`, same `search_*` stats as ASC populated from the rail's `_statContainer_` (`<N> DISPLAYED <N> TOTAL <N> MILLISECONDS` tiles paired via `_value_` / `_label_` siblings; regex fallback over the container's text if structured markup isn't present). Subtype: `asset_search`. |
|
|
59
|
+
| `folder_navigation` | Any of: `hashchange`, click on a folder in the left-side directory tree, expand a tree node, collapse a tree node, initial page load (when a folder is already in the hash route). | `folder_path` (current hash route), `search_context="asset_explorer"`, `tree_action` (`page_load` / `hash_change` / `click` / `expand` / `collapse` — derived from `aria-expanded` mutation when available, otherwise `click`), `tree_target_label` (visible text of the clicked tree node), `tree_target_class_hint` (first 240 chars of the clicked element's className — diagnostic, to refine action detection from data later), `page_url`, `page_referrer`. Subtype: `asset_browse`. No stats wait. A single user gesture can emit one `click`/`expand`/`collapse` event AND a `hash_change` event when the click also navigates — they are intentionally NOT deduped so dashboards can split intent (the user opened a node) from outcome (the route changed). |
|
|
60
|
+
| `asset_preview` | Shared with ASC — fires on a `/details/<type>.html/<assetPath>` navigation (the explorer hands off to ASC for full detail views), and on body-level clicks that resolve to an asset path attribute. | Same as ASC. |
|
|
61
|
+
| `asset_download`, `asset_add_to_cart`, `asset_share` | Shared with ASC — same network interception and click delegation. | Same as ASC. |
|
|
62
|
+
|
|
26
63
|
Every event also picks up the global enrichment dimensions (browser, viewport,
|
|
27
|
-
screen, timezone, language, color scheme, tenant, site, origin)
|
|
28
|
-
|
|
64
|
+
screen, timezone, language, color scheme, tenant, site, origin) plus the
|
|
65
|
+
SDK's transport-level fields (timestamps, anonymous_id, session_id, user_id,
|
|
66
|
+
UTM, country) so the Reports UI can slice by them without per-event
|
|
67
|
+
instrumentation.
|
|
68
|
+
|
|
69
|
+
### How each event is wired
|
|
70
|
+
|
|
71
|
+
Three strategies, picked to be as DOM-independent as practical:
|
|
72
|
+
|
|
73
|
+
1. **URL-driven** (`search_executed`, `asset_preview`, `login_page_view`) —
|
|
74
|
+
the host page navigates via real GET requests, so the resulting URL is
|
|
75
|
+
the authoritative record of what the user did. The bootstrap parses
|
|
76
|
+
`location.pathname` / `location.search` on every page load and emits
|
|
77
|
+
the event. This survives bookmarks, browser-back, and shared links.
|
|
78
|
+
2. **Network-driven** (`asset_download`) — `window.fetch` and
|
|
79
|
+
`XMLHttpRequest.prototype.{open,send}` are wrapped once per page. The
|
|
80
|
+
wrapper matches the ASC download endpoint regex and reads the asset
|
|
81
|
+
path + rendition name straight from the form-encoded POST body. No
|
|
82
|
+
DOM dependency at all, so it fires whether the user used the card
|
|
83
|
+
menu, the detail-page button, or a rendition-picker dropdown.
|
|
84
|
+
3. **Click delegation** (`asset_add_to_cart`, `asset_share`) — a single
|
|
85
|
+
body-level capturing listener uses `closest()` to find a matching
|
|
86
|
+
button regardless of which descendant icon/label the user actually
|
|
87
|
+
clicked. Survives SPA re-renders without needing a `MutationObserver`.
|
|
29
88
|
|
|
30
89
|
## Configuration contract
|
|
31
90
|
|
|
@@ -52,11 +111,52 @@ data-attribute, href, and visible-text). To opt out of the heuristic, set
|
|
|
52
111
|
```html
|
|
53
112
|
<script>
|
|
54
113
|
window.IL_PS_SELECTORS = {
|
|
114
|
+
// Login page
|
|
55
115
|
loginForm: '#loginForm',
|
|
56
116
|
signInButton: '#signInButton',
|
|
57
117
|
userField: 'input[name="username"]',
|
|
58
118
|
ssoButton: '#lionLoginBtn',
|
|
59
|
-
termsLink: 'a#termsAndConditions'
|
|
119
|
+
termsLink: 'a#termsAndConditions',
|
|
120
|
+
// Asset Share Commons
|
|
121
|
+
searchInput: 'input[name="fulltext"]',
|
|
122
|
+
filterRail: '#rail',
|
|
123
|
+
searchStatistics: '.cmp.cmp-search-statistics',
|
|
124
|
+
addToCart: '[data-il-cart-add]',
|
|
125
|
+
shareButton: '[data-il-share]',
|
|
126
|
+
// Asset Explorer (React)
|
|
127
|
+
assetExplorerRoot: '[class*="_directoryExplorer_"]',
|
|
128
|
+
assetExplorerForm: '[class*="_directoryExplorer_"] form',
|
|
129
|
+
assetExplorerSearchInput: '[class*="_directoryExplorer_"] input[type="text"]',
|
|
130
|
+
assetExplorerSearchOptionRow: '[class*="_searchOptionRow_"]',
|
|
131
|
+
assetExplorerFilterRail: '[class*="_filterWrapper_"]',
|
|
132
|
+
assetExplorerFilterSection: '[class*="_filterSection_"], [class*="_facet_"]',
|
|
133
|
+
assetExplorerSearchStatistics:'[class*="_statContainer_"]',
|
|
134
|
+
assetExplorerFolderTree: '[class*="_directoryTreeContent_"]'
|
|
135
|
+
};
|
|
136
|
+
</script>
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The easiest pattern for ASC components is to add an opt-in
|
|
140
|
+
`data-il-cart-add` / `data-il-share` attribute (or `data-asset-path`
|
|
141
|
+
on the parent card) so the bootstrap stops relying on the visible-text
|
|
142
|
+
fallback altogether.
|
|
143
|
+
|
|
144
|
+
### User-identity override
|
|
145
|
+
|
|
146
|
+
By default the bootstrap resolves the logged-in user by:
|
|
147
|
+
|
|
148
|
+
1. Calling `window.IL_PS_USER_RESOLVER()` if you defined it (sync string
|
|
149
|
+
or a `Promise<string>`).
|
|
150
|
+
2. Reading `<meta name="cq:user">` (or `name="user"` / `name="user-id"`).
|
|
151
|
+
3. Falling back to `GET /libs/granite/security/currentuser.json` and
|
|
152
|
+
using its `authorizableId` / `id`.
|
|
153
|
+
|
|
154
|
+
To bypass all three, supply a resolver:
|
|
155
|
+
|
|
156
|
+
```html
|
|
157
|
+
<script>
|
|
158
|
+
window.IL_PS_USER_RESOLVER = function () {
|
|
159
|
+
return window.MY_AUTH_PROVIDER.getUsername();
|
|
60
160
|
};
|
|
61
161
|
</script>
|
|
62
162
|
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sharadtech/infralytiqs-client-publicis-ps",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Infralytiqs client-specific bootstrap for Publicis Sapient (psassets.publicissapient.com). Reads window.IL_* configuration injected by the host page, initializes the Infralytiqs SDK loaded from the CDN, and hooks the login-page user journey: anonymous page view, credential sign-in submit, Lion Login SSO click, and Terms & Conditions click.",
|