@dismissible/react-client 0.3.2-canary.2.38782c4 → 0.3.2-canary.3.c1b8c41
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/README.md +302 -156
- package/dist/components/Dismissible.d.ts +3 -4
- package/dist/dismissible-client.es.js +367 -341
- package/dist/dismissible-client.umd.js +1 -1
- package/dist/hooks/useDismissibleItem.d.ts +2 -1
- package/dist/root.d.ts +0 -1
- package/dist/types/dismissible.types.d.ts +3 -3
- package/dist/utils/auth.utils.d.ts +0 -6
- package/package.json +1 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(a,d){typeof exports=="object"&&typeof module!="undefined"?d(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],d):(a=typeof globalThis!="undefined"?globalThis:a||self,d(a.DismissibleClient={},a.React.jsxRuntime,a.React))})(this,function(a,d,o){"use strict";var Ue=Object.defineProperty,qe=Object.defineProperties;var Oe=Object.getOwnPropertyDescriptors;var V=Object.getOwnPropertySymbols;var he=Object.prototype.hasOwnProperty,be=Object.prototype.propertyIsEnumerable;var me=(a,d,o)=>d in a?Ue(a,d,{enumerable:!0,configurable:!0,writable:!0,value:o}):a[d]=o,y=(a,d)=>{for(var o in d||(d={}))he.call(d,o)&&me(a,o,d[o]);if(V)for(var o of V(d))be.call(d,o)&&me(a,o,d[o]);return a},S=(a,d)=>qe(a,Oe(d));var ee=(a,d)=>{var o={};for(var C in a)he.call(a,C)&&d.indexOf(C)<0&&(o[C]=a[C]);if(a!=null&&V)for(var C of V(a))d.indexOf(C)<0&&be.call(a,C)&&(o[C]=a[C]);return o};var H=(a,d,o)=>new Promise((C,M)=>{var B=I=>{try{$(o.next(I))}catch(k){M(k)}},G=I=>{try{$(o.throw(I))}catch(k){M(k)}},$=I=>I.done?C(I.value):Promise.resolve(I.value).then(B,G);$((o=o.apply(a,d)).next())});const C=/\{[^{}]+\}/g,M=()=>{var e,r;return typeof process=="object"&&Number.parseInt((r=(e=process==null?void 0:process.versions)==null?void 0:e.node)==null?void 0:r.substring(0,2))>=18&&process.versions.undici};function B(){return Math.random().toString(36).slice(2,11)}function G(e){let x=y({},e),{baseUrl:r="",Request:t=globalThis.Request,fetch:i=globalThis.fetch,querySerializer:n,bodySerializer:s,headers:c,requestInitExt:m=void 0}=x,p=ee(x,["baseUrl","Request","fetch","querySerializer","bodySerializer","headers","requestInitExt"]);m=M()?m:void 0,r=se(r);const h=[];function v(l,u){return H(this,null,function*(){var de;const fe=u||{},{baseUrl:R,fetch:A=i,Request:j=t,headers:T,params:D={},parseAs:P="json",querySerializer:F,bodySerializer:N=s!=null?s:pe,body:f,middleware:E=[]}=fe,U=ee(fe,["baseUrl","fetch","Request","headers","params","parseAs","querySerializer","bodySerializer","body","middleware"]);let Q=r;R&&(Q=(de=se(R))!=null?de:r);let X=typeof n=="function"?n:te(n);F&&(X=typeof F=="function"?F:te(y(y({},typeof n=="object"?n:{}),F)));const Y=f===void 0?void 0:N(f,re(c,T,D.header)),Ae=re(Y===void 0||Y instanceof FormData?{}:{"Content-Type":"application/json"},c,T,D.header),q=[...h,...E],Te=S(y(y({redirect:"follow"},p),U),{body:Y,headers:Ae});let J,_,O=new j(we(l,{baseUrl:Q,params:D,querySerializer:X}),Te),b;for(const g in U)g in O||(O[g]=U[g]);if(q.length){J=B(),_=Object.freeze({baseUrl:Q,fetch:A,parseAs:P,querySerializer:X,bodySerializer:N});for(const g of q)if(g&&typeof g=="object"&&typeof g.onRequest=="function"){const w=yield g.onRequest({request:O,schemaPath:l,params:D,options:_,id:J});if(w)if(w instanceof j)O=w;else if(w instanceof Response){b=w;break}else throw new Error("onRequest: must return new Request() or Response() when modifying the request")}}if(!b){try{b=yield A(O,m)}catch(g){let w=g;if(q.length)for(let z=q.length-1;z>=0;z--){const W=q[z];if(W&&typeof W=="object"&&typeof W.onError=="function"){const L=yield W.onError({request:O,error:w,schemaPath:l,params:D,options:_,id:J});if(L){if(L instanceof Response){w=void 0,b=L;break}if(L instanceof Error){w=L;continue}throw new Error("onError: must return new Response() or instance of Error")}}}if(w)throw w}if(q.length)for(let g=q.length-1;g>=0;g--){const w=q[g];if(w&&typeof w=="object"&&typeof w.onResponse=="function"){const z=yield w.onResponse({request:O,response:b,schemaPath:l,params:D,options:_,id:J});if(z){if(!(z instanceof Response))throw new Error("onResponse: must return new Response() when modifying the response");b=z}}}}if(b.status===204||O.method==="HEAD"||b.headers.get("Content-Length")==="0")return b.ok?{data:void 0,response:b}:{error:void 0,response:b};if(b.ok)return P==="stream"?{data:b.body,response:b}:{data:yield b[P](),response:b};let Z=yield b.text();try{Z=JSON.parse(Z)}catch(g){}return{error:Z,response:b}})}return{request(l,u,R){return v(u,S(y({},R),{method:l.toUpperCase()}))},GET(l,u){return v(l,S(y({},u),{method:"GET"}))},PUT(l,u){return v(l,S(y({},u),{method:"PUT"}))},POST(l,u){return v(l,S(y({},u),{method:"POST"}))},DELETE(l,u){return v(l,S(y({},u),{method:"DELETE"}))},OPTIONS(l,u){return v(l,S(y({},u),{method:"OPTIONS"}))},HEAD(l,u){return v(l,S(y({},u),{method:"HEAD"}))},PATCH(l,u){return v(l,S(y({},u),{method:"PATCH"}))},TRACE(l,u){return v(l,S(y({},u),{method:"TRACE"}))},use(...l){for(const u of l)if(u){if(typeof u!="object"||!("onRequest"in u||"onResponse"in u||"onError"in u))throw new Error("Middleware must be an object with one of `onRequest()`, `onResponse() or `onError()`");h.push(u)}},eject(...l){for(const u of l){const R=h.indexOf(u);R!==-1&&h.splice(R,1)}}}}function $(e,r,t){if(r==null)return"";if(typeof r=="object")throw new Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${e}=${(t==null?void 0:t.allowReserved)===!0?r:encodeURIComponent(r)}`}function I(e,r,t){if(!r||typeof r!="object")return"";const i=[],n={simple:",",label:".",matrix:";"}[t.style]||"&";if(t.style!=="deepObject"&&t.explode===!1){for(const m in r)i.push(m,t.allowReserved===!0?r[m]:encodeURIComponent(r[m]));const c=i.join(",");switch(t.style){case"form":return`${e}=${c}`;case"label":return`.${c}`;case"matrix":return`;${e}=${c}`;default:return c}}for(const c in r){const m=t.style==="deepObject"?`${e}[${c}]`:c;i.push($(m,r[c],t))}const s=i.join(n);return t.style==="label"||t.style==="matrix"?`${n}${s}`:s}function k(e,r,t){if(!Array.isArray(r))return"";if(t.explode===!1){const s={form:",",spaceDelimited:"%20",pipeDelimited:"|"}[t.style]||",",c=(t.allowReserved===!0?r:r.map(m=>encodeURIComponent(m))).join(s);switch(t.style){case"simple":return c;case"label":return`.${c}`;case"matrix":return`;${e}=${c}`;default:return`${e}=${c}`}}const i={simple:",",label:".",matrix:";"}[t.style]||"&",n=[];for(const s of r)t.style==="simple"||t.style==="label"?n.push(t.allowReserved===!0?s:encodeURIComponent(s)):n.push($(e,s,t));return t.style==="label"||t.style==="matrix"?`${i}${n.join(i)}`:n.join(i)}function te(e){return function(t){const i=[];if(t&&typeof t=="object")for(const n in t){const s=t[n];if(s!=null){if(Array.isArray(s)){if(s.length===0)continue;i.push(k(n,s,S(y({style:"form",explode:!0},e==null?void 0:e.array),{allowReserved:(e==null?void 0:e.allowReserved)||!1})));continue}if(typeof s=="object"){i.push(I(n,s,S(y({style:"deepObject",explode:!0},e==null?void 0:e.object),{allowReserved:(e==null?void 0:e.allowReserved)||!1})));continue}i.push($(n,s,e))}}return i.join("&")}}function ye(e,r){var i;let t=e;for(const n of(i=e.match(C))!=null?i:[]){let s=n.substring(1,n.length-1),c=!1,m="simple";if(s.endsWith("*")&&(c=!0,s=s.substring(0,s.length-1)),s.startsWith(".")?(m="label",s=s.substring(1)):s.startsWith(";")&&(m="matrix",s=s.substring(1)),!r||r[s]===void 0||r[s]===null)continue;const p=r[s];if(Array.isArray(p)){t=t.replace(n,k(s,p,{style:m,explode:c}));continue}if(typeof p=="object"){t=t.replace(n,I(s,p,{style:m,explode:c}));continue}if(m==="matrix"){t=t.replace(n,`;${$(s,p)}`);continue}t=t.replace(n,m==="label"?`.${encodeURIComponent(p)}`:encodeURIComponent(p))}return t}function pe(e,r){var t,i;return e instanceof FormData?e:r&&(r.get instanceof Function?(t=r.get("Content-Type"))!=null?t:r.get("content-type"):(i=r["Content-Type"])!=null?i:r["content-type"])==="application/x-www-form-urlencoded"?new URLSearchParams(e).toString():JSON.stringify(e)}function we(e,r){var n,s;let t=`${r.baseUrl}${e}`;(n=r.params)!=null&&n.path&&(t=ye(t,r.params.path));let i=r.querySerializer((s=r.params.query)!=null?s:{});return i.startsWith("?")&&(i=i.substring(1)),i&&(t+=`?${i}`),t}function re(...e){const r=new Headers;for(const t of e){if(!t||typeof t!="object")continue;const i=t instanceof Headers?t.entries():Object.entries(t);for(const[n,s]of i)if(s===null)r.delete(n);else if(Array.isArray(s))for(const c of s)r.append(n,c);else s!==void 0&&r.set(n,s)}return r}function se(e){return e.endsWith("/")?e.substring(0,e.length-1):e}const ge={baseUrl:"http://localhost:3001"},ve={development:{baseUrl:"http://localhost:3001"},staging:{baseUrl:"https://api.staging.dismissible.io"},production:{baseUrl:"https://api.dismissible.io"}},Ee=()=>ve["production"]||ge,ne=(e,r,t)=>{try{const i=`${r}_${e}`,n=localStorage.getItem(i);if(!n)return null;const{data:s,timestamp:c}=JSON.parse(n);return t&&Date.now()-c>t?(localStorage.removeItem(i),null):s}catch(i){return null}},ie=(e,r,t)=>{try{const i=`${t}_${e}`,n={data:r,timestamp:Date.now()};localStorage.setItem(i,JSON.stringify(n))}catch(i){console.warn("Failed to cache dismissible item:",i)}},oe=(e,r)=>{try{const t=`${r}_${e}`;localStorage.removeItem(t)}catch(t){console.warn("Failed to remove cached dismissible item:",t)}},K=o.createContext(null),ae=()=>{const e=o.useContext(K);if(!e)throw new Error("useDismissibleContext must be used within a DismissibleProvider");return e},Ce="dismissible",ce=(e,r={})=>{var N;const{initialData:t,enableCache:i=!0,cachePrefix:n=Ce,cacheExpiration:s}=r,c=ae(),{userId:m}=c,p=o.useMemo(()=>{const f=Ee(),E=c.baseUrl||f.baseUrl;return G({baseUrl:E,headers:{}})},[c]),h=o.useMemo(()=>`${m}-${e}`,[m,e]),v=o.useRef({enableCache:i,cachePrefix:n,cacheExpiration:s}),x=o.useRef(e),l=o.useRef(h),[u,R]=o.useState(!1),[A,j]=o.useState(null),[T,D]=o.useState(()=>{if(t)return t;if(i){const f=ne(h,n,s);if(f)return f}}),P=o.useCallback(()=>H(this,null,function*(){if(i){const f=ne(h,n,s);if(f!=null&&f.dismissedAt){D(f),R(!1);return}}R(!0),j(null);try{const f=yield c.getAuthHeaders(),{data:E,error:U}=yield p.GET("/v1/user/{userId}/dismissible-item/{itemId}",{params:{path:{userId:m,itemId:e}},headers:f});if(U||!E)throw new Error("Failed to fetch dismissible item");D(E.data),i&&ie(h,E.data,n)}catch(f){j(f instanceof Error?f:new Error("Unknown error occurred"))}finally{R(!1)}}),[e,m,h,i,n,s,p,c]);o.useEffect(()=>{const f=x.current!==e,E=l.current!==h;f||E?(x.current=e,l.current=h,P()):t||P()},[e,h,t]),o.useEffect(()=>{const f=v.current;(f.enableCache!==i||f.cachePrefix!==n||f.cacheExpiration!==s)&&(f.cachePrefix!==n&&oe(h,f.cachePrefix),!i&&f.enableCache&&oe(h,n),v.current={enableCache:i,cachePrefix:n,cacheExpiration:s},P())},[i,n,s,h]);const F=o.useCallback(()=>H(this,null,function*(){j(null);try{const f=yield c.getAuthHeaders(),{data:E,error:U}=yield p.DELETE("/v1/user/{userId}/dismissible-item/{itemId}",{params:{path:{userId:m,itemId:e}},headers:f});if(U||!E)throw new Error("Failed to dismiss item");D(E.data),i&&ie(h,E.data,n)}catch(f){throw j(f instanceof Error?f:new Error("Failed to dismiss item")),f}}),[e,m,h,i,n,p,c]);return{dismissedOn:(N=T==null?void 0:T.dismissedAt)!=null?N:null,dismiss:F,isLoading:u,error:A,item:T}},Re=()=>d.jsx("div",{className:"dismissible-loading","aria-live":"polite",children:"Loading..."}),Se=({error:e})=>d.jsxs("div",{className:"dismissible-error",role:"alert",children:["Error loading dismissible item: ",e.message]}),Ie=({id:e,onDismiss:r,ariaLabel:t})=>d.jsx("button",{id:e,className:"dismissible-button",onClick:r,"aria-label":t,type:"button",children:"×"}),De=({id:e,children:r,onDismiss:t,LoadingComponent:i=Re,ErrorComponent:n=Se,DismissButtonComponent:s=Ie,enableCache:c,cachePrefix:m,cacheExpiration:p,ignoreErrors:h=!1})=>{const{dismissedOn:v,isLoading:x,error:l,dismiss:u}=ce(e,{enableCache:c,cachePrefix:m,cacheExpiration:p}),[R,A]=o.useState(!1);o.useEffect(()=>{A(!1)},[e]);const j=()=>H(this,null,function*(){A(!0);try{yield u(),t==null||t()}catch(T){A(!1)}});return x&&i?d.jsx(i,{id:e}):x&&!i?null:l&&n&&!h?d.jsx(n,{id:e,error:l}):v||R?null:d.jsxs("div",{className:"dismissible-container",children:[d.jsx("div",{className:"dismissible-content",children:r}),s?d.jsx(s,{id:e,onDismiss:j,ariaLabel:`Dismiss ${e}`}):null]})},le=e=>H(this,null,function*(){if(typeof e=="function")try{const r=e();return yield Promise.resolve(r)}catch(r){console.warn("Failed to resolve JWT from function:",r);return}return e}),ue=e=>H(this,null,function*(){const r=yield le(e);return r?{Authorization:`Bearer ${r}`}:{}}),je=e=>{const r=e.split(".");return r.length===3&&r.every(t=>t.length>0)},$e=({userId:e,jwt:r,baseUrl:t,children:i})=>{const n=o.useMemo(()=>({userId:e,jwt:r,baseUrl:t,getAuthHeaders:()=>H(this,null,function*(){return yield ue(r)})}),[e,r,t]);return d.jsx(K.Provider,{value:n,children:i})},xe="0.3.1";a.Dismissible=De,a.DismissibleContext=K,a.DismissibleProvider=$e,a.VERSION=xe,a.getAuthHeaders=ue,a.isValidJwtFormat=je,a.resolveJwt=le,a.useDismissibleContext=ae,a.useDismissibleItem=ce,Object.defineProperty(a,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
(function(c,d){typeof exports=="object"&&typeof module!="undefined"?d(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],d):(c=typeof globalThis!="undefined"?globalThis:c||self,d(c.DismissibleClient={},c.React.jsxRuntime,c.React))})(this,function(c,d,o){"use strict";var Ae=Object.defineProperty,$e=Object.defineProperties;var Te=Object.getOwnPropertyDescriptors;var Q=Object.getOwnPropertySymbols;var ye=Object.prototype.hasOwnProperty,be=Object.prototype.propertyIsEnumerable;var me=(c,d,o)=>d in c?Ae(c,d,{enumerable:!0,configurable:!0,writable:!0,value:o}):c[d]=o,g=(c,d)=>{for(var o in d||(d={}))ye.call(d,o)&&me(c,o,d[o]);if(Q)for(var o of Q(d))be.call(d,o)&&me(c,o,d[o]);return c},S=(c,d)=>$e(c,Te(d));var re=(c,d)=>{var o={};for(var R in c)ye.call(c,R)&&d.indexOf(R)<0&&(o[R]=c[R]);if(c!=null&&Q)for(var R of Q(c))d.indexOf(R)<0&&be.call(c,R)&&(o[R]=c[R]);return o};var U=(c,d,o)=>new Promise((R,M)=>{var V=j=>{try{q(o.next(j))}catch(F){M(F)}},X=j=>{try{q(o.throw(j))}catch(F){M(F)}},q=j=>j.done?R(j.value):Promise.resolve(j.value).then(V,X);q((o=o.apply(c,d)).next())});const R=/\{[^{}]+\}/g,M=()=>{var e,r;return typeof process=="object"&&Number.parseInt((r=(e=process==null?void 0:process.versions)==null?void 0:e.node)==null?void 0:r.substring(0,2))>=18&&process.versions.undici};function V(){return Math.random().toString(36).slice(2,11)}function X(e){let H=g({},e),{baseUrl:r="",Request:t=globalThis.Request,fetch:n=globalThis.fetch,querySerializer:i,bodySerializer:s,headers:a,requestInitExt:h=void 0}=H,b=re(H,["baseUrl","Request","fetch","querySerializer","bodySerializer","headers","requestInitExt"]);h=M()?h:void 0,r=ie(r);const m=[];function C(f,l){return U(this,null,function*(){var he;const de=l||{},{baseUrl:x,fetch:A=n,Request:L=t,headers:$,params:D={},parseAs:O="json",querySerializer:T,bodySerializer:J=s!=null?s:pe,body:W,middleware:_=[]}=de,u=re(de,["baseUrl","fetch","Request","headers","params","parseAs","querySerializer","bodySerializer","body","middleware"]);let p=r;x&&(p=(he=ie(x))!=null?he:r);let y=typeof i=="function"?i:se(i);T&&(y=typeof T=="function"?T:se(g(g({},typeof i=="object"?i:{}),T)));const k=W===void 0?void 0:J(W,ne(a,$,D.header)),ee=ne(k===void 0||k instanceof FormData?{}:{"Content-Type":"application/json"},a,$,D.header),P=[...m,..._],je=S(g(g({redirect:"follow"},b),u),{body:k,headers:ee});let B,G,I=new L(ge(f,{baseUrl:p,params:D,querySerializer:y}),je),w;for(const v in u)v in I||(I[v]=u[v]);if(P.length){B=V(),G=Object.freeze({baseUrl:p,fetch:A,parseAs:O,querySerializer:y,bodySerializer:J});for(const v of P)if(v&&typeof v=="object"&&typeof v.onRequest=="function"){const E=yield v.onRequest({request:I,schemaPath:f,params:D,options:G,id:B});if(E)if(E instanceof L)I=E;else if(E instanceof Response){w=E;break}else throw new Error("onRequest: must return new Request() or Response() when modifying the request")}}if(!w){try{w=yield A(I,h)}catch(v){let E=v;if(P.length)for(let z=P.length-1;z>=0;z--){const K=P[z];if(K&&typeof K=="object"&&typeof K.onError=="function"){const N=yield K.onError({request:I,error:E,schemaPath:f,params:D,options:G,id:B});if(N){if(N instanceof Response){E=void 0,w=N;break}if(N instanceof Error){E=N;continue}throw new Error("onError: must return new Response() or instance of Error")}}}if(E)throw E}if(P.length)for(let v=P.length-1;v>=0;v--){const E=P[v];if(E&&typeof E=="object"&&typeof E.onResponse=="function"){const z=yield E.onResponse({request:I,response:w,schemaPath:f,params:D,options:G,id:B});if(z){if(!(z instanceof Response))throw new Error("onResponse: must return new Response() when modifying the response");w=z}}}}if(w.status===204||I.method==="HEAD"||w.headers.get("Content-Length")==="0")return w.ok?{data:void 0,response:w}:{error:void 0,response:w};if(w.ok)return O==="stream"?{data:w.body,response:w}:{data:yield w[O](),response:w};let te=yield w.text();try{te=JSON.parse(te)}catch(v){}return{error:te,response:w}})}return{request(f,l,x){return C(l,S(g({},x),{method:f.toUpperCase()}))},GET(f,l){return C(f,S(g({},l),{method:"GET"}))},PUT(f,l){return C(f,S(g({},l),{method:"PUT"}))},POST(f,l){return C(f,S(g({},l),{method:"POST"}))},DELETE(f,l){return C(f,S(g({},l),{method:"DELETE"}))},OPTIONS(f,l){return C(f,S(g({},l),{method:"OPTIONS"}))},HEAD(f,l){return C(f,S(g({},l),{method:"HEAD"}))},PATCH(f,l){return C(f,S(g({},l),{method:"PATCH"}))},TRACE(f,l){return C(f,S(g({},l),{method:"TRACE"}))},use(...f){for(const l of f)if(l){if(typeof l!="object"||!("onRequest"in l||"onResponse"in l||"onError"in l))throw new Error("Middleware must be an object with one of `onRequest()`, `onResponse() or `onError()`");m.push(l)}},eject(...f){for(const l of f){const x=m.indexOf(l);x!==-1&&m.splice(x,1)}}}}function q(e,r,t){if(r==null)return"";if(typeof r=="object")throw new Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${e}=${(t==null?void 0:t.allowReserved)===!0?r:encodeURIComponent(r)}`}function j(e,r,t){if(!r||typeof r!="object")return"";const n=[],i={simple:",",label:".",matrix:";"}[t.style]||"&";if(t.style!=="deepObject"&&t.explode===!1){for(const h in r)n.push(h,t.allowReserved===!0?r[h]:encodeURIComponent(r[h]));const a=n.join(",");switch(t.style){case"form":return`${e}=${a}`;case"label":return`.${a}`;case"matrix":return`;${e}=${a}`;default:return a}}for(const a in r){const h=t.style==="deepObject"?`${e}[${a}]`:a;n.push(q(h,r[a],t))}const s=n.join(i);return t.style==="label"||t.style==="matrix"?`${i}${s}`:s}function F(e,r,t){if(!Array.isArray(r))return"";if(t.explode===!1){const s={form:",",spaceDelimited:"%20",pipeDelimited:"|"}[t.style]||",",a=(t.allowReserved===!0?r:r.map(h=>encodeURIComponent(h))).join(s);switch(t.style){case"simple":return a;case"label":return`.${a}`;case"matrix":return`;${e}=${a}`;default:return`${e}=${a}`}}const n={simple:",",label:".",matrix:";"}[t.style]||"&",i=[];for(const s of r)t.style==="simple"||t.style==="label"?i.push(t.allowReserved===!0?s:encodeURIComponent(s)):i.push(q(e,s,t));return t.style==="label"||t.style==="matrix"?`${n}${i.join(n)}`:i.join(n)}function se(e){return function(t){const n=[];if(t&&typeof t=="object")for(const i in t){const s=t[i];if(s!=null){if(Array.isArray(s)){if(s.length===0)continue;n.push(F(i,s,S(g({style:"form",explode:!0},e==null?void 0:e.array),{allowReserved:(e==null?void 0:e.allowReserved)||!1})));continue}if(typeof s=="object"){n.push(j(i,s,S(g({style:"deepObject",explode:!0},e==null?void 0:e.object),{allowReserved:(e==null?void 0:e.allowReserved)||!1})));continue}n.push(q(i,s,e))}}return n.join("&")}}function we(e,r){var n;let t=e;for(const i of(n=e.match(R))!=null?n:[]){let s=i.substring(1,i.length-1),a=!1,h="simple";if(s.endsWith("*")&&(a=!0,s=s.substring(0,s.length-1)),s.startsWith(".")?(h="label",s=s.substring(1)):s.startsWith(";")&&(h="matrix",s=s.substring(1)),!r||r[s]===void 0||r[s]===null)continue;const b=r[s];if(Array.isArray(b)){t=t.replace(i,F(s,b,{style:h,explode:a}));continue}if(typeof b=="object"){t=t.replace(i,j(s,b,{style:h,explode:a}));continue}if(h==="matrix"){t=t.replace(i,`;${q(s,b)}`);continue}t=t.replace(i,h==="label"?`.${encodeURIComponent(b)}`:encodeURIComponent(b))}return t}function pe(e,r){var t,n;return e instanceof FormData?e:r&&(r.get instanceof Function?(t=r.get("Content-Type"))!=null?t:r.get("content-type"):(n=r["Content-Type"])!=null?n:r["content-type"])==="application/x-www-form-urlencoded"?new URLSearchParams(e).toString():JSON.stringify(e)}function ge(e,r){var i,s;let t=`${r.baseUrl}${e}`;(i=r.params)!=null&&i.path&&(t=we(t,r.params.path));let n=r.querySerializer((s=r.params.query)!=null?s:{});return n.startsWith("?")&&(n=n.substring(1)),n&&(t+=`?${n}`),t}function ne(...e){const r=new Headers;for(const t of e){if(!t||typeof t!="object")continue;const n=t instanceof Headers?t.entries():Object.entries(t);for(const[i,s]of n)if(s===null)r.delete(i);else if(Array.isArray(s))for(const a of s)r.append(i,a);else s!==void 0&&r.set(i,s)}return r}function ie(e){return e.endsWith("/")?e.substring(0,e.length-1):e}const oe=(e,r,t)=>{try{const n=`${r}_${e}`,i=localStorage.getItem(n);if(!i)return null;const{data:s,timestamp:a}=JSON.parse(i);return t&&Date.now()-a>t?(localStorage.removeItem(n),null):s}catch(n){return null}},Y=(e,r,t)=>{try{const n=`${t}_${e}`,i={data:r,timestamp:Date.now()};localStorage.setItem(n,JSON.stringify(i))}catch(n){console.warn("Failed to cache dismissible item:",n)}},ae=(e,r)=>{try{const t=`${r}_${e}`;localStorage.removeItem(t)}catch(t){console.warn("Failed to remove cached dismissible item:",t)}},Z=o.createContext(null),ce=()=>{const e=o.useContext(Z);if(!e)throw new Error("useDismissibleContext must be used within a DismissibleProvider");return e},Ee="dismissible",le=(e,r={})=>{var _;const{initialData:t,enableCache:n=!0,cachePrefix:i=Ee,cacheExpiration:s}=r,a=ce(),{userId:h}=a,b=o.useMemo(()=>X({baseUrl:a.baseUrl,headers:{}}),[a.baseUrl]),m=o.useMemo(()=>`${h}-${e}`,[h,e]),C=o.useRef({enableCache:n,cachePrefix:i,cacheExpiration:s}),H=o.useRef(e),f=o.useRef(m),l=o.useRef(null),[x,A]=o.useState(!1),[L,$]=o.useState(null),[D,O]=o.useState(()=>{if(t)return t;if(n){const u=oe(m,i,s);if(u)return u}}),T=o.useCallback(()=>U(this,null,function*(){var p;if(n){const y=oe(m,i,s);if(y!=null&&y.dismissedAt){O(y),A(!1);return}}(p=l.current)==null||p.abort();const u=new AbortController;l.current=u,A(!0),$(null);try{const y=yield a.getAuthHeaders(),{data:k,error:ee}=yield b.GET("/v1/user/{userId}/dismissible-item/{itemId}",{params:{path:{userId:h,itemId:e}},headers:y,signal:u.signal});if(ee||!k)throw new Error("Failed to fetch dismissible item");O(k.data),n&&Y(m,k.data,i)}catch(y){if(y instanceof Error&&y.name==="AbortError")return;$(y instanceof Error?y:new Error("Unknown error occurred"))}finally{A(!1)}}),[e,h,m,n,i,s,b,a]);o.useEffect(()=>{const u=H.current!==e,p=f.current!==m;u||p?(H.current=e,f.current=m,T()):t||T()},[e,m,t,T]),o.useEffect(()=>()=>{var u;(u=l.current)==null||u.abort()},[]),o.useEffect(()=>{const u=C.current;(u.enableCache!==n||u.cachePrefix!==i||u.cacheExpiration!==s)&&(u.cachePrefix!==i&&ae(m,u.cachePrefix),!n&&u.enableCache&&ae(m,u.cachePrefix),C.current={enableCache:n,cachePrefix:i,cacheExpiration:s},T())},[n,i,s,m,T]);const J=o.useCallback(()=>U(this,null,function*(){$(null);try{const u=yield a.getAuthHeaders(),{data:p,error:y}=yield b.DELETE("/v1/user/{userId}/dismissible-item/{itemId}",{params:{path:{userId:h,itemId:e}},headers:u});if(y||!p)throw new Error("Failed to dismiss item");O(p.data),n&&Y(m,p.data,i)}catch(u){throw $(u instanceof Error?u:new Error("Failed to dismiss item")),u}}),[e,h,m,n,i,b,a]),W=o.useCallback(()=>U(this,null,function*(){$(null);try{const u=yield a.getAuthHeaders(),{data:p,error:y}=yield b.POST("/v1/user/{userId}/dismissible-item/{itemId}",{params:{path:{userId:h,itemId:e}},headers:u});if(y||!p)throw new Error("Failed to restore item");O(p.data),n&&Y(m,p.data,i)}catch(u){throw $(u instanceof Error?u:new Error("Failed to restore item")),u}}),[e,h,m,n,i,b,a]);return{dismissedOn:(_=D==null?void 0:D.dismissedAt)!=null?_:null,dismiss:J,restore:W,isLoading:x,error:L,item:D}},ve=()=>d.jsx("div",{className:"dismissible-loading","aria-live":"polite",children:"Loading..."}),Ce=()=>d.jsx("div",{className:"dismissible-error",role:"alert",children:"Unable to load content. Please try again later."}),Re=({onDismiss:e,ariaLabel:r})=>d.jsx("button",{className:"dismissible-button",onClick:e,"aria-label":r,type:"button",children:"×"}),Se=({itemId:e,children:r,onDismiss:t,LoadingComponent:n=ve,ErrorComponent:i=Ce,DismissButtonComponent:s=Re,enableCache:a,cachePrefix:h,cacheExpiration:b,ignoreErrors:m=!1})=>{const{dismissedOn:C,isLoading:H,error:f,dismiss:l}=le(e,{enableCache:a,cachePrefix:h,cacheExpiration:b}),[x,A]=o.useState(!1);o.useEffect(()=>{A(!1)},[e]);const L=()=>U(this,null,function*(){A(!0);try{yield l(),t==null||t()}catch($){A(!1)}});return H&&n?d.jsx(n,{itemId:e}):H&&!n?null:f&&i&&!m?d.jsx(i,{itemId:e,error:f}):C||x?null:d.jsxs("div",{className:"dismissible-container",children:[d.jsx("div",{className:"dismissible-content",children:r}),s?d.jsx(s,{onDismiss:L,ariaLabel:`Dismiss ${e}`}):null]})},ue=e=>U(this,null,function*(){if(typeof e=="function")try{const r=e();return yield Promise.resolve(r)}catch(r){console.warn("Failed to resolve JWT from function:",r);return}return e}),fe=e=>U(this,null,function*(){const r=yield ue(e);return r?{Authorization:`Bearer ${r}`}:{}}),xe=e=>{try{const r=new URL(e),t=r.hostname==="localhost"||r.hostname==="127.0.0.1"||r.hostname==="[::1]",n=r.protocol==="https:";return{isSecure:n||t,isLocalhost:t,isHttps:n}}catch(r){return{isSecure:!1,isLocalhost:!1,isHttps:!1}}},De=({userId:e,jwt:r,baseUrl:t,children:n})=>{const{isSecure:i}=xe(t);i||console.warn(`[dismissible] Insecure baseUrl "${t}". Use https:// in production (or localhost for development). JWT tokens may be exposed over insecure connections.`);const s=o.useMemo(()=>({userId:e,jwt:r,baseUrl:t,getAuthHeaders:()=>U(this,null,function*(){return yield fe(r)})}),[e,r,t]);return d.jsx(Z.Provider,{value:s,children:n})};c.Dismissible=Se,c.DismissibleContext=Z,c.DismissibleProvider=De,c.getAuthHeaders=fe,c.resolveJwt=ue,c.useDismissibleContext=ce,c.useDismissibleItem=le,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"})});
|
|
@@ -17,9 +17,10 @@ export interface UseDismissibleItemOptions {
|
|
|
17
17
|
* @param options - Configuration options for the hook
|
|
18
18
|
* @returns Object with dismissedOn, dismiss and restore functions
|
|
19
19
|
*/
|
|
20
|
-
export declare const useDismissibleItem: (
|
|
20
|
+
export declare const useDismissibleItem: (itemId: string, options?: UseDismissibleItemOptions) => {
|
|
21
21
|
dismissedOn: string | null;
|
|
22
22
|
dismiss: () => Promise<void>;
|
|
23
|
+
restore: () => Promise<void>;
|
|
23
24
|
isLoading: boolean;
|
|
24
25
|
error: Error | null;
|
|
25
26
|
item: {
|
package/dist/root.d.ts
CHANGED
|
@@ -13,8 +13,8 @@ export interface DismissibleProviderProps {
|
|
|
13
13
|
userId: string;
|
|
14
14
|
/** JWT token for authentication - can be static string or function */
|
|
15
15
|
jwt?: JwtToken;
|
|
16
|
-
/** Base URL for API requests
|
|
17
|
-
baseUrl
|
|
16
|
+
/** Base URL for API requests */
|
|
17
|
+
baseUrl: string;
|
|
18
18
|
/** Child components */
|
|
19
19
|
children: React.ReactNode;
|
|
20
20
|
}
|
|
@@ -27,7 +27,7 @@ export interface DismissibleContextValue {
|
|
|
27
27
|
/** JWT token for authentication */
|
|
28
28
|
jwt?: JwtToken;
|
|
29
29
|
/** Base URL for API requests */
|
|
30
|
-
baseUrl
|
|
30
|
+
baseUrl: string;
|
|
31
31
|
/** Helper function to get authentication headers */
|
|
32
32
|
getAuthHeaders: () => Promise<AuthHeaders>;
|
|
33
33
|
}
|
|
@@ -11,9 +11,3 @@ export declare const resolveJwt: (jwt: JwtToken | undefined) => Promise<string |
|
|
|
11
11
|
* @returns Promise that resolves to headers object with Authorization header if JWT is available
|
|
12
12
|
*/
|
|
13
13
|
export declare const getAuthHeaders: (jwt?: JwtToken) => Promise<AuthHeaders>;
|
|
14
|
-
/**
|
|
15
|
-
* Validates that a JWT token is properly formatted
|
|
16
|
-
* @param token - The JWT token to validate
|
|
17
|
-
* @returns True if token appears to be a valid JWT format
|
|
18
|
-
*/
|
|
19
|
-
export declare const isValidJwtFormat: (token: string) => boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dismissible/react-client",
|
|
3
|
-
"version": "0.3.2-canary.
|
|
3
|
+
"version": "0.3.2-canary.3.c1b8c41",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -94,7 +94,6 @@
|
|
|
94
94
|
},
|
|
95
95
|
"eslintConfig": {
|
|
96
96
|
"extends": [
|
|
97
|
-
"plugin:storybook/recommended",
|
|
98
97
|
"plugin:storybook/recommended"
|
|
99
98
|
]
|
|
100
99
|
},
|