@sentientui/policy 0.3.3 → 0.5.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/dist/index.d.cts CHANGED
@@ -134,20 +134,49 @@ declare function validateSlotDecl(decl: SlotDecl): {
134
134
  */
135
135
  declare function slotResultFor(decl: SlotDecl, arm: string): SlotResult;
136
136
 
137
- /** Empirical-Bayes pooling strength: w = m / (m + exposures). */
137
+ /**
138
+ * Empirical-Bayes pooling strength, in pseudo-observations. A cell is born
139
+ * holding `m` imaginary trials drawn at its parent's rate, and its own data
140
+ * outvotes them once it has collected more than `m` real ones.
141
+ */
138
142
  declare const SHRINKAGE_M = 20;
139
143
  /**
140
- * Empirical-Bayes persona shrinkage at read time. Persona cells are born warm
141
- * (pooled posterior dominates at 0 exposures) and detach as their own data
142
- * accumulates. Formula pinned in CONTRACTS.md:
143
- * w = m / (m + persona.exposures)
144
- * alpha' = persona.alpha + w * pooled.alpha
145
- * beta' = persona.beta + w * pooled.beta
144
+ * Empirical-Bayes shrinkage toward a parent posterior, at read time.
145
+ * Pinned in CONTRACTS.md §4.
146
+ *
147
+ * A cell is born warm — with no data of its own it sits at the parent's rate —
148
+ * and detaches as its own evidence accumulates.
149
+ *
150
+ * mu = pooled.alpha / (pooled.alpha + pooled.beta) // parent's rate
151
+ * strength = m * mass / (mass + m), mass = pooled.alpha + pooled.beta
152
+ * alpha' = cell.alpha + strength * mu
153
+ * beta' = cell.beta + strength * (1 - mu)
154
+ *
155
+ * The prior contributes a FIXED number of pseudo-observations, never a copy of
156
+ * the parent's counts. That distinction is the whole point of this function.
157
+ * The previous form was `cell.alpha + w * pooled.alpha` with
158
+ * `w = m / (m + cell.exposures)`, which folded the parent's SAMPLE SIZE into
159
+ * the child, and broke in two compounding ways once a project had real traffic:
160
+ *
161
+ * - Because the write path expands every trial into the child, both marginals
162
+ * and the global row (`weightCellsFor`), the parent's counts grow with total
163
+ * project volume. A cell then needed roughly sqrt(m * N_parent) exposures
164
+ * before its own rate mattered — ~1,400 against a 100k-exposure parent, not
165
+ * the ~20 the constant advertises. Personalization effectively never arrived.
166
+ * - Worse, the child inherited the parent's CONFIDENCE along with its rate. A
167
+ * 20-exposure cell emerged with a posterior of pseudo-count ~8,400 and a
168
+ * standard deviation of 0.002 against the ~0.09 its evidence justifies.
169
+ * Thompson Sampling draws from that posterior are effectively deterministic,
170
+ * so exploration collapsed exactly in the thin cells that needed it.
171
+ *
172
+ * `strength` is itself damped by the parent's mass so a parent that has barely
173
+ * any data of its own cannot inject `m` confident pseudo-observations of a rate
174
+ * nobody knows yet: an empty parent (mass 2, the flat Beta(1,1)) contributes
175
+ * ~1.8 pseudo-trials, a well-sampled one contributes the full `m`.
146
176
  */
147
- declare function shrunkPosterior(persona: {
177
+ declare function shrunkPosterior(cell: {
148
178
  alpha: number;
149
179
  beta: number;
150
- exposures: number;
151
180
  }, pooled: {
152
181
  alpha: number;
153
182
  beta: number;
@@ -191,11 +220,45 @@ declare function posteriorOfCounts(c: PoolCounts): {
191
220
  * Every cell is optional; an absent cell contributes Beta(1,1)-with-0-evidence,
192
221
  * which is what lets the same function reproduce the legacy variant (segment-only)
193
222
  * and legacy slot (persona-only) behaviors on day one after migration.
223
+ *
224
+ * Only the parent's MEAN crosses each shrink boundary (see shrunkPosterior) —
225
+ * never its sample size. That is what keeps a thin child's posterior as WIDE as
226
+ * its own evidence warrants, so Thompson Sampling still explores it. The blend
227
+ * weight below therefore decides which axis sets the parent's rate; the levels'
228
+ * absolute magnitudes no longer leak into the child's confidence.
194
229
  */
195
230
  declare function pooledPosterior(cells: PoolCells, personaKnown: boolean, m?: number): {
196
231
  alpha: number;
197
232
  beta: number;
198
233
  };
234
+ /** A weight row's value-posterior columns, plus the cell it belongs to. */
235
+ type ValueCellRow = {
236
+ segment: string;
237
+ persona: string;
238
+ valueSum: number;
239
+ valueCount: number;
240
+ };
241
+ /**
242
+ * The value cell for EV ranking: the BROADEST cell present for an arm.
243
+ *
244
+ * Never a sum across cells. `weightCellsFor` writes each trial to the child,
245
+ * both marginals AND the global row, so adding them up counts every real order
246
+ * 2-4x depending on whether the persona was known. The average survives that
247
+ * (numerator and denominator inflate together) but the EB shrinkage weight does
248
+ * not: `valueCount / (valueCount + EV_SHRINK_K)` with K = 20 is meant to give a
249
+ * cell its own voice at ~20 valued orders, and at 4x inflation it happened at
250
+ * 5 — by a factor that varied with the arm's persona mix, so identical arms
251
+ * shrank differently.
252
+ *
253
+ * The broadest cell already holds every trial in its slice exactly once, which
254
+ * makes this correct for both serving views: the pooled hierarchy (up to four
255
+ * rows per arm, global wins) and the legacy marginal view (exactly one row per
256
+ * arm, which is therefore the broadest).
257
+ */
258
+ declare function broadestValueCell(rows: readonly ValueCellRow[]): {
259
+ valueSum: number;
260
+ valueCount: number;
261
+ };
199
262
  /**
200
263
  * Write-side cell expansion: which weight rows one trial/credit must bump.
201
264
  * Unknown persona bumps ONLY the segment marginal + global — no 'unknown'
@@ -228,4 +291,14 @@ declare function pickDeterministicArm(sessionId: string, slotId: string, arms: s
228
291
  */
229
292
  declare function confidenceBand(c: number): 'low' | 'medium' | 'high';
230
293
 
231
- export { type ArmPosterior, CLUSTER_PRIORITY, LEGACY_PERSONA_MAP, type LearnedLayout, PERSONAS, PERSONA_DISPLAY, POOL_ALL, type Persona, type PersonaKey, type PoolCells, type PoolCounts, SHRINKAGE_M, type SlotDecl, type SlotResult, UNKNOWN_PERSONA, applyClusterHeuristic, candidateLayouts, canonicalArm, canonicalPersona, chooseLayout, confidenceBand, fnv1a, hashLayout, marginalArmKey, parseArm, pickDeterministicArm, pooledPosterior, posteriorOfCounts, sampleArm, sampleBeta, shrunkPosterior, slotBaselineArm, slotResultFor, validateSlotDecl, weightCellsFor };
294
+ /** = MIN_VALUED_CONVERSIONS: cells earn their own voice at ~20 valued orders. */
295
+ declare const EV_SHRINK_K = 20;
296
+ type ValueCell = {
297
+ valueSum: number;
298
+ valueCount: number;
299
+ };
300
+ declare function shrunkAvgValue(cell: ValueCell, reference: number, k?: number): number;
301
+ type EvArm = ArmPosterior & ValueCell;
302
+ declare function sampleArmEv(arms: EvArm[], reference: number, rand?: () => number): string | null;
303
+
304
+ export { type ArmPosterior, CLUSTER_PRIORITY, EV_SHRINK_K, type EvArm, LEGACY_PERSONA_MAP, type LearnedLayout, PERSONAS, PERSONA_DISPLAY, POOL_ALL, type Persona, type PersonaKey, type PoolCells, type PoolCounts, SHRINKAGE_M, type SlotDecl, type SlotResult, UNKNOWN_PERSONA, type ValueCell, type ValueCellRow, applyClusterHeuristic, broadestValueCell, candidateLayouts, canonicalArm, canonicalPersona, chooseLayout, confidenceBand, fnv1a, hashLayout, marginalArmKey, parseArm, pickDeterministicArm, pooledPosterior, posteriorOfCounts, sampleArm, sampleArmEv, sampleBeta, shrunkAvgValue, shrunkPosterior, slotBaselineArm, slotResultFor, validateSlotDecl, weightCellsFor };
package/dist/index.d.ts CHANGED
@@ -134,20 +134,49 @@ declare function validateSlotDecl(decl: SlotDecl): {
134
134
  */
135
135
  declare function slotResultFor(decl: SlotDecl, arm: string): SlotResult;
136
136
 
137
- /** Empirical-Bayes pooling strength: w = m / (m + exposures). */
137
+ /**
138
+ * Empirical-Bayes pooling strength, in pseudo-observations. A cell is born
139
+ * holding `m` imaginary trials drawn at its parent's rate, and its own data
140
+ * outvotes them once it has collected more than `m` real ones.
141
+ */
138
142
  declare const SHRINKAGE_M = 20;
139
143
  /**
140
- * Empirical-Bayes persona shrinkage at read time. Persona cells are born warm
141
- * (pooled posterior dominates at 0 exposures) and detach as their own data
142
- * accumulates. Formula pinned in CONTRACTS.md:
143
- * w = m / (m + persona.exposures)
144
- * alpha' = persona.alpha + w * pooled.alpha
145
- * beta' = persona.beta + w * pooled.beta
144
+ * Empirical-Bayes shrinkage toward a parent posterior, at read time.
145
+ * Pinned in CONTRACTS.md §4.
146
+ *
147
+ * A cell is born warm — with no data of its own it sits at the parent's rate —
148
+ * and detaches as its own evidence accumulates.
149
+ *
150
+ * mu = pooled.alpha / (pooled.alpha + pooled.beta) // parent's rate
151
+ * strength = m * mass / (mass + m), mass = pooled.alpha + pooled.beta
152
+ * alpha' = cell.alpha + strength * mu
153
+ * beta' = cell.beta + strength * (1 - mu)
154
+ *
155
+ * The prior contributes a FIXED number of pseudo-observations, never a copy of
156
+ * the parent's counts. That distinction is the whole point of this function.
157
+ * The previous form was `cell.alpha + w * pooled.alpha` with
158
+ * `w = m / (m + cell.exposures)`, which folded the parent's SAMPLE SIZE into
159
+ * the child, and broke in two compounding ways once a project had real traffic:
160
+ *
161
+ * - Because the write path expands every trial into the child, both marginals
162
+ * and the global row (`weightCellsFor`), the parent's counts grow with total
163
+ * project volume. A cell then needed roughly sqrt(m * N_parent) exposures
164
+ * before its own rate mattered — ~1,400 against a 100k-exposure parent, not
165
+ * the ~20 the constant advertises. Personalization effectively never arrived.
166
+ * - Worse, the child inherited the parent's CONFIDENCE along with its rate. A
167
+ * 20-exposure cell emerged with a posterior of pseudo-count ~8,400 and a
168
+ * standard deviation of 0.002 against the ~0.09 its evidence justifies.
169
+ * Thompson Sampling draws from that posterior are effectively deterministic,
170
+ * so exploration collapsed exactly in the thin cells that needed it.
171
+ *
172
+ * `strength` is itself damped by the parent's mass so a parent that has barely
173
+ * any data of its own cannot inject `m` confident pseudo-observations of a rate
174
+ * nobody knows yet: an empty parent (mass 2, the flat Beta(1,1)) contributes
175
+ * ~1.8 pseudo-trials, a well-sampled one contributes the full `m`.
146
176
  */
147
- declare function shrunkPosterior(persona: {
177
+ declare function shrunkPosterior(cell: {
148
178
  alpha: number;
149
179
  beta: number;
150
- exposures: number;
151
180
  }, pooled: {
152
181
  alpha: number;
153
182
  beta: number;
@@ -191,11 +220,45 @@ declare function posteriorOfCounts(c: PoolCounts): {
191
220
  * Every cell is optional; an absent cell contributes Beta(1,1)-with-0-evidence,
192
221
  * which is what lets the same function reproduce the legacy variant (segment-only)
193
222
  * and legacy slot (persona-only) behaviors on day one after migration.
223
+ *
224
+ * Only the parent's MEAN crosses each shrink boundary (see shrunkPosterior) —
225
+ * never its sample size. That is what keeps a thin child's posterior as WIDE as
226
+ * its own evidence warrants, so Thompson Sampling still explores it. The blend
227
+ * weight below therefore decides which axis sets the parent's rate; the levels'
228
+ * absolute magnitudes no longer leak into the child's confidence.
194
229
  */
195
230
  declare function pooledPosterior(cells: PoolCells, personaKnown: boolean, m?: number): {
196
231
  alpha: number;
197
232
  beta: number;
198
233
  };
234
+ /** A weight row's value-posterior columns, plus the cell it belongs to. */
235
+ type ValueCellRow = {
236
+ segment: string;
237
+ persona: string;
238
+ valueSum: number;
239
+ valueCount: number;
240
+ };
241
+ /**
242
+ * The value cell for EV ranking: the BROADEST cell present for an arm.
243
+ *
244
+ * Never a sum across cells. `weightCellsFor` writes each trial to the child,
245
+ * both marginals AND the global row, so adding them up counts every real order
246
+ * 2-4x depending on whether the persona was known. The average survives that
247
+ * (numerator and denominator inflate together) but the EB shrinkage weight does
248
+ * not: `valueCount / (valueCount + EV_SHRINK_K)` with K = 20 is meant to give a
249
+ * cell its own voice at ~20 valued orders, and at 4x inflation it happened at
250
+ * 5 — by a factor that varied with the arm's persona mix, so identical arms
251
+ * shrank differently.
252
+ *
253
+ * The broadest cell already holds every trial in its slice exactly once, which
254
+ * makes this correct for both serving views: the pooled hierarchy (up to four
255
+ * rows per arm, global wins) and the legacy marginal view (exactly one row per
256
+ * arm, which is therefore the broadest).
257
+ */
258
+ declare function broadestValueCell(rows: readonly ValueCellRow[]): {
259
+ valueSum: number;
260
+ valueCount: number;
261
+ };
199
262
  /**
200
263
  * Write-side cell expansion: which weight rows one trial/credit must bump.
201
264
  * Unknown persona bumps ONLY the segment marginal + global — no 'unknown'
@@ -228,4 +291,14 @@ declare function pickDeterministicArm(sessionId: string, slotId: string, arms: s
228
291
  */
229
292
  declare function confidenceBand(c: number): 'low' | 'medium' | 'high';
230
293
 
231
- export { type ArmPosterior, CLUSTER_PRIORITY, LEGACY_PERSONA_MAP, type LearnedLayout, PERSONAS, PERSONA_DISPLAY, POOL_ALL, type Persona, type PersonaKey, type PoolCells, type PoolCounts, SHRINKAGE_M, type SlotDecl, type SlotResult, UNKNOWN_PERSONA, applyClusterHeuristic, candidateLayouts, canonicalArm, canonicalPersona, chooseLayout, confidenceBand, fnv1a, hashLayout, marginalArmKey, parseArm, pickDeterministicArm, pooledPosterior, posteriorOfCounts, sampleArm, sampleBeta, shrunkPosterior, slotBaselineArm, slotResultFor, validateSlotDecl, weightCellsFor };
294
+ /** = MIN_VALUED_CONVERSIONS: cells earn their own voice at ~20 valued orders. */
295
+ declare const EV_SHRINK_K = 20;
296
+ type ValueCell = {
297
+ valueSum: number;
298
+ valueCount: number;
299
+ };
300
+ declare function shrunkAvgValue(cell: ValueCell, reference: number, k?: number): number;
301
+ type EvArm = ArmPosterior & ValueCell;
302
+ declare function sampleArmEv(arms: EvArm[], reference: number, rand?: () => number): string | null;
303
+
304
+ export { type ArmPosterior, CLUSTER_PRIORITY, EV_SHRINK_K, type EvArm, LEGACY_PERSONA_MAP, type LearnedLayout, PERSONAS, PERSONA_DISPLAY, POOL_ALL, type Persona, type PersonaKey, type PoolCells, type PoolCounts, SHRINKAGE_M, type SlotDecl, type SlotResult, UNKNOWN_PERSONA, type ValueCell, type ValueCellRow, applyClusterHeuristic, broadestValueCell, candidateLayouts, canonicalArm, canonicalPersona, chooseLayout, confidenceBand, fnv1a, hashLayout, marginalArmKey, parseArm, pickDeterministicArm, pooledPosterior, posteriorOfCounts, sampleArm, sampleArmEv, sampleBeta, shrunkAvgValue, shrunkPosterior, slotBaselineArm, slotResultFor, validateSlotDecl, weightCellsFor };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var O=Object.defineProperty,se=Object.defineProperties,ae=Object.getOwnPropertyDescriptor,ie=Object.getOwnPropertyDescriptors,ue=Object.getOwnPropertyNames,F=Object.getOwnPropertySymbols;var V=Object.prototype.hasOwnProperty,ce=Object.prototype.propertyIsEnumerable;var T=(e,r,t)=>r in e?O(e,r,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[r]=t,v=(e,r)=>{for(var t in r||(r={}))V.call(r,t)&&T(e,t,r[t]);if(F)for(var t of F(r))ce.call(r,t)&&T(e,t,r[t]);return e},L=(e,r)=>se(e,ie(r));var le=(e,r)=>{for(var t in r)O(e,t,{get:r[t],enumerable:!0})},fe=(e,r,t,n)=>{if(r&&typeof r=="object"||typeof r=="function")for(let s of ue(r))!V.call(e,s)&&s!==t&&O(e,s,{get:()=>r[s],enumerable:!(n=ae(r,s))||n.enumerable});return e};var me=e=>fe(O({},"__esModule",{value:!0}),e);var Re={};le(Re,{CLUSTER_PRIORITY:()=>Q,LEGACY_PERSONA_MAP:()=>Z,PERSONAS:()=>j,PERSONA_DISPLAY:()=>be,POOL_ALL:()=>g,SHRINKAGE_M:()=>ee,UNKNOWN_PERSONA:()=>S,applyClusterHeuristic:()=>N,candidateLayouts:()=>H,canonicalArm:()=>z,canonicalPersona:()=>xe,chooseLayout:()=>de,confidenceBand:()=>we,fnv1a:()=>re,hashLayout:()=>U,marginalArmKey:()=>he,parseArm:()=>W,pickDeterministicArm:()=>Se,pooledPosterior:()=>ke,posteriorOfCounts:()=>R,sampleArm:()=>G,sampleBeta:()=>B,shrunkPosterior:()=>w,slotBaselineArm:()=>X,slotResultFor:()=>Pe,validateSlotDecl:()=>ye,weightCellsFor:()=>Ae});module.exports=me(Re);var j=["buyer","researcher","deal_seeker","browser"],S="unknown",be={buyer:"Buyer",researcher:"Researcher",deal_seeker:"Deal seeker",browser:"Browser",unknown:"Unknown"},Z={buyers:"buyer",researchers:"researcher","deal-seekers":"deal_seeker",browsers:"browser",buyer:"buyer",researcher:"researcher",deal_seeker:"deal_seeker",browser:"browser"};function xe(e){var t;if(e==null)return S;let r=e.trim().toLowerCase();return(t=Z[r])!=null?t:S}var pe=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];function p(e,r){return e>>>r|e<<32-r}function J(e){return(e>>>0).toString(16).padStart(8,"0")}function ge(e){let r=new TextEncoder().encode(e),t=r.length,n=t*8,s=(t+8>>6)+1<<6,o=new Uint8Array(s);o.set(r),o[t]=128;let a=new DataView(o.buffer);a.setUint32(s-8,Math.floor(n/4294967296),!1),a.setUint32(s-4,n>>>0,!1);let u=1779033703,c=3144134277,m=1013904242,l=2773480762,x=1359893119,b=2600822924,y=528734635,P=1541459225,f=new Uint32Array(64);for(let C=0;C<s;C+=64){for(let i=0;i<16;i++)f[i]=a.getUint32(C+i*4,!1);for(let i=16;i<64;i++){let D=p(f[i-15],7)^p(f[i-15],18)^f[i-15]>>>3,$=p(f[i-2],17)^p(f[i-2],19)^f[i-2]>>>10;f[i]=f[i-16]+D+f[i-7]+$>>>0}let d=u,k=c,A=m,E=l,h=x,M=b,_=y,q=P;for(let i=0;i<64;i++){let D=p(h,6)^p(h,11)^p(h,25),$=h&M^~h&_,Y=q+D+$+pe[i]+f[i]>>>0,te=p(d,2)^p(d,13)^p(d,22),ne=d&k^d&A^k&A,oe=te+ne>>>0;q=_,_=M,M=h,h=E+Y>>>0,E=A,A=k,k=d,d=Y+oe>>>0}u=u+d>>>0,c=c+k>>>0,m=m+A>>>0,l=l+E>>>0,x=x+h>>>0,b=b+M>>>0,y=y+_>>>0,P=P+q>>>0}return J(u)+J(c)}function U(e){return ge(e.join("|"))}var Q={buyer:["pricing","cta","hero","comparison","social_proof","trust","features","faq","navigation","generic"],researcher:["features","comparison","faq","hero","trust","social_proof","pricing","cta","navigation","generic"],deal_seeker:["pricing","comparison","social_proof","trust","cta","hero","features","faq","navigation","generic"],browser:["hero","features","social_proof","pricing","cta","trust","faq","comparison","navigation","generic"]};function N(e,r,t){let n=t===S?void 0:Q[t];if(!n)return e;let s=n.indexOf("generic"),o=a=>{let u=n.indexOf(a);return u===-1?s:u};return[...e].sort((a,u)=>{var l,x;let c=(l=r.get(a))!=null?l:"generic",m=(x=r.get(u))!=null?x:"generic";return o(c)-o(m)})}function H(e,r,t){let n=new Map;for(let s of[...j,t]){let o=N(e,r,s);n.set(U(o),o)}return n}function I(e,r){if(e<1)return I(1+e,r)*Math.pow(Math.max(1e-15,r()),1/e);let t=e-1/3,n=1/Math.sqrt(9*t);for(;;){let s,o;do{let u=Math.max(1e-15,r()),c=r();s=Math.sqrt(-2*Math.log(u))*Math.cos(2*Math.PI*c),o=1+n*s}while(o<=0);o=o*o*o;let a=r();if(a<1-.0331*s*s*s*s||Math.log(a)<.5*s*s+t*(1-o+Math.log(o)))return t*o}}function B(e,r,t=Math.random){let n=I(e,t),s=I(r,t),o=n+s;return o<=0?e/(e+r):n/o}function G(e,r=Math.random){if(e.length===0)return null;if(e.length===1)return e[0].arm;let t=e[0],n=B(t.alpha,t.beta,r);for(let s=1;s<e.length;s++){let o=e[s],a=B(o.alpha,o.beta,r);a>n&&(t=o,n=a)}return t.arm}function de(e,r,t,n,s=Math.random){var m,l;let o=H(e,r,t),a=[];for(let x of o.keys()){let b=n.get(x);a.push({arm:x,alpha:(m=b==null?void 0:b.alpha)!=null?m:1,beta:(l=b==null?void 0:b.beta)!=null?l:1})}let u=G(a,s),c=u?o.get(u):void 0;return c!=null?c:N(e,r,t)}function z(e){return Object.keys(e).sort().map(r=>`${r}=${e[r]}`).join("|")}function W(e){if(e.length===0)return null;let r={};for(let t of e.split("|")){let n=t.indexOf("=");if(n<=0||n!==t.lastIndexOf("=")||n===t.length-1)return null;let s=t.slice(0,n);if(s in r)return null;r[s]=t.slice(n+1)}return r}function he(e,r){return`${e}=${r}`}function X(e){var t,n,s;if(e.arms)return typeof e.baseline=="string"?e.baseline:(t=e.arms[0])!=null?t:"";if(e.baseline!==void 0&&typeof e.baseline=="object")return z(e.baseline);if(typeof e.baseline=="string")return e.baseline;let r={};for(let[o,a]of Object.entries((n=e.dims)!=null?n:{}))r[o]=(s=a[0])!=null?s:"";return z(r)}function ye(e){let r=Array.isArray(e.arms),t=e.dims!=null;if(r&&t)return{ok:!1,reason:"declare exactly one of arms or dims (got both)"};if(!r&&!t)return{ok:!1,reason:"declare exactly one of arms or dims (got neither)"};if(r){let o=e.arms;if(o.length<2)return{ok:!1,reason:"arms requires at least 2 entries"};if(o.length>12)return{ok:!1,reason:"arms allows at most 12 entries"};if(new Set(o).size!==o.length)return{ok:!1,reason:"arms must be unique"};if(o.some(a=>a.includes("=")))return{ok:!1,reason:"enumerated arm ids may not contain '=' (reserved for dims encoding)"};if(e.baseline!==void 0){if(typeof e.baseline!="string")return{ok:!1,reason:"baseline for an arms slot must be a string"};if(!o.includes(e.baseline))return{ok:!1,reason:"baseline must be one of the declared arms"}}return{ok:!0}}let n=Object.entries(e.dims);if(n.length<1)return{ok:!1,reason:"dims requires at least 1 dimension"};if(n.length>4)return{ok:!1,reason:"dims allows at most 4 dimensions"};let s=1;for(let[o,a]of n){if(a.length<2)return{ok:!1,reason:`dim "${o}" requires at least 2 values`};if(a.length>6)return{ok:!1,reason:`dim "${o}" allows at most 6 values`};if(new Set(a).size!==a.length)return{ok:!1,reason:`dim "${o}" has duplicate values`};s*=a.length}if(s>64)return{ok:!1,reason:`declared space of ${s} combinations exceeds the 64 maximum`};if(e.baseline!==void 0){if(typeof e.baseline=="string")return{ok:!1,reason:"baseline for a dims slot must be a per-dim record"};let o=e.baseline,a=n.map(([c])=>c).sort(),u=Object.keys(o).sort();if(a.join(" ")!==u.join(" "))return{ok:!1,reason:"baseline must set every declared dim exactly once"};for(let[c,m]of n)if(!m.includes(o[c]))return{ok:!1,reason:`baseline value for dim "${c}" is not declared`}}return{ok:!0}}function Pe(e,r){var t,n;return e.dims!=null?(n=(t=W(r))!=null?t:W(X(e)))!=null?n:{}:r}var ee=20;function w(e,r,t=20){let n=t/(t+e.exposures);return{alpha:e.alpha+n*r.alpha,beta:e.beta+n*r.beta}}var g="__all__",K={exposures:0,conversions:0};function R(e){return{alpha:e.conversions+1,beta:Math.max(0,e.exposures-e.conversions)+1}}function ke(e,r,t=20){var b,y,P,f;let n=(b=e.segment)!=null?b:K,s=(y=e.global)!=null?y:K,o=R(s),a=w(L(v({},R(n)),{exposures:n.exposures}),o,t);if(!r)return a;let u=(P=e.persona)!=null?P:K,c=(f=e.child)!=null?f:K,m=w(L(v({},R(u)),{exposures:u.exposures}),o,t),l=(n.exposures+1)/(n.exposures+u.exposures+2),x={alpha:l*a.alpha+(1-l)*m.alpha,beta:l*a.beta+(1-l)*m.beta};return w(L(v({},R(c)),{exposures:c.exposures}),x,t)}function Ae(e,r){return r==="unknown"||r===g||r===""?[{segment:e,persona:g},{segment:g,persona:g}]:[{segment:e,persona:r},{segment:e,persona:g},{segment:g,persona:r},{segment:g,persona:g}]}function re(e){let r=2166136261;for(let t=0;t<e.length;t++)r^=e.charCodeAt(t),r=r+((r<<1)+(r<<4)+(r<<7)+(r<<8)+(r<<24))>>>0;return r}function Se(e,r,t){if(t.length===0)throw new Error("pickDeterministicArm requires at least one arm");let n=[...t].sort();return n[re(`${e}:${r}`)%n.length]}function we(e){return e>=.3?e<.7?"medium":"high":"low"}0&&(module.exports={CLUSTER_PRIORITY,LEGACY_PERSONA_MAP,PERSONAS,PERSONA_DISPLAY,POOL_ALL,SHRINKAGE_M,UNKNOWN_PERSONA,applyClusterHeuristic,candidateLayouts,canonicalArm,canonicalPersona,chooseLayout,confidenceBand,fnv1a,hashLayout,marginalArmKey,parseArm,pickDeterministicArm,pooledPosterior,posteriorOfCounts,sampleArm,sampleBeta,shrunkPosterior,slotBaselineArm,slotResultFor,validateSlotDecl,weightCellsFor});
1
+ "use strict";var D=Object.defineProperty;var te=Object.getOwnPropertyDescriptor;var ne=Object.getOwnPropertyNames;var oe=Object.prototype.hasOwnProperty;var se=(e,r)=>{for(var t in r)D(e,t,{get:r[t],enumerable:!0})},ae=(e,r,t,n)=>{if(r&&typeof r=="object"||typeof r=="function")for(let s of ne(r))!oe.call(e,s)&&s!==t&&D(e,s,{get:()=>r[s],enumerable:!(n=te(r,s))||n.enumerable});return e};var ie=e=>ae(D({},"__esModule",{value:!0}),e);var ve={};se(ve,{CLUSTER_PRIORITY:()=>Y,EV_SHRINK_K:()=>J,LEGACY_PERSONA_MAP:()=>z,PERSONAS:()=>$,PERSONA_DISPLAY:()=>ue,POOL_ALL:()=>x,SHRINKAGE_M:()=>T,UNKNOWN_PERSONA:()=>A,applyClusterHeuristic:()=>M,broadestValueCell:()=>he,candidateLayouts:()=>H,canonicalArm:()=>V,canonicalPersona:()=>le,chooseLayout:()=>me,confidenceBand:()=>Pe,fnv1a:()=>Z,hashLayout:()=>j,marginalArmKey:()=>be,parseArm:()=>B,pickDeterministicArm:()=>ye,pooledPosterior:()=>ge,posteriorOfCounts:()=>w,sampleArm:()=>U,sampleArmEv:()=>ke,sampleBeta:()=>S,shrunkAvgValue:()=>Q,shrunkPosterior:()=>R,slotBaselineArm:()=>F,slotResultFor:()=>xe,validateSlotDecl:()=>pe,weightCellsFor:()=>de});module.exports=ie(ve);var $=["buyer","researcher","deal_seeker","browser"],A="unknown",ue={buyer:"Buyer",researcher:"Researcher",deal_seeker:"Deal seeker",browser:"Browser",unknown:"Unknown"},z={buyers:"buyer",researchers:"researcher","deal-seekers":"deal_seeker",browsers:"browser",buyer:"buyer",researcher:"researcher",deal_seeker:"deal_seeker",browser:"browser"};function le(e){var t;if(e==null)return A;let r=e.trim().toLowerCase();return(t=z[r])!=null?t:A}var ce=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];function g(e,r){return e>>>r|e<<32-r}function W(e){return(e>>>0).toString(16).padStart(8,"0")}function fe(e){let r=new TextEncoder().encode(e),t=r.length,n=t*8,s=(t+8>>6)+1<<6,o=new Uint8Array(s);o.set(r),o[t]=128;let a=new DataView(o.buffer);a.setUint32(s-8,Math.floor(n/4294967296),!1),a.setUint32(s-4,n>>>0,!1);let i=1779033703,u=3144134277,m=1013904242,c=2773480762,p=1359893119,b=2600822924,y=528734635,P=1541459225,f=new Uint32Array(64);for(let E=0;E<s;E+=64){for(let l=0;l<16;l++)f[l]=a.getUint32(E+l*4,!1);for(let l=16;l<64;l++){let L=g(f[l-15],7)^g(f[l-15],18)^f[l-15]>>>3,q=g(f[l-2],17)^g(f[l-2],19)^f[l-2]>>>10;f[l]=f[l-16]+L+f[l-7]+q>>>0}let h=i,k=u,v=m,N=c,d=p,C=b,_=y,K=P;for(let l=0;l<64;l++){let L=g(d,6)^g(d,11)^g(d,25),q=d&C^~d&_,G=K+L+q+ce[l]+f[l]>>>0,X=g(h,2)^g(h,13)^g(h,22),ee=h&k^h&v^k&v,re=X+ee>>>0;K=_,_=C,C=d,d=N+G>>>0,N=v,v=k,k=h,h=G+re>>>0}i=i+h>>>0,u=u+k>>>0,m=m+v>>>0,c=c+N>>>0,p=p+d>>>0,b=b+C>>>0,y=y+_>>>0,P=P+K>>>0}return W(i)+W(u)}function j(e){return fe(e.join("|"))}var Y={buyer:["pricing","cta","hero","comparison","social_proof","trust","features","faq","navigation","generic"],researcher:["features","comparison","faq","hero","trust","social_proof","pricing","cta","navigation","generic"],deal_seeker:["pricing","comparison","social_proof","trust","cta","hero","features","faq","navigation","generic"],browser:["hero","features","social_proof","pricing","cta","trust","faq","comparison","navigation","generic"]};function M(e,r,t){let n=t===A?void 0:Y[t];if(!n)return e;let s=n.indexOf("generic"),o=a=>{let i=n.indexOf(a);return i===-1?s:i};return[...e].sort((a,i)=>{var c,p;let u=(c=r.get(a))!=null?c:"generic",m=(p=r.get(i))!=null?p:"generic";return o(u)-o(m)})}function H(e,r,t){let n=new Map;for(let s of[...$,t]){let o=M(e,r,s);n.set(j(o),o)}return n}function I(e,r){if(e<1)return I(1+e,r)*Math.pow(Math.max(1e-15,r()),1/e);let t=e-1/3,n=1/Math.sqrt(9*t);for(;;){let s,o;do{let i=Math.max(1e-15,r()),u=r();s=Math.sqrt(-2*Math.log(i))*Math.cos(2*Math.PI*u),o=1+n*s}while(o<=0);o=o*o*o;let a=r();if(a<1-.0331*s*s*s*s||Math.log(a)<.5*s*s+t*(1-o+Math.log(o)))return t*o}}function S(e,r,t=Math.random){let n=I(e,t),s=I(r,t),o=n+s;return o<=0?e/(e+r):n/o}function U(e,r=Math.random){if(e.length===0)return null;if(e.length===1)return e[0].arm;let t=e[0],n=S(t.alpha,t.beta,r);for(let s=1;s<e.length;s++){let o=e[s],a=S(o.alpha,o.beta,r);a>n&&(t=o,n=a)}return t.arm}function me(e,r,t,n,s=Math.random){var m,c;let o=H(e,r,t),a=[];for(let p of o.keys()){let b=n.get(p);a.push({arm:p,alpha:(m=b==null?void 0:b.alpha)!=null?m:1,beta:(c=b==null?void 0:b.beta)!=null?c:1})}let i=U(a,s),u=i?o.get(i):void 0;return u!=null?u:M(e,r,t)}function V(e){return Object.keys(e).sort().map(r=>`${r}=${e[r]}`).join("|")}function B(e){if(e.length===0)return null;let r={};for(let t of e.split("|")){let n=t.indexOf("=");if(n<=0||n!==t.lastIndexOf("=")||n===t.length-1)return null;let s=t.slice(0,n);if(s in r)return null;r[s]=t.slice(n+1)}return r}function be(e,r){return`${e}=${r}`}function F(e){var t,n,s;if(e.arms)return typeof e.baseline=="string"?e.baseline:(t=e.arms[0])!=null?t:"";if(e.baseline!==void 0&&typeof e.baseline=="object")return V(e.baseline);if(typeof e.baseline=="string")return e.baseline;let r={};for(let[o,a]of Object.entries((n=e.dims)!=null?n:{}))r[o]=(s=a[0])!=null?s:"";return V(r)}function pe(e){let r=Array.isArray(e.arms),t=e.dims!=null;if(r&&t)return{ok:!1,reason:"declare exactly one of arms or dims (got both)"};if(!r&&!t)return{ok:!1,reason:"declare exactly one of arms or dims (got neither)"};if(r){let o=e.arms;if(o.length<2)return{ok:!1,reason:"arms requires at least 2 entries"};if(o.length>12)return{ok:!1,reason:"arms allows at most 12 entries"};if(new Set(o).size!==o.length)return{ok:!1,reason:"arms must be unique"};if(o.some(a=>a.includes("=")))return{ok:!1,reason:"enumerated arm ids may not contain '=' (reserved for dims encoding)"};if(e.baseline!==void 0){if(typeof e.baseline!="string")return{ok:!1,reason:"baseline for an arms slot must be a string"};if(!o.includes(e.baseline))return{ok:!1,reason:"baseline must be one of the declared arms"}}return{ok:!0}}let n=Object.entries(e.dims);if(n.length<1)return{ok:!1,reason:"dims requires at least 1 dimension"};if(n.length>4)return{ok:!1,reason:"dims allows at most 4 dimensions"};let s=1;for(let[o,a]of n){if(a.length<2)return{ok:!1,reason:`dim "${o}" requires at least 2 values`};if(a.length>6)return{ok:!1,reason:`dim "${o}" allows at most 6 values`};if(new Set(a).size!==a.length)return{ok:!1,reason:`dim "${o}" has duplicate values`};s*=a.length}if(s>64)return{ok:!1,reason:`declared space of ${s} combinations exceeds the 64 maximum`};if(e.baseline!==void 0){if(typeof e.baseline=="string")return{ok:!1,reason:"baseline for a dims slot must be a per-dim record"};let o=e.baseline,a=n.map(([u])=>u).sort(),i=Object.keys(o).sort();if(a.join(" ")!==i.join(" "))return{ok:!1,reason:"baseline must set every declared dim exactly once"};for(let[u,m]of n)if(!m.includes(o[u]))return{ok:!1,reason:`baseline value for dim "${u}" is not declared`}}return{ok:!0}}function xe(e,r){var t,n;return e.dims!=null?(n=(t=B(r))!=null?t:B(F(e)))!=null?n:{}:r}var T=20;function R(e,r,t=20){let n=r.alpha+r.beta;if(n<=0||t<=0)return{alpha:e.alpha,beta:e.beta};let s=r.alpha/n,o=t*n/(n+t);return{alpha:e.alpha+o*s,beta:e.beta+o*(1-s)}}var x="__all__",O={exposures:0,conversions:0};function w(e){return{alpha:e.conversions+1,beta:Math.max(0,e.exposures-e.conversions)+1}}function ge(e,r,t=20){var b,y,P,f;let n=(b=e.segment)!=null?b:O,s=(y=e.global)!=null?y:O,o=w(s),a=R(w(n),o,t);if(!r)return a;let i=(P=e.persona)!=null?P:O,u=(f=e.child)!=null?f:O,m=R(w(i),o,t),c=(n.exposures+1)/(n.exposures+i.exposures+2),p={alpha:c*a.alpha+(1-c)*m.alpha,beta:c*a.beta+(1-c)*m.beta};return R(w(u),p,t)}function he(e){var n,s;let r=null,t=-1;for(let o of e){let a=o.segment===x,i=o.persona===x,u=a&&i?3:a||i?2:1;u>t&&(t=u,r=o)}return{valueSum:(n=r==null?void 0:r.valueSum)!=null?n:0,valueCount:(s=r==null?void 0:r.valueCount)!=null?s:0}}function de(e,r){return r==="unknown"||r===x||r===""?[{segment:e,persona:x},{segment:x,persona:x}]:[{segment:e,persona:r},{segment:e,persona:x},{segment:x,persona:r},{segment:x,persona:x}]}function Z(e){let r=2166136261;for(let t=0;t<e.length;t++)r^=e.charCodeAt(t),r=r+((r<<1)+(r<<4)+(r<<7)+(r<<8)+(r<<24))>>>0;return r}function ye(e,r,t){if(t.length===0)throw new Error("pickDeterministicArm requires at least one arm");let n=[...t].sort();return n[Z(`${e}:${r}`)%n.length]}function Pe(e){return e>=.3?e<.7?"medium":"high":"low"}var J=20;function Q(e,r,t=J){let n=e.valueCount>0?e.valueSum/e.valueCount:0;if(r<=0)return n;if(e.valueCount<=0)return r;let s=e.valueCount/(e.valueCount+t);return s*n+(1-s)*r}function ke(e,r,t=Math.random){if(e.length===0)return null;if(e.length===1)return e[0].arm;let n=null,s=-1/0;for(let o of e){let a=S(o.alpha,o.beta,t)*Q(o,r);a>s&&(n=o,s=a)}return n.arm}0&&(module.exports={CLUSTER_PRIORITY,EV_SHRINK_K,LEGACY_PERSONA_MAP,PERSONAS,PERSONA_DISPLAY,POOL_ALL,SHRINKAGE_M,UNKNOWN_PERSONA,applyClusterHeuristic,broadestValueCell,candidateLayouts,canonicalArm,canonicalPersona,chooseLayout,confidenceBand,fnv1a,hashLayout,marginalArmKey,parseArm,pickDeterministicArm,pooledPosterior,posteriorOfCounts,sampleArm,sampleArmEv,sampleBeta,shrunkAvgValue,shrunkPosterior,slotBaselineArm,slotResultFor,validateSlotDecl,weightCellsFor});
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- var X=Object.defineProperty,ee=Object.defineProperties;var re=Object.getOwnPropertyDescriptors;var U=Object.getOwnPropertySymbols;var te=Object.prototype.hasOwnProperty,ne=Object.prototype.propertyIsEnumerable;var H=(e,r,t)=>r in e?X(e,r,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[r]=t,R=(e,r)=>{for(var t in r||(r={}))te.call(r,t)&&H(e,t,r[t]);if(U)for(var t of U(r))ne.call(r,t)&&H(e,t,r[t]);return e},M=(e,r)=>ee(e,re(r));var I=["buyer","researcher","deal_seeker","browser"],_="unknown",fe={buyer:"Buyer",researcher:"Researcher",deal_seeker:"Deal seeker",browser:"Browser",unknown:"Unknown"},oe={buyers:"buyer",researchers:"researcher","deal-seekers":"deal_seeker",browsers:"browser",buyer:"buyer",researcher:"researcher",deal_seeker:"deal_seeker",browser:"browser"};function me(e){var t;if(e==null)return _;let r=e.trim().toLowerCase();return(t=oe[r])!=null?t:_}var se=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];function p(e,r){return e>>>r|e<<32-r}function B(e){return(e>>>0).toString(16).padStart(8,"0")}function ae(e){let r=new TextEncoder().encode(e),t=r.length,o=t*8,s=(t+8>>6)+1<<6,n=new Uint8Array(s);n.set(r),n[t]=128;let a=new DataView(n.buffer);a.setUint32(s-8,Math.floor(o/4294967296),!1),a.setUint32(s-4,o>>>0,!1);let u=1779033703,c=3144134277,m=1013904242,l=2773480762,x=1359893119,b=2600822924,y=528734635,P=1541459225,f=new Uint32Array(64);for(let N=0;N<s;N+=64){for(let i=0;i<16;i++)f[i]=a.getUint32(N+i*4,!1);for(let i=16;i<64;i++){let E=p(f[i-15],7)^p(f[i-15],18)^f[i-15]>>>3,q=p(f[i-2],17)^p(f[i-2],19)^f[i-2]>>>10;f[i]=f[i-16]+E+f[i-7]+q>>>0}let g=u,k=c,A=m,K=l,d=x,S=b,w=y,C=P;for(let i=0;i<64;i++){let E=p(d,6)^p(d,11)^p(d,25),q=d&S^~d&w,j=C+E+q+se[i]+f[i]>>>0,Z=p(g,2)^p(g,13)^p(g,22),J=g&k^g&A^k&A,Q=Z+J>>>0;C=w,w=S,S=d,d=K+j>>>0,K=A,A=k,k=g,g=j+Q>>>0}u=u+g>>>0,c=c+k>>>0,m=m+A>>>0,l=l+K>>>0,x=x+d>>>0,b=b+S>>>0,y=y+w>>>0,P=P+C>>>0}return B(u)+B(c)}function G(e){return ae(e.join("|"))}var ie={buyer:["pricing","cta","hero","comparison","social_proof","trust","features","faq","navigation","generic"],researcher:["features","comparison","faq","hero","trust","social_proof","pricing","cta","navigation","generic"],deal_seeker:["pricing","comparison","social_proof","trust","cta","hero","features","faq","navigation","generic"],browser:["hero","features","social_proof","pricing","cta","trust","faq","comparison","navigation","generic"]};function D(e,r,t){let o=t===_?void 0:ie[t];if(!o)return e;let s=o.indexOf("generic"),n=a=>{let u=o.indexOf(a);return u===-1?s:u};return[...e].sort((a,u)=>{var l,x;let c=(l=r.get(a))!=null?l:"generic",m=(x=r.get(u))!=null?x:"generic";return n(c)-n(m)})}function z(e,r,t){let o=new Map;for(let s of[...I,t]){let n=D(e,r,s);o.set(G(n),n)}return o}function $(e,r){if(e<1)return $(1+e,r)*Math.pow(Math.max(1e-15,r()),1/e);let t=e-1/3,o=1/Math.sqrt(9*t);for(;;){let s,n;do{let u=Math.max(1e-15,r()),c=r();s=Math.sqrt(-2*Math.log(u))*Math.cos(2*Math.PI*c),n=1+o*s}while(n<=0);n=n*n*n;let a=r();if(a<1-.0331*s*s*s*s||Math.log(a)<.5*s*s+t*(1-n+Math.log(n)))return t*n}}function W(e,r,t=Math.random){let o=$(e,t),s=$(r,t),n=o+s;return n<=0?e/(e+r):o/n}function Y(e,r=Math.random){if(e.length===0)return null;if(e.length===1)return e[0].arm;let t=e[0],o=W(t.alpha,t.beta,r);for(let s=1;s<e.length;s++){let n=e[s],a=W(n.alpha,n.beta,r);a>o&&(t=n,o=a)}return t.arm}function ke(e,r,t,o,s=Math.random){var m,l;let n=z(e,r,t),a=[];for(let x of n.keys()){let b=o.get(x);a.push({arm:x,alpha:(m=b==null?void 0:b.alpha)!=null?m:1,beta:(l=b==null?void 0:b.beta)!=null?l:1})}let u=Y(a,s),c=u?n.get(u):void 0;return c!=null?c:D(e,r,t)}function F(e){return Object.keys(e).sort().map(r=>`${r}=${e[r]}`).join("|")}function T(e){if(e.length===0)return null;let r={};for(let t of e.split("|")){let o=t.indexOf("=");if(o<=0||o!==t.lastIndexOf("=")||o===t.length-1)return null;let s=t.slice(0,o);if(s in r)return null;r[s]=t.slice(o+1)}return r}function Se(e,r){return`${e}=${r}`}function ue(e){var t,o,s;if(e.arms)return typeof e.baseline=="string"?e.baseline:(t=e.arms[0])!=null?t:"";if(e.baseline!==void 0&&typeof e.baseline=="object")return F(e.baseline);if(typeof e.baseline=="string")return e.baseline;let r={};for(let[n,a]of Object.entries((o=e.dims)!=null?o:{}))r[n]=(s=a[0])!=null?s:"";return F(r)}function we(e){let r=Array.isArray(e.arms),t=e.dims!=null;if(r&&t)return{ok:!1,reason:"declare exactly one of arms or dims (got both)"};if(!r&&!t)return{ok:!1,reason:"declare exactly one of arms or dims (got neither)"};if(r){let n=e.arms;if(n.length<2)return{ok:!1,reason:"arms requires at least 2 entries"};if(n.length>12)return{ok:!1,reason:"arms allows at most 12 entries"};if(new Set(n).size!==n.length)return{ok:!1,reason:"arms must be unique"};if(n.some(a=>a.includes("=")))return{ok:!1,reason:"enumerated arm ids may not contain '=' (reserved for dims encoding)"};if(e.baseline!==void 0){if(typeof e.baseline!="string")return{ok:!1,reason:"baseline for an arms slot must be a string"};if(!n.includes(e.baseline))return{ok:!1,reason:"baseline must be one of the declared arms"}}return{ok:!0}}let o=Object.entries(e.dims);if(o.length<1)return{ok:!1,reason:"dims requires at least 1 dimension"};if(o.length>4)return{ok:!1,reason:"dims allows at most 4 dimensions"};let s=1;for(let[n,a]of o){if(a.length<2)return{ok:!1,reason:`dim "${n}" requires at least 2 values`};if(a.length>6)return{ok:!1,reason:`dim "${n}" allows at most 6 values`};if(new Set(a).size!==a.length)return{ok:!1,reason:`dim "${n}" has duplicate values`};s*=a.length}if(s>64)return{ok:!1,reason:`declared space of ${s} combinations exceeds the 64 maximum`};if(e.baseline!==void 0){if(typeof e.baseline=="string")return{ok:!1,reason:"baseline for a dims slot must be a per-dim record"};let n=e.baseline,a=o.map(([c])=>c).sort(),u=Object.keys(n).sort();if(a.join(" ")!==u.join(" "))return{ok:!1,reason:"baseline must set every declared dim exactly once"};for(let[c,m]of o)if(!m.includes(n[c]))return{ok:!1,reason:`baseline value for dim "${c}" is not declared`}}return{ok:!0}}function Re(e,r){var t,o;return e.dims!=null?(o=(t=T(r))!=null?t:T(ue(e)))!=null?o:{}:r}var V=20;function O(e,r,t=20){let o=t/(t+e.exposures);return{alpha:e.alpha+o*r.alpha,beta:e.beta+o*r.beta}}var h="__all__",v={exposures:0,conversions:0};function L(e){return{alpha:e.conversions+1,beta:Math.max(0,e.exposures-e.conversions)+1}}function ve(e,r,t=20){var b,y,P,f;let o=(b=e.segment)!=null?b:v,s=(y=e.global)!=null?y:v,n=L(s),a=O(M(R({},L(o)),{exposures:o.exposures}),n,t);if(!r)return a;let u=(P=e.persona)!=null?P:v,c=(f=e.child)!=null?f:v,m=O(M(R({},L(u)),{exposures:u.exposures}),n,t),l=(o.exposures+1)/(o.exposures+u.exposures+2),x={alpha:l*a.alpha+(1-l)*m.alpha,beta:l*a.beta+(1-l)*m.beta};return O(M(R({},L(c)),{exposures:c.exposures}),x,t)}function Le(e,r){return r==="unknown"||r===h||r===""?[{segment:e,persona:h},{segment:h,persona:h}]:[{segment:e,persona:r},{segment:e,persona:h},{segment:h,persona:r},{segment:h,persona:h}]}function ce(e){let r=2166136261;for(let t=0;t<e.length;t++)r^=e.charCodeAt(t),r=r+((r<<1)+(r<<4)+(r<<7)+(r<<8)+(r<<24))>>>0;return r}function Ce(e,r,t){if(t.length===0)throw new Error("pickDeterministicArm requires at least one arm");let o=[...t].sort();return o[ce(`${e}:${r}`)%o.length]}function Ee(e){return e>=.3?e<.7?"medium":"high":"low"}export{ie as CLUSTER_PRIORITY,oe as LEGACY_PERSONA_MAP,I as PERSONAS,fe as PERSONA_DISPLAY,h as POOL_ALL,V as SHRINKAGE_M,_ as UNKNOWN_PERSONA,D as applyClusterHeuristic,z as candidateLayouts,F as canonicalArm,me as canonicalPersona,ke as chooseLayout,Ee as confidenceBand,ce as fnv1a,G as hashLayout,Se as marginalArmKey,T as parseArm,Ce as pickDeterministicArm,ve as pooledPosterior,L as posteriorOfCounts,Y as sampleArm,W as sampleBeta,O as shrunkPosterior,ue as slotBaselineArm,Re as slotResultFor,we as validateSlotDecl,Le as weightCellsFor};
1
+ var j=["buyer","researcher","deal_seeker","browser"],R="unknown",ne={buyer:"Buyer",researcher:"Researcher",deal_seeker:"Deal seeker",browser:"Browser",unknown:"Unknown"},T={buyers:"buyer",researchers:"researcher","deal-seekers":"deal_seeker",browsers:"browser",buyer:"buyer",researcher:"researcher",deal_seeker:"deal_seeker",browser:"browser"};function oe(e){var t;if(e==null)return R;let r=e.trim().toLowerCase();return(t=T[r])!=null?t:R}var Z=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];function x(e,r){return e>>>r|e<<32-r}function H(e){return(e>>>0).toString(16).padStart(8,"0")}function J(e){let r=new TextEncoder().encode(e),t=r.length,o=t*8,s=(t+8>>6)+1<<6,n=new Uint8Array(s);n.set(r),n[t]=128;let a=new DataView(n.buffer);a.setUint32(s-8,Math.floor(o/4294967296),!1),a.setUint32(s-4,o>>>0,!1);let i=1779033703,u=3144134277,m=1013904242,c=2773480762,p=1359893119,b=2600822924,y=528734635,P=1541459225,f=new Uint32Array(64);for(let O=0;O<s;O+=64){for(let l=0;l<16;l++)f[l]=a.getUint32(O+l*4,!1);for(let l=16;l<64;l++){let K=x(f[l-15],7)^x(f[l-15],18)^f[l-15]>>>3,L=x(f[l-2],17)^x(f[l-2],19)^f[l-2]>>>10;f[l]=f[l-16]+K+f[l-7]+L>>>0}let h=i,k=u,v=m,E=c,d=p,A=b,S=y,N=P;for(let l=0;l<64;l++){let K=x(d,6)^x(d,11)^x(d,25),L=d&A^~d&S,$=N+K+L+Z[l]+f[l]>>>0,W=x(h,2)^x(h,13)^x(h,22),Y=h&k^h&v^k&v,F=W+Y>>>0;N=S,S=A,A=d,d=E+$>>>0,E=v,v=k,k=h,h=$+F>>>0}i=i+h>>>0,u=u+k>>>0,m=m+v>>>0,c=c+E>>>0,p=p+d>>>0,b=b+A>>>0,y=y+S>>>0,P=P+N>>>0}return H(i)+H(u)}function I(e){return J(e.join("|"))}var Q={buyer:["pricing","cta","hero","comparison","social_proof","trust","features","faq","navigation","generic"],researcher:["features","comparison","faq","hero","trust","social_proof","pricing","cta","navigation","generic"],deal_seeker:["pricing","comparison","social_proof","trust","cta","hero","features","faq","navigation","generic"],browser:["hero","features","social_proof","pricing","cta","trust","faq","comparison","navigation","generic"]};function q(e,r,t){let o=t===R?void 0:Q[t];if(!o)return e;let s=o.indexOf("generic"),n=a=>{let i=o.indexOf(a);return i===-1?s:i};return[...e].sort((a,i)=>{var c,p;let u=(c=r.get(a))!=null?c:"generic",m=(p=r.get(i))!=null?p:"generic";return n(u)-n(m)})}function U(e,r,t){let o=new Map;for(let s of[...j,t]){let n=q(e,r,s);o.set(I(n),n)}return o}function D(e,r){if(e<1)return D(1+e,r)*Math.pow(Math.max(1e-15,r()),1/e);let t=e-1/3,o=1/Math.sqrt(9*t);for(;;){let s,n;do{let i=Math.max(1e-15,r()),u=r();s=Math.sqrt(-2*Math.log(i))*Math.cos(2*Math.PI*u),n=1+o*s}while(n<=0);n=n*n*n;let a=r();if(a<1-.0331*s*s*s*s||Math.log(a)<.5*s*s+t*(1-n+Math.log(n)))return t*n}}function w(e,r,t=Math.random){let o=D(e,t),s=D(r,t),n=o+s;return n<=0?e/(e+r):o/n}function V(e,r=Math.random){if(e.length===0)return null;if(e.length===1)return e[0].arm;let t=e[0],o=w(t.alpha,t.beta,r);for(let s=1;s<e.length;s++){let n=e[s],a=w(n.alpha,n.beta,r);a>o&&(t=n,o=a)}return t.arm}function be(e,r,t,o,s=Math.random){var m,c;let n=U(e,r,t),a=[];for(let p of n.keys()){let b=o.get(p);a.push({arm:p,alpha:(m=b==null?void 0:b.alpha)!=null?m:1,beta:(c=b==null?void 0:b.beta)!=null?c:1})}let i=V(a,s),u=i?n.get(i):void 0;return u!=null?u:q(e,r,t)}function B(e){return Object.keys(e).sort().map(r=>`${r}=${e[r]}`).join("|")}function G(e){if(e.length===0)return null;let r={};for(let t of e.split("|")){let o=t.indexOf("=");if(o<=0||o!==t.lastIndexOf("=")||o===t.length-1)return null;let s=t.slice(0,o);if(s in r)return null;r[s]=t.slice(o+1)}return r}function xe(e,r){return`${e}=${r}`}function X(e){var t,o,s;if(e.arms)return typeof e.baseline=="string"?e.baseline:(t=e.arms[0])!=null?t:"";if(e.baseline!==void 0&&typeof e.baseline=="object")return B(e.baseline);if(typeof e.baseline=="string")return e.baseline;let r={};for(let[n,a]of Object.entries((o=e.dims)!=null?o:{}))r[n]=(s=a[0])!=null?s:"";return B(r)}function ge(e){let r=Array.isArray(e.arms),t=e.dims!=null;if(r&&t)return{ok:!1,reason:"declare exactly one of arms or dims (got both)"};if(!r&&!t)return{ok:!1,reason:"declare exactly one of arms or dims (got neither)"};if(r){let n=e.arms;if(n.length<2)return{ok:!1,reason:"arms requires at least 2 entries"};if(n.length>12)return{ok:!1,reason:"arms allows at most 12 entries"};if(new Set(n).size!==n.length)return{ok:!1,reason:"arms must be unique"};if(n.some(a=>a.includes("=")))return{ok:!1,reason:"enumerated arm ids may not contain '=' (reserved for dims encoding)"};if(e.baseline!==void 0){if(typeof e.baseline!="string")return{ok:!1,reason:"baseline for an arms slot must be a string"};if(!n.includes(e.baseline))return{ok:!1,reason:"baseline must be one of the declared arms"}}return{ok:!0}}let o=Object.entries(e.dims);if(o.length<1)return{ok:!1,reason:"dims requires at least 1 dimension"};if(o.length>4)return{ok:!1,reason:"dims allows at most 4 dimensions"};let s=1;for(let[n,a]of o){if(a.length<2)return{ok:!1,reason:`dim "${n}" requires at least 2 values`};if(a.length>6)return{ok:!1,reason:`dim "${n}" allows at most 6 values`};if(new Set(a).size!==a.length)return{ok:!1,reason:`dim "${n}" has duplicate values`};s*=a.length}if(s>64)return{ok:!1,reason:`declared space of ${s} combinations exceeds the 64 maximum`};if(e.baseline!==void 0){if(typeof e.baseline=="string")return{ok:!1,reason:"baseline for a dims slot must be a per-dim record"};let n=e.baseline,a=o.map(([u])=>u).sort(),i=Object.keys(n).sort();if(a.join(" ")!==i.join(" "))return{ok:!1,reason:"baseline must set every declared dim exactly once"};for(let[u,m]of o)if(!m.includes(n[u]))return{ok:!1,reason:`baseline value for dim "${u}" is not declared`}}return{ok:!0}}function he(e,r){var t,o;return e.dims!=null?(o=(t=G(r))!=null?t:G(X(e)))!=null?o:{}:r}var z=20;function C(e,r,t=20){let o=r.alpha+r.beta;if(o<=0||t<=0)return{alpha:e.alpha,beta:e.beta};let s=r.alpha/o,n=t*o/(o+t);return{alpha:e.alpha+n*s,beta:e.beta+n*(1-s)}}var g="__all__",_={exposures:0,conversions:0};function M(e){return{alpha:e.conversions+1,beta:Math.max(0,e.exposures-e.conversions)+1}}function ke(e,r,t=20){var b,y,P,f;let o=(b=e.segment)!=null?b:_,s=(y=e.global)!=null?y:_,n=M(s),a=C(M(o),n,t);if(!r)return a;let i=(P=e.persona)!=null?P:_,u=(f=e.child)!=null?f:_,m=C(M(i),n,t),c=(o.exposures+1)/(o.exposures+i.exposures+2),p={alpha:c*a.alpha+(1-c)*m.alpha,beta:c*a.beta+(1-c)*m.beta};return C(M(u),p,t)}function ve(e){var o,s;let r=null,t=-1;for(let n of e){let a=n.segment===g,i=n.persona===g,u=a&&i?3:a||i?2:1;u>t&&(t=u,r=n)}return{valueSum:(o=r==null?void 0:r.valueSum)!=null?o:0,valueCount:(s=r==null?void 0:r.valueCount)!=null?s:0}}function Ae(e,r){return r==="unknown"||r===g||r===""?[{segment:e,persona:g},{segment:g,persona:g}]:[{segment:e,persona:r},{segment:e,persona:g},{segment:g,persona:r},{segment:g,persona:g}]}function ee(e){let r=2166136261;for(let t=0;t<e.length;t++)r^=e.charCodeAt(t),r=r+((r<<1)+(r<<4)+(r<<7)+(r<<8)+(r<<24))>>>0;return r}function Re(e,r,t){if(t.length===0)throw new Error("pickDeterministicArm requires at least one arm");let o=[...t].sort();return o[ee(`${e}:${r}`)%o.length]}function we(e){return e>=.3?e<.7?"medium":"high":"low"}var re=20;function te(e,r,t=re){let o=e.valueCount>0?e.valueSum/e.valueCount:0;if(r<=0)return o;if(e.valueCount<=0)return r;let s=e.valueCount/(e.valueCount+t);return s*o+(1-s)*r}function Me(e,r,t=Math.random){if(e.length===0)return null;if(e.length===1)return e[0].arm;let o=null,s=-1/0;for(let n of e){let a=w(n.alpha,n.beta,t)*te(n,r);a>s&&(o=n,s=a)}return o.arm}export{Q as CLUSTER_PRIORITY,re as EV_SHRINK_K,T as LEGACY_PERSONA_MAP,j as PERSONAS,ne as PERSONA_DISPLAY,g as POOL_ALL,z as SHRINKAGE_M,R as UNKNOWN_PERSONA,q as applyClusterHeuristic,ve as broadestValueCell,U as candidateLayouts,B as canonicalArm,oe as canonicalPersona,be as chooseLayout,we as confidenceBand,ee as fnv1a,I as hashLayout,xe as marginalArmKey,G as parseArm,Re as pickDeterministicArm,ke as pooledPosterior,M as posteriorOfCounts,V as sampleArm,Me as sampleArmEv,w as sampleBeta,te as shrunkAvgValue,C as shrunkPosterior,X as slotBaselineArm,he as slotResultFor,ge as validateSlotDecl,Ae as weightCellsFor};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentientui/policy",
3
- "version": "0.3.3",
3
+ "version": "0.5.0",
4
4
  "private": false,
5
5
  "description": "Pure decision-policy functions shared by the SentientUI API and the keyless local engine",
6
6
  "license": "MIT",