@lunora/flags 1.0.0-alpha.42 → 1.0.0-alpha.43

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.mts CHANGED
@@ -54,7 +54,9 @@ interface CreateFlagsOptions {
54
54
  * (`definition`, `env`) pair — both stable object identities for the isolate's
55
55
  * lifetime — and each pair owns its own OpenFeature domain, so a pair always
56
56
  * evaluates against the provider it was configured with instead of whichever
57
- * bind happened first. Evaluations resolve through the
57
+ * bind happened first. The bind is additionally attempted at most ONCE per
58
+ * request, so a broken deployment costs one `initialize` and one log line
59
+ * rather than one per flag read. Evaluations resolve through the
58
60
  * OpenFeature client (the SDK applies hooks and never throws — provider errors
59
61
  * surface as the default value with an `errorCode`). The default `targetingKey`
60
62
  * is merged under any per-call context, and identical evaluations within the
package/dist/index.d.ts CHANGED
@@ -54,7 +54,9 @@ interface CreateFlagsOptions {
54
54
  * (`definition`, `env`) pair — both stable object identities for the isolate's
55
55
  * lifetime — and each pair owns its own OpenFeature domain, so a pair always
56
56
  * evaluates against the provider it was configured with instead of whichever
57
- * bind happened first. Evaluations resolve through the
57
+ * bind happened first. The bind is additionally attempted at most ONCE per
58
+ * request, so a broken deployment costs one `initialize` and one log line
59
+ * rather than one per flag read. Evaluations resolve through the
58
60
  * OpenFeature client (the SDK applies hooks and never throws — provider errors
59
61
  * surface as the default value with an `errorCode`). The default `targetingKey`
60
62
  * is merged under any per-call context, and identical evaluations within the
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{defineFlags as o,isFlagsDefinition as r}from"./packem_shared/defineFlags-BZhoR_h7.mjs";import{createFlags as f}from"./packem_shared/createFlags-DqB9pDga.mjs";export{f as createFlags,o as defineFlags,r as isFlagsDefinition};
1
+ import{defineFlags as o,isFlagsDefinition as r}from"./packem_shared/defineFlags-BZhoR_h7.mjs";import{createFlags as f}from"./packem_shared/createFlags-D8e_hTbh.mjs";export{f as createFlags,o as defineFlags,r as isFlagsDefinition};
@@ -0,0 +1 @@
1
+ import{LunoraError as D}from"@lunora/errors";import{OpenFeature as E,ErrorCode as $}from"@openfeature/server-sdk";const A=/["\\\u0000-\u001F\uD800-\uDFFF]/,j=e=>A.test(e)?JSON.stringify(e):`"${e}"`,h=e=>{if(e===void 0)return"null";if(typeof e=="bigint")throw new TypeError("stableStringify: cannot use a bigint in a stable JSON cache key — pass it as a string, or use stableWireKey");if(typeof e=="number"){if(Number.isNaN(e))return"nan";if(e===1/0)return"inf";if(e===-1/0)return"-inf";if(Object.is(e,-0))return"-0"}if(typeof e=="string")return j(e);if(e===null||typeof e!="object")return JSON.stringify(e);if(Array.isArray(e)){let i="[";for(let l=0;l<e.length;l++)l>0&&(i+=","),i+=h(e[l]);return i+"]"}const c=Object.getPrototypeOf(e);if(c!==null&&c!==Object.prototype){const i=e.constructor?.name??"value";throw new TypeError(`stableStringify: cannot use a ${i} in a stable JSON cache key — only plain objects, arrays, and JSON primitives are supported (wire-typed values key via stableWireKey)`)}const a=e,s=Object.keys(a).sort();let n="{",u=!0;for(const i of s){const l=a[i];l!==void 0&&(u?u=!1:n+=",",n+=j(i),n+=":",n+=h(l))}return n+"}"},S="lunora";let O=new WeakMap,p=0;const C={},M=e=>Object.keys(e).length===0?C:e,T=e=>typeof e?.then=="function",W=(e,c)=>{const a=`@lunora/flags: could not bind the OpenFeature provider — every flag read falls back to its caller-supplied default until this is fixed: ${c instanceof Error?c.message:String(c)}`;if(e)try{const s=e.error(a);T(s)&&s.catch(()=>{});return}catch{}console.error(a)},J=(e,c,a)=>{const s=M(c);let n=O.get(e);n===void 0&&(n=new WeakMap,O.set(e,n));let u=n.get(s);if(u===void 0&&(p+=1,u={domain:p===1?S:`${S}-${String(p)}`},n.set(s,u)),u.client!==void 0)return u.client;const i=u,{domain:l}=i,{hooks:b,logger:d}=e,g=(async()=>{await E.setProviderAndWait(l,a());const t=E.getClient(l);return d&&t.setLogger(d),b&&b.length>0&&t.addHooks(...b),t})();return i.client=g,g.catch(t=>{i.client===g&&(i.client=void 0),W(d,t)}).catch(()=>{}),g},B=async()=>{O=new WeakMap,p=0,await E.clearProviders()},L=(e,c,a,s)=>{const n=h([e,c,a]);return Object.keys(s).length===0?`${n}:{}`:`${n}:${h(s)}`},P=(e,c,a,s,n)=>{switch(c){case"boolean":return e.getBooleanDetails(a,s,n);case"number":return e.getNumberDetails(a,s,n);case"object":return e.getObjectDetails(a,s,n);case"string":return e.getStringDetails(a,s,n);default:throw new D("INTERNAL",`createFlags: unknown flag type "${c}"`)}},_=(e,c,a={})=>{const{provider:s,targetingKey:n}=a,u=()=>s?.()??e.provider(c);let i;try{i=typeof n=="function"?n():n}catch{i=void 0}const l=new Map;let b;const d=()=>(b??=J(e,c,u),b),g=(t,r,o,f)=>{const k=i===void 0?{...f}:{targetingKey:i,...f},F=y=>({errorCode:$.GENERAL,errorMessage:y instanceof Error?y.message:String(y),flagKey:r,flagMetadata:{},reason:"ERROR",value:o}),w=()=>d().then(y=>P(y,t,r,o,k)).catch(F);let m;try{m=L(t,r,o,k)}catch{return w()}const v=l.get(m);if(v)return v;const N=w();return l.set(m,N),N};return{boolean:(t,r,o)=>g("boolean",t,r,o).then(f=>f.value),details:{boolean:(t,r,o)=>g("boolean",t,r,o),number:(t,r,o)=>g("number",t,r,o),object:(t,r,o)=>g("object",t,r,o),string:(t,r,o)=>g("string",t,r,o)},number:(t,r,o)=>g("number",t,r,o).then(f=>f.value),object:(t,r,o)=>g("object",t,r,o).then(f=>f.value),string:(t,r,o)=>g("string",t,r,o).then(f=>f.value)}};export{_ as createFlags,B as resetFlags};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/flags",
3
- "version": "1.0.0-alpha.42",
3
+ "version": "1.0.0-alpha.43",
4
4
  "description": "OpenFeature-based feature flags for Lunora — ctx.flags, useFlag, and a first-class Cloudflare Flagship provider with any OpenFeature provider pluggable",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -1 +0,0 @@
1
- import{LunoraError as v}from"@lunora/errors";import{OpenFeature as m,ErrorCode as F}from"@openfeature/server-sdk";const D=/["\\\u0000-\u001F\uD800-\uDFFF]/,N=e=>D.test(e)?JSON.stringify(e):`"${e}"`,y=e=>{if(e===void 0)return"null";if(typeof e=="bigint")throw new TypeError("stableStringify: cannot use a bigint in a stable JSON cache key — pass it as a string, or use stableWireKey");if(typeof e=="number"){if(Number.isNaN(e))return"nan";if(e===1/0)return"inf";if(e===-1/0)return"-inf";if(Object.is(e,-0))return"-0"}if(typeof e=="string")return N(e);if(e===null||typeof e!="object")return JSON.stringify(e);if(Array.isArray(e)){let s="[";for(let l=0;l<e.length;l++)l>0&&(s+=","),s+=y(e[l]);return s+"]"}const i=Object.getPrototypeOf(e);if(i!==null&&i!==Object.prototype){const s=e.constructor?.name??"value";throw new TypeError(`stableStringify: cannot use a ${s} in a stable JSON cache key — only plain objects, arrays, and JSON primitives are supported (wire-typed values key via stableWireKey)`)}const c=e,a=Object.keys(c).sort();let n="{",u=!0;for(const s of a){const l=c[s];l!==void 0&&(u?u=!1:n+=",",n+=N(s),n+=":",n+=y(l))}return n+"}"},j="lunora";let h=new WeakMap,d=0;const $={},A=e=>Object.keys(e).length===0?$:e,C=(e,i)=>{const c=`@lunora/flags: could not bind the OpenFeature provider — every flag read falls back to its caller-supplied default until this is fixed: ${i instanceof Error?i.message:String(i)}`;if(e){e.error(c);return}console.error(c)},M=(e,i,c)=>{const a=A(i);let n=h.get(e);n===void 0&&(n=new WeakMap,h.set(e,n));let u=n.get(a);if(u===void 0&&(d+=1,u={domain:d===1?j:`${j}-${String(d)}`},n.set(a,u)),u.client!==void 0)return u.client;const s=u,{domain:l}=s,{hooks:g,logger:o}=e,r=(async()=>{await m.setProviderAndWait(l,c());const t=m.getClient(l);return o&&t.setLogger(o),g&&g.length>0&&t.addHooks(...g),t})();return s.client=r,r.catch(t=>{s.client===r&&(s.client=void 0),C(o,t)}),r},P=async()=>{h=new WeakMap,d=0,await m.clearProviders()},T=(e,i,c,a)=>{const n=y([e,i,c]);return Object.keys(a).length===0?`${n}:{}`:`${n}:${y(a)}`},W=(e,i,c,a,n)=>{switch(i){case"boolean":return e.getBooleanDetails(c,a,n);case"number":return e.getNumberDetails(c,a,n);case"object":return e.getObjectDetails(c,a,n);case"string":return e.getStringDetails(c,a,n);default:throw new v("INTERNAL",`createFlags: unknown flag type "${i}"`)}},R=(e,i,c={})=>{const{provider:a,targetingKey:n}=c,u=()=>a?.()??e.provider(i);let s;try{s=typeof n=="function"?n():n}catch{s=void 0}const l=new Map,g=(o,r,t,f)=>{const E=s===void 0?{...f}:{targetingKey:s,...f},S=b=>({errorCode:F.GENERAL,errorMessage:b instanceof Error?b.message:String(b),flagKey:r,flagMetadata:{},reason:"ERROR",value:t}),O=()=>M(e,i,u).then(b=>W(b,o,r,t,E)).catch(S);let p;try{p=T(o,r,t,E)}catch{return O()}const k=l.get(p);if(k)return k;const w=O();return l.set(p,w),w};return{boolean:(o,r,t)=>g("boolean",o,r,t).then(f=>f.value),details:{boolean:(o,r,t)=>g("boolean",o,r,t),number:(o,r,t)=>g("number",o,r,t),object:(o,r,t)=>g("object",o,r,t),string:(o,r,t)=>g("string",o,r,t)},number:(o,r,t)=>g("number",o,r,t).then(f=>f.value),object:(o,r,t)=>g("object",o,r,t).then(f=>f.value),string:(o,r,t)=>g("string",o,r,t).then(f=>f.value)}};export{R as createFlags,P as resetFlags};