UNPKG

@mobx-sentinel/core

Version:

A TypeScript library for non-intrusive model enhancement in MobX applications. Provides model change detection, validation, and form integration capabilities while maintaining the purity of domain models.

2 lines 13.6 kB
var oe=Object.defineProperty;var ne=Object.getOwnPropertyDescriptor;var c=(n,e,t,r)=>{for(var o=r>1?void 0:r?ne(e,t):e,s=n.length-1,a;s>=0;s--)(a=n[s])&&(o=(r?a(e,t,o):a(o))||o);return r&&o&&oe(e,t,o),o};import{comparer as ie,computed as le,makeObservable as ce}from"mobx";function L(n){return typeof n=="object"&&typeof n.kind=="string"}function W(n){return typeof n=="string"||typeof n=="symbol"}var k=class n{#e=new Map;registerPropertyLike(e,t){let r=this.#e.get(e);r||(r=new Map,this.#e.set(e,r));let o=r.get(t.propertyKey);o||(o={data:[],get:t.get},r.set(t.propertyKey,o)),o.data.push(t.data)}getPropertyLike(e){return this.#e.get(e)}clone(){let e=new n;for(let[t,r]of this.#e)for(let[o,s]of r)for(let a of s.data)e.registerPropertyLike(t,{propertyKey:o,data:a,get:s.get});return e}},E=new WeakMap;function J(n){let e=!0;for(;n&&typeof n=="object";){let t=E.get(n);if(t)return{processor:t,isOwn:e};e=!1,n=Object.getPrototypeOf(n)}return{processor:null,isOwn:e}}function q(n,e){let t=J(n);return t.processor?e&&!t.isOwn&&(t.processor=t.processor.clone(),E.set(n,t.processor)):(t.processor=new k,E.set(n,t.processor)),t.processor}function g(n){return J(n).processor}function m(n,e){return(t,r)=>{L(r)?r.addInitializer(function(){q(this,!1).registerPropertyLike(n,{propertyKey:r.name,data:e(r.name),get:()=>r.access.get(this)})}):t&&W(r)&&q(t,!0).registerPropertyLike(n,{propertyKey:r,data:e(r)})}}var l;(a=>{a.Self=Symbol("self");function e(i){return i===a.Self||i===""}a.isSelf=e;function t(...i){let d=i.flatMap(h=>{switch(typeof h){case"string":return h===""?[]:[h];case"number":return[String(h)];case"symbol":return[];default:return[]}}).join(".");return d===""?a.Self:d}a.build=t;function r(i,d){return e(i)?a.Self:e(d)?i:`${i}.`.startsWith(`${d}.`)?t(i.slice(d.length+1)):null}a.getRelative=r;function o(i){if(e(i))return a.Self;let[d]=i.split(".",1);return d||a.Self}a.getParentKey=o;function*s(i,d=!0){if(d&&(yield i||a.Self),e(i))return;let h=i.split(".");for(;h.length>1;)h.pop(),yield t(...h)}a.getAncestors=s})(l||={});var S=class{#e=new Map;#t=new Map;get size(){return this.#e.size}has(e,t=!1){return this.#e.has(e)?!0:t?this.#t.has(e):!1}*findExact(e){let t=this.#e.get(e);t&&(yield*t)}*findPrefix(e){if(l.isSelf(e)){for(let o of this.#e.values())yield*o;return}let t=this.#e.get(e);t&&(yield*t);let r=this.#t.get(e);if(r)for(let o of r)yield*this.findExact(o)}get(e,t=!1){return t?new Set(this.findPrefix(e)):new Set(this.findExact(e))}set(e,t){if(Object.isFrozen(this))throw new Error("Cannot modify frozen KeyPathMultiMap");let r=this.#e.get(e);r||(r=new Set,this.#e.set(e,r)),r.add(t);for(let o of l.getAncestors(e,!1)){let s=this.#t.get(o);s||(s=new Set,this.#t.set(o,s)),s.add(e)}}delete(e){if(Object.isFrozen(this))throw new Error("Cannot modify frozen KeyPathMultiMap");this.#e.delete(e);for(let t of l.getAncestors(e,!1)){let r=this.#t.get(t);r&&(r.delete(e),r.size===0&&this.#t.delete(t))}}*[Symbol.iterator](){for(let[e,t]of this.#e.entries())for(let r of t)yield[e,r]}toImmutable(){return Object.freeze(this),this}};import{isBoxedObservable as B,isObservableArray as U,isObservableSet as $,isObservableMap as Q,isObservableObject as se,$mobx as ae}from"mobx";function w(n){return B(n)&&(n=n.get()),U(n)?n.slice():$(n)?new Set(n):Q(n)?new Map(n):n}function*T(n){if(B(n)&&(n=n.get()),Array.isArray(n)||U(n)){let e=0;for(let t of n)yield[e++,t];return}if(n instanceof Set||$(n)){let e=0;for(let t of n)yield[e++,t];return}if(n instanceof Map||Q(n)){for(let[e,t]of n)yield[e,t];return}yield[null,n]}function*X(n){if(!se(n))return;let e=n[ae];if(typeof e!="object"||!e||!("values_"in e))return;let t=e.values_;if(t instanceof Map)for(let[r,o]of t){if(typeof r!="string"&&typeof r!="symbol"&&typeof r!="number"||typeof o!="object"||!o||!("get"in o&&typeof o.get=="function"))continue;yield[r,()=>r in n?n[r]:o.get()]}}var M=Symbol("nested"),de=m(M,()=>"@nested"),ye=m(M,()=>"@nested.hoist"),he=Object.assign(de,{hoist:ye});function*j(n){let e=g(n);if(!e)return;let t=e.getPropertyLike(M);if(!t)return;let r=null;for(let[o,s]of t){let a=new Set(s.data);if(a.size>1)throw new Error(`Mixed @nested annotations are not allowed for the same key: ${String(o)}`);let i=a.has("@nested.hoist");if(i){if(r)throw new Error(`Multiple @nested.hoist annotations are not allowed in the same class: ${String(r)} and ${String(o)}`);r=o}yield{key:o,getValue:()=>o in n?n[o]:s.get?.(),hoist:i}}}var b=class{#e;#t=new Map;constructor(e,t){ce(this),this.#e=t;for(let{key:r,getValue:o,hoist:s}of j(e)){if(typeof r!="string")continue;let a=s?l.Self:l.build(r),i=this.#r(a,o);this.#t.set(a,i)}}#r(e,t){let r=this;return function*(){for(let[o,s]of T(t())){if(typeof o=="symbol")continue;let a=l.build(e,o),i=r.#e({key:e,keyPath:a,data:s})??null;i!==null&&(yield{key:e,keyPath:a,data:i})}}}*[Symbol.iterator](){for(let e of this.#t.values())for(let t of e())yield t}*getForKey(e){let t=this.#t.get(e);if(t)for(let r of t())yield r}get dataMap(){let e=new Map;for(let t of this)e.set(t.keyPath,t.data);return e}};c([le({equals:ie.shallow})],b.prototype,"dataMap",1);import{action as Y,autorun as fe,computed as V,makeObservable as ue,observable as D,reaction as K,runInAction as Z,transaction as pe}from"mobx";import{v4 as be}from"uuid";var R=Symbol("watch"),me=m(R,()=>"@watch"),ge=m(R,()=>"@watch.ref"),ee=Symbol("unwatch"),Pe=m(ee,()=>!0),A=0;function xe(n){pe(()=>{++A;try{n()}finally{fe(()=>--A)}})}var Se=Object.freeze(Object.assign(me,{ref:ge})),we=(...n)=>n.length===1&&typeof n[0]=="function"?xe(n[0]):Pe(...n),_=Symbol("watcher"),C=Symbol("watcher.internal"),f=class f{id=be();#e=D.box(!1);#t=D.box(0n);#r=D.set();#o=new Set;#n;static get(e){let t=this.getSafe(e);if(!t)throw new TypeError("target: Expected an object");return t}static getSafe(e){if(!e||typeof e!="object")return null;let t=e[_]??null;return t||(t=new this(C,e),Object.defineProperty(e,_,{value:t})),t}static get isWatching(){return A===0}constructor(e,t){if(e!==C)throw new Error("private constructor");this.#n=new b(t,r=>f.getSafe(r.data)),this.#d(t),this.#i(t),this.#c(t),this.#l(t),ue(this)}get changedTick(){return this.#t.get()}get changed(){return this.changedTick>0n||this.#e.get()}get changedKeys(){return new Set(this.#r)}get changedKeyPaths(){let e=new Set(this.#r);for(let t of this.#n)for(let r of t.data.changedKeyPaths)e.add(l.build(t.keyPath,r));return e}get nested(){return this.#n.dataMap}reset(){this.#r.clear(),this.#t.set(0n),this.#e.set(!1);for(let e of this.#n)e.data.reset()}assumeChanged(){f.isWatching&&this.#e.set(!0)}#s(e){f.isWatching&&Z(()=>{this.#r.add(e),this.#a()})}#a(){f.isWatching&&Z(()=>{this.#t.set(this.#t.get()+1n)})}#l(e){for(let[t,r]of X(e))typeof t=="string"&&(this.#o.has(t)||(this.#o.add(t),K(()=>w(r()),()=>this.#s(l.build(t)))))}#i(e){for(let{key:t,getValue:r,hoist:o}of j(e))typeof t=="string"&&(this.#o.has(t)||(this.#o.add(t),K(()=>w(r()),()=>o?this.#a():this.#s(l.build(t))),K(()=>{let s=!1;for(let[,a]of T(r()))f.getSafe(a)?.changed&&(s=!0);return s},s=>s&&this.#a())))}#c(e){let t=g(e);if(!t)return;let r=t.getPropertyLike(R);if(r)for(let[o,s]of r){if(typeof o!="string"||this.#o.has(o))continue;this.#o.add(o);let a=s.data.at(-1)==="@watch",i=()=>o in e?e[o]:s.get?.();K(()=>a?w(i()):i(),()=>this.#s(l.build(o)))}}#d(e){let t=g(e);if(!t)return;let r=t.getPropertyLike(ee);if(r)for(let[o]of r)typeof o=="string"&&this.#o.add(o)}[C](){return{didChange:this.#s.bind(this)}}};c([V],f.prototype,"changed",1),c([V.struct],f.prototype,"changedKeys",1),c([V.struct],f.prototype,"changedKeyPaths",1),c([Y],f.prototype,"reset",1),c([Y],f.prototype,"assumeChanged",1);var O=f;import{action as F,comparer as ke,computed as p,makeObservable as Ee,observable as N,reaction as Me,runInAction as z}from"mobx";import{v4 as je}from"uuid";var v=class extends Error{key;keyPath;message;cause;constructor(e){super(),this.key=l.getParentKey(e.keyPath),this.keyPath=e.keyPath,this.message=e.reason instanceof Error?e.reason.message:e.reason,this.cause=e.reason instanceof Error?e.reason:void 0}},u=class{#e=new S;static build(e){return e.#t()}invalidate(e,t){let r=l.build(e),o=new v({keyPath:r,reason:t});this.#e.set(r,o)}invalidateSelf(e){let t=l.Self,r=new v({keyPath:t,reason:e});this.#e.set(t,r)}get hasError(){return this.#e.size>0}#t(){return this.#e.toImmutable()}};import{action as Te,makeObservable as Ke,observable as ve,runInAction as I}from"mobx";var H=Symbol(),P=class{scheduledRunDelayMs;#e;#t=ve.box("idle");#r=!1;#o=null;#n=null;#s=H;constructor(e){this.#e=e.handler,this.scheduledRunDelayMs=e.scheduledRunDelayMs,Ke(this)}get state(){return this.#t.get()}request(e,t){if(this.#s=e,t?.force){this.#i();return}switch(this.state){case"idle":{this.#i();break}case"running":{this.#r=!0;break}case"scheduled":{this.#a();break}}}reset(){this.#l(),this.#n?.abort(),this.#t.set("idle")}#a(){I(()=>{this.#t.set("scheduled")}),this.#o=+setTimeout(()=>{this.#i()},this.scheduledRunDelayMs)}#l(){this.#o&&(clearTimeout(this.#o),this.#o=null)}async#i(){this.#l(),this.#n?.abort();let e=new AbortController;this.#n=e;let t=this.#s;if(this.#s=H,t!==H){I(()=>{this.#t.set("running")});try{await this.#e(t,e.signal)}catch(r){console.error(r)}}this.#n=null,I(()=>{this.#r?(this.#r=!1,this.#a()):this.#t.set("idle")})}};c([Te],P.prototype,"reset",1);var te=Symbol("validator"),re=Symbol("validator.internal");function Ve(n,...e){if(typeof e[0]=="function"&&typeof e[1]=="function"){let[o,s,a]=e;return x.get(n).addAsyncHandler(o,s,a)}let[t,r]=e;return x.get(n).addSyncHandler(t,r)}var y=class y{static defaultDelayMs=100;id=je();#e=N.map([],{equals:ke.structural});#t;#r=N.map();#o=new Map;#n=N.set();static get(e){let t=this.getSafe(e);if(!t)throw new TypeError("target: Expected an object");return t}static getSafe(e){if(!e||typeof e!="object")return null;let t=e[te]??null;return t||(t=new this(re,e),Object.defineProperty(e,te,{value:t})),t}constructor(e,t){if(e!==re)throw new Error("private constructor");this.#t=new b(t,r=>y.getSafe(r.data)),Ee(this)}get isValid(){return this.invalidKeyPathCount===0}get invalidKeyCount(){return this.invalidKeys.size}get invalidKeys(){let e=new Set;for(let t of this.#e.values())for(let[,r]of t)e.add(l.build(r.key));return Object.freeze(e)}get invalidKeyPathCount(){return this.invalidKeyPaths.size}get invalidKeyPaths(){let e=new Set;for(let t of this.#e.values())for(let[r]of t)e.add(r);for(let[t,r]of this.nested)for(let o of r.invalidKeyPaths)e.add(l.build(t,o));return Object.freeze(e)}get firstErrorMessage(){for(let[,e]of this.findErrors(l.Self,!0))return e.message;return null}getErrorMessages(e,t=!1){let r=new Set;for(let[,o]of this.findErrors(e,t))r.add(o.message);return r}hasErrors(e,t=!1){for(let r of this.findErrors(e,t))return!0;return!1}*findErrors(e,t=!1){yield*this.#s(e,t,!1)}*#s(e,t,r){if(l.isSelf(e)){if(r)for(let o of this.#e.values())for(let s of o.findExact(l.Self))yield[l.Self,s];else for(let o of this.#e.values())for(let[s,a]of o)yield[s,a];if(t)for(let[o,s]of this.nested)for(let[a,i]of s.#s(l.Self,!0,r))yield[l.build(o,a),i];else if(!r)for(let o of this.#t){let s=o.key===l.Self,a=o.keyPath===o.key;if(s||a)for(let[i,d]of o.data.#s(l.Self,!1,!s||!a))yield[l.build(o.keyPath,i),d]}}else{for(let o of this.#e.values()){let s=t?o.findPrefix(e):o.findExact(e);for(let a of s)yield[a.keyPath,a]}e:for(let o of l.getAncestors(e,!0))for(let s of this.#t.getForKey(o)){let a=t&&s.key!==s.keyPath&&l.getRelative(s.keyPath,s.key)?l.Self:l.getRelative(e,s.keyPath);if(a){for(let[i,d]of s.data.#s(a,t,r))yield[l.build(s.keyPath,i),d];break e}}}}get reactionState(){return this.#r.size}get asyncState(){let e=0;for(let t of this.#n)t.state!=="idle"&&e++;return e}get isValidating(){return this.reactionState>0||this.asyncState>0}get nested(){return this.#t.dataMap}reset(){this.#r.clear();for(let e of this.#o.values())e();for(let e of this.#n)e.reset();this.#e.clear()}updateErrors(e,t){let r=new u;t(r);let o=u.build(r);return o.size>0?this.#e.set(e,o):this.#e.delete(e),()=>{this.#e.delete(e)}}addSyncHandler(e,t){let r=Symbol();return this.#a({key:r,opt:t,expr:()=>{let o=new u;return e(o),u.build(o)},effect:o=>{o.size>0?this.#e.set(r,o):this.#e.delete(r)}})}addAsyncHandler(e,t,r){let o=r?.delayMs??y.defaultDelayMs,s=Symbol(),a=new P({handler:async(i,d)=>{let h=new u;try{await t(i,h,d)}finally{z(()=>{let G=u.build(h);G.size>0?this.#e.set(s,G):this.#e.delete(s)})}},scheduledRunDelayMs:o});return this.#n.add(a),this.#a({key:s,opt:r,expr:e,effect:i=>{a.request(i)},dispose:()=>{a.reset(),this.#n.delete(a)}})}#a(e){let t=e.opt?.delayMs??y.defaultDelayMs,r=e.opt?.initialRun??!0,o=Me(e.expr,s=>{!r&&!this.#r.has(e.key)||(r=!1,this.#r.delete(e.key),e.effect(s))},{fireImmediately:e.opt?.initialRun??!0,scheduler:s=>{let a=+setTimeout(s,t);z(()=>{this.#r.set(e.key,a)}),this.#o.set(e.key,()=>{clearTimeout(a),this.#o.delete(e.key),s()})}});return()=>{o();let s=this.#r.get(e.key);s&&clearTimeout(s),z(()=>{this.#r.delete(e.key),this.#o.delete(e.key);try{e.dispose?.()}finally{this.#e.delete(e.key)}})}}};c([p],y.prototype,"isValid",1),c([p],y.prototype,"invalidKeyCount",1),c([p.struct],y.prototype,"invalidKeys",1),c([p],y.prototype,"invalidKeyPathCount",1),c([p.struct],y.prototype,"invalidKeyPaths",1),c([p],y.prototype,"firstErrorMessage",1),c([p],y.prototype,"reactionState",1),c([p],y.prototype,"asyncState",1),c([p],y.prototype,"isValidating",1),c([F],y.prototype,"reset",1),c([F],y.prototype,"updateErrors",1),c([F],y.prototype,"addAsyncHandler",1);var x=y;export{l as KeyPath,b as StandardNestedFetcher,x as Validator,O as Watcher,Ve as makeValidatable,he as nested,we as unwatch,Se as watch}; //# sourceMappingURL=index.mjs.map