@revturbine/sdk 0.11.18 → 0.11.20
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 +90 -0
- package/dist/growthbook.d.ts +16 -1
- package/dist/headless.d.ts +296 -21
- package/dist/headless.js +2 -2
- package/dist/headless.js.map +1 -1
- package/dist/index.d.ts +322 -23
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/optimizely.d.ts +16 -1
- package/dist/types/server-node/local-server.d.ts +13 -1
- package/dist/types/server-node/local-server.d.ts.map +1 -1
- package/dist/types/web-sdk/customer-side.d.ts +70 -16
- package/dist/types/web-sdk/customer-side.d.ts.map +1 -1
- package/dist/types/web-sdk/placements/AccessDeniedPlaceholder.d.ts +25 -0
- package/dist/types/web-sdk/placements/AccessDeniedPlaceholder.d.ts.map +1 -0
- package/dist/types/web-sdk/placements/AccessGateSurfaceSlot.d.ts +2 -1
- package/dist/types/web-sdk/placements/AccessGateSurfaceSlot.d.ts.map +1 -1
- package/dist/types/web-sdk/placements/index.d.ts +2 -0
- package/dist/types/web-sdk/placements/index.d.ts.map +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -47,6 +47,96 @@ also require a changelog entry.
|
|
|
47
47
|
|
|
48
48
|
---
|
|
49
49
|
|
|
50
|
+
## 0.11.20
|
|
51
|
+
|
|
52
|
+
### One entitlement answer for browser and server, with Entitlement Mirroring; Access Gates only fire while denied (D-60, D-61)
|
|
53
|
+
|
|
54
|
+
**What changed.** Behaviour change in every port. Browser and server now run
|
|
55
|
+
the same evaluation on the same inputs: the browser is trusted for
|
|
56
|
+
interaction, and the server verifies.
|
|
57
|
+
|
|
58
|
+
- **One effective entitlement (ts/py/rs/web).** Every entitlement check runs
|
|
59
|
+
the shared core evaluator over the Playbook and the user context (plan,
|
|
60
|
+
segments, usage, reverse-trial grants), then merges app-supplied data. Server
|
|
61
|
+
runtimes previously used a separate rule path that ignored reverse-trial
|
|
62
|
+
grants and allowed everything when the Playbook had no entitlement rules.
|
|
63
|
+
**Server-side results change for the live design partner:** a configured
|
|
64
|
+
entitlement with no rule for the user's plan is now denied on the server
|
|
65
|
+
too, and reverse-trial grants are honoured there.
|
|
66
|
+
- **Entitlement Mirroring.** `UserContext.entitlements` accepts a boolean or a
|
|
67
|
+
grant (`status`, `limit`, `used`), and an app entitlement provider's
|
|
68
|
+
entries count as app data. By default the app's data wins;
|
|
69
|
+
`entitlementMerge` (`entitlement_merge` in Python and Rust) sets provider-level
|
|
70
|
+
`precedence` and per-field overrides. Browser-supplied data shapes the UI;
|
|
71
|
+
the server re-check stays authoritative.
|
|
72
|
+
- **Unknown entitlement handles fail closed.** A handle neither the Playbook
|
|
73
|
+
nor the app knows is denied with `entitlement_not_in_playbook`, warned once,
|
|
74
|
+
and reported (browser telemetry; `onUnknownEntitlement` on the server).
|
|
75
|
+
0.11.19 returned `entitlement_not_found_default_allow`.
|
|
76
|
+
- **Access Gates (D-60).** A gate placement appears only in an Access Gate
|
|
77
|
+
slot and fires only while its entitlement is denied or limited (a
|
|
78
|
+
tier-scoped gate below its tier counts as limited). Placement gates read the
|
|
79
|
+
same effective entitlements `checkEntitlement` returns.
|
|
80
|
+
- **Reason codes.** New entitlement reason `entitlement_mirrored`; new
|
|
81
|
+
placement reasons `entitlement_not_denied` and `gate_outside_access_gate`.
|
|
82
|
+
- **Scaffold pin 0.1.402 → 0.1.409** (revturbine-scaffold #462, #465
|
|
83
|
+
and #468; vendored `types.py` / `types.rs` refreshed).
|
|
84
|
+
|
|
85
|
+
**Landed in** 0.11.20. **Fail-closed in** 0.11.20.
|
|
86
|
+
|
|
87
|
+
**Proving tests.** `web-sdk/entitlement-mirroring.test.ts`; the D-60/D-61
|
|
88
|
+
blocks in each port's resolver and runtime tests; parity fixtures
|
|
89
|
+
`placement_slot_selection_is_category_first` and
|
|
90
|
+
`placement_category_interactions`.
|
|
91
|
+
|
|
92
|
+
## 0.11.19
|
|
93
|
+
|
|
94
|
+
### Placement decisions rank category first; caps run before the pick; overall presentation cap rules enforced (D-59, BL-0536)
|
|
95
|
+
|
|
96
|
+
**What changed.** Behaviour change in every port; no public signature changes.
|
|
97
|
+
|
|
98
|
+
- **Ranking (ts/py/rs).** When several placements qualify for one slot, the
|
|
99
|
+
decision now ranks by category first — Access Gates, then Fixed, then
|
|
100
|
+
usage/credit/seat + trial alerts, then conversion/retention nudges — and
|
|
101
|
+
then within the category: two-stage urgency for alerts (trial transition,
|
|
102
|
+
then limit reached, then approaching; then proximity), drag order
|
|
103
|
+
otherwise. 0.11.18 took the first eligible placement in list order (D-34),
|
|
104
|
+
so an "approaching" warning listed above a "limit reached" alert used to
|
|
105
|
+
win; now the limit-reached alert wins. Equal drag order across the two
|
|
106
|
+
categories of a shared tier resolves Usage before Trials and Conversion
|
|
107
|
+
before Retention. Among fired usage thresholds on one entitlement, the
|
|
108
|
+
highest wins.
|
|
109
|
+
- **Caps before the pick (web).** A placement over its per-payload cap or an
|
|
110
|
+
overall presentation cap is skipped and the next-ranked placement is shown.
|
|
111
|
+
0.11.18 picked first, then hid the slot. A cached decision whose winner is
|
|
112
|
+
now capped re-resolves instead of blanking the slot.
|
|
113
|
+
- **Payload caps are enforced (web).** Playbook-authored `max_per_period` /
|
|
114
|
+
`cooldown_days` never reached the cap check; they now do. A placement with
|
|
115
|
+
authored caps may now stop showing where 0.11.18 kept showing it.
|
|
116
|
+
- **Overall presentation cap rules (web).** The Placement Settings cap rules
|
|
117
|
+
and session cooldown (`placement_settings[].global_frequency_cap`) are
|
|
118
|
+
enforced for conversion/retention placements, persisted per user;
|
|
119
|
+
`session` periods count from the tab session's start.
|
|
120
|
+
- **Access Gate slots (all ports + web).** A slot that asks for an
|
|
121
|
+
entitlement is answered only by that entitlement's placements; with none
|
|
122
|
+
authored, the decision is `no_gate_for_entitlement` and
|
|
123
|
+
`<AccessGateSurfaceSlot>` renders the new `<AccessDeniedPlaceholder>`
|
|
124
|
+
unless the app passes `deniedFallback`. 0.11.18 showed any other gate on
|
|
125
|
+
the same template.
|
|
126
|
+
- **Reason codes.** New placement reasons `no_gate_for_entitlement`,
|
|
127
|
+
`suppressed_by_presentation_cap` and `suppressed_by_system_cooldown`
|
|
128
|
+
(added to the reason-code baseline).
|
|
129
|
+
- **Scaffold pin 0.1.383 → 0.1.402** (`@revt-eng/core` with revturbine-scaffold #460; vendored `types.py` / `types.rs` refreshed).
|
|
130
|
+
|
|
131
|
+
**Landed in** 0.11.19. **Fail-closed in** 0.11.19.
|
|
132
|
+
|
|
133
|
+
**Proving tests.** Parity fixtures `placement_slot_selection_is_category_first`,
|
|
134
|
+
`placement_limit_reached_beats_approaching` and
|
|
135
|
+
`placement_shared_tier_tie_resolves_by_category` (they replace
|
|
136
|
+
`placement_slot_selection_is_entry_order` and
|
|
137
|
+
`placement_first_eligible_beats_urgency`); `web-sdk/presentation-cap-rules.test.ts`;
|
|
138
|
+
`web-sdk/placements/AccessGateSurfaceSlot.placeholder.test.tsx`.
|
|
139
|
+
|
|
50
140
|
## 0.11.18
|
|
51
141
|
|
|
52
142
|
### Scaffold pin 0.1.383: interaction decision context moves onto core's input type; `growth_signal_observed` retired (plan 282 TASK-9 follow-up, BL-0463)
|
package/dist/growthbook.d.ts
CHANGED
|
@@ -293,6 +293,16 @@ type JsonValue = string | number | boolean | null | JsonValue[] | {
|
|
|
293
293
|
[key: string]: JsonValue;
|
|
294
294
|
};
|
|
295
295
|
|
|
296
|
+
/** A mirrored grant on `UserContext.entitlements`: a boolean, or a grant-shaped record. */
|
|
297
|
+
type MirroredEntitlement = boolean | {
|
|
298
|
+
status?: string;
|
|
299
|
+
allowed?: boolean;
|
|
300
|
+
limit?: number;
|
|
301
|
+
used?: number;
|
|
302
|
+
remaining?: number;
|
|
303
|
+
reason?: string;
|
|
304
|
+
};
|
|
305
|
+
|
|
296
306
|
/**
|
|
297
307
|
* User context lifecycle — pure functions for building, merging,
|
|
298
308
|
* and deriving targeting state from user context + RevTurbineConfig.
|
|
@@ -315,7 +325,12 @@ interface UserContextSnapshot {
|
|
|
315
325
|
*/
|
|
316
326
|
plan?: string | UserPlanContext;
|
|
317
327
|
custom?: Record<string, JsonValue>;
|
|
318
|
-
|
|
328
|
+
/**
|
|
329
|
+
* App-supplied entitlement data keyed by handle — a boolean or a grant
|
|
330
|
+
* (D-61 Entitlement Mirroring). Merged with the Playbook evaluation by the
|
|
331
|
+
* effective-entitlement core; flattened into segment traits as a boolean.
|
|
332
|
+
*/
|
|
333
|
+
entitlements?: Record<string, MirroredEntitlement>;
|
|
319
334
|
usage?: Record<string, UserUsageEntry>;
|
|
320
335
|
personalization?: Record<string, JsonValue>;
|
|
321
336
|
/** Canonical experiment-handle to variant-handle assignments. */
|