@moveo-ai/web-client 0.114.0 → 0.115.1-true.1

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
@@ -197,6 +197,13 @@ Any other key passes through as a widget-config override for the loaded integrat
197
197
  | `setLocale(locale)` | Switches the widget language |
198
198
  | `destroy()` | Removes the widget from the page |
199
199
 
200
+ `updateContext` calls made inside a 300 ms window merge into one update, so a
201
+ burst of calls costs one round trip and the first call still ships at once.
202
+ Arrays such as `tags` replace the stored value rather than append, so
203
+ `tags: []` clears them. A call made before a conversation exists is held and
204
+ sent once the session opens. `closeConversation` sends any update still queued
205
+ before it ends the session.
206
+
200
207
  ### WidgetController Events
201
208
 
202
209
  Register a callback per event. Every callback returns nothing and receives the
@@ -223,6 +230,8 @@ a message — never carries the text), `launcher_clicked`,
223
230
  `teaser_quick_reply_clicked` (a teaser reply the visitor tapped, carrying its
224
231
  configured `label`), `teaser_composer_submitted` (the visitor sent their own
225
232
  line from the teaser — carries no properties, because the text is theirs),
233
+ `section_not_found` (a `teaser.pages[].sections[]` entry whose strongest
234
+ selector no longer matches the page — see "A different teaser per section"),
226
235
  `rating_submitted`, and the rest of the `AnalyticsEvent` enum in
227
236
  `src/hooks/useAnalytics.ts`.
228
237
 
@@ -415,6 +424,93 @@ the new URL, and the teaser re-resolves. An integration that configures no
415
424
  `pages[]` is not watched at all, because the watcher patches `history` and never
416
425
  restores it.
417
426
 
427
+ #### A different teaser per section of a page
428
+
429
+ On a long page one teaser is one teaser for fourteen blocks. `sections[]`, nested
430
+ in a `pages[]` entry, gives each part of the page its own, and the teaser
431
+ follows what the visitor is reading.
432
+
433
+ ```javascript
434
+ MoveoAI.init({
435
+ integrationId: 'YOUR_INTEGRATION_ID',
436
+ teaser: {
437
+ quick_replies: ['Compare products', 'Help me choose'],
438
+ pages: [
439
+ {
440
+ url: '/shop',
441
+ id: 'shop',
442
+ quick_replies: ['Which Clover system fits my business?'],
443
+ sections: [
444
+ {
445
+ id: 'station_duo',
446
+ match: [
447
+ '[data-entry-id="3UlHnDQQTGvNwHKQnXgVTz"]',
448
+ 'article > section:nth-of-type(6)',
449
+ ],
450
+ quick_replies: [
451
+ 'Is Station Duo worth $1,899?',
452
+ 'Station Duo or Flex?',
453
+ ],
454
+ },
455
+ {
456
+ id: 'go',
457
+ match: ['[data-entry-id="5oA3X1sZOG6FGGUrk39jiR"]'],
458
+ quick_replies: ['Does Go work without a counter?'],
459
+ },
460
+ { id: 'legal', match: ['#legal'], variant: 'none' },
461
+ ],
462
+ },
463
+ ],
464
+ },
465
+ });
466
+ ```
467
+
468
+ **Resolution is section → page → block.** The section in view wins; no section
469
+ in view falls back to the page's teaser; no page match falls back to the block.
470
+ A section set to `variant: 'none'` goes quiet and does **not** fall back — it is
471
+ an instruction, not an absence.
472
+
473
+ **`match` is an ordered list of CSS selectors, strongest first**, and nothing
474
+ else: the loader runs `querySelector` on each until one matches, and observes
475
+ that element. A selector matching several elements resolves to the first in
476
+ document order. Put a stable `id` or a CMS data attribute first and a positional
477
+ selector like `article > section:nth-of-type(6)` last, so a section survives
478
+ losing its best anchor. Hashed CSS-module class names change on every deploy;
479
+ never use one.
480
+
481
+ **`id` is authored, not derived from position.** It names the section in
482
+ analytics, so an index that shifted whenever someone reordered the list would
483
+ break the history. Unlike `pages[]`, the order of `sections[]` decides nothing:
484
+ sections are chosen at runtime by what is on screen.
485
+
486
+ **The section with the largest visible share of the viewport wins**, not the
487
+ one with the largest visible ratio of itself — a 992px section 40% in view
488
+ fills more screen than a 373px one fully in view. A tie keeps the current
489
+ section, so a slow scroll cannot flap between two sets of chips, and a section
490
+ must hold the viewport for a moment before the teaser follows it, so one flick
491
+ of the wheel does not fire three swaps. The swap lands while the teaser is out
492
+ of the way for the scroll, and the new chips are what fades back in.
493
+
494
+ **`show_after` gates the first show only.** A later swap never waits — a visitor
495
+ scanning a long page would otherwise restart the delay at every block and see
496
+ nothing. **A new section re-arms a teaser that `hide_after` retired**, with a
497
+ fresh budget. **A teaser the visitor closed stays closed** for the visit,
498
+ whatever section they reach.
499
+
500
+ **Sections belong to their page.** A single-page-app navigation rebuilds the
501
+ watch against the new page's sections, and clears the current section so
502
+ nothing from the previous page survives the transition. A page with no
503
+ `sections[]`, or an empty list, is not observed at all, and an integration
504
+ with no sections anywhere registers no observer.
505
+
506
+ **When a selector stops matching**, the widget emits the `section_not_found`
507
+ analytics event once per section per page view, carrying `section_id`,
508
+ `page_id`, `page_url`, `matched_index` and `selector_count`. It fires whenever
509
+ the strongest selector no longer holds: `matched_index` names the fallback that
510
+ still does, so the section can be regenerated before it breaks, and is `null`
511
+ once nothing matches. A section with no match is simply left out of the
512
+ running; the page teaser covers it.
513
+
418
514
  **Chips replace the line, they do not sit under it.** Asking the question and
