@revturbine/sdk 0.10.0 → 0.10.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/CHANGELOG.md +100 -6
- package/dist/headless.d.ts +255 -51
- package/dist/headless.js +2 -2
- package/dist/headless.js.map +1 -1
- package/dist/index.d.ts +263 -51
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/types/web-sdk/controllers.d.ts +2 -0
- package/dist/types/web-sdk/controllers.d.ts.map +1 -1
- package/dist/types/web-sdk/customer-side.d.ts +203 -2
- package/dist/types/web-sdk/customer-side.d.ts.map +1 -1
- package/dist/types/web-sdk/react/RevTurbineProvider.d.ts +2 -0
- package/dist/types/web-sdk/react/RevTurbineProvider.d.ts.map +1 -1
- package/dist/types/web-sdk/react/useCan.d.ts +2 -0
- package/dist/types/web-sdk/react/useCan.d.ts.map +1 -1
- package/dist/types/web-sdk/react/useEntitlement.d.ts +2 -0
- package/dist/types/web-sdk/react/useEntitlement.d.ts.map +1 -1
- package/dist/types/web-sdk/react/useGatedAction.d.ts +2 -0
- package/dist/types/web-sdk/react/useGatedAction.d.ts.map +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -22,12 +22,19 @@ A change whose "Fail-closed in" is later than its "Landed in" had a window where
|
|
|
22
22
|
the old shape was accepted and did nothing. Those windows are the expensive ones.
|
|
23
23
|
|
|
24
24
|
> **What this file is not yet.** A CI guard fails any PR that changes a
|
|
25
|
-
> `@public`-tagged export signature without touching this file. That tagging
|
|
26
|
-
> thin
|
|
27
|
-
>
|
|
28
|
-
>
|
|
29
|
-
>
|
|
30
|
-
>
|
|
25
|
+
> `@public`-tagged export signature without touching this file. That tagging
|
|
26
|
+
> was thin (4 of ~73 methods) until BL-0005 (2026-09-22, no release — TSDoc
|
|
27
|
+
> and snapshot only) widened it to **34** of `RevTurbineCustomerSdk`'s **67**
|
|
28
|
+
> non-private methods, plus 5 provider/hook entry points
|
|
29
|
+
> (`initRevTurbine`, `RevTurbineProvider`, `useCan`, `useEntitlement`,
|
|
30
|
+
> `useGatedAction`) — every method a customer-facing guide, skill, the
|
|
31
|
+
> starter, or a demo app calls directly. The remaining ~33 methods are
|
|
32
|
+
> internal-only paths (called only by the SDK's own placement components,
|
|
33
|
+
> React bindings, or other internal packages) and stay untagged, so a
|
|
34
|
+
> breaking change to one of *those* still will not be caught automatically —
|
|
35
|
+
> it depends on whoever writes the PR. Entries here are reliable; the absence
|
|
36
|
+
> of an entry for a currently-untagged method is not yet proof that nothing
|
|
37
|
+
> changed.
|
|
31
38
|
|
|
32
39
|
> **Note on 0.x.** These packages are pre-1.0, so breaking changes ship in the
|
|
33
40
|
> **minor** position (`0.6.0` → `0.7.0`), not the major. `npm`'s caret on a `0.x`
|
|
@@ -40,6 +47,93 @@ also require a changelog entry.
|
|
|
40
47
|
|
|
41
48
|
---
|
|
42
49
|
|
|
50
|
+
## 0.10.2
|
|
51
|
+
|
|
52
|
+
### Local mode resolves placements by slot id (BL-0119)
|
|
53
|
+
|
|
54
|
+
**What changed.** In `local_only` mode the browser SDK now resolves a placement
|
|
55
|
+
request against the Playbook's authored `placement_slots[]` registry.
|
|
56
|
+
`getPlacement({ slotId })` — with or without a `componentType` — previously
|
|
57
|
+
returned `null` for a slot the Playbook declared, and a controller/`usePlacement`
|
|
58
|
+
mount of that slot resolved to `placement_not_found`. Looking the same placement
|
|
59
|
+
up by **name** worked, which is what made this look like a config problem rather
|
|
60
|
+
than an SDK one.
|
|
61
|
+
|
|
62
|
+
Two things were missing, and both are now in place:
|
|
63
|
+
|
|
64
|
+
- **`registerSurfaceSlot()` adopts the declared template.** `surface_template_ids`
|
|
65
|
+
on the registered record is what puts the shared resolver on its slot branch,
|
|
66
|
+
where `trigger.slot_id` is matched. Without it the resolver fell back to direct
|
|
67
|
+
lookup, which is keyed by placement **name**/id and therefore can never match a
|
|
68
|
+
slot id — hence `placement_not_found`. An id passed explicitly at the call site
|
|
69
|
+
still wins; the mounting code knows what it renders.
|
|
70
|
+
- **`getPlacement()` falls through to the slot registry.** The local placement
|
|
71
|
+
cache only holds slots a decision has already run through, so a cold lookup
|
|
72
|
+
found nothing and stopped. It now derives the record from `placement_slots`,
|
|
73
|
+
matching on `id` and falling back to `surface_type` when only a component type
|
|
74
|
+
is given — the same derivation scaffold's headless
|
|
75
|
+
`LocalRuntime.slotRecordForConfig` has always performed. Registration on this
|
|
76
|
+
path is local only: reading a placement never writes a surface slot back to the
|
|
77
|
+
control plane.
|
|
78
|
+
|
|
79
|
+
This closes a browser-versus-headless divergence: the same Playbook decided
|
|
80
|
+
differently depending on which runtime read it. No public API change — no
|
|
81
|
+
signature moved, and nothing new is asked of the caller. A slot id that no
|
|
82
|
+
`placement_slots` entry declares still resolves to `null`, unchanged.
|
|
83
|
+
|
|
84
|
+
**Landed in** `0.10.2`. **Fail-closed in** n/a — a previously-`null` lookup now
|
|
85
|
+
returns the placement the Playbook authored.
|
|
86
|
+
|
|
87
|
+
**Proving test:** `web-sdk/local-slot-id-lookup.test.ts` — by-slot-id and
|
|
88
|
+
by-slot-id-plus-component-type both resolve, the controller path no longer
|
|
89
|
+
reports `placement_not_found`, an undeclared slot id still returns `null` and
|
|
90
|
+
gains no invented template, an explicit `surfaceTemplateIds` still wins, and the
|
|
91
|
+
by-name lookup that always worked keeps working (the positive control).
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## 0.10.1
|
|
96
|
+
|
|
97
|
+
### Treatment interactions carry the identified `account_id`
|
|
98
|
+
|
|
99
|
+
**What changed.** Every treatment interaction the SDK sends to
|
|
100
|
+
`/api/events/interactions` — the impression that writes a
|
|
101
|
+
`placement_presentations` row, plus dismiss / click / conversion — now carries
|
|
102
|
+
`account_id`, taken from the account the integration identified
|
|
103
|
+
(`identify(userId, { account_id })` / `setUserContext`). It was never sent at
|
|
104
|
+
all, so the ingest route's `account_id ?? user_id` fallback stamped a **user**
|
|
105
|
+
id into an **account** column. `placement_presentations.account_id` is a join
|
|
106
|
+
key, not a label: `monetization_funnel` matches it against account ids from
|
|
107
|
+
`events_clickstream` / `events_billing`, and every experiment summary pipe
|
|
108
|
+
reads it when `analysis_unit='account'`. Those joins therefore matched only
|
|
109
|
+
where a user id happened to equal an account id — and an account-grain
|
|
110
|
+
experiment readout returned the user-grain n while looking perfectly valid.
|
|
111
|
+
|
|
112
|
+
Two details make it a usable key. The value is PII-redacted **identically to
|
|
113
|
+
`/api/track`**, so an email-shaped account id becomes the same hash in
|
|
114
|
+
`placement_presentations` and in `events_clickstream` and the funnel actually
|
|
115
|
+
joins. And when no account was identified the field is **omitted**, never set
|
|
116
|
+
to the user id — the route keeps its own fallback for SDKs that have not
|
|
117
|
+
upgraded, but a wrong join key is worse than a missing one.
|
|
118
|
+
|
|
119
|
+
No public API change: nothing new is asked of the caller, and
|
|
120
|
+
`RevTurbineTreatmentInteractionInput` is unchanged. Integrations that already
|
|
121
|
+
pass `account_id` to `identify()` get correct account-grain analytics with no
|
|
122
|
+
code change; integrations that never identify an account are unaffected on the
|
|
123
|
+
wire and see the same route-side fallback as before.
|
|
124
|
+
|
|
125
|
+
**Landed in** `0.10.1`. **Fail-closed in** n/a — additive; nothing old is
|
|
126
|
+
rejected.
|
|
127
|
+
|
|
128
|
+
**Proving test:** `web-sdk/interaction-wire-contract.test.ts` — "the account
|
|
129
|
+
identity the analytics joins key on": the identified account reaches the wire
|
|
130
|
+
distinct from `user_id`, an unidentified one is omitted rather than copied from
|
|
131
|
+
`user_id`, an email-shaped account id matches the `/api/track` lane
|
|
132
|
+
byte-for-byte, and a re-queued batch keeps the account that was acting when
|
|
133
|
+
each interaction happened.
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
43
137
|
## 0.10.0
|
|
44
138
|
|
|
45
139
|
### `publicKey` is the browser credential; `apiKey` is the server key
|