@revturbine/sdk 0.2.85 → 0.2.86

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.
@@ -1,173 +0,0 @@
1
- /**
2
- * @module @revt-eng/web-sdk/server
3
- *
4
- * Server-side entitlement and placement decisions for React Server Components
5
- * (plan 186 TASK-3).
6
- *
7
- * A React hook cannot run in a Server Component: every module under `react/`
8
- * opens with `'use client'`, so importing one from the server graph yields an
9
- * opaque client reference rather than a callable. This module is the server
10
- * half — the same decisions, awaited instead of subscribed to.
11
- *
12
- * ```tsx
13
- * // app/page.tsx — a Server Component, no 'use client'
14
- * const rt = createServerClient({ tenantId, playbook });
15
- * const { denied } = await getEntitlement(rt, 'brand_kit', { user: { id: userId } });
16
- * return denied ? <UpgradePrompt /> : <BrandKitEditor />;
17
- * ```
18
- *
19
- * Three properties are deliberate and load-bearing:
20
- *
21
- * - **Local by default.** An RSC tree re-renders per request, so a network hop
22
- * per decision is a latency tax the client SDK never paid. With a `playbook`
23
- * the decision resolves in-process and keeps working when the control plane
24
- * is unreachable. Remote is available by explicit configuration.
25
- * - **Fail closed.** Any evaluation failure resolves denied / not-visible and
26
- * never throws into the render tree — a control-plane outage must not turn
27
- * into an error boundary, and must never accidentally grant paid access.
28
- * - **No lifecycle fields.** The returned {@link EntitlementView} carries no
29
- * `isLoading` and no `recheck`: the value is awaited, so it is always
30
- * decided and there is nothing to re-run mid-render. Synthesizing them would
31
- * be a lie the type system then endorses.
32
- *
33
- * The credential passed here — a long-lived `server` api-token — must never
34
- * reach the browser. It is accepted only by {@link createServerClient}, is
35
- * never placed on a returned value, and never appears in the hydration payload
36
- * handed to `RevTurbineProvider`.
37
- *
38
- * Plan: docs/dev-lifecycle/inprogress/186-server-rendering-sdk-and-api-token-management.md
39
- */
40
- import { type ConfigArtifact } from '../config-artifact';
41
- import type { EntitlementView, PlacementView } from '../views';
42
- import type { RevTurbineEntitlementContext } from '../customer-side';
43
- /**
44
- * The end user a server-side decision is evaluated for.
45
- *
46
- * There is no ambient user on the server — a Server Component has no provider
47
- * to read from — so the caller states it explicitly. Plan 186 TASK-4 adds an
48
- * optional request-scoped form that supplies this implicitly.
49
- */
50
- export interface ServerUser {
51
- /** The end-user identifier decisions are evaluated for. */
52
- id: string;
53
- /** The user's current plan handle, used to resolve entitlement rules. */
54
- planHandle?: string;
55
- /** Targeting traits for segment evaluation. */
56
- traits?: Record<string, string | number | boolean>;
57
- }
58
- /** How a {@link RevTurbineServerClient} reaches its decisions. */
59
- export type ServerTransport = 'local' | 'remote';
60
- /**
61
- * Configuration for {@link createServerClient}.
62
- *
63
- * Supply a `playbook` for local mode (the default). Supply `endpoint` +
64
- * `apiToken` for remote mode, which is selected automatically when no playbook
65
- * is present and can be forced with `transport: 'remote'`.
66
- */
67
- export interface ServerClientOptions {
68
- /** Tenant the decisions belong to. */
69
- tenantId: string;
70
- /**
71
- * The bundled Playbook. Its presence selects local mode, where decisions
72
- * resolve in-process with no network call.
73
- */
74
- playbook?: ConfigArtifact;
75
- /** Target environment for Playbooks that predate environment stamping. */
76
- environmentId?: string;
77
- /**
78
- * A long-lived `server` api-token, for remote mode.
79
- *
80
- * Server-only. Never return it to the browser, never place it in props, and
81
- * never embed it in a hydration payload.
82
- */
83
- apiToken?: string;
84
- /** Control-plane origin, for remote mode. */
85
- endpoint?: string;
86
- /** Force a transport. Defaults to `'local'` whenever a `playbook` is given. */
87
- transport?: ServerTransport;
88
- }
89
- /**
90
- * A server-side decision client.
91
- *
92
- * Create one per process (or per request) with {@link createServerClient} and
93
- * pass it to {@link getEntitlement} / {@link getPlacement}. Holds no per-user
94
- * state, so it is safe to share across concurrent requests.
95
- */
96
- export declare class RevTurbineServerClient {
97
- #private;
98
- /** Tenant the decisions belong to. */
99
- readonly tenantId: string;
100
- /** How this client reaches its decisions. */
101
- readonly transport: ServerTransport;
102
- constructor(options: ServerClientOptions);
103
- /**
104
- * A runtime bound to one user.
105
- *
106
- * Built per call rather than once per client: `LocalRuntime` takes its
107
- * `userId` at construction and `createStaticProviders` resolves entitlement
108
- * rules against a specific `planHandle`, so a shared instance would evaluate
109
- * every request against whichever user built it. (This is also why the
110
- * existing `LocalEvaluationServer`, whose runtime is constructed once with
111
- * `userId: '__server__'`, cannot answer a per-user entitlement question.)
112
- * Plan 186 TASK-4 memoizes this per request via React `cache()`.
113
- */
114
- private runtimeFor;
115
- /** @internal Resolve one entitlement, fail-closed. */
116
- _entitlement(handle: string, user: ServerUser, context?: RevTurbineEntitlementContext): Promise<EntitlementView>;
117
- /** @internal Resolve one placement, fail-closed. */
118
- _placement(placementId: string, user: ServerUser): Promise<PlacementView>;
119
- }
120
- /**
121
- * Create a server-side decision client.
122
- *
123
- * @param options - Transport and tenant configuration. A `playbook` selects
124
- * local mode; `endpoint` + `apiToken` select remote.
125
- *
126
- * @example
127
- * ```ts
128
- * import playbook from '../revturbine.playbook.json';
129
- * export const rt = createServerClient({ tenantId: 'tn_acme', playbook });
130
- * ```
131
- */
132
- export declare function createServerClient(options: ServerClientOptions): RevTurbineServerClient;
133
- /**
134
- * Resolve one entitlement for one user, from a Server Component.
135
- *
136
- * Never throws: an evaluation failure resolves denied, so a control-plane
137
- * outage cannot become an error boundary and cannot accidentally grant access.
138
- *
139
- * Gate paid UI on `denied` rather than on `!allowed` — a `limited` result still
140
- * grants access when the evaluator permits it.
141
- *
142
- * @param client - From {@link createServerClient}.
143
- * @param handle - The entitlement handle, e.g. `'brand_kit'`.
144
- * @param input - The user to evaluate for, and optional usage context.
145
- *
146
- * @example
147
- * ```tsx
148
- * const { denied } = await getEntitlement(rt, 'brand_kit', { user: { id: userId } });
149
- * if (denied) return <UpgradePrompt />;
150
- * ```
151
- */
152
- export declare function getEntitlement(client: RevTurbineServerClient, handle: string, input: {
153
- user: ServerUser;
154
- context?: RevTurbineEntitlementContext;
155
- }): Promise<EntitlementView>;
156
- /**
157
- * Resolve one placement decision for one user, from a Server Component.
158
- *
159
- * Never throws: an evaluation failure resolves not-visible, so a failed
160
- * decision hides the surface rather than breaking the page.
161
- *
162
- * The result carries no interaction callbacks — `dismiss`, `ctaClick` and
163
- * viewport exposure are inherently client-side. Render the decision on the
164
- * server and let a client component own the interactions.
165
- *
166
- * @param client - From {@link createServerClient}.
167
- * @param input - The placement to resolve and the user to resolve it for.
168
- */
169
- export declare function getPlacement(client: RevTurbineServerClient, input: {
170
- placementId: string;
171
- user: ServerUser;
172
- }): Promise<PlacementView>;
173
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAKH,OAAO,EAA4B,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACnF,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC/D,OAAO,KAAK,EAEV,4BAA4B,EAE7B,MAAM,kBAAkB,CAAC;AAE1B;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,2DAA2D;IAC3D,EAAE,EAAE,MAAM,CAAC;IACX,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+CAA+C;IAC/C,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;CACpD;AAED,kEAAkE;AAClE,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEjD;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,0EAA0E;IAC1E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,eAAe,CAAC;CAC7B;AAqCD;;;;;;GAMG;AACH,qBAAa,sBAAsB;;IACjC,sCAAsC;IACtC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,6CAA6C;IAC7C,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;gBAYxB,OAAO,EAAE,mBAAmB;IA0BxC;;;;;;;;;;OAUG;IACH,OAAO,CAAC,UAAU;IAelB,sDAAsD;IAChD,YAAY,CAChB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,UAAU,EAChB,OAAO,CAAC,EAAE,4BAA4B,GACrC,OAAO,CAAC,eAAe,CAAC;IAY3B,oDAAoD;IAC9C,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC;CA0BhF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,GAAG,sBAAsB,CAEvF;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,sBAAsB,EAC9B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,CAAC,EAAE,4BAA4B,CAAA;CAAE,GAClE,OAAO,CAAC,eAAe,CAAC,CAE1B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,sBAAsB,EAC9B,KAAK,EAAE;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GAC/C,OAAO,CAAC,aAAa,CAAC,CAExB"}
@@ -1,65 +0,0 @@
1
- /**
2
- * @module @revt-eng/web-sdk/views
3
- *
4
- * The decision shapes a caller reads, independent of *how* the decision was
5
- * obtained (plan 186 TASK-1).
6
- *
7
- * A React hook resolves a decision over time, so its result carries lifecycle
8
- * fields — `isLoading`, `error`, a re-run callback. A server-rendered caller
9
- * awaits the decision, so it has none of those: by the time it holds a value,
10
- * the value is final. What both share is the decision itself, and that shared
11
- * part lives here.
12
- *
13
- * This module deliberately contains **types only and no runtime imports**, and
14
- * deliberately sits outside `react/`. Every module under `react/` opens with
15
- * `'use client'`, so a React Server Component importing one receives an opaque
16
- * client reference rather than a usable value — the server binding could not
17
- * reuse these shapes if they stayed there.
18
- *
19
- * Plan: docs/dev-lifecycle/inprogress/186-server-rendering-sdk-and-api-token-management.md
20
- */
21
- import type { EntitlementResult, PlacementOutput, RevTurbinePlacementContent, RevTurbinePlacementDecision } from './customer-side';
22
- /**
23
- * A resolved entitlement decision.
24
- *
25
- * The three booleans are conveniences over {@link EntitlementView.result} and
26
- * are mutually exclusive once resolved. Note that `allowed` and `limited` are
27
- * not opposites: a `limited` result still grants access when the evaluator
28
- * permits it, so gate paywall UI on `denied`, never on `!allowed`.
29
- *
30
- * Callers that need to distinguish "denied" from "not yet decided" want the
31
- * client-side {@link UseEntitlementResult}, whose `isLoading` carries that
32
- * distinction. On the server the question does not arise — the value is awaited,
33
- * so it is always decided.
34
- */
35
- export interface EntitlementView {
36
- /** The full entitlement result from the evaluator. `null` until resolved. */
37
- result: EntitlementResult | null;
38
- /** `true` when the entitlement is allowed outright. */
39
- allowed: boolean;
40
- /** `true` when access is granted but the balance is approaching its limit. */
41
- limited: boolean;
42
- /** `true` when the entitlement is denied. */
43
- denied: boolean;
44
- /** The upgrade surface to render on denial, when one was resolved. */
45
- gatedPlacement: PlacementOutput | null;
46
- }
47
- /**
48
- * A resolved placement decision.
49
- *
50
- * Carries what to render and whether to render it — not how to interact with
51
- * it. Interaction callbacks (`dismiss`, `ctaClick`, …) and viewport-exposure
52
- * wiring are inherently client-side and live on
53
- * {@link UsePlacementResult} instead.
54
- */
55
- export interface PlacementView {
56
- /** The resolved placement identifier. */
57
- placementId: string;
58
- /** Whether the placement should be rendered. */
59
- visible: boolean;
60
- /** The full decision from the engine. `null` until resolved. */
61
- decision: RevTurbinePlacementDecision | null;
62
- /** Resolved content with personalization tokens expanded. `null` until resolved. */
63
- content: RevTurbinePlacementContent['content'] | null;
64
- }
65
- //# sourceMappingURL=views.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"views.d.ts","sourceRoot":"","sources":["../../../views.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EACV,iBAAiB,EACjB,eAAe,EACf,0BAA0B,EAC1B,2BAA2B,EAC5B,MAAM,iBAAiB,CAAC;AAEzB;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,eAAe;IAC9B,6EAA6E;IAC7E,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACjC,uDAAuD;IACvD,OAAO,EAAE,OAAO,CAAC;IACjB,8EAA8E;IAC9E,OAAO,EAAE,OAAO,CAAC;IACjB,6CAA6C;IAC7C,MAAM,EAAE,OAAO,CAAC;IAChB,sEAAsE;IACtE,cAAc,EAAE,eAAe,GAAG,IAAI,CAAC;CACxC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC5B,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,OAAO,EAAE,OAAO,CAAC;IACjB,gEAAgE;IAChE,QAAQ,EAAE,2BAA2B,GAAG,IAAI,CAAC;IAC7C,oFAAoF;IACpF,OAAO,EAAE,0BAA0B,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;CACvD"}