@avatijs/signal
Version:
Signal package part of Avati project
7 lines • 12.3 kB
JavaScript
/*!
* @avatijs/signal 0.3.1
* Copyright (c) 2024 Khaled Sameer <khaled.smq@hotmail.com>
* Licensed under MIT, https://opensource.org/licenses/MIT/
* Please visit https://avati.io/ for details.
*/(()=>{"use strict";var e={d:(t,i)=>{for(var s in i)e.o(i,s)&&!e.o(t,s)&&Object.defineProperty(t,s,{enumerable:!0,get:i[s]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"t",{value:!0})}},t={};e.r(t),e.d(t,{LocalStorageProvider:()=>p,MemoryStorageProvider:()=>g,SessionStorageProvider:()=>m,persisted:()=>O,withHistory:()=>y});class i extends Error{constructor(e){super(`Cannot ${e} a disposed signal`),this.name="SignalDisposedError"}}class s extends Error{constructor(e){super("Circular dependency detected"+(e?` in signal "${e}"`:"")),this.name="CircularDependencyError"}}class n{constructor(){Object.defineProperty(this,"computationStack",{enumerable:!0,configurable:!0,writable:!0,value:[]}),Object.defineProperty(this,"batchDepth",{enumerable:!0,configurable:!0,writable:!0,value:0}),Object.defineProperty(this,"batchQueue",{enumerable:!0,configurable:!0,writable:!0,value:new Set}),Object.defineProperty(this,"activeEffects",{enumerable:!0,configurable:!0,writable:!0,value:new Set})}static getInstance(){return this.instance||(this.instance=new n),this.instance}getCurrentComputation(){return this.computationStack[this.computationStack.length-1]}pushComputation(e){e&&this.computationStack.includes(e)||this.computationStack.push(e)}popComputation(){this.computationStack.pop()}isBatching(){return this.batchDepth>0}beginBatch(){this.batchDepth++}endBatch(){this.batchDepth--,0===this.batchDepth&&this.flushBatchQueue()}addToBatchQueue(e){this.batchQueue.add(e)}flushBatchQueue(){const e=new Set(this.batchQueue);this.batchQueue.clear();const t=new Set;for(const i of e)for(const e of i.getDependents())t.add(e);for(const e of t)e.markDirty()}setCurrentComputation(e){this.computationStack[this.computationStack.length-1]=e}registerEffect(e){this.activeEffects.add(e)}unregisterEffect(e){this.activeEffects.delete(e)}isInEffect(){return this.activeEffects.size>0}}class r{constructor(e,t={}){Object.defineProperty(this,"equals",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"name",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"dependents",{enumerable:!0,configurable:!0,writable:!0,value:new Set}),Object.defineProperty(this,"disposed",{enumerable:!0,configurable:!0,writable:!0,value:!1}),Object.defineProperty(this,"i",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.i=e,this.equals=t.equals??Object.is,this.name=t.name||"anonymous"}isCommutable(){throw Error("Method not implemented.")}get value(){if(this.disposed)throw new i("read from");return this.trackDependency(),this.i}set value(e){if(this.disposed)throw new i("write to");this.equals(this.i,e)||(this.i=e,this.notifyDependents())}get_value_bypass_tracking(){if(this.disposed)throw new i("read from");return this.i}update(e){this.value=e(this.i)}addDependent(e){this.dependents.add(e)}removeDependent(e){this.dependents.delete(e)}notifyDependents(){const e=n.getInstance();if(e.isBatching())e.addToBatchQueue(this);else for(const e of this.dependents)e.markDirty()}dispose(){if(this.disposed)return;this.disposed=!0;const e=new Set(this.dependents);this.dependents.clear();for(const t of e)"ComputedSignal"==t.constructor.name||"ComputedSignal"==t.signal?.constructor.name?("ComputedSignal"==t.constructor.name?t:t.signal).dispose():t.dispose()}isDisposed(){return this.disposed}getDependents(){return this.dependents||new Set}hasDependents(){return this.dependents.size>0}toString(){return`Signal(${this.name})`}trackDependency(){const e=n.getInstance().getCurrentComputation();e&&(e.addDependency(this),this.addDependent(e))}}class o{constructor(){Object.defineProperty(this,"queue",{enumerable:!0,configurable:!0,writable:!0,value:new Set}),Object.defineProperty(this,"processing",{enumerable:!0,configurable:!0,writable:!0,value:!1}),Object.defineProperty(this,"updateDepth",{enumerable:!0,configurable:!0,writable:!0,value:0}),Object.defineProperty(this,"maxUpdateDepth",{enumerable:!0,configurable:!0,writable:!0,value:1e3})}static getInstance(){return this.instance||(this.instance=new o),this.instance}schedule(e){if(this.updateDepth>=this.maxUpdateDepth)throw Error("Maximum update depth exceeded - possible circular dependency");this.queue.add(e),this.processing||this.processQueue()}processQueue(){this.processing=!0,this.updateDepth++;try{for(;this.queue.size>0;){const e=Array.from(this.queue);this.queue.clear(),e.sort(((e,t)=>e.getDepth()-t.getDepth()));for(const t of e)t.isDirty()&&!t.isDisposed()&&t.recompute()}}finally{this.processing=!1,this.updateDepth--}}}class a{constructor(e){Object.defineProperty(this,"dirty",{enumerable:!0,configurable:!0,writable:!0,value:!0}),Object.defineProperty(this,"disposed",{enumerable:!0,configurable:!0,writable:!0,value:!1}),Object.defineProperty(this,"dependencies",{enumerable:!0,configurable:!0,writable:!0,value:new Set}),Object.defineProperty(this,"dependents",{enumerable:!0,configurable:!0,writable:!0,value:new Set}),Object.defineProperty(this,"depth",{enumerable:!0,configurable:!0,writable:!0,value:0}),Object.defineProperty(this,"name",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.name=e}addDependency(e){this.dependencies.has(e)||(this.dependencies.add(e),"ComputedSignal"==e.constructor.name&&this.updateDepth())}removeDependency(e){this.dependencies.delete(e)&&this.updateDepth()}dispose(){this.disposed||(this.disposed=!0,this.clearDependencies(),this.dependents.clear())}isDirty(){return this.dirty}isDisposed(){return this.disposed}getDepth(){return this.depth}markDirty(){this.disposed||(this.dirty=!0,o.getInstance().schedule(this))}hasSignal(e){return this.dependencies.has(e)}clearDependencies(){for(const e of this.dependencies)e.removeDependent(this);this.dependencies.clear(),this.updateDepth()}updateDepth(){const e=this.depth;let t=0;for(const e of this.dependencies)"ComputedSignal"==e.constructor.name&&(t=Math.max(t,e.getDepth()+1));if(e!==t){this.depth=t;for(const e of this.dependents)e.updateDepth()}}}class h extends a{constructor(e){super("subscription"),Object.defineProperty(this,"callback",{enumerable:!0,configurable:!0,writable:!0,value:e})}recompute(){if(this.disposed)return;const e=n.getInstance(),t=e.getCurrentComputation();e.setCurrentComputation(this);try{this.callback()}finally{t&&e.setCurrentComputation(t),this.dirty=!1}}}class u extends r{constructor(e,t={}){super(e,t)}subscribe(e,t={skipInitial:!1}){if(this.disposed)throw new i("subscribe to");let s=!1;const n=new h((()=>{if(!t.skipInitial||s)return e(this.value);s=!0}));return n.recompute(),()=>n.dispose()}}class c{constructor(e,t){Object.defineProperty(this,"computation",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"cleanup",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"disposed",{enumerable:!0,configurable:!0,writable:!0,value:!1}),this.computation=new class extends a{constructor(e,i){super(t),Object.defineProperty(this,"effect",{enumerable:!0,configurable:!0,writable:!0,value:e}),Object.defineProperty(this,"fn",{enumerable:!0,configurable:!0,writable:!0,value:i})}recompute(){if(this.disposed)return;const e=n.getInstance();e.pushComputation(this);try{e.pushComputation(this),e.registerEffect(this.effect),this.effect.runEffect()}finally{e.unregisterEffect(this.effect),e.popComputation(),this.dirty=!1}}}(this,e),this.computation.recompute()}dispose(){if(!this.disposed){if(this.disposed=!0,this.cleanup)try{this.cleanup()}catch(e){}this.computation.dispose()}}runEffect(){if(!this.disposed){if(this.cleanup)try{this.cleanup()}catch(e){}try{this.cleanup=this.computation.fn()}catch(e){throw e}}}}class l extends u{constructor(e,t={}){super({},t),Object.defineProperty(this,"computation",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"computeFn",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.computeFn=e,this.computation=new class extends a{constructor(e){super(),Object.defineProperty(this,"signal",{enumerable:!0,configurable:!0,writable:!0,value:e})}recompute(){if(this.disposed)return;const e=n.getInstance(),t=e.getCurrentComputation();if(e.setCurrentComputation(this),e.isInEffect())throw new s("Cannot create computed signal that depends on effects");try{for(const e of this.dependencies)if(e.isDisposed())throw this.signal.dispose(),new i("read from disposed dependency");const e=this.signal.computeFn();this.signal.equals(this.signal.i,e)||(this.signal.i=e,this.signal.notifyDependents())}catch(e){throw e instanceof i&&this.signal.dispose(),e}finally{t&&e.setCurrentComputation(t),this.dirty=!1}}}(this),this.computation.recompute()}get value(){if(this.disposed)throw new i("read from");const e=this.computation.dependencies;for(const t of e)if(t.isDisposed())throw this.dispose(),new i("read from disposed dependency");return this.computation.isDirty()&&this.computation.recompute(),this.trackDependency(),this.i}set value(e){throw Error("Cannot set the value of a computed signal")}getDepth(){return this.computation.getDepth()}dispose(){if(!this.disposed){super.dispose(),this.computation.dispose();for(const e of this.dependents)(e instanceof l||e.signal instanceof l)&&(e instanceof l?e:e.signal).dispose()}}}function b(e,t){return new u(e,t)}function d(e,t){return new l(e,t)}function f(e){const t=n.getInstance();t.beginBatch();try{return e()}finally{t.endBatch()}}const w=(e,t)=>Object.is(e,t);class p{getItem(e){if("undefined"==typeof window)return null;const t=window.localStorage.getItem(e);return t?JSON.parse(t):null}setItem(e,t){"undefined"!=typeof window&&window.localStorage.setItem(e,JSON.stringify(t))}removeItem(e){"undefined"!=typeof window&&window.localStorage.removeItem(e)}}class m{getItem(e){if("undefined"==typeof window)return null;const t=window.sessionStorage.getItem(e);return t?JSON.parse(t):null}setItem(e,t){"undefined"!=typeof window&&window.sessionStorage.setItem(e,JSON.stringify(t))}removeItem(e){"undefined"!=typeof window&&window.sessionStorage.removeItem(e)}}class g{constructor(){Object.defineProperty(this,"store",{enumerable:!0,configurable:!0,writable:!0,value:new Map})}getItem(e){return this.store.get(e)??null}setItem(e,t){this.store.set(e,t)}removeItem(e){this.store.delete(e)}}class v extends u{constructor(e,t,i,s){super(i.getItem(e)??t,s),Object.defineProperty(this,"disposed",{enumerable:!0,configurable:!0,writable:!0,value:!1}),Object.defineProperty(this,"storage",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"key",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.key=e,this.storage=i,new c((()=>{this.disposed||this.storage.setItem(this.key,this.value)}),"persist-"+e)}get value(){if(this.disposed)throw new i("Cannot read from disposed signal");return super.value}set value(e){if(this.disposed)throw new i("Cannot write to disposed signal");super.value=e}update(e){if(this.disposed)throw new i("Cannot update disposed signal");this.value=e(this.value)}dispose(){this.disposed||(this.disposed=!0,this.storage.removeItem(this.key),super.dispose())}reload(){if(this.disposed)throw new i("Cannot reload disposed signal");const e=this.storage.getItem(this.key);null!==e&&(this.value=e)}clear(){if(this.disposed)throw new i("Cannot clear disposed signal");this.storage.removeItem(this.key)}isDisposed(){return this.disposed}}function O(e,t,i,s){return new v(e,t,i,s)}function y(e,t=10,i){const s=i?.equals??w,n=b(e,{...i,equals:s}),r=b([e]),o=b(0),a=d((()=>o.value>0)),h=d((()=>r.value.length-1>o.value)),u=Object.create(n);return u.history=r,u.canUndo=a,u.canRedo=h,Object.defineProperty(u,"value",{get:()=>n.value,set:e=>{s(n.value,e)||f((()=>{const i=o.value+1,s=r.value.slice(0,i).concat([e]);s.length>t?(s.shift(),o.value=i-1):o.value=i,r.value=s,n.value=e}))}}),u.undo=()=>{a.value&&f((()=>{o.value--,n.value=r.value[o.value]}))},u.redo=()=>{h.value&&f((()=>{o.value++,n.value=r.value[o.value]}))},u}module.exports=t})();
//# sourceMappingURL=index.js.map