419
515
  offering the answers says the same thing twice, and a bubble above
420
516
  content-width chips leaves a ragged edge.
@@ -652,14 +748,14 @@ icon and the launcher, and `--color-chat-background` follows the background.
652
748
  Six more colours have no `theme_colors` key, so they are set through
653
749
  `setCSSVariables()` only:
654
750
 
655
- | Variable | Controls |
656
- | ------------------------------------ | ------------------------------------------------------------------- |
657
- | `--color-chat-background` | The area behind the messages; follows the background |
658
- | `--color-options-background` | Quick reply buttons, and the teaser chips and composer field |
659
- | `--color-options-foreground` | Quick reply labels, the teaser composer text, and a chip under the pointer or the focus ring; defaults to the accent |
751
+ | Variable | Controls |
752
+ | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------- |
753
+ | `--color-chat-background` | The area behind the messages; follows the background |
754
+ | `--color-options-background` | Quick reply buttons, and the teaser chips and composer field |
755
+ | `--color-options-foreground` | Quick reply labels, the teaser composer text, and a chip under the pointer or the focus ring; defaults to the accent |
660
756
  | `--color-options-border` | Quick reply borders, the teaser composer field, and a chip under the pointer or the focus ring; defaults to the accent |
661
- | `--color-opening-message-background` | The teaser bubble, on `callout` and `composer`; defaults to the accent |
662
- | `--color-opening-message-foreground` | The teaser bubble text; defaults to the visitor's own bubble text colour |
757
+ | `--color-opening-message-background` | The teaser bubble, on `callout` and `composer`; defaults to the accent |
758
+ | `--color-opening-message-foreground` | The teaser bubble text; defaults to the visitor's own bubble text colour |
663
759
 
664
760
  The two `opening-message` names are the teaser's, from before it was called
665
761
  one. They are the only lever that moves the bubble off the accent, so an
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  *
3
- * @moveo-ai/web-client v0.114.0
3
+ * @moveo-ai/web-client v0.115.1-true.1
4
4
  * Copyright (c) Moveo.ai (TM)
5
5
  *
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  *
3
- * @moveo-ai/web-client v0.114.0
3
+ * @moveo-ai/web-client v0.115.1-true.1
4
4
  * Copyright (c) Moveo.ai (TM)
5
5
  *
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  *
3
- * @moveo-ai/web-client v0.114.0
3
+ * @moveo-ai/web-client v0.115.1-true.1
4
4
  * Copyright (c) Moveo.ai (TM)
5
5
  *
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  *
3
- * @moveo-ai/web-client v0.114.0
3
+ * @moveo-ai/web-client v0.115.1-true.1
4
4
  * Copyright (c) Moveo.ai (TM)
5
5
  *
6
6
  */