UNPKG

x-view-model

Version:

A lightweight, type-safe MVVM state management solution for React applications. Features reactive updates, computed properties, and deep path selection with minimal bundle size.

3 lines (2 loc) 17.9 kB
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var t=require("react"),e=function(t,r){return e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r])},e(t,r)};function r(t,r){if("function"!=typeof r&&null!==r)throw new TypeError("Class extends value "+String(r)+" is not a constructor or null");function n(){this.constructor=t}e(t,r),t.prototype=null===r?Object.create(r):(n.prototype=r.prototype,new n)}var n=function(){return n=Object.assign||function(t){for(var e,r=1,n=arguments.length;r<n;r++)for(var o in e=arguments[r])Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=e[o]);return t},n.apply(this,arguments)};function o(t,e,r,n){return new(r||(r=Promise))((function(o,s){function i(t){try{c(n.next(t))}catch(t){s(t)}}function a(t){try{c(n.throw(t))}catch(t){s(t)}}function c(t){var e;t.done?o(t.value):(e=t.value,e instanceof r?e:new r((function(t){t(e)}))).then(i,a)}c((n=n.apply(t,e||[])).next())}))}function s(t,e){var r,n,o,s={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]},i=Object.create(("function"==typeof Iterator?Iterator:Object).prototype);return i.next=a(0),i.throw=a(1),i.return=a(2),"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(a){return function(c){return function(a){if(r)throw new TypeError("Generator is already executing.");for(;i&&(i=0,a[0]&&(s=0)),s;)try{if(r=1,n&&(o=2&a[0]?n.return:a[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,a[1])).done)return o;switch(n=0,o&&(a=[2&a[0],o.value]),a[0]){case 0:case 1:o=a;break;case 4:return s.label++,{value:a[1],done:!1};case 5:s.label++,n=a[1],a=[0];continue;case 7:a=s.ops.pop(),s.trys.pop();continue;default:if(!(o=s.trys,(o=o.length>0&&o[o.length-1])||6!==a[0]&&2!==a[0])){s=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]<o[3])){s.label=a[1];break}if(6===a[0]&&s.label<o[1]){s.label=o[1],o=a;break}if(o&&s.label<o[2]){s.label=o[2],s.ops.push(a);break}o[2]&&s.ops.pop(),s.trys.pop();continue}a=e.call(t,s)}catch(t){a=[6,t],n=0}finally{r=o=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,c])}}}"function"==typeof SuppressedError&&SuppressedError;const i="insert",a="update",c="delete",h="reverse",l="shuffle",p=Symbol.for("object-observer-meta-key-0"),u={async:1},f=t=>{if(!t||"object"!=typeof t)return null;const e={},r=[];for(const[n,o]of Object.entries(t))if("path"===n){if("string"!=typeof o||""===o)throw new Error('"path" option, if/when provided, MUST be a non-empty string');e[n]=o}else if("pathsOf"===n){if(t.path)throw new Error('"pathsOf" option MAY NOT be specified together with "path" option');if("string"!=typeof o)throw new Error('"pathsOf" option, if/when provided, MUST be a string (MAY be empty)');e[n]=t.pathsOf.split(".").filter(Boolean)}else if("pathsFrom"===n){if(t.path||t.pathsOf)throw new Error('"pathsFrom" option MAY NOT be specified together with "path"/"pathsOf" option/s');if("string"!=typeof o||""===o)throw new Error('"pathsFrom" option, if/when provided, MUST be a non-empty string');e[n]=o}else r.push(n);if(r.length)throw new Error(`'${r.join(", ")}' is/are not a valid observer option/s`);return e},y=(t,e)=>{const r={};r[p]=e;for(const n in t)r[n]=_(t[n],n,e);return r},d=(t,e)=>{let r=t.length;const n=new Array(r);n[p]=e;for(let o=0;o<r;o++)n[o]=_(t[o],o,e);return n},b=(t,e)=>(t[p]=e,t),v=(t,e)=>{if(null===t)return e;let r=e;if(t.path){const n=t.path;r=e.filter((t=>t.path.join(".")===n))}else if(t.pathsOf){const n=t.pathsOf,o=n.join(".");r=e.filter((t=>(t.path.length===n.length+1||t.path.length===n.length&&(t.type===h||t.type===l))&&t.path.join(".").startsWith(o)))}else if(t.pathsFrom){const n=t.pathsFrom;r=e.filter((t=>t.path.join(".").startsWith(n)))}return r},w=(t,e)=>{try{t(e)}catch(r){console.error(`failed to notify listener ${t} with ${e}`,r)}},m=function(){const t=this.batches;this.batches=[];for(const[e,r]of t)w(e,r)},g=(t,e)=>{let r,n,o,s,i,a,c=t;const h=e.length;do{for(r=c.options.async,n=c.observers,a=n.length;a--;)if([o,s]=n[a],i=v(s,e),i.length)if(r){let t;0===c.batches.length&&queueMicrotask(m.bind(c));for(const e of c.batches)if(e[0]===o){t=e;break}t||(t=[o,[]],c.batches.push(t)),Array.prototype.push.apply(t[1],i)}else w(o,i);const t=c.parent;if(t){for(let t=0;t<h;t++){const r=e[t];e[t]=new S(r.type,[c.ownKey,...r.path],r.value,r.oldValue,r.object)}c=t}else c=null}while(c)},_=(t,e,r)=>"object"!=typeof t||null===t?t:Array.isArray(t)?new K({target:t,ownKey:e,parent:r}).proxy:ArrayBuffer.isView(t)?new N({target:t,ownKey:e,parent:r}).proxy:t instanceof Date?t:new H({target:t,ownKey:e,parent:r}).proxy,j=function(){const t=this[p],e=t.target;let r,n,o;for(e.reverse(),r=0,n=e.length;r<n;r++)if(o=e[r],o&&"object"==typeof o){const t=o[p];t&&(t.ownKey=r)}const s=[new S(h,[],void 0,void 0,this)];return g(t,s),this},x=function(t){const e=this[p],r=e.target;let n,o,s;for(r.sort(t),n=0,o=r.length;n<o;n++)if(s=r[n],s&&"object"==typeof s){const t=s[p];t&&(t.ownKey=n)}const i=[new S(l,[],void 0,void 0,this)];return g(e,i),this},O=function(t,e,r){const n=this[p],o=n.target,s=[],c=o.length,h=o.slice(0);if(e=void 0===e?0:e<0?Math.max(c+e,0):Math.min(e,c),r=void 0===r?c:r<0?Math.max(c+r,0):Math.min(r,c),e<c&&r>e){let c;o.fill(t,e,r);for(let t,l,u=e;u<r;u++)t=o[u],o[u]=_(t,u,n),u in h?(l=h[u],l&&"object"==typeof l&&(c=l[p],c&&(l=c.detach())),s.push(new S(a,[u],o[u],l,this))):s.push(new S(i,[u],o[u],void 0,this));g(n,s)}return this},M=function(t,e,r){const n=this[p],o=n.target,s=o.length;t=t<0?Math.max(s+t,0):t,e=void 0===e?0:e<0?Math.max(s+e,0):Math.min(e,s),r=void 0===r?s:r<0?Math.max(s+r,0):Math.min(r,s);const i=Math.min(r-e,s-t);if(t<s&&t!==e&&i>0){const s=o.slice(0),c=[];o.copyWithin(t,e,r);for(let e,r,h,l=t;l<t+i;l++)e=o[l],e&&"object"==typeof e&&(e=_(e,l,n),o[l]=e),r=s[l],r&&"object"==typeof r&&(h=r[p],h&&(r=h.detach())),"object"!=typeof e&&e===r||c.push(new S(a,[l],e,r,this));g(n,c)}return this},A={pop:function(){const t=this[p],e=t.target,r=e.length-1;let n=e.pop();if(n&&"object"==typeof n){const t=n[p];t&&(n=t.detach())}const o=[new S(c,[r],void 0,n,this)];return g(t,o),n},push:function(){const t=this[p],e=t.target,r=arguments.length,n=new Array(r),o=e.length;for(let e=0;e<r;e++)n[e]=_(arguments[e],o+e,t);const s=Reflect.apply(e.push,e,n),a=[];for(let t=o,r=e.length;t<r;t++)a[t-o]=new S(i,[t],e[t],void 0,this);return g(t,a),s},shift:function(){const t=this[p],e=t.target;let r,n,o,s,i;for(r=e.shift(),r&&"object"==typeof r&&(i=r[p],i&&(r=i.detach())),n=0,o=e.length;n<o;n++)s=e[n],s&&"object"==typeof s&&(i=s[p],i&&(i.ownKey=n));const a=[new S(c,[0],void 0,r,this)];return g(t,a),r},unshift:function(){const t=this[p],e=t.target,r=arguments.length,n=new Array(r);for(let e=0;e<r;e++)n[e]=_(arguments[e],e,t);const o=Reflect.apply(e.unshift,e,n);for(let t,r=0,n=e.length;r<n;r++)if(t=e[r],t&&"object"==typeof t){const e=t[p];e&&(e.ownKey=r)}const s=n.length,a=new Array(s);for(let t=0;t<s;t++)a[t]=new S(i,[t],e[t],void 0,this);return g(t,a),o},reverse:j,sort:x,fill:O,copyWithin:M,splice:function(){const t=this[p],e=t.target,r=arguments.length,n=new Array(r),o=e.length;for(let e=0;e<r;e++)n[e]=_(arguments[e],e,t);const s=0===r?0:n[0]<0?o+n[0]:n[0],h=r<2?o-s:n[1],l=Math.max(r-2,0),u=Reflect.apply(e.splice,e,n),f=e.length;let y,d,b,v;for(let t,r=0;r<f;r++)t=e[r],t&&"object"==typeof t&&(y=t[p],y&&(y.ownKey=r));for(d=0,b=u.length;d<b;d++)v=u[d],v&&"object"==typeof v&&(y=v[p],y&&(u[d]=y.detach()));const w=[];let m;for(m=0;m<h;m++)m<l?w.push(new S(a,[s+m],e[s+m],u[m],this)):w.push(new S(c,[s+m],void 0,u[m],this));for(;m<l;m++)w.push(new S(i,[s+m],e[s+m],void 0,this));return g(t,w),u}},E={reverse:j,sort:x,fill:O,copyWithin:M,set:function(t,e){const r=this[p],n=r.target,o=t.length,s=n.slice(0);e=e||0,n.set(t,e);const i=new Array(o);for(let t=e;t<o+e;t++)i[t-e]=new S(a,[t],n[t],s[t],this);g(r,i)}};class S{constructor(t,e,r,n,o){this.type=t,this.path=e,this.value=r,this.oldValue=n,this.object=o}}class k{constructor(t,e){const{target:r,parent:n,ownKey:o}=t;n&&void 0!==o?(this.parent=n,this.ownKey=o):(this.parent=null,this.ownKey=null);const s=e(r,this);this.observers=[],this.revocable=Proxy.revocable(s,this),this.proxy=this.revocable.proxy,this.target=s,this.options=this.processOptions(t.options),this.options.async&&(this.batches=[])}processOptions(t){if(t){if("object"!=typeof t)throw new Error(`Observable options if/when provided, MAY only be an object, got '${t}'`);const e=Object.keys(t).filter((t=>!(t in u)));if(e.length)throw new Error(`'${e.join(", ")}' is/are not a valid Observable option/s`);return Object.assign({},t)}return{}}detach(){return this.parent=null,this.target}set(t,e,r){let n=t[e];if(r!==n){const o=_(r,e,this);if(t[e]=o,n&&"object"==typeof n){const t=n[p];t&&(n=t.detach())}const s=void 0===n?[new S(i,[e],o,void 0,this.proxy)]:[new S(a,[e],o,n,this.proxy)];g(this,s)}return!0}deleteProperty(t,e){let r=t[e];if(delete t[e],r&&"object"==typeof r){const t=r[p];t&&(r=t.detach())}const n=[new S(c,[e],void 0,r,this.proxy)];return g(this,n),!0}}class H extends k{constructor(t){super(t,y)}}class K extends k{constructor(t){super(t,d)}get(t,e){return A[e]||t[e]}}class N extends k{constructor(t){super(t,b)}get(t,e){return E[e]||t[e]}}const T=Object.freeze({from:(t,e)=>{if(t&&"object"==typeof t){if(t[p])return t;if(Array.isArray(t))return new K({target:t,ownKey:null,parent:null,options:e}).proxy;if(ArrayBuffer.isView(t))return new N({target:t,ownKey:null,parent:null,options:e}).proxy;if(t instanceof Date)throw new Error(`${t} found to be one of a non-observable types`);return new H({target:t,ownKey:null,parent:null,options:e}).proxy}throw new Error("observable MAY ONLY be created from a non-null object")},isObservable:t=>!(!t||!t[p]),observe:(t,e,r)=>{if(!T.isObservable(t))throw new Error("invalid observable parameter");if("function"!=typeof e)throw new Error(`observer MUST be a function, got '${e}'`);const n=t[p].observers;n.some((t=>t[0]===e))?console.warn("observer may be bound to an observable only once; will NOT rebind"):n.push([e,f(r)])},unobserve:(t,...e)=>{if(!T.isObservable(t))throw new Error("invalid observable parameter");const r=t[p].observers;let n=r.length;if(n)if(e.length)for(;n;){e.indexOf(r[--n][0])>=0&&r.splice(n,1)}else r.splice(0)}});var P=function(){var t=this;this.on=function(e,r){return t.handlers[e]=t.handlers[e]||[],t.handlers[e].push(r),t},this.off=function(e,r){var n=t.handlers[e];if(n)for(var o=0;o<n.length;o++)n[o]===r&&n.splice(o,1);return t},this.callEmitFromMT=function(){this.func.apply(null,this.args?this.args:[])},this.emit=function(e,r){if(t.handlers[e])for(var n=0;n<t.handlers[e].length;n++)try{queueMicrotask(t.callEmitFromMT.bind({func:t.handlers[e][n],args:r}))}catch(t){console.log(t)}return t},this.clear=function(){t.handlers={}},this.handlers={}},$=function(t){function e(e){var r=t.call(this)||this;return Object.keys(e.property).forEach((function(t){r.on(t,(function(r){try{e.property[t].apply(e.state,[r])}catch(t){console.log(t)}}))})),r}return r(e,t),e}(P),z=function(t){function e(e,r,i){var a,c,h=this;return(h=t.call(this)||this).middlewares=[],h._sendHistory=[],h._componentName="Unknown",h.watch=function(t){return o(h,void 0,void 0,(function(){var e,r,n=this;return s(this,(function(o){switch(o.label){case 0:return e=performance.now(),[4,this.executeMiddlewares(t,(function(){for(var e,r=function(t){var r=t.path.filter((function(t){return"number"!=typeof t}));if(null===(e=n._options)||void 0===e?void 0:e.deep){var o="";r.forEach((function(e){o+=e+".",n.emit(o.substring(0,o.length-1),[t.object])}))}else{var s=r.join(".");n.emit(s,[t.object])}},o=0,s=t;o<s.length;o++){r(s[o])}}))];case 1:return o.sent(),"development"===process.env.NODE_ENV&&(r=performance.now()-e)>33.34&&console.warn("[x-view-model] Slow state update detected (".concat(r.toFixed(2),"ms)"),t),[2]}}))}))},h._property=e,h._options=r,h._reference=0,h._observable=T.from(n({},h._property),{async:!0}),h._started=!1,h.services=new $(h),h._historyHandler=(null===(a=null==r?void 0:r.history)||void 0===a?void 0:a.handler)||function(){},h._historyMaxSize=(null===(c=null==r?void 0:r.history)||void 0===c?void 0:c.maxSize)||100,h.middlewares=(null==r?void 0:r.middlewares)||[],h.devTools=i,h}return r(e,t),e.prototype.use=function(t){return this.middlewares.push(t),this},e.prototype.executeMiddlewares=function(t,e){return o(this,void 0,void 0,(function(){var r=this;return s(this,(function(n){switch(n.label){case 0:return 0===this.middlewares.length?(e(),[2]):[4,this.middlewares.reduceRight((function(e,n){return function(){return n(t,e,r.state)}}),e)()];case 1:return n.sent(),[2]}}))}))},Object.defineProperty(e.prototype,"state",{get:function(){return this._observable},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"property",{get:function(){return this._property},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"reference",{get:function(){return this._reference},set:function(t){this._reference=t,this._reference>0?this.start():this.stop()},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"name",{get:function(){return this._options&&this._options.name?this._options.name:"unnamed"},enumerable:!1,configurable:!0}),e.prototype.increaseReference=function(){this.reference++},e.prototype.decreaseReference=function(){this.reference--},e.prototype.start=function(){if(!this._started)return T.observe(this._observable,this.watch),console.log(this.name,"started"),this._started=!0,this},e.prototype.stop=function(){if(this._started)return T.unobserve(this._observable),this._observable=T.from(n({},this._property)),this._started=!1,this},e.prototype.pause=function(){if(this._started)return T.unobserve(this._observable),this},e.prototype.restart=function(){return T.unobserve(this._observable),this._observable=T.from(n({},this._property)),T.observe(this._observable,this.watch),console.log(this.name,"started"),this._started=!0,this},e.prototype.snapshot=function(){this.pause();var t=JSON.stringify(this._observable);return this.start(),t},e.prototype.rebase=function(t){var e="string"==typeof t?JSON.parse(t):t;return this._property=n(n({},this._property),e),this},e.prototype.restore=function(t){this.pause();var e="string"==typeof t?JSON.parse(t):t;return this._observable=T.from(n(n({},this._property),e)),this.start(),this},e.prototype.addHistory=function(t){return o(this,void 0,void 0,(function(){return s(this,(function(e){switch(e.label){case 0:return this._historyHandler?[4,Promise.resolve(this._historyHandler(t,this.state))]:[3,2];case 1:e.sent(),e.label=2;case 2:return this._sendHistory.push(t),this._sendHistory.length>this._historyMaxSize&&(this._sendHistory=this._sendHistory.slice(-this._historyMaxSize)),[2]}}))}))},e.prototype.send=function(t,e,r){return void 0===r&&(r=!1),o(this,void 0,void 0,(function(){var n,o,i;return s(this,(function(s){switch(s.label){case 0:if(n={name:t,componentName:this._componentName,payload:e,timestamp:Date.now()},!r)return[3,7];s.label=1;case 1:return s.trys.push([1,4,,6]),[4,this.property[t].apply(this.state,[e])];case 2:return o=s.sent(),n.result=o,[4,this.addHistory(n)];case 3:return s.sent(),[2,o];case 4:return i=s.sent(),n.error=i,[4,this.addHistory(n)];case 5:throw s.sent(),i;case 6:return[3,9];case 7:return this.services.emit(t,[e]),[4,this.addHistory(n)];case 8:return s.sent(),[2,void 0];case 9:return[2]}}))}))},e.prototype.getSendHistory=function(){return this._sendHistory},e.prototype.clearSendHistory=function(){this._sendHistory=[]},e}(P),V=function(){function t(){this.state={components:new Map}}return t.prototype.components=function(){return this.state.components},t.prototype.registerComponent=function(t,e,r){var n;if(void 0===r&&(r=[]),this.state.components.has(t)){var o=this.state.components.get(t);o&&!o[e]&&(o[e]={enabled:!1,paths:r})}else{var s=((n={})[e]={enabled:!1,paths:r},n);this.state.components.set(t,s)}},t}(),Z=new V,F=function(){if("development"!==process.env.NODE_ENV)return{name:"Unknown",paths:[]};try{throw new Error}catch(y){if(!(y instanceof Error))return{name:"Unknown",paths:[]};for(var t=y.stack||"",e=t.split("\n"),r="Anonymous",n=[],o=[/at ([A-Z][A-Za-z0-9_$]*) \(/,/at ([A-Z][A-Za-z0-9_$]*)\s/,/\.(jsx|tsx|js|ts):(\d+).*\s([A-Z][A-Za-z0-9_$]*)/],s=2;s<Math.min(e.length,8);s++){for(var i=e[s],a=0,c=o;a<c.length;a++){var h=c[a],l=i.match(h);if(l&&l[1]){var p=i.match(/\((.+?):\d+:\d+\)/);if(p&&p[1]){var u=p[1].replace(/^(file:\/\/\/|\/)[A-Za-z]:\//,"").split(/[\/\\]/).filter(Boolean);u.length>0&&/\.(jsx|tsx|js|ts)$/.test(u[u.length-1])&&u.pop(),n.push.apply(n,u)}r=l[1];break}}if("Anonymous"!==r)break}if("Anonymous"===r){var f=t.match(/\/([A-Z][A-Za-z0-9_$]*)\.(jsx|tsx|js|ts)/);f&&f[1]&&(r=f[1])}return{name:r,paths:n}}},R=function(e,r,n){n||(n=t.useMemo((function(){return F()}),[])),Z.registerComponent(e.context,n.name,n.paths);var o=function(e,r){var n=t.useState(0);n[0];var o=n[1],s=t.useCallback((function(t){o((function(t){return t+1}))}),[]);return t.useMemo((function(){r.increaseReference(),Array.isArray(e)?e.forEach((function(t){r.on(t,s)})):r.on(e,s)}),[r]),t.useEffect((function(){return function(){r.decreaseReference(),Array.isArray(e)?e.forEach((function(t){r.off(t,s)})):r.off(e,s)}}),[r]),r.state}(r,e.context);return[o,e.context.send.bind(Object.assign(e.context,{_componentName:n.name,_componentPaths:n.paths})),e.ref]};exports.DevToolsHandler=V,exports.devTools=Z,exports.registViewModel=function(t,e,r){return{context:new z(t,e),ref:r||void 0}},exports.useComputedViewModel=function(e,r,n){var o=t.useMemo((function(){return F()}),[]),s=R(e,n,o),i=s[0],a=s[1],c=s[2];return[t.useMemo((function(){return r(i)}),[i,r]),a,c]},exports.useMemoizedViewModel=function(e,r){var n=t.useMemo((function(){return F()}),[]),o=R(e,r,n);return[o[0],o[1],o[2]]},exports.useViewModel=R; //# sourceMappingURL=index.min.js.map