@figma-vars/hooks 1.4.4 → 1.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.
Files changed (54) hide show
  1. package/README.md +14 -0
  2. package/dist/index.js +17 -0
  3. package/dist/index.mjs +838 -0
  4. package/package.json +1 -1
  5. package/dist/figma-vars-hooks.js +0 -838
  6. package/dist/figma-vars-hooks.umd.cjs +0 -17
  7. package/dist/src/api/mutator.test.d.ts +0 -1
  8. package/dist/tests/FigmaVarsProvider.test.d.ts +0 -1
  9. package/dist/tests/api/fetcher.test.d.ts +0 -1
  10. package/dist/tests/api/mutator.test.d.ts +0 -1
  11. package/dist/tests/constants/index.test.d.ts +0 -1
  12. package/dist/tests/contexts/index.test.d.ts +0 -1
  13. package/dist/tests/hooks/index.test.d.ts +0 -1
  14. package/dist/tests/hooks/useBulkUpdateVariables.test.d.ts +0 -1
  15. package/dist/tests/hooks/useCreateVariable.test.d.ts +0 -1
  16. package/dist/tests/hooks/useDeleteVariable.test.d.ts +0 -1
  17. package/dist/tests/hooks/useFigmaToken.test.d.ts +0 -1
  18. package/dist/tests/hooks/useMutation.test.d.ts +0 -1
  19. package/dist/tests/hooks/useUpdateVariable.test.d.ts +0 -1
  20. package/dist/tests/hooks/useVariableCollections.test.d.ts +0 -1
  21. package/dist/tests/hooks/useVariableModes.test.d.ts +0 -1
  22. package/dist/tests/hooks/useVariables.test.d.ts +0 -1
  23. package/dist/tests/index.test.d.ts +0 -1
  24. package/dist/tests/mocks/variables.d.ts +0 -2
  25. package/dist/tests/setup.d.ts +0 -0
  26. package/dist/tests/test-utils.d.ts +0 -10
  27. package/dist/tests/test-utils.test.d.ts +0 -1
  28. package/dist/tests/types.test.d.ts +0 -1
  29. package/dist/tests/utils/filterVariables.test.d.ts +0 -1
  30. package/dist/tests/utils/index.test.d.ts +0 -1
  31. /package/dist/{src/api → api}/fetcher.d.ts +0 -0
  32. /package/dist/{src/api → api}/index.d.ts +0 -0
  33. /package/dist/{src/api → api}/mutator.d.ts +0 -0
  34. /package/dist/{src/constants → constants}/index.d.ts +0 -0
  35. /package/dist/{src/contexts → contexts}/FigmaVarsProvider.d.ts +0 -0
  36. /package/dist/{src/contexts → contexts}/index.d.ts +0 -0
  37. /package/dist/{src/hooks → hooks}/index.d.ts +0 -0
  38. /package/dist/{src/hooks → hooks}/useBulkUpdateVariables.d.ts +0 -0
  39. /package/dist/{src/hooks → hooks}/useCreateVariable.d.ts +0 -0
  40. /package/dist/{src/hooks → hooks}/useDeleteVariable.d.ts +0 -0
  41. /package/dist/{src/hooks → hooks}/useFigmaToken.d.ts +0 -0
  42. /package/dist/{src/hooks → hooks}/useMutation.d.ts +0 -0
  43. /package/dist/{src/hooks → hooks}/useUpdateVariable.d.ts +0 -0
  44. /package/dist/{src/hooks → hooks}/useVariableCollections.d.ts +0 -0
  45. /package/dist/{src/hooks → hooks}/useVariableModes.d.ts +0 -0
  46. /package/dist/{src/hooks → hooks}/useVariables.d.ts +0 -0
  47. /package/dist/{src/index.d.ts → index.d.ts} +0 -0
  48. /package/dist/{src/types → types}/contexts.d.ts +0 -0
  49. /package/dist/{src/types → types}/figma.d.ts +0 -0
  50. /package/dist/{src/types → types}/hooks.d.ts +0 -0
  51. /package/dist/{src/types → types}/index.d.ts +0 -0
  52. /package/dist/{src/types → types}/mutations.d.ts +0 -0
  53. /package/dist/{src/utils → utils}/filterVariables.d.ts +0 -0
  54. /package/dist/{src/utils → utils}/index.d.ts +0 -0
