UNPKG

@qtpy/state-management-observable

Version:

1. [Основная идея и архитектура](#основная-идея-и-архитектура) 1.1. [Прозрачная реактивность](#прозрачная-реактивность) 1.2. [Поддержка типизированных строковых ключей](#поддержка-типизированных-строковых-ключей) 1.3. [Подписки с «гранул

2 lines (1 loc) 11 kB
"use strict";var J=Object.defineProperty;var X=(E,c,u)=>c in E?J(E,c,{enumerable:!0,configurable:!0,writable:!0,value:u}):E[c]=u;var $=(E,c,u)=>X(E,typeof c!="symbol"?c+"":c,u);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("./utils.cjs");class Y{constructor(c=[],u){$(this,"undoStack",new Map);$(this,"redoStack",new Map);$(this,"perPathMaxLength");this.perPathMaxLength=new Map;for(const[d,f]of c){const g=u(d);this.perPathMaxLength.set(g,f)}}getMaxLength(c){return this.perPathMaxLength.get(c)??0}push(c,u){if(!this.perPathMaxLength.get(c))return;const d=this.undoStack.get(c)??[];d.push(u);const f=this.getMaxLength(c);d.length>f&&d.shift(),this.undoStack.set(c,d),this.redoStack.set(c,[])}getUndo(c,u){const d=this.undoStack.get(c)??[];if(!(u<0||u>=d.length))return d[d.length-1-u]}getRedo(c,u){const d=this.redoStack.get(c)??[];if(!(u<0||u>=d.length))return d[d.length-1-u]}getHistory(c){const u=this.undoStack.get(c)??[],d=this.redoStack.get(c)??[];return{undo:[...u],redo:[...d]}}spliceStack(c,u,d){if(d){const[f,g]=d;if(f<0||f>=c.length||g<=0)return;const S=c.splice(f,g);return u.push(...S),S[S.length-1]}}undo(c,u){const d=this.undoStack.get(c)??[],f=this.redoStack.get(c)??[];if(d.length<=1&&!u)return;if(u){const S=this.spliceStack(d,f,u);return this.undoStack.set(c,d),this.redoStack.set(c,f),S??(d.length>0?d[d.length-1]:void 0)}const g=d.pop();return f.push(g),this.undoStack.set(c,d),this.redoStack.set(c,f),d[d.length-1]}redo(c,u){const d=this.undoStack.get(c)??[],f=this.redoStack.get(c)??[];if(f.length===0&&!u)return;if(u){const S=this.spliceStack(f,d,u);return this.undoStack.set(c,d),this.redoStack.set(c,f),S}const g=f.pop();return d.push(g),this.undoStack.set(c,d),this.redoStack.set(c,f),g}getCurrent(c){const u=this.undoStack.get(c)??[];return u[u.length-1]}clear(c,u="all",d){const f=this.undoStack.get(c)??[],g=this.redoStack.get(c)??[];if(d){const[S,w]=d;if(S<0||S>=(u==="redo"?g:f).length||w<=0)return!1;if(u==="redo")return g.splice(S,w),this.redoStack.set(c,g),!0;if(u==="undo")return f.splice(S,w),this.undoStack.set(c,f),!0;if(u==="all"){const p=f.length>0&&S>=0&&S<f.length&&w>0,m=g.length>0&&S>=0&&S<g.length&&w>0;return p&&f.splice(S,w),m&&g.splice(S,w),this.undoStack.set(c,f),this.redoStack.set(c,g),p||m}}switch(u){case"redo":return this.redoStack.delete(c);case"undo":return this.undoStack.delete(c);default:const S=this.undoStack.delete(c),w=this.redoStack.delete(c);return S||w}}pruneUnused(c){for(const u of[...this.undoStack.keys()])c.has(u)||this.clear(u)}getEntries(){return Array.from(this.undoStack.entries()).map(([c,u])=>{const d=this.redoStack.get(c)??[];return{path:c,current:u[u.length-1],undoLength:u.length,redoLength:d.length,undo:u,redo:d,maxLength:this.getMaxLength(c)}})}}function Z(E,c=[],u={}){let d={...E},f=null;const g=new Map,S=new WeakMap,w=new Map,p=new Set,m=new Map,P=new Map,L=new Set,x=new Map,H=()=>{if(g.size===0)return null;const e=Array.from(g.keys()).pop();return g.get(e)},j=()=>g.size!==0,_=e=>h.splitPath(e).reduce((t,n)=>{if(t!=null)return t[n]},d),V=(e,r)=>{const t=h.splitPath(e),n=t.pop(),a=t.reduce((s,i)=>{if(s==null)throw new Error(`Невозможно установить по пути "${e}" — промежуточное значение undefined`);return s[i]},d);a[n]=r};let K=null;function T(e,r=""){if(typeof e!="object"||e===null)return e;for(const{node:n,path:a,parent:s,key:i}of h.iterateObjectTree(e))h.withMetaSupport(n,()=>{const l=h.calculateSnapshotHash(n);if(!l)return;const y=h.wrapNode(n,s,i,S);h.setMetaData(S,y,{_prevSignature:l},w,a)});return new Proxy(e,{get(n,a,s){const i=typeof a=="string"?a:String(a),l=r?`${r}.${i}`:i;f==null||f.trackedPaths.add(l);const y=Reflect.get(n,a,s);return Array.isArray(n)&&typeof y=="function"&&h.isArrayMethod(i)?(...v)=>{K={name:i};const k=H();let A;return o.batch(()=>{A=y.apply(s,v)},"proxy"),k&&k.modeBatching==="proxy"&&r&&L.add(r),K=null,A}:y===n?s:y!==null&&typeof y=="object"?T(y,l):y},set(n,a,s,i){const l=H(),y=typeof a=="string"?a:String(a),v=r?`${r}.${y}`:y,k=Reflect.get(n,a,i);return Object.is(k,s)||(l&&l.modeBatching==="proxy"?l==null||l.pending.set(v,s):(o.update(v,s),!K&&r&&o.invalidate(r))),!0},deleteProperty(n,a){const s=typeof a=="string"?a:String(a),i=r?`${r}.${s}`:s,l=Reflect.deleteProperty(n,a);return l&&o.update(i,void 0),l},ownKeys(n){if(f){const a=r?`${r}.`:"";for(const s of Reflect.ownKeys(n))f.trackedPaths.add(`${a}${String(s)}`)}return Reflect.ownKeys(n)}})}function B(e,r,t,n,a=!0){let s=!1;const i=h.withMetaSupport(r,()=>{const l=h.getMetaData(t,e,w,n),y=l==null?void 0:l._prevSignature,v=h.calculateSnapshotHash(r);return y===v?(s=!0,!0):(v&&a&&h.setMetaData(t,r,{_prevSignature:v},w,n),!0)});return{newVal:r,oldVal:e,bool:s||!i&&h.shallowEqual(e,r),isSupportedMetaData:i,skipUpdate:s}}const o={};let C=T(d);Object.defineProperty(o,"$",{get:()=>C,enumerable:!0,configurable:!0});const b=e=>h.getStringPath(o==null?void 0:o.$,e),M=new Y((u==null?void 0:u.customLimitsHistory)??[],b),U=new Set;function z(e,r){var n;const t=new Set;return e.forEach((a,s)=>{t.add(s)}),(n=u==null?void 0:u.customLimitsHistory)==null||n.forEach(([a])=>{const s=o.resolvePath(a);t.add(s)}),r.forEach(a=>{const s=a.__meta;s!=null&&s.trackedPaths&&s.trackedPaths.forEach(i=>t.add(i))}),t}function q(e,r,t,n){const a=e?`${e}.`:"";for(const s of n){if(!s.startsWith(a)||U.has(s))continue;const i=s.slice(a.length),l=h.getByPath(t,i),y=h.getByPath(r,i);B(l,y,S,s,!1).bool||(o.update(s,y,{skipHistory:!1,keepQuiet:!0,isRecurse:!0,oldValue:l,isAddMetaData:!0}),U.add(s))}j()||U.clear()}function N(e,r,t,n,a){h.withMetaSupport(r,()=>{const s=new Set;a.forEach(i=>{h.isPathValid(d,i)?s.add(i):n.delete(i)}),q(e,r,t,s)})}function R(e,r,t,n=!1){if(p.forEach(s=>{const i=s.__meta;if(j()?i.cacheKeys&&i.cacheKeys.has(e):!i.cacheKeys||i.cacheKeys.has(e)){f=i;try{s(C,i.unsubscribe)}finally{f=null}}}),!U.has(e)){const s=m.get(e);s&&(s.forEach(i=>{const l=i.__meta;i(r,l.unsubscribe)}),U.add(e))}if(n)return;const a=z(m,p);N(e,r,t,m,a)}o.clearHistoryPath=(e,r="all",t)=>{const n=b(e);M.clear(n,r,t)},o.clearAllHistory=()=>{const e=new Set(m.keys());M.pruneUnused(e)};const D=(e,r,t=!1,n=!1,a=!1,s)=>{const i=s??_(e),l=B(i,r,S,e);a&&R(e,r,i,a),!t&&!l.bool&&M.push(e,r),!a&&(l.bool||(V(e,r),!n&&R(e,r,i,a)))};o.update=(e,r,t)=>{h.validatePath(e);const n=H(),a=b(e);let s=o.resolveValue(e,r,t==null?void 0:t.isAddMetaData);if(n&&!(t!=null&&t.keepQuiet))n.pending.set(a,s);else return D(a,s,t==null?void 0:t.skipHistory,t==null?void 0:t.keepQuiet,t==null?void 0:t.isRecurse,t==null?void 0:t.oldValue),s},o.update.quiet=(e,r)=>o.update(e,r,{keepQuiet:!0}),o.debounced=(e,r)=>{const t=h.getRandomId();let n=null;const a=(...s)=>{n&&clearTimeout(n),n=setTimeout(()=>{e(...s),x.delete(t)},r),x.set(t,n)};return a.cancel=()=>{n&&(clearTimeout(n),x.delete(t))},a};function O(e){const r=[];for(const[t,n]of e){const a=_(t),s=B(a,n,S,t),i=H();s.bool||((i==null?void 0:i.modeBatching)==="user"&&M.push(t,a),V(t,n),R(t,n,a),r.push(t))}r.length&&p.forEach(t=>{const n=t.__meta;n.cacheKeys||t(o.getRawStore(),n.unsubscribe)})}function I(e){const r=Array.from(g.keys());for(let t=r.length-1;t>=0;t--){const n=g.get(r[t]);if(n.pending.has(e))return n.pending.get(e)}return _(e)}o.resolveValue=(e,r,t=!1)=>{const n=b(e),a=I(n),s=typeof r=="function"?r(a):r;return t&&h.withMetaSupport(s,()=>{for(const{node:i,parent:l,key:y}of h.iterateObjectTree(s)){const v=h.calculateSnapshotHash(i);if(!v)break;const k=h.wrapNode(i,l,y,S);h.setMetaData(S,k,{_prevSignature:v},w,n)}}),s},o.cancelAsyncUpdates=e=>{if(e){const r=b(e),t=P.get(r);t&&(t.abort(),P.delete(r))}else P.forEach((r,t)=>{r.abort(),P.delete(t)})},o.isAborted=e=>{const r=b(e),t=P.get(r);return t?t.signal.aborted:!1},o.asyncUpdate=async(e,r,t={})=>{const{abortPrevious:n=!1,keepQuiet:a=!1}=t;h.validatePath(e);const s=b(e);n&&o.cancelAsyncUpdates(s);let i;if(n){const l=new AbortController;P.set(s,l);try{const y=_(s);return i=await r(y,l.signal),o.update(s,i,{keepQuiet:a}),i}catch(y){throw y.name!=="AbortError"&&console.error(y),y}finally{P.delete(s)}}else try{const l=_(s);return i=await r(l),o.update(s,i,{keepQuiet:a}),i}catch(l){throw console.error(l),l}},o.asyncUpdate.quiet=async(e,r,t={})=>o.asyncUpdate(e,r,{abortPrevious:t.abortPrevious??!1,keepQuiet:!0});function W(e="user"){const r=h.getRandomId();return g.set(r,{modeBatching:e,pending:new Map}),r}function G(e){const r=g.get(e);if(r)if(g.delete(e),g.size===0){O(r.pending),U.clear();for(const t of L)o.invalidate(t);L.clear()}else{const t=Array.from(g.keys()).pop(),n=g.get(t);r.pending.forEach((a,s)=>n.pending.set(s,a))}}o.batch=async(e,r="user")=>{const t=W(r);try{const n=e();n instanceof Promise&&await n}finally{G(t)}return Promise.resolve()},o.getUndo=(e,r)=>{h.validatePath(e);const t=b(e);return M.getUndo(t,r)},o.getRedo=(e,r)=>{h.validatePath(e);const t=b(e);return M.getRedo(t,r)},o.getHistory=e=>{h.validatePath(e);const r=b(e);return M.getHistory(r)},o.undo=(e,r)=>{h.validatePath(e);const t=b(e),n=M.undo(t,r);return n!==void 0?(D(t,n,!0),o.update(t,n,{skipHistory:!0,keepQuiet:!0}),!0):(console.warn(`No undo history for path: ${t}`),!1)},o.redo=(e,r)=>{h.validatePath(e);const t=b(e),n=M.redo(t,r);return n!==void 0?(D(t,n,!0),o.update(t,n,{skipHistory:!0,keepQuiet:!0}),!0):(console.warn(`No redo history for path: ${t}`),!1)},o.subscribe=(e,r)=>{const t=r?new Set(r.map(s=>h.normalizeCacheKey(s,o))):void 0,n=(s,i)=>{a.active&&e(s,i)},a={active:!0,trackedPaths:new Set,cacheKeys:t,unsubscribe:()=>{a.active=!1,p.delete(n)}};return n.__meta=a,p.add(n),a.unsubscribe},o.subscribeToPath=(e,r,t={})=>{h.validatePath(e);const{immediate:n=!1,cacheKeys:a}=t,s=b(e),i=a?a.map(k=>h.normalizeCacheKey(k,o)):[],l=[s,...i],y=(k,A)=>r(k,A),v={active:!0,trackedPaths:new Set(l),cacheKeys:i.length>0?new Set(i):void 0,unsubscribe:()=>{l.forEach(k=>{var A;(A=m.get(k))==null||A.delete(y)})}};return y.__meta=v,l.forEach(k=>{m.has(k)||m.set(k,new Set),m.get(k).add(y)}),n&&y(_(s),v.unsubscribe),v.unsubscribe},o.invalidateAll=()=>{p.forEach(e=>{const r=e.__meta;f=r;try{e(C,r.unsubscribe)}finally{f=null}}),m.forEach((e,r)=>{const t=_(r);e.forEach(n=>{const a=n.__meta;n(t,a.unsubscribe)})})},o.invalidate=e=>{const r=b(e);R(r)},o.cancelAsyncUpdates=e=>{if(e){const r=b(e),t=P.get(r);t&&(t.abort(),P.delete(r))}else P.forEach((r,t)=>{r.abort(),P.delete(t)})},o.clearStore=()=>{p.clear(),m.clear(),P.clear(),x.forEach(e=>clearTimeout(e)),x.clear(),o.clearAllHistory()},o.get=e=>(h.validatePath(e),_(b(e))),o.resolvePath=b,o.getRawStore=()=>d,o.setRawStore=async(e,r)=>{o.cancelAsyncUpdates(),o.clearAllHistory(),x.forEach(t=>clearTimeout(t)),x.clear(),d={...e},C=T(d),r!=null&&r.keepQuiet||o.invalidateAll()},o.getMemoryStats=()=>({subscribersCount:p.size,pathSubscribersCount:m.size,historyEntries:M.getEntries(),activePathsCount:m.size,debounceTimersCount:x.size,abortersCount:P.size});let Q=o.update;return c.reverse().forEach(e=>{Q=e(o,Q)}),o.update=Q,u.ssrStoreId?h.ssrStore(o,u.ssrStoreId):o}exports.createObservableStore=Z;