@revturbine/sdk 0.10.9 → 0.11.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 +181 -5
- package/dist/headless.d.ts +240 -64
- package/dist/headless.js +2 -2
- package/dist/headless.js.map +1 -1
- package/dist/index.d.ts +240 -64
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/types/server-node/local-server.d.ts +10 -2
- package/dist/types/server-node/local-server.d.ts.map +1 -1
- package/dist/types/web-sdk/browser-runtime.d.ts +27 -6
- package/dist/types/web-sdk/browser-runtime.d.ts.map +1 -1
- package/dist/types/web-sdk/customer-side.d.ts +136 -43
- package/dist/types/web-sdk/customer-side.d.ts.map +1 -1
- package/dist/types/web-sdk/index.d.ts +3 -2
- package/dist/types/web-sdk/index.d.ts.map +1 -1
- package/dist/types/web-sdk/playbook-option.d.ts +39 -0
- package/dist/types/web-sdk/playbook-option.d.ts.map +1 -0
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -47,6 +47,171 @@ also require a changelog entry.
|
|
|
47
47
|
|
|
48
48
|
---
|
|
49
49
|
|
|
50
|
+
## 0.11.0
|
|
51
|
+
|
|
52
|
+
### `Playbook` is the canonical name for every option that carries one (BL-0156)
|
|
53
|
+
|
|
54
|
+
**What changed.** `ExportedConfig` is dead vocabulary. Plan 118 renamed the
|
|
55
|
+
domain object to **Playbook** and plan 104 renamed the schema type to
|
|
56
|
+
`RevTurbineConfig`, but the *option*, *keyword* and *method* names that carry a
|
|
57
|
+
Playbook around the SDK still spelled it `exportedConfig` / `exported_config`.
|
|
58
|
+
Every one of them now has a `Playbook`-named counterpart; every old name stays
|
|
59
|
+
as a deprecated alias that still works.
|
|
60
|
+
|
|
61
|
+
TypeScript:
|
|
62
|
+
|
|
63
|
+
| deprecated | canonical |
|
|
64
|
+
|---|---|
|
|
65
|
+
| `localRuntime.exportedConfig` | `localRuntime.playbook` (already shipped; see below) |
|
|
66
|
+
| `localRuntime.resolvers.resolveExportedConfig` | `localRuntime.resolvers.resolvePlaybook` |
|
|
67
|
+
| `configProvider.getExportedConfig()` | `configProvider.getPlaybook()` |
|
|
68
|
+
| `sdk.getExportedConfig()` | `sdk.getPlaybook()` |
|
|
69
|
+
| `getPolicy().exportedConfigVersion` | `getPolicy().playbookVersion` |
|
|
70
|
+
| `BrowserRuntimeOptions.exportedConfig` | `BrowserRuntimeOptions.playbook` |
|
|
71
|
+
| `LocalEvaluationServerOptions.exportedConfig` | `LocalEvaluationServerOptions.playbook` |
|
|
72
|
+
| `ExportedConfigProvider` (type) | `RevTurbineConfigProvider`, also exported as `PlaybookProvider` |
|
|
73
|
+
| `ExportedConfig` (type) | `Playbook` |
|
|
74
|
+
|
|
75
|
+
Python: `RevTurbineCustomerSdk(exported_config=…)`, `LocalRuntime(exported_config=…)`,
|
|
76
|
+
`LocalRuntime.get_exported_config()`, `create_static_placement_resolver(exported_config=…)`,
|
|
77
|
+
`derive_local_entitlement_from_configured_rules(exported_config=…)`,
|
|
78
|
+
`configured_plan_name_from_exported_config`, `parse_exported_config_or_throw` and
|
|
79
|
+
`static.ExportedConfig` all gained `playbook`-spelled counterparts.
|
|
80
|
+
|
|
81
|
+
Rust: `configured_plan_name_from_exported_config` is now
|
|
82
|
+
`configured_plan_name_from_playbook`, with the old name kept as the crate's
|
|
83
|
+
first `#[deprecated]` item. Rust has no keyword arguments, so nothing else in
|
|
84
|
+
that port was a caller-visible name.
|
|
85
|
+
|
|
86
|
+
`RevTurbineConfigProvider`'s two accessors are both OPTIONAL on the interface so
|
|
87
|
+
that an existing `implements RevTurbineConfigProvider` clause keeps compiling;
|
|
88
|
+
the `configProvider` option intersects it with a union that still requires
|
|
89
|
+
exactly one of them, so a provider implementing neither is a compile error where
|
|
90
|
+
it is passed.
|
|
91
|
+
|
|
92
|
+
Reading a deprecated name logs **one** development-build warning per runtime
|
|
93
|
+
(one `DeprecationWarning` per process on Python) naming the canonical
|
|
94
|
+
replacement — one flag for every alias, so an integration still spelling several
|
|
95
|
+
of them gets a single line, not a wall. Production builds are silent. Requires
|
|
96
|
+
`@revt-eng/core` ≥ 0.1.331, which made the same rename upstream (scaffold #380).
|
|
97
|
+
|
|
98
|
+
Ruling: Kent, 2026-09-23 (BL-0156).
|
|
99
|
+
|
|
100
|
+
**Landed in** `0.11.0`. **Fail-closed in** `0.12.0` for the `ExportedConfig`
|
|
101
|
+
aliases — until then every old name works and warns once.
|
|
102
|
+
|
|
103
|
+
**Proving test:** `web-sdk/playbook-option.test.ts` (canonical never warns, the
|
|
104
|
+
alias still resolves, one warning across three read sites, both spellings reach
|
|
105
|
+
the same Playbook at every public read site),
|
|
106
|
+
`server-python/tests/test_playbook_option.py` (the same contract plus
|
|
107
|
+
`get_exported_config()`), and `server-rust/src/user_context.rs`
|
|
108
|
+
`playbook_rename_tests` (the alias returns exactly what the canonical returns).
|
|
109
|
+
|
|
110
|
+
### `localRuntime.playbook` is the canonical local-mode config key
|
|
111
|
+
|
|
112
|
+
**What changed.** The record this file owed and never carried: `localRuntime.playbook`
|
|
113
|
+
shipped earlier as the canonical spelling of `localRuntime.exportedConfig`, with
|
|
114
|
+
`resolveLocalPlaybook()` as the single resolver deciding precedence, but no
|
|
115
|
+
changelog entry was ever written for it — so an integration could not date the
|
|
116
|
+
change. It is recorded here rather than back-dated, because the version it
|
|
117
|
+
landed in is not the version this entry appears in and pretending otherwise is
|
|
118
|
+
exactly the confusion the "Landed in" / "Fail-closed in" split exists to
|
|
119
|
+
prevent. As of `0.11.0` the alias also warns once (it did not before).
|
|
120
|
+
|
|
121
|
+
**Landed in** a release before `0.11.0` (additive; the alias never stopped
|
|
122
|
+
working). **Fail-closed in** `0.12.0`, with the rest of the `ExportedConfig`
|
|
123
|
+
aliases.
|
|
124
|
+
|
|
125
|
+
**Proving test:** `web-sdk/playbook-option.test.ts` — `resolveLocalPlaybook`
|
|
126
|
+
accepts either key, prefers `playbook`, and warns only for the alias.
|
|
127
|
+
|
|
128
|
+
### `publicKey` is the only browser credential; `ingestPublicKey` is gone (BL-0113)
|
|
129
|
+
|
|
130
|
+
**What changed.** `0.10.0` made `publicKey` the browser credential and kept
|
|
131
|
+
`apiKey` and `ingestPublicKey` working as aliases "for one minor". This is that
|
|
132
|
+
minor:
|
|
133
|
+
|
|
134
|
+
- **`ingestPublicKey` is removed from `RevTurbineInitOptions`.** Passing it is
|
|
135
|
+
now a **type error**, including when the options are built in a variable
|
|
136
|
+
(`ExactInitOptions` rejects it there too).
|
|
137
|
+
- **`apiKey` is no longer read as a browser credential.** It still exists, and
|
|
138
|
+
still means exactly one thing: the secret **server key**, for
|
|
139
|
+
`@revturbine/sdk/server` and for the headless SDK on a backend. A browser init
|
|
140
|
+
that supplies only `apiKey` now resolves **no** browser credential and fails
|
|
141
|
+
at init, instead of silently sending a server key as the bearer.
|
|
142
|
+
|
|
143
|
+
`resolveBrowserPublicKey()` reads `publicKey` and nothing else, and
|
|
144
|
+
`resetBrowserKeyAliasWarning()` is gone with the warning it reset. Keyless
|
|
145
|
+
local-only init is unchanged, and the plan 95 anonymous `sdk_init` beacon now
|
|
146
|
+
keys off `publicKey` alone.
|
|
147
|
+
|
|
148
|
+
Ruling: Kent, 2026-09-23 (BL-0113), closing the window plan 257 opened.
|
|
149
|
+
|
|
150
|
+
**Landed in** `0.11.0`. **Fail-closed in** `0.11.0` — the same release. This IS
|
|
151
|
+
the fail-closed half of the `0.10.0` entry below; there is no further tolerance
|
|
152
|
+
window.
|
|
153
|
+
|
|
154
|
+
**Proving test:** `web-sdk/public-key-option.test.ts` (`publicKey` is the bearer
|
|
155
|
+
on ingest and every control-plane fetch; `apiKey` resolves nothing; nothing
|
|
156
|
+
warns), `web-sdk/customer-side-ingest.test.ts` (the bearer no longer carries the
|
|
157
|
+
server key), and `web-sdk/init-options-exactness.test-d.ts` (`ingestPublicKey`
|
|
158
|
+
is a type error inline AND in a variable — if the key is ever re-added, `tsc`
|
|
159
|
+
fails on the unused `@ts-expect-error`).
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## 0.10.10
|
|
164
|
+
|
|
165
|
+
### Trial tokens now reach placement content, not only `getPersonalizationTokens()` (BL-0169)
|
|
166
|
+
|
|
167
|
+
**What changed.** A placement whose copy authors `{{trial_days_remaining}}` or
|
|
168
|
+
`{{trial_days_total}}` now renders the live values. Content interpolation sources
|
|
169
|
+
its token map from the **output content itself**, so a provider-derived token
|
|
170
|
+
only reaches the copy if the resolver writes it onto that content first. The
|
|
171
|
+
usage lane always did (`usage_current`, `usage_limit`, `usage_percent`,
|
|
172
|
+
`usage_remaining`, `reset_date`); the trial lane never did, so a `trial_ending`
|
|
173
|
+
body reading `"{{trial_days_remaining}} days left"` shipped the literal
|
|
174
|
+
`{{trial_days_remaining}}` to the end user — on every port. The two names were
|
|
175
|
+
derived for `getPersonalizationTokens()` all along, which is why the gap survived:
|
|
176
|
+
a host that read the token map saw the right numbers and a host that authored the
|
|
177
|
+
token into copy did not.
|
|
178
|
+
|
|
179
|
+
| | before | now |
|
|
180
|
+
|---|---|---|
|
|
181
|
+
| `getPersonalizationTokens().trial_days_remaining` | live value | live value (unchanged) |
|
|
182
|
+
| content `{{trial_days_remaining}}` / `{{trial_days_total}}` | literal `{{…}}` | live value |
|
|
183
|
+
| `outputContent.trial_days_remaining` / `_total` | absent | written when the plan provider carries a finite number |
|
|
184
|
+
|
|
185
|
+
Identical on all three ports (`ts:local-resolver.ts`,
|
|
186
|
+
`py:core/placements/local_resolver.py`, `rs:placements/static_resolver.rs`): the
|
|
187
|
+
same two token names, a `Number.isFinite` guard, provider state winning over an
|
|
188
|
+
authored content value of the same key, and the value passed through **without
|
|
189
|
+
widening** — `day_number` 7 + `days_remaining` 3 is `trial_days_total` `10`, never
|
|
190
|
+
`10.0` (BL-0155).
|
|
191
|
+
|
|
192
|
+
**Who this reaches.** Any host whose placement copy authors either token. Copy
|
|
193
|
+
that hard-coded one of those keys as a decorative literal now has it overwritten
|
|
194
|
+
by live state — the same precedence the usage lane and
|
|
195
|
+
`derivePlacementPersonalizationTokens` have always had. `{{trial_plan_name}}` and
|
|
196
|
+
`{{trial_features_used}}` remain **not yet wired** by the placement-studio-ui
|
|
197
|
+
spec's own note and are untouched.
|
|
198
|
+
|
|
199
|
+
**Landed in.** `0.10.10`.
|
|
200
|
+
|
|
201
|
+
**Fail-closed in.** `0.10.10` — absence still leaves the raw token standing
|
|
202
|
+
rather than rendering `0`, so a host with no trial provider state sees exactly
|
|
203
|
+
what it saw before.
|
|
204
|
+
|
|
205
|
+
**Proving test.** Parity scenario `trial_tokens_in_content` under
|
|
206
|
+
`"normalize": "preserve-representation"` (byte-locked ts ≡ py ≡ rs), plus
|
|
207
|
+
`py:tests/placements/test_local_resolver.py` and `rs:tests/static_resolver.rs`
|
|
208
|
+
`trial_tokens_are_injected_from_plan_provider_state` and its two neighbours,
|
|
209
|
+
mirroring the scaffold-side `local-resolver.test.ts` cases. Needs
|
|
210
|
+
`@revt-eng/core` 0.1.331 or later (scaffold #382) for the TS half; this release
|
|
211
|
+
pins 0.1.332.
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
50
215
|
## 0.10.9
|
|
51
216
|
|
|
52
217
|
### The trial-status overlay no longer changes a number's type (BL-0155)
|
|
@@ -87,11 +252,21 @@ representation simply changes.
|
|
|
87
252
|
`server-python/tests/test_trial_overlay_upsert.py::test_overlay_preserves_integer_numeric_representation`
|
|
88
253
|
and `server-rust/src/sdk.rs::overlay_preserves_integer_numeric_representation`
|
|
89
254
|
— both assert the *type*, not just the value, because `100 == 100.0` in Python.
|
|
90
|
-
|
|
91
|
-
rule 4 collapses integral floats by design); scenario
|
|
92
|
-
`trial_overlay_integer_fields` locks that the three ports still decide
|
|
255
|
+
Scenario `trial_overlay_integer_fields` locks that the three ports still decide
|
|
93
256
|
identically from an all-integer trial status.
|
|
94
257
|
|
|
258
|
+
> **Correction, 2026-09-23 (BL-0158, harness-only — no release).** This entry
|
|
259
|
+
> originally said the parity corpus *cannot* see this class of divergence,
|
|
260
|
+
> because `tests/parity/normalize.*` rule 4 collapses integral floats by design
|
|
261
|
+
> and nothing in the corpus returned the overlaid provider state. Both halves
|
|
262
|
+
> are now closed and the sentence no longer holds:
|
|
263
|
+
> `trial_overlay_integer_fields` drives `resolveProviders` (already shipped on
|
|
264
|
+
> all three runtimes) under a new per-scenario
|
|
265
|
+
> `"normalize": "preserve-representation"` flag that turns the collapse off, so
|
|
266
|
+
> `14` and `14.0` are different bytes and the cross-language byte-diff fails on
|
|
267
|
+
> a widened field. No public API changed; the harness gained the ability to see
|
|
268
|
+
> provider state.
|
|
269
|
+
|
|
95
270
|
---
|
|
96
271
|
|
|
97
272
|
## 0.10.8
|
|
@@ -483,8 +658,9 @@ and the plan 95 anonymous `sdk_init` beacon still fires only when no public key
|
|
|
483
658
|
|
|
484
659
|
Ruling: Kent, 2026-09-21, devkit PR #808 (closed).
|
|
485
660
|
|
|
486
|
-
**Landed in** `0.10.0`. **Fail-closed in**
|
|
487
|
-
|
|
661
|
+
**Landed in** `0.10.0`. **Fail-closed in** `0.11.0` — `ingestPublicKey` was
|
|
662
|
+
removed from the options type and `apiKey` stopped being read as a browser
|
|
663
|
+
credential (BL-0113); see the `0.11.0` entry above.
|
|
488
664
|
|
|
489
665
|
**Proving test:** `web-sdk/public-key-option.test.ts` — precedence, the single
|
|
490
666
|
bearer across ingest and control-plane fetches, the browser-only warning, and
|