UNPKG

signalforge

Version:

Fine-grained reactive state management with automatic dependency tracking - Ultra-optimized, zero dependencies

2 lines (1 loc) 12.7 kB
var L=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,r)=>(typeof require<"u"?require:e)[r]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});var E=[],b=new Map,ce=0,M=!0;function de(){return`signal_${++ce}_${Date.now()}`}function H(t,e,r){let n={id:de(),type:t,createdAt:Date.now(),label:r};if(b.set(n.id,n),M){for(let i of E)if(i.onSignalCreate)try{i.onSignalCreate(n,e)}catch(o){console.error(`Error in plugin "${i.name}" onSignalCreate:`,o)}}return n}function q(t,e,r,n="set"){if(!M)return;let i=b.get(t);if(!i)return;let o={signal:i,oldValue:e,newValue:r,timestamp:Date.now(),source:n};for(let s of E)if(s.onSignalUpdate)try{s.onSignalUpdate(o)}catch(u){console.error(`Error in plugin "${s.name}" onSignalUpdate:`,u)}}function W(t){if(!M)return;let e=b.get(t);if(e){for(let r of E)if(r.onSignalDestroy)try{r.onSignalDestroy(e)}catch(n){console.error(`Error in plugin "${r.name}" onSignalDestroy:`,n)}b.delete(t)}}var d=1,$=2,R=4,C=8,J=16,G=1e4,Z=new Array(G),T=0;function ge(t){T<G&&(t.value=void 0,t.subscribers=null,t.listeners=null,t.dependencies=null,t.computeFn=null,t.flags=0,Z[T++]=t)}var h=new WeakMap,j=new Map;var K=1e4,Q=new Array(K),y=0,S=0,D=!1;function fe(t){if(t.flags&$)return;let e=(S+1)%K;e===y&&(console.error("[SignalForge] Batch queue overflow \u2192 forcing flush"),I()),t.flags|=$,Q[S]=t,S=e,D||(D=!0,queueMicrotask(I))}function I(){for(D=!1;y!==S;){let t=Q[y];y=(y+1)%K,t.flags&=~$,t.flags&d&&v(t)}}var Y=new Array(100),X=0,l=null;function pe(t){Y[X++]=l,l=t}function ye(){l=Y[--X]}var me=function(){return this._node.value},Se=function(t){this._node.subscribers||(this._node.subscribers=new Set),this._node.subscribers.add(t)},ve=function(t){this._node.subscribers&&this._node.subscribers.delete(t)};function z(t,e=null){let r=T>0?Z[--T]:{value:void 0,subscribers:null,listeners:null,dependencies:null,computeFn:null,flags:0};return r.value=t,r.computeFn=e,r.flags=e?J|d:0,e&&v(r),r}function ee(t,e){return l?(l!==t&&(te(t,l),Te(l,e)),t.flags&d&&t.computeFn&&v(t),t.value):(t.flags&d&&t.computeFn&&v(t),t.value)}function be(t,e,r){if(t.flags&J)throw new Error("Cannot set computed signal");if(typeof r=="function"&&(r=r(t.value)),Object.is(r,t.value))return;let n=t.value;t.value=r;let i=h.get(e);i&&q(i,n,r,"set"),ne(t)}function te(t,e){t.subscribers||(t.subscribers=new Set),t.subscribers.add(e)}function he(t,e){t.subscribers&&t.subscribers.delete(e)}function Te(t,e){t.dependencies||(t.dependencies=new Set),t.dependencies.has(e)||(t.dependencies.add(e),te(e._node,t))}function re(t){if(t.dependencies){for(let e of t.dependencies)he(e._node,t);t.dependencies.clear()}}function O(t){if(!(t.flags&d)&&(t.flags|=d,fe(t),t.subscribers))for(let e of t.subscribers)O(e)}function v(t){if(t.computeFn&&!(t.flags&R)){t.flags|=R,re(t),pe(t);try{let e=t.computeFn();t.flags&=~d,t.flags&=~R,Object.is(e,t.value)||(t.value=e,ne(t))}finally{ye()}}}function ne(t){if(t.subscribers)for(let e of t.subscribers)O(e);if(t.flags&C&&t.listeners)for(let e of t.listeners)e(t.value)}function ie(t,e){return t.listeners||(t.listeners=new Set),t.listeners.add(e),t.flags|=C,()=>{t.listeners.delete(e),t.listeners.size===0&&(t.flags&=~C)}}function F(t){re(t),t.subscribers&&t.subscribers.clear(),t.listeners&&t.listeners.clear(),ge(t)}function c(t){let e=z(t,null),r={get:()=>ee(e,r),set:i=>be(e,r,i),subscribe:i=>ie(e,i),destroy:()=>{let i=h.get(r);i&&(W(i),j.delete(i),h.delete(r)),F(e)},_node:e,_peek:me,_addSubscriber:Se,_removeSubscriber:ve},n=H("signal",t);return h.set(r,n.id),j.set(n.id,r),r}function g(t){let e,r=l;l=null;try{e=t()}finally{l=r}let n=z(e,t),i={get:()=>ee(n,i),set:()=>{throw new Error("Cannot set a computed signal")},subscribe:o=>ie(n,o),destroy:()=>F(n),_node:n,_peek:()=>n.value,_addSubscriber:o=>{n.subscribers||(n.subscribers=new Set),n.subscribers.add(o)},_removeSubscriber:o=>{n.subscribers&&n.subscribers.delete(o)},_markDirty:()=>O(n),_recompute:()=>v(n)};return i}function m(t){let e=z(void 0,t);return()=>F(e)}function _e(t){let e=t();return ae(),e}function ae(){y!==S&&I()}function xe(t){let e=l;l=null;try{return t()}finally{l=e}}var we=ae;function A(){let t=typeof global<"u"?global:void 0,e=typeof window<"u"?window:void 0;return typeof navigator<"u"&&navigator.product==="ReactNative"||e?.navigator?.product==="ReactNative"||t?.HermesInternal||t?.__fbBatchedBridgeConfig||t?.nativeModuleProxy||t?.__turboModuleProxy?"react-native":e?.localStorage||t?.localStorage?"web":"node"}function P(t,e=!1){let r=new WeakSet;try{return JSON.stringify(t,(n,i)=>{if(i===void 0)return"__undefined__";if(i===null)return null;if(typeof i=="function")return e&&`${n}`,"__function__";if(i instanceof Date)return{__type__:"Date",value:i.toISOString()};if(i instanceof RegExp)return{__type__:"RegExp",value:i.toString()};if(typeof i=="object"&&i!==null){if(r.has(i))return e&&`${n}`,"__circular__";r.add(i)}return i})}catch(n){e&&console.error("[StorageAdapter] Serialization error:",n);try{return JSON.stringify(t)}catch{return"{}"}}}function U(t,e=!1){try{return JSON.parse(t,(r,n)=>{if(n!=="__undefined__"&&n!=="__function__"){if(n==="__circular__")return null;if(n&&typeof n=="object"){if(n.__type__==="Date")return new Date(n.value);if(n.__type__==="RegExp"){let i=n.value.match(/^\/(.+)\/([gimuy]*)$/);if(i)return new RegExp(i[1],i[2])}}return n}})}catch(r){return e&&console.error("[StorageAdapter] Deserialization error:",r),null}}var _=class{constructor(e={}){this.prefix=e.prefix||"signalforge_",this.devMode=e.devMode??N,this.serialize=e.serialize||(r=>P(r,this.devMode)),this.deserialize=e.deserialize||(r=>U(r,this.devMode))}getKey(e){return`${this.prefix}${e}`}async load(e){try{let r=localStorage.getItem(this.getKey(e));return r===null?null:this.deserialize(r)}catch(r){return this.devMode&&console.error(`[StorageAdapter] Failed to load "${e}":`,r),null}}async save(e,r){try{let n=this.serialize(r);localStorage.setItem(this.getKey(e),n)}catch(n){throw this.devMode&&console.error(`[StorageAdapter] Failed to save "${e}":`,n),n}}async clear(e){try{localStorage.removeItem(this.getKey(e))}catch(r){throw this.devMode&&console.error(`[StorageAdapter] Failed to clear "${e}":`,r),r}}isAvailable(){try{let e="__storage_test__";return localStorage.setItem(e,e),localStorage.removeItem(e),!0}catch{return!1}}async getAllKeys(){try{let e=[];for(let r=0;r<localStorage.length;r++){let n=localStorage.key(r);n&&n.startsWith(this.prefix)&&e.push(n.slice(this.prefix.length))}return e}catch(e){return this.devMode&&console.error("[StorageAdapter] Failed to get all keys:",e),[]}}async clearAll(){try{let e=await this.getAllKeys();for(let r of e)await this.clear(r)}catch(e){throw this.devMode&&console.error("[StorageAdapter] Failed to clear all:",e),e}}},x=class{constructor(e={}){this.prefix=e.prefix||"signalforge_",this.devMode=e.devMode??N,this.serialize=e.serialize||(r=>P(r,this.devMode)),this.deserialize=e.deserialize||(r=>U(r,this.devMode));try{this.AsyncStorage=L("@react-native-async-storage/async-storage").default}catch{try{this.AsyncStorage=L("react-native").AsyncStorage}catch{this.devMode&&console.error("[StorageAdapter] AsyncStorage not found. Install @react-native-async-storage/async-storage"),this.AsyncStorage=null}}}getKey(e){return`${this.prefix}${e}`}async load(e){if(!this.AsyncStorage)return this.devMode,null;try{let r=await this.AsyncStorage.getItem(this.getKey(e));return r===null?null:this.deserialize(r)}catch(r){return this.devMode&&console.error(`[StorageAdapter] Failed to load "${e}":`,r),null}}async save(e,r){if(!this.AsyncStorage){this.devMode;return}try{let n=this.serialize(r);await this.AsyncStorage.setItem(this.getKey(e),n)}catch(n){throw this.devMode&&console.error(`[StorageAdapter] Failed to save "${e}":`,n),n}}async clear(e){if(!this.AsyncStorage){this.devMode;return}try{await this.AsyncStorage.removeItem(this.getKey(e))}catch(r){throw this.devMode&&console.error(`[StorageAdapter] Failed to clear "${e}":`,r),r}}isAvailable(){return this.AsyncStorage!==null}async getAllKeys(){if(!this.AsyncStorage)return[];try{return(await this.AsyncStorage.getAllKeys()).filter(r=>r.startsWith(this.prefix)).map(r=>r.slice(this.prefix.length))}catch(e){return this.devMode&&console.error("[StorageAdapter] Failed to get all keys:",e),[]}}async clearAll(){if(this.AsyncStorage)try{let r=(await this.getAllKeys()).map(n=>this.getKey(n));await this.AsyncStorage.multiRemove(r)}catch(e){throw this.devMode&&console.error("[StorageAdapter] Failed to clear all:",e),e}}},w=class{constructor(e={}){this.storage=new Map;this.prefix=e.prefix||"signalforge_",this.devMode=e.devMode??N,this.devMode}getKey(e){return`${this.prefix}${e}`}async load(e){let r=this.storage.get(this.getKey(e));return r!==void 0?r:null}async save(e,r){let n=JSON.parse(JSON.stringify(r));this.storage.set(this.getKey(e),n)}async clear(e){this.storage.delete(this.getKey(e))}isAvailable(){return!0}async getAllKeys(){let e=[];for(let r of this.storage.keys())r.startsWith(this.prefix)&&e.push(r.slice(this.prefix.length));return e}async clearAll(){let e=await this.getAllKeys();for(let r of e)this.storage.delete(this.getKey(r))}},f=null;function V(t={}){if(f)return f;switch(A()){case"web":f=new _(t);break;case"react-native":f=new x(t);break;case"node":case"unknown":default:f=new w(t);break}return f}function oe(){f=null}function se(t=A(),e={}){switch(t){case"web":return new _(e);case"react-native":return new x(e);case"node":case"unknown":default:return new w(e)}}function B(t,e={}){let r=e.adapter||V(),n=e.key||`signal_${Math.random().toString(36).slice(2)}`,i=e.serialize||(a=>a),o=e.deserialize||(a=>a);r.load(n).then(a=>{if(a!==null)try{let p=o(a);t.set(p)}catch(p){e.onError&&e.onError(p)}}).catch(a=>{e.onError&&e.onError(a)});let s,u=m(()=>{let a=t.get(),p=()=>{try{let k=i(a);r.save(n,k).catch(ue=>{e.onError&&e.onError(ue)})}catch(k){e.onError&&e.onError(k)}};e.debounce?(s!==void 0&&clearTimeout(s),s=setTimeout(p,e.debounce)):p()});return()=>{u(),s!==void 0&&clearTimeout(s)}}function le(t,e,r={}){let n=c(e);return B(n,{...r,key:t}),n}var N=typeof globalThis.__DEV__<"u"?globalThis.__DEV__:process.env.NODE_ENV!=="production";function Ae(t,e){return g(()=>{let r=t.map(n=>n.get());return e(...r)})}function Pe(t){return g(()=>t.map(e=>e.get()))}function Ue(t,e){return g(()=>e(t.get()))}function ke(t,e,r){return g(()=>{let n=t.get();return e(n)?n:r})}function Ee(t,e=Object.is){let r=t._peek?t._peek():t.get();return g(()=>{let n=t.get();return e(n,r)||(r=n),r})}function Me(t){let e=c({status:"pending",data:void 0,error:void 0});return t().then(r=>{e.set({status:"success",data:r,error:void 0})}).catch(r=>{e.set({status:"error",data:void 0,error:r})}),e}function Re(t,e){let r=c(t._peek?t._peek():t.get()),n;return m(()=>{let i=t.get();n!==void 0&&clearTimeout(n),n=setTimeout(()=>{r.set(i)},e)}),r}function $e(t,e){let r=c(t._peek?t._peek():t.get()),n=0,i,o;return m(()=>{let s=t.get(),u=Date.now(),a=u-n;a>=e?(r.set(s),n=u,i=void 0):(i=s,o===void 0&&(o=setTimeout(()=>{i!==void 0&&(r.set(i),n=Date.now(),i=void 0),o=void 0},e-a)))}),r}function Ce(t=[]){let e=c(t);return{...e,push(...r){e.set(n=>[...n,...r])},pop(){let r;return e.set(n=>{let i=[...n];return r=i.pop(),i}),r},filter(r){e.set(n=>n.filter(r))},map(r){return e.get().map(r)},find(r){return e.get().find(r)},remove(r){e.set(n=>n.filter(i=>i!==r))},clear(){e.set([])},get length(){return e.get().length}}}function De(t={}){let e=c(t);return{...e,setKey(r,n){e.set(i=>({...i,[r]:n}))},deleteKey(r){e.set(n=>{let i={...n};return delete i[r],i})},hasKey(r){return r in e.get()},getKey(r){return e.get()[r]},keys(){return Object.keys(e.get())},values(){return Object.values(e.get())},entries(){return Object.entries(e.get())},clear(){e.set({})}}}function Ie(t,e){let r=0,n=0,i=0,o=0;return{get(){let s=performance.now(),u=t.get(),a=performance.now()-s;return r++,i+=a,r%100===0&&`${e}${r}${(i/r).toFixed(3)}`,u},set(s){let u=performance.now();t.set(s);let a=performance.now()-u;n++,o+=a,`${e}${n}${a.toFixed(3)}`},subscribe:t.subscribe.bind(t),destroy:t.destroy.bind(t),_node:t._node,_addSubscriber:t._addSubscriber?t._addSubscriber.bind(t):void 0,_removeSubscriber:t._removeSubscriber?t._removeSubscriber.bind(t):void 0,_peek:t._peek?t._peek.bind(t):void 0}}export{_e as batch,Pe as combine,Ce as createArraySignal,g as createComputed,m as createEffect,le as createPersistentSignal,De as createRecordSignal,Me as createResource,c as createSignal,se as createStorageAdapter,Re as debounce,Ae as derive,A as detectEnvironment,ke as filter,we as flushSync,V as getStorageAdapter,Ue as map,Ee as memo,Ie as monitor,B as persist,oe as resetStorageAdapter,U as safeParse,P as safeStringify,$e as throttle,xe as untrack};