package/README.md CHANGED
@@ -9,6 +9,7 @@ Built for the modern web, this library provides a suite of hooks to fetch, manag
9
9
  ![Status](https://img.shields.io/badge/status-stable-brightgreen)
10
10
  ![CI](https://github.com/marklearst/figma-vars-hooks/actions/workflows/publish.yml/badge.svg)
11
11
  [![codecov](https://codecov.io/gh/marklearst/figma-vars-hooks/branch/main/graph/badge.svg)](https://codecov.io/gh/marklearst/figma-vars-hooks)
12
+ ![Test Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen)
12
13
  ![License](https://img.shields.io/github/license/marklearst/figma-vars-hooks)
13
14
  ![GitHub last commit](https://img.shields.io/github/last-commit/marklearst/figma-vars-hooks)
14
15
  ![GitHub code size](https://img.shields.io/github/languages/code-size/marklearst/figma-vars-hooks)
@@ -28,6 +29,19 @@ Built for the modern web, this library provides a suite of hooks to fetch, manag
28
29
 
29
30
  ---
30
31
 
32
+ ## 🧱 Architecture Highlights
33
+
34
+ ✅ **100% Test Coverage** - Comprehensive test suite with 78 tests covering all hooks, utilities, and edge cases via Vitest
35
+ ✅ **Consistent Error Handling** - Standardized error propagation with clear messages from the Figma API
36
+ ✅ **Strictly Typed APIs** - Modern TypeScript best practices with full type inference and autocompletion
37
+ ✅ **Predictable Hook Signatures** - Consistent, composable patterns designed for safe React integrations
38
+ ✅ **Developer-First Architecture** - Clean folder structure, path aliases, and logical component separation
39
+ ✅ **React Ecosystem** - Built specifically for React apps, Storybook, Next.js, and design system dashboards
40
+ ✅ **Ergonomic DX** - Intuitive API that's easy to use in both prototype and production environments
41
+ ✅ **Minimal Dependencies** - Leverages SWR for caching with careful dependency selection for optimal bundle size
42
+
43
+ ---
44
+
31
45
  ## 📦 Install
32
46
 
33
47
  ```bash
package/dist/index.js ADDED
@@ -0,0 +1,17 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const pt=require("react/jsx-runtime"),m=require("react"),Xe=m.createContext(void 0),mt=({children:e,token:t,fileKey:n})=>pt.jsx(Xe.Provider,{value:{token:t,fileKey:n},children:e}),te=()=>{const e=m.useContext(Xe);if(e===void 0)throw new Error("useFigmaTokenContext must be used within a FigmaVarsProvider");return e};var ie={exports:{}},pe={};/**
2
+ * @license React
3
+ * use-sync-external-store-shim.production.js
4
+ *
5
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
6
+ *
7
+ * This source code is licensed under the MIT license found in the
8
+ * LICENSE file in the root directory of this source tree.
9
+ */var We;function ht(){if(We)return pe;We=1;var e=m;function t(l,E){return l===E&&(l!==0||1/l===1/E)||l!==l&&E!==E}var n=typeof Object.is=="function"?Object.is:t,r=e.useState,s=e.useEffect,c=e.useLayoutEffect,o=e.useDebugValue;function u(l,E){var a=E(),p=r({inst:{value:a,getSnapshot:E}}),f=p[0].inst,I=p[1];return c(function(){f.value=a,f.getSnapshot=E,h(f)&&I({inst:f})},[l,a,E]),s(function(){return h(f)&&I({inst:f}),l(function(){h(f)&&I({inst:f})})},[l]),o(a),a}function h(l){var E=l.getSnapshot;l=l.value;try{var a=E();return!n(l,a)}catch{return!0}}function y(l,E){return E()}var v=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?y:u;return pe.useSyncExternalStore=e.useSyncExternalStore!==void 0?e.useSyncExternalStore:v,pe}var me={};/**
10
+ * @license React
11
+ * use-sync-external-store-shim.development.js
12
+ *
13
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
14
+ *
15
+ * This source code is licensed under the MIT license found in the
16
+ * LICENSE file in the root directory of this source tree.
17
+ */var ke;function St(){return ke||(ke=1,process.env.NODE_ENV!=="production"&&function(){function e(a,p){return a===p&&(a!==0||1/a===1/p)||a!==a&&p!==p}function t(a,p){v||s.startTransition===void 0||(v=!0,console.error("You are using an outdated, pre-release alpha of React 18 that does not support useSyncExternalStore. The use-sync-external-store shim will not work correctly. Upgrade to a newer pre-release."));var f=p();if(!l){var I=p();c(f,I)||(console.error("The result of getSnapshot should be cached to avoid an infinite loop"),l=!0)}I=o({inst:{value:f,getSnapshot:p}});var i=I[0].inst,U=I[1];return h(function(){i.value=f,i.getSnapshot=p,n(i)&&U({inst:i})},[a,f,p]),u(function(){return n(i)&&U({inst:i}),a(function(){n(i)&&U({inst:i})})},[a]),y(f),f}function n(a){var p=a.getSnapshot;a=a.value;try{var f=p();return!c(a,f)}catch{return!0}}function r(a,p){return p()}typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart=="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());var s=m,c=typeof Object.is=="function"?Object.is:e,o=s.useState,u=s.useEffect,h=s.useLayoutEffect,y=s.useDebugValue,v=!1,l=!1,E=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?r:t;me.useSyncExternalStore=s.useSyncExternalStore!==void 0?s.useSyncExternalStore:E,typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop=="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error())}()),me}var $e;function _t(){return $e||($e=1,process.env.NODE_ENV==="production"?ie.exports=ht():ie.exports=St()),ie.exports}var Ot=_t();const Qe=0,Ze=1,et=2,He=3;var Ke=Object.prototype.hasOwnProperty;function we(e,t){var n,r;if(e===t)return!0;if(e&&t&&(n=e.constructor)===t.constructor){if(n===Date)return e.getTime()===t.getTime();if(n===RegExp)return e.toString()===t.toString();if(n===Array){if((r=e.length)===t.length)for(;r--&&we(e[r],t[r]););return r===-1}if(!n||typeof e=="object"){r=0;for(n in e)if(Ke.call(e,n)&&++r&&!Ke.call(t,n)||!(n in t)||!we(e[n],t[n]))return!1;return Object.keys(t).length===r}}return e!==e&&t!==t}const j=new WeakMap,q=()=>{},C=q(),ge=Object,d=e=>e===C,F=e=>typeof e=="function",B=(e,t)=>({...e,...t}),tt=e=>F(e.then),he={},ae={},be="undefined",ne=typeof window!=be,Te=typeof document!=be,vt=ne&&"Deno"in window,Rt=()=>ne&&typeof window.requestAnimationFrame!=be,nt=(e,t)=>{const n=j.get(e);return[()=>!d(t)&&e.get(t)||he,r=>{if(!d(t)){const s=e.get(t);t in ae||(ae[t]=s),n[5](t,B(s,r),s||he)}},n[6],()=>!d(t)&&t in ae?ae[t]:!d(t)&&e.get(t)||he]};let ye=!0;const wt=()=>ye,[Ae,De]=ne&&window.addEventListener?[window.addEventListener.bind(window),window.removeEventListener.bind(window)]:[q,q],gt=()=>{const e=Te&&document.visibilityState;return d(e)||e!=="hidden"},Tt=e=>(Te&&document.addEventListener("visibilitychange",e),Ae("focus",e),()=>{Te&&document.removeEventListener("visibilitychange",e),De("focus",e)}),yt=e=>{const t=()=>{ye=!0,e()},n=()=>{ye=!1};return Ae("online",t),Ae("offline",n),()=>{De("online",t),De("offline",n)}},At={isOnline:wt,isVisible:gt},Dt={initFocus:Tt,initReconnect:yt},Je=!m.useId,ee=!ne||vt,Ct=e=>Rt()?window.requestAnimationFrame(e):setTimeout(e,1),Se=ee?m.useEffect:m.useLayoutEffect,_e=typeof navigator<"u"&&navigator.connection,Ye=!ee&&_e&&(["slow-2g","2g"].includes(_e.effectiveType)||_e.saveData),ce=new WeakMap,It=e=>ge.prototype.toString.call(e),Oe=(e,t)=>e===`[object ${t}]`;let bt=0;const Ce=e=>{const t=typeof e,n=It(e),r=Oe(n,"Date"),s=Oe(n,"RegExp"),c=Oe(n,"Object");let o,u;if(ge(e)===e&&!r&&!s){if(o=ce.get(e),o)return o;if(o=++bt+"~",ce.set(e,o),Array.isArray(e)){for(o="@",u=0;u<e.length;u++)o+=Ce(e[u])+",";ce.set(e,o)}if(c){o="#";const h=ge.keys(e).sort();for(;!d(u=h.pop());)d(e[u])||(o+=u+":"+Ce(e[u])+",");ce.set(e,o)}}else o=r?e.toJSON():t=="symbol"?e.toString():t=="string"?JSON.stringify(e):""+e;return o},Le=e=>{if(F(e))try{e=e()}catch{e=""}const t=e;return e=typeof e=="string"?e:(Array.isArray(e)?e.length:e)?Ce(e):"",[e,t]};let Lt=0;const Ie=()=>++Lt;async function rt(...e){const[t,n,r,s]=e,c=B({populateCache:!0,throwOnError:!0},typeof s=="boolean"?{revalidate:s}:s||{});let o=c.populateCache;const u=c.rollbackOnError;let h=c.optimisticData;const y=E=>typeof u=="function"?u(E):u!==!1,v=c.throwOnError;if(F(n)){const E=n,a=[],p=t.keys();for(const f of p)!/^\$(inf|sub)\$/.test(f)&&E(t.get(f)._k)&&a.push(f);return Promise.all(a.map(l))}return l(n);async function l(E){const[a]=Le(E);if(!a)return;const[p,f]=nt(t,a),[I,i,U,X]=j.get(t),G=()=>{const A=I[a];return(F(c.revalidate)?c.revalidate(p().data,E):c.revalidate!==!1)&&(delete U[a],delete X[a],A&&A[0])?A[0](et).then(()=>p().data):p().data};if(e.length<3)return G();let g=r,M,V=!1;const O=Ie();i[a]=[O,0];const $=!d(h),N=p(),H=N.data,re=N._c,W=d(re)?H:re;if($&&(h=F(h)?h(W,H):h,f({data:h,_c:W})),F(g))try{g=g(W)}catch(A){M=A,V=!0}if(g&&tt(g))if(g=await g.catch(A=>{M=A,V=!0}),O!==i[a][0]){if(V)throw M;return g}else V&&$&&y(M)&&(o=!0,f({data:W,_c:C}));if(o&&!V)if(F(o)){const A=o(g,W);f({data:A,error:C,_c:C})}else f({data:g,error:C,_c:C});if(i[a][1]=Ie(),Promise.resolve(G()).then(()=>{f({_c:C})}),V){if(v)throw M;return}return g}}const ze=(e,t)=>{for(const n in e)e[n][0]&&e[n][0](t)},Vt=(e,t)=>{if(!j.has(e)){const n=B(Dt,t),r=Object.create(null),s=rt.bind(C,e);let c=q;const o=Object.create(null),u=(v,l)=>{const E=o[v]||[];return o[v]=E,E.push(l),()=>E.splice(E.indexOf(l),1)},h=(v,l,E)=>{e.set(v,l);const a=o[v];if(a)for(const p of a)p(l,E)},y=()=>{if(!j.has(e)&&(j.set(e,[r,Object.create(null),Object.create(null),Object.create(null),s,h,u]),!ee)){const v=n.initFocus(setTimeout.bind(C,ze.bind(C,r,Qe))),l=n.initReconnect(setTimeout.bind(C,ze.bind(C,r,Ze)));c=()=>{v&&v(),l&&l(),j.delete(e)}}};return y(),[e,s,y,c]}return[e,j.get(e)[4]]},Nt=(e,t,n,r,s)=>{const c=n.errorRetryCount,o=s.retryCount,u=~~((Math.random()+.5)*(1<<(o<8?o:8)))*n.errorRetryInterval;!d(c)&&o>c||setTimeout(r,u,s)},Ft=we,[ot,Mt]=Vt(new Map),xt=B({onLoadingSlow:q,onSuccess:q,onError:q,onErrorRetry:Nt,onDiscarded:q,revalidateOnFocus:!0,revalidateOnReconnect:!0,revalidateIfStale:!0,shouldRetryOnError:!0,errorRetryInterval:Ye?1e4:5e3,focusThrottleInterval:5*1e3,dedupingInterval:2*1e3,loadingTimeout:Ye?5e3:3e3,compare:Ft,isPaused:()=>!1,cache:ot,mutate:Mt,fallback:{}},At),Pt=(e,t)=>{const n=B(e,t);if(t){const{use:r,fallback:s}=e,{use:c,fallback:o}=t;r&&c&&(n.use=r.concat(c)),s&&o&&(n.fallback=B(s,o))}return n},jt=m.createContext({}),Ut="$inf$",st=ne&&window.__SWR_DEVTOOLS_USE__,Gt=st?window.__SWR_DEVTOOLS_USE__:[],qt=()=>{st&&(window.__SWR_DEVTOOLS_REACT__=m)},Bt=e=>F(e[1])?[e[0],e[1],e[2]||{}]:[e[0],null,(e[1]===null?e[2]:e[1])||{}],Wt=()=>B(xt,m.useContext(jt)),kt=e=>(t,n,r)=>e(t,n&&((...c)=>{const[o]=Le(t),[,,,u]=j.get(ot);if(o.startsWith(Ut))return n(...c);const h=u[o];return d(h)?n(...c):(delete u[o],h)}),r),$t=Gt.concat(kt),Ht=e=>function(...n){const r=Wt(),[s,c,o]=Bt(n),u=Pt(r,o);let h=e;const{use:y}=u,v=(y||[]).concat($t);for(let l=v.length;l--;)h=v[l](h);return h(s,c||u.fetcher||null,u)},Kt=(e,t,n)=>{const r=t[e]||(t[e]=[]);return r.push(n),()=>{const s=r.indexOf(n);s>=0&&(r[s]=r[r.length-1],r.pop())}};qt();const ve=m.use||(e=>{switch(e.status){case"pending":throw e;case"fulfilled":return e.value;case"rejected":throw e.reason;default:throw e.status="pending",e.then(t=>{e.status="fulfilled",e.value=t},t=>{e.status="rejected",e.reason=t}),e}}),Re={dedupe:!0},Jt=(e,t,n)=>{const{cache:r,compare:s,suspense:c,fallbackData:o,revalidateOnMount:u,revalidateIfStale:h,refreshInterval:y,refreshWhenHidden:v,refreshWhenOffline:l,keepPreviousData:E}=n,[a,p,f,I]=j.get(r),[i,U]=Le(e),X=m.useRef(!1),G=m.useRef(!1),g=m.useRef(i),M=m.useRef(t),V=m.useRef(n),O=()=>V.current,$=()=>O().isVisible()&&O().isOnline(),[N,H,re,W]=nt(r,i),A=m.useRef({}).current,Q=d(o)?d(n.fallback)?C:n.fallback[i]:o,Fe=(_,S)=>{for(const T in A){const R=T;if(R==="data"){if(!s(_[R],S[R])&&(!d(_[R])||!s(se,S[R])))return!1}else if(S[R]!==_[R])return!1}return!0},Me=m.useMemo(()=>{const _=!i||!t?!1:d(u)?O().isPaused()||c?!1:h!==!1:u,S=D=>{const x=B(D);return delete x._k,_?{isValidating:!0,isLoading:!0,...x}:x},T=N(),R=W(),L=S(T),Y=T===R?L:S(R);let w=L;return[()=>{const D=S(N());return Fe(D,w)?(w.data=D.data,w.isLoading=D.isLoading,w.isValidating=D.isValidating,w.error=D.error,w):(w=D,D)},()=>Y]},[r,i]),K=Ot.useSyncExternalStore(m.useCallback(_=>re(i,(S,T)=>{Fe(T,S)||_()}),[r,i]),Me[0],Me[1]),xe=!X.current,lt=a[i]&&a[i].length>0,J=K.data,k=d(J)?Q&&tt(Q)?ve(Q):Q:J,oe=K.error,fe=m.useRef(k),se=E?d(J)?d(fe.current)?k:fe.current:J:k,Pe=lt&&!d(oe)?!1:xe&&!d(u)?u:O().isPaused()?!1:c?d(k)?!1:h:d(k)||h,je=!!(i&&t&&xe&&Pe),ft=d(K.isValidating)?je:K.isValidating,dt=d(K.isLoading)?je:K.isLoading,Z=m.useCallback(async _=>{const S=M.current;if(!i||!S||G.current||O().isPaused())return!1;let T,R,L=!0;const Y=_||{},w=!f[i]||!Y.dedupe,D=()=>Je?!G.current&&i===g.current&&X.current:i===g.current,x={isValidating:!1,isLoading:!1},Ge=()=>{H(x)},qe=()=>{const b=f[i];b&&b[1]===R&&delete f[i]},Be={isValidating:!0};d(N().data)&&(Be.isLoading=!0);try{if(w&&(H(Be),n.loadingTimeout&&d(N().data)&&setTimeout(()=>{L&&D()&&O().onLoadingSlow(i,n)},n.loadingTimeout),f[i]=[S(U),Ie()]),[T,R]=f[i],T=await T,w&&setTimeout(qe,n.dedupingInterval),!f[i]||f[i][1]!==R)return w&&D()&&O().onDiscarded(i),!1;x.error=C;const b=p[i];if(!d(b)&&(R<=b[0]||R<=b[1]||b[1]===0))return Ge(),w&&D()&&O().onDiscarded(i),!1;const P=N().data;x.data=s(P,T)?P:T,w&&D()&&O().onSuccess(T,i,n)}catch(b){qe();const P=O(),{shouldRetryOnError:de}=P;P.isPaused()||(x.error=b,w&&D()&&(P.onError(b,i,P),(de===!0||F(de)&&de(b))&&(!O().revalidateOnFocus||!O().revalidateOnReconnect||$())&&P.onErrorRetry(b,i,P,Et=>{const Ee=a[i];Ee&&Ee[0]&&Ee[0](He,Et)},{retryCount:(Y.retryCount||0)+1,dedupe:!0})))}return L=!1,Ge(),!0},[i,r]),Ue=m.useCallback((..._)=>rt(r,g.current,..._),[]);if(Se(()=>{M.current=t,V.current=n,d(J)||(fe.current=J)}),Se(()=>{if(!i)return;const _=Z.bind(C,Re);let S=0;O().revalidateOnFocus&&(S=Date.now()+O().focusThrottleInterval);const R=Kt(i,a,(L,Y={})=>{if(L==Qe){const w=Date.now();O().revalidateOnFocus&&w>S&&$()&&(S=w+O().focusThrottleInterval,_())}else if(L==Ze)O().revalidateOnReconnect&&$()&&_();else{if(L==et)return Z();if(L==He)return Z(Y)}});return G.current=!1,g.current=i,X.current=!0,H({_k:U}),Pe&&(f[i]||(d(k)||ee?_():Ct(_))),()=>{G.current=!0,R()}},[i]),Se(()=>{let _;function S(){const R=F(y)?y(N().data):y;R&&_!==-1&&(_=setTimeout(T,R))}function T(){!N().error&&(v||O().isVisible())&&(l||O().isOnline())?Z(Re).then(S):S()}return S(),()=>{_&&(clearTimeout(_),_=-1)}},[y,v,l,i]),m.useDebugValue(se),c&&d(k)&&i){if(!Je&&ee)throw new Error("Fallback data is required when using Suspense in SSR.");M.current=t,V.current=n,G.current=!1;const _=I[i];if(!d(_)){const S=Ue(_);ve(S)}if(d(oe)){const S=Z(Re);d(se)||(S.status="fulfilled",S.value=!0),ve(S)}else throw oe}return{mutate:Ue,get data(){return A.data=!0,se},get error(){return A.error=!0,oe},get isValidating(){return A.isValidating=!0,ft},get isLoading(){return A.isLoading=!0,dt}}},Yt=Ht(Jt),Ve="https://api.figma.com",zt=`${Ve}/v1/files`,it=`${Ve}/v1/variables`,at=it,ct=e=>`${it}/${e}`,Xt=e=>`${zt}/${e}/variables/local`,Qt="application/json",ut="X-FIGMA-TOKEN",z="A Figma API token is required.",Zt="An error occurred while fetching data from the Figma API.";async function en(e,t){if(!t)throw new Error(z);const n=await fetch(e,{method:"GET",headers:{[ut]:t,"Content-Type":Qt}});if(!n.ok){let r=Zt;try{const s=await n.json();s!=null&&s.message&&(r=s.message)}catch{}throw new Error(r)}return n.json()}const Ne=()=>{const{token:e,fileKey:t}=te(),n=t?Xt(t):null,{data:r,error:s,isLoading:c,isValidating:o,mutate:u}=Yt(e&&n?[n,e]:null,en);return{data:r,isLoading:c,isValidating:o,error:s,mutate:u}},tn=()=>{const{data:e}=Ne(),t=m.useMemo(()=>e!=null&&e.meta?Object.values(e.meta.variableCollections):[],[e]),n=m.useMemo(()=>e!=null&&e.meta?e.meta.variableCollections:{},[e]);return{collections:t,collectionsById:n}},nn=()=>{const{data:e}=Ne();return m.useMemo(()=>{const t=[],n={},r={};if(e!=null&&e.meta)for(const s of Object.values(e.meta.variableCollections)){t.push(...s.modes),n[s.id]=s.modes;for(const c of s.modes)r[c.modeId]=c}return{modes:t,modesByCollectionId:n,modesById:r}},[e])};function rn(e,t){switch(t.type){case"loading":return{...e,status:"loading",error:null};case"success":return{...e,status:"success",data:t.payload};case"error":return{...e,status:"error",error:t.payload};default:return e}}const ue=e=>{const t={status:"idle",data:null,error:null},[n,r]=m.useReducer(rn,t);return{mutate:m.useCallback(async c=>{r({type:"loading"});try{const o=await e(c);return r({type:"success",payload:o}),o}catch(o){r({type:"error",payload:o});return}},[e]),...n,isLoading:n.status==="loading",isSuccess:n.status==="success",isError:n.status==="error"}};async function le(e,t,n,r){if(!t)throw new Error(z);const c={CREATE:"POST",UPDATE:"PUT",DELETE:"DELETE"}[n],o=await fetch(`${Ve}${e}`,{method:c,headers:{"Content-Type":"application/json",[ut]:t},body:r?JSON.stringify(r):void 0});if(!o.ok){const u=await o.json().catch(()=>({}));throw new Error(u.err||u.message||"An API error occurred")}return o.status===204||!o.body?{}:o.json()}const on=()=>{const{token:e}=te();return ue(async n=>{if(!e)throw new Error(z);return await le(at,e,"CREATE",n)})},sn=()=>{const{token:e}=te();return ue(async({variableId:n,payload:r})=>{if(!e)throw new Error(z);const s=ct(n);return await le(s,e,"UPDATE",r)})},an=()=>{const{token:e}=te();return ue(async n=>{if(!e)throw new Error(z);return await le(ct(n),e,"DELETE",void 0)})},cn=()=>{const{token:e}=te();return ue(async n=>{if(!e)throw new Error(z);return await le(at,e,"CREATE",n)})};function un(e,t){return e.filter(n=>{let r=!0;return t.resolvedType&&(r=r&&n.resolvedType===t.resolvedType),t.name&&(r=r&&n.name.includes(t.name)),r})}exports.FigmaVarsProvider=mt;exports.filterVariables=un;exports.useBulkUpdateVariables=cn;exports.useCreateVariable=on;exports.useDeleteVariable=an;exports.useUpdateVariable=sn;exports.useVariableCollections=tn;exports.useVariableModes=nn;exports.useVariables=Ne;