@sensiblestats/widget-react 0.63.0 → 0.64.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/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # @sensiblestats/widget-react
2
2
 
3
+ ## 0.64.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Host events. `createWidgetHost()` and the `host` prop let an operator tell the widget when a slip selection is removed (`slipRemoved`), a bet is placed (`betPlaced`) and a match page is opened (`matchOpened`). `config.onOpenMatch` turns team names into links that call the operator with the match id. The "In slip" mark now belongs to the odd, so it survives closing the panel and shows on every button for that odd. New event names `slip_remove`, `bet_placed`, `match_view` and `match_open`; `match_view` is deferred and never starts a request of its own. `EventLogger.resume()` undoes `dispose()`, which stops events being dropped under React StrictMode in a development build.
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies
12
+ - @sensiblestats/widget-sdk@0.39.0
13
+
3
14
  ## 0.63.0
4
15
 
5
16
  ### Minor Changes
package/README.md CHANGED
@@ -39,6 +39,63 @@ Common `config` fields:
39
39
  - White-label branding — `logoUrl`, `headerTitle`, `accent`, `cta`, `surface`,
40
40
  `ink`. Absent → the default SensibleStats look.
41
41
 
42
+ ## Hooks: the slip and the match page
43
+
44
+ Optional hooks keep the widget and your site in step. Two are `config` callbacks, from the widget
45
+ to your code. Three are methods on a host object you create, from your code to the widget.
46
+
47
+ ```tsx
48
+ // widget-host.ts
49
+ import { createWidgetHost } from '@sensiblestats/widget-react'
50
+
51
+ // Create it once, at module scope. It is safe under server rendering.
52
+ export const widgetHost = createWidgetHost()
53
+ ```
54
+
55
+ ```tsx
56
+ <StatsWidget
57
+ host={widgetHost}
58
+ config={{
59
+ ...config,
60
+ onAddToSlip: (selection) => addToMySlip(selection),
61
+ onOpenMatch: ({ matchId }) => router.push(`/match/${matchId}`),
62
+ }}
63
+ />
64
+ ```
65
+
66
+ ```ts
67
+ widgetHost.slipRemoved({ matchOddsId }) // a leg left your slip
68
+ widgetHost.betPlaced({ selections: [{ matchOddsId }] }) // the bet was placed
69
+ widgetHost.matchOpened({ matchId }) // your match page opened
70
+ ```
71
+
72
+ What each one does:
73
+
74
+ - `onAddToSlip`. Called when the user taps "Add to slip", with `{ matchOddsId, matchId, oddsDecimal }`.
75
+ Add that selection to your slip. Return nothing, or a result such as `{ status: 'added' }`,
76
+ `{ status: 'duplicate' }` or `{ status: 'rejected', reason }`. The widget shows "In slip" for an
77
+ added or duplicate selection. Answer within 10 seconds. Without a `host`, an "In slip" button
78
+ stays that way until the page reloads; with one, `slipRemoved` and `betPlaced` clear it.
79
+ - `onOpenMatch`. Without it team names in the widget are plain text. With it they are buttons that
80
+ call you with the match id. On a phone the panel closes after the tap, because it covers the
81
+ page.
82
+ - `slipRemoved`. Clears the widget's "In slip" mark for that selection. Call it whenever a leg
83
+ leaves your slip for any reason, a "clear all" included. A leg the widget still believes is in
84
+ the slip can be reported as bet later.
85
+ - `betPlaced`. Pass every leg of the bet. The widget reports the legs it added itself, at most 25
86
+ per call, and ignores the rest, so you do not filter.
87
+ - `matchOpened`. Call it from your match page. A view counts only for a visitor who has opened the
88
+ widget in that tab, and at most once per match every 30 minutes.
89
+
90
+ Rules for the three host methods:
91
+
92
+ - `matchOddsId` and `matchId` are the numbers `onAddToSlip` gave you. Anything that is not a
93
+ positive integer is ignored, a numeric string included.
94
+ - No method throws, and each is safe to call twice.
95
+ - A call made while no widget is mounted is queued, the last 20, and replayed when one mounts. The
96
+ queue lives in the page, so it does not survive a full page load.
97
+ - Use one host for one mounted widget.
98
+
42
99
  ## Integration: persisting the conversation across SPA navigation
43
100
 
44
101
  The conversation (messages, conversation id, open/closed state) lives in the