@revturbine/sdk 0.10.1 → 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 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 is
26
- > thin: as of `0.8.0` it covers **4** methods on `RevTurbineCustomerSdk`, which
27
- > declares roughly **73**. `can()`, `getPlacementDecision()`, `identify()` and
28
- > `dismiss()` are among the untagged, so a breaking change to one of them will
29
- > not be caught automatically — it depends on whoever writes the PR. Entries here
30
- > are reliable; the absence of an entry is not yet proof that nothing changed.
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,51 @@ 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
+
43
95
  ## 0.10.1
44
96
 
45
97
  ### Treatment interactions carry the identified `account_id`