@vio-live/web-sdk 0.23.1 → 0.24.0

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
@@ -183,10 +183,11 @@ Every mounted element registers its id (and label); after the first successful
183
183
  `Vio.bootstrap()` the SDK sends **one** manifest for the whole page
184
184
  (`POST /v2/mobile/components/manifest`, `mode: 'merge'`, so one page never
185
185
  deprecates another page's slots) and again whenever a new id or label appears.
186
- The browser remembers **each id (under its label) for 24 h** in `localStorage`
187
- (under the platform and a hash of the key — never the key itself), so a
188
- multi-page site posts only the ids a page adds, a revisit posts nothing, a
189
- renamed block posts again; without storage it simply posts each load. A failed
186
+ The browser remembers **each id — under its label and the campaign it was
187
+ declared with — for 24 h** in `localStorage` (under the platform and a hash of
188
+ the key — never the key itself; one state per id), so a multi-page site posts
189
+ only the ids a page adds, a revisit posts nothing, a renamed block or a page that
190
+ changed campaign posts again; without storage it simply posts each load. A failed
190
191
  attempt (or a server that ignored `merge`) is not retried for 1 h; a declaration
191
192
  sends at most 100 locations and a page load at most 3 manifests (each cap warns
192
193
  once). Best-effort, never throws. By hand, e.g. from an editor (`force` re-sends
@@ -201,14 +202,63 @@ await Vio.declareSlots(['hero', { id: 'sidebar', displayName: 'Sidebar' }], { fo
201
202
 
202
203
  Among the active campaigns of the bootstrap, the one whose assignment names the
203
204
  slot (for this platform, or for all) and whose window is open right now; if
204
- several, the default campaign, else the first listed. No assignment → the default
205
+ several, the default campaign, else the first listed. No assignment → the page's
206
+ campaign (see *Page campaign*) when the bootstrap lists it as active → the default
205
207
  campaign. `Vio.campaignForSlot('hero')` answers from the last bootstrap (`null`
206
- before it); the pure `resolveSlotCampaign(boot, slot, now?, platform?)` is exported
207
- from `/core`. A carousel or card **without a `sponsor-id`** uses the primary sponsor
208
+ before it); the pure `resolveSlotCampaign(boot, slot, now?, platform?, pageCampaignId?)`
209
+ is exported from `/core`. A carousel or card **without a `sponsor-id`** uses the primary sponsor
208
210
  of its slot's campaign (the default campaign's when the slot has none), and the
209
211
  detail opened by such a card does the same — before 0.23 a sponsorless card did
210
212
  nothing. An explicit `sponsor-id` still wins.
211
213
 
214
+ ### Page campaign — an editorial page that belongs to one campaign
215
+
216
+ Native-SDK style placements stay the primary model: the **dashboard assigns**
217
+ a campaign to a slot. But an editorial page — a Vev article, a Replit article —
218
+ often *is* part of one campaign, and the page can say so:
219
+
220
+ ```ts
221
+ Vio.init({ apiKey: '…', campaignId: 12 }) // the whole page
222
+ ```
223
+
224
+ ```html
225
+ <body data-vio-campaign="12"> <!-- inheritable, like the scope -->
226
+ <vio-product-carousel vio-campaign="10" …> <!-- one element of another campaign -->
227
+ ```
228
+
229
+ Precedence per element: `vio-campaign` on the element → the nearest ancestor's
230
+ `data-vio-campaign` → `Vio.init({ campaignId })`; an unusable level (not a positive
231
+ integer, paused, unknown) falls through to the next. The attributes are read when
232
+ the element mounts or its own attribute changes — there is no observer on the
233
+ ancestors. On web/Replit a **per-article** campaign needs a per-article scope too
234
+ (`data-vio-scope`, see above): without it the auto ids of every article are the
235
+ same `carousel-1`, and the articles' campaigns would overwrite one another's
236
+ assignment; Vev ids are per block, so it does not apply there. What it does:
237
+
238
+ - **Declaration.** The manifest carries the page's campaign (top-level) and an
239
+ element's own campaign per location when it differs. The campaigns service
240
+ (campaigns micro PR #16) turns that into assignments of the page's slots
241
+ (`source: 'page'`) — **unless the dashboard already assigned the slot: the
242
+ dashboard wins**, and the SDK warns once per such slot (and once when this page
243
+ moved a slot from an earlier page assignment). A page that changes campaign
244
+ declares again; a campaign the micro did not take up is retried after an hour.
245
+ - **Resolution, immediately.** `Vio.campaignForSlot()` / `Vio.attribution()` (and
246
+ so the elements, the cart origins and the events) resolve as: the slot's
247
+ assignment (a dashboard one always; a page-sourced one unless the page now
248
+ declares a different active campaign or the known sponsor takes no part in it)
249
+ → the page's campaign, when the bootstrap lists it as active and — with a known
250
+ sponsor — that sponsor takes part in it → the sponsor's campaign → the default. An editor sees the effect in the Vev
251
+ editor before the manifest round-trips.
252
+ - `Vio.pageCampaign()` returns the init-level campaign as the bootstrap lists it
253
+ (active), else `null`.
254
+ - With a **known sponsor** (a card with `sponsor-id`), the page's campaign — and a
255
+ slot assignment the page made itself (`source: 'page'`) — count only when that
256
+ sponsor takes part in the campaign; otherwise the sponsor's own campaign applies.
257
+ A dashboard assignment counts unconditionally.
258
+ - `Vio.init({ debug: true })` logs the micro's `assignment` per slot at
259
+ `console.debug`. It is independent of `Vio.analytics.start({ debug })`, which
260
+ logs the analytics events.
261
+
212
262
  ## Attribution — the slot, the campaign, the article
213
263
 
214
264
  `Vio.attribution(slot?)` is **the** attribution helper — the SDK elements use it,
@@ -241,7 +291,8 @@ titles are cut — in one place, before anything is sent. Per element,
241
291
  tracks carries `slot` (the effective id), `location_id` (= the slot), `content_id`
242
292
  and `content_title`. `campaign_id` resolves as explicit `campaignId` (the element's
243
293
  own attribution travels in its event detail and is honored as such) → the slot's
244
- assigned campaign → the sponsor's campaign → the default. Two things changed from
294
+ assigned campaign → the page's campaign (when the sponsor takes part in it) → the
295
+ sponsor's campaign → the default. Two things changed from
245
296
  0.22 for carousels: a carousel's impressions and `view_item_list` report
246
297
  `location_id` as its slot id (`carousel-1`, or the `vio-slot`) instead of its
247
298
  `label`, and every event now carries `content_id` / `content_title` — including